]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
support allowing pidf-ful presence clients to share the same account and 'appear...
authorAnthony Minessale <anthm@freeswitch.org>
Thu, 30 Dec 2010 17:38:23 +0000 (11:38 -0600)
committerAnthony Minessale <anthm@freeswitch.org>
Thu, 30 Dec 2010 17:38:23 +0000 (11:38 -0600)
src/mod/endpoints/mod_sofia/mod_sofia.h
src/mod/endpoints/mod_sofia/sofia_glue.c
src/mod/endpoints/mod_sofia/sofia_presence.c

index 61d165753c60fc9b4b956656cbca7c1adba257ba..5fd6cd79632d3adc453c4439e812ce7760698de8 100644 (file)
@@ -745,6 +745,14 @@ typedef struct {
        char *route_uri;
 } sofia_destination_t;
 
+typedef struct {
+       char network_ip[80];
+       int network_port;
+       const char *is_nat;
+       int is_auto_nat;
+} sofia_nat_parse_t;
+
+
 #define sofia_test_pflag(obj, flag) ((obj)->pflags[flag] ? 1 : 0)
 #define sofia_set_pflag(obj, flag) (obj)->pflags[flag] = 1
 #define sofia_set_pflag_locked(obj, flag) assert(obj->flag_mutex != NULL);\
@@ -1040,3 +1048,4 @@ switch_status_t sofia_glue_sdp_map(const char *r_sdp, switch_event_t **fmtp, swi
 void sofia_glue_build_vid_refresh_message(switch_core_session_t *session, const char *pl);
 void sofia_glue_check_dtmf_type(private_object_t *tech_pvt);
 void sofia_glue_parse_rtp_bugs(uint32_t *flag_pole, const char *str);
+char *sofia_glue_gen_contact_str(sofia_profile_t *profile, sip_t const *sip, sofia_nat_parse_t *np);
index 029f60ad3382eb168837e666f0bef1d6b31bb6b4..4779ef167f3755a4268aa8127ab5de757983aca7 100644 (file)
@@ -6136,6 +6136,129 @@ void sofia_glue_parse_rtp_bugs(uint32_t *flag_pole, const char *str)
        }
 }
 
+char *sofia_glue_gen_contact_str(sofia_profile_t *profile, sip_t const *sip, sofia_nat_parse_t *np)
+{
+       char *contact_str = NULL;
+       const char *contact_host, *contact_user;
+       sip_contact_t const *contact;
+       char *port;
+       const char *display = "\"user\"";
+       char new_port[25] = "";
+       sofia_nat_parse_t lnp = { { 0 } };
+       const char *ipv6;
+       sip_from_t const *from;
+
+       if (!sip || !sip->sip_contact || !sip->sip_contact->m_url) {
+               return NULL;
+       }
+
+       from = sip->sip_from;
+       contact = sip->sip_contact;
+
+       if (!np) {
+               np = &lnp;
+       }
+
+       sofia_glue_get_addr(nua_current_request(profile->nua), np->network_ip, sizeof(np->network_ip), &np->network_port);
+       
+       if (sofia_glue_check_nat(profile, np->network_ip)) {
+               np->is_auto_nat = 1;
+       }
+
+       port = (char *) contact->m_url->url_port;
+       contact_host = sip->sip_contact->m_url->url_host;
+       contact_user = sip->sip_contact->m_url->url_user;
+
+       display = contact->m_display;
+
+
+       if (zstr(display)) {
+               if (from) {
+                       display = from->a_display;
+                       if (zstr(display)) {
+                               display = "\"user\"";
+                       }
+               }
+       } else {
+               display = "\"user\"";
+       }
+
+       if (sofia_test_pflag(profile, PFLAG_AGGRESSIVE_NAT_DETECTION)) {
+               if (sip->sip_via) {
+                       const char *v_port = sip->sip_via->v_port;
+                       const char *v_host = sip->sip_via->v_host;
+
+                       if (v_host && sip->sip_via->v_received) {
+                               np->is_nat = "via received";
+                       } else if (v_host && strcmp(np->network_ip, v_host)) {
+                               np->is_nat = "via host";
+                       } else if (v_port && atoi(v_port) != np->network_port) {
+                               np->is_nat = "via port";
+                       }
+               }
+       }
+
+       if (!np->is_nat && sip && sip->sip_via && sip->sip_via->v_port &&
+               atoi(sip->sip_via->v_port) == 5060 && np->network_port != 5060 ) {
+               np->is_nat = "via port";
+       }
+
+       if (!np->is_nat && profile->nat_acl_count) {
+               uint32_t x = 0;
+               int ok = 1;
+               char *last_acl = NULL;
+
+               if (!zstr(contact_host)) {
+                       for (x = 0; x < profile->nat_acl_count; x++) {
+                               last_acl = profile->nat_acl[x];
+                               if (!(ok = switch_check_network_list_ip(contact_host, last_acl))) {
+                                       break;
+                               }
+                       }
+
+                       if (ok) {
+                               np->is_nat = last_acl;
+                       }
+               }
+       }
+
+       if (np->is_nat && profile->local_network && switch_check_network_list_ip(np->network_ip, profile->local_network)) {
+               if (profile->debug) {
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "IP %s is on local network, not seting NAT mode.\n", np->network_ip);
+               }
+               np->is_nat = NULL;
+       }
+
+       if (zstr(contact_host)) {
+               np->is_nat = "No contact host";
+       }
+
+       if (np->is_nat) {
+               contact_host = np->network_ip;
+               switch_snprintf(new_port, sizeof(new_port), ":%d", np->network_port);
+               port = NULL;
+       }
+
+
+       if (port) {
+               switch_snprintf(new_port, sizeof(new_port), ":%s", port);
+       }
+
+       ipv6 = strchr(contact_host, ':');
+       if (contact->m_url->url_params) {
+               contact_str = switch_mprintf("%s <sip:%s@%s%s%s%s;%s>%s",
+                                                                        display, contact->m_url->url_user,
+                                                                        ipv6 ? "[" : "",
+                                                                        contact_host, ipv6 ? "]" : "", new_port, contact->m_url->url_params, np->is_nat ? ";fs_nat=yes" : "");
+       } else {
+               contact_str = switch_mprintf("%s <sip:%s@%s%s%s%s>%s",
+                                                                        display,
+                                                                        contact->m_url->url_user, ipv6 ? "[" : "", contact_host, ipv6 ? "]" : "", new_port, np->is_nat ? ";fs_nat=yes" : "");
+       }
+
+               
+       return contact_str;
+}
 
 
 
