/*! \brief Relay a MESSAGE to a SIP client \todo This assumes that a message is text/plain, which is not always the case with XMPP messages. We should propably also set the character set, as all SIP clients doesn't assume utf8 for text/plain */ int xmpp_send_sip_msg(char *from, char *to, char *msg) { str msg_type = { "MESSAGE", 7 }; str hdr, fromstr, tostr, msgstr; char buf[512]; uac_req_t uac_r; hdr.s = buf; hdr.len = snprintf(buf, sizeof(buf), "Content-type: text/plain" CRLF "Contact: %s" CRLF, from); fromstr.s = from; fromstr.len = strlen(from); tostr.s = to; tostr.len = strlen(to); msgstr.s = msg; msgstr.len = strlen(msg); set_uac_req(&uac_r, &msg_type, &hdr, &msgstr, 0, 0, 0, 0); return tmb.t_request( &uac_r, 0, /*!< Request-URI */ &tostr, /*!< To */ &fromstr, /*!< From */ (outbound_proxy.s)?&outbound_proxy:NULL/* Outbound proxy*/ ); }
int imc_handle_unknown(struct sip_msg* msg, imc_cmd_t *cmd, str *src, str *dst) { str body; uac_req_t uac_r; body.s = imc_body_buf; body.len = snprintf(body.s, IMC_BUF_SIZE, "invalid command '%.*s' - send ''%.*shelp' for details", cmd->name.len, cmd->name.s, imc_cmd_start_str.len, imc_cmd_start_str.s); if(body.len<0 || body.len>=IMC_BUF_SIZE) { LM_ERR("unable to print message\n"); return -1; } LM_DBG("to: [%.*s] from: [%.*s]\n", src->len, src->s, dst->len, dst->s); set_uac_req(&uac_r, &imc_msg_type, &all_hdrs, &body, 0, 0, 0, 0); tmb.t_request(&uac_r, NULL, /* Request-URI */ src, /* To */ dst, /* From */ (outbound_proxy.s)?&outbound_proxy:NULL /* outbound proxy */ ); return 0; }
/* Relay a MESSAGE to a SIP client */ int purple_send_sip_msg(char *to, char *from, char *msg) { LM_DBG("sending message from %s to %s\n", from, to); str msg_type = { "MESSAGE", 7 }; str ruri, hdr, fromstr, tostr, msgstr; char hdr_buf[512], ruri_buf[512]; uac_req_t uac_r; /* update the local config framework structures */ cfg_update(); ruri.s = ruri_buf; ruri.len = snprintf(ruri_buf, sizeof(ruri_buf), "%s;proto=purple", to); hdr.s = hdr_buf; hdr.len = snprintf(hdr_buf, sizeof(hdr_buf), "Content-type: text/plain" CRLF "Contact: %s" CRLF, from); fromstr.s = from; fromstr.len = strlen(from); tostr.s = to; tostr.len = strlen(to); msgstr.s = msg; msgstr.len = strlen(msg); set_uac_req(&uac_r, &msg_type, &hdr, &msgstr, 0, 0, 0, 0); if (tmb.t_request(&uac_r, &ruri, &tostr, &fromstr, 0) < 0) { LM_ERR("error sending request\n"); return -1; } LM_DBG("message sent successfully\n"); return 0; }
static int sca_notify_subscriber_internal( sca_mod *scam, sca_subscription *sub, str *headers ) { uac_req_t request; dlg_t *dlg = NULL; int rc = -1; dlg = sca_notify_dlg_for_subscription( sub ); if ( dlg == NULL ) { LM_ERR( "Failed to create dlg_t for %s NOTIFY to %.*s", sca_event_name_from_type( sub->event ), STR_FMT( &sub->subscriber )); goto done; } set_uac_req( &request, (str *)&SCA_METHOD_NOTIFY, headers, NULL, dlg, TMCB_LOCAL_COMPLETED, sca_notify_reply_cb, scam ); rc = scam->tm_api->t_request_within( &request ); if ( rc < 0 ) { LM_ERR( "Failed to send in-dialog %s NOTIFY to %.*s", sca_event_name_from_type( sub->event ), STR_FMT( &sub->subscriber )); } /* fall through, return rc from t_request_within */ done: if ( dlg != NULL ) { pkg_free( dlg ); } return( rc ); }
/** * send a SIP MESSAGE message * - to : destination * - from : origin * - contact : contact header * - msg : body of the message * return : 0 on success or <0 on error */ int xj_send_sip_msg(str *proxy, str *to, str *from, str *msg, int *cbp) { str msg_type = { "MESSAGE", 7}; char buf[512]; str tfrom; str str_hdr; char buf1[1024]; uac_req_t uac_r; if( !to || !to->s || to->len <= 0 || !from || !from->s || from->len <= 0 || !msg || !msg->s || msg->len <= 0 || (cbp && *cbp!=0) ) return -1; // from correction tfrom.len = 0; strncpy(buf+tfrom.len, "<sip:", 5); tfrom.len += 5; strncpy(buf+tfrom.len, from->s, from->len); tfrom.len += from->len; buf[tfrom.len++] = '>'; tfrom.s = buf; // building Contact and Content-Type strcpy(buf1,"Content-Type: text/plain"CRLF"Contact: "); str_hdr.len = 24 + CRLF_LEN + 9; strncat(buf1,tfrom.s,tfrom.len); str_hdr.len += tfrom.len; strcat(buf1, CRLF); str_hdr.len += CRLF_LEN; str_hdr.s = buf1; if(cbp) { #ifdef XJ_EXTRA_DEBUG LM_DBG("uac callback parameter [%p==%d]\n", cbp, *cbp); #endif set_uac_req(&uac_r, &msg_type, &str_hdr, msg, 0, TMCB_LOCAL_COMPLETED, xj_tuac_callback, (void*)cbp); } else { set_uac_req(&uac_r, &msg_type, &str_hdr, msg, 0, 0, 0, 0); } return tmb.t_request(&uac_r, 0, to, &tfrom, 0); }
/* send keep-alive * dlg - pointer to a struct dlg_cell * dir - direction: the request will be sent to: * DLG_CALLER_LEG (0): caller * DLG_CALLEE_LEG (1): callee */ int dlg_send_ka(dlg_cell_t *dlg, int dir, str *hdrs) { uac_req_t uac_r; dlg_t* di; str met = {"OPTIONS", 7}; int result; dlg_iuid_t *iuid = NULL; /* do not send KA request for non-confirmed dialogs (not supported) */ if (dlg->state != DLG_STATE_CONFIRMED) { LM_DBG("skipping non-confirmed dialogs\n"); return 0; } /* build tm dlg by direction */ if ((di = build_dlg_t(dlg, dir)) == 0){ LM_ERR("failed to create dlg_t\n"); goto err; } /* tm increases cseq value, decrease it no to make it invalid * - dialog is ended on timeout (408) or C/L does not exist (481) */ if(di->loc_seq.value>1) di->loc_seq.value -= 2; else di->loc_seq.value -= 1; LM_DBG("sending BYE to %s\n", (dir==DLG_CALLER_LEG)?"caller":"callee"); iuid = dlg_get_iuid_shm_clone(dlg); if(iuid==NULL) { LM_ERR("failed to create dialog unique id clone\n"); goto err; } memset(&uac_r,'\0', sizeof(uac_req_t)); set_uac_req(&uac_r, &met, hdrs, NULL, di, TMCB_LOCAL_COMPLETED, dlg_ka_cb, (void*)iuid); result = d_tmb.t_request_within(&uac_r); if(result < 0){ LM_ERR("failed to send the BYE request\n"); goto err; } free_tm_dlg(di); LM_DBG("keep-alive sent to %s\n", (dir==0)?"caller":"callee"); return 0; err: if(di) free_tm_dlg(di); return -1; }
static int dlg_refer_callee(dlg_transfer_ctx_t *dtc) { /*verify direction*/ dlg_t* dialog_info = NULL; str met = {"REFER", 5}; int result; str hdrs; struct dlg_cell *dlg; uac_req_t uac_r; dlg = dtc->dlg; if ((dialog_info = build_dlg_t(dlg, DLG_CALLEE_LEG)) == 0){ LM_ERR("failed to create dlg_t\n"); goto error; } hdrs.len = 23 + 2*CRLF_LEN + dlg_bridge_controller.len + dtc->to.len + dlg_bridge_ref_hdrs.len; LM_DBG("sending REFER [%d] <%.*s>\n", hdrs.len, dtc->to.len, dtc->to.s); hdrs.s = (char*)pkg_malloc(hdrs.len*sizeof(char)); if(hdrs.s == NULL) goto error; memcpy(hdrs.s, "Referred-By: ", 13); memcpy(hdrs.s+13, dlg_bridge_controller.s, dlg_bridge_controller.len); memcpy(hdrs.s+13+dlg_bridge_controller.len, CRLF, CRLF_LEN); memcpy(hdrs.s+13+dlg_bridge_controller.len+CRLF_LEN, "Refer-To: ", 10); memcpy(hdrs.s+23+dlg_bridge_controller.len+CRLF_LEN, dtc->to.s, dtc->to.len); memcpy(hdrs.s+23+dlg_bridge_controller.len+CRLF_LEN+dtc->to.len, CRLF, CRLF_LEN); memcpy(hdrs.s+23+dlg_bridge_controller.len+CRLF_LEN+dtc->to.len+CRLF_LEN, dlg_bridge_ref_hdrs.s, dlg_bridge_ref_hdrs.len); set_uac_req(&uac_r, &met, &hdrs, NULL, dialog_info, TMCB_LOCAL_COMPLETED, dlg_refer_tm_callback, (void*)dtc); result = d_tmb.t_request_within(&uac_r); pkg_free(hdrs.s); if(result < 0) { LM_ERR("failed to send the REFER request\n"); /* todo: clean-up dtc */ goto error; } free_tm_dlg(dialog_info); LM_DBG("REFER sent\n"); return 0; error: if(dialog_info) free_tm_dlg(dialog_info); return -1; }
static int prepare_winfo_notify(struct retr_buf **dst, struct presentity* _p, struct watcher* _w, pa_notify_cb_param_t *cbd) { str doc = STR_NULL; str content_type = STR_NULL; str headers = STR_NULL; int res = 0; str body = STR_STATIC_INIT(""); uac_req_t uac_r; switch (_w->preferred_mimetype) { case DOC_WINFO: create_winfo_document(_p, _w, &doc, &content_type); DEBUG("winfo document created\n"); break; /* other formats ? */ default: ERR("unknow doctype\n"); return -1; } if (create_headers(_w, &headers, &content_type) < 0) { ERR("Error while adding headers\n"); str_free_content(&doc); str_free_content(&content_type); return -7; } if (!is_str_empty(&doc)) body = doc; /* res = tmb.t_request_within(¬ify, &headers, &body, _w->dialog, 0, 0); */ set_uac_req(&uac_r, ¬ify, &headers, &body, _w->dialog, TMCB_LOCAL_COMPLETED, pa_notify_cb, cbd ); res = tmb.prepare_request_within(&uac_r, dst); if (res < 0) { ERR("Can't send watcherinfo notification (%d)\n", res); } else { _w->document_index++; /* increment index for next document */ } str_free_content(&doc); str_free_content(&headers); str_free_content(&content_type); return res; }
void dlg_refer_tm_callback(struct cell *t, int type, struct tmcb_params *ps) { dlg_transfer_ctx_t *dtc = NULL; dlg_t* dialog_info = NULL; str met = {"BYE", 3}; int result; struct dlg_cell *dlg; uac_req_t uac_r; if(ps->param==NULL || *ps->param==0) { LM_DBG("message id not received\n"); return; } dtc = *((dlg_transfer_ctx_t**)ps->param); if(dtc==NULL) return; LM_DBG("REFER completed with status %d\n", ps->code); /* we send the BYE anyhow */ dlg = dtc->dlg; if ((dialog_info = build_dlg_t(dlg, DLG_CALLEE_LEG)) == 0){ LM_ERR("failed to create dlg_t\n"); goto error; } /* after REFER, the CSeq must be increased */ dialog_info->loc_seq.value++; set_uac_req(&uac_r, &met, NULL, NULL, dialog_info, 0, NULL, NULL); result = d_tmb.t_request_within(&uac_r); if(result < 0) { LM_ERR("failed to send the REFER request\n"); /* todo: clean-up dtc */ goto error; } free_tm_dlg(dialog_info); dlg_transfer_ctx_free(dtc); LM_DBG("BYE sent\n"); return; error: dlg_transfer_ctx_free(dtc); if(dialog_info) free_tm_dlg(dialog_info); return; }
/* cell- pointer to a struct dlg_cell * dir- direction: the request will be sent to: * DLG_CALLER_LEG (0): caller * DLG_CALLEE_LEG (1): callee */ static inline int send_bye(struct dlg_cell * cell, int dir, str *hdrs) { uac_req_t uac_r; dlg_t* dialog_info; str met = {"BYE", 3}; int result; dlg_iuid_t *iuid = NULL; /* do not send BYE request for non-confirmed dialogs (not supported) */ if (cell->state != DLG_STATE_CONFIRMED_NA && cell->state != DLG_STATE_CONFIRMED) { LM_ERR("terminating non-confirmed dialogs not supported\n"); return -1; } /*verify direction*/ if ((dialog_info = build_dlg_t(cell, dir)) == 0){ LM_ERR("failed to create dlg_t\n"); goto err; } LM_DBG("sending BYE to %s\n", (dir==DLG_CALLER_LEG)?"caller":"callee"); iuid = dlg_get_iuid_shm_clone(cell); if(iuid==NULL) { LM_ERR("failed to create dialog unique id clone\n"); goto err; } memset(&uac_r,'\0', sizeof(uac_req_t)); set_uac_req(&uac_r, &met, hdrs, NULL, dialog_info, TMCB_LOCAL_COMPLETED, bye_reply_cb, (void*)iuid); result = d_tmb.t_request_within(&uac_r); if(result < 0){ LM_ERR("failed to send the BYE request\n"); goto err; } free_tm_dlg(dialog_info); LM_DBG("BYE sent to %s\n", (dir==0)?"caller":"callee"); return 0; err: if(dialog_info) free_tm_dlg(dialog_info); return -1; }
int send_winfo_notify_offline(struct presentity* _p, struct watcher* _w, offline_winfo_t *info, transaction_cb completion_cb, void* cbp) { str doc = STR_NULL; str content_type = STR_NULL; str headers = STR_NULL; str body = STR_STATIC_INIT(""); uac_req_t uac_r; switch (_w->preferred_mimetype) { case DOC_WINFO: create_winfo_document_offline(_p, _w, info, &doc, &content_type); break; /* other formats ? */ default: ERR("send_winfo_notify: unknow doctype\n"); return -1; } if (create_headers(_w, &headers, &content_type) < 0) { ERR("send_winfo_notify(): Error while adding headers\n"); str_free_content(&doc); str_free_content(&content_type); return -7; } if (!is_str_empty(&doc)) body = doc; set_uac_req(&uac_r, ¬ify, &headers, &body, _w->dialog, TMCB_LOCAL_COMPLETED, completion_cb, cbp ); tmb.t_request_within(&uac_r); str_free_content(&doc); str_free_content(&headers); str_free_content(&content_type); _w->document_index++; /* increment index for next document */ if (use_db) db_update_watcher(_p, _w); /* dialog and index have changed */ return 0; }
int imc_send_message(str *src, str *dst, str *headers, str *body) { uac_req_t uac_r; if(src==NULL || dst==NULL || body==NULL) return -1; /* to-do: callbac to remove user fi delivery fails */ set_uac_req(&uac_r, &imc_msg_type, headers, body, 0, 0, 0, 0); tmb.t_request(&uac_r, NULL, /* Request-URI */ dst, /* To */ src, /* From */ (outbound_proxy.s)?&outbound_proxy:NULL /* outbound proxy */ ); return 0; }
int imc_handle_help(struct sip_msg* msg, imc_cmd_t *cmd, str *src, str *dst) { str body; uac_req_t uac_r; body.s = IMC_HELP_MSG; body.len = IMC_HELP_MSG_LEN; LM_DBG("to: [%.*s] from: [%.*s]\n", src->len, src->s, dst->len, dst->s); set_uac_req(&uac_r, &imc_msg_type, &all_hdrs, &body, 0, 0, 0, 0); tmb.t_request(&uac_r, NULL, /* Request-URI */ src, /* To */ dst, /* From */ (outbound_proxy.s)?&outbound_proxy:NULL/* outbound proxy */ ); return 0; }
static int sca_notify_subscriber_internal(sca_mod *scam, sca_subscription *sub, str *headers) { uac_req_t request; dlg_t *dlg = NULL; str state_str = STR_NULL; int rc = -1; sca_appearance_state_to_str(sub->state, &state_str); LM_DBG("SCA: NOTIFYing subscriber '%.*s' of event '%s' with a state of '%.*s' to index '%d'\n", STR_FMT(&sub->subscriber), sca_event_name_from_type(sub->event), STR_FMT(&state_str), sub->index); dlg = sca_notify_dlg_for_subscription(sub); if (dlg == NULL) { LM_ERR("Failed to create dlg_t for %s NOTIFY to %.*s\n", sca_event_name_from_type(sub->event), STR_FMT(&sub->subscriber)); goto done; } set_uac_req(&request, (str *)&SCA_METHOD_NOTIFY, headers, NULL, dlg, TMCB_LOCAL_COMPLETED, sca_notify_reply_cb, scam); rc = scam->tm_api->t_request_within(&request); if (rc < 0) { LM_ERR("Failed to send in-dialog %s NOTIFY to %.*s\n", sca_event_name_from_type(sub->event), STR_FMT(&sub->subscriber)); } // fall through, return rc from t_request_within done: if (dlg != NULL) { if (dlg->route_set != NULL) { free_rr(&dlg->route_set); } pkg_free(dlg); } return (rc); }
int prepare_unauthorized_notify(struct retr_buf **dst, struct presentity* _p, struct watcher* _w, pa_notify_cb_param_t *cbd) { str headers = STR_NULL; str body = STR_STATIC_INIT(""); int res; unc_req_t uac_r; /* send notifications to unauthorized (pending) watchers */ if (create_headers(_w, &headers, NULL) < 0) { LOG(L_ERR, "notify_unauthorized_watcher(): Error while adding headers\n"); return -7; } set_uac_req(&uac_r, ¬ify, &headers, &body, _w->dialog, TMCB_LOCAL_COMPLETED, pa_notify_cb, cbd ); res = tmb.prepare_request_within(&uac_r, dst); if (res < 0) { ERR("Can't send NOTIFY (%d) in dlg %.*s, %.*s, %.*s\n", res, FMT_STR(_w->dialog->id.call_id), FMT_STR(_w->dialog->id.rem_tag), FMT_STR(_w->dialog->id.loc_tag)); } str_free_content(&headers); return res; }
/** * Creates a NOTIFY message and sends it * @param n - the r_notification to create the NOTIFY after */ void send_notification(r_notification *n) { str h={0,0}; int k=0; #ifdef SER_MOD_INTERFACE uac_req_t req; #endif LOG(L_DBG,"DBG:"M_NAME":send_notification: NOTIFY about <%.*s>\n",n->uri.len,n->uri.s); //tmb.print_dlg(stdout,n->dialog); h.len = 0; h.len += contact_hdr1.len + n->uri.len + contact_hdr2.len ; if (n->subscription_state.len) h.len += subss_hdr1.len + subss_hdr2.len + n->subscription_state.len; h.len+=event_hdr.len; h.len+=maxfwds_hdr.len; if (n->content_type.len) h.len += ctype_hdr1.len + ctype_hdr2.len + n->content_type.len; h.s = pkg_malloc(h.len); if (!h.s){ LOG(L_ERR,"ERR:"M_NAME":send_notification: Error allocating %d bytes\n",h.len); h.len = 0; } h.len = 0; STR_APPEND(h,contact_hdr1); STR_APPEND(h,n->uri); STR_APPEND(h,contact_hdr2); STR_APPEND(h,event_hdr); STR_APPEND(h,maxfwds_hdr); if (n->subscription_state.len) { STR_APPEND(h,subss_hdr1); STR_APPEND(h,n->subscription_state); STR_APPEND(h,subss_hdr2); } if (n->content_type.len) { STR_APPEND(h,ctype_hdr1); STR_APPEND(h,n->content_type); STR_APPEND(h,ctype_hdr2); } //LOG(L_CRIT,"DLG:%p\n",n->dialog); #ifdef WITH_IMS_PM k = n->is_scscf_dereg; #endif if (n->content.len) { #ifdef SER_MOD_INTERFACE set_uac_req(&req, &method, &h, &(n->content), n->dialog, TMCB_RESPONSE_IN|TMCB_ON_FAILURE|TMCB_LOCAL_COMPLETED, uac_request_cb, (void*)k); tmb.t_request_within(&req); #else tmb.t_request_within(&method, &h, &(n->content), n->dialog, uac_request_cb, (void*)k); #endif } else { #ifdef SER_MOD_INTERFACE set_uac_req(&req, &method, 0, &(n->content), n->dialog, TMCB_RESPONSE_IN|TMCB_ON_FAILURE|TMCB_LOCAL_COMPLETED, uac_request_cb, (void*)k); tmb.t_request_within(&req); #else tmb.t_request_within(&method, &h, 0, n->dialog, uac_request_cb, (void*)k); #endif } if (h.s) pkg_free(h.s); #ifdef WITH_IMS_PM if (n->is_scscf_dereg) IMS_PM_LOG11(UR_AttDeRegCscf,n->dialog->id.call_id,n->dialog->loc_seq.value); #endif }
int imc_handle_invite(struct sip_msg* msg, imc_cmd_t *cmd, struct sip_uri *src, struct sip_uri *dst) { imc_room_p room = 0; imc_member_p member = 0; int flag_member = 0; int size = 0; int i = 0; int add_domain = 0; int add_sip = 0; str uri = {0, 0}; str body; str room_name; struct sip_uri inv_uri; del_member_t *cback_param = NULL; int result; uac_req_t uac_r; size = cmd->param[0].len+2 ; add_domain = 1; add_sip = 0; while (i<size ) { if(cmd->param[0].s[i]== '@') { add_domain = 0; break; } i++; } if(add_domain) size += dst->host.len; if(cmd->param[0].len<4 || strncmp(cmd->param[0].s, "sip:", 4)!=0) { size += 4; add_sip = 1; } uri.s = (char*)pkg_malloc(size *sizeof(char)); if(uri.s == NULL) { LM_ERR("no more pkg memory\n"); goto error; } size= 0; if(add_sip) { strcpy(uri.s, "sip:"); size=4; } memcpy(uri.s+size, cmd->param[0].s, cmd->param[0].len); size += cmd->param[0].len; if(add_domain) { uri.s[size] = '@'; size++; memcpy(uri.s+ size, dst->host.s, dst->host.len); size+= dst->host.len; } uri.len = size; if(parse_uri(uri.s, uri.len, &inv_uri)!=0) { LM_ERR("bad uri [%.*s]!\n", uri.len, uri.s); goto error; } room_name = (cmd->param[1].s)?cmd->param[1]:dst->user; room = imc_get_room(&room_name, &dst->host); if(room== NULL || (room->flags&IMC_ROOM_DELETED)) { LM_ERR("the room does not exist [%.*s]!\n", room_name.len, room_name.s); goto error; } member= imc_get_member(room, &src->user, &src->host); if(member==NULL) { LM_ERR("user [%.*s] is not member of[%.*s]!\n", src->user.len, src->user.s, room_name.len, room_name.s); goto error; } if(!(member->flags & IMC_MEMBER_OWNER) && !(member->flags & IMC_MEMBER_ADMIN)) { LM_ERR("user [%.*s] has no right to invite" " other users!\n", src->user.len, src->user.s); goto error; } member= imc_get_member(room, &inv_uri.user, &inv_uri.host); if(member!=NULL) { LM_ERR("user [%.*s] is already member" " of the room!\n", inv_uri.user.len, inv_uri.user.s); goto error; } flag_member |= IMC_MEMBER_INVITED; member=imc_add_member(room, &inv_uri.user, &inv_uri.host, flag_member); if(member == NULL) { LM_ERR("adding member [%.*s]\n", inv_uri.user.len, inv_uri.user.s); goto error; } body.len = 13 + member->uri.len - 4/* sip: */ + 28; if(body.len>=IMC_BUF_SIZE || member->uri.len>=IMC_BUF_SIZE || room->uri.len>=IMC_BUF_SIZE) { LM_ERR("buffer size overflow\n"); goto error; } body.s = imc_body_buf; memcpy(body.s, "INVITE from: ", 13); memcpy(body.s+13, member->uri.s + 4, member->uri.len - 4); memcpy(body.s+ 9 + member->uri.len, "(Type: '#accept' or '#deny')", 28); body.s[body.len] = '\0'; LM_DBG("to=[%.*s]\nfrom=[%.*s]\nbody=[%.*s]\n", member->uri.len,member->uri.s,room->uri.len, room->uri.s, body.len, body.s); cback_param = (del_member_t*)shm_malloc(sizeof(del_member_t)); if(cback_param==NULL) { LM_ERR("no more shm\n"); goto error; } memset(cback_param, 0, sizeof(del_member_t)); cback_param->room_name = room->name; cback_param->room_domain = room->domain; cback_param->member_name = member->user; cback_param->member_domain = member->domain; cback_param->inv_uri = member->uri; /*?!?! possible race with 'remove user' */ set_uac_req(&uac_r, &imc_msg_type, &all_hdrs, &body, 0, TMCB_LOCAL_COMPLETED, imc_inv_callback, (void*)(cback_param)); result= tmb.t_request(&uac_r, &member->uri, /* Request-URI */ &member->uri, /* To */ &room->uri, /* From */ (outbound_proxy.s)?&outbound_proxy:NULL/* outbound proxy*/ ); if(result< 0) { LM_ERR("in tm send request\n"); shm_free(cback_param); goto error; } if(uri.s!=NULL) pkg_free(uri.s); imc_release_room(room); return 0; error: if(uri.s!=0) pkg_free(uri.s); if(room!=NULL) imc_release_room(room); return -1; }
void imc_inv_callback( struct cell *t, int type, struct tmcb_params *ps) { str body_final; char from_uri_buf[256]; char to_uri_buf[256]; char body_buf[256]; str from_uri_s, to_uri_s; imc_member_p member= NULL; imc_room_p room = NULL; uac_req_t uac_r; if(ps->param==NULL || *ps->param==NULL || (del_member_t*)(*ps->param) == NULL) { LM_DBG("member not received\n"); return; } LM_DBG("completed with status %d [member name domain:" "%p/%.*s/%.*s]\n",ps->code, ps->param, ((del_member_t *)(*ps->param))->member_name.len, ((del_member_t *)(*ps->param))->member_name.s, ((del_member_t *)(*ps->param))->member_domain.len, ((del_member_t *)(*ps->param))->member_domain.s); if(ps->code < 300) return; else { room= imc_get_room(&((del_member_t *)(*ps->param))->room_name, &((del_member_t *)(*ps->param))->room_domain ); if(room==NULL) { LM_ERR("the room does not exist!\n"); goto error; } /*verify if the user who sent the request is a member in the room * and has the right to remove other users */ member= imc_get_member(room, &((del_member_t *)(*ps->param))->member_name, &((del_member_t *)(*ps->param))->member_domain); if(member== NULL) { LM_ERR("the user is not a member of the room!\n"); goto error; } imc_del_member(room, &((del_member_t *)(*ps->param))->member_name, &((del_member_t *)(*ps->param))->member_domain); goto build_inform; } build_inform: body_final.s = body_buf; body_final.len = member->uri.len - 4 /* sip: part of URI */ + 20; memcpy(body_final.s, member->uri.s + 4, member->uri.len - 4); memcpy(body_final.s+member->uri.len-4," is not registered. ",21); goto send_message; send_message: from_uri_s.s = from_uri_buf; from_uri_s.len = room->uri.len; strncpy(from_uri_s.s, room->uri.s, room->uri.len); LM_DBG("sending message\n"); to_uri_s.s = to_uri_buf; to_uri_s.len = ((del_member_t *)(*ps->param))->inv_uri.len; strncpy(to_uri_s.s,((del_member_t *)(*ps->param))->inv_uri.s , ((del_member_t *)(*ps->param))->inv_uri.len); LM_DBG("to: %.*s\nfrom: %.*s\nbody: %.*s\n", to_uri_s.len, to_uri_s.s, from_uri_s.len, from_uri_s.s, body_final.len, body_final.s); set_uac_req(&uac_r, &imc_msg_type, &extra_hdrs, &body_final, 0, 0, 0, 0); tmb.t_request(&uac_r, NULL, /* Request-URI */ &to_uri_s, /* To */ &from_uri_s, /* From */ (outbound_proxy.s)?&outbound_proxy:NULL /* outbound proxy*/ ); if(room!=NULL) { imc_release_room(room); } if((del_member_t *)(*ps->param)) shm_free(*ps->param); return; error: if(room!=NULL) { imc_release_room(room); } if((del_member_t *)(*ps->param)) shm_free(*ps->param); return; }
int r_send_third_party_reg(r_third_party_registration *r, int expires) { str h = {0, 0}; str b = {0, 0}; uac_req_t req; LM_DBG("r_send_third_party_reg: REGISTER to <%.*s>\n", r->req_uri.len, r->req_uri.s); h.len = event_hdr.len + max_fwds_hdr.len; h.len += expires_s.len + 12 + expires_e.len; h.len += contact_s.len + isc_my_uri_sip.len + contact_e.len; if (r->pvni.len) { h.len += p_visited_network_id_s.len + p_visited_network_id_e.len + r->pvni.len; } if (r->pani.len) { h.len += p_access_network_info_s.len + p_access_network_info_e.len + r->pani.len; } if (r->cv.len) { h.len += p_charging_vector_s.len + p_charging_vector_e.len + r->cv.len; } if (r->path.len) { h.len += path_s.len + path_e.len + r->path.len + 6/*',' and ';lr' and '<' and '>'*/ + r->from.len /*adding our own address to path*/; } str pauri = {0,0}; if (p_associated_uri.data_len > 0) { pauri.s = p_associated_uri.buf; pauri.len = p_associated_uri.data_len; h.len += pauri.len; } if (r->body.content_type == CT_SERVICE_INFO) { h.len += content_type_s.len; h.len += ct_service_info.len; h.len += content_type_e.len; } else if (r->body.content_type == CT_REGISTER_REQ) { h.len += content_type_s.len; h.len += ct_register_req.len; h.len += content_type_e.len; } else if (r->body.content_type == CT_REGISTER_RESP) { h.len += content_type_s.len; h.len += ct_register_resp.len; h.len += content_type_e.len; } h.s = pkg_malloc(h.len); if (!h.s) { LM_ERR("r_send_third_party_reg: Error allocating %d bytes\n", h.len); h.len = 0; return 0; } h.len = 0; STR_APPEND(h, event_hdr); STR_APPEND(h, max_fwds_hdr); STR_APPEND(h, expires_s); sprintf(h.s + h.len, "%d", expires); h.len += strlen(h.s + h.len); STR_APPEND(h, expires_e); if (r->path.len) { STR_APPEND(h, path_s); STR_APPEND(h, path_mine_s); STR_APPEND(h, r->from); STR_APPEND(h, path_mine_e); STR_APPEND(h, comma); STR_APPEND(h, r->path); STR_APPEND(h, path_e); } STR_APPEND(h, contact_s); STR_APPEND(h, isc_my_uri_sip); STR_APPEND(h, contact_e); if (r->pvni.len) { STR_APPEND(h, p_visited_network_id_s); STR_APPEND(h, r->pvni); STR_APPEND(h, p_visited_network_id_e); } if (r->pani.len) { STR_APPEND(h, p_access_network_info_s); STR_APPEND(h, r->pani); STR_APPEND(h, p_access_network_info_e); } if (r->cv.len) { STR_APPEND(h, p_charging_vector_s); STR_APPEND(h, r->cv); STR_APPEND(h, p_charging_vector_e); } if (p_associated_uri.data_len > 0) { STR_APPEND(h, pauri); } LM_DBG("BODY TYPE(3rd PARTY REGISTER):<%d>\n", r->body.content_type); if (r->body.content_type != CT_NONE) { if (r->body.content_type == CT_SERVICE_INFO) { LM_ERR("BODY (3rd PARTY REGISTER) \"SI\": <%.*s>\n", r->body.content.len, r->body.content.s); b.len = body_s.len + r->body.content.len + body_e.len; b.s = pkg_malloc(b.len); if (!b.s) { LM_ERR("r_send_third_party_reg: Error allocating %d bytes\n", b.len); b.len = 0; goto error; } b.len = 0; STR_APPEND(b, body_s); STR_APPEND(b, r->body.content); STR_APPEND(b, body_e); STR_APPEND(h, content_type_s); STR_APPEND(h, ct_service_info); STR_APPEND(h, content_type_e); } else if (r->body.content_type == CT_REGISTER_REQ) { LM_ERR("BODY (3rd PARTY REGISTER) \"REQ\": <%.*s>\n", r->body.content.len, r->body.content.s); b.len = r->body.content.len; b.s = pkg_malloc(b.len); if (!b.s) { LM_ERR("r_send_third_party_reg: Error allocating %d bytes\n", b.len); b.len = 0; goto error; } b.len = 0; STR_APPEND(b, r->body.content); STR_APPEND(h, content_type_s); STR_APPEND(h, ct_register_req); STR_APPEND(h, content_type_e); } else if (r->body.content_type == CT_REGISTER_RESP) { LM_ERR("BODY (3rd PARTY REGISTER) \"RESP\": <%.*s>\n", r->body.content.len, r->body.content.s); b.len = r->body.content.len; b.s = pkg_malloc(b.len); if (!b.s) { LM_ERR("r_send_third_party_reg: Error allocating %d bytes\n", b.len); b.len = 0; goto error; } b.len = 0; STR_APPEND(b, r->body.content); STR_APPEND(h, content_type_s); STR_APPEND(h, ct_register_resp); STR_APPEND(h, content_type_e); } } set_uac_req(&req, &method, &h, &b, 0, TMCB_RESPONSE_IN | TMCB_ON_FAILURE | TMCB_LOCAL_COMPLETED, r_third_party_reg_response, &(r->req_uri)); if (isc_tmb.t_request(&req, &(r->req_uri), &(r->to), &(r->from), 0) < 0) { LM_ERR("r_send_third_party_reg: Error sending in transaction\n"); goto error; } if (h.s) pkg_free(h.s); if (b.s) pkg_free(b.s); if (r->body.content_type == CT_REGISTER_RESP) pkg_free(r->body.content.s); return 1; error: if (h.s) pkg_free(h.s); if (b.s) pkg_free(b.s); if (r->body.content_type == CT_REGISTER_RESP) pkg_free(r->body.content.s); return 0; }
/** * @brief send a dmq message * * peer - the peer structure on behalf of which we are sending * body - the body of the message * node - we send the message to this node * resp_cback - a response callback that gets called when the transaction is complete */ int dmq_send_message(dmq_peer_t *peer, str *body, dmq_node_t *node, dmq_resp_cback_t *resp_cback, int max_forwards, str *content_type) { uac_req_t uac_r; str str_hdr = {0, 0}; str from = {0, 0}, to = {0, 0}; dmq_cback_param_t *cb_param = NULL; int result = 0; int len = 0; if(!content_type) { LM_ERR("content-type is null\n"); return -1; } /* add Max-Forwards and Content-Type headers */ str_hdr.len = 34 + content_type->len + (CRLF_LEN * 2); str_hdr.s = pkg_malloc(str_hdr.len); if(str_hdr.s == NULL) { LM_ERR("no more pkg\n"); return -1; } len += sprintf(str_hdr.s, "Max-Forwards: %d" CRLF "Content-Type: %.*s" CRLF, max_forwards, content_type->len, content_type->s); str_hdr.len = len; cb_param = shm_malloc(sizeof(*cb_param)); if(cb_param == NULL) { LM_ERR("no more shm for building callback parameter\n"); goto error; } memset(cb_param, 0, sizeof(*cb_param)); cb_param->resp_cback = *resp_cback; cb_param->node = shm_dup_node(node); if(cb_param->node == NULL) { LM_ERR("error building callback parameter\n"); goto error; } if(build_uri_str(&peer->peer_id, &dmq_server_uri, &from) < 0) { LM_ERR("error building from string [username %.*s]\n", STR_FMT(&peer->peer_id)); goto error; } if(build_uri_str(&peer->peer_id, &node->uri, &to) < 0) { LM_ERR("error building to string\n"); goto error; } set_uac_req(&uac_r, &dmq_request_method, &str_hdr, body, NULL, TMCB_LOCAL_COMPLETED, dmq_tm_callback, (void *)cb_param); uac_r.ssock = &dmq_server_socket; result = tmb.t_request(&uac_r, &to, &to, &from, NULL); if(result < 0) { LM_ERR("error in tmb.t_request_within\n"); goto error; } pkg_free(str_hdr.s); pkg_free(from.s); pkg_free(to.s); return 0; error: pkg_free(str_hdr.s); if(from.s != NULL) pkg_free(from.s); if(to.s != NULL) pkg_free(to.s); if(cb_param) { if(cb_param->node) destroy_dmq_node(cb_param->node, 1); shm_free(cb_param); } return -1; }
int update_pua(ua_pres_t* p) { str* str_hdr= NULL; int expires; int result; uac_req_t uac_r; int ret_code = 0; dlg_t* td = NULL; if(p->desired_expires== 0) expires= 3600; else expires= p->desired_expires- (int)time(NULL); if(p->watcher_uri == NULL || p->watcher_uri->len == 0) { str met= {"PUBLISH", 7}; ua_pres_t* cb_param; str_hdr = publ_build_hdr(expires, get_event(p->event), NULL, &p->etag, p->extra_headers, 0); if(str_hdr == NULL) { LM_ERR("while building extra_headers\n"); ret_code = -1; goto done; } LM_DBG("str_hdr:\n%.*s\n ", str_hdr->len, str_hdr->s); cb_param= build_uppubl_cbparam(p); if(cb_param== NULL) { LM_ERR("while constructing publ callback param\n"); ret_code = -1; goto done; } set_uac_req(&uac_r, &met, str_hdr, 0, 0, TMCB_LOCAL_COMPLETED, publ_cback_func, (void*)cb_param); result= tmb.t_request(&uac_r, p->pres_uri, /* Request-URI */ p->pres_uri, /* To */ p->pres_uri, /* From */ &outbound_proxy /* Outbound proxy*/ ); if(result< 0) { LM_ERR("in t_request function\n"); shm_free(cb_param); ret_code = -1; goto done; } } else { str met= {"SUBSCRIBE", 9}; ua_pres_t* cb_param= NULL; td= pua_build_dlg_t(p); if(td== NULL) { LM_ERR("while building tm dlg_t structure"); ret_code = -1; goto done; }; str_hdr= subs_build_hdr(&p->contact, expires,p->event,p->extra_headers); if(str_hdr== NULL || str_hdr->s== NULL) { if(p->event!=0) LM_ERR("while building extra headers\n"); ret_code = -1; goto done; } cb_param= subs_cbparam_indlg(p, expires, REQ_ME); if(cb_param== NULL) { LM_ERR("while constructing subs callback param\n"); ret_code = -1; goto done; } set_uac_req(&uac_r, &met, str_hdr, 0, td, TMCB_LOCAL_COMPLETED, subs_cback_func, (void*)cb_param); result= tmb.t_request_within(&uac_r); if(result< 0) { LM_ERR("in t_request function\n"); shm_free(cb_param); ret_code = -1; goto done; } } done: if(td!=NULL) { if(td->route_set) free_rr(&td->route_set); pkg_free(td); td= NULL; } if(str_hdr) pkg_free(str_hdr); return ret_code; }
static int prepare_presence_notify(struct retr_buf **dst, struct presentity* _p, struct watcher* _w, pa_notify_cb_param_t *cbd) { /* Send a notify, saved Contact will be put in * Request-URI, To will be put in from and new tag * will be generated, callid will be callid, * from will be put in to including tag */ str doc = STR_NULL; str content_type = STR_NULL; str headers = STR_NULL; str body = STR_STATIC_INIT(""); int res = 0; uac_req_t uac_r; switch(_w->preferred_mimetype) { case DOC_XPIDF: res = create_xpidf_document(&_p->data, &doc, &content_type); break; case DOC_LPIDF: res = create_lpidf_document(&_p->data, &doc, &content_type); break; case DOC_CPIM_PIDF: res = create_cpim_pidf_document(&_p->data, &doc, &content_type); break; case DOC_MSRTC_PIDF: case DOC_PIDF: default: res = create_pidf_document(&_p->data, &doc, &content_type); } if (res != 0) { LOG(L_ERR, "can't create presence document (%d)\n", _w->preferred_mimetype); return -2; } if (create_headers(_w, &headers, &content_type) < 0) { LOG(L_ERR, "send_presence_notify(): Error while adding headers\n"); str_free_content(&doc); str_free_content(&content_type); return -7; } if (!is_str_empty(&doc)) body = doc; /* res = tmb.t_request_within(¬ify, &headers, &body, _w->dialog, pa_notify_cb, cbd);*/ set_uac_req(&uac_r, ¬ify, &headers, &body, _w->dialog, TMCB_LOCAL_COMPLETED, pa_notify_cb, cbd ); res = tmb.prepare_request_within(&uac_r, dst); if (res < 0) { ERR("Can't send NOTIFY (%d) in dlg %.*s, %.*s, %.*s\n", res, FMT_STR(_w->dialog->id.call_id), FMT_STR(_w->dialog->id.rem_tag), FMT_STR(_w->dialog->id.loc_tag)); } str_free_content(&doc); str_free_content(&headers); str_free_content(&content_type); return res; }
/*Actions are composed as follows: * (the action length and type as always= 5 bytes) * 4:uac_id * * int request(str* method, str* req_uri, str* to, str* from, str* headers, str* body, transaction_cb c, void* cp) * TODO performance speedup: instead of using * dynamically allocated memory for headers,body,totag,reason and my_msg * use static buffers. * */ int ac_uac_req(as_p the_as,unsigned char processor_id,unsigned int flags,char *action,int len) { unsigned int cseq; char err_buf[MAX_REASON_LEN]; struct sip_msg *my_msg; struct to_body *fb,*tb; struct cseq_body *cseqb; struct as_uac_param *the_param; dlg_t *my_dlg; int k,retval,uac_id,sip_error,ret,err_ret; long clen; str headers,body,fake_uri; uac_req_t uac_r; headers.s=body.s=fake_uri.s=NULL; my_dlg=NULL; my_msg=NULL; the_param=NULL; k=clen=0; net2hostL(uac_id,action,k); if(!(headers.s=pkg_malloc(MAX_HEADER))){ LM_ERR("Out of Memory!!"); goto error; } headers.len=0; LM_DBG("Action UAC Message: uac_id:%d processor_id=%d\n",uac_id,processor_id); if (!(my_msg = parse_ac_msg(HDR_EOH_F,action+k,len-k))) { LM_ERR("out of memory!\n"); goto error; } if(my_msg->first_line.type==SIP_REPLY){ LM_ERR("trying to create a UAC with a SIP response!!\n"); goto error; } if(parse_headers(my_msg,HDR_EOH_F,0)==-1){ LM_ERR("ERROR:seas:ac_uac_req:parsing headers\n"); goto error; } if(parse_from_header(my_msg)<0){ LM_ERR("parsing from header ! \n"); goto error; } if(check_transaction_quadruple(my_msg)==0){ as_action_fail_resp(uac_id,SE_UAC,"Headers missing (to,from,call-id,cseq)?",0); LM_ERR("Headers missing (to,from,call-id,cseq)?"); goto error; } if(!(get_from(my_msg)) || !(get_from(my_msg)->tag_value.s) || !(get_from(my_msg)->tag_value.len)){ as_action_fail_resp(uac_id,SE_UAC,"From tag missing",0); LM_ERR("From tag missing"); goto error; } fb=my_msg->from->parsed; tb=my_msg->to->parsed; cseqb=my_msg->cseq->parsed; if(0!=(str2int(&cseqb->number,&cseq))){ LM_DBG("unable to parse CSeq\n"); goto error; } if(my_msg->first_line.u.request.method_value != METHOD_ACK && my_msg->first_line.u.request.method_value != METHOD_CANCEL) { /** we trick req_within */ cseq--; } if(seas_f.tmb.new_dlg_uac(&(my_msg->callid->body),&(fb->tag_value),cseq,\ &(fb->uri),&(tb->uri),&my_dlg) < 0) { as_action_fail_resp(uac_id,SE_UAC,"Error creating new dialog",0); LM_ERR("Error while creating new dialog\n"); goto error; } if(seas_f.tmb.dlg_add_extra(my_dlg,&(fb->display),&(tb->display)) < 0 ) { as_action_fail_resp(uac_id,SE_UAC, "Error adding the display names to the new dialog",0); LM_ERR("failed to add display names to the new dialog\n"); goto error; } if(tb->tag_value.s && tb->tag_value.len) shm_str_dup(&my_dlg->id.rem_tag,&tb->tag_value); /**Awful hack: to be able to set our own CSeq, from_tag and call-ID we have * to use req_within instead of req_outside (it sets it's own CSeq,Call-ID * and ftag), so we have to simulate that the dialog is already in completed * state so... */ server_signature=0; my_dlg->state = DLG_CONFIRMED; if(0>(headers.len=extract_allowed_headers(my_msg,1,-1,HDR_CONTENTLENGTH_F|HDR_ROUTE_F|HDR_TO_F|HDR_FROM_F|HDR_CALLID_F|HDR_CSEQ_F,headers.s,MAX_HEADER))) { LM_ERR("Unable to extract allowed headers!!\n"); goto error; } headers.s[headers.len]=0; /*let's get the body*/ if(my_msg->content_length) clen=(long)get_content_length(my_msg); if(clen!=0){ if(!(body.s=pkg_malloc(clen))){ LM_ERR("Out of Memory!"); goto error; } memcpy(body.s,get_body(my_msg),clen); body.len=clen; body.s[clen]=0; LM_DBG("Trying to construct a Sip Request with: body:%d[%.*s] headers:%d[%.*s]\n",\ body.len,body.len,body.s,headers.len,headers.len,headers.s); /*t_reply_with_body un-ref-counts the transaction, so dont use it anymore*/ }else{ body.s=NULL; body.len=0; } /*Now... create the UAC !! * it would be great to know the hash_index and the label that have been assigned * to our newly created cell, but t_uac does not leave any way for us to know... * only that when that transaction transitions its state (ie. a response is received, * a timeout is reached, etc...) the callback will be called with the given parameter. * * So the only way we have to know who we are, is passing as a parameter a structure with * 2 pointers: one to the app_server and the other, the identifier of the UAC (uac_id). * */ if(!(the_param=shm_malloc(sizeof(struct as_uac_param)))){ LM_ERR("out of shared memory\n"); goto error; } the_param->who=my_as; the_param->uac_id=uac_id; the_param->processor_id=processor_id; the_param->destroy_cb_set=0; shm_str_dup(&my_dlg->rem_target,&my_msg->first_line.u.request.uri); if (my_msg->route) { if (parse_rr(my_msg->route) < 0) { LM_ERR( "Error while parsing Route body\n"); goto error; } /* TODO route_set should be a shm copy of my_msg->route->parsed */ my_dlg->route_set=(rr_t*)my_msg->route->parsed; /** this SHOULD be: shm_duplicate_rr(&my_dlg->route_set,my_msg->route->parsed); * but it will last more... */ } calculate_hooks(my_dlg); if(flags & SPIRAL_FLAG){ memcpy(headers.s+headers.len,SPIRAL_HDR CRLF,SPIRAL_HDR_LEN + CRLF_LEN); headers.len+=SPIRAL_HDR_LEN+CRLF_LEN; headers.s[headers.len]=0; fake_uri.s=pkg_malloc(200); fake_uri.len=print_local_uri(the_as,processor_id,fake_uri.s,200); if(fake_uri.len<0){ LM_ERR("printing local uri\n"); goto error; } my_dlg->hooks.next_hop=&fake_uri; } /* Kamailio and OpenSIPs seem to have diverged quite a bit on flags and events notified to UACs. Let's see if kamailio gets it right by now, if not this is a TODO: check PASS_PROVISIONAL my_dlg->T_flags=T_NO_AUTO_ACK|T_PASS_PROVISIONAL_FLAG ; this is the same as (TMCB_DONT_ACK|TMCB_LOCAL_RESPONSE_OUT) in Kamailio */ set_uac_req(&uac_r, &(my_msg->first_line.u.request.method), &headers, &body, my_dlg,TMCB_DONT_ACK|TMCB_LOCAL_RESPONSE_OUT, uac_cb, (void*)the_param); ret=seas_f.tmb.t_request_within(&uac_r); /** now undo all the fakes we have put in my_dlg*/ /*because my_dlg->route_set should be shm but we fake it (its pkg_mem)*/ my_dlg->route_set=(rr_t *)0; if (ret < 0) { err_ret = err2reason_phrase(ret,&sip_error,err_buf, sizeof(err_buf), "SEAS/UAC"); LM_ERR("failed to send the [%.*s] request\n",uac_r.method->len,uac_r.method->s); LM_ERR("Error on request_within %s\n",err_buf ); if(err_ret > 0) { as_action_fail_resp(uac_id,ret,err_buf,0); }else{ as_action_fail_resp(uac_id,E_UNSPEC,"500 SEAS/UAC error",0); } goto error; } retval=0; goto exit; error: retval = -1; if(the_param) shm_free(the_param); exit: seas_f.tmb.free_dlg(my_dlg); if(headers.s) pkg_free(headers.s); if(body.s) pkg_free(body.s); if(fake_uri.s) pkg_free(fake_uri.s); if(my_msg){ if(my_msg->headers) free_hdr_field_lst(my_msg->headers); pkg_free(my_msg); } return retval; }
int send_sip_msg_request(str *to, str *from_user, str *body) { str msg_type = STR_STATIC_INIT("MESSAGE"); str from; str hdrs; int foo; char *p; uac_req_t uac_r; from.s = hdrs.s = 0; from.len = hdrs.len = 0; /* From header */ from.len = 6 /*"<sip:+"*/ + from_user->len/*user*/ + 1/*"@"*/ + domain.len /*host*/ + 1 /*">"*/ ; from.s = (char*)pkg_malloc(from.len); if (!from.s) goto error; p=from.s; append_str(p,"<sip:+",6); append_str(p,from_user->s,from_user->len); *(p++)='@'; append_str(p,domain.s,domain.len); *(p++)='>'; /* hdrs = Contact header + Content-type */ /* length */ hdrs.len = CONTENT_TYPE_HDR_LEN + CRLF_LEN; if (use_contact) hdrs.len += 15 /*"Contact: <sip:+"*/ + from_user->len/*user*/ + 1/*"@"*/ + domain.len/*host*/ + 1 /*">"*/ + CRLF_LEN; hdrs.s = (char*)pkg_malloc(hdrs.len); if (!hdrs.s) goto error; p=hdrs.s; append_str(p,CONTENT_TYPE_HDR,CONTENT_TYPE_HDR_LEN); append_str(p,CRLF,CRLF_LEN); if (use_contact) { append_str(p,"Contact: <sip:+",15); append_str(p,from_user->s,from_user->len); *(p++)='@'; append_str(p,domain.s,domain.len); append_str(p,">"CRLF,1+CRLF_LEN); } /* sending the request */ set_uac_req(&uac_r, &msg_type, /* request type */ &hdrs, /* Additional headers including CRLF */ body, /* Message body */ 0, /* dialog structure */ 0, /* callback flags */ 0, /* Callback function */ 0 /* Callback parameter */ ); foo = tmb.t_request(&uac_r, 0, /* Request-URI */ to, /* To */ &from, /* From */ 0 /* next hop */ ); if (from.s) pkg_free(from.s); if (hdrs.s) pkg_free(hdrs.s); return foo; error: LM_ERR("no free pkg memory!\n"); if (from.s) pkg_free(from.s); if (hdrs.s) pkg_free(hdrs.s); return -1; }
int r_send_third_party_reg(r_third_party_registration *r, int expires) { str h = {0, 0}; str b = {0, 0}; uac_req_t req; LM_DBG("r_send_third_party_reg: REGISTER to <%.*s>\n", r->req_uri.len, r->req_uri.s); h.len = event_hdr.len + max_fwds_hdr.len; h.len += expires_s.len + 12 + expires_e.len; h.len += contact_s.len + isc_my_uri_sip.len + contact_e.len; if (r->pvni.len) h.len += p_visited_network_id_s.len + p_visited_network_id_e.len + r->pvni.len; if (r->pani.len) h.len += p_access_network_info_s.len + p_access_network_info_e.len + r->pani.len; if (r->cv.len) h.len += p_charging_vector_s.len + p_charging_vector_e.len + r->cv.len; if (r->path.len) h.len += path_s.len + path_e.len + r->path.len + 6/*',' and ';lr' and '<' and '>'*/ + r->from.len /*adding our own address to path*/; h.s = pkg_malloc(h.len); if (!h.s) { LM_ERR("r_send_third_party_reg: Error allocating %d bytes\n", h.len); h.len = 0; return 0; } h.len = 0; STR_APPEND(h, event_hdr); STR_APPEND(h, max_fwds_hdr); STR_APPEND(h, expires_s); sprintf(h.s + h.len, "%d", expires); h.len += strlen(h.s + h.len); STR_APPEND(h, expires_e); if (r->path.len) { STR_APPEND(h, path_s); STR_APPEND(h, path_mine_s); STR_APPEND(h, r->from); STR_APPEND(h, path_mine_e); STR_APPEND(h, comma); STR_APPEND(h, r->path); STR_APPEND(h, path_e); } STR_APPEND(h, contact_s); STR_APPEND(h, isc_my_uri_sip); STR_APPEND(h, contact_e); if (r->pvni.len) { STR_APPEND(h, p_visited_network_id_s); STR_APPEND(h, r->pvni); STR_APPEND(h, p_visited_network_id_e); } if (r->pani.len) { STR_APPEND(h, p_access_network_info_s); STR_APPEND(h, r->pani); STR_APPEND(h, p_access_network_info_e); } if (r->cv.len) { STR_APPEND(h, p_charging_vector_s); STR_APPEND(h, r->cv); STR_APPEND(h, p_charging_vector_e); } LM_DBG("SRV INFO:<%.*s>\n", r->service_info.len, r->service_info.s); if (r->service_info.len) { b.len = body_s.len + r->service_info.len + body_e.len; b.s = pkg_malloc(b.len); if (!b.s) { LM_ERR("r_send_third_party_reg: Error allocating %d bytes\n", b.len); b.len = 0; return 0; } b.len = 0; STR_APPEND(b, body_s); STR_APPEND(b, r->service_info); STR_APPEND(b, body_e); } set_uac_req(&req, &method, &h, &b, 0, TMCB_RESPONSE_IN | TMCB_ON_FAILURE | TMCB_LOCAL_COMPLETED, r_third_party_reg_response, &(r->req_uri)); if (isc_tmb.t_request(&req, &(r->req_uri), &(r->to), &(r->from), 0) < 0) { LM_ERR("r_send_third_party_reg: Error sending in transaction\n"); goto error; } if (h.s) pkg_free(h.s); return 1; error: if (h.s) pkg_free(h.s); return 0; }
int send_subscribe(subs_info_t* subs) { ua_pres_t* presentity= NULL; str met= {"SUBSCRIBE", 9}; str* str_hdr= NULL; int ret= -1; unsigned int hash_code=0; ua_pres_t* hentity= NULL; int expires; int flag; int result; uac_req_t uac_r; db1_res_t *res=NULL; ua_pres_t dbpres; str pres_uri={0,0}, watcher_uri={0,0}, extra_headers={0,0}; dlg_t* td= NULL; memset(&dbpres, 0, sizeof(dbpres)); dbpres.pres_uri = &pres_uri; dbpres.watcher_uri = &watcher_uri; dbpres.extra_headers = &extra_headers; print_subs(subs); flag= subs->source_flag; if(subs->source_flag & XMPP_INITIAL_SUBS) subs->source_flag= XMPP_SUBSCRIBE; if(subs->expires< 0) expires= 3600; else expires= subs->expires; str_hdr= subs_build_hdr(subs->contact, expires, subs->event, subs->extra_headers); if(str_hdr== NULL || str_hdr->s== NULL) { LM_ERR("while building extra headers\n"); return -1; } if (dbmode == PUA_DB_ONLY && pua_dbf.start_transaction) { if (pua_dbf.start_transaction(pua_db, db_table_lock) < 0) { LM_ERR("in start_transaction\n"); goto error; } } /* generation of hash and getting lock moved from here to further down */ if (dbmode==PUA_DB_ONLY) { presentity = get_dialog_puadb(subs->id, subs->pres_uri, &dbpres, &res); } else { ua_pres_t pres; memset(&pres, 0, sizeof(ua_pres_t)); pres.pres_uri = subs->pres_uri; pres.watcher_uri = subs->watcher_uri; pres.flag = subs->source_flag; pres.id = subs->id; pres.event = subs->event; if (subs->remote_target) pres.remote_contact = *subs->remote_target; hash_code=core_hash(subs->pres_uri, subs->watcher_uri, HASH_SIZE); lock_get(&HashT->p_records[hash_code].lock); presentity= search_htable(&pres, hash_code); } /* if flag == INSERT_TYPE insert no matter what the search result is */ if(subs->flag & INSERT_TYPE) { LM_DBG("A subscription request with insert type\n"); goto insert; } if(presentity== NULL ) { int size; insert: if (subs->expires == 0) { /* Don't create a new dialog when expires == 0 */ if (dbmode != PUA_DB_ONLY) lock_release(&HashT->p_records[hash_code].lock); goto done; } if(subs->flag & UPDATE_TYPE) { LM_DBG("request for a subscription with update type" " and no record found\n"); subs->flag= INSERT_TYPE; } hentity= subscribe_cbparam(subs, REQ_OTHER); if(hentity== NULL) { LM_ERR("while building callback" " param\n"); if (dbmode != PUA_DB_ONLY) lock_release(&HashT->p_records[hash_code].lock); goto error; } hentity->flag= flag; set_uac_req(&uac_r, &met, str_hdr, 0, 0, TMCB_LOCAL_COMPLETED, subs_cback_func, (void*)hentity); result= tmb.t_request_outside (&uac_r, /* Type of the message */ subs->remote_target?subs->remote_target:subs->pres_uri,/* Request-URI*/ subs->pres_uri, /* To */ subs->watcher_uri, /* From */ subs->outbound_proxy /* Outbound_proxy */ ); if(result< 0) { LM_ERR("while sending request with t_request\n"); if (uac_r.dialog != NULL) { uac_r.dialog->rem_target.s = 0; uac_r.dialog->dst_uri.s = 0; tmb.free_dlg(uac_r.dialog); uac_r.dialog = 0; } shm_free(hentity); if (dbmode != PUA_DB_ONLY) lock_release(&HashT->p_records[hash_code].lock); /* Although this is an error must not return -1 as the calling function must continue processing. */ ret = 0; goto error; } /* Now create a temporary hash table entry. This is needed to deal with the race-hazard when NOTIFYs arrive before the 2xx response to the SUBSCRIBE. */ size = sizeof(ua_pres_t)+ 2 * sizeof(str) + ( subs->pres_uri->len + subs->watcher_uri->len + uac_r.dialog->id.loc_tag.len + uac_r.dialog->id.call_id.len + subs->id.len) * sizeof(char); presentity= (ua_pres_t*)shm_malloc(size); if(presentity== NULL) { LM_ERR("no more share memory\n"); if (dbmode != PUA_DB_ONLY) lock_release(&HashT->p_records[hash_code].lock); goto error; } memset(presentity, 0, size); size= sizeof(ua_pres_t); presentity->pres_uri = (str *) ((char *) presentity + size); size += sizeof(str); presentity->pres_uri->s= (char *) presentity + size; memcpy(presentity->pres_uri->s, subs->pres_uri->s, subs->pres_uri->len); presentity->pres_uri->len= subs->pres_uri->len; size+= subs->pres_uri->len; presentity->watcher_uri= (str *) ((char *) presentity + size); size += sizeof(str); presentity->watcher_uri->s= (char *) presentity + size; memcpy(presentity->watcher_uri->s, subs->watcher_uri->s, subs->watcher_uri->len); presentity->watcher_uri->len = subs->watcher_uri->len; size += subs->watcher_uri->len; presentity->call_id.s = (char *) presentity + size; memcpy(presentity->call_id.s, uac_r.dialog->id.call_id.s, uac_r.dialog->id.call_id.len); presentity->call_id.len = uac_r.dialog->id.call_id.len; size += uac_r.dialog->id.call_id.len; presentity->from_tag.s = (char *) presentity + size; memcpy(presentity->from_tag.s, uac_r.dialog->id.loc_tag.s, uac_r.dialog->id.loc_tag.len); presentity->from_tag.len= uac_r.dialog->id.loc_tag.len; size += uac_r.dialog->id.loc_tag.len; presentity->id.s = (char *) presentity+ size; memcpy(presentity->id.s, subs->id.s, subs->id.len); presentity->id.len = subs->id.len; size += subs->id.len; presentity->event = subs->event; presentity->flag = subs->source_flag; presentity->cseq = uac_r.dialog->loc_seq.value; /* Set the temporary record expiry for 2 * 64T1 seconds from now */ presentity->expires= (int)time(NULL) + 64; presentity->desired_expires= presentity->expires; if (dbmode==PUA_DB_ONLY) { insert_dialog_puadb(presentity); shm_free(presentity); } else { insert_htable(presentity, hash_code); lock_release(&HashT->p_records[hash_code].lock); } uac_r.dialog->rem_target.s = 0; uac_r.dialog->dst_uri.s = 0; tmb.free_dlg(uac_r.dialog); uac_r.dialog = 0; } else { if (subs->internal_update_flag == INTERNAL_UPDATE_TRUE) { LM_INFO("attempting to re-SUBSCRIBE on internal (rls_update_subs()) update - skipping\n"); if (dbmode != PUA_DB_ONLY) lock_release(&HashT->p_records[hash_code].lock); goto done; } if (presentity->to_tag.len == 0) { if (subs->expires > 0) LM_WARN("attempting to re-SUBSCRIBE to a temporary (non-established) dialog - skipping\n"); else { LM_WARN("attempting to un-SUBSCRIBE from a temporary (non-established) dialog - skipping and deleting dialog\n"); if (dbmode==PUA_DB_ONLY) delete_dialog_puadb(presentity); else delete_htable(presentity, hash_code); } if (dbmode != PUA_DB_ONLY) lock_release(&HashT->p_records[hash_code].lock); goto done; } td= pua_build_dlg_t(presentity); if(td== NULL) { LM_ERR("while building tm dlg_t structure"); if (dbmode!=PUA_DB_ONLY) lock_release(&HashT->p_records[hash_code].lock); goto error; } hentity= subs_cbparam_indlg(presentity, expires, REQ_OTHER); if(hentity== NULL) { LM_ERR("while building callback param\n"); if (dbmode!=PUA_DB_ONLY) lock_release(&HashT->p_records[hash_code].lock); goto error; } if (dbmode!=PUA_DB_ONLY) lock_release(&HashT->p_records[hash_code].lock); LM_DBG("event parameter: %d\n", hentity->event); set_uac_req(&uac_r, &met, str_hdr, 0, td, TMCB_LOCAL_COMPLETED, subs_cback_func, (void*)hentity); result= tmb.t_request_within(&uac_r); if(result< 0) { shm_free(hentity); hentity= NULL; LM_ERR("while sending request with t_request\n"); goto error; } } done: if (dbmode == PUA_DB_ONLY && pua_dbf.end_transaction) { if (pua_dbf.end_transaction(pua_db) < 0) { LM_ERR("in end_transaction\n"); goto error; } } ret = 0; error: pua_free_tm_dlg(td); pkg_free(str_hdr); free_results_puadb(res); if (dbmode == PUA_DB_ONLY && pua_dbf.abort_transaction) { if (pua_dbf.abort_transaction(pua_db) < 0) LM_ERR("in abort_transaction\n"); } return ret; }
int send_publish( publ_info_t* publ ) { str met = {"PUBLISH", 7}; str* str_hdr = NULL; ua_pres_t* presentity= NULL; str* body= NULL; str* tuple_id= NULL; ua_pres_t* cb_param= NULL; unsigned int hash_code=0; str etag= {0, 0}; int ver= 0; int result; int ret_code= 0; pua_event_t* ev= NULL; uac_req_t uac_r; db1_res_t *res=NULL; ua_pres_t dbpres; str pres_uri={0,0}, watcher_uri={0,0}, extra_headers={0,0}; int ret = -1; LM_DBG("pres_uri=%.*s\n", publ->pres_uri->len, publ->pres_uri->s ); if (dbmode == PUA_DB_ONLY && pua_dbf.start_transaction) { if (pua_dbf.start_transaction(pua_db, db_table_lock) < 0) { LM_ERR("in start_transaction\n"); goto error; } } /* get event from list */ ev= get_event(publ->event); if(ev== NULL) { LM_ERR("event not found in list\n"); goto error; } if (dbmode==PUA_DB_ONLY) { if (publ->etag) { memset(&dbpres, 0, sizeof(dbpres)); dbpres.pres_uri = &pres_uri; dbpres.watcher_uri = &watcher_uri; dbpres.extra_headers = &extra_headers; presentity = get_record_puadb(publ->id, publ->etag, &dbpres, &res); } } else { ua_pres_t pres; memset(&pres, 0, sizeof(ua_pres_t)); pres.pres_uri = publ->pres_uri; pres.flag = publ->source_flag; pres.id = publ->id; pres.event = publ->event; if(publ->etag) pres.etag = *publ->etag; hash_code= core_hash(publ->pres_uri, NULL, HASH_SIZE); lock_get(&HashT->p_records[hash_code].lock); presentity= search_htable(&pres, hash_code); } if(publ->etag && presentity== NULL) { if (dbmode!=PUA_DB_ONLY) lock_release(&HashT->p_records[hash_code].lock); ret = 418; goto error; } if(publ->flag & INSERT_TYPE) { LM_DBG("Insert flag set\n"); goto insert; } if(presentity== NULL) { insert: if (dbmode!=PUA_DB_ONLY) lock_release(&HashT->p_records[hash_code].lock); LM_DBG("insert type\n"); if(publ->flag & UPDATE_TYPE ) { LM_DBG("UPDATE_TYPE and no record found \n"); publ->flag= INSERT_TYPE; } if(publ->expires== 0) { LM_DBG("request for a publish with expires 0 and" " no record found\n"); goto done; } if(publ->body== NULL) { LM_ERR("New PUBLISH and no body found- invalid request\n"); ret = ERR_PUBLISH_NO_BODY; goto error; } } else { LM_DBG("record found\n"); publ->flag= UPDATE_TYPE; etag.s= (char*)pkg_malloc(presentity->etag.len* sizeof(char)); if(etag.s== NULL) { LM_ERR("while allocating memory\n"); if (dbmode!=PUA_DB_ONLY) lock_release(&HashT->p_records[hash_code].lock); goto error; } memcpy(etag.s, presentity->etag.s, presentity->etag.len); etag.len= presentity->etag.len; if(presentity->tuple_id.s && presentity->tuple_id.len) { /* get tuple_id*/ tuple_id=(str*)pkg_malloc(sizeof(str)); if(tuple_id== NULL) { LM_ERR("No more memory\n"); if (dbmode!=PUA_DB_ONLY) lock_release(&HashT->p_records[hash_code].lock); goto error; } tuple_id->s= (char*)pkg_malloc(presentity->tuple_id.len* sizeof(char)); if(tuple_id->s== NULL) { LM_ERR("No more memory\n"); if (dbmode!=PUA_DB_ONLY) lock_release(&HashT->p_records[hash_code].lock); goto error; } memcpy(tuple_id->s, presentity->tuple_id.s, presentity->tuple_id.len); tuple_id->len= presentity->tuple_id.len; } if(publ->expires== 0) { LM_DBG("expires= 0- delete from hash table\n"); if (dbmode!=PUA_DB_ONLY) lock_release(&HashT->p_records[hash_code].lock); goto send_publish; } presentity->version++; ver= presentity->version; if (dbmode==PUA_DB_ONLY) { update_version_puadb(presentity); } else { lock_release(&HashT->p_records[hash_code].lock); } } /* handle body */ if(publ->body && publ->body->s) { ret_code= ev->process_body(publ, &body, ver, &tuple_id ); if( ret_code< 0 || body== NULL) { LM_ERR("while processing body\n"); if(body== NULL) LM_ERR("NULL body\n"); goto error; } } if(tuple_id) LM_DBG("tuple_id= %.*s\n", tuple_id->len, tuple_id->s ); send_publish: /* construct the callback parameter */ if(etag.s && etag.len) publ->etag = &etag; cb_param= publish_cbparam(publ, body, tuple_id, REQ_OTHER); if(cb_param== NULL) { LM_ERR("constructing callback parameter\n"); goto error; } if(publ->flag & UPDATE_TYPE) LM_DBG("etag:%.*s\n", etag.len, etag.s); str_hdr = publ_build_hdr((publ->expires< 0)?3600:publ->expires, ev, &publ->content_type, (publ->flag & UPDATE_TYPE)?&etag:NULL, publ->extra_headers, (body)?1:0); if(str_hdr == NULL) { LM_ERR("while building extra_headers\n"); goto error; } LM_DBG("publ->pres_uri:\n%.*s\n ", publ->pres_uri->len, publ->pres_uri->s); LM_DBG("str_hdr:\n%.*s %d\n ", str_hdr->len, str_hdr->s, str_hdr->len); if(body && body->len && body->s ) LM_DBG("body:\n%.*s\n ", body->len, body->s); set_uac_req(&uac_r, &met, str_hdr, body, 0, TMCB_LOCAL_COMPLETED, publ_cback_func, (void*)cb_param); result= tmb.t_request(&uac_r, publ->pres_uri, /*! Request-URI */ publ->pres_uri, /*! To */ publ->pres_uri, /*! From */ publ->outbound_proxy? publ->outbound_proxy:&outbound_proxy /*! Outbound proxy*/ ); if(result< 0) { LM_ERR("in t_request tm module function\n"); goto error; } done: ret = 0; if (dbmode == PUA_DB_ONLY && pua_dbf.end_transaction) { if (pua_dbf.end_transaction(pua_db) < 0) { LM_ERR("in end_transaction\n"); goto error; } } goto finish; error: if(cb_param) shm_free(cb_param); if (dbmode == PUA_DB_ONLY && pua_dbf.abort_transaction) { if (pua_dbf.abort_transaction(pua_db) < 0) LM_ERR("in abort_transaction\n"); } finish: if(etag.s) pkg_free(etag.s); if(body && ret_code) { if(body->s) xmlFree(body->s); pkg_free(body); } if(str_hdr) pkg_free(str_hdr); if(tuple_id) { if(tuple_id->s) pkg_free(tuple_id->s); pkg_free(tuple_id); } free_results_puadb(res); return ret; }