int eXosip_register_build_initial_register_withqvalue(const char *from, const char *proxy, const char *contact, int expires, const char *qvalue, osip_message_t ** reg) { eXosip_reg_t *jr = NULL; int i; *reg = NULL; if (from == NULL || proxy == NULL) return OSIP_BADPARAMETER; #ifdef REJECT_DOUBLE_REGISTRATION /* Avoid adding the same registration info twice to prevent mem leaks */ for (jr = eXosip.j_reg; jr != NULL; jr = jr->next) { if (strcmp(jr->r_aor, from) == 0 && strcmp(jr->r_registrar, proxy) == 0) { REMOVE_ELEMENT(eXosip.j_reg, jr); eXosip_reg_free(jr); jr = NULL; break; } } #endif if (jr == NULL) { /* Add new registration info */ i = eXosip_reg_init(&jr, from, proxy, contact); if (i != 0) { OSIP_TRACE(osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot register! ")); return i; } ADD_ELEMENT(eXosip.j_reg, jr); } /* build register */ jr->r_reg_period = expires; if (jr->r_reg_period <= 0) /* too low */ jr->r_reg_period = 0; else if (jr->r_reg_period < 30) /* too low */ jr->r_reg_period = 30; if(qvalue) osip_strncpy(jr->r_qvalue, qvalue, sizeof(jr->r_qvalue)); i = _eXosip_register_build_register(jr, reg); if (i != 0) { OSIP_TRACE(osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot build REGISTER!\n")); *reg = NULL; return i; } return jr->r_id; }
int _eXosip_insubscription_answer_1xx (eXosip_notify_t * jn, 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_subscribe (jn, 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, 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 subscribe\n")); return -1; } 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")); } ADD_ELEMENT (jn->n_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_register_build_initial_register (const char *from, const char *proxy, const char *contact, int expires, osip_message_t ** reg) { eXosip_reg_t *jr = NULL; int i; *reg = NULL; /* Avoid adding the same registration info twice to prevent mem leaks */ for (jr = eXosip.j_reg; jr != NULL; jr = jr->next) { if (strcmp (jr->r_aor, from) == 0 && strcmp (jr->r_registrar, proxy) == 0) { REMOVE_ELEMENT (eXosip.j_reg, jr); eXosip_reg_free (jr); jr=NULL; break; } } if (jr == NULL) { /* Add new registration info */ i = eXosip_reg_init (&jr, from, proxy, contact); if (i != 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot register! ")); return i; } ADD_ELEMENT (eXosip.j_reg, jr); } /* build register */ jr->r_reg_period = expires; if (jr->r_reg_period <= 0) /* too low */ jr->r_reg_period = 0; else if (jr->r_reg_period < 100) /* too low */ jr->r_reg_period = 100; i = _eXosip_register_build_register (jr, reg); if (i != 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot build REGISTER!\n")); *reg = NULL; return i; } return jr->r_id; }
int eXosip_call_send_initial_invite (osip_message_t * invite) { eXosip_call_t *jc; osip_transaction_t *transaction; osip_event_t *sipevent; int i; if (invite == NULL) { osip_message_free (invite); return OSIP_BADPARAMETER; } i = eXosip_call_init (&jc); if (i != 0) { osip_message_free (invite); return i; } i = _eXosip_transaction_init (&transaction, ICT, eXosip.j_osip, invite); if (i != 0) { eXosip_call_free (jc); osip_message_free (invite); return i; } jc->c_out_tr = transaction; sipevent = osip_new_outgoing_sipmessage (invite); sipevent->transactionid = transaction->transactionid; #ifndef MINISIZE osip_transaction_set_your_instance (transaction, __eXosip_new_jinfo (jc, NULL, NULL, NULL)); #else osip_transaction_set_your_instance (transaction, __eXosip_new_jinfo (jc, NULL)); #endif osip_transaction_add_event (transaction, sipevent); jc->external_reference = NULL; ADD_ELEMENT (eXosip.j_calls, jc); eXosip_update (); /* fixed? */ __eXosip_wakeup (); return jc->c_id; }
int josua_config_addrealm(char *realm, char *username, char *password) { josua_realm_t *jr; jr = (josua_realm_t*) osip_malloc(sizeof(josua_realm_t)); snprintf(jr->realm, 100, realm); snprintf(jr->username, 100, username); snprintf(jr->password, 100, password); jr->next = NULL; jr->parent = NULL; ADD_ELEMENT(selected_config->realms, jr); return selected_config->id; }
int josua_config_create(char *identity, char *proxy, char *registrar) { josua_config_t *jc; static int id = 0; id++; jc = (josua_config_t*) osip_malloc(sizeof(josua_config_t)); jc->id = id; snprintf(jc->identity, 100, identity); snprintf(jc->proxy, 100, proxy); snprintf(jc->registrar, 100, registrar); jc->realms = NULL; jc->next = NULL; jc->parent = NULL; ADD_ELEMENT(josua_configs, jc); selected_config = jc; return jc->id; }
int eXosip_subscribe_send_initial_request (struct eXosip_t *excontext, osip_message_t * subscribe) { eXosip_subscribe_t *js = NULL; osip_transaction_t *transaction; osip_event_t *sipevent; int i; i = _eXosip_subscribe_init (&js); if (i != 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot subscribe.")); osip_message_free (subscribe); return i; } i = _eXosip_transaction_init (excontext, &transaction, NICT, excontext->j_osip, subscribe); if (i != 0) { _eXosip_subscribe_free (excontext, js); osip_message_free (subscribe); return i; } js->s_reg_period = 3600; _eXosip_subscribe_set_refresh_interval (js, subscribe); js->s_out_tr = transaction; sipevent = osip_new_outgoing_sipmessage (subscribe); sipevent->transactionid = transaction->transactionid; osip_transaction_set_reserved5 (transaction, js); osip_transaction_add_event (transaction, sipevent); ADD_ELEMENT (excontext->j_subscribes, js); _eXosip_update (excontext); /* fixed? */ _eXosip_wakeup (excontext); return js->s_id; }
int eXosip_add_authentication_info (const char *username, const char *userid, const char *passwd, const char *ha1, const char *realm) { jauthinfo_t *authinfos; if (username == NULL || username[0] == '\0') return -1; if (userid == NULL || userid[0] == '\0') return -1; if (passwd != NULL && passwd[0] != '\0') { } else if (ha1 != NULL && ha1[0] != '\0') { } else return -1; authinfos = (jauthinfo_t *) osip_malloc (sizeof (jauthinfo_t)); if (authinfos == NULL) return -1; memset (authinfos, 0, sizeof (jauthinfo_t)); snprintf (authinfos->username, 50, "%s", username); snprintf (authinfos->userid, 50, "%s", userid); if (passwd != NULL && passwd[0] != '\0') snprintf (authinfos->passwd, 50, "%s", passwd); else if (ha1 != NULL && ha1[0] != '\0') snprintf (authinfos->ha1, 50, "%s", ha1); if (realm != NULL && realm[0] != '\0') snprintf (authinfos->realm, 50, "%s", realm); ADD_ELEMENT (eXosip.authinfos, authinfos); return 0; }
int jidentity_load() { FILE *file; char *s; jidentity_t *fr; int pos; char *home; char filename[255]; jidentity_unload(); home = getenv("HOME"); sprintf(filename, "%s/%s/%s", home, EXOSIP_ETC_DIR, "jm_identity"); file = fopen(filename, "r"); if (file==NULL) return -1; s = (char *)osip_malloc(255*sizeof(char)); pos = 0; while (NULL!=fgets(s, 254, file)) { char *tmp = s; while (*tmp!='\0' && *tmp!=' ') tmp++; while (*tmp!='\0' && *tmp==' ') tmp++; while (*tmp!='\0' && *tmp!=' ') tmp++; tmp++; /* first usefull characters */ pos++; jidentity_init(&fr, tmp); if (fr!=NULL) { ADD_ELEMENT(eXosip.j_identitys, fr); } } osip_free(s); fclose(file); return 0; /* ok */ }
void __nist_load_fsm () { transition_t *transition; nist_fsm = (osip_statemachine_t *) osip_malloc (sizeof (osip_statemachine_t)); nist_fsm->transitions = NULL; transition = (transition_t *) osip_malloc (sizeof (transition_t)); transition->state = NIST_PRE_TRYING; transition->type = RCV_REQUEST; transition->method = (void (*)(void *, void *)) &nist_rcv_request; ADD_ELEMENT (nist_fsm->transitions, transition); transition = (transition_t *) osip_malloc (sizeof (transition_t)); transition->state = NIST_TRYING; transition->type = SND_STATUS_1XX; transition->method = (void (*)(void *, void *)) &nist_snd_1xx; ADD_ELEMENT (nist_fsm->transitions, transition); transition = (transition_t *) osip_malloc (sizeof (transition_t)); transition->state = NIST_TRYING; transition->type = SND_STATUS_2XX; transition->method = (void (*)(void *, void *)) &nist_snd_23456xx; ADD_ELEMENT (nist_fsm->transitions, transition); transition = (transition_t *) osip_malloc (sizeof (transition_t)); transition->state = NIST_TRYING; transition->type = SND_STATUS_3456XX; transition->method = (void (*)(void *, void *)) &nist_snd_23456xx; ADD_ELEMENT (nist_fsm->transitions, transition); transition = (transition_t *) osip_malloc (sizeof (transition_t)); transition->state = NIST_PROCEEDING; transition->type = SND_STATUS_1XX; transition->method = (void (*)(void *, void *)) &nist_snd_1xx; ADD_ELEMENT (nist_fsm->transitions, transition); transition = (transition_t *) osip_malloc (sizeof (transition_t)); transition->state = NIST_PROCEEDING; transition->type = SND_STATUS_2XX; transition->method = (void (*)(void *, void *)) &nist_snd_23456xx; ADD_ELEMENT (nist_fsm->transitions, transition); transition = (transition_t *) osip_malloc (sizeof (transition_t)); transition->state = NIST_PROCEEDING; transition->type = SND_STATUS_3456XX; transition->method = (void (*)(void *, void *)) &nist_snd_23456xx; ADD_ELEMENT (nist_fsm->transitions, transition); transition = (transition_t *) osip_malloc (sizeof (transition_t)); transition->state = NIST_PROCEEDING; transition->type = RCV_REQUEST; transition->method = (void (*)(void *, void *)) &nist_rcv_request; ADD_ELEMENT (nist_fsm->transitions, transition); transition = (transition_t *) osip_malloc (sizeof (transition_t)); transition->state = NIST_COMPLETED; transition->type = TIMEOUT_J; transition->method = (void (*)(void *, void *)) &osip_nist_timeout_j_event; ADD_ELEMENT (nist_fsm->transitions, transition); transition = (transition_t *) osip_malloc (sizeof (transition_t)); transition->state = NIST_COMPLETED; transition->type = RCV_REQUEST; transition->method = (void (*)(void *, void *)) &nist_rcv_request; ADD_ELEMENT (nist_fsm->transitions, transition); }
void Node::RegisterUser(REG_TYPE type,char * aor,char *contact,char *username,char * passwd) { /* REGISTER sip:[email protected] SIP/2.0 Via:SIP/2.0/UDP 192.168.1.61:15060;branch=z9hG4bkxxxxx To:liqq <sip:[email protected]> From:liqq <sip:[email protected]> Call-ID: CSeq: Contact:<sip:[email protected]> Content-Length:0 */ /*判断本节点是否对该用户信息负责, 如果负责,添加到user_info_list, 如果不负责,计算next-hop,并发送REGISTER请求*/ unsigned int uid; uid=uhash(aor); ChordId localnode=getChordId(); ChordId pred=getFingerTable()->getPredecessor(); Constants constants(NULL); ChordId UserID(uid,&constants); aor_t aaor(aor); binding_t abind(contact); uinfo_t *user_info=new uinfo_t(username,passwd); user_info->uinfo_set_aor(&aaor); user_info->uinfo_set_binding(&abind); ADD_ELEMENT(local_user_info_list,user_info); // int lid=localnode.GetId(); // int pid=predecessor.GetId(); //if((lid<pid && uid<=lid && uid>pid)||(lid>pid && (uid < lid || uid >=pid))) if(UserID.BelongsRightInclusive(pred,localnode)) { printf("Add a new local user\n"); uinfo_t *uinfo=new uinfo_t(username,passwd); uinfo->uinfo_set_aor(&aaor); uinfo->uinfo_set_binding(&abind); ADD_ELEMENT(user_info_list,uinfo); if(pred.equals(localnode)) { uinfo_t *ruinfo=new uinfo_t(username,passwd); ruinfo->uinfo_set_aor(&aaor); ruinfo->uinfo_set_binding(&abind); ADD_ELEMENT(red_user_info_list,ruinfo); } ChordId succ=getFingerTable()->getSuccessor(0); if(!succ.equals(getChordId())) { string next_hop="sip:"; next_hop+=succ.GetAddress(); SndUserRegisterRequest(RED_REGISTER,uinfo,next_hop.c_str() ,3600); } } else { ChordId node=closestPrecedingFinger(UserID); //ChordId node=getFingerTable()->getPredecessor(); //ChordId node=getChordId(); string registrar="sip:"; registrar+=node.GetAddress(); SndUserRegisterRequest(USER_REGISTRATION,user_info,registrar.c_str() ,3600); } }
int _eXosip_insubscription_answer_2xx (eXosip_notify_t * jn, 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_subscribe (jn, 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, this is a no hop! */ OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: cannot answer this closed transaction\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 subscribe\n")); code = 500; /* ? which code to use? */ return -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, 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 (jn->n_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); __eXosip_wakeup (); osip_dialog_set_state (jd->d_dialog, DIALOG_CONFIRMED); return 0; g2atii_error_1: osip_message_free (response); return -1; }
/* This method returns: -2 if plugin consider this request should be totally discarded! -1 on error 0 nothing has been done 1 things has been done on psp_req element */ int cb_groups_search_location(psp_request_t *psp_req) { location_t *loc; osip_route_t *route; int i; int index; int match; grp_t *grp=NULL; osip_uri_param_t *psp_param; osip_message_t *request; request = psp_request_get_request(psp_req); OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL, "groups plugin: entering cb_groups_search_location\n")); /* default OUTPUT */ if (ISSET_R_ROUTE_MODE(groups_context->flag)) psp_request_set_property(psp_req, PSP_STAY_ON_PATH); else psp_request_set_property(psp_req, 0); psp_request_set_mode(psp_req, PSP_SFULL_MODE); i=0; for (; !osip_list_eol(&request->routes, i); i++) { osip_message_get_route (request, i, &route); if (0 != psp_core_is_responsible_for_this_route(route->url)) { psp_request_set_mode (psp_req, PSP_SFULL_MODE); psp_request_set_state (psp_req, PSP_MANDATE); OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "groups plugin: mandate statefull handling for route.\n")); return 0; } } psp_request_set_state(psp_req, PSP_MANDATE); if (i>1) { psp_request_set_uas_status(psp_req, 482); /* loop? */ psp_request_set_mode(psp_req, PSP_UAS_MODE); return 0; } if (i==1) { osip_message_get_route(request, 0, &route); /* should be the first one */ /* if this route header contains the "psp" parameter, it means the element does not come from a pre-route-set header (in this last case, we want to execute the plugin for the initial request) */ /* NON compliant UAs (not returning this parameter) are guilty. */ osip_uri_uparam_get_byname (route->url, "psp", &psp_param); if (psp_param!=NULL) { psp_request_set_state(psp_req, PSP_MANDATE); psp_request_set_mode (psp_req, PSP_SFULL_MODE); /* got it, leave this plugin. */ return 0; } } if (request->req_uri->username==NULL || request->req_uri->host==NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "groups plugin: No username in uri.\n")); psp_request_set_state(psp_req, PSP_PROPOSE); psp_request_set_uas_status(psp_req, 404); psp_request_set_mode(psp_req, PSP_UAS_MODE); return 0; } /* search for a group */ match=0; for (index=0; index<MAX_GROUPS; index++) { grp = &(groups_context->grps[index]); if (grp->group[0]!='\0') { if (osip_strcasecmp(grp->group, request->req_uri->username)==0) { if (grp->domain[0]=='\0') { match=1; break; } else if (osip_strcasecmp(grp->domain, request->req_uri->host)==0) { match=1; break; } } } grp=NULL; } if (match==1 && grp!=NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "groups plugin: A group match this call (%s).\n", grp->group)); for (index=0; index<MAX_MEMBERS; index++) { osip_uri_t *uri; int i; char *dest; dest = grp->members[index]; if (dest[0]=='\0') break; OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO3,NULL, "groups plugin: members of %s: %s\n", grp->group, dest)); osip_uri_init(&uri); i = osip_uri_parse(uri, dest); if (i==0) { i = location_init(&loc, uri, 3600); if (i!=0) { /* This can only happen in case we don't have enough memory */ osip_uri_free(uri); OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_BUG,NULL, "groups plugin: Could not create location info!\n")); } else { ADD_ELEMENT(psp_req->locations, loc); } } } return 0; } OSIP_TRACE(osip_trace(__FILE__,__LINE__,OSIP_INFO1,NULL, "groups plugin: Didn't do anything with this request?\n")); psp_request_set_state(psp_req, PSP_PROPOSE); psp_request_set_uas_status(psp_req, 404); psp_request_set_mode(psp_req, PSP_UAS_MODE); return 0; }
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_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; }
/* This method returns: -2 if plugin consider this request should be totally discarded! -1 on error 0 nothing has been done 1 things has been done on psp_req element */ int cb_ls_localdb_search_user_location (psp_request_t * psp_req) { osip_route_t *route; ppl_uinfo_t *uinfo; int i; int numlocs = 0 /* DAB */ ; osip_message_t *request; request = psp_request_get_request(psp_req); /* default OUTPUT */ if (ISSET_R_ROUTE_MODE (ls_localdb_context->flag)) psp_request_set_property (psp_req, PSP_STAY_ON_PATH); else psp_request_set_property (psp_req, 0); /* mode */ if (ISSET_FORKING_MODE (ls_localdb_context->flag)) psp_request_set_mode (psp_req, PSP_FORK_MODE); else if (ISSET_SEQUENTIAL_MODE (ls_localdb_context->flag)) psp_request_set_mode (psp_req, PSP_SEQ_MODE); else if (ISSET_REDIRECT_MODE (ls_localdb_context->flag)) { psp_request_set_uas_status (psp_req, 302); psp_request_set_mode (psp_req, PSP_UAS_MODE); } else psp_request_set_mode (psp_req, PSP_FORK_MODE); psp_request_set_state (psp_req, PSP_MANDATE); /* THIS IS MANDATORY FOR ALL PLUGINS TO CHECK THAT! this is rarely used as a previous plugin 'ls_localdb' should have checked for it. In case you remove it. */ osip_message_get_route (request, 1, &route); if (route != NULL) { if (ISSET_SEQUENTIAL_MODE (ls_localdb_context->flag)) psp_request_set_mode (psp_req, PSP_SEQ_MODE); else psp_request_set_mode (psp_req, PSP_FORK_MODE); psp_request_set_state (psp_req, PSP_MANDATE); return 0; /* do nothing.. */ } if (request->req_uri->username == NULL) { /* Propose 484, but let's keep searching if another plugin can find the destination. */ psp_request_set_uas_status (psp_req, 484); psp_request_set_state (psp_req, PSP_CONTINUE); psp_request_set_mode (psp_req, PSP_UAS_MODE); return 0; } /* look for this URI in our list of users */ uinfo = ppl_uinfo_find_by_aor (request->req_uri); if (uinfo != NULL) { /* add all locations to the psp_req element */ binding_t *bind; binding_t *bindnext; location_t *loc; osip_uri_t *url; bind = uinfo->bindings; bindnext = uinfo->bindings; for (; bind != NULL; bind = bindnext) { bindnext = bind->next; i = ppl_uinfo_check_binding (bind); if (i != 0) { /* binding is expired */ ppl_uinfo_remove_binding (uinfo, bind); } } bind = uinfo->bindings; if (bind == NULL) { /* user is not around... */ OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "ls_localdb plugin: User Exist but has no valid registration!\n")); psp_request_set_uas_status (psp_req, 480); psp_request_set_mode (psp_req, PSP_UAS_MODE); psp_request_set_state (psp_req, PSP_MANDATE); return 0; } bindnext = uinfo->bindings; /* DAB */ for (; bind != NULL; bind = bindnext) /* DAB */ { /* DAB */ /* If this is an INVITE Request, collect all locations DAB */ #ifdef EXPERIMENTAL_FORK if (MSG_IS_INVITE (request)) bindnext = bind->next; /* DAB */ else bindnext = NULL; /* DAB */ #else /* always accept only ONE location even for INVITE */ /* this is a limitation for stability reason as the forking mode is unfinished (calculation of the best response is not compliant to the rfc3261.txt behavior. */ bindnext = NULL; /* loop will be execute onece only */ #endif i = osip_uri_clone (bind->contact->url, &url); if (i != 0) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "ls_localdb plugin: Could not clone contact info!\n")); psp_request_set_uas_status (psp_req, 400); psp_request_set_mode (psp_req, PSP_UAS_MODE); psp_request_set_state (psp_req, PSP_MANDATE); return -1; } i = location_init (&loc, url, 3600); if (i != 0) { osip_uri_free (url); OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_BUG, NULL, "ls_localdb plugin: Could not create location info!\n")); psp_request_set_uas_status (psp_req, 400); psp_request_set_mode (psp_req, PSP_UAS_MODE); psp_request_set_state (psp_req, PSP_MANDATE); return -1; } /* new support for rfc3327.txt and Path header */ if (bind->path!=NULL) location_set_path(loc, osip_strdup(bind->path)); ADD_ELEMENT (psp_req->locations, loc); numlocs++; /* DAB */ } /* DAB */ OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "ls_localdb plugin: %d locations found!\n", numlocs)); return 0; } /* no user location found in local database... */ psp_request_set_uas_status (psp_req, 404); psp_request_set_state (psp_req, PSP_CONTINUE); psp_request_set_mode (psp_req, PSP_UAS_MODE); OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL, "ls_localdb plugin: No location found for known user: return 404 Not found!!\n")); 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 eXosip_reinvite_with_authentication (struct eXosip_call_t *jc) { struct eXosip_call_t *jcc; #ifdef SM char *locip; #else char locip[50]; #endif osip_message_t * cloneinvite; osip_event_t *sipevent; osip_transaction_t *transaction; int osip_cseq_num,length; osip_via_t *via; char *tmp; int i; osip_message_clone (jc->c_out_tr->orig_request, &cloneinvite); osip_cseq_num = osip_atoi(jc->c_out_tr->orig_request->cseq->number); length = strlen(jc->c_out_tr->orig_request->cseq->number); tmp = (char *)osip_malloc(90*sizeof(char)); via = (osip_via_t *) osip_list_get (cloneinvite->vias, 0); osip_list_remove(cloneinvite->vias, 0); osip_via_free(via); #ifdef SM eXosip_get_localip_for(cloneinvite->req_uri->host,&locip); #else eXosip_guess_ip_for_via(eXosip.ip_family, locip, 49); #endif if (eXosip.ip_family==AF_INET6) { sprintf(tmp, "SIP/2.0/UDP [%s]:%s;branch=z9hG4bK%u", locip, eXosip.localport, via_branch_new_random()); } else { sprintf(tmp, "SIP/2.0/UDP %s:%s;branch=z9hG4bK%u", locip, eXosip.localport, via_branch_new_random()); } #ifdef SM osip_free(locip); #endif osip_via_init(&via); osip_via_parse(via, tmp); osip_list_add(cloneinvite->vias, via, 0); osip_free(tmp); osip_cseq_num++; osip_free(cloneinvite->cseq->number); cloneinvite->cseq->number = (char*)osip_malloc(length + 2); sprintf(cloneinvite->cseq->number, "%i", osip_cseq_num); eXosip_add_authentication_information(cloneinvite, jc->c_out_tr->last_response); cloneinvite->message_property = 0; eXosip_call_init(&jcc); i = osip_transaction_init(&transaction, ICT, eXosip.j_osip, cloneinvite); if (i!=0) { eXosip_call_free(jc); osip_message_free(cloneinvite); return -1; } jcc->c_out_tr = transaction; sipevent = osip_new_outgoing_sipmessage(cloneinvite); sipevent->transactionid = transaction->transactionid; osip_transaction_set_your_instance(transaction, __eXosip_new_jinfo(jcc, NULL, NULL, NULL)); osip_transaction_add_event(transaction, sipevent); jcc->external_reference = 0; ADD_ELEMENT(eXosip.j_calls, jcc); eXosip_update(); /* fixed? */ __eXosip_wakeup(); return 0; }
int eXosip_publish (struct eXosip_t *excontext, osip_message_t * message, const char *to) { osip_transaction_t *transaction; osip_event_t *sipevent; int i; eXosip_pub_t *pub = NULL; if (message == NULL) return OSIP_BADPARAMETER; if (message->cseq == NULL || message->cseq->number == NULL) { osip_message_free (message); return OSIP_SYNTAXERROR; } if (to == NULL) { osip_message_free (message); return OSIP_BADPARAMETER; } i = _eXosip_pub_find_by_aor (excontext, &pub, to); if (i != 0 || pub == NULL) { osip_header_t *expires; osip_message_get_expires (message, 0, &expires); if (expires == NULL || expires->hvalue == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: missing expires header in PUBLISH!")); osip_message_free (message); return OSIP_SYNTAXERROR; } else { /* start a new publication context */ i = _eXosip_pub_init (&pub, to, expires->hvalue); if (i != 0) { osip_message_free (message); return i; } ADD_ELEMENT (excontext->j_pub, pub); } } else { if (pub->p_sip_etag[0] != '\0') { /* increase cseq */ osip_message_set_header (message, "SIP-If-Match", pub->p_sip_etag); } { osip_header_t *expires; osip_message_get_expires (message, 0, &expires); if (expires == NULL || expires->hvalue == NULL) { OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL, "eXosip: missing expires header in PUBLISH!")); osip_message_free (message); return OSIP_SYNTAXERROR; } pub->p_period = atoi (expires->hvalue); } if (pub->p_last_tr != NULL && pub->p_last_tr->cseq != NULL && pub->p_last_tr->cseq->number != NULL) { int osip_cseq_num = osip_atoi (pub->p_last_tr->cseq->number); int length = (int) strlen (pub->p_last_tr->cseq->number); osip_cseq_num++; osip_free (message->cseq->number); message->cseq->number = (char *) osip_malloc (length + 2); /* +2 like for 9 to 10 */ if (message->cseq->number == NULL) { osip_message_free (message); return OSIP_NOMEM; } snprintf (message->cseq->number, length + 2, "%i", osip_cseq_num); } } i = _eXosip_transaction_init (excontext, &transaction, NICT, excontext->j_osip, message); if (i != 0) { osip_message_free (message); return i; } if (pub->p_last_tr != NULL) osip_list_add (&excontext->j_transactions, pub->p_last_tr, 0); pub->p_last_tr = transaction; sipevent = osip_new_outgoing_sipmessage (message); sipevent->transactionid = transaction->transactionid; osip_transaction_add_event (transaction, sipevent); _eXosip_wakeup (excontext); return transaction->transactionid; }
void __ict_load_fsm() { transition_t *transition; ict_fsm = (osip_statemachine_t *) osip_malloc(sizeof(osip_statemachine_t)); if (ict_fsm == NULL) return; ict_fsm->transitions = NULL; /* a new state is needed because a race can happen between the timer and the timeout event! One day to find out this bug ;-) */ transition = (transition_t *) osip_malloc(sizeof(transition_t)); transition->state = ICT_PRE_CALLING; transition->type = SND_REQINVITE; transition->method = (void (*)(void *, void *)) &ict_snd_invite; ADD_ELEMENT(ict_fsm->transitions, transition); /* transition = (transition_t *) osip_malloc(sizeof(transition_t)); transition->state = ICT_CALLING; transition->type = SND_REQINVITE; transition->method = (void(*)(void *,void *))&ict_snd_invite; osip_list_add(ict_fsm->transitions,transition,-1); */ transition = (transition_t *) osip_malloc(sizeof(transition_t)); transition->state = ICT_CALLING; transition->type = TIMEOUT_A; transition->method = (void (*)(void *, void *)) &osip_ict_timeout_a_event; ADD_ELEMENT(ict_fsm->transitions, transition); transition = (transition_t *) osip_malloc(sizeof(transition_t)); transition->state = ICT_CALLING; transition->type = TIMEOUT_B; transition->method = (void (*)(void *, void *)) &osip_ict_timeout_b_event; ADD_ELEMENT(ict_fsm->transitions, transition); transition = (transition_t *) osip_malloc(sizeof(transition_t)); transition->state = ICT_CALLING; transition->type = RCV_STATUS_1XX; transition->method = (void (*)(void *, void *)) &ict_rcv_1xx; ADD_ELEMENT(ict_fsm->transitions, transition); transition = (transition_t *) osip_malloc(sizeof(transition_t)); transition->state = ICT_CALLING; transition->type = RCV_STATUS_2XX; transition->method = (void (*)(void *, void *)) &ict_rcv_2xx; ADD_ELEMENT(ict_fsm->transitions, transition); transition = (transition_t *) osip_malloc(sizeof(transition_t)); transition->state = ICT_CALLING; transition->type = RCV_STATUS_3456XX; transition->method = (void (*)(void *, void *)) &ict_rcv_3456xx; ADD_ELEMENT(ict_fsm->transitions, transition); transition = (transition_t *) osip_malloc(sizeof(transition_t)); transition->state = ICT_PROCEEDING; transition->type = RCV_STATUS_1XX; transition->method = (void (*)(void *, void *)) &ict_rcv_1xx; ADD_ELEMENT(ict_fsm->transitions, transition); transition = (transition_t *) osip_malloc(sizeof(transition_t)); transition->state = ICT_PROCEEDING; transition->type = RCV_STATUS_2XX; transition->method = (void (*)(void *, void *)) &ict_rcv_2xx; ADD_ELEMENT(ict_fsm->transitions, transition); transition = (transition_t *) osip_malloc(sizeof(transition_t)); transition->state = ICT_PROCEEDING; transition->type = RCV_STATUS_3456XX; transition->method = (void (*)(void *, void *)) &ict_rcv_3456xx; ADD_ELEMENT(ict_fsm->transitions, transition); transition = (transition_t *) osip_malloc(sizeof(transition_t)); transition->state = ICT_COMPLETED; transition->type = RCV_STATUS_3456XX; transition->method = (void (*)(void *, void *)) &ict_retransmit_ack; ADD_ELEMENT(ict_fsm->transitions, transition); transition = (transition_t *) osip_malloc(sizeof(transition_t)); transition->state = ICT_COMPLETED; transition->type = TIMEOUT_D; transition->method = (void (*)(void *, void *)) &osip_ict_timeout_d_event; ADD_ELEMENT(ict_fsm->transitions, transition); }