index 4b93492eaef9460d9d359907fc74462b644857ef..68296052e64c94362963c9c53980e5a40a8ffb8e 100644 (file)
@@ -289,7 +289,8 @@ void sofia_presence_cancel(void)
 
        if ((sql = switch_mprintf("select proto,sip_user,sip_host,sub_to_user,sub_to_host,event,contact,call_id,full_from,"
                                                          "full_via,expires,user_agent,accept,profile_name,network_ip"
-                                                         ",-1,'unavailable','unavailable' from sip_subscriptions where expires > -1 and event='presence' and hostname='%q'",
+                                                         ",-1,'unavailable','unavailable' from sip_subscriptions where version > -1 and "
+                                                         "expires > -1 and event='presence' and hostname='%q'",
                                                          mod_sofia_globals.hostname))) {
                switch_mutex_lock(mod_sofia_globals.hash_mutex);
                for (hi = switch_hash_first(NULL, mod_sofia_globals.profile_hash); hi; hi = switch_hash_next(hi)) {
@@ -322,7 +323,7 @@ void sofia_presence_establish_presence(sofia_profile_t *profile)
 
        if (sofia_glue_execute_sql_callback(profile, profile->ireg_mutex,
                                                                                "select sub_to_user,sub_to_host,'Online','unknown',proto from sip_subscriptions "
-                                                                               "where expires > -1 and proto='ext' or proto='user' or proto='conf'",
+                                                                               "where expires > -1 and version > -1 and proto='ext' or proto='user' or proto='conf'",
                                                                                sofia_presence_resub_callback, &h) != SWITCH_TRUE) {
                return;
        }
@@ -435,12 +436,12 @@ static void actual_sofia_presence_mwi_event_handler(switch_event_t *event)
        if (for_everyone) {
                sql = switch_mprintf("select proto,sip_user,sip_host,sub_to_user,sub_to_host,event,contact,call_id,full_from,"
                                                         "full_via,expires,user_agent,accept,profile_name,network_ip"
-                                                        ",'%q','%q' from sip_subscriptions where expires > -1 and event='message-summary' "
+                                                        ",'%q','%q' from sip_subscriptions where version > -1 and expires > -1 and event='message-summary' "
                                                         "and sub_to_user='%q' and (sub_to_host='%q' or presence_hosts like '%%%q%%')", stream.data, host, user, host, host);
        } else if (sub_call_id) {
                sql = switch_mprintf("select proto,sip_user,sip_host,sub_to_user,sub_to_host,event,contact,call_id,full_from,"
                                                         "full_via,expires,user_agent,accept,profile_name,network_ip"
-                                                        ",'%q','%q' from sip_subscriptions where expires > -1 and event='message-summary' "
+                                                        ",'%q','%q' from sip_subscriptions where version > -1 and expires > -1 and event='message-summary' "
                                                         "and sub_to_user='%q' and (sub_to_host='%q' or presence_hosts like '%%%q%%' and call_id='%q')",
                                                         stream.data, host, user, host, host, sub_call_id);
        }
@@ -545,7 +546,8 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
                                                                 "from sip_subscriptions left join sip_presence on "
                                                                 "(sip_subscriptions.sub_to_user=sip_presence.sip_user and sip_subscriptions.sub_to_host=sip_presence.sip_host and "
                                                                 "sip_subscriptions.profile_name=sip_presence.profile_name) "
-                                                                "where sip_subscriptions.expires > -1 and sip_subscriptions.event='presence' and sip_subscriptions.full_from like '%%%q%%'",
+                                                                "where sip_subscriptions.version > -1 and "
+                                                                "sip_subscriptions.expires > -1 and sip_subscriptions.event='presence' and sip_subscriptions.full_from like '%%%q%%'",
                                                                 switch_str_nil(status), switch_str_nil(rpid), from);
                } else {
                        sql = switch_mprintf("select sip_subscriptions.proto,sip_subscriptions.sip_user,sip_subscriptions.sip_host,"
@@ -557,7 +559,8 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
                                                                 "from sip_subscriptions left join sip_presence on "
                                                                 "(sip_subscriptions.sub_to_user=sip_presence.sip_user and sip_subscriptions.sub_to_host=sip_presence.sip_host and "
                                                                 "sip_subscriptions.profile_name=sip_presence.profile_name) "
-                                                                "where sip_subscriptions.expires > -1 and sip_subscriptions.event='presence'", switch_str_nil(status),
+                                                                "where sip_subscriptions.version > -1 and "
+                                                                "sip_subscriptions.expires > -1 and sip_subscriptions.event='presence'", switch_str_nil(status),
                                                                 switch_str_nil(rpid));
                }
 
@@ -833,7 +836,7 @@ static void actual_sofia_presence_event_handler(switch_event_t *event)
                                                                  "(sip_subscriptions.sub_to_user=sip_presence.sip_user and sip_subscriptions.sub_to_host=sip_presence.sip_host and "
                                                                  "sip_subscriptions.profile_name=sip_presence.profile_name) "
                                                                  
-                                                                 "where sip_subscriptions.expires > -1 and "
+                                                                 "where sip_subscriptions.version > -1 and sip_subscriptions.expires > -1 and "
                                                                  "(event='%q' or event='%q') and sub_to_user='%q' "
                                                                  "and (sub_to_host='%q' or presence_hosts like '%%%q%%') "
                                                                  "and (sip_subscriptions.profile_name = '%q' or sip_subscriptions.presence_hosts != sip_subscriptions.sub_to_host) ",
