/* get data from Subscriber and save in list link with notify information: . dialog id of emergency call . dialog id of subscribe . local uri . remote uri . contact . expires . time to expire subscriber - status . cell next . cell previus */ struct sm_subscriber* build_notify_cell(struct sip_msg *msg, int expires){ char *subs_callid, *subs_fromtag; str callid_event; str fromtag_event; str callid; struct to_body *pto= NULL, *pfrom = NULL; int size_notify_cell; int vsp_addr_len; char *vsp_addr = "@vsp.com"; int vsp_port = 5060; int size_vsp_port = 4; char* str_vsp_port; struct sm_subscriber *notify_cell = NULL; time_t rawtime; int time_now; char *p; unsigned int hash_code; static str msg489={"Bad Event",sizeof("Bad Event")-1}; // get data from SUBSCRIBE request // get callid from Subscribe if( msg->callid==NULL || msg->callid->body.s==NULL){ LM_ERR("subscribe without callid header\n"); return NULL; } callid = msg->callid->body; LM_DBG("CALLID: %.*s \n ", callid.len, callid.s ); //get From header from Subscribe if (msg->from->parsed == NULL){ if ( parse_from_header( msg )<0 ){ LM_ERR("subscribe without From header\n"); return NULL; } } pfrom = get_from(msg); LM_DBG("PFROM: %.*s \n ", pfrom->uri.len, pfrom->uri.s ); LM_DBG("PFROM_TAG: %.*s \n ", pfrom->tag_value.len, pfrom->tag_value.s ); if( pfrom->tag_value.s ==NULL || pfrom->tag_value.len == 0){ LM_ERR("subscribe without from_tag value \n"); return NULL; } if( msg->to==NULL || msg->to->body.s==NULL){ LM_ERR("error in parse TO header\n"); return NULL; } // get To header from Subscribe pto = get_to(msg); if (pto == NULL || pto->error != PARSE_OK) { LM_ERR("failed to parse TO header\n"); return NULL; } LM_DBG("PTO: %.*s \n ", pto->uri.len, pto->uri.s ); LM_DBG("PTO_TAG: %.*s \n ", pto->tag_value.len, pto->tag_value.s ); /* get in event header: callid and from_tag */ if(get_event_header(msg, &subs_callid, &subs_fromtag) != 1){ LM_ERR("failed to parse Event header\n"); return NULL; } LM_DBG("SUBS_CALLID: %s\n ", subs_callid); LM_DBG("SUBS_FROMTAG: %s\n ", subs_fromtag); callid_event.s = subs_callid; callid_event.len = strlen(subs_callid); fromtag_event.s = subs_fromtag; fromtag_event.len = strlen(subs_fromtag); hash_code= core_hash(&callid_event, 0, emet_size); LM_DBG("********************************************HASH_CODE%d\n", hash_code); // search call hash with hash_code, callidHeader and from/to_tag params if (search_ehtable(call_htable, subs_callid, subs_fromtag, hash_code, 0) == NULL) { LM_ERR(" ---CALLID NOT FOUND IN SHTABLE\n"); if(!eme_tm.t_reply(msg,489,&msg489)){ LM_DBG("t_reply (489)\n"); } pkg_free(callid_event.s); pkg_free(fromtag_event.s); return 0; } LM_DBG("CALLID OK in subs_hash\n"); time(&rawtime); time_now = (int)rawtime; LM_DBG("TIME : %d \n", (int)rawtime ); // get source ip address that send INVITE vsp_addr = ip_addr2a(&msg->rcv.src_ip); vsp_addr_len = strlen(vsp_addr); vsp_port = msg->rcv.src_port; str_vsp_port= int2str(vsp_port, &size_vsp_port); LM_DBG("SRC_PORT : %s \n", str_vsp_port); /* build notifier cell */ size_notify_cell = sizeof(struct sm_subscriber) + (2 * sizeof(struct dialog_id)) + callid.len + pfrom->tag_value.len + pto->tag_value.len + pfrom->uri.len + pto->uri.len + callid_event.len + fromtag_event.len + vsp_addr_len + size_vsp_port + 11 ; notify_cell = pkg_malloc(size_notify_cell + 1); if (!notify_cell) { LM_ERR("no more shm\n"); return NULL; } memset(notify_cell, 0, size_notify_cell + 1); notify_cell->expires = expires; LM_DBG("EXPIRES: %d \n ", notify_cell->expires ); notify_cell->timeout = TIMER_N + time_now; LM_DBG("SUBS_TIMEOUT: %d \n ", notify_cell->timeout ); notify_cell->version = 0; LM_DBG("SUBS_VERSION: %d \n ", notify_cell->version ); notify_cell->dlg_id = (struct dialog_id*)(notify_cell + 1); notify_cell->dlg_id->callid.len = callid.len; notify_cell->dlg_id->callid.s = (char *) (notify_cell->dlg_id + 1); memcpy(notify_cell->dlg_id->callid.s, callid.s, callid.len); LM_DBG("SUBS_CALLID: %.*s \n ", notify_cell->dlg_id->callid.len, notify_cell->dlg_id->callid.s ); notify_cell->dlg_id->rem_tag.len = pfrom->tag_value.len; notify_cell->dlg_id->rem_tag.s = (char *) (notify_cell->dlg_id + 1) + callid.len; memcpy(notify_cell->dlg_id->rem_tag.s, pfrom->tag_value.s, pfrom->tag_value.len); LM_DBG("SUBS_FROM_TAG: %.*s \n ", notify_cell->dlg_id->rem_tag.len, notify_cell->dlg_id->rem_tag.s ); p = (char *)(notify_cell->dlg_id + 1) + callid.len + pfrom->tag_value.len; notify_cell->call_dlg_id = (struct dialog_id*)p; notify_cell->call_dlg_id->callid.len= callid_event.len; notify_cell->call_dlg_id->callid.s = (char *) (notify_cell->call_dlg_id + 1); memcpy(notify_cell->call_dlg_id->callid.s, callid_event.s, callid_event.len); LM_DBG("SUBS_CALLID_event: %.*s \n ", notify_cell->call_dlg_id->callid.len, notify_cell->call_dlg_id->callid.s ); notify_cell->call_dlg_id->rem_tag.len= fromtag_event.len; notify_cell->call_dlg_id->rem_tag.s = (char *) (notify_cell->call_dlg_id + 1) + callid_event.len; memcpy(notify_cell->call_dlg_id->rem_tag.s, fromtag_event.s, fromtag_event.len); LM_DBG("SUBS_FROMTAG_event: %.*s \n ", notify_cell->call_dlg_id->rem_tag.len, notify_cell->call_dlg_id->rem_tag.s ); notify_cell->loc_uri.len = pto->uri.len; notify_cell->loc_uri.s = (char *) (notify_cell->call_dlg_id + 1) + callid_event.len + fromtag_event.len; memcpy(notify_cell->loc_uri.s,pto->uri.s,pto->uri.len); LM_DBG("SUBS_LOC_URI: %.*s \n ", notify_cell->loc_uri.len, notify_cell->loc_uri.s ); notify_cell->rem_uri.len= pfrom->uri.len; notify_cell->rem_uri.s = (char *) (notify_cell->call_dlg_id + 1) + callid_event.len + fromtag_event.len + pto->uri.len; memcpy(notify_cell->rem_uri.s, pfrom->uri.s, pfrom->uri.len); LM_DBG("SUBS_REM_URI: %.*s \n ", notify_cell->rem_uri.len, notify_cell->rem_uri.s ); notify_cell->contact.len = vsp_addr_len + size_vsp_port +11; notify_cell->contact.s = (char *) (notify_cell->call_dlg_id + 1) + pfrom->uri.len + pto->uri.len + callid_event.len + fromtag_event.len; memcpy(notify_cell->contact.s, "sip:teste@", 10); memcpy(notify_cell->contact.s + 10, vsp_addr, vsp_addr_len); memcpy(notify_cell->contact.s + 10 + vsp_addr_len, ":", 1); memcpy(notify_cell->contact.s + 11 + vsp_addr_len, str_vsp_port, size_vsp_port); LM_DBG("SUBS_CONTACT: %.*s \n ", notify_cell->contact.len, notify_cell->contact.s ); notify_cell->dlg_id->status = RESP_WAIT; pkg_free(callid_event.s); pkg_free(fromtag_event.s); return notify_cell; }
/* finish the emergency call frees resources: - pull call cell this call from list linked eme_calls - send esct to VPC to release ESQK Key*/ int send_esct(struct sip_msg *msg, str callid_ori, str from_tag){ char* esct_callid; NODE* info_call; char* xml = NULL; time_t rawtime; struct tm * timeinfo; char* response; int resp; char* callidHeader; char* ftag; unsigned int hash_code; str callid; callidHeader = pkg_malloc(callid_ori.len + 1); if(callidHeader == NULL){ LM_ERR("No memory left\n"); return -1; } memset(callidHeader, 0, callid_ori.len + 1); memcpy(callidHeader, callid_ori.s, callid_ori.len); ftag = pkg_malloc(from_tag.len + 1); if(ftag == NULL){ LM_ERR("No memory left\n"); return -1; } memset(ftag, 0, from_tag.len + 1); memcpy(ftag, from_tag.s, from_tag.len); // extract call cell with same callid from list linked eme_calls LM_DBG(" --- BYE callid=%s \n", callidHeader); callid.s = callidHeader, callid.len = strlen(callidHeader); hash_code= core_hash(&callid, 0, emet_size); LM_DBG("********************************************HASH_CODE%d\n", hash_code); info_call= search_ehtable(call_htable, callidHeader, ftag, hash_code, 1); if (info_call == NULL) { LM_ERR(" --- BYE DID NOT FIND CALLID \n"); return -1; }else{ if (collect_data(info_call, db_url, *db_table) == 1) { LM_DBG("****** REPORT OK\n"); } else { LM_DBG("****** REPORT NOK\n"); } } if (strlen(info_call->esct->esqk) > 0){ // if VPC provide ESQK then opensips need send esct to free this key LM_DBG(" --- SEND ESQK =%s\n \n",info_call->esct->esqk); time(&rawtime); timeinfo = localtime(&rawtime); strftime(info_call->esct->datetimestamp, MAX_TIME_SIZE, "%Y-%m-%dT%H:%M:%S%Z", timeinfo); LM_DBG(" --- TREAT BYE - XML ESCT %s \n \n", xml); xml = buildXmlFromModel(info_call->esct); // sends HTTP POST esctRequest to VPC resp = post(url_vpc, xml, &response); if (resp == -1) { LM_ERR(" --- PROBLEM IN POST DO BYE\n \n"); shm_free(info_call); pkg_free(xml); return -1; } // verify if esct response came OK esct_callid = parse_xml_esct(response); if (esct_callid== NULL) { LM_ERR(" --- esctAck invalid format or without mandatory field \n \n"); } else { if (strcmp(esct_callid, callidHeader)){ LM_ERR(" --- callid in esctAck different from asctRequest \n \n"); } if(esct_callid) pkg_free(esct_callid); } pkg_free(response); pkg_free(xml); } shm_free(info_call->esct->esgwri); shm_free(info_call); return 1; }