From fd1736b38fe16131a5496ff7a6866e084d354c32 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 21 Oct 2010 12:50:19 -0500 Subject: [PATCH] 1) Add force-publish-expires to set custom presence update expires delta (-1 means endless) 2) Check how many users are registered when receiving a PUBLISH AND Multiple Registrations is enabled: if there is more than just 1 AND you are sending a offline message: skip publishing it to everyone to prevent clients from thinking themselves has gone offline. --- src/mod/endpoints/mod_sofia/mod_sofia.h | 1 + src/mod/endpoints/mod_sofia/sofia.c | 10 +++ src/mod/endpoints/mod_sofia/sofia_presence.c | 72 +++++++++++++------- 3 files changed, 58 insertions(+), 25 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index 87e0a5be4d..90f5d3a511 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -548,6 +548,7 @@ struct sofia_profile { sofia_presence_type_t pres_type; sofia_media_options_t media_options; uint32_t force_subscription_expires; + uint32_t force_publish_expires; char *user_agent_filter; uint32_t max_registrations_perext; switch_rtp_bug_flag_t auto_rtp_bugs; diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 2f5cbbd8f9..5a14c2cb5a 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -2428,6 +2428,11 @@ switch_status_t reconfig_sofia(sofia_profile_t *profile) if (tmp > 0) { profile->force_subscription_expires = tmp; } + } else if (!strcasecmp(var, "force-publish-expires")) { + int tmp = atoi(val); + if (tmp > 0) { + profile->force_publish_expires = tmp; + } } else if (!strcasecmp(var, "inbound-late-negotiation")) { if (switch_true(val)) { sofia_set_flag(profile, TFLAG_LATE_NEGOTIATION); @@ -3104,6 +3109,11 @@ switch_status_t config_sofia(int reload, char *profile_name) if (tmp > 0) { profile->force_subscription_expires = tmp; } + } else if (!strcasecmp(var, "force-publish-expires")) { + int tmp = atoi(val); + if (tmp > 0) { + profile->force_publish_expires = tmp; + } } else if (!strcasecmp(var, "send-message-query-on-register")) { if (switch_true(val)) { sofia_set_pflag(profile, PFLAG_MESSAGE_QUERY_ON_REGISTER); diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index ceb540d85a..7e3163c2c8 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -2543,7 +2543,7 @@ void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, n char *from_host = NULL; char *rpid = ""; sip_payload_t *payload = sip->sip_payload; - char *event_type; + char *event_type = NULL; char etag[9] = ""; char expstr[30] = ""; long exp = 0, exp_delta = 3600; @@ -2565,13 +2565,22 @@ void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, n exp_delta = (sip->sip_expires ? sip->sip_expires->ex_delta : 3600); - exp = (long) switch_epoch_time_now(NULL) + exp_delta; + 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 (payload) { switch_xml_t xml, note, person, tuple, status, basic, act; switch_event_t *event; char *sql; char *full_agent = NULL; + int count = 1; pd_dup = strdup(payload->pl_data); @@ -2599,34 +2608,47 @@ void sofia_presence_handle_sip_i_publish(nua_t *nua, sofia_profile_t *profile, n } } - - 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 (sofia_test_pflag(profile, PFLAG_MULTIREG) && !strcasecmp(open_closed, "closed")) { + char buf[32] = ""; - 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); + 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); } - event_type = sip_header_as_string(profile->home, (void *) sip->sip_event); + /* 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); + } + + 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); + } - 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); + + 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) {