@@ -2009,13 +2012,13 @@ static void sync_sla(sofia_profile_t *profile, const char *to_user, const char *
        if (unseize) {
                sql = switch_mprintf("select call_id,expires,sub_to_user,sub_to_host,event "
                                                         "from sip_subscriptions "
-                                                        "where expires > -1 and hostname='%q' "
+                                                        "where version > -1 and expires > -1 and hostname='%q' "
                                                         "and sub_to_user='%q' and sub_to_host='%q' "
                                                         "and (event='call-info' or event='line-seize')", mod_sofia_globals.hostname, to_user, to_host);
        } else {
                sql = switch_mprintf("select call_id,expires,sub_to_user,sub_to_host,event "
                                                         "from sip_subscriptions "
-                                                        "where expires > -1 and hostname='%q' "
+                                                        "where version > -1 and expires > -1 and hostname='%q' "
                                                         "and sub_to_user='%q' and sub_to_host='%q' " "and (event='call-info')", mod_sofia_globals.hostname, to_user, to_host);
        }
 
@@ -2044,350 +2047,287 @@ static void sync_sla(sofia_profile_t *profile, const char *to_user, const char *
 
 }
 
-
 void sofia_presence_handle_sip_i_subscribe(int status,
                                                                                   char const *phrase,
                                                                                   nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
                                                                                   tagi_t tags[])
 {
-       if (sip) {
-               long exp_abs, exp_delta;
-               char exp_delta_str[30] = "";
-               sip_to_t const *to = sip->sip_to;
-               sip_from_t const *from = sip->sip_from;
-               sip_contact_t const *contact = sip->sip_contact;
-               const char *from_user = NULL, *from_host = NULL;
-               const char *to_user = NULL, *to_host = NULL;
-               char *my_to_user = NULL;
-               char *sql, *event = NULL;
-               char *proto = "sip";
-               char *d_user = NULL;
-               char *contact_str = "";
-               const char *call_id = NULL;
-               char *to_str = NULL;
-               char *full_from = NULL;
-               char *full_via = NULL;
-               char *full_agent = NULL;
-               char *sstr;
-               const char *display = "\"user\"";
-               switch_event_t *sevent;
-               int sub_state;
-               int sent_reply = 0;
-               int network_port = 0;
-               char network_ip[80];
-               const char *contact_host, *contact_user;
-               char *port;
-               char new_port[25] = "";
-               char *is_nat = NULL;
-               int is_auto_nat = 0;
-               const char *ipv6;
-
-               if (!(contact && sip->sip_contact->m_url)) {
-                       nua_respond(nh, 481, "INVALID SUBSCRIPTION", TAG_END());
-                       return;
-               }
 
-               sofia_glue_get_addr(nua_current_request(nua), network_ip, sizeof(network_ip), &network_port);
+       long exp_abs, exp_delta;
+       char exp_delta_str[30] = "";
+       sip_to_t const *to;
+       const char *from_user = NULL, *from_host = NULL;
+       const char *to_user = NULL, *to_host = NULL;
+       char *my_to_user = NULL;
+       char *sql, *event = NULL;
+       char *proto = "sip";
+       char *d_user = NULL;
+       char *contact_str = "";
+       const char *call_id = NULL;
+       char *to_str = NULL;
+       char *full_from = NULL;
+       char *full_via = NULL;
+       char *full_agent = NULL;
+       char *sstr;
+       switch_event_t *sevent;
+       int sub_state;
+       int sent_reply = 0;
+       sip_contact_t const *contact;
+       const char *ipv6;
+       const char *contact_host, *contact_user;
+       sofia_nat_parse_t np = { { 0 } };
 
-               if (sofia_glue_check_nat(profile, network_ip)) {
-                       is_auto_nat = 1;
-               }
+       if (!sip) {
+               return;
+       }
 
-               tl_gets(tags, NUTAG_SUBSTATE_REF(sub_state), TAG_END());
+       to = sip->sip_to;
+       contact = sip->sip_contact;
 
-               event = sip_header_as_string(profile->home, (void *) sip->sip_event);
+       if (!(contact_str = sofia_glue_gen_contact_str(profile, sip, &np))) {
+               nua_respond(nh, 481, "INVALID SUBSCRIPTION", TAG_END());
+               return;
+       }
 
-               port = (char *) contact->m_url->url_port;
-               contact_host = sip->sip_contact->m_url->url_host;
-               contact_user = sip->sip_contact->m_url->url_user;
+       contact_host = sip->sip_contact->m_url->url_host;
+       contact_user = sip->sip_contact->m_url->url_user;
 
-               display = contact->m_display;
+       tl_gets(tags, NUTAG_SUBSTATE_REF(sub_state), TAG_END());
 
-               if (zstr(display)) {
-                       if (from) {
-                               display = from->a_display;
-                               if (zstr(display)) {
-                                       display = "\"user\"";
-                               }
-                       }
-               } else {
-                       display = "\"user\"";
-               }
+       event = sip_header_as_string(profile->home, (void *) sip->sip_event);
 
-               if (sofia_test_pflag(profile, PFLAG_AGGRESSIVE_NAT_DETECTION)) {
-                       if (sip && sip->sip_via) {
-                               const char *v_port = sip->sip_via->v_port;
-                               const char *v_host = sip->sip_via->v_host;
 
-                               if (v_host && sip->sip_via->v_received) {
-                                       is_nat = "via received";
-                               } else if (v_host && strcmp(network_ip, v_host)) {
-                                       is_nat = "via host";
-                               } else if (v_port && atoi(v_port) != network_port) {
-                                       is_nat = "via port";
-                               }
+       /* the following could be refactored back to the calling event handler in sofia.c XXX MTK */
+       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"))) {
+                       /* 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 (!is_nat && sip && sip->sip_via && sip->sip_via->v_port &&
-                       atoi(sip->sip_via->v_port) == 5060 && network_port != 5060 ) {
-                       is_nat = "via port";
-               }
+       if (to) {
+               to_str = switch_mprintf("sip:%s@%s", to->a_url->url_user, to->a_url->url_host);
+       }
 
-               if (!is_nat && profile->nat_acl_count) {
-                       uint32_t x = 0;
-                       int ok = 1;
-                       char *last_acl = NULL;
+       if (to) {
+               to_user = to->a_url->url_user;
+               to_host = to->a_url->url_host;
+       }
 
-                       if (!zstr(contact_host)) {
-                               for (x = 0; x < profile->nat_acl_count; x++) {
-                                       last_acl = profile->nat_acl[x];
-                                       if (!(ok = switch_check_network_list_ip(contact_host, last_acl))) {
-                                               break;
-                                       }
-                               }
+       if (profile->sub_domain) {
+               to_host = profile->sub_domain;
+       }
 
-                               if (ok) {
-                                       is_nat = last_acl;
-                               }
-                       }
-               }
+       if (sip->sip_from) {
+               from_user = sip->sip_from->a_url->url_user;
+               from_host = sip->sip_from->a_url->url_host;
+       } else {
+               from_user = "n/a";
+               from_host = "n/a";
+       }
 
-               if (is_nat && profile->local_network && switch_check_network_list_ip(network_ip, profile->local_network)) {
-                       if (profile->debug) {
-                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "IP %s is on local network, not seting NAT mode.\n", network_ip);
-                       }
-                       is_nat = NULL;
+       if ((exp_delta = sip->sip_expires ? sip->sip_expires->ex_delta : 3600)) {
+               if (profile->force_subscription_expires) {
+                       exp_delta = profile->force_subscription_expires;
                }
+       }
 
-               if (zstr(contact_host)) {
-                       is_nat = "No contact host";
-               }
+       if (exp_delta) {
+               exp_abs = (long) switch_epoch_time_now(NULL) + exp_delta;
+       } else {
+               exp_abs = 0;
+               sub_state = nua_substate_terminated;
+       }
 
-               if (is_nat) {
-                       contact_host = network_ip;
-                       switch_snprintf(new_port, sizeof(new_port), ":%d", network_port);
-                       port = NULL;
-               }
+       switch_snprintf(exp_delta_str, sizeof(exp_delta_str), "%ld", exp_delta);
 
-               if (zstr(contact_host)) {
-                       nua_respond(nh, 481, "INVALID SUBSCRIPTION", TAG_END());
-                       return;
+       if (to_user && strchr(to_user, '+')) {
+               char *h;
+               if ((proto = (d_user = strdup(to_user)))) {
+                       if ((my_to_user = strchr(d_user, '+'))) {
+                               *my_to_user++ = '\0';
+                               to_user = my_to_user;
+                               if ((h = strchr(to_user, '+')) || (h = strchr(to_user, '@'))) {
+                                       *h++ = '\0';
+                                       to_host = h;
+                               }
+                       }
                }
 
-               if (port) {
-                       switch_snprintf(new_port, sizeof(new_port), ":%s", port);
+               if (!(proto && to_user && to_host)) {
+                       nua_respond(nh, SIP_404_NOT_FOUND, NUTAG_WITH_THIS(nua), TAG_END());
+                       goto end;
                }
+       }
 
-               ipv6 = strchr(contact_host, ':');
-               if (contact->m_url->url_params) {
-                       contact_str = switch_mprintf("%s <sip:%s@%s%s%s%s;%s>%s",
-                                                                                display, contact->m_url->url_user,
-                                                                                ipv6 ? "[" : "",
-                                                                                contact_host, ipv6 ? "]" : "", new_port, contact->m_url->url_params, is_nat ? ";fs_nat=yes" : "");
-               } else {
-                       contact_str = switch_mprintf("%s <sip:%s@%s%s%s%s>%s",
-                                                                                display,
-                                                                                contact->m_url->url_user, ipv6 ? "[" : "", contact_host, ipv6 ? "]" : "", new_port, is_nat ? ";fs_nat=yes" : "");
-               }
+       call_id = sip->sip_call_id->i_id;
+       full_from = sip_header_as_string(profile->home, (void *) sip->sip_from);
+       full_via = sip_header_as_string(profile->home, (void *) sip->sip_via);
 
+       if (sip->sip_expires && sip->sip_expires->ex_delta > 31536000) {
+               sip->sip_expires->ex_delta = 31536000;
+       }
 
+       if (sofia_test_pflag(profile, PFLAG_MULTIREG)) {
+               sql = switch_mprintf("delete from sip_subscriptions where call_id='%q' "
+                                                        "or (proto='%q' and sip_user='%q' and sip_host='%q' "
+                                                        "and sub_to_user='%q' and sub_to_host='%q' and event='%q' and hostname='%q' "
+                                                        "and contact='%q')",
+                                                        call_id, proto, from_user, from_host, to_user, to_host, event, mod_sofia_globals.hostname, contact_str);
 
-               /* the following could be refactored back to the calling event handler in sofia.c XXX MTK */
-               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"))) {
-                               /* 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;
-                       }
-               }
+       } else {
+               sql = switch_mprintf("delete from sip_subscriptions where "
+                                                        "proto='%q' and sip_user='%q' and sip_host='%q' and sub_to_user='%q' and sub_to_host='%q' and event='%q' and hostname='%q'",
+                                                        proto, from_user, from_host, to_user, to_host, event, mod_sofia_globals.hostname);
+       }
 
+       switch_mutex_lock(profile->ireg_mutex);
+       switch_assert(sql != NULL);
+       sofia_glue_actually_execute_sql(profile, sql, NULL);
+       switch_safe_free(sql);
 
+       if (sub_state == nua_substate_terminated) {
+               sstr = switch_mprintf("terminated");
+       } else {
+               sip_accept_t *ap = sip->sip_accept;
+               char accept[256] = "";
+               full_agent = sip_header_as_string(profile->home, (void *) sip->sip_user_agent);
+               while (ap) {
+                       switch_snprintf(accept + strlen(accept), sizeof(accept) - strlen(accept), "%s%s ", ap->ac_type, ap->ac_next ? "," : "");
+                       ap = ap->ac_next;
+               }
+
+               sql = switch_mprintf("insert into sip_subscriptions "
+                                                        "(proto,sip_user,sip_host,sub_to_user,sub_to_host,presence_hosts,event,contact,call_id,full_from,"
+                                                        "full_via,expires,user_agent,accept,profile_name,hostname,network_port,network_ip) "
+                                                        "values ('%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q',%ld,'%q','%q','%q','%q','%d','%q')",
+                                                        proto, from_user, from_host, to_user, to_host, profile->presence_hosts ? profile->presence_hosts : to_host,
+                                                        event, contact_str, call_id, full_from, full_via,
+                                                        //sofia_test_pflag(profile, PFLAG_MULTIREG) ? switch_epoch_time_now(NULL) + exp_delta : exp_delta * -1,
+                                                        (long) switch_epoch_time_now(NULL) + (exp_delta * 2),
+                                                        full_agent, accept, profile->name, mod_sofia_globals.hostname, np.network_port, np.network_ip);
 
-               if (to) {
-                       to_str = switch_mprintf("sip:%s@%s", to->a_url->url_user, to->a_url->url_host);
-               }
+               switch_assert(sql != NULL);
 
-               if (to) {
-                       to_user = to->a_url->url_user;
-                       to_host = to->a_url->url_host;
+               if (mod_sofia_globals.debug_presence > 0 || mod_sofia_globals.debug_sla > 0) {
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "%s SUBSCRIBE %s@%s %s@%s\n%s\n",
+                                                         profile->name, from_user, from_host, to_user, to_host, sql);
                }
 
-               if (profile->sub_domain) {
-                       to_host = profile->sub_domain;
-               }
 
-               if (sip && sip->sip_from) {
-                       from_user = sip->sip_from->a_url->url_user;
-                       from_host = sip->sip_from->a_url->url_host;
-               } else {
-                       from_user = "n/a";
-                       from_host = "n/a";
-               }
+               sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
+               sstr = switch_mprintf("active;expires=%ld", exp_delta);
+       }
+
+       switch_mutex_unlock(profile->ireg_mutex);
+
+       if (status < 200) {
+               char *sticky = NULL;
+               char *contactstr = profile->url, *cs = NULL;
+               char *p = NULL, *new_contactstr = NULL;
 
-               if ((exp_delta = sip->sip_expires ? sip->sip_expires->ex_delta : 3600)) {
-                       if (profile->force_subscription_expires) {
-                               exp_delta = profile->force_subscription_expires;
+               if (np.is_nat) {
+                       char params[128] = "";
+                       if (contact->m_url->url_params) {
+                               switch_snprintf(params, sizeof(params), ";%s", contact->m_url->url_params);
                        }
+                       ipv6 = strchr(np.network_ip, ':');
+                       sticky = switch_mprintf("sip:%s@%s%s%s:%d%s", contact_user, ipv6 ? "[" : "", np.network_ip, ipv6 ? "]" : "", np.network_port, params);
                }
 
-               if (exp_delta) {
-                       exp_abs = (long) switch_epoch_time_now(NULL) + exp_delta;
+               if (np.is_auto_nat) {
+                       contactstr = profile->public_url;
                } else {
-                       exp_abs = 0;
-                       sub_state = nua_substate_terminated;
+                       contactstr = profile->url;
                }
 
-               switch_snprintf(exp_delta_str, sizeof(exp_delta_str), "%ld", exp_delta);
 
-               if (to_user && strchr(to_user, '+')) {
-                       char *h;
-                       if ((proto = (d_user = strdup(to_user)))) {
-                               if ((my_to_user = strchr(d_user, '+'))) {
-                                       *my_to_user++ = '\0';
-                                       to_user = my_to_user;
-                                       if ((h = strchr(to_user, '+')) || (h = strchr(to_user, '@'))) {
-                                               *h++ = '\0';
-                                               to_host = h;
-                                       }
-                               }
+               if (switch_stristr("port=tcp", contact->m_url->url_params)) {
+                       if (np.is_auto_nat) {
+                               cs = profile->tcp_public_contact;
+                       } else {
+                               cs = profile->tcp_contact;
                        }
-
-                       if (!(proto && to_user && to_host)) {
-                               nua_respond(nh, SIP_404_NOT_FOUND, NUTAG_WITH_THIS(nua), TAG_END());
-                               goto end;
+               } else if (switch_stristr("port=tls", contact->m_url->url_params)) {
+                       if (np.is_auto_nat) {
+                               cs = profile->tls_public_contact;
+                       } else {
+                               cs = profile->tls_contact;
                        }
                }
 
-               call_id = sip->sip_call_id->i_id;
-               full_from = sip_header_as_string(profile->home, (void *) sip->sip_from);
-               full_via = sip_header_as_string(profile->home, (void *) sip->sip_via);
-
-               if (sip && sip->sip_expires && sip->sip_expires->ex_delta > 31536000) {
-                       sip->sip_expires->ex_delta = 31536000;
+               if (cs) {
+                       contactstr = cs;
                }
 
-               if (sofia_test_pflag(profile, PFLAG_MULTIREG)) {
-                       sql = switch_mprintf("delete from sip_subscriptions where call_id='%q' "
-                                                                "or (proto='%q' and sip_user='%q' and sip_host='%q' "
-                                                                "and sub_to_user='%q' and sub_to_host='%q' and event='%q' and hostname='%q' "
-                                                                "and contact='%q')",
-                                                                call_id, proto, from_user, from_host, to_user, to_host, event, mod_sofia_globals.hostname, contact_str);
-
-               } else {
-                       sql = switch_mprintf("delete from sip_subscriptions where "
-                                                                "proto='%q' and sip_user='%q' and sip_host='%q' and sub_to_user='%q' and sub_to_host='%q' and event='%q' and hostname='%q'",
-                                                                proto, from_user, from_host, to_user, to_host, event, mod_sofia_globals.hostname);
+                       
+               if (nh && nh->nh_ds && nh->nh_ds->ds_usage) {
+                       /* nua_dialog_usage_set_refresh_range(nh->nh_ds->ds_usage, exp_delta + SUB_OVERLAP, exp_delta + SUB_OVERLAP); */
+                       nua_dialog_usage_set_refresh_range(nh->nh_ds->ds_usage, exp_delta * 2, exp_delta * 2);
                }
 
-               switch_mutex_lock(profile->ireg_mutex);
-               switch_assert(sql != NULL);
-               sofia_glue_actually_execute_sql(profile, sql, NULL);
-               switch_safe_free(sql);
-
-               if (sub_state == nua_substate_terminated) {
-                       sstr = switch_mprintf("terminated");
-               } else {
-                       sip_accept_t *ap = sip->sip_accept;
-                       char accept[256] = "";
-                       full_agent = sip_header_as_string(profile->home, (void *) sip->sip_user_agent);
-                       while (ap) {
-                               switch_snprintf(accept + strlen(accept), sizeof(accept) - strlen(accept), "%s%s ", ap->ac_type, ap->ac_next ? "," : "");
-                               ap = ap->ac_next;
-                       }
-
-                       sql = switch_mprintf("insert into sip_subscriptions "
-                                                                "(proto,sip_user,sip_host,sub_to_user,sub_to_host,presence_hosts,event,contact,call_id,full_from,"
-                                                                "full_via,expires,user_agent,accept,profile_name,hostname,network_port,network_ip) "
-                                                                "values ('%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q',%ld,'%q','%q','%q','%q','%d','%q')",
-                                                                proto, from_user, from_host, to_user, to_host, profile->presence_hosts ? profile->presence_hosts : to_host,
-                                                                event, contact_str, call_id, full_from, full_via,
-                                                                //sofia_test_pflag(profile, PFLAG_MULTIREG) ? switch_epoch_time_now(NULL) + exp_delta : exp_delta * -1,
-                                                                (long) switch_epoch_time_now(NULL) + (exp_delta * 2),
-                                                                full_agent, accept, profile->name, mod_sofia_globals.hostname, network_port, network_ip);
-
-                       switch_assert(sql != NULL);
-
-                       if (mod_sofia_globals.debug_presence > 0 || mod_sofia_globals.debug_sla > 0) {
-                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "%s SUBSCRIBE %s@%s %s@%s\n%s\n",
-                                                                 profile->name, from_user, from_host, to_user, to_host, sql);
+               if (contactstr && (p = strchr(contactstr, '@'))) {
+                       if (strrchr(p, '>')) {
+                               new_contactstr = switch_mprintf("<sip:%s%s", to_user, p);
+                       } else {
+                               new_contactstr = switch_mprintf("<sip:%s%s>", to_user, p);
                        }
-
-
-                       sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
-                       sstr = switch_mprintf("active;expires=%ld", exp_delta);
                }
 
-               switch_mutex_unlock(profile->ireg_mutex);
+               nua_respond(nh, SIP_202_ACCEPTED,
+                                       TAG_IF(new_contactstr, SIPTAG_CONTACT_STR(new_contactstr)),
+                                       NUTAG_WITH_THIS(nua),
+                                       SIPTAG_SUBSCRIPTION_STATE_STR(sstr), SIPTAG_EXPIRES_STR(exp_delta_str), TAG_IF(sticky, NUTAG_PROXY(sticky)), TAG_END());
 
-               if (status < 200) {
-                       char *sticky = NULL;
-                       char *contactstr = profile->url, *cs = NULL;
-                       char *p = NULL, *new_contactstr = NULL;
+               switch_safe_free(new_contactstr);
+               switch_safe_free(sticky);
+       }
 
-                       if (is_nat) {
-                               char params[128] = "";
-                               if (contact->m_url->url_params) {
-                                       switch_snprintf(params, sizeof(params), ";%s", contact->m_url->url_params);
-                               }
-                               ipv6 = strchr(network_ip, ':');
-                               sticky = switch_mprintf("sip:%s@%s%s%s:%d%s", contact_user, ipv6 ? "[" : "", network_ip, ipv6 ? "]" : "", network_port, params);
-                       }
+       if (sub_state == nua_substate_terminated) {
+               char *full_call_info = NULL;
+               char *p = NULL;
 
-                       if (is_auto_nat) {
-                               contactstr = profile->public_url;
-                       } else {
-                               contactstr = profile->url;
+               if (sip->sip_call_info) {
+                       full_call_info = sip_header_as_string(profile->home, (void *) sip->sip_call_info);
+                       if ((p = strchr(full_call_info, ';'))) {
+                               p++;
                        }
 
+                       nua_notify(nh,
+                                          SIPTAG_EXPIRES_STR("0"),
+                                          SIPTAG_SUBSCRIPTION_STATE_STR(sstr), TAG_IF(full_call_info, SIPTAG_CALL_INFO_STR(full_call_info)), TAG_END());
 
-                       if (switch_stristr("port=tcp", contact->m_url->url_params)) {
-                               if (is_auto_nat) {
-                                       cs = profile->tcp_public_contact;
-                               } else {
-                                       cs = profile->tcp_contact;
-                               }
-                       } else if (switch_stristr("port=tls", contact->m_url->url_params)) {
-                               if (is_auto_nat) {
-                                       cs = profile->tls_public_contact;
-                               } else {
-                                       cs = profile->tls_contact;
+
+                       if (!strcasecmp(event, "line-seize")) {
+                               if (mod_sofia_globals.debug_sla > 1) {
+                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "CANCEL LINE SEIZE\n");
                                }
-                       }
 
-                       if (cs) {
-                               contactstr = cs;
-                       }
+                               sql = switch_mprintf("delete from sip_dialogs where ((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q') "
+                                                                        "and call_info_state='seized'",
+                                                                        to_user, to_host, to_user, to_host);
 
-                       
-                       if (nh && nh->nh_ds && nh->nh_ds->ds_usage) {
-                               /* nua_dialog_usage_set_refresh_range(nh->nh_ds->ds_usage, exp_delta + SUB_OVERLAP, exp_delta + SUB_OVERLAP); */
-                               nua_dialog_usage_set_refresh_range(nh->nh_ds->ds_usage, exp_delta * 2, exp_delta * 2);
-                       }
 
-                       if (contactstr && (p = strchr(contactstr, '@'))) {
-                               if (strrchr(p, '>')) {
-                                       new_contactstr = switch_mprintf("<sip:%s%s", to_user, p);
-                               } else {
-                                       new_contactstr = switch_mprintf("<sip:%s%s>", to_user, p);
+                               if (mod_sofia_globals.debug_sla > 1) {
+                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "CLEAR SQL %s\n", sql);
                                }
+                               sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
+
+                               sync_sla(profile, to_user, to_host, SWITCH_FALSE, SWITCH_FALSE);
                        }
 
-                       nua_respond(nh, SIP_202_ACCEPTED,
-                                               TAG_IF(new_contactstr, SIPTAG_CONTACT_STR(new_contactstr)),
-                                               NUTAG_WITH_THIS(nua),
-                                               SIPTAG_SUBSCRIPTION_STATE_STR(sstr), SIPTAG_EXPIRES_STR(exp_delta_str), TAG_IF(sticky, NUTAG_PROXY(sticky)), TAG_END());
+                       su_free(profile->home, full_call_info);
 
-                       switch_safe_free(new_contactstr);
-                       switch_safe_free(sticky);
                }
-
-               if (sub_state == nua_substate_terminated) {
+                       
+       } else {
+               if (!strcasecmp(event, "line-seize")) {
                        char *full_call_info = NULL;
-                       char *p = NULL;
+                       char *p;
 
                        if (sip->sip_call_info) {
                                full_call_info = sip_header_as_string(profile->home, (void *) sip->sip_call_info);
@@ -2396,153 +2336,117 @@ void sofia_presence_handle_sip_i_subscribe(int status,
                                }
 
                                nua_notify(nh,
-                                                  SIPTAG_EXPIRES_STR("0"),
-                                                  SIPTAG_SUBSCRIPTION_STATE_STR(sstr), TAG_IF(full_call_info, SIPTAG_CALL_INFO_STR(full_call_info)), TAG_END());
+                                                  SIPTAG_EXPIRES_STR(exp_delta_str),
+                                                  SIPTAG_SUBSCRIPTION_STATE_STR(sstr),
+                                                  SIPTAG_EVENT_STR("line-seize"), TAG_IF(full_call_info, SIPTAG_CALL_INFO_STR(full_call_info)), TAG_END());
 
 
-                               if (!strcasecmp(event, "line-seize")) {
-                                       if (mod_sofia_globals.debug_sla > 1) {
-                                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "CANCEL LINE SEIZE\n");
-                                       }
 
-                                       sql = switch_mprintf("delete from sip_dialogs where ((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q') "
-                                                                                "and call_info_state='seized'",
-                                                                                to_user, to_host, to_user, to_host);
+                               sql = switch_mprintf("delete from sip_dialogs where ((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q') "
+                                                                        "and call_info_state='seized'",
+                                                                        to_user, to_host, to_user, to_host);
 
 
-                                       if (mod_sofia_globals.debug_sla > 1) {
-                                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "CLEAR SQL %s\n", sql);
-                                       }
-                                       sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
-
-                                       sync_sla(profile, to_user, to_host, SWITCH_FALSE, SWITCH_FALSE);
+                               if (mod_sofia_globals.debug_sla > 1) {
+                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "CLEAR SQL %s\n", sql);
                                }
+                               sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
 
-                               su_free(profile->home, full_call_info);
-
-                       }
-                       
-               } else {
-                       if (!strcasecmp(event, "line-seize")) {
-                               char *full_call_info = NULL;
-                               char *p;
-
-                               if (sip->sip_call_info) {
-                                       full_call_info = sip_header_as_string(profile->home, (void *) sip->sip_call_info);
-                                       if ((p = strchr(full_call_info, ';'))) {
-                                               p++;
-                                       }
-
-                                       nua_notify(nh,
-                                                          SIPTAG_EXPIRES_STR(exp_delta_str),
-                                                          SIPTAG_SUBSCRIPTION_STATE_STR(sstr),
-                                                          SIPTAG_EVENT_STR("line-seize"), TAG_IF(full_call_info, SIPTAG_CALL_INFO_STR(full_call_info)), TAG_END());
-
-
-
-                                       sql = switch_mprintf("delete from sip_dialogs where ((sip_from_user='%q' and sip_from_host='%q') or presence_id='%q@%q') "
-                                                                                "and call_info_state='seized'",
-                                                                                to_user, to_host, to_user, to_host);
-
+                               sql = switch_mprintf("insert into sip_dialogs (sip_from_user,sip_from_host,call_info,call_info_state,hostname,expires) "
+                                                                        "values ('%q','%q','%q','seized','%q',%ld)",
+                                                                        to_user, to_host, switch_str_nil(p), mod_sofia_globals.hostname, switch_epoch_time_now(NULL) + exp_delta);
 
-                                       if (mod_sofia_globals.debug_sla > 1) {
-                                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "CLEAR SQL %s\n", sql);
-                                       }
-                                       sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
-
-                                       sql = switch_mprintf("insert into sip_dialogs (sip_from_user,sip_from_host,call_info,call_info_state,hostname,expires) "
-                                                                                "values ('%q','%q','%q','seized','%q',%ld)",
-                                                                                to_user, to_host, switch_str_nil(p), mod_sofia_globals.hostname, switch_epoch_time_now(NULL) + exp_delta);
-
-                                       if (mod_sofia_globals.debug_sla > 1) {
-                                               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SEIZE SQL %s\n", sql);
-                                       }
-                                       sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
-                                       sync_sla(profile, to_user, to_host, SWITCH_FALSE, SWITCH_FALSE);
-
-                                       su_free(profile->home, full_call_info);
+                               if (mod_sofia_globals.debug_sla > 1) {
+                                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SEIZE SQL %s\n", sql);
                                }
-                       } else if (!strcasecmp(event, "call-info")) {
+                               sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
                                sync_sla(profile, to_user, to_host, SWITCH_FALSE, SWITCH_FALSE);
+
+                               su_free(profile->home, full_call_info);
                        }
+               } else if (!strcasecmp(event, "call-info")) {
+                       sync_sla(profile, to_user, to_host, SWITCH_FALSE, SWITCH_FALSE);
                }
+       }
 
-               sent_reply++;
+       sent_reply++;
 
-               switch_safe_free(sstr);
+       switch_safe_free(sstr);
 
-               if (!strcasecmp(event, "message-summary")) {
-                       if ((sql = switch_mprintf("select proto,sip_user,'%q',sub_to_user,sub_to_host,event,contact,call_id,full_from,"
-                                                                         "full_via,expires,user_agent,accept,profile_name,network_ip"
-                                                                         " from sip_subscriptions where expires > -1 and event='message-summary' and sip_user='%q' "
-                                                                         "and (sip_host='%q' or presence_hosts like '%%%q%%')", to_host, to_user, to_host, to_host))) {
-                               sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_presence_sub_reg_callback, profile);
+       if (!strcasecmp(event, "message-summary")) {
+               if ((sql = switch_mprintf("select proto,sip_user,'%q',sub_to_user,sub_to_host,event,contact,call_id,full_from,"
+                                                                 "full_via,expires,user_agent,accept,profile_name,network_ip"
+                                                                 " from sip_subscriptions where version > -1 and "
+                                                                 "expires > -1 and event='message-summary' and sip_user='%q' "
+                                                                 "and (sip_host='%q' or presence_hosts like '%%%q%%')", to_host, to_user, to_host, to_host))) {
+                       sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_presence_sub_reg_callback, profile);
 
-                               switch_safe_free(sql);
-                       }
+                       switch_safe_free(sql);
                }
+       }
 
        end:
+ end:
 
-               if (to_user && (strstr(to_user, "ext+") || strstr(to_user, "user+"))) {
-                       char protocol[80];
-                       char *p;
+       if (to_user && (strstr(to_user, "ext+") || strstr(to_user, "user+"))) {
+               char protocol[80];
+               char *p;
 
-                       switch_copy_string(protocol, to_user, sizeof(protocol));
-                       if ((p = strchr(protocol, '+'))) {
-                               *p = '\0';
-                       }
+               switch_copy_string(protocol, to_user, sizeof(protocol));
+               if ((p = strchr(protocol, '+'))) {
+                       *p = '\0';
+               }
 
-                       if (switch_event_create(&sevent, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
-                               switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "proto", protocol);
-                               switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "login", profile->name);
-                               switch_event_add_header(sevent, SWITCH_STACK_BOTTOM, "from", "%s@%s", to_user, to_host);
-                               switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "rpid", "active");
-                               switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "status", "Click To Call");
-                               switch_event_fire(&sevent);
-                       }
+               if (switch_event_create(&sevent, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
+                       switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "proto", protocol);
+                       switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "login", profile->name);
+                       switch_event_add_header(sevent, SWITCH_STACK_BOTTOM, "from", "%s@%s", to_user, to_host);
+                       switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "rpid", "active");
+                       switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "status", "Click To Call");
+                       switch_event_fire(&sevent);
+               }
 
