void dialog_publish_multi(char *state, struct str_list* ruris, str *entity, str *peer, str *callid, unsigned int initiator, unsigned int lifetime, str *localtag, str *remotetag, str *localtarget, str *remotetarget, unsigned short do_pubruri_localcheck) { while(ruris) { LM_INFO("CALLING dialog_publish for URI %.*s\n",ruris->s.len, ruris->s.s); dialog_publish(state,&(ruris->s),entity,peer,callid,initiator,lifetime,localtag,remotetag,localtarget,remotetarget,do_pubruri_localcheck); ruris=ruris->next; } }
int dialoginfo_set(struct sip_msg* msg, char* flag_pv, char* str2) { struct dlg_cell * dlg; str peer_uri= {0, 0}; /* constructed from TO display name and RURI */ struct to_body* from, peer_to_body, FROM, *to; str* ruri; int len =0,ret=-1; char flag= DLG_PUB_AB; static char buf[256]; int buf_len= 255; str flag_str; char caller_buf[256], callee_buf[256]; pv_value_t tok; peer_to_body.param_lst = FROM.param_lst = NULL; if (msg->REQ_METHOD != METHOD_INVITE) return 1; if(dlg_api.create_dlg(msg,0)< 0) { LM_ERR("Failed to create dialog\n"); return -1; } dlg = dlg_api.get_dlg(); LM_DBG("new INVITE dialog created: from=%.*s\n", dlg->from_uri.len, dlg->from_uri.s); from = get_from(msg); /* if defined overwrite */ if(caller_spec_param.s) /* if parameter defined */ { memset(&tok, 0, sizeof(pv_value_t)); if(pv_get_spec_value(msg, &caller_spec, &tok) < 0) /* if value set */ { LM_ERR("Failed to get caller value\n"); return -1; } if(tok.flags&PV_VAL_STR) { str caller_str; if(tok.rs.len + CRLF_LEN > buf_len) { LM_ERR("Buffer overflow"); return -1; } trim(&tok.rs); memcpy(caller_buf, tok.rs.s, tok.rs.len); len = tok.rs.len; if(strncmp(tok.rs.s+len-CRLF_LEN, CRLF, CRLF_LEN)) { memcpy(caller_buf + len, CRLF, CRLF_LEN); len+= CRLF_LEN; } parse_to(caller_buf, caller_buf+len , &FROM); if(FROM.error != PARSE_OK) { LM_ERR("Failed to parse caller specification - not a valid uri\n"); goto end; } from = &FROM; caller_str.s = caller_buf; caller_str.len = len; LM_DBG("caller: %*s- len= %d\n", len, caller_buf, len); /* store caller in a dlg variable */ if(dlg_api.store_dlg_value(dlg, &entity_dlg_var, &caller_str)< 0) { LM_ERR("Failed to store dialog ruri\n"); goto end; } } } peer_uri.s = callee_buf; if(callee_spec_param.s) { memset(&tok, 0, sizeof(pv_value_t)); if(pv_get_spec_value(msg, &callee_spec, &tok) < 0) { LM_ERR("Failed to get callee value\n"); goto end; } if(tok.flags&PV_VAL_STR) { if(tok.rs.len + CRLF_LEN > buf_len) { LM_ERR("Buffer overflow"); goto end; } trim(&tok.rs); memcpy(peer_uri.s, tok.rs.s, tok.rs.len); len = tok.rs.len; if(strncmp(tok.rs.s+len-CRLF_LEN, CRLF, CRLF_LEN)) { memcpy(peer_uri.s + len, CRLF, CRLF_LEN); len+= CRLF_LEN; } peer_uri.len = len; } else goto default_callee; } else { default_callee: ruri = GET_RURI(msg); to = get_to(msg); len= to->display.len + 2 + ruri->len + CRLF_LEN; if(len > buf_len) { LM_ERR("Buffer overflow\n"); goto end; } len = 0; if(to->display.len && to->display.s) { memcpy(peer_uri.s, to->display.s, to->display.len); peer_uri.s[to->display.len]='<'; len = to->display.len + 1; } memcpy(peer_uri.s + len, ruri->s, ruri->len); len+= ruri->len; if(to->display.len) { peer_uri.s[len++]='>'; } memcpy(peer_uri.s + len, CRLF, CRLF_LEN); len+= CRLF_LEN; peer_uri.len = len; } LM_DBG("Peer uri = %.*s\n", peer_uri.len, peer_uri.s); parse_to(peer_uri.s, peer_uri.s+peer_uri.len, &peer_to_body); if(peer_to_body.error != PARSE_OK) { LM_ERR("Failed to peer uri [%.*s]\n", peer_uri.len, peer_uri.s); goto end; } /* store peer uri in dialog structure */ if(dlg_api.store_dlg_value(dlg, &peer_dlg_var, &peer_uri)< 0) { LM_ERR("Failed to store dialog ruri\n"); goto end; } /* store flag, if defined */ if(flag_pv) { if(pv_printf(msg, (pv_elem_t*)flag_pv, buf, &buf_len)<0) { LM_ERR("cannot print the format\n"); goto end; } if(!check_flag(buf, buf_len)) { LM_ERR("Wrong value for flag\n"); goto end; } flag = buf[0]; flag_str.s = buf; flag_str.len = buf_len; if(dlg_api.store_dlg_value(dlg, &flag_dlg_var, &flag_str)< 0) { LM_ERR("Failed to store dialog ruri\n"); goto end; } } /* register dialog callbacks which triggers sending PUBLISH */ if (dlg_api.register_dlgcb(dlg, DLGCB_FAILED| DLGCB_CONFIRMED | DLGCB_TERMINATED | DLGCB_EXPIRED | DLGCB_RESPONSE_WITHIN | DLGCB_EARLY, __dialog_sendpublish, 0, 0) != 0) { LM_ERR("cannot register callback for interesting dialog types\n"); goto end; } #ifdef PUA_DIALOGINFO_DEBUG /* dialog callback testing (registered last to be executed first) */ if (dlg_api.register_dlgcb(dlg, DLGCB_FAILED| DLGCB_CONFIRMED | DLGCB_REQ_WITHIN | DLGCB_TERMINATED | DLGCB_EXPIRED | DLGCB_EARLY | DLGCB_RESPONSE_FWDED | DLGCB_RESPONSE_WITHIN | DLGCB_MI_CONTEXT | DLGCB_DESTROY, __dialog_cbtest, NULL, NULL) != 0) { LM_ERR("cannot register callback for all dialog types\n"); goto end; } #endif if(publish_on_trying) { if(flag == DLG_PUB_A || flag == DLG_PUB_AB) dialog_publish("trying", from, &peer_to_body, &(dlg->callid), 1, DEFAULT_CREATED_LIFETIME, 0, 0); if(flag == DLG_PUB_B || flag == DLG_PUB_AB) dialog_publish("trying", &peer_to_body, from, &(dlg->callid), 0, DEFAULT_CREATED_LIFETIME, 0, 0); } ret=1; end: if (peer_to_body.param_lst) free_to_params(&peer_to_body); if (FROM.param_lst) free_to_params(&FROM); return ret; }
static void __dialog_sendpublish(struct dlg_cell *dlg, int type, struct dlg_cb_params *_params) { str tag = {0,0}; struct to_body from; str peer_uri= {0, 0}; char flag = DLG_PUB_AB; str flag_str; struct to_body peer_to_body; str entity_uri= {0, 0}; int buf_len = 255; struct sip_msg* msg = _params->msg; flag_str.s = &flag; flag_str.len = 1; memset(&from, 0, sizeof(struct to_body)); memset(&peer_to_body, 0, sizeof(struct to_body)); from.uri = dlg->from_uri; peer_uri.len = buf_len; peer_uri.s = (char*)pkg_malloc(buf_len); if(peer_uri.s == NULL) { LM_ERR("No more memory\n"); goto error; } /* extract the peer_uri */ if(dlg_api.fetch_dlg_value(dlg, &peer_dlg_var, &peer_uri, 1) < 0 || peer_uri.len==0) { LM_ERR("Failed to fetch peer uri dialog variable\n"); goto error; } LM_DBG("peer_uri = %.*s\n", peer_uri.len, peer_uri.s); parse_to(peer_uri.s, peer_uri.s+peer_uri.len, &peer_to_body); if(peer_to_body.error != PARSE_OK) { LM_ERR("Failed to peer uri [%.*s]\n", peer_uri.len, peer_uri.s); goto error; } /* try to extract the flag */ dlg_api.fetch_dlg_value(dlg, &flag_dlg_var, &flag_str, 1); LM_DBG("flag = %c\n", flag); entity_uri.len = buf_len; entity_uri.s = (char*)pkg_malloc(buf_len); if(entity_uri.s == NULL) { LM_ERR("No more memory\n"); goto error; } /* check if entity is also custom */ if(dlg_api.fetch_dlg_value(dlg, &entity_dlg_var, &entity_uri, 1) == 0) { /* overwrite from with this value */ parse_to(entity_uri.s, entity_uri.s + entity_uri.len, &from); if(from.error != PARSE_OK) { LM_ERR("Wrong format for entity body\n"); goto error; } LM_DBG("entity_uri = %.*s\n", entity_uri.len, entity_uri.s); LM_DBG("from uri = %.*s\n", from.uri.len, from.uri.s); } switch (type) { case DLGCB_FAILED: case DLGCB_TERMINATED: case DLGCB_EXPIRED: LM_DBG("dialog over, from=%.*s\n", dlg->from_uri.len, dlg->from_uri.s); if(flag == DLG_PUB_AB || flag == DLG_PUB_A) dialog_publish("terminated", &from, &peer_to_body, &(dlg->callid), 1, 0, 0, 0); if(flag == DLG_PUB_AB || flag == DLG_PUB_B) dialog_publish("terminated", &peer_to_body, &from, &(dlg->callid), 0, 0, 0, 0); break; case DLGCB_RESPONSE_WITHIN: if (get_cseq(msg)->method_id==METHOD_INVITE) { if (msg->flags & nopublish_flag) { LM_DBG("nopublish flag was set for this INVITE\n"); break; } LM_DBG("nopublish flag not set for this INVITE, will publish\n"); } else { /* no publish for non-INVITEs */ break; } case DLGCB_CONFIRMED: LM_DBG("dialog confirmed, from=%.*s\n", dlg->from_uri.len, dlg->from_uri.s); if(flag == DLG_PUB_AB || flag == DLG_PUB_A) dialog_publish("confirmed", &from, &peer_to_body, &(dlg->callid), 1, dlg->lifetime, 0, 0); if(flag == DLG_PUB_AB || flag == DLG_PUB_B) dialog_publish("confirmed", &peer_to_body, &from, &(dlg->callid), 0, dlg->lifetime, 0, 0); break; case DLGCB_EARLY: LM_DBG("dialog is early, from=%.*s\n", from.uri.len, from.uri.s); if (include_tags) { /* get to tag*/ if ( !_params->msg->to && ((parse_headers(_params->msg, HDR_TO_F,0)<0) || !_params->msg->to) ) { LM_ERR("bad reply or missing TO hdr :-/\n"); tag.s = 0; tag.len = 0; } else { tag = get_to(_params->msg)->tag_value; if (tag.s==0 || tag.len==0) { LM_ERR("missing TAG param in TO hdr :-/\n"); tag.s = 0; tag.len = 0; } } if(flag == DLG_PUB_AB || flag == DLG_PUB_A) { if (caller_confirmed) { dialog_publish("confirmed", &from, &peer_to_body, &(dlg->callid), 1, dlg->lifetime, &(dlg->legs[DLG_CALLER_LEG].tag), &tag); } else { dialog_publish("early", &from, &peer_to_body, &(dlg->callid), 1, dlg->lifetime, &(dlg->legs[DLG_CALLER_LEG].tag), &tag); } } if(flag == DLG_PUB_AB || flag == DLG_PUB_B) { dialog_publish("early", &peer_to_body, &from, &(dlg->callid), 0, dlg->lifetime, &tag, &(dlg->legs[DLG_CALLER_LEG].tag)); } } else { if(flag == DLG_PUB_AB || flag == DLG_PUB_A) { if (caller_confirmed) { dialog_publish("confirmed", &from, &peer_to_body, &(dlg->callid), 1, dlg->lifetime, 0, 0); } else { dialog_publish("early", &from, &peer_to_body, &(dlg->callid), 1, dlg->lifetime, 0, 0); } } if(flag == DLG_PUB_AB || flag == DLG_PUB_B) { dialog_publish("early", &peer_to_body, &from, &(dlg->callid), 0, dlg->lifetime, 0, 0); } } break; default: LM_ERR("unhandled dialog callback type %d received, from=%.*s\n", type, dlg->from_uri.len, dlg->from_uri.s); if(flag == DLG_PUB_AB || flag == DLG_PUB_A) dialog_publish("terminated", &from, &peer_to_body, &(dlg->callid), 1, 0, 0, 0); if(flag == DLG_PUB_AB || flag == DLG_PUB_B) dialog_publish("terminated", &peer_to_body, &from, &(dlg->callid), 0, 0, 0, 0); } error: if(peer_uri.s) pkg_free(peer_uri.s); if(entity_uri.s) pkg_free(entity_uri.s); if (peer_to_body.param_lst) free_to_params(&peer_to_body); if (from.param_lst) free_to_params(&from); }