/* 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; }
/* 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_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(¬ify_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; }