Example #1
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;
}
/* 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;
    struct notify_body* notify_body = NULL;
    struct sm_subscriber* next;
    struct sm_subscriber* previous;
    time_t rawtime;
    int time_now;
    static str msg200={"OK Notify",sizeof("OK Notify")-1};



    /* look for cell in list linked subs_pt with same dialog Id*/
    cell_subs = get_subs_cell(msg);
    LM_INFO("STATUS: %d \n ", cell_subs->status);
    LM_INFO("TIMEOUT: %d \n ", cell_subs->timeout);

    /* get in Subscription_state header: state and expire */
    if(get_subscription_state_header(msg, &subs_state, &subs_expires) == 1){
        LM_INFO("STATE: %s\n ", subs_state);
        LM_INFO("SUBS_EXPIRES: %s\n ", subs_expires);
    }


    time(&rawtime);
    time_now = (int)rawtime;
    LM_INFO("TIME : %d \n", (int)rawtime );

    /* analise state value*/
    if (strcmp(subs_state, "active") == 0){
       cell_subs->status = ACTIVE;
       cell_subs->expires = atoi(subs_expires);
       cell_subs->timeout =  cell_subs->expires + time_now;
        LM_INFO("TIMEOUT: %d \n ", cell_subs->timeout);
    }else{
        if (strcmp(subs_state, "pending") == 0){
            cell_subs->status = PENDING ;
            cell_subs->expires = atoi(subs_expires);
            cell_subs->timeout =  TIMER_B + 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_INFO(" --- CLEAR CELL \n");
                callid_orig = cell_subs->callid_ori;

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

                next = cell_subs->next;
                previous = cell_subs->prev;
                if (previous == NULL){
                    if (next == NULL){;
                        *subs_pt = NULL;
                    }else{
                        *subs_pt = next;
                    }
                }else{
                    previous->next = next;
                }

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

            }else{
                LM_ERR("INCOMPATIBLE RECEIVED STATUS\n");
                resp = 0;
                goto end;
            }
        }
    }

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

    notify_body = parse_notify(msg->eoh);
    LM_INFO(" --- STATE %s", notify_body->state);

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

    /* 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_INFO(" --- STATE %s", notify_body->state);
        if(send_subscriber_within(msg, cell_subs, expires) == -1){
            LM_ERR(" --- Error in send subscriber terminated \n");
        }
    }

    resp = 1;
end:
    pkg_free(subs_state);
    pkg_free(subs_expires);
    return resp;
}