[Freeswitch-svn] [commit] r4669 - in freeswitch/trunk: conf src/mod/endpoints/mod_sofia
Freeswitch SVN
anthm at freeswitch.org
Mon Mar 19 17:09:53 EDT 2007
Author: anthm
Date: Mon Mar 19 17:09:53 2007
New Revision: 4669
Modified:
freeswitch/trunk/conf/sofia.conf.xml
freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c
Log:
retool the sofia outbound registration syntax and dialstring syntax for said registrations ***ATTENTION*** syntax has heavily changed and the former syntax removed completely
Modified: freeswitch/trunk/conf/sofia.conf.xml
==============================================================================
--- freeswitch/trunk/conf/sofia.conf.xml (original)
+++ freeswitch/trunk/conf/sofia.conf.xml Mon Mar 19 17:09:53 2007
@@ -1,18 +1,23 @@
<configuration name="sofia.conf" description="sofia Endpoint">
<profiles>
<profile name="$${domain}">
- <registrations>
- <!-- <registration name="asterlink">
- <param name="register-scheme" value="Digest"/>
- <param name="register-realm" value=""/>
- <param name="register-username" value="1001"/>
- <param name="register-password" value="nhy65tgb"/>
- <param name="register-from" value="sip:1001 at 208.64.200.40"/>
- <param name="register-to" value="sip:1001 at conference.freeswitch.org"/>
- <param name="register-proxy" value="sip:conference.freeswitch.org:5060"/>
- <param name="register-frequency" value="20"/>
- </registration> -->
- </registrations>
+ <!-- Outbound Registrations -->
+ <gateways>
+ <gateway name="asterlink.com">
+ <!--/// account username *required* ///-->
+ <param name="username" value="cluecon"/>
+ <!--/// auth realm: *optional* same as gateway name, if blank ///-->
+ <!--<param name="realm" value="asterlink.com"/>-->
+ <!--/// account password *required* ///-->
+ <param name="password" value="2007"/>
+ <!--/// extension for inbound calls: *optional* same as username, if blank ///-->
+ <!--<param name="extension" value="cluecon"/>-->
+ <!--/// proxy host: *optional* same as realm, if blank ///-->
+ <!--<param name="proxy" value="asterlink.com"/>-->
+ <!--/// expire in seconds: *optional* 3600, if blank ///-->
+ <param name="expire-seconds" value="60"/>
+ </gateway>
+ </gateways>
<settings>
<param name="debug" value="1"/>
<param name="rfc2833-pt" value="101"/>
Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c (original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c Mon Mar 19 17:09:53 2007
@@ -51,7 +51,7 @@
struct sofia_private {
char uuid[SWITCH_UUID_FORMATTED_LENGTH + 1];
- outbound_reg_t *oreg;
+ outbound_reg_t *gateway;
};
typedef struct sofia_private sofia_private_t;
@@ -68,6 +68,7 @@
#define SOFIA_CHAT_PROTO "sip"
#define SOFIA_SIP_HEADER_PREFIX "sip_h_"
#define SOFIA_SIP_HEADER_PREFIX_T "~sip_h_"
+#define SOFIA_DEFAULT_PORT "5060"
#include <sofia-sip/nua.h>
#include <sofia-sip/sip_status.h>
@@ -180,6 +181,7 @@
static struct {
switch_hash_t *profile_hash;
+ switch_hash_t *gateway_hash;
switch_mutex_t *hash_mutex;
uint32_t callid;
int32_t running;
@@ -210,6 +212,7 @@
char *register_username;
char *register_password;
char *register_from;
+ char *register_contact;
char *register_to;
char *register_proxy;
char *expires_str;
@@ -255,8 +258,8 @@
switch_payload_t cng_pt;
uint32_t codec_flags;
switch_mutex_t *ireg_mutex;
- switch_mutex_t *oreg_mutex;
- outbound_reg_t *registrations;
+ switch_mutex_t *gateway_mutex;
+ outbound_reg_t *gateways;
su_home_t *home;
switch_hash_t *profile_hash;
switch_hash_t *chat_hash;
@@ -441,6 +444,42 @@
} auth_res_t;
+static sofia_profile_t *find_profile(char *key)
+{
+ static sofia_profile_t *profile;
+
+ switch_mutex_lock(globals.hash_mutex);
+ profile = (sofia_profile_t *) switch_core_hash_find(globals.profile_hash, key);
+ switch_mutex_unlock(globals.hash_mutex);
+
+ return profile;
+}
+
+static void add_profile(char *key, sofia_profile_t *profile)
+{
+ switch_mutex_lock(globals.hash_mutex);
+ switch_core_hash_insert(globals.profile_hash, key, profile);
+ switch_mutex_unlock(globals.hash_mutex);
+}
+
+static outbound_reg_t *find_gateway(char *key)
+{
+ outbound_reg_t *gateway;
+
+ switch_mutex_lock(globals.hash_mutex);
+ gateway = (outbound_reg_t *) switch_core_hash_find(globals.gateway_hash, key);
+ switch_mutex_unlock(globals.hash_mutex);
+
+ return gateway;
+}
+
+static void add_gateway(char *key, outbound_reg_t *gateway)
+{
+ switch_mutex_lock(globals.hash_mutex);
+ switch_core_hash_insert(globals.gateway_hash, key, gateway);
+ switch_mutex_unlock(globals.hash_mutex);
+}
+
static char *get_url_from_contact(char *buf, uint8_t to_dup)
{
char *url = NULL, *e;
@@ -804,7 +843,6 @@
{
switch_channel_t *channel;
char *abs, *codec_string = NULL;
- char *csdyn = NULL;
char *ocodec = NULL;
if (switch_test_flag(tech_pvt, TFLAG_NOMEDIA)) {
@@ -834,31 +872,27 @@
if (!codec_string || (tech_pvt->profile->pflags & PFLAG_DISABLE_TRANSCODING)) {
codec_string = ocodec;
} else {
- if ((csdyn = switch_mprintf("%s,%s", ocodec, codec_string))) {
- codec_string = csdyn;
- } else {
- codec_string = ocodec;
- }
+ if (!(codec_string = switch_core_session_sprintf(tech_pvt->session, "%s,%s", ocodec, codec_string))) {
+ codec_string = ocodec;
+ }
}
}
}
if (codec_string) {
char *tmp_codec_string;
- if ((tmp_codec_string = strdup(codec_string))) {
+ if ((tmp_codec_string = switch_core_session_strdup(tech_pvt->session, codec_string))) {
tech_pvt->codec_order_last = switch_separate_string(tmp_codec_string, ',', tech_pvt->codec_order, SWITCH_MAX_CODECS);
tech_pvt->num_codecs = switch_loadable_module_get_codecs_sorted(tech_pvt->codecs,
SWITCH_MAX_CODECS,
tech_pvt->codec_order,
tech_pvt->codec_order_last);
- free(tmp_codec_string);
}
} else {
tech_pvt->num_codecs = switch_loadable_module_get_codecs(switch_core_session_get_pool(tech_pvt->session), tech_pvt->codecs,
sizeof(tech_pvt->codecs) / sizeof(tech_pvt->codecs[0]));
}
- switch_safe_free(csdyn);
}
@@ -1024,10 +1058,13 @@
char *extra_headers = NULL;
const void *vvar;
switch_status_t status = SWITCH_STATUS_FALSE;
+ char *rep;
channel = switch_core_session_get_channel(session);
assert(channel != NULL);
+ rep = switch_channel_get_variable(channel, SOFIA_REPLACES_HEADER);
+
tech_pvt = (private_object_t *) switch_core_session_get_private(session);
assert(tech_pvt != NULL);
@@ -1037,128 +1074,132 @@
cid_num = (char *) caller_profile->caller_id_number;
tech_set_codecs(tech_pvt);
- if ((tech_pvt->from_str = switch_mprintf("\"%s\" <sip:%s@%s>",
- cid_name,
- cid_num,
- tech_pvt->profile->extsipip ? tech_pvt->profile->extsipip : tech_pvt->profile->sipip
- ))) {
+ if (!tech_pvt->from_str) {
+ tech_pvt->from_str = switch_core_session_sprintf(tech_pvt->session, "\"%s\" <sip:%s@%s>",
+ cid_name,
+ cid_num,
+ tech_pvt->profile->extsipip ? tech_pvt->profile->extsipip : tech_pvt->profile->sipip);
+
+ }
- char *rep = switch_channel_get_variable(channel, SOFIA_REPLACES_HEADER);
+ if (!tech_pvt->from_str) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n");
+ return SWITCH_STATUS_FALSE;
+ }
- if ((alertbuf = switch_channel_get_variable(channel, "alert_info"))) {
- snprintf(alert_info, sizeof(alert_info) - 1, "Alert-Info: %s", alertbuf);
- }
- if ((forwardbuf = switch_channel_get_variable(channel, SWITCH_MAX_FORWARDS_VARIABLE))) {
- forwardval = atoi(forwardbuf) - 1;
- snprintf(max_forwards, sizeof(max_forwards) - 1, "%d", forwardval);
- }
- if (tech_choose_port(tech_pvt) != SWITCH_STATUS_SUCCESS) {
- return status;
- }
+
+ if ((alertbuf = switch_channel_get_variable(channel, "alert_info"))) {
+ snprintf(alert_info, sizeof(alert_info) - 1, "Alert-Info: %s", alertbuf);
+ }
+
+ if ((forwardbuf = switch_channel_get_variable(channel, SWITCH_MAX_FORWARDS_VARIABLE))) {
+ forwardval = atoi(forwardbuf) - 1;
+ snprintf(max_forwards, sizeof(max_forwards) - 1, "%d", forwardval);
+ }
+
+ if (tech_choose_port(tech_pvt) != SWITCH_STATUS_SUCCESS) {
+ return status;
+ }
- set_local_sdp(tech_pvt, NULL, 0, NULL, 0);
+ set_local_sdp(tech_pvt, NULL, 0, NULL, 0);
- switch_set_flag_locked(tech_pvt, TFLAG_READY);
+ switch_set_flag_locked(tech_pvt, TFLAG_READY);
- // forge a RPID for now KHR -- Should wrap this in an if statement so it can be turned on and off
- if (switch_test_flag(caller_profile, SWITCH_CPF_SCREEN)) {
- const char *priv = "off";
- const char *screen = "no";
- if (switch_test_flag(caller_profile, SWITCH_CPF_HIDE_NAME)) {
- priv = "name";
- if (switch_test_flag(caller_profile, SWITCH_CPF_HIDE_NUMBER)) {
- priv = "yes";
- }
- } else if (switch_test_flag(caller_profile, SWITCH_CPF_HIDE_NUMBER)) {
+ // forge a RPID for now KHR -- Should wrap this in an if statement so it can be turned on and off
+ if (switch_test_flag(caller_profile, SWITCH_CPF_SCREEN)) {
+ const char *priv = "off";
+ const char *screen = "no";
+ if (switch_test_flag(caller_profile, SWITCH_CPF_HIDE_NAME)) {
+ priv = "name";
+ if (switch_test_flag(caller_profile, SWITCH_CPF_HIDE_NUMBER)) {
priv = "yes";
}
- if (switch_test_flag(caller_profile, SWITCH_CPF_SCREEN)) {
- screen = "yes";
- }
-
- snprintf(rpid, sizeof(rpid) - 1, "Remote-Party-ID: %s;party=calling;screen=%s;privacy=%s", tech_pvt->from_str, screen, priv);
-
+ } else if (switch_test_flag(caller_profile, SWITCH_CPF_HIDE_NUMBER)) {
+ priv = "yes";
+ }
+ if (switch_test_flag(caller_profile, SWITCH_CPF_SCREEN)) {
+ screen = "yes";
}
- if (!tech_pvt->nh) {
- char *url = get_url_from_contact(tech_pvt->dest, 1);
- tech_pvt->nh = nua_handle(tech_pvt->profile->nua, NULL,
- NUTAG_URL(url),
- SIPTAG_TO_STR(tech_pvt->dest_to),
- SIPTAG_FROM_STR(tech_pvt->from_str),
- SIPTAG_CONTACT_STR(tech_pvt->profile->url),
- TAG_END());
- switch_safe_free(url);
+ snprintf(rpid, sizeof(rpid) - 1, "Remote-Party-ID: %s;party=calling;screen=%s;privacy=%s", tech_pvt->from_str, screen, priv);
+
+ }
- if (!(tech_pvt->sofia_private = malloc(sizeof(*tech_pvt->sofia_private)))) {
- abort();
- }
- memset(tech_pvt->sofia_private, 0, sizeof(*tech_pvt->sofia_private));
- switch_copy_string(tech_pvt->sofia_private->uuid, switch_core_session_get_uuid(session), sizeof(tech_pvt->sofia_private->uuid));
- nua_handle_bind(tech_pvt->nh, tech_pvt->sofia_private);
+ if (!tech_pvt->nh) {
+ char *url = get_url_from_contact(tech_pvt->dest, 1);
+ tech_pvt->nh = nua_handle(tech_pvt->profile->nua, NULL,
+ NUTAG_URL(url),
+ SIPTAG_TO_STR(tech_pvt->dest_to),
+ SIPTAG_FROM_STR(tech_pvt->from_str),
+ SIPTAG_CONTACT_STR(tech_pvt->profile->url),
+ TAG_END());
+ switch_safe_free(url);
+ if (!(tech_pvt->sofia_private = malloc(sizeof(*tech_pvt->sofia_private)))) {
+ abort();
}
+ memset(tech_pvt->sofia_private, 0, sizeof(*tech_pvt->sofia_private));
+ switch_copy_string(tech_pvt->sofia_private->uuid, switch_core_session_get_uuid(session), sizeof(tech_pvt->sofia_private->uuid));
+ nua_handle_bind(tech_pvt->nh, tech_pvt->sofia_private);
+ }
- if (tech_pvt->e_dest && (e_dest = strdup(tech_pvt->e_dest))) {
- char *user = e_dest, *host = NULL;
- char hash_key[256] = "";
- if ((host = strchr(user, '@'))) {
- *host++ = '\0';
- }
- snprintf(hash_key, sizeof(hash_key), "%s%s%s", user, host, cid_num);
+ if (tech_pvt->e_dest && (e_dest = strdup(tech_pvt->e_dest))) {
+ char *user = e_dest, *host = NULL;
+ char hash_key[256] = "";
- tech_pvt->chat_from = tech_pvt->from_str;
- tech_pvt->chat_to = tech_pvt->dest;
- tech_pvt->hash_key = switch_core_session_strdup(tech_pvt->session, hash_key);
- switch_core_hash_insert(tech_pvt->profile->chat_hash, tech_pvt->hash_key, tech_pvt);
- free(e_dest);
+ if ((host = strchr(user, '@'))) {
+ *host++ = '\0';
}
+ snprintf(hash_key, sizeof(hash_key), "%s%s%s", user, host, cid_num);
- holdstr = switch_test_flag(tech_pvt, TFLAG_SIP_HOLD) ? "*" : "";
+ tech_pvt->chat_from = tech_pvt->from_str;
+ tech_pvt->chat_to = tech_pvt->dest;
+ tech_pvt->hash_key = switch_core_session_strdup(tech_pvt->session, hash_key);
+ switch_core_hash_insert(tech_pvt->profile->chat_hash, tech_pvt->hash_key, tech_pvt);
+ free(e_dest);
+ }
+ holdstr = switch_test_flag(tech_pvt, TFLAG_SIP_HOLD) ? "*" : "";
- SWITCH_STANDARD_STREAM(stream);
- for (hi = switch_channel_variable_first(channel, switch_core_session_get_pool(tech_pvt->session)); hi; hi = switch_hash_next(hi)) {
- switch_hash_this(hi, &vvar, NULL, &vval);
- if (vvar && vval) {
- const char *name = vvar;
- char *value = (char *) vval;
- if (!strncasecmp(name, SOFIA_SIP_HEADER_PREFIX, strlen(SOFIA_SIP_HEADER_PREFIX))) {
- const char *hname = name + strlen(SOFIA_SIP_HEADER_PREFIX);
- stream.write_function(&stream, "%s: %s\r\n", hname, value);
- }
+ SWITCH_STANDARD_STREAM(stream);
+ for (hi = switch_channel_variable_first(channel, switch_core_session_get_pool(tech_pvt->session)); hi; hi = switch_hash_next(hi)) {
+ switch_hash_this(hi, &vvar, NULL, &vval);
+ if (vvar && vval) {
+ const char *name = vvar;
+ char *value = (char *) vval;
+
+ if (!strncasecmp(name, SOFIA_SIP_HEADER_PREFIX, strlen(SOFIA_SIP_HEADER_PREFIX))) {
+ const char *hname = name + strlen(SOFIA_SIP_HEADER_PREFIX);
+ stream.write_function(&stream, "%s: %s\r\n", hname, value);
}
}
+ }
- if (stream.data) {
- extra_headers = stream.data;
- }
+ if (stream.data) {
+ extra_headers = stream.data;
+ }
- nua_invite(tech_pvt->nh,
- TAG_IF(!switch_strlen_zero(rpid), SIPTAG_HEADER_STR(rpid)),
- TAG_IF(!switch_strlen_zero(alert_info), SIPTAG_HEADER_STR(alert_info)),
- TAG_IF(!switch_strlen_zero(extra_headers), SIPTAG_HEADER_STR(extra_headers)),
- TAG_IF(!switch_strlen_zero(max_forwards),SIPTAG_MAX_FORWARDS_STR(max_forwards)),
- //SIPTAG_CONTACT_STR(tech_pvt->profile->url),
- SOATAG_USER_SDP_STR(tech_pvt->local_sdp_str),
- SOATAG_RTP_SORT(SOA_RTP_SORT_REMOTE),
- SOATAG_RTP_SELECT(SOA_RTP_SELECT_ALL),
- TAG_IF(rep, SIPTAG_REPLACES_STR(rep)),
- SOATAG_HOLD(holdstr),
- TAG_END());
+ nua_invite(tech_pvt->nh,
+ TAG_IF(!switch_strlen_zero(rpid), SIPTAG_HEADER_STR(rpid)),
+ TAG_IF(!switch_strlen_zero(alert_info), SIPTAG_HEADER_STR(alert_info)),
+ TAG_IF(!switch_strlen_zero(extra_headers), SIPTAG_HEADER_STR(extra_headers)),
+ TAG_IF(!switch_strlen_zero(max_forwards),SIPTAG_MAX_FORWARDS_STR(max_forwards)),
+ //SIPTAG_CONTACT_STR(tech_pvt->profile->url),
+ SOATAG_USER_SDP_STR(tech_pvt->local_sdp_str),
+ SOATAG_RTP_SORT(SOA_RTP_SORT_REMOTE),
+ SOATAG_RTP_SELECT(SOA_RTP_SELECT_ALL),
+ TAG_IF(rep, SIPTAG_REPLACES_STR(rep)),
+ SOATAG_HOLD(holdstr),
+ TAG_END());
- switch_safe_free(stream.data);
- status = SWITCH_STATUS_SUCCESS;
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n");
- }
+ switch_safe_free(stream.data);
- return status;
+ return SWITCH_STATUS_SUCCESS;
}
@@ -1181,11 +1222,11 @@
- if ((tech_pvt->from_str = switch_mprintf("\"%s\" <sip:%s@%s>",
- (char *) caller_profile->caller_id_name,
- (char *) caller_profile->caller_id_number,
- tech_pvt->profile->extsipip ? tech_pvt->profile->extsipip : tech_pvt->profile->sipip
- ))) {
+ if ((tech_pvt->from_str = switch_core_session_sprintf(session, "\"%s\" <sip:%s@%s>",
+ (char *) caller_profile->caller_id_name,
+ (char *) caller_profile->caller_id_number,
+ tech_pvt->profile->extsipip ? tech_pvt->profile->extsipip : tech_pvt->profile->sipip
+ ))) {
char *rep = switch_channel_get_variable(channel, SOFIA_REPLACES_HEADER);
@@ -1427,10 +1468,6 @@
}
}
- if (tech_pvt->from_str) {
- switch_safe_free(tech_pvt->from_str);
- }
-
switch_clear_flag_locked(tech_pvt, TFLAG_IO);
if (tech_pvt->home) {
@@ -2334,57 +2371,95 @@
data = switch_core_session_strdup(nsession, outbound_profile->destination_number);
profile_name = data;
- if (!(dest = strchr(profile_name, '/'))) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid URL\n");
- terminate_session(&nsession, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER, __LINE__);
- cause = SWITCH_CAUSE_INVALID_NUMBER_FORMAT;
- goto done;
- }
+ if (!strncasecmp(profile_name, "gateway", 7)) {
+ char *gw;
+ outbound_reg_t *gateway_ptr;
- *dest++ = '\0';
-
- if (!(profile = (sofia_profile_t *) switch_core_hash_find(globals.profile_hash, profile_name))) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Profile\n");
- terminate_session(&nsession, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER, __LINE__);
- cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
- goto done;
- }
+
+ if (!(gw = strchr(profile_name, '/'))) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid URL\n");
+ terminate_session(&nsession, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER, __LINE__);
+ cause = SWITCH_CAUSE_INVALID_NUMBER_FORMAT;
+ goto done;
+ }
- if ((dest_to = strchr(dest, '^'))) {
- *dest_to++ = '\0';
- tech_pvt->dest_to = switch_core_session_alloc(nsession, strlen(dest_to) + 5);
- snprintf(tech_pvt->dest_to, strlen(dest_to) + 5, "sip:%s", dest_to);
- }
+ *gw++ = '\0';
+
+ if (!(dest = strchr(gw, '/'))) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid URL\n");
+ terminate_session(&nsession, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER, __LINE__);
+ cause = SWITCH_CAUSE_INVALID_NUMBER_FORMAT;
+ goto done;
+ }
- if ((host = strchr(dest, '%'))) {
- char buf[128];
- *host = '@';
- tech_pvt->e_dest = switch_core_session_strdup(nsession, dest);
- *host++ = '\0';
- if (find_reg_url(profile, dest, host, buf, sizeof(buf))) {
- tech_pvt->dest = switch_core_session_strdup(nsession, buf);
-
+ *dest++ = '\0';
+
+ if (!(gateway_ptr = find_gateway(gw))) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Gateway\n");
+ terminate_session(&nsession, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER, __LINE__);
+ cause = SWITCH_CAUSE_INVALID_NUMBER_FORMAT;
+ goto done;
+ }
+
+ profile = gateway_ptr->profile;
+ tech_pvt->from_str = switch_core_session_strdup(nsession, gateway_ptr->register_from);
+ if (!strchr(dest, '@')) {
+ tech_pvt->dest = switch_core_session_sprintf(nsession, "sip:%s@%s", dest, gateway_ptr->register_proxy + 4);
} else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cannot locate registered user %s@%s\n", dest, host);
- cause = SWITCH_CAUSE_NO_ROUTE_DESTINATION;
- terminate_session(&nsession, cause, __LINE__);
+ tech_pvt->dest = switch_core_session_sprintf(nsession, "sip:%s", dest);
+ }
+ } else {
+ if (!(dest = strchr(profile_name, '/'))) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid URL\n");
+ terminate_session(&nsession, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER, __LINE__);
+ cause = SWITCH_CAUSE_INVALID_NUMBER_FORMAT;
goto done;
}
- } else if (!strchr(dest, '@')) {
- char buf[128];
- tech_pvt->e_dest = switch_core_session_strdup(nsession, dest);
- if (find_reg_url(profile, dest, profile_name, buf, sizeof(buf))) {
- tech_pvt->dest = switch_core_session_strdup(nsession, buf);
+ *dest++ = '\0';
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cannot locate registered user %s@%s\n", dest, profile_name);
- cause = SWITCH_CAUSE_NO_ROUTE_DESTINATION;
- terminate_session(&nsession, cause, __LINE__);
- goto done;
- }
- } else {
- tech_pvt->dest = switch_core_session_alloc(nsession, strlen(dest) + 5);
- snprintf(tech_pvt->dest, strlen(dest) + 5, "sip:%s", dest);
+ if (!(profile = find_profile(profile_name))) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Profile\n");
+ terminate_session(&nsession, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER, __LINE__);
+ cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
+ goto done;
+ }
+
+ if ((dest_to = strchr(dest, '^'))) {
+ *dest_to++ = '\0';
+ tech_pvt->dest_to = switch_core_session_alloc(nsession, strlen(dest_to) + 5);
+ snprintf(tech_pvt->dest_to, strlen(dest_to) + 5, "sip:%s", dest_to);
+ }
+
+ if ((host = strchr(dest, '%'))) {
+ char buf[128];
+ *host = '@';
+ tech_pvt->e_dest = switch_core_session_strdup(nsession, dest);
+ *host++ = '\0';
+ if (find_reg_url(profile, dest, host, buf, sizeof(buf))) {
+ tech_pvt->dest = switch_core_session_strdup(nsession, buf);
+
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cannot locate registered user %s@%s\n", dest, host);
+ cause = SWITCH_CAUSE_NO_ROUTE_DESTINATION;
+ terminate_session(&nsession, cause, __LINE__);
+ goto done;
+ }
+ } else if (!strchr(dest, '@')) {
+ char buf[128];
+ tech_pvt->e_dest = switch_core_session_strdup(nsession, dest);
+ if (find_reg_url(profile, dest, profile_name, buf, sizeof(buf))) {
+ tech_pvt->dest = switch_core_session_strdup(nsession, buf);
+
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cannot locate registered user %s@%s\n", dest, profile_name);
+ cause = SWITCH_CAUSE_NO_ROUTE_DESTINATION;
+ terminate_session(&nsession, cause, __LINE__);
+ goto done;
+ }
+ } else {
+ tech_pvt->dest = switch_core_session_alloc(nsession, strlen(dest) + 5);
+ snprintf(tech_pvt->dest, strlen(dest) + 5, "sip:%s", dest);
+ }
}
if (!tech_pvt->dest_to) {
@@ -3058,7 +3133,7 @@
switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "RECEIVED_3PCC");
if (tech_choose_port(tech_pvt) != SWITCH_STATUS_SUCCESS) {
- return;
+ goto done;
}
set_local_sdp(tech_pvt, NULL, 0, NULL, 0);
@@ -3353,7 +3428,7 @@
}
if (!port) {
- port = "5060";
+ port = SOFIA_DEFAULT_PORT;
}
if (contact->m_url->url_params) {
@@ -3785,7 +3860,7 @@
}
if (!port) {
- port = "5060";
+ port = SOFIA_DEFAULT_PORT;
}
if (contact->m_url->url_params) {
@@ -4399,7 +4474,7 @@
}
if (!port) {
- port = "5060";
+ port = SOFIA_DEFAULT_PORT;
}
switch_channel_set_variable(channel, port_var, port);
@@ -4708,12 +4783,28 @@
sip_t const *sip,
tagi_t tags[])
{
- if (sofia_private && sofia_private->oreg) {
- if (status == 200) {
- sofia_private->oreg->state = REG_STATE_REGISTER;
- } else {
- sofia_private->oreg->state = REG_STATE_FAILED;
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "received %d on register!\n", status);
+ if (sofia_private && sofia_private->gateway) {
+ switch (status) {
+ case 200:
+ if (sip && sip->sip_contact && sip->sip_contact->m_expires) {
+ char *new_expires = (char *) sip->sip_contact->m_expires;
+ int expi = atoi(new_expires);
+
+ if (expi != sofia_private->gateway->freq) {
+ sofia_private->gateway->freq = expi;
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE,
+ "Changing expire time to %d by request of proxy %s\n", expi, sofia_private->gateway->register_proxy);
+ }
+
+ }
+ sofia_private->gateway->state = REG_STATE_REGISTER;
+ break;
+ case 100:
+ break;
+ default:
+ sofia_private->gateway->state = REG_STATE_FAILED;
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Registration Failed with status %d\n", status);
+ break;
}
}
}
@@ -4727,7 +4818,7 @@
sip_t const *sip,
tagi_t tags[])
{
- outbound_reg_t *oreg = NULL;
+ outbound_reg_t *gateway = NULL;
sip_www_authenticate_t const *authenticate = NULL;
char const *realm = NULL;
char *p = NULL, *duprealm = NULL, *qrealm = NULL;
@@ -4770,7 +4861,7 @@
}
if (profile) {
- outbound_reg_t *oregp;
+ outbound_reg_t *gateway_ptr;
if ((duprealm = strdup(realm))) {
qrealm = duprealm;
@@ -4782,14 +4873,29 @@
if ((p = strchr(qrealm, '"'))) {
*p = '\0';
}
+
+ if (sip->sip_from) {
+ char *from_key = switch_mprintf("sip:%s@%s",
+ (char *) sip->sip_from->a_url->url_user,
+ (char *) sip->sip_from->a_url->url_host);
+
+ if (!(gateway = find_gateway(from_key))) {
+ gateway = find_gateway(qrealm);
+ }
+
+ switch_safe_free(from_key);
+ }
- for (oregp = profile->registrations; oregp; oregp = oregp->next) {
- if (scheme && qrealm && !strcasecmp(oregp->register_scheme, scheme) && !strcasecmp(oregp->register_realm, qrealm)) {
- oreg = oregp;
- break;
+ if (!gateway) {
+ for (gateway_ptr = profile->gateways; gateway_ptr; gateway_ptr = gateway_ptr->next) {
+ if (scheme && qrealm && !strcasecmp(gateway_ptr->register_scheme, scheme) && !strcasecmp(gateway_ptr->register_realm, qrealm)) {
+ gateway = gateway_ptr;
+ break;
+ }
}
}
- if (!oreg) {
+
+ if (!gateway) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "No Match for Scheme [%s] Realm [%s]\n", scheme, qrealm);
return;
}
@@ -4801,8 +4907,8 @@
}
snprintf(authentication, sizeof(authentication), "%s:%s:%s:%s", scheme, realm,
- oreg->register_username,
- oreg->register_password);
+ gateway->register_username,
+ gateway->register_password);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Authenticating '%s' with '%s'.\n",
profile->username, authentication);
@@ -4815,7 +4921,7 @@
SIPTAG_WWW_AUTHENTICATE_REF(authenticate),
TAG_END());
- nua_authenticate(nh, SIPTAG_EXPIRES_STR(oreg->expires_str), NUTAG_AUTH(authentication), TAG_END());
+ nua_authenticate(nh, SIPTAG_EXPIRES_STR(gateway->expires_str), NUTAG_AUTH(authentication), TAG_END());
}
@@ -4974,73 +5080,73 @@
static void unreg(sofia_profile_t *profile)
{
- outbound_reg_t *oregp;
- for (oregp = profile->registrations; oregp; oregp = oregp->next) {
- if (oregp->sofia_private) {
- free(oregp->sofia_private);
- nua_handle_bind(oregp->nh, NULL);
- oregp->sofia_private = NULL;
+ outbound_reg_t *gateway_ptr;
+ for (gateway_ptr = profile->gateways; gateway_ptr; gateway_ptr = gateway_ptr->next) {
+ if (gateway_ptr->sofia_private) {
+ free(gateway_ptr->sofia_private);
+ nua_handle_bind(gateway_ptr->nh, NULL);
+ gateway_ptr->sofia_private = NULL;
}
- nua_handle_destroy(oregp->nh);
+ nua_handle_destroy(gateway_ptr->nh);
}
}
-static void check_oreg(sofia_profile_t *profile, time_t now)
+static void check_gateway(sofia_profile_t *profile, time_t now)
{
- outbound_reg_t *oregp;
- for (oregp = profile->registrations; oregp; oregp = oregp->next) {
+ outbound_reg_t *gateway_ptr;
+ for (gateway_ptr = profile->gateways; gateway_ptr; gateway_ptr = gateway_ptr->next) {
int ss_state = nua_callstate_authenticating;
- reg_state_t ostate = oregp->state;
+ reg_state_t ostate = gateway_ptr->state;
switch(ostate) {
case REG_STATE_REGISTER:
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "registered %s\n", oregp->name);
- oregp->expires = now + oregp->freq;
- oregp->state = REG_STATE_REGED;
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "registered %s\n", gateway_ptr->name);
+ gateway_ptr->expires = now + gateway_ptr->freq;
+ gateway_ptr->state = REG_STATE_REGED;
break;
case REG_STATE_UNREGED:
- if ((oregp->nh = nua_handle(oregp->profile->nua, NULL,
- NUTAG_URL(oregp->register_proxy),
- SIPTAG_TO_STR(oregp->register_to),
+ if ((gateway_ptr->nh = nua_handle(gateway_ptr->profile->nua, NULL,
+ NUTAG_URL(gateway_ptr->register_proxy),
+ SIPTAG_TO_STR(gateway_ptr->register_to),
NUTAG_CALLSTATE_REF(ss_state),
- SIPTAG_FROM_STR(oregp->register_from), TAG_END()))) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "registering %s\n", oregp->name);
+ SIPTAG_FROM_STR(gateway_ptr->register_from), TAG_END()))) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "registering %s\n", gateway_ptr->name);
- if (!(oregp->sofia_private = malloc(sizeof(*oregp->sofia_private)))) {
+ if (!(gateway_ptr->sofia_private = malloc(sizeof(*gateway_ptr->sofia_private)))) {
abort();
}
- memset(oregp->sofia_private, 0, sizeof(*oregp->sofia_private));
+ memset(gateway_ptr->sofia_private, 0, sizeof(*gateway_ptr->sofia_private));
- oregp->sofia_private->oreg = oregp;
- nua_handle_bind(oregp->nh, oregp->sofia_private);
+ gateway_ptr->sofia_private->gateway = gateway_ptr;
+ nua_handle_bind(gateway_ptr->nh, gateway_ptr->sofia_private);
- nua_register(oregp->nh,
- SIPTAG_FROM_STR(oregp->register_from),
- SIPTAG_CONTACT_STR(oregp->register_from),
- SIPTAG_EXPIRES_STR(oregp->expires_str),
- NUTAG_REGISTRAR(oregp->register_proxy),
- NUTAG_OUTBOUND("no-options-keepalive"),
- NUTAG_OUTBOUND("no-validate"),
- NUTAG_KEEPALIVE(0),
- TAG_NULL());
- oregp->retry = now + 10;
- oregp->state = REG_STATE_TRYING;
+ nua_register(gateway_ptr->nh,
+ SIPTAG_FROM_STR(gateway_ptr->register_from),
+ SIPTAG_CONTACT_STR(gateway_ptr->register_contact),
+ SIPTAG_EXPIRES_STR(gateway_ptr->expires_str),
+ NUTAG_REGISTRAR(gateway_ptr->register_proxy),
+ NUTAG_OUTBOUND("no-options-keepalive"),
+ NUTAG_OUTBOUND("no-validate"),
+ NUTAG_KEEPALIVE(0),
+ TAG_NULL());
+ gateway_ptr->retry = now + 10;
+ gateway_ptr->state = REG_STATE_TRYING;
} else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error registering %s\n", oregp->name);
- oregp->state = REG_STATE_FAILED;
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error registering %s\n", gateway_ptr->name);
+ gateway_ptr->state = REG_STATE_FAILED;
}
break;
case REG_STATE_TRYING:
- if (oregp->retry && now >= oregp->retry) {
- oregp->state = REG_STATE_UNREGED;
- oregp->retry = 0;
+ if (gateway_ptr->retry && now >= gateway_ptr->retry) {
+ gateway_ptr->state = REG_STATE_UNREGED;
+ gateway_ptr->retry = 0;
}
break;
default:
- if (oregp->expires && now >= oregp->expires) {
- oregp->state = REG_STATE_UNREGED;
- oregp->expires = 0;
+ if (gateway_ptr->expires && now >= gateway_ptr->expires) {
+ gateway_ptr->state = REG_STATE_UNREGED;
+ gateway_ptr->expires = 0;
}
break;
}
@@ -5049,14 +5155,14 @@
}
#define IREG_SECONDS 30
-#define OREG_SECONDS 1
+#define GATEWAY_SECONDS 1
static void *SWITCH_THREAD_FUNC profile_thread_run(switch_thread_t *thread, void *obj)
{
sofia_profile_t *profile = (sofia_profile_t *) obj;
switch_memory_pool_t *pool;
sip_alias_node_t *node;
uint32_t ireg_loops = 0;
- uint32_t oreg_loops = 0;
+ uint32_t gateway_loops = 0;
switch_core_db_t *db;
switch_event_t *s_event;
@@ -5122,10 +5228,10 @@
switch_mutex_init(&profile->ireg_mutex, SWITCH_MUTEX_NESTED, profile->pool);
- switch_mutex_init(&profile->oreg_mutex, SWITCH_MUTEX_NESTED, profile->pool);
+ switch_mutex_init(&profile->gateway_mutex, SWITCH_MUTEX_NESTED, profile->pool);
ireg_loops = IREG_SECONDS;
- oreg_loops = OREG_SECONDS;
+ gateway_loops = GATEWAY_SECONDS;
if (switch_event_create(&s_event, SWITCH_EVENT_PUBLISH) == SWITCH_STATUS_SUCCESS) {
switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "service", "_sip._udp");
@@ -5145,27 +5251,21 @@
switch_event_fire(&s_event);
}
-
- switch_mutex_lock(globals.hash_mutex);
- switch_core_hash_insert(globals.profile_hash, profile->name, profile);
- switch_mutex_unlock(globals.hash_mutex);
+ add_profile(profile->name, profile);
if (profile->pflags & PFLAG_PRESENCE) {
establish_presence(profile);
}
-
-
-
while(globals.running == 1) {
if (++ireg_loops >= IREG_SECONDS) {
check_expire(db, profile, time(NULL));
ireg_loops = 0;
}
- if (++oreg_loops >= OREG_SECONDS) {
- check_oreg(profile, time(NULL));
- oreg_loops = 0;
+ if (++gateway_loops >= GATEWAY_SECONDS) {
+ check_gateway(profile, time(NULL));
+ gateway_loops = 0;
}
su_root_step(profile->s_root, 1000);
@@ -5208,7 +5308,7 @@
static switch_status_t config_sofia(int reload)
{
char *cf = "sofia.conf";
- switch_xml_t cfg, xml = NULL, xprofile, param, settings, profiles, registration, registrations;
+ switch_xml_t cfg, xml = NULL, xprofile, param, settings, profiles, gateway_tag, gateways_tag;
switch_status_t status = SWITCH_STATUS_SUCCESS;
sofia_profile_t *profile = NULL;
char url[512] = "";
@@ -5419,7 +5519,7 @@
}
if (!profile->sip_port) {
- profile->sip_port = 5060;
+ profile->sip_port = atoi(SOFIA_DEFAULT_PORT);
}
if (!profile->dialplan) {
@@ -5438,79 +5538,118 @@
}
}
if (profile) {
- if ((registrations = switch_xml_child(xprofile, "registrations"))) {
- for (registration = switch_xml_child(registrations, "registration"); registration; registration = registration->next) {
- char *name = (char *) switch_xml_attr_soft(registration, "name");
- outbound_reg_t *oreg;
+ if ((gateways_tag = switch_xml_child(xprofile, "registrations"))) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT,
+ "The <registrations> syntax has been discontinued, please see the new syntax in the default configuration examples\n");
+ }
+ if ((gateways_tag = switch_xml_child(xprofile, "gateways"))) {
+ for (gateway_tag = switch_xml_child(gateways_tag, "gateway"); gateway_tag; gateway_tag = gateway_tag->next) {
+ char *name = (char *) switch_xml_attr_soft(gateway_tag, "name");
+ outbound_reg_t *gateway;
+
if (switch_strlen_zero(name)) {
name = "anonymous";
}
-
- if ((oreg = switch_core_alloc(profile->pool, sizeof(*oreg)))) {
- oreg->pool = profile->pool;
- oreg->profile = profile;
- oreg->name = switch_core_strdup(oreg->pool, name);
- oreg->freq = 0;
-
- for (param = switch_xml_child(registration, "param"); param; param = param->next) {
+
+ if ((gateway = switch_core_alloc(profile->pool, sizeof(*gateway)))) {
+ gateway->pool = profile->pool;
+ gateway->profile = profile;
+ gateway->name = switch_core_strdup(gateway->pool, name);
+ gateway->freq = 0;
+ char *scheme = "Digest",
+ *realm = NULL,
+ *username = NULL,
+ *password = NULL,
+ *extension = NULL,
+ *proxy = NULL,
+ *expire_seconds = "3600";
+
+ for (param = switch_xml_child(gateway_tag, "param"); param; param = param->next) {
char *var = (char *) switch_xml_attr_soft(param, "name");
char *val = (char *) switch_xml_attr_soft(param, "value");
- if (!strcmp(var, "register-scheme")) {
- oreg->register_scheme = switch_core_strdup(oreg->pool, val);
- } else if (!strcmp(var, "register-realm")) {
- oreg->register_realm = switch_core_strdup(oreg->pool, val);
- } else if (!strcmp(var, "register-username")) {
- oreg->register_username = switch_core_strdup(oreg->pool, val);
- } else if (!strcmp(var, "register-password")) {
- oreg->register_password = switch_core_strdup(oreg->pool, val);
- } else if (!strcmp(var, "register-from")) {
- oreg->register_from = switch_core_strdup(oreg->pool, val);
- } else if (!strcmp(var, "register-to")) {
- oreg->register_to = switch_core_strdup(oreg->pool, val);
- } else if (!strcmp(var, "register-proxy")) {
- oreg->register_proxy = switch_core_strdup(oreg->pool, val);
- } else if (!strcmp(var, "register-frequency")) {
- oreg->expires_str = switch_core_strdup(oreg->pool, val);
+ if (!strcmp(var, "scheme")) {
+ scheme = val;
+ } else if (!strcmp(var, "realm")) {
+ realm = val;
+ } else if (!strcmp(var, "username")) {
+ username = val;
+ } else if (!strcmp(var, "password")) {
+ password = val;
+ } else if (!strcmp(var, "extension")) {
+ extension = val;
+ } else if (!strcmp(var, "proxy")) {
+ proxy = val;
+ } else if (!strcmp(var, "expire-seconds")) {
+ expire_seconds = val;
}
}
- if (switch_strlen_zero(oreg->register_scheme)) {
- oreg->register_scheme = switch_core_strdup(oreg->pool, "Digest");
- }
- if (switch_strlen_zero(oreg->register_realm)) {
- oreg->register_realm = switch_core_strdup(oreg->pool, "freeswitch.org");
+
+ if (switch_strlen_zero(realm)) {
+ realm = name;
}
- if (switch_strlen_zero(oreg->register_username)) {
- oreg->register_username = switch_core_strdup(oreg->pool, "freeswitch");
+
+ if (switch_strlen_zero(username)) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERROR: username param is REQUIRED!\n");
+ switch_xml_free(xml);
+ goto skip;
}
- if (switch_strlen_zero(oreg->register_password)) {
- oreg->register_password = switch_core_strdup(oreg->pool, "works");
- }
- if (switch_strlen_zero(oreg->register_from)) {
- oreg->register_from = switch_core_strdup(oreg->pool, "FreeSWITCH <sip:freeswitch at freeswitch.org>");
+
+ if (switch_strlen_zero(password)) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERROR: password param is REQUIRED!\n");
+ switch_xml_free(xml);
+ goto skip;
}
- if (switch_strlen_zero(oreg->register_to)) {
- oreg->register_to = switch_core_strdup(oreg->pool, "sip:freeswitch at freeswitch.org");
+
+ if (switch_strlen_zero(extension)) {
+ extension = username;
}
- if (switch_strlen_zero(oreg->register_proxy)) {
- oreg->register_proxy = switch_core_strdup(oreg->pool, "sip:freeswitch at freeswitch.org");
+
+ if (switch_strlen_zero(proxy)) {
+ proxy = realm;
}
- if (switch_strlen_zero(oreg->expires_str)) {
- oreg->expires_str = switch_core_strdup(oreg->pool, "300");
+ gateway->register_scheme = switch_core_strdup(gateway->pool, scheme);
+ gateway->register_realm = switch_core_strdup(gateway->pool, realm);
+ gateway->register_username = switch_core_strdup(gateway->pool, username);
+ gateway->register_password = switch_core_strdup(gateway->pool, password);
+ gateway->register_from = switch_core_sprintf(gateway->pool, "sip:%s@%s", extension, realm);
+ gateway->register_contact = switch_core_sprintf(gateway->pool,
+ "sip:%s@%s:%d", extension, profile->sipip, profile->sip_port);
+
+ 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);
+ } else {
+ gateway->register_proxy = switch_core_sprintf(gateway->pool, "sip:%s", proxy);
+ gateway->register_to = switch_core_sprintf(gateway->pool, "sip:%s@%s", username, proxy);
}
-
- if ((oreg->freq = atoi(oreg->expires_str)) < 5) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid Freq: %d. Setting Register-Frequency to 5\n", oreg->freq);
- oreg->freq = 5;
+
+ gateway->expires_str = switch_core_strdup(gateway->pool, expire_seconds);
+
+ if ((gateway->freq = atoi(gateway->expires_str)) < 5) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
+ "Invalid Freq: %d. Setting Register-Frequency to 3600\n", gateway->freq);
+ gateway->freq = 3600;
}
- oreg->freq -= 2;
+ gateway->freq -= 2;
- oreg->next = profile->registrations;
- profile->registrations = oreg;
+ gateway->next = profile->gateways;
+ profile->gateways = gateway;
+ if (find_gateway(gateway->name)) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Ignoring duplicate gateway '%s'\n", gateway->name);
+ } else if (find_gateway(gateway->register_from)) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Ignoring duplicate uri '%s'\n", gateway->register_from);
+ } else {
+ add_gateway(gateway->name, gateway);
+ add_gateway(gateway->register_from, gateway);
+ }
}
+
+ skip:
+ assert(gateway_tag);
}
}
@@ -5552,7 +5691,7 @@
rpid = "unknown";
}
- if (!profile_name || !(profile = (sofia_profile_t *) switch_core_hash_find(globals.profile_hash, profile_name))) {
+ if (!profile_name || !(profile = find_profile(profile_name))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid Profile\n");
return;
}
@@ -5602,7 +5741,7 @@
*host++ = '\0';
}
- if (!host || !(profile = (sofia_profile_t *) switch_core_hash_find(globals.profile_hash, host))) {
+ if (!host || !(profile = find_profile(host))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Chat proto [%s]\nfrom [%s]\nto [%s]\n%s\nInvalid Profile %s\n",
proto,
from,
@@ -5671,6 +5810,7 @@
void *val;
if ((sql = switch_mprintf("select 0,'unavailable','unavailable',* from sip_subscriptions where event='presence'"))) {
+ switch_mutex_lock(globals.hash_mutex);
for (hi = switch_hash_first(switch_hash_pool_get(globals.profile_hash), globals.profile_hash); hi; hi = switch_hash_next(hi)) {
switch_hash_this(hi, NULL, NULL, &val);
profile = (sofia_profile_t *) val;
@@ -5689,7 +5829,7 @@
}
switch_safe_free(sql);
}
-
+ switch_mutex_unlock(globals.hash_mutex);
}
static void establish_presence(sofia_profile_t *profile)
@@ -5805,6 +5945,7 @@
sql = switch_mprintf("select 1,'%q','%q',* from sip_subscriptions where event='presence'", status, rpid);
}
+ switch_mutex_lock(globals.hash_mutex);
for (hi = switch_hash_first(switch_hash_pool_get(globals.profile_hash), globals.profile_hash); hi; hi = switch_hash_next(hi)) {
switch_hash_this(hi, NULL, NULL, &val);
profile = (sofia_profile_t *) val;
@@ -5824,6 +5965,7 @@
}
}
+ switch_mutex_unlock(globals.hash_mutex);
return;
}
@@ -5875,7 +6017,7 @@
if (euser && host &&
(sql = switch_mprintf("select user,host,status,rpid,'' from sip_registrations where user='%q' and host='%q'", euser, host)) &&
- (profile = (sofia_profile_t *) switch_core_hash_find(globals.profile_hash, host))) {
+ (profile = find_profile(host))) {
if (!(db = switch_core_db_open_file(profile->dbname))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB %s\n", profile->dbname);
switch_safe_free(user);
@@ -5904,6 +6046,7 @@
break;
}
+ switch_mutex_lock(globals.hash_mutex);
for (hi = switch_hash_first(switch_hash_pool_get(globals.profile_hash), globals.profile_hash); hi; hi = switch_hash_next(hi)) {
switch_hash_this(hi, NULL, NULL, &val);
profile = (sofia_profile_t *) val;
@@ -5923,6 +6066,7 @@
switch_core_db_close(db);
}
}
+ switch_mutex_unlock(globals.hash_mutex);
switch_safe_free(sql);
switch_safe_free(user);
@@ -5958,6 +6102,7 @@
su_log_redirect(tport_log, logger, NULL);
switch_core_hash_init(&globals.profile_hash, module_pool);
+ switch_core_hash_init(&globals.gateway_hash, module_pool);
switch_mutex_init(&globals.hash_mutex, SWITCH_MUTEX_NESTED, module_pool);
config_sofia(0);
More information about the Freeswitch-svn
mailing list