-               } else {
-                       if (switch_event_create(&sevent, SWITCH_EVENT_PRESENCE_PROBE) == SWITCH_STATUS_SUCCESS) {
-                               switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO);
-                               switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "login", profile->name);
-                               switch_event_add_header(sevent, SWITCH_STACK_BOTTOM, "from", "%s@%s", from_user, from_host);
-                               switch_event_add_header(sevent, SWITCH_STACK_BOTTOM, "to", "%s@%s", to_user, to_host);
-                               switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "proto-specific-event-name", event);
-                               switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "expires", exp_delta_str);
-                               switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "event_type", "presence");
-                               switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog");
-                               switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "expires", exp_delta_str);
-                               switch_event_fire(&sevent);
-                       }
+       } else {
+               if (switch_event_create(&sevent, SWITCH_EVENT_PRESENCE_PROBE) == SWITCH_STATUS_SUCCESS) {
+                       switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO);
+                       switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "login", profile->name);
+                       switch_event_add_header(sevent, SWITCH_STACK_BOTTOM, "from", "%s@%s", from_user, from_host);
+                       switch_event_add_header(sevent, SWITCH_STACK_BOTTOM, "to", "%s@%s", to_user, to_host);
+                       switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "proto-specific-event-name", event);
+                       switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "expires", exp_delta_str);
+                       switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "event_type", "presence");
+                       switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog");
+                       switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "expires", exp_delta_str);
+                       switch_event_fire(&sevent);
                }
