diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 46e031aec5..375ced0971 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -89,7 +89,10 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status, private_object_t *tech_pvt = NULL; switch_event_t *s_event = NULL; sofia_gateway_subscription_t *gw_sub_ptr; + int sub_state; + tl_gets(tags, NUTAG_SUBSTATE_REF(sub_state), TAG_END()); + /* make sure we have a proper event */ if (!sip || !sip->sip_event) { goto error; @@ -105,18 +108,8 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status, if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)) { if (sip->sip_request->rq_url->url_user && !strncmp(sip->sip_request->rq_url->url_user, "sla-agent", sizeof("sla-agent"))) { - int sub_state; - tl_gets(tags, NUTAG_SUBSTATE_REF(sub_state), TAG_END()); - sofia_sla_handle_sip_i_notify(nua, profile, nh, sip, tags); - - if (sub_state == nua_substate_terminated) { - sofia_private_free(sofia_private); - nua_handle_bind(nh, NULL); - nua_handle_destroy(nh); - } - - return; + goto end; } } @@ -124,7 +117,7 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status, if (!strcasecmp(sip->sip_event->o_type, "keep-alive")) { /* XXX MTK - is this right? in this case isn't sofia is already sending a 200 itself also? */ nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS(nua), TAG_END()); - return; + goto end; } if (session) { @@ -214,7 +207,7 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status, switch_channel_set_variable(channel, "auto_answer_destination", switch_channel_get_variable(channel, "destination_number")); switch_ivr_session_transfer(session, "auto_answer", NULL, NULL); nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS(nua), TAG_END()); - return; + goto end; } } @@ -257,11 +250,20 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status, goto error; } - return; + goto end; error: + nua_respond(nh, 481, "Subscription Does Not Exist", NUTAG_WITH_THIS(nua), TAG_END()); - return; + + end: + + if (sub_state == nua_substate_terminated) { + sofia_private_free(sofia_private); + nua_handle_bind(nh, NULL); + nua_handle_destroy(nh); + } + } void sofia_handle_sip_i_bye(switch_core_session_t *session, int status, @@ -425,7 +427,6 @@ void sofia_event_callback(nua_event_t event, switch (event) { case nua_r_get_params: - case nua_r_unregister: case nua_i_fork: case nua_r_info: case nua_r_bye: @@ -463,6 +464,7 @@ void sofia_event_callback(nua_event_t event, sofia_handle_sip_i_notify(session, status, phrase, nua, profile, nh, sofia_private, sip, tags); break; case nua_r_register: + case nua_r_unregister: sofia_reg_handle_sip_r_register(status, phrase, nua, profile, nh, sofia_private, sip, tags); break; case nua_i_options: diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c index 4b377308de..9152dbf049 100644 --- a/src/mod/endpoints/mod_sofia/sofia_reg.c +++ b/src/mod/endpoints/mod_sofia/sofia_reg.c @@ -37,7 +37,7 @@ */ #include "mod_sofia.h" -static void sofia_reg_new_handle(sofia_gateway_t *gateway_ptr) +static void sofia_reg_new_handle(sofia_gateway_t *gateway_ptr, int attach) { int ss_state = nua_callstate_authenticating; @@ -54,23 +54,23 @@ static void sofia_reg_new_handle(sofia_gateway_t *gateway_ptr) SIPTAG_TO_STR(gateway_ptr->register_to), NUTAG_CALLSTATE_REF(ss_state), SIPTAG_FROM_STR(gateway_ptr->register_from), TAG_END()); - - if (!gateway_ptr->sofia_private) { - gateway_ptr->sofia_private = malloc(sizeof(*gateway_ptr->sofia_private)); - switch_assert(gateway_ptr->sofia_private); - } - memset(gateway_ptr->sofia_private, 0, sizeof(*gateway_ptr->sofia_private)); + if (attach) { + if (!gateway_ptr->sofia_private) { + gateway_ptr->sofia_private = malloc(sizeof(*gateway_ptr->sofia_private)); + switch_assert(gateway_ptr->sofia_private); + } + memset(gateway_ptr->sofia_private, 0, sizeof(*gateway_ptr->sofia_private)); - gateway_ptr->sofia_private->gateway = gateway_ptr; - nua_handle_bind(gateway_ptr->nh, gateway_ptr->sofia_private); + gateway_ptr->sofia_private->gateway = gateway_ptr; + nua_handle_bind(gateway_ptr->nh, gateway_ptr->sofia_private); + } } static void sofia_reg_kill_reg(sofia_gateway_t *gateway_ptr) { if (!gateway_ptr->nh) { - sofia_reg_new_handle(gateway_ptr); - + sofia_reg_new_handle(gateway_ptr, SWITCH_FALSE); } if (gateway_ptr->nh) { @@ -80,7 +80,7 @@ static void sofia_reg_kill_reg(sofia_gateway_t *gateway_ptr) SIPTAG_FROM_STR(gateway_ptr->register_from), SIPTAG_TO_STR(gateway_ptr->register_from), SIPTAG_CONTACT_STR(gateway_ptr->register_contact), - SIPTAG_EXPIRES_STR(gateway_ptr->expires_str), + SIPTAG_EXPIRES_STR("0"), NUTAG_REGISTRAR(gateway_ptr->register_proxy), NUTAG_OUTBOUND("no-options-keepalive"), NUTAG_OUTBOUND("no-validate"), NUTAG_KEEPALIVE(0), TAG_NULL()); } @@ -100,10 +100,13 @@ void sofia_reg_unregister(sofia_profile_t *profile) { sofia_gateway_t *gateway_ptr; for (gateway_ptr = profile->gateways; gateway_ptr; gateway_ptr = gateway_ptr->next) { + if (gateway_ptr->sofia_private) { sofia_private_free(gateway_ptr->sofia_private); } + sofia_reg_kill_reg(gateway_ptr); + } } @@ -288,7 +291,7 @@ void sofia_reg_check_gateway(sofia_profile_t *profile, time_t now) case REG_STATE_UNREGED: gateway_ptr->status = SOFIA_GATEWAY_DOWN; - sofia_reg_new_handle(gateway_ptr); + sofia_reg_new_handle(gateway_ptr, now ? 1 : 0); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Registering %s\n", gateway_ptr->name); @@ -1318,7 +1321,7 @@ void sofia_reg_handle_sip_r_register(int status, } - if (status >= 200) { + if (status >= 300) { if (sofia_private) { if (sofia_private->gateway) { nua_handle_destroy(sofia_private->gateway->nh);