/* osip_message_t *sip is filled while analysing buf */ static int _osip_message_parse (osip_message_t * sip, const char *buf, size_t length, int sipfrag) { int i; const char *next_header_index; char *tmp; char *beg; tmp = osip_malloc (length + 2); if (tmp == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Could not allocate memory.\n")); return OSIP_NOMEM; } beg = tmp; memcpy (tmp, buf, length); /* may contain binary data */ tmp[length] = '\0'; /* skip initial \r\n */ while (tmp[0] == '\r' || tmp[0] == '\n') tmp++; osip_util_replace_all_lws (tmp); /* parse request or status line */ i = __osip_message_startline_parse (sip, tmp, &next_header_index); if (i != 0 && !sipfrag) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Could not parse start line of message.\n")); osip_free (beg); return i; } tmp = (char *) next_header_index; /* parse headers */ i = msg_headers_parse (sip, tmp, &next_header_index); if (i != 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "error in msg_headers_parse()\n")); osip_free (beg); return i; } tmp = (char *) next_header_index; /* this is a *very* simple test... (which handle most cases...) */ if (tmp[0] == '\0' || tmp[1] == '\0' || tmp[2] == '\0') { /* this is mantory in the oSIP stack */ if (sip->content_length == NULL) osip_message_set_content_length (sip, "0"); osip_free (beg); return OSIP_SUCCESS; /* no body found */ } i = msg_osip_body_parse (sip, tmp, &next_header_index, length - (tmp - beg)); osip_free (beg); if (i != 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "error in msg_osip_body_parse()\n")); return i; } /* this is mandatory in the oSIP stack */ if (sip->content_length == NULL) osip_message_set_content_length (sip, "0"); return OSIP_SUCCESS; }
extern int _eXosip_answer_refer_123456(eXosip_call_t *jc, eXosip_dialog_t *jd, int code) { osip_event_t *evt_answer; osip_transaction_t *tr; osip_message_t *response; int i; tr = eXosip_find_last_inc_refer(jc, jd); if (tr==NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot find transaction to answer")); return -1; } if (jd!=NULL) { i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request); } else { i = _eXosip_build_response_default(&response, NULL, code, tr->orig_request); } if (i!=0) { OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"ERROR: Could not create response for REFER\n")); return -1; } if ( ( code >= 200 ) && ( code <= 299) ) complete_answer_that_establish_a_dialog(response, tr->orig_request); /* Yet another eeek */ /* if (300<=code<=399) */ /* { */ /* /\* Should add contact fields *\/ */ /* /\* ... *\/ */ /* } */ osip_message_set_content_length(response, "0"); /* send message to transaction layer */ evt_answer = osip_new_outgoing_sipmessage(response); evt_answer->transactionid = tr->transactionid; osip_transaction_add_event(tr, evt_answer); __eXosip_wakeup(); return 0; }
int _eXosip_answer_invite_1xx (eXosip_call_t * jc, eXosip_dialog_t * jd, int code, osip_message_t ** answer) { int i; osip_transaction_t *tr; *answer = NULL; tr = eXosip_find_last_inc_invite (jc, jd); if (tr == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot find transaction to answer")); return -1; } /* is the transaction already answered? */ if (tr->state == IST_COMPLETED || tr->state == IST_CONFIRMED || tr->state == IST_TERMINATED) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: transaction already answered\n")); return -1; } if (jd == NULL) i = _eXosip_build_response_default (answer, NULL, code, tr->orig_request); else i = _eXosip_build_response_default (answer, jd->d_dialog, code, tr->orig_request); if (i != 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "ERROR: Could not create response for invite\n")); return -2; } osip_message_set_content_length (*answer, "0"); /* send message to transaction layer */ if (code > 100) { i = complete_answer_that_establish_a_dialog (*answer, tr->orig_request); } return 0; }
int eXosip_answer_invite_3456xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code, const char *contact) { osip_event_t *evt_answer; osip_message_t *response; int i; osip_transaction_t *tr; tr = eXosip_find_last_inc_invite(jc, jd); if (tr==NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot find transaction to answer")); return -1; } /* is the transaction already answered? */ if (tr->state==IST_COMPLETED || tr->state==IST_CONFIRMED || tr->state==IST_TERMINATED) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: transaction already answered\n")); return -1; } i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request); if (i!=0) { OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"ERROR: Could not create response for invite\n")); return -1; } if ( ( code >= 300 ) && ( code <= 399 ) && ( contact != 0 ) ) { owsip_message_clean_contacts(response); osip_message_set_contact(response, contact); } osip_message_set_content_length(response, "0"); /* send message to transaction layer */ evt_answer = osip_new_outgoing_sipmessage(response); evt_answer->transactionid = tr->transactionid; osip_transaction_add_event(tr, evt_answer); __eXosip_wakeup(); return 0; }
int eXosip_answer_options_3456xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code) { osip_event_t *evt_answer; osip_transaction_t *tr; osip_message_t *response; int i; tr = eXosip_find_last_inc_options(jc, jd); if (tr==NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot find transaction to answer")); return -1; } if (jd!=NULL) { i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request); } else { i = _eXosip_build_response_default(&response, NULL, code, tr->orig_request); } if (i!=0) { OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"ERROR: Could not create response for options\n")); return -1; } /* eeeeeeekkk! should be OUT of wengophone! */ /* if (300<=code<=399) */ /* { */ /* /\* Should add contact fields *\/ */ /* /\* ... *\/ */ /* } */ osip_message_set_content_length(response, "0"); /* send message to transaction layer */ evt_answer = osip_new_outgoing_sipmessage(response); evt_answer->transactionid = tr->transactionid; osip_transaction_add_event(tr, evt_answer); __eXosip_wakeup(); return 0; }
int _eXosip_answer_invite_3456xx (eXosip_call_t * jc, eXosip_dialog_t * jd, int code, osip_message_t ** answer) { int i; osip_transaction_t *tr; *answer = NULL; tr = eXosip_find_last_inc_invite (jc, jd); if (tr == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot find transaction to answer")); return -1; } /* is the transaction already answered? */ if (tr->state == IST_COMPLETED || tr->state == IST_CONFIRMED || tr->state == IST_TERMINATED) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: transaction already answered\n")); return -1; } i = _eXosip_build_response_default (answer, jd->d_dialog, code, tr->orig_request); if (i != 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "ERROR: Could not create response for invite\n")); return -1; } if ((300 <= code) && (code <= 399)) { /* Should add contact fields */ /* ... */ } osip_message_set_content_length (*answer, "0"); /* send message to transaction layer */ return 0; }
static int msg_osip_body_parse(osip_message_t * sip, const char *start_of_buf, const char **next_body, size_t length) { const char *start_of_body; const char *end_of_body; const char *end_of_buf; char *tmp; int i; char *sep_boundary; size_t len_sep_boundary; osip_generic_param_t *ct_param; if (sip->content_type == NULL || sip->content_type->type == NULL || sip->content_type->subtype == NULL) return OSIP_SUCCESS; /* no body is attached */ if (0 != osip_strcasecmp(sip->content_type->type, "multipart")) { size_t osip_body_len; if (start_of_buf[0] == '\0') return OSIP_SYNTAXERROR; /* final CRLF is missing */ /* get rid of the first CRLF */ if ('\r' == start_of_buf[0]) { if ('\n' == start_of_buf[1]) start_of_body = start_of_buf + 2; else start_of_body = start_of_buf + 1; } else if ('\n' == start_of_buf[0]) start_of_body = start_of_buf + 1; else return OSIP_SYNTAXERROR; /* message does not end with CRLFCRLF, CRCR or LFLF */ /* update length (without CRLFCRLF */ length = length - (start_of_body - start_of_buf); /* fixed 24 08 2004 */ if (length <= 0) return OSIP_SYNTAXERROR; if (sip->content_length != NULL) osip_body_len = osip_atoi(sip->content_length->value); else { /* if content_length does not exist, set it. */ char tmp[16]; /* case where content-length is missing but the body only contains non-binary data */ if (0 == osip_strcasecmp(sip->content_type->type, "application") && 0 == osip_strcasecmp(sip->content_type->subtype, "sdp")) { osip_body_len = strlen(start_of_body); sprintf(tmp, "%i", osip_body_len); i = osip_message_set_content_length(sip, tmp); if (i != 0) return i; } else return OSIP_SYNTAXERROR; /* Content-type may be non binary data */ } if (length < osip_body_len) { OSIP_TRACE(osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Message was not receieved enterely. length=%i osip_body_len=%i\n", length, osip_body_len)); return OSIP_SYNTAXERROR; } end_of_body = start_of_body + osip_body_len; tmp = osip_malloc(end_of_body - start_of_body + 2); if (tmp == NULL) return OSIP_NOMEM; memcpy(tmp, start_of_body, end_of_body - start_of_body); tmp[end_of_body - start_of_body] = '\0'; i = osip_message_set_body(sip, tmp, end_of_body - start_of_body); osip_free(tmp); if (i != 0) return i; return OSIP_SUCCESS; } /* find the boundary */ i = osip_generic_param_get_byname(&sip->content_type->gen_params, "boundary", &ct_param); if (i != 0) return i; if (ct_param == NULL) return OSIP_SYNTAXERROR; if (ct_param->gvalue == NULL) return OSIP_SYNTAXERROR; /* No boundary but multiple headers??? */ { const char *boundary_prefix = "\n--"; size_t len = strlen(ct_param->gvalue); sep_boundary = (char *) osip_malloc(len + 4); if (sep_boundary == NULL) return OSIP_NOMEM; strcpy(sep_boundary, boundary_prefix); if (ct_param->gvalue[0] == '"' && ct_param->gvalue[len - 1] == '"') strncat(sep_boundary, ct_param->gvalue + 1, len - 2); else strncat(sep_boundary, ct_param->gvalue, len); } len_sep_boundary = strlen(sep_boundary); *next_body = NULL; start_of_body = start_of_buf; end_of_buf = start_of_buf + length; for (;;) { size_t body_len = 0; i = __osip_find_next_occurence(sep_boundary, start_of_body, &start_of_body, end_of_buf); if (i != 0) { osip_free(sep_boundary); return i; } i = __osip_find_next_occurence(sep_boundary, start_of_body + len_sep_boundary, &end_of_body, end_of_buf); if (i != 0) { osip_free(sep_boundary); return i; } /* this is the real beginning of body */ start_of_body = start_of_body + len_sep_boundary + 1; if ('\n' == start_of_body[0] || '\r' == start_of_body[0]) start_of_body++; body_len = end_of_body - start_of_body; /* Skip CR before end boundary. */ if (*(end_of_body - 1) == '\r') body_len--; tmp = osip_malloc(body_len + 2); if (tmp == NULL) { osip_free(sep_boundary); return OSIP_NOMEM; } memcpy(tmp, start_of_body, body_len); tmp[body_len] = '\0'; i = osip_message_set_body_mime(sip, tmp, body_len); osip_free(tmp); if (i != 0) { osip_free(sep_boundary); return i; } if (strncmp(end_of_body + len_sep_boundary, "--", 2) == 0) { /* end of all bodies */ *next_body = end_of_body; osip_free(sep_boundary); return OSIP_SUCCESS; } /* continue on the next body */ start_of_body = end_of_body; } /* Unreachable code */ /* osip_free (sep_boundary); */ return OSIP_SYNTAXERROR; }
/* * Processing. * */ int PLUGIN_PROCESS(int stage, sip_ticket_t *ticket){ /* stage contains the PLUGIN_* value - the stage of SIP processing. */ int sts; char *buff; size_t buflen; osip_body_t *body; sdp_message_t *sdp; int content_length; osip_content_type_t *content_type; char clen[8]; /* content length: probably never more than 7 digits !*/ // // check that we have the expected payload "application/sdp" // // get content length content_length=0; if (ticket->sipmsg && ticket->sipmsg->content_length && ticket->sipmsg->content_length->value) { sts=sscanf(ticket->sipmsg->content_length->value, "%i", &content_length); } // check if we have a content type defined and that payload length >0 content_type=osip_message_get_content_type(ticket->sipmsg); if ((content_length == 0) || (content_type == NULL) || (content_type->type == NULL) || (content_type->subtype == NULL)) { DEBUGC(DBCLASS_PLUGIN, "%s: no content", name); return STS_SUCCESS; } // check content type: must be "application/sdp" if ((strncmp(content_type->type, "application", sizeof("application")) != 0) || (strncmp(content_type->subtype, "sdp", sizeof("sdp")) != 0)) { DEBUGC(DBCLASS_PLUGIN, "%s: unsupported content-type %s/%s", name, content_type->type, content_type->subtype); return STS_SUCCESS; } DEBUGC(DBCLASS_PLUGIN, "%s: content-type %s/%s, size=%i", name, content_type->type, content_type->subtype, content_length); // // parse the payload // // get a pointer to the payload of the SIP packet sts = osip_message_get_body(ticket->sipmsg, 0, &body); if (sts != 0) { DEBUGC(DBCLASS_PLUGIN, "%s: no body found in message", name); return STS_SUCCESS; } // dump it into a buffer sts = sip_body_to_str(body, &buff, &buflen); if (sts != 0) { WARN("%s: unable to sip_body_to_str", name); return STS_SUCCESS; } // and parse it into an SDP structure sts = sdp_message_init(&sdp); sts = sdp_message_parse (sdp, buff); if (sts != 0) { WARN("%s: unable to sdp_message_parse() body", name); DUMP_BUFFER(-1, buff, buflen); osip_free(buff); buff=NULL; sdp_message_free(sdp); return STS_SUCCESS; } osip_free(buff); buff=NULL; // // now do the codec filtering magic... sdp_filter_codec(sdp); // // replace the original payload with the new modified payload // // remove old body from SIP packet sts = osip_list_remove(&(ticket->sipmsg->bodies), 0); osip_body_free(body); body=NULL; // dump new body to buffer sdp_message_to_str(sdp, &buff); buflen=strlen(buff); // free sdp structure (no longer needed) sdp_message_free(sdp); sdp=NULL; // put new body into SIP message sts=sip_message_set_body(ticket->sipmsg, buff, buflen); if (sts != 0) { ERROR("%s: unable to sip_message_set_body body", name); DUMP_BUFFER(-1, buff, buflen); buflen=0; } // free buffer osip_free(buff); buff=NULL; // // set new content length // // remove old content leght field osip_content_length_free(ticket->sipmsg->content_length); ticket->sipmsg->content_length=NULL; // set new content length sprintf(clen,"%ld",(long)buflen); sts = osip_message_set_content_length(ticket->sipmsg, clen); return STS_SUCCESS; }
int Node::SndRegister(REG_TYPE type , ChordId req_uri , ChordId to , ChordId contact , BOOL IncludeSuccList) { char *message1; unsigned int len = 0; osip_transaction_t *transaction; osip_event_t *sipevent; osip_message_t *request; /* temp uri */ char * tmp_uri; int i; i = osip_message_init(&request); if (i!=0) goto si2perror1; /* prepare the request-line */ osip_message_set_method(request, osip_strdup("REGISTER")); osip_message_set_version(request, osip_strdup("SIP/2.0")); osip_message_set_status_code(request, 0); osip_message_set_reason_phrase(request, NULL); //requset uri if(type == MULTICAST) { tmp_uri = osip_strdup("sip:224.0.1.75") ; } else tmp_uri = ChordId2Uri(req_uri,false) ; osip_uri_t *uri; i=osip_uri_init(&uri); if (i!=0) goto si2perror2; i=osip_uri_parse(uri, tmp_uri ); if(tmp_uri) osip_free(tmp_uri) ; if (i!=0) goto si2perror2; osip_message_set_uri(request , uri) ; if(type == JOIN) { tmp_uri = ChordId2Uri(to,false) ; /* when JOIN , to and from are same */ osip_message_set_to(request, tmp_uri ); osip_message_set_from(request, tmp_uri); if (tmp_uri) osip_free(tmp_uri) ; osip_from_param_add (request->from, osip_strdup ("user"), osip_strdup("join")); } else if(type == FINDSUCC) { tmp_uri = ChordId2Uri(to,true) ; osip_message_set_to(request, tmp_uri ); if (tmp_uri) osip_free(tmp_uri) ; tmp_uri = ChordId2Uri(chordId,false); osip_message_set_from(request, tmp_uri ); if (tmp_uri) osip_free(tmp_uri) ; osip_from_param_add (request->from, osip_strdup ("user"), osip_strdup("findsucc")); //has no contact } else if(type == STABILIZE) { tmp_uri = ChordId2Uri(to,false); osip_message_set_to(request, tmp_uri); if (tmp_uri) osip_free(tmp_uri) ; tmp_uri = ChordId2Uri(chordId,false) ; osip_message_set_from(request, tmp_uri ); osip_from_param_add (request->from, osip_strdup ("user"), osip_strdup("stabilize")); if (tmp_uri) osip_free(tmp_uri) ; //contact tmp_uri = ChordId2Uri(chordId,false); char * pre_uri = ChordId2Uri(getFingerTable()->getPredecessor(),false) ; char *ctt = (char *) osip_malloc(strlen(tmp_uri) + strlen(";predecessor=") + strlen(pre_uri) +1) ; if (ctt == NULL) return NULL; sprintf (ctt, "%s;predecessor=%s", tmp_uri,pre_uri); osip_free(tmp_uri) ; osip_free(pre_uri) ; osip_message_set_contact(request, ctt ); osip_free(ctt) ; } else if(type == LEAVE) { tmp_uri = ChordId2Uri(to,false) ; osip_message_set_to(request, tmp_uri ); if (tmp_uri) osip_free(tmp_uri) ; tmp_uri = ChordId2Uri(chordId,false) ; osip_message_set_from(request, tmp_uri ); if (tmp_uri) osip_free(tmp_uri) ; osip_from_param_add (request->from, osip_strdup ("user"), osip_strdup("leave")); //contact tmp_uri = ChordId2Uri(chordId,false); char * pre_uri = ChordId2Uri(getFingerTable()->getPredecessor(),false) ; char *ctt = (char *) osip_malloc(strlen(tmp_uri) + strlen(";predecessor=") + strlen(pre_uri) +1) ; if (ctt == NULL) return NULL; sprintf (ctt, "%s;predecessor=%s", tmp_uri,pre_uri); osip_free(tmp_uri) ; osip_free(pre_uri) ; osip_message_set_contact(request, ctt ); osip_free(ctt) ; //succlist if(IncludeSuccList) { for(i = 0 ; i < getFingerTable()->getSuccNum() ; i++) { tmp_uri = ChordId2Uri(getFingerTable()->getSuccessor(i),false) ; osip_message_set_contact(request, tmp_uri ); osip_free(tmp_uri) ; } } }//type == LEAVE if(type == MULTICAST) { tmp_uri = ChordId2Uri(chordId,false); /* when JOIN , to and from are same */ osip_message_set_to(request, tmp_uri ); osip_message_set_from(request, tmp_uri); osip_from_param_add (request->from, osip_strdup ("user"), osip_strdup("multicast")); osip_free(tmp_uri) ; //no contact }//type == MULTIPL //---set call_id and cseq osip_call_id_t *callid; osip_cseq_t *cseq; char *num; char *cidrand; char *register_callid_number ; /* call-id is always the same for REGISTRATIONS */ i = osip_call_id_init(&callid); if (i!=0) goto si2perror2; cidrand = osip_strdup("BF9598C48B184EBBAFADFE527EED8186") ; osip_call_id_set_number(callid, cidrand); register_callid_number = cidrand; osip_call_id_set_host(callid, osip_strdup("SI2P.COM")); request->call_id = callid; //cseq i = osip_cseq_init(&cseq); if (i!=0) goto si2perror2 ; num = osip_strdup("1"); osip_cseq_set_number(cseq, num); osip_cseq_set_method(cseq, osip_strdup("REGISTER")); request->cseq = cseq; /*the Max-Forward header */ osip_message_set_max_forwards(request, "5"); /* a UA should start a request with 70 */ /* the via header */ char tmp[200]; unsigned int branch; branch=osip_build_random_number(); snprintf(tmp, 200, "SIP/2.0/%s %s:%s;rport;branch=z9hG4bK%u", "UDP", localip, localport, branch ); osip_message_set_via(request, tmp); /* the UA header */ osip_message_set_user_agent(request, user_agent); /* the expires header */ char exp[10]; /* MUST never be ouside 1 and 3600 */ snprintf(exp, 9, "%i", expires); osip_message_set_expires(request, exp); osip_message_set_content_length(request, "0"); /*** then must wake up osip ***/ i = osip_transaction_init(&transaction, NICT, adosip->j_osip, request); if (i!=0) goto si2perror2 ; //jr->r_last_tr = transaction; /* send REGISTER */ i = osip_message_to_str(request, &message1, &len); LogStream("SEND======================================>>\n") ; LogStream(message1) ; if(message1) osip_free(message1) ; // printf("SEND======================================>>\n") ; // printf(message1) ; sipevent = osip_new_outgoing_sipmessage(request); sipevent->transactionid = transaction->transactionid; osip_message_force_update(request); osip_transaction_add_event(transaction, sipevent); adosip->ThreadWakeUp(); return 0; si2perror1: if(request != NULL)osip_message_free(request); return -1 ; si2perror2: if(request != NULL)osip_message_free(request); return -1; }
int Node::SndUserRegisterRequest(REG_TYPE type, uinfo_t *user_info, const char *registrar, int expires) { char *message1; unsigned int len = 0; osip_message_t *request; osip_event_t *sipevent; osip_transaction_t *transaction; osip_uri_t *uri; char *tmp_uri; int i; i=osip_message_init(&request); if(i!=0) goto si2perror1; osip_message_set_method(request,strdup("REGISTER")); osip_message_set_version(request,strdup("SIP/2.0")); osip_message_set_status_code(request,0); osip_message_set_reason_phrase(request,NULL); i=osip_uri_init(&uri); if(i!=0) goto si2perror2; i=osip_uri_parse(uri,osip_strdup(registrar)); osip_message_set_uri(request,uri); //*set to,from and header if(type==USER_REGISTRATION) { char *dest1; char *dest2; osip_uri_to_str(user_info->aor->uri,&dest1); i=osip_message_set_to(request,dest1); i=osip_message_set_from(request,dest1); if(dest1) osip_free(dest1) ; osip_from_param_add (request->from, osip_strdup ("user"), osip_strdup("user_registration")); osip_contact_to_str(user_info->bindings->contact,&dest2); i=osip_message_set_contact(request,osip_strdup(dest2)); if(dest2) osip_free(dest2) ; } if(type == RED_REGISTER) { char *dest1; char *dest2; osip_uri_to_str(user_info->aor->uri,&dest1); i=osip_message_set_to(request,dest1); i=osip_message_set_from(request,dest1); if(dest1) osip_free(dest1) ; osip_from_param_add (request->from, osip_strdup ("user"), osip_strdup("red_register")); osip_contact_to_str(user_info->bindings->contact,&dest2); i=osip_message_set_contact(request,osip_strdup(dest2)); if(dest2) osip_free(dest2) ; } if(type==TRANSFER_REGISTRATION) { char *dest1; char *dest2; //string tmp_uri; osip_uri_to_str(user_info->aor->uri,&dest1); osip_message_set_to(request,dest1); if(dest1) osip_free(dest1) ; tmp_uri = ChordId2Uri(chordId,false); osip_message_set_from(request,tmp_uri); osip_from_param_add (request->from, osip_strdup ("user"), osip_strdup("transfer_registration")); if(tmp_uri) osip_free(tmp_uri) ; osip_contact_to_str(user_info->bindings->contact,&dest2); osip_message_set_contact(request,dest2); if(dest2) osip_free(dest2) ; } if(type==THIRD_PARTY) { //todo } //---set call_id and cseq osip_call_id_t *callid; osip_cseq_t *cseq; char *num; char *cidrand; char *register_callid_number ; //* call-id is always the same for REGISTRATIONS i = osip_call_id_init(&callid); if (i!=0) goto si2perror2; cidrand = osip_strdup("BF9598C48B184EBBAFADFE527EED8186") ; osip_call_id_set_number(callid, cidrand); register_callid_number = cidrand; osip_call_id_set_host(callid, osip_strdup("SI2P.COM")); request->call_id = callid; //cseq i = osip_cseq_init(&cseq); if (i!=0) goto si2perror2 ; num = osip_strdup("1"); osip_cseq_set_number(cseq, num); osip_cseq_set_method(cseq, osip_strdup("REGISTER")); request->cseq = cseq; //*the Max-Forward header osip_message_set_max_forwards(request, "5"); //* a UA should start a request with 70 //* the via header char tmp[200]; snprintf(tmp, 200, "SIP/2.0/%s %s:%s;rport;branch=z9hG4bK%u", "UDP", localip, localport, via_branch_new_random() ); osip_message_set_via(request, tmp); //* the UA header osip_message_set_user_agent(request, user_agent); //* the expires header char exp[10]; //* MUST never be ouside 1 and 3600 snprintf(exp, 9, "%i", expires); osip_message_set_expires(request, exp); osip_message_set_content_length(request, "0"); //*** then must wake up osip i = osip_transaction_init(&transaction, NICT, adosip->j_osip, request); if (i!=0) goto si2perror3 ; //* send REGISTER i = osip_message_to_str(request, &message1, &len); LogStream("SEND======================================>>\n") ; LogStream(message1) ; if(message1) osip_free(message1) ; // printf("SEND======================================>>\n") ; // printf(message1) ; sipevent = osip_new_outgoing_sipmessage(request); sipevent->transactionid = transaction->transactionid; osip_message_force_update(request); osip_transaction_add_event(transaction, sipevent); adosip->ThreadWakeUp(); return 0; si2perror1: return -1; si2perror2: if(request!=NULL) osip_message_free(request); return -1; si2perror3: if(transaction!=NULL) osip_message_free(request); return -1; }
int eXosip_answer_invite_2xx_with_body(eXosip_call_t *jc, eXosip_dialog_t *jd, int code,const char*bodytype, const char*body) { osip_event_t *evt_answer; osip_message_t *response; int i; char *size; osip_transaction_t *tr; tr = eXosip_find_last_inc_invite(jc, jd); if (tr==NULL || tr->orig_request==NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot find transaction to answer\n")); return -1; } if (jd!=NULL && jd->d_dialog==NULL) { /* element previously removed */ OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot answer this closed transaction\n")); return -1; } /* is the transaction already answered? */ if (tr->state==IST_COMPLETED || tr->state==IST_CONFIRMED || tr->state==IST_TERMINATED) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: transaction already answered\n")); return -1; } if (jd==NULL) i = _eXosip_build_response_default(&response, NULL, code, tr->orig_request); else i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request); if (i!=0) { OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"ERROR: Could not create response for invite\n")); code = 500; /* ? which code to use? */ return -1; } if (code==488) { osip_message_set_content_length(response, "0"); /* TODO: send message to transaction layer */ evt_answer = osip_new_outgoing_sipmessage(response); evt_answer->transactionid = tr->transactionid; osip_transaction_add_event(tr, evt_answer); __eXosip_wakeup(); return 0; } if ( ! body ) { fprintf(stderr, "%s,%d: body is NULL\n", __FILE__, __LINE__); return -1; } i = osip_message_set_body(response, body, strlen(body)); if (i!=0) { goto g2atii_error_1; } size = (char *) osip_malloc(6*sizeof(char)); sprintf(size,"%i",strlen(body)); i = osip_message_set_content_length(response, size); osip_free(size); if (i!=0) goto g2atii_error_1; i = owsip_message_set_header(response, "content-type", bodytype); if (i!=0) goto g2atii_error_1; /* request that estabish a dialog: */ /* 12.1.1 UAS Behavior */ i = complete_answer_that_establish_a_dialog(response, tr->orig_request); if (i!=0) goto g2atii_error_1; /* ?? */ /* THIS RESPONSE MUST BE SENT RELIABILY until the final ACK is received !! */ /* this response must be stored at the upper layer!!! (it will be destroyed*/ /* right after being sent! */ if (jd==NULL) { i = eXosip_dialog_init_as_uas(&jd, owsip_transaction_account_get (tr), tr->orig_request, response); if (i!=0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot create dialog!\n")); return -1; } ADD_ELEMENT(jc->c_dialogs, jd); } eXosip_dialog_set_200ok(jd, response); evt_answer = osip_new_outgoing_sipmessage(response); evt_answer->transactionid = tr->transactionid; osip_transaction_add_event(tr, evt_answer); osip_dialog_set_state(jd->d_dialog, DIALOG_CONFIRMED); __eXosip_wakeup(); return 0; g2atii_error_1: osip_message_free(response); return -1; }
int eXosip_answer_options_2xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code) { osip_event_t *evt_answer; osip_transaction_t *tr; osip_message_t *response; sdp_message_t *sdp; char *body; char size[10]; int i; tr = eXosip_find_last_inc_options(jc, jd); if (tr==NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot find transaction to answer")); return -1; } osip_negotiation_sdp_build_offer(eXosip.osip_negotiation, NULL, &sdp, "10400", NULL); if (sdp==NULL) { return -1; } if (jd!=NULL) { i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request); } else { i = _eXosip_build_response_default(&response, NULL, code, tr->orig_request); } if (i!=0) { OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"ERROR: Could not create response for options\n")); sdp_message_free(sdp); /* not used */ return -1; } i = sdp_message_to_str(sdp, &body); sdp_message_free(sdp); if ( ( i!=0 ) || ( ! body ) ) { osip_message_free(response); return -1; } i = osip_message_set_body(response, body, strlen(body)); if (i!=0) { osip_message_free(response); return -1; } #ifdef __APPLE_CC__ snprintf(size, 9,"%li",strlen(body)); #else snprintf(size, 9,"%i",strlen(body)); #endif i = osip_message_set_content_length(response, size); if (i!=0) { osip_free(body); osip_message_free(response); return -1; } osip_free(body); i = osip_message_set_content_type(response, "application/sdp"); if (i!=0) { osip_message_free(response); return -1; } evt_answer = osip_new_outgoing_sipmessage(response); evt_answer->transactionid = tr->transactionid; osip_transaction_add_event(tr, evt_answer); __eXosip_wakeup(); return 0; }
static char * generating_no_sdp_answer(eXosip_call_t *jc, eXosip_dialog_t *jd, osip_message_t *orig_request, char *local_sdp_port, char *local_video_port) { sdp_message_t *local_sdp = NULL; char *local_body = NULL; char *size; int i; jc->c_ack_sdp = 1; if(osip_negotiation_sdp_build_offer(eXosip.osip_negotiation, NULL, &local_sdp, local_sdp_port, local_video_port) != 0) return NULL; if (local_sdp!=NULL) { int pos=0; while (!sdp_message_endof_media (local_sdp, pos)) { int k = 0; char *tmp = sdp_message_m_media_get (local_sdp, pos); if (0 == strncmp (tmp, "audio", 5)) { char *payload = NULL; do { payload = sdp_message_m_payload_get (local_sdp, pos, k); if (payload == NULL) { } else if (0==strncmp("110",payload,3)) { sdp_message_a_attribute_add (local_sdp, pos, osip_strdup ("AS"), osip_strdup ("110 20")); } else if (0==strncmp("111",payload,3)) { sdp_message_a_attribute_add (local_sdp, pos, osip_strdup ("AS"), osip_strdup ("111 20")); } k++; } while (payload != NULL); } pos++; } } i = sdp_message_to_str(local_sdp, &local_body); if (local_body!=NULL) { size= (char *)osip_malloc(7*sizeof(char)); #ifdef __APPLE_CC__ sprintf(size,"%li",strlen(local_body)); #else sprintf(size,"%i",strlen(local_body)); #endif osip_message_set_content_length(orig_request, size); osip_free(size); osip_message_set_body(orig_request, local_body, strlen(local_body)); osip_message_set_content_type(orig_request, "application/sdp"); } else osip_message_set_content_length(orig_request, "0"); osip_negotiation_ctx_set_local_sdp(jc->c_ctx, local_sdp); OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO3,NULL,"200 OK w/ SDP (RESPONSE TO INVITE w/ NO SDP)=\n%s\n", local_body)); return local_body; }
int _eXosip_default_answer_invite_1xx (eXosip_call_t * jc, eXosip_dialog_t * jd, int code) { osip_event_t *evt_answer; osip_message_t *response; int i; osip_transaction_t *tr; tr = eXosip_find_last_inc_invite (jc, jd); if (tr == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot find transaction to answer")); return -1; } /* is the transaction already answered? */ if (tr->state == IST_COMPLETED || tr->state == IST_CONFIRMED || tr->state == IST_TERMINATED) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: transaction already answered\n")); return -1; } if (jd == NULL) i = _eXosip_build_response_default (&response, NULL, code, tr->orig_request); else i = _eXosip_build_response_default (&response, jd->d_dialog, code, tr->orig_request); if (i != 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "ERROR: Could not create response for invite\n")); return -2; } osip_message_set_content_length (response, "0"); /* send message to transaction layer */ if (code > 100) { /* request that estabish a dialog: */ /* 12.1.1 UAS Behavior */ i = complete_answer_that_establish_a_dialog (response, tr->orig_request); if (jd == NULL) { i = eXosip_dialog_init_as_uas (&jd, tr->orig_request, response); if (i != 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot create dialog!\n")); } else { ADD_ELEMENT (jc->c_dialogs, jd); } } } evt_answer = osip_new_outgoing_sipmessage (response); evt_answer->transactionid = tr->transactionid; osip_transaction_add_event (tr, evt_answer); __eXosip_wakeup (); return 0; }
int eXosip_answer_invite_2xx(eXosip_call_t *jc, eXosip_dialog_t *jd, int code, char *local_sdp_port, char *ctct, char *local_video_port, char *public_sdp_port, char *public_video_port) { osip_event_t *evt_answer; osip_message_t *response; int i; char *size; char *body = NULL; osip_transaction_t *tr; tr = eXosip_find_last_inc_invite(jc, jd); if (tr==NULL || tr->orig_request==NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot find transaction to answer\n")); return -1; } if (jd!=NULL && jd->d_dialog==NULL) { /* element previously removed */ OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot answer this closed transaction\n")); return -1; } /* is the transaction already answered? */ if (tr->state==IST_COMPLETED || tr->state==IST_CONFIRMED || tr->state==IST_TERMINATED) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: transaction already answered\n")); return -1; } /* WE SHOULD LOOK FOR A SDP PACKET!! */ if(NULL != osip_list_get(&tr->orig_request->bodies,0)) { body = generating_sdp_answer(tr->orig_request, jc->c_ctx); if (body==NULL) code = 488; /* bad sdp */ } else { if(local_sdp_port==NULL && local_video_port == NULL) code = 488; /* session description in the request is not acceptable. */ else /* body is NULL (contains no SDP), generate a response to INVITE w/ no SDP */ body = generating_no_sdp_answer(jc, jd, tr->orig_request, public_sdp_port ? public_sdp_port : local_sdp_port , public_video_port ? public_video_port : local_video_port); } if (jd==NULL) i = _eXosip_build_response_default(&response, NULL, code, tr->orig_request); else i = _eXosip_build_response_default(&response, jd->d_dialog, code, tr->orig_request); if (i!=0) { OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL,"ERROR: Could not create response for invite\n")); code = 500; /* ? which code to use? */ osip_free(body); /* not used */ return -1; } if (code==488) { osip_message_set_content_length(response, "0"); /* TODO: send message to transaction layer */ osip_free(body); evt_answer = osip_new_outgoing_sipmessage(response); evt_answer->transactionid = tr->transactionid; osip_transaction_add_event(tr, evt_answer); __eXosip_wakeup(); return 0; } if ( ! body ) { fprintf(stderr, "%s,%d: body is NULL\n", __FILE__, __LINE__); return -1; } i = osip_message_set_body(response, body, strlen(body)); if (i!=0) { goto g2atii_error_1; } size = (char *) osip_malloc(6*sizeof(char)); #ifdef __APPLE_CC__ sprintf(size,"%li",strlen(body)); #else sprintf(size,"%i",strlen(body)); #endif i = osip_message_set_content_length(response, size); osip_free(size); if (i!=0) goto g2atii_error_1; i = osip_message_set_content_type(response, "application/sdp"); if (i!=0) goto g2atii_error_1; /* request that estabish a dialog: */ /* 12.1.1 UAS Behavior */ { i = complete_answer_that_establish_a_dialog2(response, tr->orig_request, ctct); if (i!=0) goto g2atii_error_1;; /* ?? */ } osip_free(body); /* THIS RESPONSE MUST BE SENT RELIABILY until the final ACK is received !! */ /* this response must be stored at the upper layer!!! (it will be destroyed*/ /* right after being sent! */ if (jd==NULL) { i = eXosip_dialog_init_as_uas(&jd, owsip_transaction_account_get (tr), tr->orig_request, response); if (i!=0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot create dialog!\n")); return -1; } ADD_ELEMENT(jc->c_dialogs, jd); } eXosip_dialog_set_200ok(jd, response); evt_answer = osip_new_outgoing_sipmessage(response); evt_answer->transactionid = tr->transactionid; osip_transaction_add_event(tr, evt_answer); osip_dialog_set_state(jd->d_dialog, DIALOG_CONFIRMED); __eXosip_wakeup(); return 0; g2atii_error_1: osip_free(body); osip_message_free(response); return -1; }
int generating_register (eXosip_reg_t * jreg, osip_message_t ** reg, char *transport, char *from, char *proxy, char *contact, int expires) { int i; char locip[65]; char firewall_ip[65]; char firewall_port[10]; if (eXosip.eXtl == NULL) return OSIP_NO_NETWORK; if (eXosip.eXtl->tl_get_masquerade_contact != NULL) { eXosip.eXtl->tl_get_masquerade_contact (firewall_ip, sizeof (firewall_ip), firewall_port, sizeof (firewall_port)); } i = generating_request_out_of_dialog (reg, "REGISTER", NULL, transport, from, proxy); if (i != 0) return i; memset (locip, '\0', sizeof (locip)); eXosip_guess_ip_for_via (eXosip.eXtl->proto_family, locip, 49); if (locip[0] == '\0') { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: no default interface defined\n")); osip_message_free (*reg); *reg = NULL; return OSIP_NO_NETWORK; } if (contact == NULL) { osip_contact_t *new_contact = NULL; osip_uri_t *new_contact_url = NULL; i = osip_contact_init (&new_contact); if (i == 0) i = osip_uri_init (&new_contact_url); new_contact->url = new_contact_url; if (i == 0 && (*reg)->from != NULL && (*reg)->from->url != NULL && (*reg)->from->url->username != NULL) { new_contact_url->username = osip_strdup ((*reg)->from->url->username); } if (i == 0 && (*reg)->from != NULL && (*reg)->from->url != NULL) { /* serach for correct ip */ if (firewall_ip[0] != '\0') { char *c_address = (*reg)->req_uri->host; struct addrinfo *addrinfo; struct __eXosip_sockaddr addr; i = eXosip_get_addrinfo (&addrinfo, (*reg)->req_uri->host, 5060, IPPROTO_UDP); if (i == 0) { memcpy (&addr, addrinfo->ai_addr, addrinfo->ai_addrlen); eXosip_freeaddrinfo (addrinfo); c_address = inet_ntoa (((struct sockaddr_in *) &addr)->sin_addr); OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "eXosip: here is the resolved destination host=%s\n", c_address)); } if (eXosip_is_public_address (c_address)) { new_contact_url->host = osip_strdup (firewall_ip); new_contact_url->port = osip_strdup (firewall_port); } else { new_contact_url->host = osip_strdup (locip); new_contact_url->port = osip_strdup (firewall_port); } } else { new_contact_url->host = osip_strdup (locip); new_contact_url->port = osip_strdup (firewall_port); } if (transport != NULL && osip_strcasecmp (transport, "UDP") != 0) { osip_uri_uparam_add (new_contact_url, osip_strdup ("transport"), osip_strdup (transport)); } if (jreg->r_line[0] != '\0') { osip_uri_uparam_add (new_contact_url, osip_strdup ("line"), osip_strdup (jreg->r_line)); } osip_list_add (&(*reg)->contacts, new_contact, -1); } } else { osip_message_set_contact (*reg, contact); } { char exp[10]; /* MUST never be ouside 1 and 3600 */ snprintf (exp, 9, "%i", expires); osip_message_set_expires (*reg, exp); } osip_message_set_content_length (*reg, "0"); return OSIP_SUCCESS; }
int uas_invite(sipua_uas_t *sipuas, const char *to, sipua_call_t* call_info, char* sdp_body, int sdp_bytes) { eXosipua_t *jua = (eXosipua_t*)sipuas; osip_message_t *invite; char sdp_size[8]; char* proxy = NULL; int ret; char *from = call_info->user_prof->regname; /* OSIP_TRACE (osip_trace(__FILE__, __LINE__, OSIP_INFO2, NULL, "To: |%s|\n", to)); */ if (0!=jua_check_url(from)) { jua_log(("uas_call: illigal sip id!\n")); return UA_FAIL; } if (0!=jua_check_url(to)) { jua_log(("uas_invite: illigal sip destination\n")); return UA_FAIL; } if(jua->sipuas.proxy[0]!='\0') { proxy = uas_check_route(jua->sipuas.proxy); } #if 0 else { proxy = uas_check_route(call_info->user_prof->registrar); } #endif sprintf(sdp_size,"%i", sdp_bytes); printf("uas_invite: [%s] from %s to %s, proxy[%s]\n", call_info->subject, from, to, proxy); printf("\n-------Initiate SDP [%d bytes]--------\n", sdp_bytes); printf("Callid[%s]\n", call_info->setid.id); printf("----------------------------------------\n"); printf("%s", sdp_body); printf("----------------------------------------\n"); if (eXosip_build_initial_invite(&invite, to, from, proxy, call_info->subject) != 0) return UA_FAIL; /* sdp content of the call */ osip_message_set_content_type(invite, "application/sdp"); osip_message_set_content_length(invite, sdp_size); osip_message_set_body(invite, sdp_body, sdp_bytes); eXosip_lock(); ret = eXosip_initiate_call(invite, call_info, NULL/*negotiation_reference*/, NULL/*local_audio_port*/); eXosip_unlock(); if(proxy) osip_free(proxy); /*When to free it ??? osip_message_free(invite); */ return ret; }
int Node::SndUserRegisterRequest(char *aor ,const char *requri) { char *message1; unsigned int len = 0; osip_transaction_t *transaction; osip_event_t *sipevent; osip_message_t *request; int i; i = osip_message_init(&request); if (i!=0) goto si2perror1; /* prepare the request-line */ osip_message_set_method(request, osip_strdup("REGISTER")); osip_message_set_version(request, osip_strdup("SIP/2.0")); osip_message_set_status_code(request, 0); osip_message_set_reason_phrase(request, NULL); //requset uri osip_uri_t *uri; i=osip_uri_init(&uri); if (i!=0) goto si2perror2; i=osip_uri_parse(uri, requri); if (i!=0) goto si2perror2; osip_message_set_uri(request , uri) ; //to from ,no contact osip_message_set_to(request,aor); osip_message_set_from(request,aor); osip_from_param_add(request->from,osip_strdup("user"),osip_strdup("user_query")); //---set call_id and cseq osip_call_id_t *callid; osip_cseq_t *cseq; char *num; char *cidrand; char *register_callid_number ; /* call-id is always the same for REGISTRATIONS */ i = osip_call_id_init(&callid); if (i!=0) goto si2perror2; cidrand = osip_strdup("BF9598C48B184EBBAFADFE527EED8186") ; osip_call_id_set_number(callid, cidrand); register_callid_number = cidrand; osip_call_id_set_host(callid, osip_strdup("SI2P.COM")); request->call_id = callid; //cseq i = osip_cseq_init(&cseq); if (i!=0) goto si2perror2 ; num = osip_strdup("1"); osip_cseq_set_number(cseq, num); osip_cseq_set_method(cseq, osip_strdup("REGISTER")); request->cseq = cseq; /*the Max-Forward header */ osip_message_set_max_forwards(request, "5"); /* a UA should start a request with 70 */ /* the via header */ char tmp[200]; unsigned int branch; branch=osip_build_random_number(); snprintf(tmp, 200, "SIP/2.0/%s %s:%s;rport;branch=z9hG4bK%u", "UDP", localip, localport, branch ); osip_message_set_via(request, tmp); /* the UA header */ osip_message_set_user_agent(request, user_agent); /* the expires header */ char exp[10]; /* MUST never be ouside 1 and 3600 */ snprintf(exp, 9, "%i", expires); osip_message_set_expires(request, exp); osip_message_set_content_length(request, "0"); /*** then must wake up osip ***/ i = osip_transaction_init(&transaction, NICT, adosip->j_osip, request); if (i!=0) goto si2perror2 ; /* send REGISTER */ i = osip_message_to_str(request, &message1, &len); LogStream("SEND======================================>>\n") ; LogStream(message1) ; if(message1) osip_free(message1) ; sipevent = osip_new_outgoing_sipmessage(request); sipevent->transactionid = transaction->transactionid; osip_message_force_update(request); osip_transaction_add_event(transaction, sipevent); adosip->ThreadWakeUp(); return 0; si2perror1: if(request != NULL)osip_message_free(request); return -1 ; si2perror2: if(request != NULL)osip_message_free(request); return -1; return 0; }
/* osip_message_t *sip is filled while analysing buf */ static int _osip_message_parse (osip_message_t * sip, const char *buf, size_t length, int sipfrag) { int i; const char *next_header_index; char *tmp; char *beg; tmp = osip_malloc (length + 2); if (tmp == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Could not allocate memory.\n")); return OSIP_NOMEM; } beg = tmp; memcpy (tmp, buf, length); /* may contain binary data */ tmp[length] = '\0'; /* skip initial \r\n */ while (tmp[0] == '\r' || tmp[0] == '\n') tmp++; osip_util_replace_all_lws (tmp); /* parse request or status line */ i = __osip_message_startline_parse (sip, tmp, &next_header_index); if (i != 0 && !sipfrag) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "Could not parse start line of message.\n")); osip_free (beg); return i; } tmp = (char *) next_header_index; /* parse headers */ i = msg_headers_parse (sip, tmp, &next_header_index); if (i != 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "error in msg_headers_parse()\n")); osip_free (beg); return i; } tmp = (char *) next_header_index; if (sip->content_length != NULL && sip->content_length->value == NULL) { /* empty content_length header */ osip_content_length_free(sip->content_length); sip->content_length=NULL; } if (sip->content_length != NULL && sip->content_length->value != NULL && atoi(sip->content_length->value) >0) { /* body exist */ } else if (sip->content_length == NULL && '\r' == next_header_index[0] && '\n' == next_header_index[1] && length - (tmp - beg) - (2) >0) { /* body exist */ } else if (sip->content_length == NULL && '\n' == next_header_index[0] && length - (tmp - beg) - (1) >0) { /* body exist */ } else { if (sip->content_length == NULL) osip_message_set_content_length (sip, "0"); osip_free (beg); return OSIP_SUCCESS; /* no body found */ } i = msg_osip_body_parse (sip, tmp, &next_header_index, length - (tmp - beg)); osip_free (beg); if (i != 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "error in msg_osip_body_parse()\n")); return i; } /* this is mandatory in the oSIP stack */ if (sip->content_length == NULL) osip_message_set_content_length (sip, "0"); return OSIP_SUCCESS; }
/* * PROXY_REWRITE_INVITATION_BODY * * rewrites the outgoing INVITATION request or response packet * * RETURNS * STS_SUCCESS on success * STS_FAILURE on error */ int proxy_rewrite_invitation_body(osip_message_t *mymsg, int direction){ osip_body_t *body; sdp_message_t *sdp; struct in_addr map_addr, addr_sess, addr_media, outside_addr, inside_addr; int sts; char *bodybuff; int bodybuflen; char clen[8]; /* content length: probably never more than 7 digits !*/ int map_port, msg_port; int media_stream_no; sdp_connection_t *sdp_conn; sdp_media_t *sdp_med; int rtp_direction=0; int have_c_media=0; if (configuration.rtp_proxy_enable == 0) return STS_SUCCESS; /* * get SDP structure */ sts = osip_message_get_body(mymsg, 0, &body); if (sts != 0) { #if 0 if ((MSG_IS_RESPONSE_FOR(mymsg,"INVITE")) && (MSG_IS_STATUS_1XX(mymsg))) { /* 1xx responses *MAY* contain SDP data */ DEBUGC(DBCLASS_PROXY, "rewrite_invitation_body: " "no body found in message"); return STS_SUCCESS; } else { /* INVITE request and 200 response *MUST* contain SDP data */ ERROR("rewrite_invitation_body: no body found in message"); return STS_FAILURE; } #else DEBUGC(DBCLASS_PROXY, "rewrite_invitation_body: " "no body found in message"); return STS_SUCCESS; #endif } sts = sip_body_to_str(body, &bodybuff, &bodybuflen); if (sts != 0) { ERROR("rewrite_invitation_body: unable to sip_body_to_str"); } sts = sdp_message_init(&sdp); sts = sdp_message_parse (sdp, bodybuff); if (sts != 0) { ERROR("rewrite_invitation_body: unable to sdp_message_parse body"); DUMP_BUFFER(-1, bodybuff, bodybuflen); osip_free(bodybuff); sdp_message_free(sdp); return STS_FAILURE; } osip_free(bodybuff); if (configuration.debuglevel) { /* just dump the buffer */ char *tmp, *tmp2; int tmplen; sts = osip_message_get_body(mymsg, 0, &body); sts = sip_body_to_str(body, &tmp, &tmplen); osip_content_length_to_str(mymsg->content_length, &tmp2); DEBUG("Body before rewrite (clen=%s, strlen=%i):\n%s\n----", tmp2, tmplen, tmp); osip_free(tmp); osip_free(tmp2); } /* * RTP proxy: get ready and start forwarding * start forwarding for each media stream ('m=' item in SIP message) */ /* get outbound address */ if (get_interface_ip(IF_OUTBOUND, &outside_addr) != STS_SUCCESS) { sdp_message_free(sdp); return STS_FAILURE; } /* get inbound address */ if (get_interface_ip(IF_INBOUND, &inside_addr) != STS_SUCCESS) { sdp_message_free(sdp); return STS_FAILURE; } /* figure out what address to use for RTP masquerading */ if (MSG_IS_REQUEST(mymsg)) { if (direction == DIR_INCOMING) { memcpy(&map_addr, &inside_addr, sizeof (map_addr)); rtp_direction = DIR_OUTGOING; } else { memcpy(&map_addr, &outside_addr, sizeof (map_addr)); rtp_direction = DIR_INCOMING; } } else /* MSG_IS_REPONSE(mymsg) */ { if (direction == DIR_INCOMING) { memcpy(&map_addr, &inside_addr, sizeof (map_addr)); rtp_direction = DIR_OUTGOING; } else { memcpy(&map_addr, &outside_addr, sizeof (map_addr)); rtp_direction = DIR_INCOMING; } } DEBUGC(DBCLASS_PROXY, "proxy_rewrite_invitation_body: SIP[%s %s] RTP[%s %s]", MSG_IS_REQUEST(mymsg)? "RQ" : "RS", (direction==DIR_INCOMING)? "IN" : "OUT", (rtp_direction==DIR_INCOMING)? "IN" : "OUT", utils_inet_ntoa(map_addr)); /* * first, check presence of a 'c=' item on session level */ if (sdp->c_connection==NULL || sdp->c_connection->c_addr==NULL) { /* * No 'c=' on session level, search on media level now * * According to RFC2327, ALL media description must * include a 'c=' item now: */ media_stream_no=0; while (!sdp_message_endof_media(sdp, media_stream_no)) { /* check if n'th media stream is present */ if (sdp_message_c_addr_get(sdp, media_stream_no, 0) == NULL) { ERROR("SDP: have no 'c=' on session level and neither " "on media level (media=%i)",media_stream_no); sdp_message_free(sdp); return STS_FAILURE; } media_stream_no++; } /* while */ } /* Required 'c=' items ARE present */ /* * rewrite 'c=' item on session level if present and not yet done. * remember the original address in addr_sess */ memset(&addr_sess, 0, sizeof(addr_sess)); if (sdp->c_connection && sdp->c_connection->c_addr) { sts = get_ip_by_host(sdp->c_connection->c_addr, &addr_sess); if (sts == STS_FAILURE) { ERROR("SDP: cannot resolve session 'c=' host [%s]", sdp->c_connection->c_addr); sdp_message_free(sdp); return STS_FAILURE; } /* * Rewrite * an IP address of 0.0.0.0 means *MUTE*, don't rewrite such */ if (strcmp(sdp->c_connection->c_addr, "0.0.0.0") != 0) { osip_free(sdp->c_connection->c_addr); sdp->c_connection->c_addr=osip_malloc(HOSTNAME_SIZE); sprintf(sdp->c_connection->c_addr, "%s", utils_inet_ntoa(map_addr)); } else { /* 0.0.0.0 - don't rewrite */ DEBUGC(DBCLASS_PROXY, "proxy_rewrite_invitation_body: " "got a MUTE c= record (on session level - legal?)"); } } /* * rewrite 'o=' item (originator) on session level if present. */ if (sdp->o_addrtype && sdp->o_addr) { if (strcmp(sdp->o_addrtype, "IP4") != 0) { ERROR("got IP6 in SDP originator - not yet suported by siproxd"); sdp_message_free(sdp); return STS_FAILURE; } osip_free(sdp->o_addr); sdp->o_addr=osip_malloc(HOSTNAME_SIZE); sprintf(sdp->o_addr, "%s", utils_inet_ntoa(map_addr)); } /* * loop through all media descritions, * start RTP proxy and rewrite them */ for (media_stream_no=0;;media_stream_no++) { /* check if n'th media stream is present */ if (sdp_message_m_port_get(sdp, media_stream_no) == NULL) break; /* * check if a 'c=' item is present in this media description, * if so -> rewrite it */ memset(&addr_media, 0, sizeof(addr_media)); have_c_media=0; sdp_conn=sdp_message_connection_get(sdp, media_stream_no, 0); if (sdp_conn && sdp_conn->c_addr) { if (strcmp(sdp_conn->c_addr, "0.0.0.0") != 0) { sts = get_ip_by_host(sdp_conn->c_addr, &addr_media); have_c_media=1; /* have a valid address */ osip_free(sdp_conn->c_addr); sdp_conn->c_addr=osip_malloc(HOSTNAME_SIZE); sprintf(sdp_conn->c_addr, "%s", utils_inet_ntoa(map_addr)); } else { /* 0.0.0.0 - don't rewrite */ DEBUGC(DBCLASS_PROXY, "proxy_rewrite_invitation_body: got a " "MUTE c= record (media level)"); } } /* start an RTP proxying stream */ if (sdp_message_m_port_get(sdp, media_stream_no)) { msg_port=atoi(sdp_message_m_port_get(sdp, media_stream_no)); if (msg_port > 0) { osip_uri_t *cont_url = NULL; char *client_id=NULL; /* try to get some additional UA specific unique ID. * Try: * 1) User part of Contact header * 2) Host part of Contact header (will be different * between internal UA and external UA) */ if (!osip_list_eol(mymsg->contacts, 0)) cont_url = ((osip_contact_t*)(mymsg->contacts->node->element))->url; if (cont_url) { client_id=cont_url->username; if (client_id == NULL) client_id=cont_url->host; } /* * do we have a 'c=' item on media level? * if not, use the same as on session level */ if (have_c_media == 0) { memcpy(&addr_media, &addr_sess, sizeof(addr_sess)); } /* * Am I running in front of the routing device? Then I cannot * use the external IP to bind a listen socket to, so force * the use of my inbound IP for listening. */ if ((rtp_direction == DIR_INCOMING) && (configuration.outbound_host) && (strcmp(configuration.outbound_host, "")!=0)) { DEBUGC(DBCLASS_PROXY, "proxy_rewrite_invitation_body: " "in-front-of-NAT-Router"); memcpy(&map_addr, &inside_addr, sizeof (map_addr)); } sts = rtp_start_fwd(osip_message_get_call_id(mymsg), client_id, rtp_direction, media_stream_no, map_addr, &map_port, addr_media, msg_port); if (sts == STS_SUCCESS) { /* and rewrite the port */ sdp_med=osip_list_get(sdp->m_medias, media_stream_no); if (sdp_med && sdp_med->m_port) { osip_free(sdp_med->m_port); sdp_med->m_port=osip_malloc(8); /* 5 digits, \0 + align */ sprintf(sdp_med->m_port, "%i", map_port); DEBUGC(DBCLASS_PROXY, "proxy_rewrite_invitation_body: " "m= rewrote port to [%i]",map_port); } else { ERROR("rewriting port in m= failed sdp_med=%p, " "m_number_of_port=%p", sdp_med, sdp_med->m_port); } } /* sts == success */ } /* if msg_port > 0 */ } else { /* no port defined - skip entry */ WARN("no port defined in m=(media) stream_no=%i", media_stream_no); continue; } } /* for media_stream_no */ /* remove old body */ sts = osip_list_remove(mymsg->bodies, 0); osip_body_free(body); /* dump new body */ sdp_message_to_str(sdp, &bodybuff); bodybuflen=strlen(bodybuff); /* free sdp structure */ sdp_message_free(sdp); /* include new body */ sip_message_set_body(mymsg, bodybuff, bodybuflen); if (sts != 0) { ERROR("rewrite_invitation_body: unable to sip_message_set_body body"); } /* free content length resource and include new one*/ osip_content_length_free(mymsg->content_length); mymsg->content_length=NULL; sprintf(clen,"%i",bodybuflen); sts = osip_message_set_content_length(mymsg, clen); /* free old body */ osip_free(bodybuff); if (configuration.debuglevel) { /* just dump the buffer */ char *tmp, *tmp2; int tmplen; sts = osip_message_get_body(mymsg, 0, &body); sts = sip_body_to_str(body, &tmp, &tmplen); osip_content_length_to_str(mymsg->content_length, &tmp2); DEBUG("Body after rewrite (clen=%s, strlen=%i):\n%s\n----", tmp2, tmplen, tmp); osip_free(tmp); osip_free(tmp2); } return STS_SUCCESS; }
int bSipRegisterBuild(osip_message_t **regMsgPtrPtr) { static int gSeqNum = 1; int status; char *callidNumberStr = NULL; char *seqNumStr = NULL; osip_call_id_t *callidPtr; char temp[MESSAGE_ENTRY_MAX_LENGTH]; char sipPort[MESSAGE_ENTRY_MAX_LENGTH]; osip_cseq_t *cseqPtr; unsigned int number; osip_message_t *regMsgPtr; char expires[10]; if((status = osip_message_init(®MsgPtr)) != 0){ OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_BUG,NULL,"Can't init message!\n")); return -1; } osip_message_set_method(regMsgPtr, osip_strdup("OPTIONS")); osip_uri_init(&(regMsgPtr->req_uri)); if ( ( status = osip_uri_parse(regMsgPtr->req_uri, SIP_PROXY) ) != 0) { OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_BUG,NULL,"uri parse failed!\n")); osip_message_free(regMsgPtr); return -1; } osip_message_set_version(regMsgPtr, osip_strdup("SIP/2.0")); osip_message_set_status_code(regMsgPtr, 0); osip_message_set_reason_phrase(regMsgPtr, NULL); osip_message_set_to(regMsgPtr, SIP_TO); osip_message_set_from(regMsgPtr, SIP_FROM); if((status = osip_call_id_init(&callidPtr)) != 0 ){ OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_BUG,NULL,"call id failed!\n")); osip_message_free(regMsgPtr); return -1; } callidNumberStr = (char *)osip_malloc(MAX_ADDR_STR); number = osip_build_random_number(); sprintf(callidNumberStr,"%u",number); osip_call_id_set_number(callidPtr, callidNumberStr); osip_call_id_set_host(callidPtr, osip_strdup("10.1.1.63")); regMsgPtr->call_id = callidPtr; if((status = osip_cseq_init(&cseqPtr)) != 0 ){ OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_BUG,NULL,"seq init failed!\n")); osip_message_free(regMsgPtr); return -1; } gSeqNum++; seqNumStr = (char *)osip_malloc(MAX_ADDR_STR); sprintf(seqNumStr,"%i", gSeqNum); osip_cseq_set_number(cseqPtr, seqNumStr); osip_cseq_set_method(cseqPtr, osip_strdup("OPTIONS")); regMsgPtr->cseq = cseqPtr; osip_message_set_max_forwards(regMsgPtr, "70"); sprintf(sipPort, "%i", SIP_PORT); sprintf(temp, "SIP/2.0/%s %s;branch=z9hG4bK%u", "UDP",LOCAL_IP,osip_build_random_number() ); osip_message_set_via(regMsgPtr, temp); osip_message_set_contact(regMsgPtr, SIP_CONTACT); sprintf(expires, "%i", EXPIRES_TIME_INSECS); osip_message_set_expires(regMsgPtr, expires); osip_message_set_content_length(regMsgPtr, "0"); osip_message_set_user_agent(regMsgPtr, "TotalView 1.0"); AddSupportedMethods(regMsgPtr); *regMsgPtrPtr = regMsgPtr; return 0; }