+       }
 
 
 
-               if (event) {
-                       su_free(profile->home, event);
-               }
+       if (event) {
+               su_free(profile->home, event);
+       }
 
-               if (full_from) {
-                       su_free(profile->home, full_from);
-               }
-               if (full_via) {
-                       su_free(profile->home, full_via);
-               }
-               if (full_agent) {
-                       su_free(profile->home, full_agent);
-               }
+       if (full_from) {
+               su_free(profile->home, full_from);
+       }
+       if (full_via) {
+               su_free(profile->home, full_via);
+       }
+       if (full_agent) {
+               su_free(profile->home, full_agent);
+       }
 
-               switch_safe_free(d_user);
-               switch_safe_free(to_str);
-               switch_safe_free(contact_str);
+       switch_safe_free(d_user);
+       switch_safe_free(to_str);
+       switch_safe_free(contact_str);
 
-               if (!sent_reply) {
-                       nua_respond(nh, 481, "INVALID SUBSCRIPTION", TAG_END());
-               }
+       if (!sent_reply) {
+               nua_respond(nh, 481, "INVALID SUBSCRIPTION", TAG_END());
        }
+               
 }
 
+
 sofia_gateway_subscription_t *sofia_find_gateway_subscription(sofia_gateway_t *gateway_ptr, const char *event)
 {
        sofia_gateway_subscription_t *gw_sub_ptr;
@@ -2624,145 +2528,197 @@ void sofia_presence_handle_sip_r_subscribe(int status,
        }
 }
 
