From 941052b656aeeb4708d57eff8aeadf2873d1d1da Mon Sep 17 00:00:00 2001 From: Anthony Minessale <anthony.minessale@gmail.com> Date: Fri, 23 Jan 2009 20:33:30 +0000 Subject: [PATCH] allow <params> tag in gateways as well as <variables> with direction inbound/outbound (default both) and call counter git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@11468 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- src/mod/endpoints/mod_sofia/mod_sofia.c | 106 +++++++++++++----------- src/mod/endpoints/mod_sofia/mod_sofia.h | 6 +- src/mod/endpoints/mod_sofia/sofia.c | 106 +++++++++++++++++++----- src/mod/endpoints/mod_sofia/sofia_reg.c | 7 +- 4 files changed, 152 insertions(+), 73 deletions(-) diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index fb42db3331..891120efb6 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -1503,22 +1503,25 @@ static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t switch_assert(gp->state < REG_STATE_LAST); stream->write_function(stream, "%s\n", line); - stream->write_function(stream, "Name \t\t%s\n", switch_str_nil(gp->name)); - stream->write_function(stream, "Scheme \t\t%s\n", switch_str_nil(gp->register_scheme)); - stream->write_function(stream, "Realm \t\t%s\n", switch_str_nil(gp->register_realm)); - stream->write_function(stream, "Username\t\t%s\n", switch_str_nil(gp->register_username)); - stream->write_function(stream, "Password\t\t%s\n", switch_strlen_zero(gp->register_password) ? "no" : "yes"); - stream->write_function(stream, "From \t\t%s\n", switch_str_nil(gp->register_from)); - stream->write_function(stream, "Contact \t\t%s\n", switch_str_nil(gp->register_contact)); - stream->write_function(stream, "To \t\t%s\n", switch_str_nil(gp->register_to)); - stream->write_function(stream, "Proxy \t\t%s\n", switch_str_nil(gp->register_proxy)); - stream->write_function(stream, "Context \t\t%s\n", switch_str_nil(gp->register_context)); - stream->write_function(stream, "Expires \t\t%s\n", switch_str_nil(gp->expires_str)); - stream->write_function(stream, "Freq \t\t%d\n", gp->freq); - stream->write_function(stream, "Ping \t\t%d\n", gp->ping); - stream->write_function(stream, "PingFreq\t\t%d\n", gp->ping_freq); - stream->write_function(stream, "State \t\t%s\n", sofia_state_names[gp->state]); - stream->write_function(stream, "Status \t\t%s%s\n", status_names[gp->status], gp->pinging ? " (ping)" : ""); + stream->write_function(stream, "Name \t%s\n", switch_str_nil(gp->name)); + stream->write_function(stream, "Scheme \t%s\n", switch_str_nil(gp->register_scheme)); + stream->write_function(stream, "Realm \t%s\n", switch_str_nil(gp->register_realm)); + stream->write_function(stream, "Username\t%s\n", switch_str_nil(gp->register_username)); + stream->write_function(stream, "Password\t%s\n", switch_strlen_zero(gp->register_password) ? "no" : "yes"); + stream->write_function(stream, "From \t%s\n", switch_str_nil(gp->register_from)); + stream->write_function(stream, "Contact \t%s\n", switch_str_nil(gp->register_contact)); + stream->write_function(stream, "Exten \t%s\n", switch_str_nil(gp->extension)); + stream->write_function(stream, "To \t%s\n", switch_str_nil(gp->register_to)); + stream->write_function(stream, "Proxy \t%s\n", switch_str_nil(gp->register_proxy)); + stream->write_function(stream, "Context \t%s\n", switch_str_nil(gp->register_context)); + stream->write_function(stream, "Expires \t%s\n", switch_str_nil(gp->expires_str)); + stream->write_function(stream, "Freq \t%d\n", gp->freq); + stream->write_function(stream, "Ping \t%d\n", gp->ping); + stream->write_function(stream, "PingFreq\t%d\n", gp->ping_freq); + stream->write_function(stream, "State \t%s\n", sofia_state_names[gp->state]); + stream->write_function(stream, "Status \t%s%s\n", status_names[gp->status], gp->pinging ? " (ping)" : ""); + stream->write_function(stream, "CallsIN \t%d\n", gp->ib_calls); + stream->write_function(stream, "CallsOUT\t%d\n", gp->ob_calls); stream->write_function(stream, "%s\n", line); sofia_reg_release_gateway(gp); } else { @@ -1531,51 +1534,51 @@ static switch_status_t cmd_status(char **argv, int argc, switch_stream_handle_t if ((argv[1]) && (profile = sofia_glue_find_profile(argv[1]))) { if (!argv[2] || strcasecmp(argv[2], "reg")) { stream->write_function(stream, "%s\n", line); - stream->write_function(stream, "Name \t\t%s\n", switch_str_nil(argv[1])); - stream->write_function(stream, "Domain Name \t\t%s\n", profile->domain_name ? profile->domain_name : "N/A"); + stream->write_function(stream, "Name \t%s\n", switch_str_nil(argv[1])); + stream->write_function(stream, "Domain Name \t%s\n", profile->domain_name ? profile->domain_name : "N/A"); if (strcasecmp(argv[1], profile->name)) { - stream->write_function(stream, "Alias Of \t\t%s\n", switch_str_nil(profile->name)); + stream->write_function(stream, "Alias Of \t%s\n", switch_str_nil(profile->name)); } - stream->write_function(stream, "DBName \t\t%s\n", switch_str_nil(profile->dbname)); - stream->write_function(stream, "Pres Hosts \t\t%s\n", switch_str_nil(profile->presence_hosts)); - stream->write_function(stream, "Dialplan \t\t%s\n", switch_str_nil(profile->dialplan)); - stream->write_function(stream, "Context \t\t%s\n", switch_str_nil(profile->context)); - stream->write_function(stream, "Challenge Realm\t\t%s\n", + stream->write_function(stream, "DBName \t%s\n", switch_str_nil(profile->dbname)); + stream->write_function(stream, "Pres Hosts \t%s\n", switch_str_nil(profile->presence_hosts)); + stream->write_function(stream, "Dialplan \t%s\n", switch_str_nil(profile->dialplan)); + stream->write_function(stream, "Context \t%s\n", switch_str_nil(profile->context)); + stream->write_function(stream, "Challenge Realm \t%s\n", switch_strlen_zero(profile->challenge_realm) ? "auto_to" : profile->challenge_realm); - stream->write_function(stream, "RTP-IP \t\t%s\n", switch_str_nil(profile->rtpip)); + stream->write_function(stream, "RTP-IP \t%s\n", switch_str_nil(profile->rtpip)); if (profile->extrtpip) { - stream->write_function(stream, "Ext-RTP-IP \t\t%s\n", profile->extrtpip); + stream->write_function(stream, "Ext-RTP-IP \t%s\n", profile->extrtpip); } - stream->write_function(stream, "SIP-IP \t\t%s\n", switch_str_nil(profile->sipip)); + stream->write_function(stream, "SIP-IP \t%s\n", switch_str_nil(profile->sipip)); if (profile->extsipip) { - stream->write_function(stream, "Ext-SIP-IP \t\t%s\n", profile->extsipip); + stream->write_function(stream, "Ext-SIP-IP \t%s\n", profile->extsipip); } - stream->write_function(stream, "URL \t\t%s\n", switch_str_nil(profile->url)); - stream->write_function(stream, "BIND-URL \t\t%s\n", switch_str_nil(profile->bindurl)); + stream->write_function(stream, "URL \t%s\n", switch_str_nil(profile->url)); + stream->write_function(stream, "BIND-URL \t%s\n", switch_str_nil(profile->bindurl)); if (sofia_test_pflag(profile, PFLAG_TLS)) { - stream->write_function(stream, "TLS-URL \t\t%s\n", switch_str_nil(profile->tls_url)); - stream->write_function(stream, "TLS-BIND-URL \t%s\n", switch_str_nil(profile->tls_bindurl)); + stream->write_function(stream, "TLS-URL \t%s\n", switch_str_nil(profile->tls_url)); + stream->write_function(stream, "TLS-BIND-URL \t%s\n", switch_str_nil(profile->tls_bindurl)); } - stream->write_function(stream, "HOLD-MUSIC \t\t%s\n", switch_strlen_zero(profile->hold_music) ? "N/A" : profile->hold_music); - stream->write_function(stream, "CODECS \t\t%s\n", switch_str_nil(profile->codec_string)); - stream->write_function(stream, "TEL-EVENT \t\t%d\n", profile->te); + stream->write_function(stream, "HOLD-MUSIC \t%s\n", switch_strlen_zero(profile->hold_music) ? "N/A" : profile->hold_music); + stream->write_function(stream, "CODECS \t%s\n", switch_str_nil(profile->codec_string)); + stream->write_function(stream, "TEL-EVENT \t%d\n", profile->te); if (profile->dtmf_type == DTMF_2833) { - stream->write_function(stream, "DTMF-MODE \t\trfc2833\n"); + stream->write_function(stream, "DTMF-MODE \trfc2833\n"); } else if (profile->dtmf_type == DTMF_INFO) { - stream->write_function(stream, "DTMF-MODE \t\tinfo\n"); + stream->write_function(stream, "DTMF-MODE \tinfo\n"); } else { - stream->write_function(stream, "DTMF-MODE \t\tnone\n"); + stream->write_function(stream, "DTMF-MODE \tnone\n"); } - stream->write_function(stream, "CNG \t\t%d\n", profile->cng_pt); - stream->write_function(stream, "SESSION-TO \t\t%d\n", profile->session_timeout); - stream->write_function(stream, "MAX-DIALOG \t\t%d\n", profile->max_proceeding); - stream->write_function(stream, "NOMEDIA \t\t%s\n", switch_test_flag(profile, TFLAG_INB_NOMEDIA) ? "true" : "false"); - stream->write_function(stream, "LATE-NEG \t\t%s\n", switch_test_flag(profile, TFLAG_LATE_NEGOTIATION) ? "true" : "false"); - stream->write_function(stream, "PROXY-MEDIA \t\t%s\n", switch_test_flag(profile, TFLAG_PROXY_MEDIA) ? "true" : "false"); - stream->write_function(stream, "AGGRESSIVENAT \t\t%s\n", sofia_test_pflag(profile, PFLAG_AGGRESSIVE_NAT_DETECTION) ? "true" : "false"); - stream->write_function(stream, "STUN_ENABLED \t\t%s\n", sofia_test_pflag(profile, PFLAG_STUN_ENABLED) ? "true" : "false"); - stream->write_function(stream, "STUN_AUTO_DISABLE \t%s\n", sofia_test_pflag(profile, PFLAG_STUN_AUTO_DISABLE) ? "true" : "false"); + stream->write_function(stream, "CNG \t%d\n", profile->cng_pt); + stream->write_function(stream, "SESSION-TO \t%d\n", profile->session_timeout); + stream->write_function(stream, "MAX-DIALOG \t%d\n", profile->max_proceeding); + stream->write_function(stream, "NOMEDIA \t%s\n", switch_test_flag(profile, TFLAG_INB_NOMEDIA) ? "true" : "false"); + stream->write_function(stream, "LATE-NEG \t%s\n", switch_test_flag(profile, TFLAG_LATE_NEGOTIATION) ? "true" : "false"); + stream->write_function(stream, "PROXY-MEDIA \t%s\n", switch_test_flag(profile, TFLAG_PROXY_MEDIA) ? "true" : "false"); + stream->write_function(stream, "AGGRESSIVENAT \t%s\n", sofia_test_pflag(profile, PFLAG_AGGRESSIVE_NAT_DETECTION) ? "true" : "false"); + stream->write_function(stream, "STUN_ENABLED \t%s\n", sofia_test_pflag(profile, PFLAG_STUN_ENABLED) ? "true" : "false"); + stream->write_function(stream, "STUN_AUTO_DISABLE\t%s\n", sofia_test_pflag(profile, PFLAG_STUN_AUTO_DISABLE) ? "true" : "false"); } stream->write_function(stream, "\nRegistrations:\n%s\n", line); @@ -1695,6 +1698,7 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl stream->write_function(stream, "<Password>%s</Password>\n", switch_strlen_zero(gp->register_password) ? "no" : "yes"); stream->write_function(stream, "<From>%s</From>\n", switch_amp_encode(switch_str_nil(gp->register_from),xmlbuf,buflen)); stream->write_function(stream, "<Contact>%s</Contact>\n", switch_amp_encode(switch_str_nil(gp->register_contact),xmlbuf,buflen)); + stream->write_function(stream, "<Exten>%s</Exten>\n", switch_amp_encode(switch_str_nil(gp->extension),xmlbuf,buflen)); stream->write_function(stream, "<To>%s</To>\n", switch_str_nil(gp->register_to)); stream->write_function(stream, "<Proxy>%s</Proxy>\n", switch_str_nil(gp->register_proxy)); stream->write_function(stream, "<Context>%s</Context>\n", switch_str_nil(gp->register_context)); @@ -1704,6 +1708,8 @@ static switch_status_t cmd_xml_status(char **argv, int argc, switch_stream_handl stream->write_function(stream, "<PingFreq>%d</PingFreq>\n", gp->ping_freq); stream->write_function(stream, "<State>%s</State>\n", sofia_state_names[gp->state]); stream->write_function(stream, "<Status>%s%s</Status>\n", status_names[gp->status], gp->pinging ? " (ping)" : ""); + stream->write_function(stream, "<CallsIN>%d</CallsIN>\n", gp->ib_calls); + stream->write_function(stream, "<CallsOUT>%d</CallsOUT>\n", gp->ob_calls); stream->write_function(stream, "</Gateway>\n"); sofia_reg_release_gateway(gp); } else { @@ -2424,10 +2430,12 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session } else { tech_pvt->invite_contact = switch_core_session_strdup(nsession, gateway_ptr->register_contact); } + + gateway_ptr->ob_calls++; - if (gateway_ptr->vars) { + if (gateway_ptr->ob_vars) { switch_event_header_t *hp; - for(hp = gateway_ptr->vars->headers; hp; hp = hp->next) { + for(hp = gateway_ptr->ob_vars->headers; hp; hp = hp->next) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s setting variable [%s]=[%s]\n", switch_channel_get_name(nchannel), hp->name, hp->value); switch_channel_set_variable(nchannel, hp->name, hp->value); diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index 2a712cc2b7..d9b138eb6f 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -315,6 +315,7 @@ struct sofia_gateway { char *register_password; char *register_from; char *register_contact; + char *extension; char *register_to; char *register_proxy; char *register_sticky_proxy; @@ -334,7 +335,10 @@ struct sofia_gateway { reg_state_t state; switch_memory_pool_t *pool; int deleted; - switch_event_t *vars; + switch_event_t *ib_vars; + switch_event_t *ob_vars; + uint32_t ib_calls; + uint32_t ob_calls; char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1]; int failures; struct sofia_gateway *next; diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 6423bd883d..1c6faf3f29 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -953,7 +953,7 @@ static void parse_gateway_subscriptions(sofia_profile_t *profile, sofia_gateway_ static void parse_gateways(sofia_profile_t *profile, switch_xml_t gateways_tag) { - switch_xml_t gateway_tag, param, gw_subs_tag; + switch_xml_t gateway_tag, param = NULL, x_params, gw_subs_tag; sofia_gateway_t *gp; for (gateway_tag = switch_xml_child(gateways_tag, "gateway"); gateway_tag; gateway_tag = gateway_tag->next) { @@ -1001,8 +1001,55 @@ static void parse_gateways(sofia_profile_t *profile, switch_xml_t gateways_tag) gateway->next = NULL; gateway->ping = 0; gateway->ping_freq = 0; + + + if ((x_params = switch_xml_child(gateway_tag, "variables"))) { + param = switch_xml_child(x_params, "variable"); + } else { + param = switch_xml_child(gateway_tag, "variable"); + } + + + for (; param; param = param->next) { + const char *var = switch_xml_attr(param, "name"); + const char *val = switch_xml_attr(param, "value"); + const char *direction = switch_xml_attr(param, "direction"); + int in = 0, out = 0; + + if (var && val) { + if (direction) { + if (!strcasecmp(direction, "inbound")) { + in = 1; + } else if (!strcasecmp(direction, "outbound")) { + out = 1; + } + } else { + in = out = 1; + } - for (param = switch_xml_child(gateway_tag, "param"); param; param = param->next) { + if (in) { + if (!gateway->ib_vars) { + switch_event_create(&gateway->ib_vars, SWITCH_EVENT_GENERAL); + } + switch_event_add_header_string(gateway->ib_vars, SWITCH_STACK_BOTTOM, var, val); + } + + if (out) { + if (!gateway->ob_vars) { + switch_event_create(&gateway->ob_vars, SWITCH_EVENT_GENERAL); + } + switch_event_add_header_string(gateway->ob_vars, SWITCH_STACK_BOTTOM, var, val); + } + } + } + + if ((x_params = switch_xml_child(gateway_tag, "params"))) { + param = switch_xml_child(x_params, "param"); + } else { + param = switch_xml_child(gateway_tag, "param"); + } + + for (; param; param = param->next) { char *var = (char *) switch_xml_attr_soft(param, "name"); char *val = (char *) switch_xml_attr_soft(param, "value"); @@ -1144,12 +1191,13 @@ static void parse_gateways(sofia_profile_t *profile, switch_xml_t gateways_tag) gateway->register_from = switch_core_sprintf(gateway->pool, "<sip:%s@%s;transport=%s>", from_user, from_domain, register_transport); sipip = profile->extsipip ? profile->extsipip : profile->sipip; - format = strchr(sipip, ':') ? "<sip:%s@[%s]:%d%s>" : "<sip:%s@%s:%d%s>"; - gateway->register_contact = switch_core_sprintf(gateway->pool, format, extension, + format = strchr(sipip, ':') ? "<sip:gw+%s@[%s]:%d%s>" : "<sip:gw+%s@%s:%d%s>"; + gateway->extension = switch_core_strdup(gateway->pool, extension); + gateway->register_contact = switch_core_sprintf(gateway->pool, format, gateway->name, sipip, - sofia_glue_transport_has_tls(gateway->register_transport) ? profile->tls_sip_port : profile-> - sip_port, params); - + sofia_glue_transport_has_tls(gateway->register_transport) ? + profile->tls_sip_port : profile->sip_port, params); + if (!strncasecmp(proxy, "sip:", 4)) { gateway->register_proxy = switch_core_strdup(gateway->pool, proxy); gateway->register_to = switch_core_sprintf(gateway->pool, "sip:%s@%s", username, proxy + 4); @@ -4024,6 +4072,7 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_ check_decode(destination_number, session); } + if (sip->sip_to && sip->sip_to->a_url) { const char *host, *user; int port; @@ -4174,20 +4223,6 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_ switch_channel_set_variable(channel, SWITCH_MAX_FORWARDS_VARIABLE, max_forwards); } - if (sip->sip_request->rq_url) { - sofia_gateway_t *gateway; - char *from_key; - char *user = (char *) sip->sip_request->rq_url->url_user; - check_decode(user, session); - from_key = switch_core_session_sprintf(session, "sip:%s@%s", user, sip->sip_request->rq_url->url_host); - - if ((gateway = sofia_reg_find_gateway(from_key))) { - context = gateway->register_context; - switch_channel_set_variable(channel, "sip_gateway", gateway->name); - sofia_reg_release_gateway(gateway); - } - } - if (!context) { context = switch_channel_get_variable(channel, "user_context"); } @@ -4220,6 +4255,35 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_ free(tmp); } + + if (strstr(destination_number, "gw+")) { + const char *gw_name = destination_number + 3; + sofia_gateway_t *gateway; + if (gw_name && (gateway = sofia_reg_find_gateway(gw_name))) { + context = switch_core_session_strdup(session, gateway->register_context); + switch_channel_set_variable(channel, "sip_gateway", gateway->name); + + if (gateway->extension) { + destination_number = switch_core_session_strdup(session, gateway->extension); + } + + gateway->ib_calls++; + + if (gateway->ib_vars) { + switch_event_header_t *hp; + for(hp = gateway->ib_vars->headers; hp; hp = hp->next) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s setting variable [%s]=[%s]\n", + switch_channel_get_name(channel), hp->name, hp->value); + switch_channel_set_variable(channel, hp->name, hp->value); + } + } + + sofia_reg_release_gateway(gateway); + } + } + + + check_decode(displayname, session); tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session), from_user, diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c index 5cb9ba74a2..3c59dab062 100644 --- a/src/mod/endpoints/mod_sofia/sofia_reg.c +++ b/src/mod/endpoints/mod_sofia/sofia_reg.c @@ -194,8 +194,11 @@ void sofia_reg_check_gateway(sofia_profile_t *profile, time_t now) switch_core_hash_delete(mod_sofia_globals.gateway_hash, gateway_ptr->register_from); switch_core_hash_delete(mod_sofia_globals.gateway_hash, gateway_ptr->register_contact); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Deleted gateway %s\n", gateway_ptr->name); - if (gateway_ptr->vars) { - switch_event_destroy(&gateway_ptr->vars); + if (gateway_ptr->ob_vars) { + switch_event_destroy(&gateway_ptr->ob_vars); + } + if (gateway_ptr->ib_vars) { + switch_event_destroy(&gateway_ptr->ib_vars); } } else { last = gateway_ptr;