diff --git a/conf/sip_profiles/internal.xml b/conf/sip_profiles/internal.xml index dd0dda153f..e4af5cc772 100644 --- a/conf/sip_profiles/internal.xml +++ b/conf/sip_profiles/internal.xml @@ -43,6 +43,8 @@ + + diff --git a/src/include/switch_utils.h b/src/include/switch_utils.h index 9bec46687d..f24cee5e9f 100644 --- a/src/include/switch_utils.h +++ b/src/include/switch_utils.h @@ -587,6 +587,7 @@ SWITCH_DECLARE(unsigned int) switch_separate_string_string(char *buf, char *deli SWITCH_DECLARE(switch_bool_t) switch_is_number(const char *str); SWITCH_DECLARE(char *) switch_strip_spaces(const char *str); +SWITCH_DECLARE(char *) switch_strip_whitespace(const char *str); SWITCH_DECLARE(char *) switch_strip_commas(char *in, char *out, switch_size_t len); SWITCH_DECLARE(char *) switch_strip_nonnumerics(char *in, char *out, switch_size_t len); SWITCH_DECLARE(char *) switch_separate_paren_args(char *str); diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index 78db36e8d5..0168a33187 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -210,6 +210,7 @@ typedef enum { PFLAG_SQL_IN_TRANS, PFLAG_PASS_CALLEE_ID, PFLAG_LOG_AUTH_FAIL, + PFLAG_FORWARD_MWI_NOTIFY, PFLAG_TRACK_CALLS, PFLAG_TRACK_CALLS_EVENTS, PFLAG_DESTROY, diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 0a0c641365..49ddd2a273 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -372,7 +372,7 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status, sip->sip_event->o_type); } goto error; - } + } /* find the corresponding gateway subscription (if any) */ if (!(gw_sub_ptr = sofia_find_gateway_subscription(sofia_private->gateway, sip->sip_event->o_type))) { @@ -412,6 +412,47 @@ void sofia_handle_sip_i_notify(switch_core_session_t *session, int status, if (sip && sip->sip_event && sip->sip_event->o_type && !strcasecmp(sip->sip_event->o_type, "message-summary")) { /* unsolicited mwi, just say ok */ nua_respond(nh, SIP_200_OK, NUTAG_WITH_THIS(nua), TAG_END()); + + if (sofia_test_pflag(profile, PFLAG_FORWARD_MWI_NOTIFY)) { + const char *mwi_status = NULL; + char network_ip[80]; + uint32_t x = 0; + int acl_ok = 1; + char *last_acl = NULL; + + if (sip->sip_to && sip->sip_to->a_url && sip->sip_to->a_url->url_user && sip->sip_to->a_url->url_host + && sip->sip_payload && sip->sip_payload->pl_data ) { + + sofia_glue_get_addr(nua_current_request(nua), network_ip, sizeof(network_ip), NULL); + for (x = 0; x < profile->acl_count; x++) { + last_acl = profile->acl[x]; + if (!(acl_ok = switch_check_network_list_ip(network_ip, last_acl))) { + break; + } + } + + if ( acl_ok ) + { + mwi_status = switch_stristr("Messages-Waiting: ", sip->sip_payload->pl_data); + + if ( mwi_status ) { + mwi_status += strlen( "Messages-Waiting: " ); + mwi_status = switch_strip_whitespace( mwi_status ); + + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Forwarding unsolicited MWI ( %s : %s@%s )\n", mwi_status, sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host ); + if (switch_event_create(&s_event, SWITCH_EVENT_MESSAGE_WAITING) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header_string(s_event, SWITCH_STACK_BOTTOM, "MWI-Messages-Waiting", mwi_status ); + switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "MWI-Message-Account", "%s@%s", sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host ); + switch_event_fire(&s_event); + } + } + } else { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Dropping unsolicited MWI ( %s@%s ) because of ACL\n", sip->sip_to->a_url->url_user, sip->sip_to->a_url->url_host ); + }; + + } + } + } else { nua_respond(nh, 481, "Subscription Does Not Exist", NUTAG_WITH_THIS(nua), TAG_END()); } @@ -2252,6 +2293,18 @@ switch_status_t reconfig_sofia(sofia_profile_t *profile) } else { sofia_clear_pflag(profile, PFLAG_LOG_AUTH_FAIL); } + } else if (!strcasecmp(var, "forward-unsolicited-mwi-notify")) { + if (switch_true(val)) { + sofia_set_pflag(profile, PFLAG_FORWARD_MWI_NOTIFY); + } else { + sofia_clear_pflag(profile, PFLAG_FORWARD_MWI_NOTIFY); + } + } else if (!strcasecmp(var, "forward-unsolicited-mwi-notify")) { + if (switch_true(val)) { + sofia_set_pflag(profile, PFLAG_FORWARD_MWI_NOTIFY); + } else { + sofia_clear_pflag(profile, PFLAG_FORWARD_MWI_NOTIFY); + } } else if (!strcasecmp(var, "t38-passthru")) { if (switch_true(val)) { sofia_set_pflag(profile, PFLAG_T38_PASSTHRU); diff --git a/src/switch_utils.c b/src/switch_utils.c index 123d8aa162..d7c5d6b6d4 100644 --- a/src/switch_utils.c +++ b/src/switch_utils.c @@ -716,6 +716,32 @@ SWITCH_DECLARE(char *) switch_replace_char(char *str, char from, char to, switch return p; } +SWITCH_DECLARE(char *) switch_strip_whitespace(const char *str) +{ + const char *sp = str; + char *p, *s = NULL; + + if (!sp) + return NULL; + + while ((*sp == 13 ) || (*sp == 10 ) || (*sp == 9 ) || (*sp == 20) || (*sp == 11) ) { + sp++; + } + + s = strdup(sp); + + if (!s) + return NULL; + + p = s + (strlen(s) - 1); + + while ((*p == 13 ) || (*p == 10 ) || (*p == 9 ) || (*p == 20) || (*p == 11) ) { + *p-- = '\0'; + } + + return s; +} + SWITCH_DECLARE(char *) switch_strip_spaces(const char *str) { const char *sp = str;