Example #1
0
/* 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;

}
Example #2
0
/* 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;

}