+static int sofia_counterpath_crutch(void *pArg, int argc, char **argv, char **columnNames)
+{
+       nua_handle_t *nh;
+       sofia_profile_t *profile = (sofia_profile_t *) pArg;
+       char *call_id = argv[0];
+       char *pl = argv[1];
+       char *event_type = argv[2];
+       long exp_delta = atol(argv[3]);
+
+       if ((nh = nua_handle_by_call_id(profile->nua, call_id))) {
+               char sstr[128] = "", expstr[128] = "";
+               switch_snprintf(expstr, sizeof(expstr), "%d", exp_delta);
+               switch_snprintf(sstr, sizeof(sstr), "active;expires=%u", exp_delta);
+               nua_notify(nh,
+                                  NUTAG_WITH_THIS(profile->nua),
+                                  SIPTAG_EXPIRES_STR(expstr),
+                                  SIPTAG_SUBSCRIPTION_STATE_STR(sstr), SIPTAG_EVENT_STR(event_type), 
+                                  SIPTAG_CONTENT_TYPE_STR("application/pidf+xml"), SIPTAG_PAYLOAD_STR(pl), TAG_END());
+       }
+
+       return 0;
+}
+
 void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, nua_handle_t *nh, sofia_private_t *sofia_private, sip_t const *sip,
                                                                                 tagi_t tags[])
 {
-       if (sip) {
-               sip_from_t const *from = sip->sip_from;
-               char *from_user = NULL;
-               char *from_host = NULL;
-               char *rpid = "";
-               sip_payload_t *payload = sip->sip_payload;
-               char *event_type = NULL;
-               char etag[9] = "";
-               char expstr[30] = "";
-               long exp = 0, exp_delta = 3600;
-               char *pd_dup = NULL;
-
-               /* the following could instead be refactored back to the calling event handler in sofia.c XXX MTK */
-               if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)) {
-                       /* also it probably is unsafe to dereference so many things in a row without testing XXX MTK */
-                       if (sip->sip_request->rq_url->url_user && !strncmp(sip->sip_request->rq_url->url_user, "sla-agent", sizeof("sla-agent"))) {
-                               sofia_sla_handle_sip_i_publish(nua, profile, nh, sip, tags);
-                               return;
-                       }
-               }
+       
+       sip_from_t const *from;
+       char *from_user = NULL;
+       char *from_host = NULL;
+       char *rpid = "";
+       sip_payload_t *payload;
+       char *event_type = NULL;
+       char etag[9] = "";
+       char expstr[30] = "";
+       long exp = 0, exp_delta = 3600;
+       char *pd_dup = NULL;
+       int count = 1;
+       char *contact_str;
+       int open = 1;
 
