예제 #1
0
/* look for subscriber cell using callid and to_tag of Notify*/
struct sm_subscriber* get_subs_cell(struct sip_msg *msg) {

    str callid;
    struct to_body *pto= NULL, *pfrom = NULL;

    if ( parse_headers(msg,HDR_EOH_F, 0) == -1 ){
        LM_ERR("error in parsing headers\n");
        return NULL;
    }
    if(check_event_header(msg) == 0){
        LM_ERR("event not allow\n");
        return NULL;
    }

    // get callid from Notify
    if( msg->callid==NULL || msg->callid->body.s==NULL){
        LM_ERR("reply without callid header\n");
        return NULL;
    }
    callid = msg->callid->body;
    LM_DBG("CALLID: %.*s \n ", callid.len, callid.s );

    if (msg->from->parsed == NULL){
        if ( parse_from_header( msg )<0 ){
            LM_ERR("reply without From header\n");
            return NULL;
        }
    }

    //get From header from Notify
    pfrom = get_from(msg);
    LM_DBG("PFROM: %.*s \n ", pfrom->uri.len, pfrom->uri.s );

    if( pfrom->tag_value.s ==NULL || pfrom->tag_value.len == 0){
        LM_ERR("reply without 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 Notify
    pto = get_to(msg);
    if (pto == NULL || pto->error != PARSE_OK) {
        LM_ERR("failed to parse TO header\n");
        return NULL;
    }
    if( pto->tag_value.s ==NULL || pto->tag_value.len == 0){
        LM_ERR("reply without tag value \n");
        //return 0;
    }
    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 );

    return find_subscriber_cell(&callid, &pto->tag_value);
}
예제 #2
0
/* Treat Notify to Subscriber Dialog in scenario III*/
int treat_notify(struct sip_msg *msg) {

	int resp = 1;
	struct sm_subscriber*  cell_subs;
	int expires= 0;
	char *subs_state, *subs_expires;
	str callid_orig;
	str from_tag;
	struct notify_body* notify_body = NULL;
	time_t rawtime;
	int time_now;
	int version;
	char *version_init, *version_end, *version_aux;
	int size_version;
	unsigned int hash_code;
	str callid_event;
	static str msg200={"OK Notify",sizeof("OK Notify")-1};
	static str msg481={"Subscription does not exist",sizeof("Subscription does not exist")-1};
	static str msg489={"Bad Event",sizeof("Bad Event")-1};
	static str msg400={"Bad Request",sizeof("Bad Request")-1};

	if(!check_event_header(msg)){
		LM_ERR("event header type not allow\n");
		if(!eme_tm.t_reply(msg,489,&msg489)){
			LM_ERR("t_reply (489)\n");
		}
		return 0;
	}

	if ( parse_headers(msg,HDR_EOH_F, 0) == -1 ){
		LM_ERR("error in parsing headers\n");
		return 0;
	}

	// get callid from Notify
	if( msg->callid==NULL || msg->callid->body.s==NULL){
		LM_ERR("reply without callid header\n");
		return 0;
	}
	callid_event = msg->callid->body;
	LM_DBG("CALLID: %.*s \n ", callid_event.len, callid_event.s );

	/* look for cell in list linked subs_pt with same dialog Id*/
	cell_subs = get_subs_cell(msg, callid_event);
	if(cell_subs == NULL){
		if(!eme_tm.t_reply(msg,481,&msg481)){
			LM_ERR("t_reply (481)\n");
		}
		return 0;
	}

	LM_DBG("STATUS: %d \n ", cell_subs->dlg_id->status);
	LM_DBG("TIMEOUT NOTIFY: %d \n ", cell_subs->timeout);

	/* get in Subscription_state header: state and expire */
	if(!get_subscription_state_header(msg, &subs_state, &subs_expires)){
		LM_ERR("invalid body of Subscription_state header\n");
		if(!eme_tm.t_reply(msg,400,&msg400)){
			LM_ERR("t_reply (400)\n");
		}
		return 0;
	}
	LM_DBG("STATE: %s\n ", subs_state);
	LM_DBG("SUBS_EXPIRES: %s\n ", subs_expires);

	time(&rawtime);
	time_now = (int)rawtime;

	/* analise state value*/
	if (strcmp(subs_state, "active") == 0){
		cell_subs->dlg_id->status = ACTIVE;
		cell_subs->expires = atoi(subs_expires);
		cell_subs->timeout =  cell_subs->expires + time_now;
	}else{
		if (strcmp(subs_state, "pending") == 0){
			cell_subs->dlg_id->status = PENDING ;
			cell_subs->expires = atoi(subs_expires);
			cell_subs->timeout =  TIMER_N + time_now;
		}else{
			if(strcmp(subs_state, "terminated") == 0){

				/* state is terminated indicate that subcriber dialog finish
				   then pull cell of the list linked and send esct to VPC*/
				LM_DBG(" --- CLEAR CELL \n");
				callid_orig = cell_subs->call_dlg_id->callid;
				from_tag = cell_subs->call_dlg_id->local_tag;

				LM_DBG(" --- CALLID_ORIG %.*s \n", callid_orig.len, callid_orig.s);
				LM_DBG(" --- FROM_TAG_ORIG %.*s \n", from_tag.len, from_tag.s);

				if(send_esct(msg, callid_orig, from_tag) == 0){
					LM_ERR("error in send to esct\n");
				}

				hash_code= core_hash(&callid_event, 0, subst_size);
				LM_DBG("********************************************HASH_CODE%d\n", hash_code);

				delete_shtable(subs_htable, hash_code, cell_subs);

				/* Reply OK to Notify*/
				if(!eme_tm.t_reply(msg,200,&msg200)){
					LM_ERR("t_reply (200)\n");
					return 0;
				}
				return 1;

			}else{
				LM_ERR("INCOMPATIBLE RECEIVED STATUS\n");
				if(!eme_tm.t_reply(msg,400,&msg400)){
					LM_ERR("t_reply (400)\n");
				}
				return 0;
			}
		}
	}

	LM_DBG("STATUS: %d \n ", cell_subs->dlg_id->status);
	LM_DBG(" --- NOTIFY BODY %s", msg->eoh);

	notify_body = parse_notify(msg->eoh);
	if( notify_body == NULL){
		LM_ERR("invalid body in Notify request\n");
		if(!eme_tm.t_reply(msg,400,&msg400)){
			LM_ERR("t_reply (400)\n");
		}
		resp = 0;
		goto end;
	}

	version_init = strchr(notify_body->params->version,'\"');
	version_init++;
	version_end = strchr(version_init,'\"');
	size_version = version_end - version_init;
	version_aux = pkg_malloc(size_version + 1);
	if (version_aux == NULL) {
		LM_ERR("no more pkg memory\n");
		return 0;
	}
	memcpy(version_aux, version_init, size_version );
	version_aux[size_version] = '\0';
	version = atoi(version_aux);
	pkg_free(version_aux);
	LM_DBG(" --- STATE %s", notify_body->state);
	LM_DBG(" --- VERSION %d", version);

	/* Reply OK to Notify*/
	if(!eme_tm.t_reply(msg,200,&msg200)){
		LM_DBG("t_reply (200)\n");
		free_parsed_notify(notify_body);
		resp = 0;
		goto end;
	}

	if(cell_subs->version >= version){
		LM_ERR(" --- ERRO IN VERSION PARAMETER IN NOTIFY BODY");
		free_parsed_notify(notify_body);
		resp = 0;
		goto end;
	}else{
		cell_subs->version  = version;
	}


	/* if Notify body state has terminated value, which indicates that emergency call finish,
	   then send subscribe with expire=0 to terminate the subscriber dialog*/
	if(strcmp(notify_body->state, "terminated") == 0){
		expires = 0;
		LM_DBG(" --- STATE %s", notify_body->state);
		if(send_subscriber_within(msg, cell_subs, expires) == -1){
			LM_ERR(" --- Error in send subscriber terminated \n");
		}
	}

	resp = 1;
	free_parsed_notify(notify_body);

end:
	pkg_free(subs_state);
	pkg_free(subs_expires);
	return resp;
}
예제 #3
0
/* Treat Notify to Subscriber Dialog in scenario III*/
int treat_subscribe(struct sip_msg *msg) {

	struct cell *t;
	static str msg200={"OK Subscribe",sizeof("OK Subscribe")-1};
	static str msg423={"Interval Too Brief",sizeof("Interval Too Brief")-1};
	static str msg481={"Subscription does not exist",sizeof("Subscription does not exist")-1};
	static str msg489={"Bad Event",sizeof("Bad Event")-1};
	struct sm_subscriber *notify_cell = NULL;
	struct sm_subscriber *pt_notify = NULL;
	char  *subs_expires;
	int expires= 0;
	char *subs_callid, *subs_fromtag;
	str callid_event;
	unsigned int hash_code;

	if(!check_event_header(msg)){
		LM_ERR("event header type not allow\n");
		if(!eme_tm.t_reply(msg,489,&msg489)){
			LM_ERR("t_reply (489)\n");
		}
		return 0;
	}

	/* get expires field */
	if(!get_expires_header(msg, &subs_expires)){
		LM_ERR("body's expires header not found\n");
		expires =  TIME_DEFAULT_SUBS;
	}else{
		LM_DBG("SUBS_EXPIRES: %s\n ", subs_expires);
		// if expires body isn't a numerical string, then expires value is zero
		expires = atoi(subs_expires);
		pkg_free(subs_expires);
		if ((expires != 0) & (expires < TIMER_MIN_SUBS)){
			/* Reply NOK to Notify*/
			if(!eme_tm.t_reply(msg,423,&msg423)){
				LM_DBG("t_reply (423)\n");
			}
			return 0;
		}
	}

	if (expires == 0){

		if(get_event_header(msg, &subs_callid, &subs_fromtag) == 1){
			callid_event.s = subs_callid;
			callid_event.len = strlen(subs_callid);
		}else{
			LM_ERR("error in Event Header of Subscriber\n");
			return 0;
		}

		pt_notify = get_subs_cell(msg, callid_event);

		if (pt_notify == NULL){
			LM_ERR("**** notify cell not found\n");
			if(!eme_tm.t_reply(msg,481,&msg481)){
				LM_ERR("t_reply (481)\n");
			}
			return 0;
		}
		pt_notify->dlg_id->status =  TERMINATED;
		pt_notify->expires =  0;

		pkg_free(subs_callid);
		pkg_free(subs_fromtag);

		/* Reply OK to Notify*/
		if(!eme_tm.t_reply(msg,200,&msg200)){
			LM_DBG("t_reply (200)\n");
			return 0;
		}

	}else{
		notify_cell =  build_notify_cell(msg, expires);
		if (notify_cell == NULL){
			LM_ERR("**** error in build notify cell\n");
			if(!eme_tm.t_reply(msg,489,&msg489)){
				LM_ERR("t_reply (489)\n");
			}
			return 0;
		}
		/* Reply OK to Notify*/
		if(!eme_tm.t_reply(msg,200,&msg200)){
			LM_DBG("t_reply (200)\n");
			pkg_free(notify_cell);
			return 0;
		}

		t = eme_tm.t_gett();

		LM_DBG(" --- TO TAG %.*s \n", t->uas.local_totag.len, t->uas.local_totag.s);

		notify_cell->dlg_id->local_tag.s = pkg_malloc(t->uas.local_totag.len + 1);
		if (!notify_cell->dlg_id->local_tag.s) {
			LM_ERR("no more shm\n");
			return 0;
		}
		notify_cell->dlg_id->local_tag.s[t->uas.local_totag.len] = 0;
		notify_cell->dlg_id->local_tag.len = t->uas.local_totag.len;
		memcpy(notify_cell->dlg_id->local_tag.s, t->uas.local_totag.s, t->uas.local_totag.len);
		LM_DBG("SUBS_FROM_TAG: %.*s \n ", notify_cell->dlg_id->local_tag.len, notify_cell->dlg_id->local_tag.s );

		hash_code= core_hash(&notify_cell->call_dlg_id->callid, 0, subst_size);
		LM_DBG("********************************************HASH_CODE%d\n", hash_code);
		LM_DBG("********************************************CALLID_STR%.*s\n", notify_cell->call_dlg_id->callid.len, notify_cell->call_dlg_id->callid.s);

		pt_notify = insert_shtable(subs_htable, hash_code, notify_cell);
		if(pt_notify == NULL){
			LM_ERR("inserting new record in subs_htable\n");
			return 0;
		}

		pkg_free(notify_cell->dlg_id->local_tag.s);
		pkg_free(notify_cell);

	}

	if( !send_notifier_within(msg, pt_notify)){
		LM_ERR("send_notifier_within\n");
		return 0;
	}

	return 1;
}