diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index 98a6fc34ce..b8e54e80af 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -779,7 +779,7 @@ void sofia_glue_set_image_sdp(private_object_t *tech_pvt, switch_t38_options_t * void sofia_sla_handle_register(nua_t *nua, sofia_profile_t *profile, sip_t const *sip); void sofia_sla_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip, tagi_t tags[]); -void sofia_sla_handle_sip_i_subscribe(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip, tagi_t tags[]); +void sofia_sla_handle_sip_i_subscribe(nua_t *nua, const char *contact_str, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip, tagi_t tags[]); void sofia_sla_handle_sip_r_subscribe(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip, tagi_t tags[]); void sofia_sla_handle_sip_i_notify(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip, tagi_t tags[]); diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c index ab2817fb87..64b4e39cca 100644 --- a/src/mod/endpoints/mod_sofia/sofia_glue.c +++ b/src/mod/endpoints/mod_sofia/sofia_glue.c @@ -3047,7 +3047,8 @@ int sofia_glue_init_sql(sofia_profile_t *profile) " call_id VARCHAR(255),\n" " aor VARCHAR(255),\n" " profile_name VARCHAR(255),\n" - " hostname VARCHAR(255)\n" + " hostname VARCHAR(255),\n" + " contact_str VARCHAR(255)\n" ");\n"; if (profile->odbc_dsn) { @@ -3105,7 +3106,7 @@ int sofia_glue_init_sql(sofia_profile_t *profile) free(test_sql); if (profile->manage_shared_appearance) { - test_sql = switch_mprintf("delete from sip_shared_appearance_subscriptions where hostname='%q'", mod_sofia_globals.hostname); + test_sql = switch_mprintf("delete from sip_shared_appearance_subscriptions where contact_str='' or hostname='%q'", mod_sofia_globals.hostname); if (switch_odbc_handle_exec(profile->master_odbc, test_sql, NULL) != SWITCH_ODBC_SUCCESS) { switch_odbc_handle_exec(profile->master_odbc, "DROP TABLE sip_shared_appearance_subscriptions", NULL); switch_odbc_handle_exec(profile->master_odbc, shared_appearance_sql, NULL); @@ -3145,7 +3146,7 @@ int sofia_glue_init_sql(sofia_profile_t *profile) free(test_sql); if(profile->manage_shared_appearance) { - test_sql = switch_mprintf("delete from sip_shared_appearance_subscriptions where hostname='%q'", mod_sofia_globals.hostname); + test_sql = switch_mprintf("delete from sip_shared_appearance_subscriptions where contact_str = '' or hostname='%q'", mod_sofia_globals.hostname); switch_core_db_test_reactive(profile->master_db, test_sql, "DROP TABLE sip_shared_appearance_subscriptions", shared_appearance_sql); free(test_sql); diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index 5afe2670c2..c1cc3aea66 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -1423,17 +1423,6 @@ void sofia_presence_handle_sip_i_subscribe(int status, return; } - /* the following could be refactored back to the calling event handler in sofia.c XXX MTK */ - if (profile->manage_shared_appearance) { - if (!strncmp(sip->sip_request->rq_url->url_user, "sla-agent", sizeof("sla-agent"))) { - /* only fire this on <200 to try to avoid resubscribes. probably better ways to do this? */ - if (status < 200) { - sofia_sla_handle_sip_i_subscribe(nua, profile, nh, sip, tags); - } - return; - } - } - get_addr(network_ip, sizeof(network_ip), my_addrinfo->ai_addr, my_addrinfo->ai_addrlen); network_port = ntohs(((struct sockaddr_in *) msg_addrinfo(nua_current_request(nua))->ai_addr)->sin_port); @@ -1524,6 +1513,22 @@ void sofia_presence_handle_sip_i_subscribe(int status, is_nat ? ";nat" : ""); } + + + /* the following could be refactored back to the calling event handler in sofia.c XXX MTK */ + if (profile->manage_shared_appearance) { + if (!strncmp(sip->sip_request->rq_url->url_user, "sla-agent", sizeof("sla-agent"))) { + /* only fire this on <200 to try to avoid resubscribes. probably better ways to do this? */ + if (status < 200) { + sofia_sla_handle_sip_i_subscribe(nua, contact_str, profile, nh, sip, tags); + } + switch_safe_free(contact_str); + return; + } + } + + + if (to) { to_str = switch_mprintf("sip:%s@%s", to->a_url->url_user, to->a_url->url_host); } diff --git a/src/mod/endpoints/mod_sofia/sofia_sla.c b/src/mod/endpoints/mod_sofia/sofia_sla.c index 04128b6ce3..6311a8b3b1 100644 --- a/src/mod/endpoints/mod_sofia/sofia_sla.c +++ b/src/mod/endpoints/mod_sofia/sofia_sla.c @@ -78,12 +78,13 @@ void sofia_sla_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, nua_ha nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS(nua), TAG_END()); } -void sofia_sla_handle_sip_i_subscribe(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip, tagi_t tags[]) +void sofia_sla_handle_sip_i_subscribe(nua_t *nua, const char *contact_str, sofia_profile_t *profile, nua_handle_t *nh, sip_t const *sip, tagi_t tags[]) { char *aor = NULL; char *subscriber = NULL; char *sql = NULL; - + char *route_uri = NULL; + /* * XXX MTK FIXME - we don't look at the tag to see if NUTAG_SUBSTATE(nua_substate_terminated) or * a Subscription-State header with state "terminated" and/or expiration of 0. So we never forget @@ -119,22 +120,43 @@ void sofia_sla_handle_sip_i_subscribe(nua_t *nua, sofia_profile_t *profile, nua_ } if ((sql = - switch_mprintf("insert into sip_shared_appearance_subscriptions (subscriber, call_id, aor, profile_name, hostname) " - "values ('%q','%q','%q','%q','%q')", - subscriber, sip->sip_call_id->i_id, aor, profile->name, mod_sofia_globals.hostname))) { + switch_mprintf("insert into sip_shared_appearance_subscriptions (subscriber, call_id, aor, profile_name, hostname, contact_str) " + "values ('%q','%q','%q','%q','%q','%q')", + subscriber, sip->sip_call_id->i_id, aor, profile->name, mod_sofia_globals.hostname, contact_str))) { sofia_glue_execute_sql(profile, &sql, SWITCH_TRUE); } + if (strstr(contact_str, ";fs_nat")) { + char *p; + route_uri = strdup(contact_str); + if ((p = strstr(contact_str, ";fs_"))) { + *p = '\0'; + } + } + + + if (route_uri) { + char *p; + + while (route_uri && *route_uri && (*route_uri == '<' || *route_uri == ' ')) { + route_uri++; + } + if ((p = strchr(route_uri, '>'))) { + *p++ = '\0'; + } + } nua_respond(nh, SIP_202_ACCEPTED, SIPTAG_CONTACT_STR(profile->sla_contact), NUTAG_WITH_THIS(nua), - SIPTAG_SUBSCRIPTION_STATE_STR("active;expires=300"), /* you thought the OTHER time was fake... need delta here FIXME XXX MTK */ - SIPTAG_EXPIRES_STR("300"), /* likewise, totally fake - FIXME XXX MTK */ + TAG_IF(route_uri, NUTAG_PROXY(route_uri)), + SIPTAG_SUBSCRIPTION_STATE_STR("active;expires=300"), /* you thought the OTHER time was fake... need delta here FIXME XXX MTK */ + SIPTAG_EXPIRES_STR("300"), /* likewise, totally fake - FIXME XXX MTK */ /* sofia_presence says something about needing TAG_IF(sticky, NUTAG_PROXY(sticky)) for NAT stuff? */ TAG_END()); switch_safe_free(aor); switch_safe_free(subscriber); + switch_safe_free(route_uri); switch_safe_free(sql); } @@ -199,7 +221,7 @@ void sofia_sla_handle_sip_i_notify(nua_t *nua, sofia_profile_t *profile, nua_han contact = switch_mprintf("sip:%s@%s",sip->sip_contact->m_url->url_user, sip->sip_contact->m_url->url_host); if(sip->sip_payload && sip->sip_payload->pl_data) { - sql = switch_mprintf("select subscriber,call_id,aor,profile_name,hostname from sip_shared_appearance_subscriptions where " + sql = switch_mprintf("select subscriber,call_id,aor,profile_name,hostname,route_uri from sip_shared_appearance_subscriptions where " "aor='%q' and subscriber<>'%q' and profile_name='%q' and hostname='%q'", aor, contact, profile->name, mod_sofia_globals.hostname); @@ -224,17 +246,41 @@ static int sofia_sla_sub_callback(void *pArg, int argc, char **argv, char **colu /* char *aor = argv[2]; */ /* char *profile_name = argv[3]; */ /* char *hostname = argv[4]; */ + char *contact_str = argv[5]; nua_handle_t *nh; + char *route_uri = NULL; + nh = nua_handle_by_call_id(helper->profile->nua, call_id); /* that's all you need to find the subscription's nh */ - if(nh) - { + if(nh) { + + if (strstr(contact_str, ";fs_nat")) { + char *p; + route_uri = strdup(contact_str); + if ((p = strstr(contact_str, ";fs_"))) { + *p = '\0'; + } + } + + if (route_uri) { + char *p; + + while (route_uri && *route_uri && (*route_uri == '<' || *route_uri == ' ')) { + route_uri++; + } + if ((p = strchr(route_uri, '>'))) { + *p++ = '\0'; + } + } + nua_notify(nh, - SIPTAG_SUBSCRIPTION_STATE_STR("active;expires=300"), /* XXX MTK FIXME - this is totally fake calculation */ - SIPTAG_CONTENT_TYPE_STR("application/dialog-info+xml"), /* could've just kept the type from the payload */ - SIPTAG_PAYLOAD_STR(helper->payload), - TAG_END()); + SIPTAG_SUBSCRIPTION_STATE_STR("active;expires=300"), /* XXX MTK FIXME - this is totally fake calculation */ + TAG_IF(route_uri, NUTAG_PROXY(route_uri)), + SIPTAG_CONTENT_TYPE_STR("application/dialog-info+xml"), /* could've just kept the type from the payload */ + SIPTAG_PAYLOAD_STR(helper->payload), + TAG_END()); + switch_safe_free(route_uri); } return 0; }