-               if (from) {
-                       from_user = (char *) from->a_url->url_user;
-                       from_host = (char *) from->a_url->url_host;
+       if (!sip) {
+               return;
+       }
+
+       from = sip->sip_from;
+       payload = sip->sip_payload;
+
+       /* the following could instead be refactored back to the calling event handler in sofia.c XXX MTK */
+       if (sofia_test_pflag(profile, PFLAG_MANAGE_SHARED_APPEARANCE)) {
+               /* also it probably is unsafe to dereference so many things in a row without testing XXX MTK */
+               if (sip->sip_request->rq_url->url_user && !strncmp(sip->sip_request->rq_url->url_user, "sla-agent", sizeof("sla-agent"))) {
+                       sofia_sla_handle_sip_i_publish(nua, profile, nh, sip, tags);
+                       return;
                }
+       }
+
+       contact_str = sofia_glue_gen_contact_str(profile, sip, NULL);
+
+       if (from) {
+               from_user = (char *) from->a_url->url_user;
+               from_host = (char *) from->a_url->url_host;
+       }
                
-               
-               exp_delta = (sip->sip_expires ? sip->sip_expires->ex_delta : 3600);
-               if (profile->force_publish_expires) {
-                       exp_delta = profile->force_publish_expires;
-               }
+       exp_delta = (sip->sip_expires ? sip->sip_expires->ex_delta : 3600);
+       if (profile->force_publish_expires) {
+               exp_delta = profile->force_publish_expires;
+       }
 
-               if (exp_delta < 0) {
-                       exp = exp_delta;
-               } else {
-                       exp = (long) switch_epoch_time_now(NULL) + exp_delta;
-               }
+       if (exp_delta < 0) {
+               exp = exp_delta;
+       } else {
+               exp = (long) switch_epoch_time_now(NULL) + exp_delta;
+       }
 
-               if (payload) {
-                       switch_xml_t xml, note, person, tuple, status, basic, act;
-                       switch_event_t *event;
-                       char *sql;
-                       char *full_agent = NULL;
-                       int count = 1;
+       if (payload) {
+               switch_xml_t xml, note, person, tuple, status, basic, act;
+               switch_event_t *event;
+               char *sql;
+               char *full_agent = NULL;
+                       
+               pd_dup = strdup(payload->pl_data);
 
-                       pd_dup = strdup(payload->pl_data);
+               if ((xml = switch_xml_parse_str(pd_dup, strlen(pd_dup)))) {
+                       char *open_closed = "", *note_txt = "";
 
-                       if ((xml = switch_xml_parse_str(pd_dup, strlen(pd_dup)))) {
-                               char *open_closed = "", *note_txt = "";
+                       if (sip->sip_user_agent) {
+                               full_agent = sip_header_as_string(profile->home, (void *) sip->sip_user_agent);
+                       }
 
-                               if (sip->sip_user_agent) {
-                                       full_agent = sip_header_as_string(profile->home, (void *) sip->sip_user_agent);
-                               }
+                       if ((tuple = switch_xml_child(xml, "tuple")) && (status = switch_xml_child(tuple, "status"))
+                               && (basic = switch_xml_child(status, "basic"))) {
+                               open_closed = basic->txt;
+                       }
 
-                               if ((tuple = switch_xml_child(xml, "tuple")) && (status = switch_xml_child(tuple, "status"))
-                                       && (basic = switch_xml_child(status, "basic"))) {
-                                       open_closed = basic->txt;
-                               }
+                       if ((person = switch_xml_child(xml, "dm:person")) && (note = switch_xml_child(person, "dm:note"))) {
+                               note_txt = note->txt;
+                       }
 
-                               if ((person = switch_xml_child(xml, "dm:person")) && (note = switch_xml_child(person, "dm:note"))) {
-                                       note_txt = note->txt;
+                       if (person && (act = switch_xml_child(person, "rpid:activities")) && act->child && act->child->name) {
+                               if ((rpid = strchr(act->child->name, ':'))) {
+                                       rpid++;
+                               } else {
+                                       rpid = act->child->name;
                                }
+                       }
+
+                       if (!(open = !strcasecmp(open_closed, "open"))) {
+                               sql = switch_mprintf("update sip_subscriptions set version = -1 where contact='%q'", contact_str);
+                       } else {
+                               sql = switch_mprintf("update sip_subscriptions set version = 0 where contact='%q'", contact_str);
+                       }
+                       
+                       sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
 
-                               if (person && (act = switch_xml_child(person, "rpid:activities")) && act->child && act->child->name) {
-                                       if ((rpid = strchr(act->child->name, ':'))) {
-                                               rpid++;
-                                       } else {
-                                               rpid = act->child->name;
-                                       }
-                               }
 
-                               if (sofia_test_pflag(profile, PFLAG_MULTIREG) && !strcasecmp(open_closed, "closed")) {
-                                       char buf[32] = "";
+                       if (sofia_test_pflag(profile, PFLAG_MULTIREG) && !open) {
+                               char buf[32] = "";
                                        
-                                       sql = switch_mprintf("select count(*) from sip_registrations where sip_user='%q' and orig_server_host='%q'", from_user, from_host);
-                                       sofia_glue_execute_sql2str(profile, profile->ireg_mutex, sql, buf, sizeof(buf));
-                                       switch_safe_free(sql);
-                                       count = atoi(buf);                                                                              
-                               }
+                               sql = switch_mprintf("select count(*) from sip_registrations where "
+                                                                        "sip_user='%q' and (sip_host='%q' or presence_hosts like '%%%q%%')", from_user, from_host, from_host);
+                                       
+                               sofia_glue_execute_sql2str(profile, profile->ireg_mutex, sql, buf, sizeof(buf));
+                               switch_safe_free(sql);
+                               count = atoi(buf);                                                                              
+                       }
                                
 
-                               /* if (count > 1) let's not and say we did or all the clients who subscribe to their own presence will think they selves is offline */
+                       /* if (count > 1) let's not and say we did or all the clients who subscribe to their own presence will think they selves is offline */
 
-                               if (count < 2) {
-                                       if ((sql =
-                                                switch_mprintf("delete from sip_presence where sip_user='%q' and sip_host='%q' "
-                                                                               " and profile_name='%q' and hostname='%q'", from_user, from_host, profile->name, mod_sofia_globals.hostname))) {
-                                               sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
-                                       }
+                       event_type = sip_header_as_string(profile->home, (void *) sip->sip_event);
+
+                       if (count < 2) {
+                               if ((sql =
+                                        switch_mprintf("delete from sip_presence where sip_user='%q' and sip_host='%q' "
+                                                                       " and profile_name='%q' and hostname='%q'", from_user, from_host, profile->name, mod_sofia_globals.hostname))) {
+                                       sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
+                               }
                                        
-                                       if ((sql =
-                                                switch_mprintf("insert into sip_presence (sip_user, sip_host, status, rpid, expires, user_agent,"
-                                                                               " profile_name, hostname, open_closed) "
-                                                                               "values ('%q','%q','%q','%q',%ld,'%q','%q','%q','%q')",
-                                                                               from_user, from_host, note_txt, rpid, exp, full_agent, profile->name, mod_sofia_globals.hostname, open_closed))) {
+                               if ((sql =
+                                        switch_mprintf("insert into sip_presence (sip_user, sip_host, status, rpid, expires, user_agent,"
+                                                                       " profile_name, hostname, open_closed) "
+                                                                       "values ('%q','%q','%q','%q',%ld,'%q','%q','%q','%q')",
+                                                                       from_user, from_host, note_txt, rpid, exp, full_agent, profile->name, mod_sofia_globals.hostname, open_closed))) {
                                                
-                                               sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
-                                       }
+                                       sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
+                               }
                                
+                       } else if (contact_str) {
+                               sql = switch_mprintf("select call_id,'%q','%q','%ld' from sip_subscriptions where sub_to_user='%q' and sub_to_host='%q' "
+                                                                        "and contact = '%q' ", payload->pl_data ? payload->pl_data : "", event_type, exp_delta,
+                                                                        from_user, from_host, contact_str);
+                               sofia_glue_execute_sql_callback(profile, profile->ireg_mutex, sql, sofia_counterpath_crutch, profile);
+                               switch_safe_free(sql);
+                       }
 
-                                       event_type = sip_header_as_string(profile->home, (void *) sip->sip_event);
-                               
-                                       if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
-                                               switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO);
-                                               switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "rpid", rpid);
-                                               switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", profile->url);
-                                               switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "user-agent", full_agent);
-                                               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", from_user, from_host);
-                                               switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "status", note_txt);
-                                               switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_type", event_type);
-                                               switch_event_fire(&event);
-                                       }
-                               }
 
-                               if (event_type) {
-                                       su_free(profile->home, event_type);
-                               }
+                       if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) {
+                               switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO);
+                               switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "rpid", rpid);
+                               switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", profile->url);
+                               switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "user-agent", full_agent);
+                               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "from", "%s@%s", from_user, from_host);
+                               switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "status", note_txt);
+                               switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "event_type", event_type);
+                               switch_event_fire(&event);
+                       }
 
