/*Create cell to control Subscriber Dialog States This cell save this information: - Dialog Id: .Callid .rem_tag .local_tag - expires - Local_uri - Remote_uri - Notifier_uri - INVITE's Callid - Event body - State */ int create_subscriber_cell(struct sip_msg* reply, struct parms_cb* params_cb){ str* callid = NULL; int expires= 0; struct to_body *pto= NULL, *pfrom = NULL; int size_subs_cell; int vsp_addr_len; char *vsp_addr = "@vsp.com"; time_t rawtime; int time_now; struct sm_subscriber *subs_cell = NULL; char *p; unsigned int hash_code; callid= (str*) pkg_malloc (sizeof (str)); if (callid == NULL) { LM_ERR("--------------------------------------------------no more pkg memory\n"); return 0; } /*Verify repĺy is OK and get callid and expires from response*/ if ( !extract_reply_headers(reply, callid, expires)){ LM_ERR("fail in extract headers\n"); pkg_free(callid); return 0; } /*get From header fields */ pfrom = get_from(reply); 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"); pkg_free(callid); return 0; } /*get To header fields */ pto = get_to(reply); LM_DBG("PTO: %.*s \n ", pto->uri.len, pto->uri.s ); if (pto == NULL || pto->error != PARSE_OK) { LM_ERR("failed to parse TO header\n"); pkg_free(callid); return 0; } // get source ip address that send INVITE vsp_addr = ip_addr2a(&reply->rcv.src_ip); vsp_addr_len = strlen(vsp_addr); time(&rawtime); time_now = (int)rawtime; LM_DBG("TIME : %d \n", (int)rawtime ); /* build subscriber cell */ size_subs_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 + params_cb->callid_ori.len + params_cb->event.len + params_cb->from_tag.len + vsp_addr_len + 9 ; subs_cell = pkg_malloc(size_subs_cell + 1); if (!subs_cell) { LM_ERR("no more shm\n"); return 0; } memset(subs_cell, 0, size_subs_cell + 1); subs_cell->expires = expires; subs_cell->timeout = TIMER_N + time_now; LM_DBG("SUBS_TIMEOUT: %d \n ", subs_cell->timeout ); subs_cell->version = -1; subs_cell->dlg_id = (struct dialog_id*)(subs_cell + 1); subs_cell->dlg_id->callid.len = callid->len; subs_cell->dlg_id->callid.s = (char *) (subs_cell->dlg_id + 1); memcpy(subs_cell->dlg_id->callid.s, callid->s, callid->len); LM_DBG("SUBS_CALLID: %.*s \n ", subs_cell->dlg_id->callid.len, subs_cell->dlg_id->callid.s ); subs_cell->dlg_id->local_tag.len = pfrom->tag_value.len; subs_cell->dlg_id->local_tag.s = (char *) (subs_cell->dlg_id + 1) + callid->len; memcpy(subs_cell->dlg_id->local_tag.s, pfrom->tag_value.s, pfrom->tag_value.len); LM_DBG("SUBS_FROM_TAG: %.*s \n ", subs_cell->dlg_id->local_tag.len, subs_cell->dlg_id->local_tag.s ); subs_cell->dlg_id->rem_tag.len = pto->tag_value.len; subs_cell->dlg_id->rem_tag.s = (char *) (subs_cell->dlg_id + 1) + callid->len + pfrom->tag_value.len; memcpy(subs_cell->dlg_id->rem_tag.s, pto->tag_value.s, pto->tag_value.len); LM_DBG("SUBS_TO_TAG: %.*s \n ", subs_cell->dlg_id->rem_tag.len, subs_cell->dlg_id->rem_tag.s ); p = (char *)(subs_cell->dlg_id + 1) + callid->len + pfrom->tag_value.len + pto->tag_value.len; subs_cell->call_dlg_id = (struct dialog_id*)p; subs_cell->call_dlg_id->callid.len= params_cb->callid_ori.len; subs_cell->call_dlg_id->callid.s = (char *) (subs_cell->call_dlg_id + 1); memcpy(subs_cell->call_dlg_id->callid.s, params_cb->callid_ori.s, params_cb->callid_ori.len); LM_DBG("SUBS_CALLID_ORI: %.*s \n ", subs_cell->call_dlg_id->callid.len, subs_cell->call_dlg_id->callid.s ); subs_cell->call_dlg_id->local_tag.len= params_cb->from_tag.len; subs_cell->call_dlg_id->local_tag.s = (char *) (subs_cell->call_dlg_id + 1) + params_cb->callid_ori.len; memcpy(subs_cell->call_dlg_id->local_tag.s, params_cb->from_tag.s, params_cb->from_tag.len); LM_DBG("SUBS_FROMTAG_event: %.*s \n ", subs_cell->call_dlg_id->local_tag.len, subs_cell->call_dlg_id->local_tag.s ); subs_cell->loc_uri.len = pfrom->uri.len; subs_cell->loc_uri.s = (char *) (subs_cell->call_dlg_id + 1) + params_cb->callid_ori.len + params_cb->from_tag.len; memcpy(subs_cell->loc_uri.s,pfrom->uri.s,pfrom->uri.len); LM_DBG("SUBS_LOC_URI: %.*s \n ", subs_cell->loc_uri.len, subs_cell->loc_uri.s ); subs_cell->rem_uri.len= pto->uri.len; subs_cell->rem_uri.s = (char *) (subs_cell->call_dlg_id + 1) + params_cb->callid_ori.len + params_cb->from_tag.len + pfrom->uri.len; memcpy(subs_cell->rem_uri.s, pto->uri.s, pto->uri.len); LM_DBG("SUBS_REM_URI: %.*s \n ", subs_cell->rem_uri.len, subs_cell->rem_uri.s ); subs_cell->event.len= params_cb->event.len; subs_cell->event.s = (char *) (subs_cell->call_dlg_id + 1) + params_cb->callid_ori.len + params_cb->from_tag.len + pfrom->uri.len + pto->uri.len; memcpy(subs_cell->event.s, params_cb->event.s, params_cb->event.len); LM_DBG("SUBS_EVENT: %.*s \n ", subs_cell->event.len, subs_cell->event.s ); subs_cell->contact.len = vsp_addr_len + 9; subs_cell->contact.s = (char *) (subs_cell->call_dlg_id + 1) + params_cb->callid_ori.len + params_cb->from_tag.len + pfrom->uri.len + pto->uri.len + params_cb->event.len; memcpy(subs_cell->contact.s, "sip:test@", 9); memcpy(subs_cell->contact.s + 9, vsp_addr, vsp_addr_len); LM_DBG("SUBS_CONTACT: %.*s \n ", subs_cell->contact.len, subs_cell->contact.s ); subs_cell->dlg_id->status = NOTIFY_WAIT; hash_code= core_hash(&subs_cell->dlg_id->callid, 0, subst_size); LM_DBG("********************************************HASH_CODE%d\n", hash_code); if(insert_shtable(subs_htable, hash_code,subs_cell) == NULL){ LM_ERR("inserting new record in subs_htable\n"); } pkg_free(subs_cell); pkg_free(callid); return 1; }
/* 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; }