diff --git a/modules/ims_qos/cdpeventprocessor.c b/modules/ims_qos/cdpeventprocessor.c index 390b5a5b1c7..82fc2f8242e 100644 --- a/modules/ims_qos/cdpeventprocessor.c +++ b/modules/ims_qos/cdpeventprocessor.c @@ -64,262 +64,272 @@ extern int cdp_event_list_size_threshold; extern struct ims_qos_counters_h ims_qos_cnts_h; extern int terminate_dialog_on_rx_failure; - -int init_cdp_cb_event_list() { - cdp_event_list = shm_malloc(sizeof (cdp_cb_event_list_t)); - if (!cdp_event_list) { - LM_ERR("No more SHM mem\n"); - return 0; - } - memset(cdp_event_list, 0, sizeof (cdp_cb_event_list_t)); - cdp_event_list->lock = lock_alloc(); - if (!cdp_event_list->lock) { - LM_ERR("failed to create cdp event list lock\n"); - return 0; - } - cdp_event_list->lock = lock_init(cdp_event_list->lock); - cdp_event_list->size = 0; - - sem_new(cdp_event_list->empty, 0); //pre-locked - as we assume list is empty at start - - return 1; +extern int delete_contact_on_rx_failure; + +int init_cdp_cb_event_list() +{ + cdp_event_list = shm_malloc(sizeof(cdp_cb_event_list_t)); + if (!cdp_event_list) { + LM_ERR("No more SHM mem\n"); + return 0; + } + memset(cdp_event_list, 0, sizeof(cdp_cb_event_list_t)); + cdp_event_list->lock = lock_alloc(); + if (!cdp_event_list->lock) { + LM_ERR("failed to create cdp event list lock\n"); + return 0; + } + cdp_event_list->lock = lock_init(cdp_event_list->lock); + cdp_event_list->size = 0; + + sem_new(cdp_event_list->empty, 0); //pre-locked - as we assume list is empty at start + + return 1; } -void destroy_cdp_cb_event_list() { - cdp_cb_event_t *ev, *tmp; - - lock_get(cdp_event_list->lock); - ev = cdp_event_list->head; - while (ev) { - tmp = ev->next; - free_cdp_cb_event(ev); - ev = tmp; - } - lock_destroy(cdp_event_list->lock); - lock_dealloc(cdp_event_list->lock); - shm_free(cdp_event_list); +void destroy_cdp_cb_event_list() +{ + cdp_cb_event_t *ev, *tmp; + + lock_get(cdp_event_list->lock); + ev = cdp_event_list->head; + while (ev) { + tmp = ev->next; + free_cdp_cb_event(ev); + ev = tmp; + } + lock_destroy(cdp_event_list->lock); + lock_dealloc(cdp_event_list->lock); + shm_free(cdp_event_list); } -cdp_cb_event_t* new_cdp_cb_event(int event, str *rx_session_id, rx_authsessiondata_t *session_data) { - cdp_cb_event_t *new_event = shm_malloc(sizeof (cdp_cb_event_t)); - if (!new_event) { - LM_ERR("no more shm mem\n"); - return NULL; - } - memset(new_event, 0, sizeof (cdp_cb_event_t)); - - //we have to make a copy of the rx session id because it is not in shm mem - if ((rx_session_id->len > 0) && rx_session_id->s) { - LM_DBG("Creating new event for rx session [%.*s]\n", rx_session_id->len, rx_session_id->s); - new_event->rx_session_id.s = (char*) shm_malloc(rx_session_id->len); - if (!new_event->rx_session_id.s) { - LM_ERR("no more shm memory\n"); - shm_free(new_event); - return NULL; - } - memcpy(new_event->rx_session_id.s, rx_session_id->s, rx_session_id->len); - new_event->rx_session_id.len = rx_session_id->len; - } - - new_event->event = event; - new_event->registered = time(NULL); - new_event->session_data = session_data; //session_data is already in shm mem - - return new_event; +cdp_cb_event_t* new_cdp_cb_event(int event, str *rx_session_id, rx_authsessiondata_t *session_data) +{ + cdp_cb_event_t *new_event = shm_malloc(sizeof(cdp_cb_event_t)); + if (!new_event) { + LM_ERR("no more shm mem\n"); + return NULL; + } + memset(new_event, 0, sizeof(cdp_cb_event_t)); + + //we have to make a copy of the rx session id because it is not in shm mem + if ((rx_session_id->len > 0) && rx_session_id->s) { + LM_DBG("Creating new event for rx session [%.*s]\n", rx_session_id->len, rx_session_id->s); + new_event->rx_session_id.s = (char*) shm_malloc(rx_session_id->len); + if (!new_event->rx_session_id.s) { + LM_ERR("no more shm memory\n"); + shm_free(new_event); + return NULL; + } + memcpy(new_event->rx_session_id.s, rx_session_id->s, rx_session_id->len); + new_event->rx_session_id.len = rx_session_id->len; + } + + new_event->event = event; + new_event->registered = time(NULL); + new_event->session_data = session_data; //session_data is already in shm mem + + return new_event; } //add to tail -void push_cdp_cb_event(cdp_cb_event_t* event) { - lock_get(cdp_event_list->lock); - if (cdp_event_list->head == 0) { //empty list - cdp_event_list->head = cdp_event_list->tail = event; - } else { - cdp_event_list->tail->next = event; - cdp_event_list->tail = event; - } - cdp_event_list->size++; - if(cdp_event_list_size_threshold > 0 && cdp_event_list->size > cdp_event_list_size_threshold) { - LM_WARN("cdp_event_list is size [%d] and has exceed cdp_event_list_size_threshold of [%d]", cdp_event_list->size, cdp_event_list_size_threshold); - } - sem_release(cdp_event_list->empty); - lock_release(cdp_event_list->lock); +void push_cdp_cb_event(cdp_cb_event_t* event) +{ + lock_get(cdp_event_list->lock); + if (cdp_event_list->head == 0) { //empty list + cdp_event_list->head = cdp_event_list->tail = event; + } else { + cdp_event_list->tail->next = event; + cdp_event_list->tail = event; + } + cdp_event_list->size++; + if (cdp_event_list_size_threshold > 0 && cdp_event_list->size > cdp_event_list_size_threshold) { + LM_WARN("cdp_event_list is size [%d] and has exceed cdp_event_list_size_threshold of [%d]", cdp_event_list->size, cdp_event_list_size_threshold); + } + sem_release(cdp_event_list->empty); + lock_release(cdp_event_list->lock); } //pop from head -cdp_cb_event_t* pop_cdp_cb_event() { - cdp_cb_event_t *ev; +cdp_cb_event_t* pop_cdp_cb_event() +{ + cdp_cb_event_t *ev; - lock_get(cdp_event_list->lock); - while (cdp_event_list->head == 0) { - lock_release(cdp_event_list->lock); - sem_get(cdp_event_list->empty); - lock_get(cdp_event_list->lock); - } + lock_get(cdp_event_list->lock); + while (cdp_event_list->head == 0) { + lock_release(cdp_event_list->lock); + sem_get(cdp_event_list->empty); + lock_get(cdp_event_list->lock); + } - ev = cdp_event_list->head; - cdp_event_list->head = ev->next; + ev = cdp_event_list->head; + cdp_event_list->head = ev->next; - if (ev == cdp_event_list->tail) { //list now empty - cdp_event_list->tail = 0; - } - ev->next = 0; //make sure whoever gets this cant access our list - cdp_event_list->size--; - lock_release(cdp_event_list->lock); + if (ev == cdp_event_list->tail) { //list now empty + cdp_event_list->tail = 0; + } + ev->next = 0; //make sure whoever gets this cant access our list + cdp_event_list->size--; + lock_release(cdp_event_list->lock); - return ev; + return ev; } /*main event process function*/ -void cdp_cb_event_process() { - cdp_cb_event_t *ev; - udomain_t* domain; - pcontact_t* pcontact; - pcontact_info_t contact_info; - - struct pcontact_info ci; - memset(&ci, 0, sizeof (struct pcontact_info)); - - for (;;) { - ev = pop_cdp_cb_event(); - - if (cdp_event_latency) { //track delays - unsigned int diff = time(NULL) - ev->registered; - if (diff > cdp_event_threshold) { - switch (cdp_event_latency_loglevel) { - case 0: - LM_ERR("Took to long to pickup CDP callback event [%d] > [%d]\n", diff, cdp_event_threshold); - break; - case 1: - LM_WARN("Took to long to pickup CDP callback event [%d] > [%d]\n", diff, cdp_event_threshold); - break; - case 2: - LM_INFO("Took to long to pickup CDP callback event [%d] > [%d]\n", diff, cdp_event_threshold); - break; - case 3: - LM_DBG("Took to long to pickup CDP callback event [%d] > [%d]\n", diff, cdp_event_threshold); - break; - default: - LM_DBG("Unknown log level....printing as debug\n"); - LM_DBG("Took to long to pickup CDP callback event [%d] > [%d]\n", diff, cdp_event_threshold); - break; - } - } - } - LM_DBG("processing event [%d]\n", ev->event); - rx_authsessiondata_t *p_session_data = ev->session_data; - str *rx_session_id = &ev->rx_session_id; - - switch (ev->event) { - case AUTH_EV_SESSION_TIMEOUT: - case AUTH_EV_SESSION_GRACE_TIMEOUT: - case AUTH_EV_RECV_ASR: - LM_DBG("Received notification of ASR from transport plane or CDP timeout for CDP session with Rx session ID: [%.*s] and associated contact [%.*s]" - " and domain [%.*s]\n", - rx_session_id->len, rx_session_id->s, - p_session_data->registration_aor.len, p_session_data->registration_aor.s, - p_session_data->domain.len, p_session_data->domain.s); - - - if (p_session_data->subscribed_to_signaling_path_status) { - LM_DBG("This is a subscription to signalling bearer session"); - //nothing to do here - just wait for AUTH_EV_SERVICE_TERMINATED event - } else { - LM_DBG("This is a media bearer session session"); - //this is a media bearer session that was terminated from the transport plane - we need to terminate the associated dialog - //so we set p_session_data->must_terminate_dialog to 1 and when we receive AUTH_EV_SERVICE_TERMINATED event we will terminate the dialog - //we only terminate the dialog if terminate_dialog_on_rx_failure is set - if(terminate_dialog_on_rx_failure) { - p_session_data->must_terminate_dialog = 1; - } - } - break; - - case AUTH_EV_SERVICE_TERMINATED: - LM_DBG("Received notification of CDP TERMINATE of CDP session with Rx session ID: [%.*s] and associated contact [%.*s]" - " and domain [%.*s]\n", - rx_session_id->len, rx_session_id->s, - p_session_data->registration_aor.len, p_session_data->registration_aor.s, - p_session_data->domain.len, p_session_data->domain.s); - - if (p_session_data->subscribed_to_signaling_path_status) { - LM_DBG("This is a subscription to signalling bearer session"); - //instead of removing the contact from usrloc_pcscf we just change the state of the contact to TERMINATE_PENDING_NOTIFY - //pcscf_registrar sees this, sends a SIP PUBLISH and on SIP NOTIFY the contact is deleted - //note we only send SIP PUBLISH if the session has been successfully opened - - if(p_session_data->session_has_been_opened) { - if (ul.register_udomain(p_session_data->domain.s, &domain) - < 0) { - LM_DBG("Unable to register usrloc domain....aborting\n"); - return; - } - ul.lock_udomain(domain, &p_session_data->via_host, p_session_data->via_port, p_session_data->via_proto); - - contact_info.received_host = p_session_data->ip; - contact_info.received_port = p_session_data->recv_port; - contact_info.received_proto = p_session_data->recv_proto; - contact_info.searchflag = (1 << SEARCH_RECEIVED); - - contact_info.via_host = p_session_data->via_host; - contact_info.via_port = p_session_data->via_port; - contact_info.via_prot = p_session_data->via_proto; - contact_info.aor = p_session_data->registration_aor; - contact_info.reg_state = PCONTACT_ANY; - - if (ul.get_pcontact(domain, &contact_info, &pcontact) != 0) { - LM_DBG("no contact found for terminated Rx reg session..... ignoring\n"); - } else { - LM_DBG("Updating contact [%.*s] after Rx reg session terminated, setting state to PCONTACT_DEREG_PENDING_PUBLISH\n", pcontact->aor.len, pcontact->aor.s); - ci.reg_state = PCONTACT_DEREG_PENDING_PUBLISH; - ci.num_service_routes = 0; - ul.update_pcontact(domain, &ci, pcontact); - } - ul.unlock_udomain(domain, &p_session_data->via_host, p_session_data->via_port, p_session_data->via_proto); - counter_add(ims_qos_cnts_h.active_registration_rx_sessions, -1); - } - } else { - LM_DBG("This is a media bearer session session"); - if(p_session_data->session_has_been_opened) { - LM_DBG("Session was opened so decrementing active_media_rx_sessions\n"); - counter_add(ims_qos_cnts_h.active_media_rx_sessions, -1); - } - - //we only terminate the dialog if this was triggered from the transport plane or timeout - i.e. if must_terminate_dialog is set - //if this was triggered from the signalling plane (i.e. someone hanging up) then we don'y need to terminate the dialog - if (p_session_data->must_terminate_dialog) { - LM_DBG("Terminating dialog with callid, ftag, ttag: [%.*s], [%.*s], [%.*s]\n", - p_session_data->callid.len, p_session_data->callid.s, - p_session_data->ftag.len, p_session_data->ftag.s, - p_session_data->ttag.len, p_session_data->ttag.s); - dlgb.terminate_dlg(&p_session_data->callid, - &p_session_data->ftag, &p_session_data->ttag, &confirmed_qosrelease_headers, - &early_qosrelease_reason); - } - } - - //free callback data - if (p_session_data) { - free_callsessiondata(p_session_data); - } - break; - default: - break; - } - - free_cdp_cb_event(ev); - } +void cdp_cb_event_process() +{ + cdp_cb_event_t *ev; + udomain_t* domain; + pcontact_t* pcontact; + pcontact_info_t contact_info; + + struct pcontact_info ci; + memset(&ci, 0, sizeof(struct pcontact_info)); + + for (;;) { + ev = pop_cdp_cb_event(); + + if (cdp_event_latency) { //track delays + unsigned int diff = time(NULL) - ev->registered; + if (diff > cdp_event_threshold) { + switch (cdp_event_latency_loglevel) { + case 0: + LM_ERR("Took to long to pickup CDP callback event [%d] > [%d]\n", diff, cdp_event_threshold); + break; + case 1: + LM_WARN("Took to long to pickup CDP callback event [%d] > [%d]\n", diff, cdp_event_threshold); + break; + case 2: + LM_INFO("Took to long to pickup CDP callback event [%d] > [%d]\n", diff, cdp_event_threshold); + break; + case 3: + LM_DBG("Took to long to pickup CDP callback event [%d] > [%d]\n", diff, cdp_event_threshold); + break; + default: + LM_DBG("Unknown log level....printing as debug\n"); + LM_DBG("Took to long to pickup CDP callback event [%d] > [%d]\n", diff, cdp_event_threshold); + break; + } + } + } + LM_DBG("processing event [%d]\n", ev->event); + rx_authsessiondata_t *p_session_data = ev->session_data; + str *rx_session_id = &ev->rx_session_id; + + switch (ev->event) { + case AUTH_EV_SESSION_TIMEOUT: + case AUTH_EV_SESSION_GRACE_TIMEOUT: + case AUTH_EV_RECV_ASR: + LM_DBG("Received notification of ASR from transport plane or CDP timeout for CDP session with Rx session ID: [%.*s] and associated contact [%.*s]" + " and domain [%.*s]\n", + rx_session_id->len, rx_session_id->s, + p_session_data->registration_aor.len, p_session_data->registration_aor.s, + p_session_data->domain.len, p_session_data->domain.s); + + + if (p_session_data->subscribed_to_signaling_path_status) { + LM_DBG("This is a subscription to signalling bearer session"); + //nothing to do here - just wait for AUTH_EV_SERVICE_TERMINATED event + } else { + LM_DBG("This is a media bearer session session"); + //this is a media bearer session that was terminated from the transport plane - we need to terminate the associated dialog + //so we set p_session_data->must_terminate_dialog to 1 and when we receive AUTH_EV_SERVICE_TERMINATED event we will terminate the dialog + //we only terminate the dialog if terminate_dialog_on_rx_failure is set + if (terminate_dialog_on_rx_failure) { + p_session_data->must_terminate_dialog = 1; + } + } + break; + + case AUTH_EV_SERVICE_TERMINATED: + LM_DBG("Received notification of CDP TERMINATE of CDP session with Rx session ID: [%.*s] and associated contact [%.*s]" + " and domain [%.*s]\n", + rx_session_id->len, rx_session_id->s, + p_session_data->registration_aor.len, p_session_data->registration_aor.s, + p_session_data->domain.len, p_session_data->domain.s); + + if (p_session_data->subscribed_to_signaling_path_status) { + LM_DBG("This is a subscription to signalling bearer session"); + //instead of removing the contact from usrloc_pcscf we just change the state of the contact to TERMINATE_PENDING_NOTIFY + //pcscf_registrar sees this, sends a SIP PUBLISH and on SIP NOTIFY the contact is deleted + //note we only send SIP PUBLISH if the session has been successfully opened + + if (p_session_data->session_has_been_opened) { + if (delete_contact_on_rx_failure) { + if (ul.register_udomain(p_session_data->domain.s, &domain) + < 0) { + LM_DBG("Unable to register usrloc domain....aborting\n"); + return; + } + ul.lock_udomain(domain, &p_session_data->via_host, p_session_data->via_port, p_session_data->via_proto); + + contact_info.received_host = p_session_data->ip; + contact_info.received_port = p_session_data->recv_port; + contact_info.received_proto = p_session_data->recv_proto; + contact_info.searchflag = (1 << SEARCH_RECEIVED); + + contact_info.via_host = p_session_data->via_host; + contact_info.via_port = p_session_data->via_port; + contact_info.via_prot = p_session_data->via_proto; + contact_info.aor = p_session_data->registration_aor; + contact_info.reg_state = PCONTACT_ANY; + + if (ul.get_pcontact(domain, &contact_info, &pcontact) != 0) { + LM_DBG("no contact found for terminated Rx reg session..... ignoring\n"); + } else { + LM_DBG("Updating contact [%.*s] after Rx reg session terminated, setting state to PCONTACT_DEREG_PENDING_PUBLISH\n", pcontact->aor.len, pcontact->aor.s); + ci.reg_state = PCONTACT_DEREG_PENDING_PUBLISH; + ci.num_service_routes = 0; + ul.update_pcontact(domain, &ci, pcontact); + } + ul.unlock_udomain(domain, &p_session_data->via_host, p_session_data->via_port, p_session_data->via_proto); + } + counter_add(ims_qos_cnts_h.active_registration_rx_sessions, -1); + } + } else { + LM_DBG("This is a media bearer session session"); + if (p_session_data->session_has_been_opened) { + LM_DBG("Session was opened so decrementing active_media_rx_sessions\n"); + counter_add(ims_qos_cnts_h.active_media_rx_sessions, -1); + } + + //we only terminate the dialog if this was triggered from the transport plane or timeout - i.e. if must_terminate_dialog is set + //if this was triggered from the signalling plane (i.e. someone hanging up) then we don'y need to terminate the dialog + if (p_session_data->must_terminate_dialog) { + LM_DBG("Terminating dialog with callid, ftag, ttag: [%.*s], [%.*s], [%.*s]\n", + p_session_data->callid.len, p_session_data->callid.s, + p_session_data->ftag.len, p_session_data->ftag.s, + p_session_data->ttag.len, p_session_data->ttag.s); + dlgb.terminate_dlg(&p_session_data->callid, + &p_session_data->ftag, &p_session_data->ttag, &confirmed_qosrelease_headers, + &early_qosrelease_reason); + } + } + + //free callback data + if (p_session_data) { + free_callsessiondata(p_session_data); + } + break; + default: + break; + } + + free_cdp_cb_event(ev); + } } -void free_cdp_cb_event(cdp_cb_event_t *ev) { - if (ev) { - LM_DBG("Freeing cdpb CB event structure\n"); - if (ev->rx_session_id.len > 0 && ev->rx_session_id.s) { - LM_DBG("about to free string from cdp CB event [%.*s]\n", ev->rx_session_id.len, ev->rx_session_id.s); - shm_free(ev->rx_session_id.s); - } - shm_free(ev); - } +void free_cdp_cb_event(cdp_cb_event_t *ev) +{ + if (ev) { + LM_DBG("Freeing cdpb CB event structure\n"); + if (ev->rx_session_id.len > 0 && ev->rx_session_id.s) { + LM_DBG("about to free string from cdp CB event [%.*s]\n", ev->rx_session_id.len, ev->rx_session_id.s); + shm_free(ev->rx_session_id.s); + } + shm_free(ev); + } } diff --git a/modules/ims_qos/doc/ims_qos_admin.xml b/modules/ims_qos/doc/ims_qos_admin.xml index eecb95d82f5..4033cfc5294 100644 --- a/modules/ims_qos/doc/ims_qos_admin.xml +++ b/modules/ims_qos/doc/ims_qos_admin.xml @@ -121,29 +121,6 @@ modparam("ims_qos", "rx_auth_expiry", 14400) -
- <varname>af_signaling_ip</varname> (string) - - Defines the IP address to use in the flow description for the - media flow of the SIP registration. This is known in EPC as the - AF-Signaling path and usually would create a dedicated bearer for the SIP - signaling between the UE IP and the P-CSCF IP. - - Usually set this value to the IP address of the P-CSCF. - - Default value is 127.0.0.1 - dummy value. - - - <varname>rx_auth_expiry</varname> parameter usage - - -... -modparam("ims_qos", "af_signaling_ip", "192.168.1.45") -... - - -
-
<varname>cdp_event_latency</varname> (integer) @@ -347,6 +324,47 @@ modparam("ims_qos", "regex_sdp_ip_prefix_to_maintain_in_fd", "10.21.0.1")
+ +
+ <varname>terminate_dialog_on_rx_failure</varname> integer + + If set then active dialogs associated with an Rx session are + torn down in the Rx session fails + + Default value is 1, dialogs are torn down + + + <varname>terminate_dialog_on_rx_failure</varname> parameter + usage + + +... +modparam("ims_qos", "terminate_dialog_on_rx_failure", 0) +... + + +
+ +
+ <varname>delete_contact_on_rx_failure</varname> integer + + If set then contacts associated with signalling Rx sessions are deleted +if the Rx session fails + + Default value is 1, contacts are deleted + + + <varname>delete_contact_on_rx_failure</varname> parameter + usage + + +... +modparam("ims_qos", "delete_contact_on_rx_failure", 0) +... + + +
+
diff --git a/modules/ims_qos/mod.c b/modules/ims_qos/mod.c index fedcfe74f7c..48c993cc448 100644 --- a/modules/ims_qos/mod.c +++ b/modules/ims_qos/mod.c @@ -3,23 +3,23 @@ * * Copyright (C) 2012 Smile Communications, jason.penton@smilecoms.com * Copyright (C) 2012 Smile Communications, richard.good@smilecoms.com - * + * * The initial version of this code was written by Dragos Vingarzan * (dragos(dot)vingarzan(at)fokus(dot)fraunhofer(dot)de and the * Fruanhofer Institute. It was and still is maintained in a separate * branch of the original SER. We are therefore migrating it to * Kamailio/SR and look forward to maintaining it from here on out. * 2011/2012 Smile Communications, Pty. Ltd. - * ported/maintained/improved by + * ported/maintained/improved by * Jason Penton (jason(dot)penton(at)smilecoms.com and - * Richard Good (richard(dot)good(at)smilecoms.com) as part of an + * Richard Good (richard(dot)good(at)smilecoms.com) as part of an * effort to add full IMS support to Kamailio/SR using a new and * improved architecture - * + * * NB: Alot of this code was originally part of OpenIMSCore, - * FhG Fokus. + * FhG Fokus. * Copyright (C) 2004-2006 FhG Fokus - * Thanks for great work! This is an effort to + * Thanks for great work! This is an effort to * break apart the various CSCF functions into logically separate * components. We hope this will drive wider use. We also feel * that in this way the architecture is more complete and thereby easier @@ -37,10 +37,10 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * + * */ #include @@ -126,17 +126,18 @@ static int fixup_aar(void** param, int param_no); int * callback_singleton; /*< Callback singleton */ int terminate_dialog_on_rx_failure = 1; //this specifies whether a dialog is torn down when a media rx session fails - in some cases you might not want the dialog torn down +int delete_contact_on_rx_failure = 1; //If this is set we delete the contact if the associated signalling bearer is removed + str early_qosrelease_reason = {"QoS released", 12}; str confirmed_qosrelease_headers = {NULL, 0}; + /* parameters storage */ str rx_dest_realm = str_init("ims.smilecoms.com"); /* Only used if we want to force the Rx peer usually this is configured at a stack level and the first request uses realm routing */ str rx_forced_peer = str_init(""); -/* P-CSCF IP address to generate the flows for the UE<->PCSCF signaling path */ -str af_signaling_ip = str_init("127.0.0.1"); /* commands wrappers and fixups */ static int w_rx_aar(struct sip_msg *msg, char *route, char* dir, char *id, int id_type); @@ -187,7 +188,6 @@ static param_export_t params[] = { { "rx_dest_realm", PARAM_STR, &rx_dest_realm}, { "rx_forced_peer", PARAM_STR, &rx_forced_peer}, { "rx_auth_expiry", INT_PARAM, &rx_auth_expiry}, - { "af_signaling_ip", PARAM_STR, &af_signaling_ip}, /* IP of this P-CSCF, to be used in the flow for the AF-signaling */ { "cdp_event_latency", INT_PARAM, &cdp_event_latency}, /*flag: report slow processing of CDP callback events or not */ { "cdp_event_threshold", INT_PARAM, &cdp_event_threshold}, /*time in ms above which we should report slow processing of CDP callback event*/ { "cdp_event_latency_log", INT_PARAM, &cdp_event_latency_loglevel}, /*log-level to use to report slow processing of CDP callback event*/ @@ -198,6 +198,7 @@ static param_export_t params[] = { { "early_qosrelease_reason", PARAM_STR, &early_qosrelease_reason}, { "confirmed_qosrelease_headers", PARAM_STR, &confirmed_qosrelease_headers}, { "terminate_dialog_on_rx_failure", INT_PARAM, &terminate_dialog_on_rx_failure}, + { "delete_contact_on_rx_failure", INT_PARAM, &delete_contact_on_rx_failure}, { "regex_sdp_ip_prefix_to_maintain_in_fd", PARAM_STR, ®ex_sdp_ip_prefix_to_maintain_in_fd}, { 0, 0, 0} }; @@ -720,8 +721,8 @@ static int w_rx_aar(struct sip_msg *msg, char *route, char* dir, char *c_id, int /* we may need the request message from here on.. if there are headers we need that were not parsed in the original request - (which we cannot assume) then we would pollute the shm_msg t->uas.request if we did any parsing on it. Instead, we need to - make a private copy of the message and free it when we are done + (which we cannot assume) then we would pollute the shm_msg t->uas.request if we did any parsing on it. Instead, we need to + make a private copy of the message and free it when we are done */ if ((_pv_treq.T != t || t->uas.request != _pv_treq.tmsgp) && t->uas.request->id != _pv_treq.id) { @@ -947,7 +948,7 @@ static int w_rx_aar(struct sip_msg *msg, char *route, char* dir, char *c_id, int identifier_type = AVP_Subscription_Id_Type_SIP_URI; //default is END_USER_SIP_URI } } - //IP + //IP //if its mo we use request SDP //if its mt we use reply SDP if (dlg_direction == DLG_MOBILE_ORIGINATING) { @@ -965,9 +966,9 @@ static int w_rx_aar(struct sip_msg *msg, char *route, char* dir, char *c_id, int } ip = sdp_session->ip_addr; ip_version = sdp_session->pf; - + LM_DBG("IP retrieved from Request SDP to use for framed IP address: [%.*s]", ip.len, ip.s); - + if (ip.len <= 0) { LM_DBG("Request SDP connection IP could not be retrieved, so we use SDP stream IP"); sdp_stream = get_sdp_stream(orig_sip_request_msg, 0, 0); @@ -975,7 +976,7 @@ static int w_rx_aar(struct sip_msg *msg, char *route, char* dir, char *c_id, int LM_ERR("Missing SDP stream information from request\n"); goto error; } - + ip = sdp_stream->ip_addr; if (ip.len <= 0) { LM_ERR("Request SDP IP information could not be retrieved"); @@ -986,11 +987,11 @@ static int w_rx_aar(struct sip_msg *msg, char *route, char* dir, char *c_id, int LM_ERR("check_ip_version returned 0 \n"); goto error; } - + } - + free_sdp((sdp_info_t**) (void*) &t->uas.request->body); - + } else { LM_DBG("terminating direction\n"); //get ip from reply sdp (we use first SDP session) @@ -1006,9 +1007,9 @@ static int w_rx_aar(struct sip_msg *msg, char *route, char* dir, char *c_id, int } ip = sdp_session->ip_addr; ip_version = sdp_session->pf; - + LM_DBG("IP retrieved from Reply SDP to use for framed IP address: [%.*s]", ip.len, ip.s); - + if (ip.len <= 0) { LM_DBG("Reply SDP connection IP could not be retrieved, so we use SDP stream IP"); sdp_stream = get_sdp_stream(msg, 0, 0); @@ -1016,7 +1017,7 @@ static int w_rx_aar(struct sip_msg *msg, char *route, char* dir, char *c_id, int LM_ERR("Missing SDP stream information from reply\n"); goto error; } - + ip = sdp_stream->ip_addr; if (ip.len <= 0) { LM_ERR("Reply SDP IP information could not be retrieved"); @@ -1027,9 +1028,9 @@ static int w_rx_aar(struct sip_msg *msg, char *route, char* dir, char *c_id, int LM_ERR("check_ip_version returned 0 \n"); goto error; } - + } - + free_sdp((sdp_info_t**) (void*) &msg->body); } @@ -1059,7 +1060,6 @@ static int w_rx_aar(struct sip_msg *msg, char *route, char* dir, char *c_id, int dlgb.set_dlg_var(&callid, &ftag, &ttag, &term_session_key, &auth_session->id); } - auth_session->vendor_id = IMS_vendor_id_3GPP; LM_DBG("Attached CDP auth session [%.*s] for Rx to dialog in %s mode\n", auth_session->id.len, auth_session->id.s, direction); } else { LM_DBG("Update AAR session for this dialog in mode %s\n", direction); @@ -1254,7 +1254,7 @@ static int w_rx_aar_register(struct sip_msg *msg, char* route, char* str1, char* goto error; } - //we use the received IP address for the framed_ip_address + //we use the received IP address for the framed_ip_address recv_ip.s = ip_addr2a(&msg->rcv.src_ip); recv_ip.len = strlen(ip_addr2a(&msg->rcv.src_ip)); @@ -1338,7 +1338,6 @@ static int w_rx_aar_register(struct sip_msg *msg, char* route, char* str1, char* goto error; } auth->u.auth.class = AUTH_CLASS_RXREG; - auth->vendor_id = IMS_vendor_id_3GPP; } //we are ready to send the AAR async. lets save the local data data