int main(int argc, char *argv[]){ char *str; struct stat st; int fd; int i; if (argc!=2){ fprintf(stderr,"Usage:\n%s <text file containing messages>\n",argv[0]); return -1; } if (stat(argv[1],&st)==-1){ fprintf(stderr,"Could not stat %s: %s\n",argv[1],strerror(errno)); return -1; } fd=open(argv[1],O_RDONLY); if (fd==-1){ fprintf(stderr,"Could not open %s: %s\n",argv[1],strerror(errno)); return -1; } str=belle_sip_malloc0(st.st_size+1); if (read(fd,str,st.st_size)==-1){ fprintf(stderr,"Could not open %s: %s\n",argv[1],strerror(errno)); belle_sip_free(str); close(fd); return -1; } close(fd); for (i=0;i<st.st_size;){ size_t read; belle_sip_message_t *msg=belle_sip_message_parse_raw(str+i,st.st_size-i,&read); if (msg){ printf("Succesfully parsed message of %i bytes.",(int)read); }else{ fprintf(stderr,"Failed to parse message."); break; } i+=read; } belle_sip_free(str); return 0; }
static void testRegisterRaw(void) { const char* raw_message = "REGISTER sip:192.168.0.20 SIP/2.0\r\n"\ "Via: SIP/2.0/UDP 192.168.1.8:5062;rport;branch=z9hG4bK1439638806\r\n"\ "From: <sip:[email protected]>;tag=465687829\r\n"\ "To: <sip:[email protected]>\r\n"\ "Call-ID: 1053183492\r\n"\ "CSeq: 1 REGISTER\r\n"\ "Contact: <sip:[email protected]:5062>\r\n"\ "Max-Forwards: 70\r\n"\ "User-Agent: Linphone/3.3.99.10 (eXosip2/3.3.0)\r\n"\ "Expires: 3600\r\n"\ "Content-Length: 0\r\n\r\n123456789"; belle_sip_request_t* request; size_t size=0; size_t raw_message_size= strlen(raw_message); belle_sip_message_t* message = belle_sip_message_parse_raw(raw_message,raw_message_size,&size); CU_ASSERT_EQUAL(raw_message_size,size+9); request = BELLE_SIP_REQUEST(message); CU_ASSERT_STRING_EQUAL(belle_sip_request_get_method(request),"REGISTER"); CU_ASSERT_PTR_NOT_NULL(belle_sip_request_get_uri(request)); CU_ASSERT_STRING_EQUAL(&raw_message[size],"123456789"); belle_sip_object_unref(message); }
void belle_sip_channel_parse_stream(belle_sip_channel_t *obj, int end_of_stream){ int offset; size_t read_size=0; int num; while ((num=(obj->input_stream.write_ptr-obj->input_stream.read_ptr))>0){ if (obj->input_stream.state == WAITING_MESSAGE_START) { int i; /*first, make sure there is \r\n in the buffer, otherwise, micro parser cannot conclude, because we need a complete request or response line somewhere*/ for (i=0;i<num-1;i++) { if ((obj->input_stream.read_ptr[i]=='\r' && obj->input_stream.read_ptr[i+1]=='\n') || belle_sip_channel_input_stream_get_buff_length(&obj->input_stream) <= 1 /*1 because null terminated*/ /*if buffer full try to parse in any case*/) { /*good, now we can start searching for request/response*/ if ((offset=get_message_start_pos(obj->input_stream.read_ptr,num)) >=0 ) { /*message found !*/ if (offset>0) { belle_sip_warning("trashing [%i] bytes in front of sip message on channel [%p]",offset,obj); obj->input_stream.read_ptr+=offset; } obj->input_stream.state=MESSAGE_AQUISITION; } else { belle_sip_debug("Unexpected [%s] received on channel [%p], trashing",obj->input_stream.read_ptr,obj); obj->input_stream.read_ptr=obj->input_stream.write_ptr; belle_sip_channel_input_stream_reset(&obj->input_stream); continue; } break; } } if (i >= num-1) { belle_sip_debug("[%s] received on channel [%p], cannot determine if expected or not, waiting for new data",obj->input_stream.read_ptr,obj); break; } } if (obj->input_stream.state==MESSAGE_AQUISITION) { /*search for \r\n\r\n*/ char* end_of_message=NULL; if ((end_of_message=strstr(obj->input_stream.read_ptr,"\r\n\r\n"))){ int bytes_to_parse; char tmp; /*end of message found*/ end_of_message+=4;/*add \r\n\r\n*/ bytes_to_parse=end_of_message-obj->input_stream.read_ptr; tmp=*end_of_message; *end_of_message='\0';/*this is in order for the following log to print the message only to its end.*/ /*belle_sip_message("channel [%p] read message of [%i] bytes:\n%.40s...",obj, bytes_to_parse, obj->input_stream.read_ptr);*/ obj->input_stream.msg=belle_sip_message_parse_raw(obj->input_stream.read_ptr ,bytes_to_parse ,&read_size); *end_of_message=tmp; obj->input_stream.read_ptr+=read_size; if (obj->input_stream.msg && read_size > 0){ belle_sip_message("channel [%p] [%i] bytes parsed",obj,(int)read_size); belle_sip_object_ref(obj->input_stream.msg); if (belle_sip_message_is_request(obj->input_stream.msg)) fix_incoming_via(BELLE_SIP_REQUEST(obj->input_stream.msg),obj->current_peer); /*check for body*/ if (check_body(obj)){ obj->input_stream.state=BODY_AQUISITION; } else { /*no body*/ belle_sip_channel_message_ready(obj); continue; } }else{ belle_sip_error("Could not parse [%s], on channel [%p] skipping to [%s]",obj->input_stream.read_ptr ,obj ,end_of_message); obj->input_stream.read_ptr=end_of_message; obj->input_stream.state=WAITING_MESSAGE_START; continue; } }else break; /*The message isn't finished to be receive, we need more data*/ } if (obj->input_stream.state==BODY_AQUISITION) { if (acquire_body(obj,end_of_stream)==BELLE_SIP_STOP) break; } } }
int main(int argc, char *argv[]){ char *str; struct stat st; int fd; int i; const char *filename=NULL; const char *protocol="sip"; if (argc<2){ fprintf(stderr,"Usage:\n%s [--protocol sip|http|sdp] <text file containing messages>\n",argv[0]); return -1; } for(i=1;i<argc;++i){ if (strcmp(argv[i],"--protocol")==0){ i++; if (i<argc){ protocol=argv[i]; }else{ fprintf(stderr,"Missing argument for --protocol\n"); return -1; } }else filename=argv[i]; } if (!filename){ fprintf(stderr,"No filename specified\n"); return -1; } if (stat(filename,&st)==-1){ fprintf(stderr,"Could not stat %s: %s\n",filename,strerror(errno)); return -1; } fd=open(filename,O_RDONLY); if (fd==-1){ fprintf(stderr,"Could not open %s: %s\n",filename,strerror(errno)); return -1; } str=belle_sip_malloc0(st.st_size+1); if (read(fd,str,st.st_size)==-1){ fprintf(stderr,"Could not read %s: %s\n",filename,strerror(errno)); belle_sip_free(str); close(fd); return -1; } close(fd); belle_sip_set_log_level(BELLE_SIP_LOG_DEBUG); for (i=0;i<st.st_size;){ size_t read; if (strcasecmp(protocol,"sip")==0 || strcasecmp(protocol,"http")==0){ belle_sip_message_t *msg; uint64_t begin,end; begin=belle_sip_time_ms(); msg=belle_sip_message_parse_raw(str+i,st.st_size-i,&read); end=belle_sip_time_ms(); if (msg){ printf("Successfully parsed %s message of %i bytes in %i ms.\n",protocol,(int)read, (int)(end-begin)); }else{ fprintf(stderr,"Failed to parse message.\n"); break; } i+=read; }else if (strcasecmp(protocol,"sdp")==0){ belle_sdp_session_description_t *sdp=belle_sdp_session_description_parse(str); if (sdp){ printf("Successfully parsed %s message of %i bytes.\n",protocol,(int)strlen(str)); }else{ fprintf(stderr,"Failed to parse SDP message.\n"); } break; } } belle_sip_free(str); return 0; }