-                               if (full_agent) {
-                                       su_free(profile->home, full_agent);
-                               }
+                       if (event_type) {
+                               su_free(profile->home, event_type);
+                       }
 
-                               switch_xml_free(xml);
+                       if (full_agent) {
+                               su_free(profile->home, full_agent);
                        }
-               } else {
-                       char *sql = switch_mprintf("update sip_presence set expires=%ld where sip_user='%q' and sip_host='%q' and profile_name='%q' and hostname='%q'",
-                                                                exp, from_user, from_host, profile->name, mod_sofia_globals.hostname);
-                       sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
+
+                       switch_xml_free(xml);
                }
+       } else {
+               char *sql = switch_mprintf("update sip_presence set expires=%ld where sip_user='%q' and sip_host='%q' and profile_name='%q' and hostname='%q'",
+                                                                  exp, from_user, from_host, profile->name, mod_sofia_globals.hostname);
+               sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
+       }
 
-               switch_safe_free(pd_dup);
+       switch_safe_free(pd_dup);
 
-               switch_snprintf(expstr, sizeof(expstr), "%d", exp_delta);
-               switch_stun_random_string(etag, 8, NULL);
-               nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS(nua), SIPTAG_ETAG_STR(etag), SIPTAG_EXPIRES_STR(expstr), TAG_END());
-       }
+       switch_snprintf(expstr, sizeof(expstr), "%d", exp_delta);
+       switch_stun_random_string(etag, 8, NULL);
+       nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS(nua), SIPTAG_ETAG_STR(etag), SIPTAG_EXPIRES_STR(expstr), TAG_END());
+
+       switch_safe_free(contact_str);
 }
 
 void sofia_presence_set_hash_key(char *hash_key, int32_t len, sip_t const *sip)