2008-11-22 15:53:56 +00:00
|
|
|
/*
|
2007-04-02 19:54:25 +00:00
|
|
|
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
2014-02-05 15:02:28 -06:00
|
|
|
* Copyright (C) 2005-2014, Anthony Minessale II <anthm@freeswitch.org>
|
2007-04-02 19:54:25 +00:00
|
|
|
*
|
|
|
|
* Version: MPL 1.1
|
|
|
|
*
|
|
|
|
* The contents of this file are subject to the Mozilla Public License Version
|
|
|
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
|
|
|
* the License. You may obtain a copy of the License at
|
|
|
|
* http://www.mozilla.org/MPL/
|
|
|
|
*
|
|
|
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
|
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
|
|
* for the specific language governing rights and limitations under the
|
|
|
|
* License.
|
|
|
|
*
|
|
|
|
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
|
|
|
|
*
|
|
|
|
* The Initial Developer of the Original Code is
|
2009-02-04 21:20:54 +00:00
|
|
|
* Anthony Minessale II <anthm@freeswitch.org>
|
2007-04-02 19:54:25 +00:00
|
|
|
* Portions created by the Initial Developer are Copyright (C)
|
|
|
|
* the Initial Developer. All Rights Reserved.
|
|
|
|
*
|
|
|
|
* Contributor(s):
|
|
|
|
*
|
2009-02-04 21:20:54 +00:00
|
|
|
* Anthony Minessale II <anthm@freeswitch.org>
|
2012-04-18 11:04:16 -05:00
|
|
|
* Ken Rice <krice@freeswitch.org>
|
2007-04-02 19:54:25 +00:00
|
|
|
* Paul D. Tinsley <pdt at jackhammer.org>
|
|
|
|
* Bret McDanel <trixter AT 0xdecafbad.com>
|
2009-03-04 19:45:10 +00:00
|
|
|
* Eliot Gable <egable AT.AT broadvox.com>
|
2007-04-02 19:54:25 +00:00
|
|
|
*
|
|
|
|
*
|
|
|
|
* sofia_glue.c -- SOFIA SIP Endpoint (code to tie sofia to freeswitch)
|
|
|
|
*
|
|
|
|
*/
|
2007-03-31 19:01:33 +00:00
|
|
|
#include "mod_sofia.h"
|
2007-06-20 09:02:30 +00:00
|
|
|
#include <switch_stun.h>
|
2007-03-31 19:01:33 +00:00
|
|
|
|
2012-10-09 20:20:32 -05:00
|
|
|
switch_cache_db_handle_t *_sofia_glue_get_db_handle(sofia_profile_t *profile, const char *file, const char *func, int line);
|
|
|
|
#define sofia_glue_get_db_handle(_p) _sofia_glue_get_db_handle(_p, __FILE__, __SWITCH_FUNC__, __LINE__)
|
2009-03-04 23:03:25 +00:00
|
|
|
|
2010-06-23 13:22:52 -05:00
|
|
|
|
2012-12-21 21:30:14 -06:00
|
|
|
int sofia_glue_check_nat(sofia_profile_t *profile, const char *network_ip)
|
|
|
|
{
|
|
|
|
switch_assert(network_ip);
|
2010-05-12 21:25:54 -05:00
|
|
|
|
2012-12-21 21:30:14 -06:00
|
|
|
return (profile->extsipip &&
|
|
|
|
!switch_check_network_list_ip(network_ip, "loopback.auto") &&
|
|
|
|
!switch_check_network_list_ip(network_ip, profile->local_network));
|
2008-12-30 19:50:33 +00:00
|
|
|
}
|
2007-03-31 19:01:33 +00:00
|
|
|
|
2012-08-23 11:10:03 -05:00
|
|
|
private_object_t *sofia_glue_new_pvt(switch_core_session_t *session)
|
|
|
|
{
|
|
|
|
private_object_t *tech_pvt = (private_object_t *) switch_core_session_alloc(session, sizeof(private_object_t));
|
|
|
|
switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
|
|
|
|
switch_mutex_init(&tech_pvt->sofia_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
|
|
|
|
return tech_pvt;
|
|
|
|
}
|
2007-03-31 19:01:33 +00:00
|
|
|
|
2012-08-23 11:10:03 -05:00
|
|
|
void sofia_glue_set_name(private_object_t *tech_pvt, const char *channame)
|
2007-03-31 19:01:33 +00:00
|
|
|
{
|
|
|
|
char name[256];
|
2009-06-18 15:59:28 +00:00
|
|
|
char *p;
|
2007-03-31 19:01:33 +00:00
|
|
|
|
2012-08-23 11:10:03 -05:00
|
|
|
switch_snprintf(name, sizeof(name), "sofia/%s/%s", tech_pvt->profile->name, channame);
|
|
|
|
if ((p = strchr(name, ';'))) {
|
|
|
|
*p = '\0';
|
|
|
|
}
|
|
|
|
switch_channel_set_name(tech_pvt->channel, name);
|
|
|
|
}
|
|
|
|
|
|
|
|
void sofia_glue_attach_private(switch_core_session_t *session, sofia_profile_t *profile, private_object_t *tech_pvt, const char *channame)
|
|
|
|
{
|
|
|
|
|
2013-01-09 22:31:25 -06:00
|
|
|
unsigned int x, i;
|
2012-08-23 11:10:03 -05:00
|
|
|
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(session != NULL);
|
|
|
|
switch_assert(profile != NULL);
|
|
|
|
switch_assert(tech_pvt != NULL);
|
2013-01-15 22:56:02 -06:00
|
|
|
|
2007-03-31 19:01:33 +00:00
|
|
|
switch_core_session_add_stream(session, NULL);
|
|
|
|
|
|
|
|
switch_mutex_lock(tech_pvt->flag_mutex);
|
2007-04-29 01:16:49 +00:00
|
|
|
switch_mutex_lock(profile->flag_mutex);
|
2009-02-11 20:49:45 +00:00
|
|
|
|
|
|
|
/* copy flags from profile to the sofia private */
|
2010-02-06 03:38:24 +00:00
|
|
|
for (x = 0; x < TFLAG_MAX; x++) {
|
2009-02-11 20:49:45 +00:00
|
|
|
tech_pvt->flags[x] = profile->flags[x];
|
|
|
|
}
|
|
|
|
|
2009-10-21 18:48:28 +00:00
|
|
|
tech_pvt->x_freeswitch_support_local = FREESWITCH_SUPPORT;
|
2009-10-08 15:07:12 +00:00
|
|
|
|
2007-03-31 19:01:33 +00:00
|
|
|
tech_pvt->profile = profile;
|
2010-06-10 17:08:29 -05:00
|
|
|
|
2015-06-02 21:20:03 -05:00
|
|
|
if (!zstr(profile->rtpip[profile->rtpip_next])) {
|
|
|
|
tech_pvt->mparams.rtpip4 = switch_core_session_strdup(session, profile->rtpip[profile->rtpip_next++]);
|
|
|
|
tech_pvt->mparams.rtpip = tech_pvt->mparams.rtpip4;
|
|
|
|
|
|
|
|
if (profile->rtpip_next >= profile->rtpip_index) {
|
|
|
|
profile->rtpip_next = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-06-09 15:58:46 -05:00
|
|
|
if (!zstr(profile->rtpip6[profile->rtpip_next6])) {
|
|
|
|
tech_pvt->mparams.rtpip6 = switch_core_session_strdup(session, profile->rtpip6[profile->rtpip_next6++]);
|
2015-06-02 21:20:03 -05:00
|
|
|
|
|
|
|
if (zstr(tech_pvt->mparams.rtpip)) {
|
|
|
|
tech_pvt->mparams.rtpip = tech_pvt->mparams.rtpip6;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (profile->rtpip_next6 >= profile->rtpip_index6) {
|
|
|
|
profile->rtpip_next6 = 0;
|
|
|
|
}
|
2010-06-10 17:08:29 -05:00
|
|
|
}
|
|
|
|
|
2007-04-29 01:16:49 +00:00
|
|
|
profile->inuse++;
|
|
|
|
switch_mutex_unlock(profile->flag_mutex);
|
|
|
|
switch_mutex_unlock(tech_pvt->flag_mutex);
|
|
|
|
|
2007-03-31 19:01:33 +00:00
|
|
|
if (tech_pvt->bte) {
|
2010-03-25 03:51:04 +00:00
|
|
|
tech_pvt->recv_te = tech_pvt->te = tech_pvt->bte;
|
2007-03-31 19:01:33 +00:00
|
|
|
} else if (!tech_pvt->te) {
|
2012-12-22 08:36:15 -06:00
|
|
|
tech_pvt->mparams.recv_te = tech_pvt->mparams.te = profile->te;
|
2007-03-31 19:01:33 +00:00
|
|
|
}
|
|
|
|
|
2012-12-22 17:34:08 -06:00
|
|
|
tech_pvt->mparams.dtmf_type = tech_pvt->profile->dtmf_type;
|
2011-02-18 19:03:07 -06:00
|
|
|
|
2012-12-21 21:30:14 -06:00
|
|
|
if (!sofia_test_media_flag(tech_pvt->profile, SCMF_SUPPRESS_CNG)) {
|
2008-10-23 05:52:05 +00:00
|
|
|
if (tech_pvt->bcng_pt) {
|
|
|
|
tech_pvt->cng_pt = tech_pvt->bcng_pt;
|
|
|
|
} else if (!tech_pvt->cng_pt) {
|
|
|
|
tech_pvt->cng_pt = profile->cng_pt;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-03-31 19:01:33 +00:00
|
|
|
tech_pvt->session = session;
|
2007-05-09 19:30:41 +00:00
|
|
|
tech_pvt->channel = switch_core_session_get_channel(session);
|
2012-08-22 16:27:02 -05:00
|
|
|
|
|
|
|
if (sofia_test_pflag(profile, PFLAG_TRACK_CALLS)) {
|
|
|
|
switch_channel_set_flag(tech_pvt->channel, CF_TRACKABLE);
|
|
|
|
}
|
|
|
|
|
2012-12-21 21:30:14 -06:00
|
|
|
|
|
|
|
if (profile->flags[PFLAG_PASS_RFC2833]) {
|
|
|
|
switch_channel_set_flag(tech_pvt->channel, CF_PASS_RFC2833);
|
|
|
|
}
|
|
|
|
|
2012-12-22 11:51:03 -06:00
|
|
|
if (sofia_test_pflag(tech_pvt->profile, PFLAG_RTP_NOTIMER_DURING_BRIDGE)) {
|
|
|
|
switch_channel_set_flag(tech_pvt->channel, CF_RTP_NOTIMER_DURING_BRIDGE);
|
|
|
|
}
|
|
|
|
|
2013-06-26 10:47:40 -05:00
|
|
|
if (sofia_test_pflag(tech_pvt->profile, PFLAG_T38_PASSTHRU)) {
|
|
|
|
switch_channel_set_flag(tech_pvt->channel, CF_T38_PASSTHRU);
|
|
|
|
}
|
2012-12-21 21:30:14 -06:00
|
|
|
|
|
|
|
switch_core_media_check_dtmf_type(session);
|
2009-10-14 19:26:10 +00:00
|
|
|
switch_channel_set_cap(tech_pvt->channel, CC_MEDIA_ACK);
|
2009-10-19 19:58:23 +00:00
|
|
|
switch_channel_set_cap(tech_pvt->channel, CC_BYPASS_MEDIA);
|
2009-10-20 17:03:03 +00:00
|
|
|
switch_channel_set_cap(tech_pvt->channel, CC_PROXY_MEDIA);
|
2011-01-05 16:25:07 -06:00
|
|
|
switch_channel_set_cap(tech_pvt->channel, CC_JITTERBUFFER);
|
|
|
|
switch_channel_set_cap(tech_pvt->channel, CC_FS_RTP);
|
2011-08-29 11:04:38 -05:00
|
|
|
switch_channel_set_cap(tech_pvt->channel, CC_QUEUEABLE_DTMF_DELAY);
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2012-12-21 23:56:53 -06:00
|
|
|
|
|
|
|
|
2012-12-22 08:36:15 -06:00
|
|
|
tech_pvt->mparams.ndlb = tech_pvt->profile->mndlb;
|
|
|
|
tech_pvt->mparams.inbound_codec_string = profile->inbound_codec_string;
|
|
|
|
tech_pvt->mparams.outbound_codec_string = profile->outbound_codec_string;
|
|
|
|
tech_pvt->mparams.auto_rtp_bugs = profile->auto_rtp_bugs;
|
|
|
|
tech_pvt->mparams.timer_name = profile->timer_name;
|
|
|
|
tech_pvt->mparams.vflags = profile->vflags;
|
|
|
|
tech_pvt->mparams.manual_rtp_bugs = profile->manual_rtp_bugs;
|
|
|
|
tech_pvt->mparams.manual_video_rtp_bugs = profile->manual_video_rtp_bugs;
|
|
|
|
tech_pvt->mparams.extsipip = profile->extsipip;
|
2013-04-02 13:40:32 -05:00
|
|
|
tech_pvt->mparams.extrtpip = profile->extrtpip;
|
2012-12-22 08:36:15 -06:00
|
|
|
tech_pvt->mparams.local_network = profile->local_network;
|
|
|
|
tech_pvt->mparams.sipip = profile->sipip;
|
|
|
|
tech_pvt->mparams.jb_msec = profile->jb_msec;
|
|
|
|
tech_pvt->mparams.rtcp_audio_interval_msec = profile->rtcp_audio_interval_msec;
|
|
|
|
tech_pvt->mparams.rtcp_video_interval_msec = profile->rtcp_video_interval_msec;
|
|
|
|
tech_pvt->mparams.sdp_username = profile->sdp_username;
|
2013-01-08 12:59:02 -06:00
|
|
|
tech_pvt->mparams.cng_pt = tech_pvt->cng_pt;
|
2013-05-07 08:50:02 -05:00
|
|
|
tech_pvt->mparams.rtp_timeout_sec = profile->rtp_timeout_sec;
|
|
|
|
tech_pvt->mparams.rtp_hold_timeout_sec = profile->rtp_hold_timeout_sec;
|
|
|
|
|
2015-04-28 16:12:24 -05:00
|
|
|
if (profile->rtp_digit_delay) {
|
|
|
|
tech_pvt->mparams.dtmf_delay = profile->rtp_digit_delay;
|
|
|
|
}
|
2012-12-21 14:22:25 -06:00
|
|
|
|
2012-12-22 08:36:15 -06:00
|
|
|
switch_media_handle_create(&tech_pvt->media_handle, session, &tech_pvt->mparams);
|
2012-12-21 14:22:25 -06:00
|
|
|
switch_media_handle_set_media_flags(tech_pvt->media_handle, tech_pvt->profile->media_flags);
|
|
|
|
|
|
|
|
|
2013-01-09 22:31:25 -06:00
|
|
|
for(i = 0; i < profile->cand_acl_count; i++) {
|
|
|
|
switch_core_media_add_ice_acl(session, SWITCH_MEDIA_TYPE_AUDIO, profile->cand_acl[i]);
|
|
|
|
switch_core_media_add_ice_acl(session, SWITCH_MEDIA_TYPE_VIDEO, profile->cand_acl[i]);
|
|
|
|
}
|
2012-12-19 22:42:03 -06:00
|
|
|
|
|
|
|
|
2007-03-31 19:01:33 +00:00
|
|
|
switch_core_session_set_private(session, tech_pvt);
|
|
|
|
|
2010-02-06 03:38:24 +00:00
|
|
|
if (channame) {
|
2012-08-23 11:10:03 -05:00
|
|
|
sofia_glue_set_name(tech_pvt, channame);
|
2009-06-18 15:59:28 +00:00
|
|
|
}
|
2012-08-23 11:10:03 -05:00
|
|
|
|
2007-03-31 19:01:33 +00:00
|
|
|
}
|
|
|
|
|
2012-12-21 21:30:14 -06:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
switch_status_t sofia_glue_ext_address_lookup(sofia_profile_t *profile, char **ip, switch_port_t *port,
|
|
|
|
const char *sourceip, switch_memory_pool_t *pool)
|
|
|
|
{
|
|
|
|
char *error = "";
|
|
|
|
switch_status_t status = SWITCH_STATUS_FALSE;
|
|
|
|
int x;
|
|
|
|
switch_port_t stun_port = SWITCH_STUN_DEFAULT_PORT;
|
|
|
|
char *stun_ip = NULL;
|
|
|
|
|
|
|
|
if (!sourceip) {
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!strncasecmp(sourceip, "host:", 5)) {
|
|
|
|
status = (*ip = switch_stun_host_lookup(sourceip + 5, pool)) ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE;
|
|
|
|
} else if (!strncasecmp(sourceip, "stun:", 5)) {
|
|
|
|
char *p;
|
|
|
|
|
|
|
|
stun_ip = strdup(sourceip + 5);
|
|
|
|
|
|
|
|
if ((p = strchr(stun_ip, ':'))) {
|
|
|
|
int iport;
|
|
|
|
*p++ = '\0';
|
|
|
|
iport = atoi(p);
|
|
|
|
if (iport > 0 && iport < 0xFFFF) {
|
|
|
|
stun_port = (switch_port_t) iport;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (zstr(stun_ip)) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "STUN Failed! NO STUN SERVER\n");
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
for (x = 0; x < 5; x++) {
|
|
|
|
if ((status = switch_stun_lookup(ip, port, stun_ip, stun_port, &error, pool)) != SWITCH_STATUS_SUCCESS) {
|
|
|
|
switch_yield(100000);
|
|
|
|
} else {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!*ip) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "STUN Failed! No IP returned\n");
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "STUN Success [%s]:[%d]\n", *ip, *port);
|
|
|
|
status = SWITCH_STATUS_SUCCESS;
|
|
|
|
} else {
|
|
|
|
*ip = (char *) sourceip;
|
|
|
|
status = SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
out:
|
|
|
|
|
|
|
|
switch_safe_free(stun_ip);
|
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-12-22 00:32:20 +00:00
|
|
|
const char *sofia_glue_get_unknown_header(sip_t const *sip, const char *name)
|
|
|
|
{
|
|
|
|
sip_unknown_t *un;
|
|
|
|
for (un = sip->sip_unknown; un; un = un->un_next) {
|
|
|
|
if (!strcasecmp(un->un_name, name)) {
|
2009-10-23 16:03:42 +00:00
|
|
|
if (!zstr(un->un_value)) {
|
2007-12-22 00:32:20 +00:00
|
|
|
return un->un_value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2008-01-17 17:37:49 +00:00
|
|
|
sofia_transport_t sofia_glue_str2transport(const char *str)
|
2007-12-18 19:12:45 +00:00
|
|
|
{
|
2008-01-17 17:37:49 +00:00
|
|
|
if (!strncasecmp(str, "udp", 3)) {
|
2007-12-18 19:12:45 +00:00
|
|
|
return SOFIA_TRANSPORT_UDP;
|
2008-05-27 04:54:52 +00:00
|
|
|
} else if (!strncasecmp(str, "tcp", 3)) {
|
2007-12-18 19:12:45 +00:00
|
|
|
return SOFIA_TRANSPORT_TCP;
|
2008-05-27 04:54:52 +00:00
|
|
|
} else if (!strncasecmp(str, "sctp", 4)) {
|
2007-12-18 19:12:45 +00:00
|
|
|
return SOFIA_TRANSPORT_SCTP;
|
2008-05-27 04:54:52 +00:00
|
|
|
} else if (!strncasecmp(str, "tls", 3)) {
|
2007-12-18 19:12:45 +00:00
|
|
|
return SOFIA_TRANSPORT_TCP_TLS;
|
|
|
|
}
|
|
|
|
|
|
|
|
return SOFIA_TRANSPORT_UNKNOWN;
|
|
|
|
}
|
|
|
|
|
2011-12-18 11:37:04 -05:00
|
|
|
enum tport_tls_verify_policy sofia_glue_str2tls_verify_policy(const char * str){
|
2011-12-18 11:54:38 -05:00
|
|
|
char *ptr_next;
|
|
|
|
int len;
|
|
|
|
enum tport_tls_verify_policy ret;
|
|
|
|
char *ptr_cur = (char *) str;
|
|
|
|
ret = TPTLS_VERIFY_NONE;
|
|
|
|
|
|
|
|
while (ptr_cur) {
|
|
|
|
if ((ptr_next = strchr(ptr_cur, '|'))) {
|
2014-01-22 22:28:53 +01:00
|
|
|
len = (int)(ptr_next++ - ptr_cur);
|
2011-12-18 11:54:38 -05:00
|
|
|
} else {
|
2014-01-22 22:28:53 +01:00
|
|
|
len = (int)strlen(ptr_cur);
|
2011-12-18 11:54:38 -05:00
|
|
|
}
|
|
|
|
if (!strncasecmp(ptr_cur, "in",len)) {
|
|
|
|
ret |= TPTLS_VERIFY_IN;
|
|
|
|
} else if (!strncasecmp(ptr_cur, "out",len)) {
|
|
|
|
ret |= TPTLS_VERIFY_OUT;
|
|
|
|
} else if (!strncasecmp(ptr_cur, "all",len)) {
|
|
|
|
ret |= TPTLS_VERIFY_ALL;
|
|
|
|
} else if (!strncasecmp(ptr_cur, "subjects_in",len)) {
|
|
|
|
ret |= TPTLS_VERIFY_SUBJECTS_IN;
|
|
|
|
} else if (!strncasecmp(ptr_cur, "subjects_out",len)) {
|
|
|
|
ret |= TPTLS_VERIFY_SUBJECTS_OUT;
|
|
|
|
} else if (!strncasecmp(ptr_cur, "subjects_all",len)) {
|
|
|
|
ret |= TPTLS_VERIFY_SUBJECTS_ALL;
|
Fix docs on enabling cert CN/SAN validation
The correct incantations to enable certification common name / subject
alternative name verification, per our code, are `subjects_all`,
`subjects_in`, and `subjects_out` in a Sofia profile's
`tls-verify-policy`. What we've had in our examples and documentation
for years are `all_subjects`, `in_subjects`, and `out_subjects`.
The result of this is that we've almost certainly confused people into
using the incorrect forms. Those poor people will believe that they
are verifying the CN/SAN of the received host certificate against the
list in `tls-verify-in-subjects` when in fact they are not.
One clear issue in this case was that the incorrect forms failed to
have any effect without providing any warning or error. This issue
could not have persisted if we had made more noise about incorrect
input.
Given how long this has been broken, it's tempting to alias the
incorrect forms to the correct ones. However this would certainly
break many existing installations that have, because of this error,
never actually tested their setup with CN/SAN validation enabled.
In this commit, we fix the examples and documentation, and add an
error-level log output when unknown values are passed to
`tls-verify-policy`.
Thanks-to: Andrew Patrikalakis <anrp+freeswitch@anrp.net>
2015-05-26 14:01:31 +00:00
|
|
|
} else {
|
|
|
|
char el[32] = {0};
|
|
|
|
strncpy(el, ptr_cur, len < sizeof(el) ? len : sizeof(el) - 1);
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid tls-verify-policy value: %s\n", el);
|
2011-12-18 11:54:38 -05:00
|
|
|
}
|
|
|
|
ptr_cur = ptr_next;
|
|
|
|
}
|
|
|
|
return ret;
|
2011-12-18 11:37:04 -05:00
|
|
|
}
|
|
|
|
|
2010-10-03 20:00:32 -04:00
|
|
|
char *sofia_glue_find_parameter_value(switch_core_session_t *session, const char *str, const char *param)
|
|
|
|
{
|
|
|
|
const char *param_ptr;
|
|
|
|
char *param_value;
|
|
|
|
char *tmp;
|
|
|
|
switch_size_t param_len;
|
|
|
|
|
|
|
|
if (zstr(str) || zstr(param) || !session) return NULL;
|
|
|
|
|
|
|
|
if (end_of(param) != '=') {
|
|
|
|
param = switch_core_session_sprintf(session, "%s=", param);
|
|
|
|
if (zstr(param)) return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
param_len = strlen(param);
|
|
|
|
param_ptr = sofia_glue_find_parameter(str, param);
|
|
|
|
|
|
|
|
if (zstr(param_ptr)) return NULL;
|
|
|
|
|
|
|
|
param_value = switch_core_session_strdup(session, param_ptr + param_len);
|
|
|
|
|
|
|
|
if (zstr(param_value)) return NULL;
|
|
|
|
|
|
|
|
if ((tmp = strchr(param_value, ';'))) *tmp = '\0';
|
|
|
|
|
|
|
|
return param_value;
|
|
|
|
}
|
|
|
|
|
2008-05-27 04:54:52 +00:00
|
|
|
char *sofia_glue_find_parameter(const char *str, const char *param)
|
2008-01-17 17:37:49 +00:00
|
|
|
{
|
|
|
|
char *ptr = NULL;
|
|
|
|
|
2008-05-27 04:54:52 +00:00
|
|
|
ptr = (char *) str;
|
|
|
|
while (ptr) {
|
2008-01-17 17:37:49 +00:00
|
|
|
if (!strncasecmp(ptr, param, strlen(param)))
|
|
|
|
return ptr;
|
|
|
|
|
|
|
|
if ((ptr = strchr(ptr, ';')))
|
|
|
|
ptr++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2007-12-18 19:12:45 +00:00
|
|
|
sofia_transport_t sofia_glue_url2transport(const url_t *url)
|
|
|
|
{
|
|
|
|
char *ptr = NULL;
|
|
|
|
int tls = 0;
|
|
|
|
|
2008-02-15 23:18:18 +00:00
|
|
|
if (!url)
|
2007-12-18 19:12:45 +00:00
|
|
|
return SOFIA_TRANSPORT_UNKNOWN;
|
|
|
|
|
|
|
|
if (url->url_scheme && !strcasecmp(url->url_scheme, "sips")) {
|
|
|
|
tls++;
|
|
|
|
}
|
|
|
|
|
2008-01-17 17:37:49 +00:00
|
|
|
if ((ptr = sofia_glue_find_parameter(url->url_params, "transport="))) {
|
|
|
|
return sofia_glue_str2transport(ptr + 10);
|
2007-12-18 19:12:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return (tls) ? SOFIA_TRANSPORT_TCP_TLS : SOFIA_TRANSPORT_UDP;
|
|
|
|
}
|
|
|
|
|
2010-06-23 13:22:52 -05:00
|
|
|
sofia_transport_t sofia_glue_via2transport(const sip_via_t * via)
|
2007-12-18 19:12:45 +00:00
|
|
|
{
|
|
|
|
char *ptr = NULL;
|
|
|
|
|
|
|
|
if (!via || !via->v_protocol)
|
|
|
|
return SOFIA_TRANSPORT_UNKNOWN;
|
|
|
|
|
|
|
|
if ((ptr = strrchr(via->v_protocol, '/'))) {
|
|
|
|
ptr++;
|
|
|
|
|
|
|
|
if (!strncasecmp(ptr, "udp", 3)) {
|
|
|
|
return SOFIA_TRANSPORT_UDP;
|
2008-05-27 04:54:52 +00:00
|
|
|
} else if (!strncasecmp(ptr, "tcp", 3)) {
|
2007-12-18 19:12:45 +00:00
|
|
|
return SOFIA_TRANSPORT_TCP;
|
2008-05-27 04:54:52 +00:00
|
|
|
} else if (!strncasecmp(ptr, "tls", 3)) {
|
2007-12-18 19:12:45 +00:00
|
|
|
return SOFIA_TRANSPORT_TCP_TLS;
|
2008-05-27 04:54:52 +00:00
|
|
|
} else if (!strncasecmp(ptr, "sctp", 4)) {
|
2007-12-18 19:12:45 +00:00
|
|
|
return SOFIA_TRANSPORT_SCTP;
|
2013-02-06 09:48:04 -06:00
|
|
|
} else if (!strncasecmp(ptr, "wss", 3)) {
|
|
|
|
return SOFIA_TRANSPORT_WSS;
|
|
|
|
} else if (!strncasecmp(ptr, "ws", 2)) {
|
|
|
|
return SOFIA_TRANSPORT_WS;
|
2007-12-18 19:12:45 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return SOFIA_TRANSPORT_UNKNOWN;
|
|
|
|
}
|
|
|
|
|
|
|
|
const char *sofia_glue_transport2str(const sofia_transport_t tp)
|
|
|
|
{
|
2008-05-27 04:54:52 +00:00
|
|
|
switch (tp) {
|
2007-12-18 19:12:45 +00:00
|
|
|
case SOFIA_TRANSPORT_TCP:
|
|
|
|
return "tcp";
|
|
|
|
|
|
|
|
case SOFIA_TRANSPORT_TCP_TLS:
|
|
|
|
return "tls";
|
|
|
|
|
|
|
|
case SOFIA_TRANSPORT_SCTP:
|
|
|
|
return "sctp";
|
|
|
|
|
2013-02-06 09:48:04 -06:00
|
|
|
case SOFIA_TRANSPORT_WS:
|
|
|
|
return "ws";
|
|
|
|
|
|
|
|
case SOFIA_TRANSPORT_WSS:
|
|
|
|
return "wss";
|
|
|
|
|
2007-12-18 19:12:45 +00:00
|
|
|
default:
|
|
|
|
return "udp";
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-02-06 03:38:24 +00:00
|
|
|
char *sofia_glue_create_external_via(switch_core_session_t *session, sofia_profile_t *profile, sofia_transport_t transport)
|
2009-06-03 21:08:34 +00:00
|
|
|
{
|
2010-02-06 03:38:24 +00:00
|
|
|
return sofia_glue_create_via(session, profile->extsipip, (sofia_glue_transport_has_tls(transport))
|
2012-11-21 10:32:41 -06:00
|
|
|
? profile->tls_sip_port : profile->extsipport, transport);
|
2009-06-03 21:08:34 +00:00
|
|
|
}
|
|
|
|
|
2010-02-06 03:38:24 +00:00
|
|
|
char *sofia_glue_create_via(switch_core_session_t *session, const char *ip, switch_port_t port, sofia_transport_t transport)
|
2009-06-03 21:08:34 +00:00
|
|
|
{
|
2015-07-30 11:45:46 -05:00
|
|
|
char *ipv6 = strchr(ip, ':');
|
2009-06-03 21:08:34 +00:00
|
|
|
if (port && port != 5060) {
|
|
|
|
if (session) {
|
2015-07-30 11:45:46 -05:00
|
|
|
return switch_core_session_sprintf(session, "SIP/2.0/%s %s%s%s:%d;rport", sofia_glue_transport2str(transport), ipv6 ? "[" : "", ip, ipv6 ? "]" : "", port);
|
2009-06-03 21:08:34 +00:00
|
|
|
} else {
|
2015-07-30 11:45:46 -05:00
|
|
|
return switch_mprintf("SIP/2.0/%s %s%s%s:%d;rport", sofia_glue_transport2str(transport), ipv6 ? "[" : "", ip, ipv6 ? "]" : "", port);
|
2009-06-03 21:08:34 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (session) {
|
2015-07-30 11:45:46 -05:00
|
|
|
return switch_core_session_sprintf(session, "SIP/2.0/%s %s%s%s;rport", sofia_glue_transport2str(transport), ipv6 ? "[" : "", ip, ipv6 ? "]" : "");
|
2009-06-03 21:08:34 +00:00
|
|
|
} else {
|
2015-07-30 11:45:46 -05:00
|
|
|
return switch_mprintf("SIP/2.0/%s %s%s%s;rport", sofia_glue_transport2str(transport), ipv6 ? "[" : "", ip, ipv6 ? "]" : "");
|
2009-06-03 21:08:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-06-09 16:33:33 +00:00
|
|
|
char *sofia_glue_strip_uri(const char *str)
|
|
|
|
{
|
|
|
|
char *p;
|
|
|
|
char *r;
|
|
|
|
|
|
|
|
if ((p = strchr(str, '<'))) {
|
|
|
|
p++;
|
|
|
|
r = strdup(p);
|
|
|
|
if ((p = strchr(r, '>'))) {
|
|
|
|
*p = '\0';
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
r = strdup(str);
|
|
|
|
}
|
|
|
|
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
2010-02-19 22:08:10 +00:00
|
|
|
|
2009-06-03 21:08:34 +00:00
|
|
|
|
2007-12-18 19:12:45 +00:00
|
|
|
int sofia_glue_transport_has_tls(const sofia_transport_t tp)
|
|
|
|
{
|
2008-05-27 04:54:52 +00:00
|
|
|
switch (tp) {
|
2007-12-18 19:12:45 +00:00
|
|
|
case SOFIA_TRANSPORT_TCP_TLS:
|
|
|
|
return 1;
|
|
|
|
|
|
|
|
default:
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-02-06 03:38:24 +00:00
|
|
|
void sofia_glue_get_addr(msg_t *msg, char *buf, size_t buflen, int *port)
|
|
|
|
{
|
2009-06-03 21:08:34 +00:00
|
|
|
su_addrinfo_t *addrinfo = msg_addrinfo(msg);
|
|
|
|
|
|
|
|
if (buf) {
|
2014-01-22 22:28:53 +01:00
|
|
|
get_addr(buf, buflen, addrinfo->ai_addr, (socklen_t)addrinfo->ai_addrlen);
|
2009-06-03 21:08:34 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (port) {
|
2010-02-06 03:38:24 +00:00
|
|
|
*port = get_port(addrinfo->ai_addr);
|
2009-06-03 21:08:34 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2008-05-27 04:54:52 +00:00
|
|
|
char *sofia_overcome_sip_uri_weakness(switch_core_session_t *session, const char *uri, const sofia_transport_t transport, switch_bool_t uri_only,
|
2013-02-27 09:04:51 -06:00
|
|
|
const char *params, const char *invite_tel_params)
|
2007-11-15 16:22:18 +00:00
|
|
|
{
|
|
|
|
char *stripped = switch_core_session_strdup(session, uri);
|
|
|
|
char *new_uri = NULL;
|
2008-06-27 16:01:40 +00:00
|
|
|
char *p;
|
2013-08-21 22:26:04 +05:00
|
|
|
const char *url_params = NULL;
|
2007-11-15 16:22:18 +00:00
|
|
|
|
2013-08-21 22:26:04 +05:00
|
|
|
if (!zstr(params) && *params == '~') {
|
|
|
|
url_params = params + 1;
|
|
|
|
params = NULL;
|
|
|
|
}
|
2013-02-27 09:04:51 -06:00
|
|
|
|
2007-11-15 16:22:18 +00:00
|
|
|
stripped = sofia_glue_get_url_from_contact(stripped, 0);
|
2008-06-27 16:01:40 +00:00
|
|
|
|
|
|
|
/* remove our params so we don't make any whiny moronic device piss it's pants and forget who it is for a half-hour */
|
2010-02-06 03:38:24 +00:00
|
|
|
if ((p = (char *) switch_stristr(";fs_", stripped))) {
|
|
|
|
*p = '\0';
|
2008-06-27 16:01:40 +00:00
|
|
|
}
|
|
|
|
|
2007-12-18 19:12:45 +00:00
|
|
|
if (transport && transport != SOFIA_TRANSPORT_UDP) {
|
|
|
|
|
2007-11-15 16:22:18 +00:00
|
|
|
if (switch_stristr("port=", stripped)) {
|
2007-12-07 03:57:48 +00:00
|
|
|
new_uri = switch_core_session_sprintf(session, "%s%s%s", uri_only ? "" : "<", stripped, uri_only ? "" : ">");
|
2007-11-15 16:22:18 +00:00
|
|
|
} else {
|
2008-05-27 04:54:52 +00:00
|
|
|
|
2007-11-15 16:22:18 +00:00
|
|
|
if (strchr(stripped, ';')) {
|
2008-03-11 18:19:17 +00:00
|
|
|
if (params) {
|
2009-05-14 16:18:33 +00:00
|
|
|
new_uri = switch_core_session_sprintf(session, "%s%s;transport=%s;%s%s",
|
2008-03-11 18:19:17 +00:00
|
|
|
uri_only ? "" : "<", stripped, sofia_glue_transport2str(transport), params, uri_only ? "" : ">");
|
|
|
|
} else {
|
2009-05-14 16:18:33 +00:00
|
|
|
new_uri = switch_core_session_sprintf(session, "%s%s;transport=%s%s",
|
2008-03-11 18:19:17 +00:00
|
|
|
uri_only ? "" : "<", stripped, sofia_glue_transport2str(transport), uri_only ? "" : ">");
|
|
|
|
}
|
2007-11-15 16:22:18 +00:00
|
|
|
} else {
|
2008-03-11 18:19:17 +00:00
|
|
|
if (params) {
|
2008-05-27 04:54:52 +00:00
|
|
|
new_uri = switch_core_session_sprintf(session, "%s%s;transport=%s;%s%s",
|
2008-03-11 18:19:17 +00:00
|
|
|
uri_only ? "" : "<", stripped, sofia_glue_transport2str(transport), params, uri_only ? "" : ">");
|
|
|
|
} else {
|
2008-05-27 04:54:52 +00:00
|
|
|
new_uri = switch_core_session_sprintf(session, "%s%s;transport=%s%s",
|
2008-03-11 18:19:17 +00:00
|
|
|
uri_only ? "" : "<", stripped, sofia_glue_transport2str(transport), uri_only ? "" : ">");
|
|
|
|
}
|
2007-11-15 16:22:18 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2008-03-11 18:19:17 +00:00
|
|
|
if (params) {
|
2008-05-29 17:35:16 +00:00
|
|
|
new_uri = switch_core_session_sprintf(session, "%s%s;%s%s", uri_only ? "" : "<", stripped, params, uri_only ? "" : ">");
|
2008-03-11 18:19:17 +00:00
|
|
|
} else {
|
2008-05-29 17:35:16 +00:00
|
|
|
if (uri_only) {
|
|
|
|
new_uri = stripped;
|
|
|
|
} else {
|
|
|
|
new_uri = switch_core_session_sprintf(session, "<%s>", stripped);
|
|
|
|
}
|
2008-03-11 18:19:17 +00:00
|
|
|
}
|
2007-11-15 16:22:18 +00:00
|
|
|
}
|
2008-05-29 20:25:58 +00:00
|
|
|
|
2013-08-21 22:26:04 +05:00
|
|
|
if (url_params && !uri_only) {
|
|
|
|
new_uri = switch_core_session_sprintf(session, "%s;%s", new_uri, url_params);
|
|
|
|
}
|
2013-02-27 09:04:51 -06:00
|
|
|
|
|
|
|
if (!zstr(invite_tel_params)) {
|
|
|
|
char *lhs, *rhs = strchr(new_uri, '@');
|
|
|
|
|
|
|
|
if (!zstr(rhs)) {
|
|
|
|
*rhs++ = '\0';
|
|
|
|
lhs = new_uri;
|
|
|
|
new_uri = switch_core_session_sprintf(session, "%s;%s@%s", lhs, invite_tel_params, rhs);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-11-15 16:22:18 +00:00
|
|
|
return new_uri;
|
|
|
|
}
|
|
|
|
|
2010-02-06 03:38:24 +00:00
|
|
|
char *sofia_glue_get_extra_headers(switch_channel_t *channel, const char *prefix)
|
2009-08-11 00:54:39 +00:00
|
|
|
{
|
|
|
|
char *extra_headers = NULL;
|
|
|
|
switch_stream_handle_t stream = { 0 };
|
2010-02-06 03:38:24 +00:00
|
|
|
switch_event_header_t *hi = NULL;
|
2011-08-01 16:29:37 -05:00
|
|
|
const char *exclude_regex = NULL;
|
|
|
|
switch_regex_t *re = NULL;
|
|
|
|
int ovector[30] = {0};
|
|
|
|
int proceed;
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2011-08-01 16:29:37 -05:00
|
|
|
exclude_regex = switch_channel_get_variable(channel, "exclude_outgoing_extra_header");
|
2010-02-06 03:38:24 +00:00
|
|
|
SWITCH_STANDARD_STREAM(stream);
|
|
|
|
if ((hi = switch_channel_variable_first(channel))) {
|
|
|
|
for (; hi; hi = hi->next) {
|
|
|
|
const char *name = (char *) hi->name;
|
|
|
|
char *value = (char *) hi->value;
|
2013-04-18 16:44:40 -05:00
|
|
|
|
|
|
|
if (!strcasecmp(name, "sip_geolocation")) {
|
|
|
|
stream.write_function(&stream, "Geolocation: %s\r\n", value);
|
|
|
|
}
|
2010-02-06 03:38:24 +00:00
|
|
|
|
|
|
|
if (!strncasecmp(name, prefix, strlen(prefix))) {
|
2011-08-01 16:29:37 -05:00
|
|
|
if ( !exclude_regex || !(proceed = switch_regex_perform(name, exclude_regex, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
|
|
|
|
const char *hname = name + strlen(prefix);
|
|
|
|
stream.write_function(&stream, "%s: %s\r\n", hname, value);
|
|
|
|
switch_regex_safe_free(re);
|
|
|
|
} else {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Ignoring Extra Header [%s] , matches exclude_outgoing_extra_header [%s]\n", name, exclude_regex);
|
|
|
|
}
|
2010-02-06 03:38:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
switch_channel_variable_last(channel);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!zstr((char *) stream.data)) {
|
|
|
|
extra_headers = stream.data;
|
|
|
|
} else {
|
2009-08-11 00:54:39 +00:00
|
|
|
switch_safe_free(stream.data);
|
|
|
|
}
|
|
|
|
|
|
|
|
return extra_headers;
|
|
|
|
}
|
|
|
|
|
2011-11-23 15:38:54 -06:00
|
|
|
void sofia_glue_set_extra_headers(switch_core_session_t *session, sip_t const *sip, const char *prefix)
|
2009-08-11 00:54:39 +00:00
|
|
|
{
|
|
|
|
sip_unknown_t *un;
|
|
|
|
char name[512] = "";
|
2011-11-23 15:38:54 -06:00
|
|
|
switch_channel_t *channel = switch_core_session_get_channel(session);
|
2015-09-23 11:58:57 -05:00
|
|
|
char pstr[32];
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2011-11-23 15:38:54 -06:00
|
|
|
|
2009-08-11 00:54:39 +00:00
|
|
|
if (!sip || !channel) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (un = sip->sip_unknown; un; un = un->un_next) {
|
2011-09-08 10:01:52 -05:00
|
|
|
if ((!strncasecmp(un->un_name, "X-", 2) && strncasecmp(un->un_name, "X-FS-", 5)) || !strncasecmp(un->un_name, "P-", 2)) {
|
2009-10-23 16:03:42 +00:00
|
|
|
if (!zstr(un->un_value)) {
|
2009-08-11 00:54:39 +00:00
|
|
|
switch_snprintf(name, sizeof(name), "%s%s", prefix, un->un_name);
|
|
|
|
switch_channel_set_variable(channel, name, un->un_value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2011-11-23 15:38:54 -06:00
|
|
|
|
2015-09-23 11:58:57 -05:00
|
|
|
switch_snprintf(pstr, sizeof(pstr), "execute_on_%sprefix", prefix);
|
2011-11-23 15:38:54 -06:00
|
|
|
switch_channel_execute_on(channel, pstr);
|
|
|
|
switch_channel_api_on(channel, pstr);
|
|
|
|
|
|
|
|
switch_channel_execute_on(channel, "execute_on_sip_extra_headers");
|
|
|
|
switch_channel_api_on(channel, "api_on_sip_extra_headers");
|
2009-08-11 00:54:39 +00:00
|
|
|
}
|
|
|
|
|
2012-02-22 15:26:38 -06:00
|
|
|
char *sofia_glue_get_extra_headers_from_event(switch_event_t *event, const char *prefix)
|
|
|
|
{
|
|
|
|
char *extra_headers = NULL;
|
|
|
|
switch_stream_handle_t stream = { 0 };
|
|
|
|
switch_event_header_t *hp;
|
|
|
|
|
|
|
|
SWITCH_STANDARD_STREAM(stream);
|
|
|
|
for (hp = event->headers; hp; hp = hp->next) {
|
|
|
|
if (!zstr(hp->name) && !zstr(hp->value) && !strncasecmp(hp->name, prefix, strlen(prefix))) {
|
|
|
|
char *name = strdup(hp->name);
|
|
|
|
const char *hname = name + strlen(prefix);
|
|
|
|
stream.write_function(&stream, "%s: %s\r\n", hname, (char *)hp->value);
|
|
|
|
free(name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!zstr((char *) stream.data)) {
|
|
|
|
extra_headers = stream.data;
|
|
|
|
} else {
|
|
|
|
switch_safe_free(stream.data);
|
|
|
|
}
|
|
|
|
|
|
|
|
return extra_headers;
|
|
|
|
}
|
2008-02-21 17:48:41 +00:00
|
|
|
|
2007-03-31 19:01:33 +00:00
|
|
|
switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
|
|
|
|
{
|
2007-09-23 20:08:26 +00:00
|
|
|
char *alert_info = NULL;
|
2007-12-24 18:52:10 +00:00
|
|
|
const char *max_forwards = NULL;
|
2007-11-01 11:28:26 +00:00
|
|
|
const char *alertbuf;
|
2008-01-28 07:26:10 +00:00
|
|
|
private_object_t *tech_pvt = switch_core_session_get_private(session);
|
|
|
|
switch_channel_t *channel = switch_core_session_get_channel(session);
|
2007-03-31 19:01:33 +00:00
|
|
|
switch_caller_profile_t *caller_profile;
|
2007-11-01 11:28:26 +00:00
|
|
|
const char *cid_name, *cid_num;
|
2007-03-31 19:01:33 +00:00
|
|
|
char *e_dest = NULL;
|
|
|
|
const char *holdstr = "";
|
|
|
|
char *extra_headers = NULL;
|
|
|
|
switch_status_t status = SWITCH_STATUS_FALSE;
|
2007-10-19 21:06:09 +00:00
|
|
|
uint32_t session_timeout = 0;
|
2007-11-01 11:28:26 +00:00
|
|
|
const char *val;
|
|
|
|
const char *rep;
|
2008-06-07 15:34:33 +00:00
|
|
|
const char *call_id = NULL;
|
2008-06-26 20:19:09 +00:00
|
|
|
char *route = NULL;
|
|
|
|
char *route_uri = NULL;
|
2009-06-19 15:35:26 +00:00
|
|
|
sofia_destination_t *dst = NULL;
|
2009-03-04 23:03:25 +00:00
|
|
|
sofia_cid_type_t cid_type = tech_pvt->profile->cid_type;
|
2010-02-06 03:38:24 +00:00
|
|
|
sip_cseq_t *cseq = NULL;
|
2011-11-10 15:16:53 -06:00
|
|
|
const char *invite_record_route = switch_channel_get_variable(tech_pvt->channel, "sip_invite_record_route");
|
2010-02-06 03:38:24 +00:00
|
|
|
const char *invite_route_uri = switch_channel_get_variable(tech_pvt->channel, "sip_invite_route_uri");
|
|
|
|
const char *invite_full_from = switch_channel_get_variable(tech_pvt->channel, "sip_invite_full_from");
|
|
|
|
const char *invite_full_to = switch_channel_get_variable(tech_pvt->channel, "sip_invite_full_to");
|
|
|
|
const char *handle_full_from = switch_channel_get_variable(tech_pvt->channel, "sip_handle_full_from");
|
|
|
|
const char *handle_full_to = switch_channel_get_variable(tech_pvt->channel, "sip_handle_full_to");
|
2011-04-03 12:03:29 -05:00
|
|
|
const char *force_full_from = switch_channel_get_variable(tech_pvt->channel, "sip_force_full_from");
|
|
|
|
const char *force_full_to = switch_channel_get_variable(tech_pvt->channel, "sip_force_full_to");
|
2014-03-06 00:01:02 +05:00
|
|
|
const char *content_encoding = switch_channel_get_variable(tech_pvt->channel, "sip_content_encoding");
|
2010-06-01 17:13:22 -05:00
|
|
|
char *mp = NULL, *mp_type = NULL;
|
2011-11-10 15:16:53 -06:00
|
|
|
char *record_route = NULL;
|
2011-11-28 16:11:09 -06:00
|
|
|
const char *recover_via = NULL;
|
2012-04-27 14:41:32 -05:00
|
|
|
int require_timer = 1;
|
2015-02-24 16:43:24 +01:00
|
|
|
uint8_t is_t38 = 0;
|
2012-04-26 10:35:02 -05:00
|
|
|
|
2012-08-22 16:27:02 -05:00
|
|
|
if (switch_channel_test_flag(tech_pvt->channel, CF_RECOVERING)) {
|
2011-11-16 09:57:15 -06:00
|
|
|
const char *recover_contact = switch_channel_get_variable(tech_pvt->channel, "sip_recover_contact");
|
2011-11-28 16:11:09 -06:00
|
|
|
recover_via = switch_channel_get_variable(tech_pvt->channel, "sip_recover_via");
|
2011-11-16 09:57:15 -06:00
|
|
|
|
2011-11-10 15:16:53 -06:00
|
|
|
if (!zstr(invite_record_route)) {
|
|
|
|
record_route = switch_core_session_sprintf(session, "Record-Route: %s", invite_record_route);
|
|
|
|
}
|
2011-11-16 09:57:15 -06:00
|
|
|
|
|
|
|
if (recover_contact) {
|
|
|
|
char *tmp = switch_core_session_strdup(session, recover_contact);
|
|
|
|
tech_pvt->redirected = sofia_glue_get_url_from_contact(tmp, 0);
|
|
|
|
}
|
2011-11-10 15:16:53 -06:00
|
|
|
}
|
2011-11-16 09:57:15 -06:00
|
|
|
|
|
|
|
|
2012-05-30 13:08:31 -05:00
|
|
|
if ((rep = switch_channel_get_variable(channel, SOFIA_REPLACES_HEADER))) {
|
|
|
|
switch_channel_set_variable(channel, SOFIA_REPLACES_HEADER, NULL);
|
|
|
|
}
|
2007-03-31 19:01:33 +00:00
|
|
|
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(tech_pvt != NULL);
|
2007-03-31 19:01:33 +00:00
|
|
|
|
2009-02-09 17:56:38 +00:00
|
|
|
sofia_clear_flag_locked(tech_pvt, TFLAG_SDP);
|
2007-05-09 19:30:41 +00:00
|
|
|
|
2007-03-31 19:01:33 +00:00
|
|
|
caller_profile = switch_channel_get_caller_profile(channel);
|
|
|
|
|
2011-10-26 09:00:59 -05:00
|
|
|
if (!caller_profile) {
|
|
|
|
switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
|
|
|
|
return SWITCH_STATUS_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-04-27 14:41:32 -05:00
|
|
|
if ((val = switch_channel_get_variable_dup(channel, "sip_require_timer", SWITCH_FALSE, -1)) && switch_false(val)) {
|
|
|
|
require_timer = 0;
|
2012-04-26 10:35:02 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-11-01 11:28:26 +00:00
|
|
|
cid_name = caller_profile->caller_id_name;
|
|
|
|
cid_num = caller_profile->caller_id_number;
|
2014-10-03 11:34:37 -05:00
|
|
|
|
|
|
|
if (!tech_pvt->sent_invites && !switch_channel_test_flag(channel, CF_ANSWERED)) {
|
|
|
|
switch_core_media_prepare_codecs(tech_pvt->session, SWITCH_FALSE);
|
|
|
|
switch_core_media_check_video_codecs(tech_pvt->session);
|
|
|
|
}
|
|
|
|
|
2007-11-10 00:47:09 +00:00
|
|
|
check_decode(cid_name, session);
|
|
|
|
check_decode(cid_num, session);
|
2007-03-31 19:01:33 +00:00
|
|
|
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2007-03-31 19:01:33 +00:00
|
|
|
if ((alertbuf = switch_channel_get_variable(channel, "alert_info"))) {
|
2007-09-23 20:08:26 +00:00
|
|
|
alert_info = switch_core_session_sprintf(tech_pvt->session, "Alert-Info: %s", alertbuf);
|
2007-03-31 19:01:33 +00:00
|
|
|
}
|
|
|
|
|
2007-12-24 18:52:10 +00:00
|
|
|
max_forwards = switch_channel_get_variable(channel, SWITCH_MAX_FORWARDS_VARIABLE);
|
2007-03-31 19:01:33 +00:00
|
|
|
|
2012-12-21 23:56:53 -06:00
|
|
|
if ((status = switch_core_media_choose_port(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO, 0)) != SWITCH_STATUS_SUCCESS) {
|
2010-01-22 00:51:32 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "Port Error!\n");
|
2007-03-31 19:01:33 +00:00
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
2012-12-22 08:36:15 -06:00
|
|
|
if (!switch_channel_get_private(tech_pvt->channel, "t38_options") || zstr(tech_pvt->mparams.local_sdp_str)) {
|
2013-11-08 03:48:00 +05:00
|
|
|
switch_core_media_gen_local_sdp(session, SDP_TYPE_REQUEST, NULL, 0, NULL, 0);
|
2010-05-12 21:25:54 -05:00
|
|
|
}
|
2007-03-31 19:01:33 +00:00
|
|
|
|
2009-02-09 17:56:38 +00:00
|
|
|
sofia_set_flag_locked(tech_pvt, TFLAG_READY);
|
2007-03-31 19:01:33 +00:00
|
|
|
|
|
|
|
if (!tech_pvt->nh) {
|
2010-01-22 23:37:50 +00:00
|
|
|
char *d_url = NULL, *url = NULL, *url_str = NULL;
|
2007-10-03 23:42:40 +00:00
|
|
|
sofia_private_t *sofia_private;
|
2010-01-20 19:20:11 +00:00
|
|
|
char *invite_contact = NULL, *to_str, *use_from_str, *from_str;
|
2007-12-18 19:12:45 +00:00
|
|
|
const char *t_var;
|
2010-09-15 19:46:15 -05:00
|
|
|
char *rpid_domain = NULL, *p;
|
2007-11-26 16:18:50 +00:00
|
|
|
const char *priv = "off";
|
|
|
|
const char *screen = "no";
|
2008-03-11 18:36:56 +00:00
|
|
|
const char *invite_params = switch_channel_get_variable(tech_pvt->channel, "sip_invite_params");
|
2009-02-25 20:22:12 +00:00
|
|
|
const char *invite_to_params = switch_channel_get_variable(tech_pvt->channel, "sip_invite_to_params");
|
2013-02-27 09:04:51 -06:00
|
|
|
const char *invite_tel_params = switch_channel_get_variable(switch_core_session_get_channel(session), "sip_invite_tel_params");
|
2009-03-04 19:45:10 +00:00
|
|
|
const char *invite_to_uri = switch_channel_get_variable(tech_pvt->channel, "sip_invite_to_uri");
|
2010-02-06 03:38:24 +00:00
|
|
|
const char *invite_from_uri = switch_channel_get_variable(tech_pvt->channel, "sip_invite_from_uri");
|
2009-02-25 23:07:45 +00:00
|
|
|
const char *invite_contact_params = switch_channel_get_variable(tech_pvt->channel, "sip_invite_contact_params");
|
2009-02-25 20:22:12 +00:00
|
|
|
const char *invite_from_params = switch_channel_get_variable(tech_pvt->channel, "sip_invite_from_params");
|
2008-11-14 03:41:17 +00:00
|
|
|
const char *from_var = switch_channel_get_variable(tech_pvt->channel, "sip_from_uri");
|
2009-03-11 15:14:24 +00:00
|
|
|
const char *from_display = switch_channel_get_variable(tech_pvt->channel, "sip_from_display");
|
2010-02-06 03:38:24 +00:00
|
|
|
const char *invite_req_uri = switch_channel_get_variable(tech_pvt->channel, "sip_invite_req_uri");
|
2010-09-15 19:46:15 -05:00
|
|
|
const char *invite_domain = switch_channel_get_variable(tech_pvt->channel, "sip_invite_domain");
|
2013-02-27 09:04:51 -06:00
|
|
|
|
2010-02-06 03:38:24 +00:00
|
|
|
const char *use_name, *use_number;
|
2010-01-21 00:12:24 +00:00
|
|
|
|
|
|
|
if (zstr(tech_pvt->dest)) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "URL Error!\n");
|
|
|
|
return SWITCH_STATUS_FALSE;
|
|
|
|
}
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2010-01-21 00:12:24 +00:00
|
|
|
if ((d_url = sofia_glue_get_url_from_contact(tech_pvt->dest, 1))) {
|
|
|
|
url = d_url;
|
|
|
|
} else {
|
|
|
|
url = tech_pvt->dest;
|
|
|
|
}
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2010-01-21 00:12:24 +00:00
|
|
|
url_str = url;
|
|
|
|
|
|
|
|
if (!tech_pvt->from_str) {
|
2010-02-06 03:38:24 +00:00
|
|
|
const char *sipip;
|
|
|
|
const char *format;
|
|
|
|
|
2010-01-21 00:12:24 +00:00
|
|
|
sipip = tech_pvt->profile->sipip;
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2012-12-22 08:36:15 -06:00
|
|
|
if (!zstr(tech_pvt->mparams.remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->mparams.remote_ip)) {
|
2010-01-21 00:12:24 +00:00
|
|
|
sipip = tech_pvt->profile->extsipip;
|
|
|
|
}
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2010-09-15 19:46:15 -05:00
|
|
|
if (!zstr(invite_domain)) {
|
|
|
|
sipip = invite_domain;
|
2010-01-21 00:12:24 +00:00
|
|
|
}
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2014-05-01 15:20:25 -05:00
|
|
|
format = strchr(sipip, ':') ? "\"%s\" <sip:%s%s[%s]>" : "\"%s\" <sip:%s%s%s>";
|
|
|
|
|
2010-02-06 03:38:24 +00:00
|
|
|
tech_pvt->from_str = switch_core_session_sprintf(tech_pvt->session, format, cid_name, cid_num, !zstr(cid_num) ? "@" : "", sipip);
|
2010-01-21 00:12:24 +00:00
|
|
|
}
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2008-11-14 03:41:17 +00:00
|
|
|
if (from_var) {
|
|
|
|
if (strncasecmp(from_var, "sip:", 4) || strncasecmp(from_var, "sips:", 5)) {
|
|
|
|
use_from_str = switch_core_session_strdup(tech_pvt->session, from_var);
|
|
|
|
} else {
|
|
|
|
use_from_str = switch_core_session_sprintf(tech_pvt->session, "sip:%s", from_var);
|
|
|
|
}
|
2009-10-23 16:03:42 +00:00
|
|
|
} else if (!zstr(tech_pvt->gateway_from_str)) {
|
2007-10-23 14:22:53 +00:00
|
|
|
use_from_str = tech_pvt->gateway_from_str;
|
|
|
|
} else {
|
|
|
|
use_from_str = tech_pvt->from_str;
|
|
|
|
}
|
2007-12-18 19:12:45 +00:00
|
|
|
|
2009-10-23 16:03:42 +00:00
|
|
|
if (!zstr(tech_pvt->gateway_from_str)) {
|
2009-03-11 13:15:02 +00:00
|
|
|
rpid_domain = switch_core_session_strdup(session, tech_pvt->gateway_from_str);
|
2009-10-23 16:03:42 +00:00
|
|
|
} else if (!zstr(tech_pvt->from_str)) {
|
2011-10-14 14:05:32 -05:00
|
|
|
rpid_domain = switch_core_session_strdup(session, use_from_str);
|
2010-02-06 03:38:24 +00:00
|
|
|
}
|
2009-03-11 13:15:02 +00:00
|
|
|
|
2007-11-21 00:56:41 +00:00
|
|
|
sofia_glue_get_url_from_contact(rpid_domain, 0);
|
2008-03-27 17:38:30 +00:00
|
|
|
if ((rpid_domain = strrchr(rpid_domain, '@'))) {
|
2007-11-21 00:56:41 +00:00
|
|
|
rpid_domain++;
|
|
|
|
if ((p = strchr(rpid_domain, ';'))) {
|
|
|
|
*p = '\0';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-01-22 23:37:50 +00:00
|
|
|
if (sofia_test_pflag(tech_pvt->profile, PFLAG_AUTO_NAT)) {
|
2012-12-22 08:36:15 -06:00
|
|
|
if (!zstr(tech_pvt->mparams.remote_ip) && !zstr(tech_pvt->profile->extsipip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->mparams.remote_ip)) {
|
2010-01-22 23:37:50 +00:00
|
|
|
rpid_domain = tech_pvt->profile->extsipip;
|
|
|
|
} else {
|
|
|
|
rpid_domain = tech_pvt->profile->sipip;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-09-15 19:46:15 -05:00
|
|
|
if (!zstr(invite_domain)) {
|
|
|
|
rpid_domain = (char *)invite_domain;
|
|
|
|
}
|
|
|
|
|
2010-06-14 13:42:06 -05:00
|
|
|
if (zstr(rpid_domain)) {
|
|
|
|
rpid_domain = "cluecon.com";
|
|
|
|
}
|
|
|
|
|
2008-01-17 17:37:49 +00:00
|
|
|
/*
|
|
|
|
* Ignore transport chanvar and uri parameter for gateway connections
|
|
|
|
* since all of them have been already taken care of in mod_sofia.c:sofia_outgoing_channel()
|
|
|
|
*/
|
2009-10-23 16:03:42 +00:00
|
|
|
if (tech_pvt->transport == SOFIA_TRANSPORT_UNKNOWN && zstr(tech_pvt->gateway_name)) {
|
2008-05-27 04:54:52 +00:00
|
|
|
if ((p = (char *) switch_stristr("port=", url))) {
|
2008-01-17 17:37:49 +00:00
|
|
|
p += 5;
|
2008-05-27 04:54:52 +00:00
|
|
|
tech_pvt->transport = sofia_glue_str2transport(p);
|
2008-01-17 17:37:49 +00:00
|
|
|
} else {
|
|
|
|
if ((t_var = switch_channel_get_variable(channel, "sip_transport"))) {
|
|
|
|
tech_pvt->transport = sofia_glue_str2transport(t_var);
|
|
|
|
}
|
2007-10-23 03:00:15 +00:00
|
|
|
}
|
|
|
|
|
2008-01-17 17:37:49 +00:00
|
|
|
if (tech_pvt->transport == SOFIA_TRANSPORT_UNKNOWN) {
|
|
|
|
tech_pvt->transport = SOFIA_TRANSPORT_UDP;
|
|
|
|
}
|
2007-12-18 22:06:20 +00:00
|
|
|
}
|
2009-06-25 15:40:38 +00:00
|
|
|
|
2012-12-22 08:36:15 -06:00
|
|
|
if (!zstr(tech_pvt->mparams.remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->mparams.remote_ip)) {
|
2009-06-03 21:08:34 +00:00
|
|
|
tech_pvt->user_via = sofia_glue_create_external_via(session, tech_pvt->profile, tech_pvt->transport);
|
|
|
|
}
|
2007-12-18 22:06:20 +00:00
|
|
|
|
2008-02-21 17:48:41 +00:00
|
|
|
if (!sofia_test_pflag(tech_pvt->profile, PFLAG_TLS) && sofia_glue_transport_has_tls(tech_pvt->transport)) {
|
2009-08-13 20:35:02 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "TLS not supported by profile\n");
|
2008-01-18 21:13:52 +00:00
|
|
|
return SWITCH_STATUS_FALSE;
|
2008-02-21 17:48:41 +00:00
|
|
|
}
|
2008-01-18 21:13:52 +00:00
|
|
|
|
2009-10-23 16:03:42 +00:00
|
|
|
if (zstr(tech_pvt->invite_contact)) {
|
2010-02-06 03:38:24 +00:00
|
|
|
const char *contact;
|
2008-07-28 17:09:51 +00:00
|
|
|
if ((contact = switch_channel_get_variable(channel, "sip_contact_user"))) {
|
2011-08-26 13:51:41 -05:00
|
|
|
char *ip_addr = tech_pvt->profile->sipip;
|
2009-06-03 21:08:34 +00:00
|
|
|
char *ipv6;
|
2010-01-22 23:37:50 +00:00
|
|
|
|
2012-12-22 08:36:15 -06:00
|
|
|
if ( !zstr(tech_pvt->mparams.remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->mparams.remote_ip ) ) {
|
2011-08-26 13:51:41 -05:00
|
|
|
ip_addr = tech_pvt->profile->extsipip;
|
2009-06-03 21:08:34 +00:00
|
|
|
}
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2009-06-03 21:08:34 +00:00
|
|
|
ipv6 = strchr(ip_addr, ':');
|
|
|
|
|
2008-07-28 17:09:51 +00:00
|
|
|
if (sofia_glue_transport_has_tls(tech_pvt->transport)) {
|
2010-02-06 03:38:24 +00:00
|
|
|
tech_pvt->invite_contact = switch_core_session_sprintf(session, "sip:%s@%s%s%s:%d", contact,
|
|
|
|
ipv6 ? "[" : "", ip_addr, ipv6 ? "]" : "", tech_pvt->profile->tls_sip_port);
|
2008-07-28 17:09:51 +00:00
|
|
|
} else {
|
2010-02-06 03:38:24 +00:00
|
|
|
tech_pvt->invite_contact = switch_core_session_sprintf(session, "sip:%s@%s%s%s:%d", contact,
|
2012-12-07 10:29:44 -06:00
|
|
|
ipv6 ? "[" : "", ip_addr, ipv6 ? "]" : "", tech_pvt->profile->extsipport);
|
2008-07-28 17:09:51 +00:00
|
|
|
}
|
2008-02-21 17:48:41 +00:00
|
|
|
} else {
|
2008-07-28 17:09:51 +00:00
|
|
|
if (sofia_glue_transport_has_tls(tech_pvt->transport)) {
|
|
|
|
tech_pvt->invite_contact = tech_pvt->profile->tls_url;
|
|
|
|
} else {
|
2012-12-22 08:36:15 -06:00
|
|
|
if (!zstr(tech_pvt->mparams.remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->mparams.remote_ip)) {
|
2009-06-03 21:08:34 +00:00
|
|
|
tech_pvt->invite_contact = tech_pvt->profile->public_url;
|
|
|
|
} else {
|
|
|
|
tech_pvt->invite_contact = tech_pvt->profile->url;
|
|
|
|
}
|
2008-07-28 17:09:51 +00:00
|
|
|
}
|
2008-02-21 17:48:41 +00:00
|
|
|
}
|
2007-12-18 19:12:45 +00:00
|
|
|
}
|
|
|
|
|
2013-02-27 09:04:51 -06:00
|
|
|
url_str = sofia_overcome_sip_uri_weakness(session, url, tech_pvt->transport, SWITCH_TRUE, invite_params, invite_tel_params);
|
|
|
|
invite_contact = sofia_overcome_sip_uri_weakness(session, tech_pvt->invite_contact, tech_pvt->transport, SWITCH_FALSE, invite_contact_params, NULL);
|
|
|
|
from_str = sofia_overcome_sip_uri_weakness(session, invite_from_uri ? invite_from_uri : use_from_str, 0, SWITCH_TRUE, invite_from_params, NULL);
|
|
|
|
to_str = sofia_overcome_sip_uri_weakness(session, invite_to_uri ? invite_to_uri : tech_pvt->dest_to, 0, SWITCH_FALSE, invite_to_params, NULL);
|
2008-05-27 04:54:52 +00:00
|
|
|
|
2010-02-06 03:38:24 +00:00
|
|
|
switch_channel_set_variable(channel, "sip_outgoing_contact_uri", invite_contact);
|
|
|
|
|
2007-12-18 19:12:45 +00:00
|
|
|
/*
|
2010-06-23 13:22:52 -05:00
|
|
|
Does the "genius" who wanted SIP to be "text-based" so it was "easier to read" even use it now,
|
|
|
|
or did he just suggest it to make our lives miserable?
|
|
|
|
*/
|
2007-11-19 17:09:46 +00:00
|
|
|
use_from_str = from_str;
|
2010-02-06 03:38:24 +00:00
|
|
|
|
|
|
|
if (!switch_stristr("sip:", use_from_str)) {
|
|
|
|
use_from_str = switch_core_session_sprintf(session, "sip:%s", use_from_str);
|
|
|
|
}
|
|
|
|
|
2009-03-11 15:14:24 +00:00
|
|
|
if (!from_display && !strcasecmp(tech_pvt->caller_profile->caller_id_name, "_undef_")) {
|
2008-11-24 23:12:36 +00:00
|
|
|
from_str = switch_core_session_sprintf(session, "<%s>", use_from_str);
|
|
|
|
} else {
|
2011-04-14 19:09:11 -04:00
|
|
|
char *name = switch_core_session_strdup(session, from_display ? from_display : tech_pvt->caller_profile->caller_id_name);
|
|
|
|
check_decode(name, session);
|
|
|
|
from_str = switch_core_session_sprintf(session, "\"%s\" <%s>", name, use_from_str);
|
2008-11-24 23:12:36 +00:00
|
|
|
}
|
2010-02-06 03:38:24 +00:00
|
|
|
|
|
|
|
if (!(call_id = switch_channel_get_variable(channel, "sip_invite_call_id"))) {
|
2009-02-09 17:56:38 +00:00
|
|
|
if (sofia_test_pflag(tech_pvt->profile, PFLAG_UUID_AS_CALLID)) {
|
2008-11-15 17:44:27 +00:00
|
|
|
call_id = switch_core_session_get_uuid(session);
|
|
|
|
}
|
2008-11-15 02:46:25 +00:00
|
|
|
}
|
2010-01-22 23:37:50 +00:00
|
|
|
|
2010-02-06 03:38:24 +00:00
|
|
|
if (handle_full_from) {
|
|
|
|
from_str = (char *) handle_full_from;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (handle_full_to) {
|
|
|
|
to_str = (char *) handle_full_to;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2011-04-03 12:03:29 -05:00
|
|
|
if (force_full_from) {
|
|
|
|
from_str = (char *) force_full_from;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (force_full_to) {
|
|
|
|
to_str = (char *) force_full_to;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-02-06 03:38:24 +00:00
|
|
|
if (invite_req_uri) {
|
|
|
|
url_str = (char *) invite_req_uri;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (url_str) {
|
|
|
|
char *s = NULL;
|
|
|
|
if (!strncasecmp(url_str, "sip:", 4)) {
|
|
|
|
s = url_str + 4;
|
|
|
|
}
|
|
|
|
if (!strncasecmp(url_str, "sips:", 5)) {
|
|
|
|
s = url_str + 5;
|
|
|
|
}
|
2011-05-09 09:41:50 -07:00
|
|
|
|
|
|
|
/* tel: patch from jaybinks, added by MC
|
|
|
|
It compiles but I don't have a way to test it
|
|
|
|
*/
|
|
|
|
if (!strncasecmp(url_str, "tel:", 4)) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session),
|
|
|
|
SWITCH_LOG_ERROR, "URL Error! tel: uri's not supported at this time\n");
|
|
|
|
return SWITCH_STATUS_FALSE;
|
|
|
|
}
|
2010-02-06 03:38:24 +00:00
|
|
|
if (!s) {
|
|
|
|
s = url_str;
|
|
|
|
}
|
|
|
|
switch_channel_set_variable(channel, "sip_req_uri", s);
|
|
|
|
}
|
2011-11-22 17:59:04 -06:00
|
|
|
|
|
|
|
switch_channel_set_variable(channel, "sip_to_host", sofia_glue_get_host(to_str, switch_core_session_get_pool(session)));
|
|
|
|
switch_channel_set_variable(channel, "sip_from_host", sofia_glue_get_host(from_str, switch_core_session_get_pool(session)));
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2010-09-24 15:14:49 -05:00
|
|
|
if (!(tech_pvt->nh = nua_handle(tech_pvt->profile->nua, NULL,
|
|
|
|
NUTAG_URL(url_str),
|
|
|
|
TAG_IF(call_id, SIPTAG_CALL_ID_STR(call_id)),
|
2011-11-10 15:16:53 -06:00
|
|
|
TAG_IF(!zstr(record_route), SIPTAG_HEADER_STR(record_route)),
|
2010-09-24 15:14:49 -05:00
|
|
|
SIPTAG_TO_STR(to_str), SIPTAG_FROM_STR(from_str), SIPTAG_CONTACT_STR(invite_contact), TAG_END()))) {
|
|
|
|
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT,
|
|
|
|
"Error creating HANDLE!\nurl_str=[%s]\ncall_id=[%s]\nto_str=[%s]\nfrom_str=[%s]\ninvite_contact=[%s]\n",
|
|
|
|
url_str,
|
|
|
|
call_id ? call_id : "N/A",
|
|
|
|
to_str,
|
|
|
|
from_str,
|
|
|
|
invite_contact);
|
|
|
|
|
|
|
|
switch_safe_free(d_url);
|
|
|
|
return SWITCH_STATUS_FALSE;
|
|
|
|
}
|
2007-03-31 19:01:33 +00:00
|
|
|
|
2010-02-06 03:38:24 +00:00
|
|
|
if (tech_pvt->dest && (strstr(tech_pvt->dest, ";fs_nat") || strstr(tech_pvt->dest, ";received")
|
2008-07-03 16:48:05 +00:00
|
|
|
|| ((val = switch_channel_get_variable(channel, "sip_sticky_contact")) && switch_true(val)))) {
|
2009-02-09 17:56:38 +00:00
|
|
|
sofia_set_flag(tech_pvt, TFLAG_NAT);
|
2008-05-13 23:22:21 +00:00
|
|
|
tech_pvt->record_route = switch_core_session_strdup(tech_pvt->session, url_str);
|
2008-06-26 20:19:09 +00:00
|
|
|
route_uri = tech_pvt->record_route;
|
2008-05-14 14:13:40 +00:00
|
|
|
session_timeout = SOFIA_NAT_SESSION_TIMEOUT;
|
|
|
|
switch_channel_set_variable(channel, "sip_nat_detected", "true");
|
2008-05-13 23:22:21 +00:00
|
|
|
}
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2009-03-04 23:03:25 +00:00
|
|
|
if ((val = switch_channel_get_variable(channel, "sip_cid_type"))) {
|
|
|
|
cid_type = sofia_cid_name2type(val);
|
2010-06-23 13:22:52 -05:00
|
|
|
}
|
2009-11-15 02:16:10 +00:00
|
|
|
|
2012-08-22 16:27:02 -05:00
|
|
|
if (switch_channel_test_flag(tech_pvt->channel, CF_RECOVERING) && switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_INBOUND) {
|
2010-02-06 03:38:24 +00:00
|
|
|
if (zstr((use_name = switch_channel_get_variable(tech_pvt->channel, "effective_callee_id_name"))) &&
|
|
|
|
zstr((use_name = switch_channel_get_variable(tech_pvt->channel, "sip_callee_id_name")))) {
|
|
|
|
if (!(use_name = switch_channel_get_variable(tech_pvt->channel, "sip_to_display"))) {
|
|
|
|
use_name = switch_channel_get_variable(tech_pvt->channel, "sip_to_user");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (zstr((use_number = switch_channel_get_variable(tech_pvt->channel, "effective_callee_id_number"))) &&
|
|
|
|
zstr((use_number = switch_channel_get_variable(tech_pvt->channel, "sip_callee_id_number")))) {
|
|
|
|
use_number = switch_channel_get_variable(tech_pvt->channel, "sip_to_user");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (zstr(use_name) && zstr(use_name = tech_pvt->caller_profile->callee_id_name)) {
|
|
|
|
use_name = tech_pvt->caller_profile->caller_id_name;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (zstr(use_number) && zstr(use_number = tech_pvt->caller_profile->callee_id_number)) {
|
|
|
|
use_number = tech_pvt->caller_profile->caller_id_number;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
use_name = tech_pvt->caller_profile->caller_id_name;
|
|
|
|
use_number = tech_pvt->caller_profile->caller_id_number;
|
|
|
|
}
|
|
|
|
|
2011-09-27 15:38:40 -05:00
|
|
|
check_decode(use_name, session);
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2009-03-04 23:03:25 +00:00
|
|
|
switch (cid_type) {
|
|
|
|
case CID_TYPE_PID:
|
|
|
|
if (switch_test_flag(caller_profile, SWITCH_CPF_SCREEN)) {
|
2012-04-02 14:37:40 -05:00
|
|
|
if (zstr(tech_pvt->caller_profile->caller_id_name) || !strcasecmp(tech_pvt->caller_profile->caller_id_name, "_undef_")) {
|
|
|
|
tech_pvt->asserted_id = switch_core_session_sprintf(tech_pvt->session, "<sip:%s@%s>",
|
|
|
|
use_number, rpid_domain);
|
|
|
|
} else {
|
|
|
|
tech_pvt->asserted_id = switch_core_session_sprintf(tech_pvt->session, "\"%s\"<sip:%s@%s>",
|
|
|
|
use_name, use_number, rpid_domain);
|
|
|
|
}
|
2009-03-04 23:03:25 +00:00
|
|
|
} else {
|
2012-04-02 14:37:40 -05:00
|
|
|
if (zstr(tech_pvt->caller_profile->caller_id_name) || !strcasecmp(tech_pvt->caller_profile->caller_id_name, "_undef_")) {
|
|
|
|
tech_pvt->preferred_id = switch_core_session_sprintf(tech_pvt->session, "<sip:%s@%s>",
|
|
|
|
tech_pvt->caller_profile->caller_id_number, rpid_domain);
|
|
|
|
} else {
|
|
|
|
tech_pvt->preferred_id = switch_core_session_sprintf(tech_pvt->session, "\"%s\"<sip:%s@%s>",
|
|
|
|
tech_pvt->caller_profile->caller_id_name,
|
|
|
|
tech_pvt->caller_profile->caller_id_number, rpid_domain);
|
|
|
|
}
|
2009-03-04 23:03:25 +00:00
|
|
|
}
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2009-02-11 20:49:45 +00:00
|
|
|
if (switch_test_flag(caller_profile, SWITCH_CPF_HIDE_NUMBER)) {
|
2009-03-04 23:03:25 +00:00
|
|
|
tech_pvt->privacy = "id";
|
|
|
|
} else {
|
2014-09-11 19:44:36 +00:00
|
|
|
if (!(val = switch_channel_get_variable(channel, "sip_cid_suppress_privacy_none")) || !switch_true(val)) {
|
|
|
|
tech_pvt->privacy = "none";
|
|
|
|
}
|
2007-11-21 00:56:41 +00:00
|
|
|
}
|
2008-02-21 17:48:41 +00:00
|
|
|
|
2009-03-04 23:03:25 +00:00
|
|
|
break;
|
|
|
|
case CID_TYPE_RPID:
|
|
|
|
{
|
|
|
|
if (switch_test_flag(caller_profile, SWITCH_CPF_HIDE_NAME)) {
|
|
|
|
priv = "name";
|
|
|
|
if (switch_test_flag(caller_profile, SWITCH_CPF_HIDE_NUMBER)) {
|
|
|
|
priv = "full";
|
|
|
|
}
|
|
|
|
} else if (switch_test_flag(caller_profile, SWITCH_CPF_HIDE_NUMBER)) {
|
|
|
|
priv = "full";
|
|
|
|
}
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2009-03-04 23:03:25 +00:00
|
|
|
if (switch_test_flag(caller_profile, SWITCH_CPF_SCREEN)) {
|
|
|
|
screen = "yes";
|
|
|
|
}
|
2010-02-06 03:38:24 +00:00
|
|
|
|
|
|
|
if (zstr(tech_pvt->caller_profile->caller_id_name) || !strcasecmp(tech_pvt->caller_profile->caller_id_name, "_undef_")) {
|
2009-11-11 03:53:50 +00:00
|
|
|
tech_pvt->rpid = switch_core_session_sprintf(tech_pvt->session, "<sip:%s@%s>;party=calling;screen=%s;privacy=%s",
|
2010-02-06 03:38:24 +00:00
|
|
|
use_number, rpid_domain, screen, priv);
|
2009-11-11 03:53:50 +00:00
|
|
|
} else {
|
|
|
|
tech_pvt->rpid = switch_core_session_sprintf(tech_pvt->session, "\"%s\"<sip:%s@%s>;party=calling;screen=%s;privacy=%s",
|
2010-02-06 03:38:24 +00:00
|
|
|
use_name, use_number, rpid_domain, screen, priv);
|
2009-11-11 03:53:50 +00:00
|
|
|
}
|
2009-03-04 23:03:25 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
break;
|
2007-11-26 16:18:50 +00:00
|
|
|
}
|
|
|
|
|
2007-11-21 00:56:41 +00:00
|
|
|
|
2007-09-23 20:08:26 +00:00
|
|
|
switch_safe_free(d_url);
|
2008-05-27 04:54:52 +00:00
|
|
|
|
2011-06-16 14:37:22 -05:00
|
|
|
if (!(sofia_private = su_alloc(tech_pvt->nh->nh_home, sizeof(*sofia_private)))) {
|
2007-03-31 19:01:33 +00:00
|
|
|
abort();
|
|
|
|
}
|
2008-07-29 17:54:42 +00:00
|
|
|
|
2007-10-03 23:42:40 +00:00
|
|
|
memset(sofia_private, 0, sizeof(*sofia_private));
|
2012-09-17 20:02:14 -05:00
|
|
|
sofia_private->is_call = 2;
|
2011-07-16 11:30:36 -05:00
|
|
|
sofia_private->is_static++;
|
2011-07-16 01:02:22 -05:00
|
|
|
|
2012-08-22 16:27:02 -05:00
|
|
|
if (switch_channel_test_flag(tech_pvt->channel, CF_RECOVERING)) {
|
2012-08-22 15:51:35 -05:00
|
|
|
sofia_private->is_call++;
|
|
|
|
}
|
|
|
|
|
2007-10-03 23:42:40 +00:00
|
|
|
tech_pvt->sofia_private = sofia_private;
|
2007-03-31 19:01:33 +00:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2010-08-18 14:58:14 -05:00
|
|
|
if (tech_pvt->e_dest && sofia_test_pflag(tech_pvt->profile, PFLAG_IN_DIALOG_CHAT)) {
|
2007-09-23 20:08:26 +00:00
|
|
|
char *user = NULL, *host = NULL;
|
2007-03-31 19:01:33 +00:00
|
|
|
char hash_key[256] = "";
|
|
|
|
|
2007-09-23 20:08:26 +00:00
|
|
|
e_dest = strdup(tech_pvt->e_dest);
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(e_dest != NULL);
|
2007-09-23 20:08:26 +00:00
|
|
|
user = e_dest;
|
2008-05-27 04:54:52 +00:00
|
|
|
|
2007-03-31 19:01:33 +00:00
|
|
|
if ((host = strchr(user, '@'))) {
|
|
|
|
*host++ = '\0';
|
|
|
|
}
|
2007-12-12 21:53:32 +00:00
|
|
|
switch_snprintf(hash_key, sizeof(hash_key), "%s%s%s", user, host, cid_num);
|
2007-03-31 19:01:33 +00:00
|
|
|
|
|
|
|
tech_pvt->chat_from = tech_pvt->from_str;
|
|
|
|
tech_pvt->chat_to = tech_pvt->dest;
|
2008-09-18 00:01:03 +00:00
|
|
|
if (tech_pvt->profile->pres_type) {
|
2008-09-16 20:04:33 +00:00
|
|
|
tech_pvt->hash_key = switch_core_session_strdup(tech_pvt->session, hash_key);
|
|
|
|
switch_mutex_lock(tech_pvt->profile->flag_mutex);
|
|
|
|
switch_core_hash_insert(tech_pvt->profile->chat_hash, tech_pvt->hash_key, tech_pvt);
|
|
|
|
switch_mutex_unlock(tech_pvt->profile->flag_mutex);
|
|
|
|
}
|
2007-03-31 19:01:33 +00:00
|
|
|
free(e_dest);
|
|
|
|
}
|
|
|
|
|
2009-02-09 17:56:38 +00:00
|
|
|
holdstr = sofia_test_flag(tech_pvt, TFLAG_SIP_HOLD) ? "*" : "";
|
2007-03-31 19:01:33 +00:00
|
|
|
|
2007-09-21 19:20:15 +00:00
|
|
|
if (!switch_channel_get_variable(channel, "sofia_profile_name")) {
|
|
|
|
switch_channel_set_variable(channel, "sofia_profile_name", tech_pvt->profile->name);
|
2012-08-22 16:27:02 -05:00
|
|
|
switch_channel_set_variable(channel, "recovery_profile_name", tech_pvt->profile->name);
|
2007-09-21 19:20:15 +00:00
|
|
|
}
|
2007-03-31 19:01:33 +00:00
|
|
|
|
2009-08-11 00:54:39 +00:00
|
|
|
extra_headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_HEADER_PREFIX);
|
2008-05-27 04:54:52 +00:00
|
|
|
|
2008-02-02 20:55:15 +00:00
|
|
|
session_timeout = tech_pvt->profile->session_timeout;
|
2011-08-22 10:59:33 -05:00
|
|
|
|
2007-10-19 21:06:09 +00:00
|
|
|
if ((val = switch_channel_get_variable(channel, SOFIA_SESSION_TIMEOUT))) {
|
|
|
|
int v_session_timeout = atoi(val);
|
|
|
|
if (v_session_timeout >= 0) {
|
|
|
|
session_timeout = v_session_timeout;
|
|
|
|
}
|
|
|
|
}
|
2007-03-31 19:01:33 +00:00
|
|
|
|
2008-02-21 17:48:41 +00:00
|
|
|
if (switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
|
2012-12-22 16:54:35 -06:00
|
|
|
if (switch_core_media_ready(tech_pvt->session, SWITCH_MEDIA_TYPE_AUDIO)) {
|
2012-12-21 21:30:14 -06:00
|
|
|
switch_core_media_proxy_remote_addr(session, NULL);
|
2008-02-22 15:27:40 +00:00
|
|
|
}
|
2012-12-21 23:56:53 -06:00
|
|
|
switch_core_media_patch_sdp(tech_pvt->session);
|
2008-02-21 17:48:41 +00:00
|
|
|
}
|
|
|
|
|
2009-10-23 16:03:42 +00:00
|
|
|
if (!zstr(tech_pvt->dest)) {
|
2009-06-22 18:37:07 +00:00
|
|
|
dst = sofia_glue_get_destination(tech_pvt->dest);
|
2008-06-27 16:01:40 +00:00
|
|
|
|
2009-06-22 18:37:07 +00:00
|
|
|
if (dst->route_uri) {
|
2013-02-27 09:04:51 -06:00
|
|
|
route_uri = sofia_overcome_sip_uri_weakness(tech_pvt->session, dst->route_uri, tech_pvt->transport, SWITCH_TRUE, NULL, NULL);
|
2009-06-22 18:37:07 +00:00
|
|
|
}
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2009-06-22 18:37:07 +00:00
|
|
|
if (dst->route) {
|
|
|
|
route = dst->route;
|
|
|
|
}
|
2008-10-21 18:14:37 +00:00
|
|
|
}
|
|
|
|
|
2009-03-04 16:02:02 +00:00
|
|
|
if ((val = switch_channel_get_variable(channel, "sip_route_uri"))) {
|
|
|
|
route_uri = switch_core_session_strdup(session, val);
|
|
|
|
route = NULL;
|
|
|
|
}
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2008-10-21 18:14:37 +00:00
|
|
|
if (route_uri) {
|
2010-02-06 03:38:24 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "%s Setting proxy route to %s\n", route_uri,
|
|
|
|
switch_channel_get_name(channel));
|
2009-05-20 20:51:35 +00:00
|
|
|
tech_pvt->route_uri = switch_core_session_strdup(tech_pvt->session, route_uri);
|
2008-06-26 20:19:09 +00:00
|
|
|
}
|
|
|
|
|
2010-02-06 03:38:24 +00:00
|
|
|
|
|
|
|
if ((val = switch_channel_get_variable(tech_pvt->channel, "sip_invite_cseq"))) {
|
|
|
|
uint32_t callsequence = (uint32_t) strtoul(val, NULL, 10);
|
|
|
|
cseq = sip_cseq_create(tech_pvt->nh->nh_home, callsequence, SIP_METHOD_INVITE);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-01-22 00:51:32 +00:00
|
|
|
switch_channel_clear_flag(channel, CF_MEDIA_ACK);
|
|
|
|
|
2010-02-06 03:38:24 +00:00
|
|
|
if (handle_full_from) {
|
|
|
|
tech_pvt->nh->nh_has_invite = 1;
|
|
|
|
}
|
|
|
|
|
2013-08-08 22:55:04 +05:00
|
|
|
if ((mp = sofia_media_get_multipart(session, "sip_multipart", tech_pvt->mparams.local_sdp_str, &mp_type))) {
|
2010-06-01 17:13:22 -05:00
|
|
|
sofia_clear_flag(tech_pvt, TFLAG_ENABLE_SOA);
|
|
|
|
}
|
2010-06-23 13:22:52 -05:00
|
|
|
|
2011-08-22 10:59:33 -05:00
|
|
|
if ((tech_pvt->session_timeout = session_timeout)) {
|
|
|
|
tech_pvt->session_refresher = switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND ? nua_local_refresher : nua_remote_refresher;
|
|
|
|
} else {
|
|
|
|
tech_pvt->session_refresher = nua_no_refresher;
|
2010-09-08 22:53:57 -05:00
|
|
|
}
|
2012-03-02 16:42:05 -06:00
|
|
|
|
2014-01-20 23:34:32 +05:00
|
|
|
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "%s sending invite version: %s\nLocal SDP:\n%s\n",
|
|
|
|
switch_channel_get_name(tech_pvt->channel), switch_version_full_human(),
|
|
|
|
tech_pvt->mparams.local_sdp_str ? tech_pvt->mparams.local_sdp_str : "NO SDP PRESENT\n");
|
2012-06-07 19:49:30 +00:00
|
|
|
|
2014-11-06 17:13:02 -06:00
|
|
|
|
2013-07-23 13:52:49 -05:00
|
|
|
|
2015-02-24 16:43:24 +01:00
|
|
|
if ((switch_channel_get_private(tech_pvt->channel, "t38_options")) ||
|
2015-05-20 14:52:23 -05:00
|
|
|
((sofia_test_flag(tech_pvt, TFLAG_INB_NOMEDIA) ||
|
|
|
|
sofia_test_flag(tech_pvt, TFLAG_PROXY_MEDIA) ||
|
|
|
|
switch_true(switch_channel_get_variable(tech_pvt->channel, SWITCH_BYPASS_MEDIA_VARIABLE)) )
|
2015-02-24 16:43:24 +01:00
|
|
|
&& switch_stristr("m=image", tech_pvt->mparams.local_sdp_str))) {
|
2014-11-06 18:26:16 -06:00
|
|
|
sofia_clear_flag(tech_pvt, TFLAG_ENABLE_SOA);
|
2015-02-24 16:43:24 +01:00
|
|
|
is_t38 = 1;
|
|
|
|
}
|
2014-11-06 18:26:16 -06:00
|
|
|
|
2010-01-07 05:22:02 +00:00
|
|
|
if (sofia_use_soa(tech_pvt)) {
|
|
|
|
nua_invite(tech_pvt->nh,
|
|
|
|
NUTAG_AUTOANSWER(0),
|
2012-12-22 08:36:15 -06:00
|
|
|
//TAG_IF(zstr(tech_pvt->mparams.local_sdp_str), NUTAG_AUTOACK(0)),
|
|
|
|
//TAG_IF(!zstr(tech_pvt->mparams.local_sdp_str), NUTAG_AUTOACK(1)),
|
2011-08-04 00:01:26 -05:00
|
|
|
// The code above is breaking things...... grrr WE need this because we handle our own acks and there are 3pcc cases in there too
|
|
|
|
NUTAG_AUTOACK(0),
|
2011-08-22 10:59:33 -05:00
|
|
|
NUTAG_SESSION_TIMER(tech_pvt->session_timeout),
|
|
|
|
NUTAG_SESSION_REFRESHER(tech_pvt->session_refresher),
|
2010-09-08 15:32:34 -05:00
|
|
|
TAG_IF(sofia_test_flag(tech_pvt, TFLAG_RECOVERED), NUTAG_INVITE_TIMER(UINT_MAX)),
|
2010-02-06 03:38:24 +00:00
|
|
|
TAG_IF(invite_full_from, SIPTAG_FROM_STR(invite_full_from)),
|
|
|
|
TAG_IF(invite_full_to, SIPTAG_TO_STR(invite_full_to)),
|
2010-01-07 05:22:02 +00:00
|
|
|
TAG_IF(tech_pvt->redirected, NUTAG_URL(tech_pvt->redirected)),
|
2011-11-28 16:11:09 -06:00
|
|
|
TAG_IF(!zstr(recover_via), SIPTAG_VIA_STR(recover_via)),
|
2012-04-03 13:29:39 -05:00
|
|
|
TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
|
2010-01-07 05:22:02 +00:00
|
|
|
TAG_IF(!zstr(tech_pvt->rpid), SIPTAG_REMOTE_PARTY_ID_STR(tech_pvt->rpid)),
|
|
|
|
TAG_IF(!zstr(tech_pvt->preferred_id), SIPTAG_P_PREFERRED_IDENTITY_STR(tech_pvt->preferred_id)),
|
|
|
|
TAG_IF(!zstr(tech_pvt->asserted_id), SIPTAG_P_ASSERTED_IDENTITY_STR(tech_pvt->asserted_id)),
|
|
|
|
TAG_IF(!zstr(tech_pvt->privacy), SIPTAG_PRIVACY_STR(tech_pvt->privacy)),
|
|
|
|
TAG_IF(!zstr(alert_info), SIPTAG_HEADER_STR(alert_info)),
|
|
|
|
TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)),
|
2010-02-06 03:38:24 +00:00
|
|
|
TAG_IF(sofia_test_pflag(tech_pvt->profile, PFLAG_PASS_CALLEE_ID), SIPTAG_HEADER_STR("X-FS-Support: " FREESWITCH_SUPPORT)),
|
2010-01-07 05:22:02 +00:00
|
|
|
TAG_IF(!zstr(max_forwards), SIPTAG_MAX_FORWARDS_STR(max_forwards)),
|
|
|
|
TAG_IF(!zstr(route_uri), NUTAG_PROXY(route_uri)),
|
2010-02-06 03:38:24 +00:00
|
|
|
TAG_IF(!zstr(invite_route_uri), NUTAG_INITIAL_ROUTE_STR(invite_route_uri)),
|
2010-01-07 05:22:02 +00:00
|
|
|
TAG_IF(!zstr(route), SIPTAG_ROUTE_STR(route)),
|
|
|
|
TAG_IF(tech_pvt->profile->minimum_session_expires, NUTAG_MIN_SE(tech_pvt->profile->minimum_session_expires)),
|
2010-02-06 03:38:24 +00:00
|
|
|
TAG_IF(cseq, SIPTAG_CSEQ(cseq)),
|
2014-03-06 00:01:02 +05:00
|
|
|
TAG_IF(content_encoding, SIPTAG_CONTENT_ENCODING_STR(content_encoding)),
|
2012-12-22 08:36:15 -06:00
|
|
|
TAG_IF(zstr(tech_pvt->mparams.local_sdp_str), SIPTAG_PAYLOAD_STR("")),
|
|
|
|
TAG_IF(!zstr(tech_pvt->mparams.local_sdp_str), SOATAG_ADDRESS(tech_pvt->mparams.adv_sdp_audio_ip)),
|
|
|
|
TAG_IF(!zstr(tech_pvt->mparams.local_sdp_str), SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str)),
|
|
|
|
TAG_IF(!zstr(tech_pvt->mparams.local_sdp_str), SOATAG_REUSE_REJECTED(1)),
|
2015-02-24 16:43:24 +01:00
|
|
|
TAG_IF(is_t38, SOATAG_ORDERED_USER(1)),
|
2012-12-22 08:36:15 -06:00
|
|
|
TAG_IF(!zstr(tech_pvt->mparams.local_sdp_str), SOATAG_RTP_SORT(SOA_RTP_SORT_REMOTE)),
|
|
|
|
TAG_IF(!zstr(tech_pvt->mparams.local_sdp_str), SOATAG_RTP_SELECT(SOA_RTP_SELECT_ALL)),
|
2011-06-15 10:29:07 -05:00
|
|
|
TAG_IF(rep, SIPTAG_REPLACES_STR(rep)),
|
2012-04-26 10:35:02 -05:00
|
|
|
TAG_IF(!require_timer, NUTAG_TIMER_AUTOREQUIRE(0)),
|
2012-12-22 08:36:15 -06:00
|
|
|
TAG_IF(!zstr(tech_pvt->mparams.local_sdp_str), SOATAG_HOLD(holdstr)), TAG_END());
|
2010-01-07 05:22:02 +00:00
|
|
|
} else {
|
|
|
|
nua_invite(tech_pvt->nh,
|
|
|
|
NUTAG_AUTOANSWER(0),
|
2011-06-15 10:29:07 -05:00
|
|
|
NUTAG_AUTOACK(0),
|
2011-08-22 10:59:33 -05:00
|
|
|
NUTAG_SESSION_TIMER(tech_pvt->session_timeout),
|
|
|
|
NUTAG_SESSION_REFRESHER(tech_pvt->session_refresher),
|
2010-09-08 15:32:34 -05:00
|
|
|
TAG_IF(sofia_test_flag(tech_pvt, TFLAG_RECOVERED), NUTAG_INVITE_TIMER(UINT_MAX)),
|
2010-02-06 03:38:24 +00:00
|
|
|
TAG_IF(invite_full_from, SIPTAG_FROM_STR(invite_full_from)),
|
|
|
|
TAG_IF(invite_full_to, SIPTAG_TO_STR(invite_full_to)),
|
2010-01-07 05:22:02 +00:00
|
|
|
TAG_IF(tech_pvt->redirected, NUTAG_URL(tech_pvt->redirected)),
|
2011-11-28 16:11:09 -06:00
|
|
|
TAG_IF(!zstr(recover_via), SIPTAG_VIA_STR(recover_via)),
|
2012-04-03 13:29:39 -05:00
|
|
|
TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
|
2010-01-07 05:22:02 +00:00
|
|
|
TAG_IF(!zstr(tech_pvt->rpid), SIPTAG_REMOTE_PARTY_ID_STR(tech_pvt->rpid)),
|
|
|
|
TAG_IF(!zstr(tech_pvt->preferred_id), SIPTAG_P_PREFERRED_IDENTITY_STR(tech_pvt->preferred_id)),
|
|
|
|
TAG_IF(!zstr(tech_pvt->asserted_id), SIPTAG_P_ASSERTED_IDENTITY_STR(tech_pvt->asserted_id)),
|
|
|
|
TAG_IF(!zstr(tech_pvt->privacy), SIPTAG_PRIVACY_STR(tech_pvt->privacy)),
|
|
|
|
TAG_IF(!zstr(alert_info), SIPTAG_HEADER_STR(alert_info)),
|
|
|
|
TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)),
|
2010-02-06 03:38:24 +00:00
|
|
|
TAG_IF(sofia_test_pflag(tech_pvt->profile, PFLAG_PASS_CALLEE_ID), SIPTAG_HEADER_STR("X-FS-Support: " FREESWITCH_SUPPORT)),
|
2010-01-07 05:22:02 +00:00
|
|
|
TAG_IF(!zstr(max_forwards), SIPTAG_MAX_FORWARDS_STR(max_forwards)),
|
|
|
|
TAG_IF(!zstr(route_uri), NUTAG_PROXY(route_uri)),
|
|
|
|
TAG_IF(!zstr(route), SIPTAG_ROUTE_STR(route)),
|
2010-02-06 03:38:24 +00:00
|
|
|
TAG_IF(!zstr(invite_route_uri), NUTAG_INITIAL_ROUTE_STR(invite_route_uri)),
|
2010-01-07 05:22:02 +00:00
|
|
|
TAG_IF(tech_pvt->profile->minimum_session_expires, NUTAG_MIN_SE(tech_pvt->profile->minimum_session_expires)),
|
2012-04-26 10:35:02 -05:00
|
|
|
TAG_IF(!require_timer, NUTAG_TIMER_AUTOREQUIRE(0)),
|
2010-02-06 03:38:24 +00:00
|
|
|
TAG_IF(cseq, SIPTAG_CSEQ(cseq)),
|
2014-03-06 00:01:02 +05:00
|
|
|
TAG_IF(content_encoding, SIPTAG_CONTENT_ENCODING_STR(content_encoding)),
|
2010-01-07 05:22:02 +00:00
|
|
|
NUTAG_MEDIA_ENABLE(0),
|
2010-06-01 17:13:22 -05:00
|
|
|
SIPTAG_CONTENT_TYPE_STR(mp_type ? mp_type : "application/sdp"),
|
2012-12-22 08:36:15 -06:00
|
|
|
SIPTAG_PAYLOAD_STR(mp ? mp : tech_pvt->mparams.local_sdp_str), TAG_IF(rep, SIPTAG_REPLACES_STR(rep)), SOATAG_HOLD(holdstr), TAG_END());
|
2010-01-07 05:22:02 +00:00
|
|
|
}
|
2007-03-31 19:01:33 +00:00
|
|
|
|
2009-06-19 15:35:26 +00:00
|
|
|
sofia_glue_free_destination(dst);
|
2009-08-11 00:54:39 +00:00
|
|
|
switch_safe_free(extra_headers);
|
2010-06-01 17:13:22 -05:00
|
|
|
switch_safe_free(mp);
|
2009-06-09 19:05:11 +00:00
|
|
|
tech_pvt->redirected = NULL;
|
2007-03-31 19:01:33 +00:00
|
|
|
|
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
void sofia_glue_do_xfer_invite(switch_core_session_t *session)
|
|
|
|
{
|
2008-01-28 07:26:10 +00:00
|
|
|
private_object_t *tech_pvt = switch_core_session_get_private(session);
|
|
|
|
switch_channel_t *channel = switch_core_session_get_channel(session);
|
2007-03-31 19:01:33 +00:00
|
|
|
switch_caller_profile_t *caller_profile;
|
2010-02-06 03:38:24 +00:00
|
|
|
const char *sipip, *format, *contact_url;
|
2007-03-31 19:01:33 +00:00
|
|
|
|
2007-12-12 23:21:45 +00:00
|
|
|
switch_assert(tech_pvt != NULL);
|
2008-11-03 21:54:03 +00:00
|
|
|
switch_mutex_lock(tech_pvt->sofia_mutex);
|
2007-03-31 19:01:33 +00:00
|
|
|
caller_profile = switch_channel_get_caller_profile(channel);
|
|
|
|
|
2012-12-22 08:36:15 -06:00
|
|
|
if (!zstr(tech_pvt->mparams.remote_ip) && sofia_glue_check_nat(tech_pvt->profile, tech_pvt->mparams.remote_ip)) {
|
2009-06-03 21:08:34 +00:00
|
|
|
sipip = tech_pvt->profile->extsipip;
|
|
|
|
contact_url = tech_pvt->profile->public_url;
|
|
|
|
} else {
|
|
|
|
sipip = tech_pvt->profile->extsipip ? tech_pvt->profile->extsipip : tech_pvt->profile->sipip;
|
|
|
|
contact_url = tech_pvt->profile->url;
|
|
|
|
}
|
|
|
|
|
2008-07-03 18:50:15 +00:00
|
|
|
format = strchr(sipip, ':') ? "\"%s\" <sip:%s@[%s]>" : "\"%s\" <sip:%s@%s>";
|
2009-06-03 21:08:34 +00:00
|
|
|
|
2010-02-06 03:38:24 +00:00
|
|
|
if ((tech_pvt->from_str = switch_core_session_sprintf(session, format, caller_profile->caller_id_name, caller_profile->caller_id_number, sipip))) {
|
2007-03-31 19:01:33 +00:00
|
|
|
|
2007-11-01 11:28:26 +00:00
|
|
|
const char *rep = switch_channel_get_variable(channel, SOFIA_REPLACES_HEADER);
|
2007-03-31 19:01:33 +00:00
|
|
|
|
|
|
|
tech_pvt->nh2 = nua_handle(tech_pvt->profile->nua, NULL,
|
2010-02-06 03:38:24 +00:00
|
|
|
SIPTAG_TO_STR(tech_pvt->dest), SIPTAG_FROM_STR(tech_pvt->from_str), SIPTAG_CONTACT_STR(contact_url), TAG_END());
|
2007-03-31 19:01:33 +00:00
|
|
|
|
|
|
|
nua_handle_bind(tech_pvt->nh2, tech_pvt->sofia_private);
|
|
|
|
|
|
|
|
nua_invite(tech_pvt->nh2,
|
2009-06-03 21:08:34 +00:00
|
|
|
SIPTAG_CONTACT_STR(contact_url),
|
2009-10-23 16:03:42 +00:00
|
|
|
TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)),
|
2012-12-22 08:36:15 -06:00
|
|
|
SOATAG_ADDRESS(tech_pvt->mparams.adv_sdp_audio_ip),
|
|
|
|
SOATAG_USER_SDP_STR(tech_pvt->mparams.local_sdp_str),
|
2008-03-05 22:39:22 +00:00
|
|
|
SOATAG_REUSE_REJECTED(1),
|
2007-03-31 19:01:33 +00:00
|
|
|
SOATAG_RTP_SORT(SOA_RTP_SORT_REMOTE), SOATAG_RTP_SELECT(SOA_RTP_SELECT_ALL), TAG_IF(rep, SIPTAG_REPLACES_STR(rep)), TAG_END());
|
|
|
|
} else {
|
2009-08-13 20:35:02 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_ERROR, "Memory Error!\n");
|
2007-03-31 19:01:33 +00:00
|
|
|
}
|
2008-11-03 21:54:03 +00:00
|
|
|
switch_mutex_unlock(tech_pvt->sofia_mutex);
|
2007-03-31 19:01:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-11-20 02:27:48 +00:00
|
|
|
/* map sip responses to QSIG cause codes ala RFC4497 section 8.4.4 */
|
2007-03-31 19:01:33 +00:00
|
|
|
switch_call_cause_t sofia_glue_sip_cause_to_freeswitch(int status)
|
|
|
|
{
|
|
|
|
switch (status) {
|
|
|
|
case 200:
|
|
|
|
return SWITCH_CAUSE_NORMAL_CLEARING;
|
|
|
|
case 401:
|
|
|
|
case 402:
|
|
|
|
case 403:
|
|
|
|
case 407:
|
|
|
|
case 603:
|
|
|
|
return SWITCH_CAUSE_CALL_REJECTED;
|
|
|
|
case 404:
|
2010-06-13 19:17:52 -05:00
|
|
|
return SWITCH_CAUSE_UNALLOCATED_NUMBER;
|
2007-03-31 19:01:33 +00:00
|
|
|
case 485:
|
|
|
|
case 604:
|
|
|
|
return SWITCH_CAUSE_NO_ROUTE_DESTINATION;
|
|
|
|
case 408:
|
|
|
|
case 504:
|
|
|
|
return SWITCH_CAUSE_RECOVERY_ON_TIMER_EXPIRE;
|
|
|
|
case 410:
|
|
|
|
return SWITCH_CAUSE_NUMBER_CHANGED;
|
|
|
|
case 413:
|
|
|
|
case 414:
|
|
|
|
case 416:
|
|
|
|
case 420:
|
|
|
|
case 421:
|
|
|
|
case 423:
|
|
|
|
case 505:
|
|
|
|
case 513:
|
|
|
|
return SWITCH_CAUSE_INTERWORKING;
|
|
|
|
case 480:
|
|
|
|
return SWITCH_CAUSE_NO_USER_RESPONSE;
|
|
|
|
case 400:
|
|
|
|
case 481:
|
|
|
|
case 500:
|
|
|
|
case 503:
|
|
|
|
return SWITCH_CAUSE_NORMAL_TEMPORARY_FAILURE;
|
|
|
|
case 486:
|
|
|
|
case 600:
|
|
|
|
return SWITCH_CAUSE_USER_BUSY;
|
|
|
|
case 484:
|
|
|
|
return SWITCH_CAUSE_INVALID_NUMBER_FORMAT;
|
|
|
|
case 488:
|
|
|
|
case 606:
|
2007-04-17 18:53:18 +00:00
|
|
|
return SWITCH_CAUSE_INCOMPATIBLE_DESTINATION;
|
2007-03-31 19:01:33 +00:00
|
|
|
case 502:
|
|
|
|
return SWITCH_CAUSE_NETWORK_OUT_OF_ORDER;
|
|
|
|
case 405:
|
|
|
|
return SWITCH_CAUSE_SERVICE_UNAVAILABLE;
|
|
|
|
case 406:
|
|
|
|
case 415:
|
|
|
|
case 501:
|
|
|
|
return SWITCH_CAUSE_SERVICE_NOT_IMPLEMENTED;
|
|
|
|
case 482:
|
|
|
|
case 483:
|
|
|
|
return SWITCH_CAUSE_EXCHANGE_ROUTING_ERROR;
|
|
|
|
case 487:
|
|
|
|
return SWITCH_CAUSE_ORIGINATOR_CANCEL;
|
|
|
|
default:
|
|
|
|
return SWITCH_CAUSE_NORMAL_UNSPECIFIED;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-04-13 22:15:58 +00:00
|
|
|
void sofia_glue_pass_sdp(private_object_t *tech_pvt, char *sdp)
|
2007-03-31 19:01:33 +00:00
|
|
|
{
|
2007-11-01 11:28:26 +00:00
|
|
|
const char *val;
|
2007-03-31 19:01:33 +00:00
|
|
|
switch_core_session_t *other_session;
|
|
|
|
switch_channel_t *other_channel;
|
|
|
|
|
2012-05-29 13:10:15 -05:00
|
|
|
if ((val = switch_channel_get_partner_uuid(tech_pvt->channel))
|
2007-03-31 19:01:33 +00:00
|
|
|
&& (other_session = switch_core_session_locate(val))) {
|
|
|
|
other_channel = switch_core_session_get_channel(other_session);
|
|
|
|
switch_channel_set_variable(other_channel, SWITCH_B_SDP_VARIABLE, sdp);
|
2013-06-20 18:33:40 -05:00
|
|
|
|
|
|
|
#if 0
|
2012-08-22 16:27:02 -05:00
|
|
|
if (!sofia_test_flag(tech_pvt, TFLAG_CHANGE_MEDIA) && !switch_channel_test_flag(tech_pvt->channel, CF_RECOVERING) &&
|
2010-12-15 20:59:23 -06:00
|
|
|
(switch_channel_direction(other_channel) == SWITCH_CALL_DIRECTION_OUTBOUND &&
|
2013-06-20 18:33:40 -05:00
|
|
|
switch_channel_direction(tech_pvt->channel) == SWITCH_CALL_DIRECTION_OUTBOUND && switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE))) {
|
2007-03-31 19:01:33 +00:00
|
|
|
switch_ivr_nomedia(val, SMF_FORCE);
|
2009-02-09 17:56:38 +00:00
|
|
|
sofia_set_flag_locked(tech_pvt, TFLAG_CHANGE_MEDIA);
|
2007-03-31 19:01:33 +00:00
|
|
|
}
|
2013-06-20 18:33:40 -05:00
|
|
|
#endif
|
|
|
|
|
2007-03-31 19:01:33 +00:00
|
|
|
switch_core_session_rwunlock(other_session);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-04-04 12:35:18 -05:00
|
|
|
char *sofia_glue_get_path_from_contact(char *buf)
|
|
|
|
{
|
|
|
|
char *p, *e, *path = NULL, *contact = NULL;
|
|
|
|
|
|
|
|
if (!buf) return NULL;
|
|
|
|
|
|
|
|
contact = sofia_glue_get_url_from_contact(buf, SWITCH_TRUE);
|
|
|
|
|
|
|
|
if (!contact) return NULL;
|
|
|
|
|
|
|
|
if ((p = strstr(contact, "fs_path="))) {
|
|
|
|
p += 8;
|
|
|
|
|
|
|
|
if (!zstr(p)) {
|
|
|
|
path = strdup(p);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-01-22 15:27:51 -08:00
|
|
|
if (!path) {
|
|
|
|
free(contact);
|
|
|
|
return NULL;
|
|
|
|
}
|
2013-04-04 12:35:18 -05:00
|
|
|
|
|
|
|
if ((e = strrchr(path, ';'))) {
|
|
|
|
*e = '\0';
|
|
|
|
}
|
|
|
|
|
|
|
|
switch_url_decode(path);
|
|
|
|
|
|
|
|
free(contact);
|
|
|
|
|
|
|
|
return path;
|
|
|
|
}
|
|
|
|
|
2007-03-31 19:01:33 +00:00
|
|
|
char *sofia_glue_get_url_from_contact(char *buf, uint8_t to_dup)
|
|
|
|
{
|
|
|
|
char *url = NULL, *e;
|
|
|
|
|
2012-03-29 10:07:34 -05:00
|
|
|
switch_assert(buf);
|
|
|
|
|
2012-01-28 13:09:12 -06:00
|
|
|
while(*buf == ' ') {
|
|
|
|
buf++;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (*buf == '"') {
|
|
|
|
buf++;
|
2012-01-28 18:32:35 -06:00
|
|
|
if((e = strchr(buf, '"'))) {
|
2012-01-28 13:09:12 -06:00
|
|
|
buf = e+1;
|
|
|
|
}
|
2012-01-26 04:46:48 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
while(*buf == ' ') {
|
|
|
|
buf++;
|
|
|
|
}
|
|
|
|
|
2014-07-30 22:13:57 +05:00
|
|
|
url = strchr(buf, '<');
|
|
|
|
|
|
|
|
if (url && (e = switch_find_end_paren(url, '<', '>'))) {
|
2007-03-31 19:01:33 +00:00
|
|
|
url++;
|
|
|
|
if (to_dup) {
|
|
|
|
url = strdup(url);
|
|
|
|
e = strchr(url, '>');
|
|
|
|
}
|
|
|
|
|
|
|
|
*e = '\0';
|
2007-10-28 16:07:23 +00:00
|
|
|
} else {
|
2014-07-30 22:13:57 +05:00
|
|
|
if (url) buf++;
|
|
|
|
|
2007-10-28 16:07:23 +00:00
|
|
|
if (to_dup) {
|
|
|
|
url = strdup(buf);
|
|
|
|
} else {
|
|
|
|
url = buf;
|
|
|
|
}
|
2007-03-31 19:01:33 +00:00
|
|
|
}
|
|
|
|
return url;
|
|
|
|
}
|
|
|
|
|
2010-02-16 00:07:50 +00:00
|
|
|
switch_status_t sofia_glue_profile_rdlock__(const char *file, const char *func, int line, sofia_profile_t *profile)
|
|
|
|
{
|
|
|
|
switch_status_t status = switch_thread_rwlock_tryrdlock(profile->rwlock);
|
|
|
|
if (status != SWITCH_STATUS_SUCCESS) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_ERROR, "Profile %s is locked\n", profile->name);
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
#ifdef SOFIA_DEBUG_RWLOCKS
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_ERROR, "XXXXXXXXXXXXXX LOCK %s\n", profile->name);
|
|
|
|
#endif
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
2010-09-03 12:46:21 -05:00
|
|
|
switch_bool_t sofia_glue_profile_exists(const char *key)
|
|
|
|
{
|
|
|
|
switch_bool_t tf = SWITCH_FALSE;
|
|
|
|
|
|
|
|
switch_mutex_lock(mod_sofia_globals.hash_mutex);
|
|
|
|
if (switch_core_hash_find(mod_sofia_globals.profile_hash, key)) {
|
|
|
|
tf = SWITCH_TRUE;
|
|
|
|
}
|
|
|
|
switch_mutex_unlock(mod_sofia_globals.hash_mutex);
|
|
|
|
|
|
|
|
return tf;
|
|
|
|
}
|
|
|
|
|
2008-07-22 22:23:50 +00:00
|
|
|
sofia_profile_t *sofia_glue_find_profile__(const char *file, const char *func, int line, const char *key)
|
2007-03-31 19:01:33 +00:00
|
|
|
{
|
|
|
|
sofia_profile_t *profile;
|
|
|
|
|
2007-04-01 01:16:16 +00:00
|
|
|
switch_mutex_lock(mod_sofia_globals.hash_mutex);
|
2007-04-29 01:16:49 +00:00
|
|
|
if ((profile = (sofia_profile_t *) switch_core_hash_find(mod_sofia_globals.profile_hash, key))) {
|
2009-02-09 17:56:38 +00:00
|
|
|
if (!sofia_test_pflag(profile, PFLAG_RUNNING)) {
|
2008-05-02 16:43:07 +00:00
|
|
|
#ifdef SOFIA_DEBUG_RWLOCKS
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_ERROR, "Profile %s is not running\n", profile->name);
|
|
|
|
#endif
|
2008-04-04 18:53:24 +00:00
|
|
|
profile = NULL;
|
|
|
|
goto done;
|
2008-01-08 16:35:20 +00:00
|
|
|
}
|
2010-02-16 00:07:50 +00:00
|
|
|
if (sofia_glue_profile_rdlock__(file, func, line, profile) != SWITCH_STATUS_SUCCESS) {
|
2007-04-29 01:16:49 +00:00
|
|
|
profile = NULL;
|
2008-05-27 04:54:52 +00:00
|
|
|
}
|
2007-05-02 23:32:45 +00:00
|
|
|
} else {
|
2007-05-03 01:55:25 +00:00
|
|
|
#ifdef SOFIA_DEBUG_RWLOCKS
|
2008-05-02 16:43:07 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_ERROR, "Profile %s is not in the hash\n", key);
|
2007-05-03 01:55:25 +00:00
|
|
|
#endif
|
2007-04-29 01:16:49 +00:00
|
|
|
}
|
2008-04-04 18:53:24 +00:00
|
|
|
|
2010-06-23 13:22:52 -05:00
|
|
|
done:
|
2007-04-01 01:16:16 +00:00
|
|
|
switch_mutex_unlock(mod_sofia_globals.hash_mutex);
|
2007-03-31 19:01:33 +00:00
|
|
|
|
|
|
|
return profile;
|
|
|
|
}
|
|
|
|
|
2007-05-03 01:55:25 +00:00
|
|
|
void sofia_glue_release_profile__(const char *file, const char *func, int line, sofia_profile_t *profile)
|
|
|
|
{
|
|
|
|
if (profile) {
|
|
|
|
#ifdef SOFIA_DEBUG_RWLOCKS
|
2008-05-02 16:43:07 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, NULL, SWITCH_LOG_ERROR, "XXXXXXXXXXXXXX UNLOCK %s\n", profile->name);
|
2007-05-03 01:55:25 +00:00
|
|
|
#endif
|
|
|
|
switch_thread_rwlock_unlock(profile->rwlock);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2007-04-30 20:35:35 +00:00
|
|
|
switch_status_t sofia_glue_add_profile(char *key, sofia_profile_t *profile)
|
2007-03-31 19:01:33 +00:00
|
|
|
{
|
2007-04-30 20:35:35 +00:00
|
|
|
switch_status_t status = SWITCH_STATUS_FALSE;
|
2009-12-14 20:10:06 +00:00
|
|
|
|
2007-04-01 01:16:16 +00:00
|
|
|
switch_mutex_lock(mod_sofia_globals.hash_mutex);
|
2007-04-30 20:35:35 +00:00
|
|
|
if (!switch_core_hash_find(mod_sofia_globals.profile_hash, key)) {
|
|
|
|
status = switch_core_hash_insert(mod_sofia_globals.profile_hash, key, profile);
|
|
|
|
}
|
2007-04-01 01:16:16 +00:00
|
|
|
switch_mutex_unlock(mod_sofia_globals.hash_mutex);
|
2007-04-30 20:35:35 +00:00
|
|
|
|
|
|
|
return status;
|
|
|
|
}
|
|
|
|
|
2010-03-31 15:02:50 -05:00
|
|
|
|
|
|
|
void sofia_glue_del_every_gateway(sofia_profile_t *profile)
|
|
|
|
{
|
|
|
|
sofia_gateway_t *gp = NULL;
|
|
|
|
|
|
|
|
switch_mutex_lock(mod_sofia_globals.hash_mutex);
|
|
|
|
for (gp = profile->gateways; gp; gp = gp->next) {
|
|
|
|
sofia_glue_del_gateway(gp);
|
|
|
|
}
|
|
|
|
switch_mutex_unlock(mod_sofia_globals.hash_mutex);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-09-17 14:11:57 -05:00
|
|
|
void sofia_glue_gateway_list(sofia_profile_t *profile, switch_stream_handle_t *stream, int up)
|
|
|
|
{
|
|
|
|
sofia_gateway_t *gp = NULL;
|
|
|
|
char *r = (char *) stream->data;
|
|
|
|
|
|
|
|
switch_mutex_lock(mod_sofia_globals.hash_mutex);
|
|
|
|
for (gp = profile->gateways; gp; gp = gp->next) {
|
2010-09-17 17:06:59 -05:00
|
|
|
int reged = (gp->status == SOFIA_GATEWAY_UP);
|
2010-09-17 14:11:57 -05:00
|
|
|
|
|
|
|
if (up ? reged : !reged) {
|
|
|
|
stream->write_function(stream, "%s ", gp->name);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (r) {
|
|
|
|
end_of(r) = '\0';
|
|
|
|
}
|
|
|
|
|
|
|
|
switch_mutex_unlock(mod_sofia_globals.hash_mutex);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2008-07-08 22:05:34 +00:00
|
|
|
void sofia_glue_del_gateway(sofia_gateway_t *gp)
|
|
|
|
{
|
|
|
|
if (!gp->deleted) {
|
|
|
|
if (gp->state != REG_STATE_NOREG) {
|
|
|
|
gp->retry = 0;
|
|
|
|
gp->state = REG_STATE_UNREGISTER;
|
|
|
|
}
|
|
|
|
|
|
|
|
gp->deleted = 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-02-06 03:38:24 +00:00
|
|
|
void sofia_glue_restart_all_profiles(void)
|
2008-07-22 22:23:50 +00:00
|
|
|
{
|
|
|
|
switch_hash_index_t *hi;
|
|
|
|
const void *var;
|
2010-02-06 03:38:24 +00:00
|
|
|
void *val;
|
|
|
|
sofia_profile_t *pptr;
|
2008-07-22 22:23:50 +00:00
|
|
|
switch_xml_t xml_root;
|
|
|
|
const char *err;
|
|
|
|
|
|
|
|
if ((xml_root = switch_xml_open_root(1, &err))) {
|
|
|
|
switch_xml_free(xml_root);
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Reload XML [%s]\n", err);
|
|
|
|
}
|
|
|
|
|
|
|
|
switch_mutex_lock(mod_sofia_globals.hash_mutex);
|
|
|
|
if (mod_sofia_globals.profile_hash) {
|
2014-04-02 03:21:29 +05:00
|
|
|
for (hi = switch_core_hash_first(mod_sofia_globals.profile_hash); hi; hi = switch_core_hash_next(&hi)) {
|
2014-03-09 00:37:09 +05:00
|
|
|
switch_core_hash_this(hi, &var, NULL, &val);
|
2010-02-06 03:38:24 +00:00
|
|
|
if ((pptr = (sofia_profile_t *) val)) {
|
2008-10-13 19:26:28 +00:00
|
|
|
int rsec = 10;
|
2009-01-25 21:23:07 +00:00
|
|
|
int diff = (int) (switch_epoch_time_now(NULL) - pptr->started);
|
2008-10-13 19:26:28 +00:00
|
|
|
int remain = rsec - diff;
|
|
|
|
if (sofia_test_pflag(pptr, PFLAG_RESPAWN) || !sofia_test_pflag(pptr, PFLAG_RUNNING)) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (diff < rsec) {
|
2010-02-06 03:38:24 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
|
2008-10-13 19:26:28 +00:00
|
|
|
"Profile %s must be up for at least %d seconds to stop/restart.\nPlease wait %d second%s\n",
|
|
|
|
pptr->name, rsec, remain, remain == 1 ? "" : "s");
|
|
|
|
continue;
|
|
|
|
}
|
2008-07-22 22:23:50 +00:00
|
|
|
sofia_set_pflag_locked(pptr, PFLAG_RESPAWN);
|
|
|
|
sofia_clear_pflag_locked(pptr, PFLAG_RUNNING);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
switch_mutex_unlock(mod_sofia_globals.hash_mutex);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2010-09-20 16:55:09 -05:00
|
|
|
|
|
|
|
void sofia_glue_global_siptrace(switch_bool_t on)
|
|
|
|
{
|
|
|
|
switch_hash_index_t *hi;
|
|
|
|
const void *var;
|
|
|
|
void *val;
|
|
|
|
sofia_profile_t *pptr;
|
|
|
|
|
|
|
|
switch_mutex_lock(mod_sofia_globals.hash_mutex);
|
|
|
|
if (mod_sofia_globals.profile_hash) {
|
2014-04-02 03:21:29 +05:00
|
|
|
for (hi = switch_core_hash_first(mod_sofia_globals.profile_hash); hi; hi = switch_core_hash_next(&hi)) {
|
2014-03-09 00:37:09 +05:00
|
|
|
switch_core_hash_this(hi, &var, NULL, &val);
|
2010-09-20 16:55:09 -05:00
|
|
|
if ((pptr = (sofia_profile_t *) val)) {
|
|
|
|
nua_set_params(pptr->nua, TPTAG_LOG(on), TAG_END());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
switch_mutex_unlock(mod_sofia_globals.hash_mutex);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2011-12-16 13:41:15 -06:00
|
|
|
void sofia_glue_global_standby(switch_bool_t on)
|
|
|
|
{
|
|
|
|
switch_hash_index_t *hi;
|
|
|
|
const void *var;
|
|
|
|
void *val;
|
|
|
|
sofia_profile_t *pptr;
|
|
|
|
|
|
|
|
switch_mutex_lock(mod_sofia_globals.hash_mutex);
|
|
|
|
if (mod_sofia_globals.profile_hash) {
|
2014-04-02 03:21:29 +05:00
|
|
|
for (hi = switch_core_hash_first(mod_sofia_globals.profile_hash); hi; hi = switch_core_hash_next(&hi)) {
|
2014-03-09 00:37:09 +05:00
|
|
|
switch_core_hash_this(hi, &var, NULL, &val);
|
2011-12-16 13:41:15 -06:00
|
|
|
if ((pptr = (sofia_profile_t *) val)) {
|
|
|
|
if (on) {
|
|
|
|
sofia_set_pflag_locked(pptr, PFLAG_STANDBY);
|
|
|
|
} else {
|
|
|
|
sofia_clear_pflag_locked(pptr, PFLAG_STANDBY);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
switch_mutex_unlock(mod_sofia_globals.hash_mutex);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2011-07-31 18:36:23 -05:00
|
|
|
void sofia_glue_global_capture(switch_bool_t on)
|
|
|
|
{
|
|
|
|
switch_hash_index_t *hi;
|
|
|
|
const void *var;
|
|
|
|
void *val;
|
|
|
|
sofia_profile_t *pptr;
|
|
|
|
|
|
|
|
switch_mutex_lock(mod_sofia_globals.hash_mutex);
|
|
|
|
if (mod_sofia_globals.profile_hash) {
|
2014-04-02 03:21:29 +05:00
|
|
|
for (hi = switch_core_hash_first(mod_sofia_globals.profile_hash); hi; hi = switch_core_hash_next(&hi)) {
|
2014-03-09 00:37:09 +05:00
|
|
|
switch_core_hash_this(hi, &var, NULL, &val);
|
2011-07-31 18:36:23 -05:00
|
|
|
if ((pptr = (sofia_profile_t *) val)) {
|
|
|
|
nua_set_params(pptr->nua, TPTAG_CAPT(on ? mod_sofia_globals.capture_server : NULL), TAG_END());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
switch_mutex_unlock(mod_sofia_globals.hash_mutex);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-10-06 15:17:48 -05:00
|
|
|
void sofia_glue_global_watchdog(switch_bool_t on)
|
|
|
|
{
|
|
|
|
switch_hash_index_t *hi;
|
|
|
|
const void *var;
|
|
|
|
void *val;
|
|
|
|
sofia_profile_t *pptr;
|
|
|
|
|
|
|
|
switch_mutex_lock(mod_sofia_globals.hash_mutex);
|
|
|
|
if (mod_sofia_globals.profile_hash) {
|
2014-04-02 03:21:29 +05:00
|
|
|
for (hi = switch_core_hash_first(mod_sofia_globals.profile_hash); hi; hi = switch_core_hash_next(&hi)) {
|
2014-03-09 00:37:09 +05:00
|
|
|
switch_core_hash_this(hi, &var, NULL, &val);
|
2010-10-06 15:17:48 -05:00
|
|
|
if ((pptr = (sofia_profile_t *) val)) {
|
|
|
|
pptr->watchdog_enabled = (on ? 1 : 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
switch_mutex_unlock(mod_sofia_globals.hash_mutex);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2007-04-30 20:35:35 +00:00
|
|
|
void sofia_glue_del_profile(sofia_profile_t *profile)
|
|
|
|
{
|
2007-09-29 01:06:08 +00:00
|
|
|
sofia_gateway_t *gp;
|
2007-11-08 03:16:28 +00:00
|
|
|
char *aliases[512];
|
|
|
|
int i = 0, j = 0;
|
|
|
|
switch_hash_index_t *hi;
|
|
|
|
const void *var;
|
|
|
|
void *val;
|
2007-11-08 14:06:32 +00:00
|
|
|
sofia_profile_t *pptr;
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2007-04-30 20:35:35 +00:00
|
|
|
switch_mutex_lock(mod_sofia_globals.hash_mutex);
|
2008-04-16 21:29:08 +00:00
|
|
|
if (mod_sofia_globals.profile_hash) {
|
2014-04-02 03:21:29 +05:00
|
|
|
for (hi = switch_core_hash_first(mod_sofia_globals.profile_hash); hi; hi = switch_core_hash_next(&hi)) {
|
2014-03-09 00:37:09 +05:00
|
|
|
switch_core_hash_this(hi, &var, NULL, &val);
|
2008-04-16 21:29:08 +00:00
|
|
|
if ((pptr = (sofia_profile_t *) val) && pptr == profile) {
|
|
|
|
aliases[i++] = strdup((char *) var);
|
|
|
|
if (i == 512) {
|
|
|
|
abort();
|
|
|
|
}
|
2007-11-08 14:06:32 +00:00
|
|
|
}
|
2007-11-08 03:16:28 +00:00
|
|
|
}
|
|
|
|
|
2008-04-16 21:29:08 +00:00
|
|
|
for (j = 0; j < i && j < 512; j++) {
|
|
|
|
switch_core_hash_delete(mod_sofia_globals.profile_hash, aliases[j]);
|
|
|
|
free(aliases[j]);
|
|
|
|
}
|
2007-11-08 03:16:28 +00:00
|
|
|
|
2008-04-16 21:29:08 +00:00
|
|
|
for (gp = profile->gateways; gp; gp = gp->next) {
|
2011-03-25 15:50:52 -04:00
|
|
|
char *pkey = switch_mprintf("%s::%s", profile->name, gp->name);
|
|
|
|
|
2008-07-21 18:42:11 +00:00
|
|
|
switch_core_hash_delete(mod_sofia_globals.gateway_hash, gp->name);
|
2011-03-25 15:50:52 -04:00
|
|
|
switch_core_hash_delete(mod_sofia_globals.gateway_hash, pkey);
|
|
|
|
switch_safe_free(pkey);
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "deleted gateway %s from profile %s\n", gp->name, profile->name);
|
2008-04-16 21:29:08 +00:00
|
|
|
}
|
2011-03-25 15:50:52 -04:00
|
|
|
profile->gateways = NULL;
|
2007-04-30 20:35:35 +00:00
|
|
|
}
|
|
|
|
switch_mutex_unlock(mod_sofia_globals.hash_mutex);
|
2007-03-31 19:01:33 +00:00
|
|
|
}
|
|
|
|
|
2012-08-22 16:27:02 -05:00
|
|
|
int sofia_recover_callback(switch_core_session_t *session)
|
2010-02-06 03:38:24 +00:00
|
|
|
{
|
2012-08-22 16:27:02 -05:00
|
|
|
|
|
|
|
switch_channel_t *channel = switch_core_session_get_channel(session);
|
2010-02-06 03:38:24 +00:00
|
|
|
private_object_t *tech_pvt = NULL;
|
2012-08-22 16:27:02 -05:00
|
|
|
sofia_profile_t *profile = NULL;
|
2010-02-06 03:38:24 +00:00
|
|
|
const char *tmp;
|
2011-11-16 09:57:15 -06:00
|
|
|
const char *rr;
|
2012-08-22 16:27:02 -05:00
|
|
|
int r = 0;
|
|
|
|
const char *profile_name = switch_channel_get_variable_dup(channel, "recovery_profile_name", SWITCH_FALSE, -1);
|
|
|
|
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2012-08-22 16:27:02 -05:00
|
|
|
if (zstr(profile_name)) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Missing profile\n");
|
2010-02-06 03:38:24 +00:00
|
|
|
return 0;
|
2012-08-22 16:27:02 -05:00
|
|
|
}
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2012-08-22 16:27:02 -05:00
|
|
|
if (!(profile = sofia_glue_find_profile(profile_name))) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Invalid profile %s\n", profile_name);
|
2010-02-06 03:38:24 +00:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2012-08-22 16:27:02 -05:00
|
|
|
|
2012-08-22 17:05:25 -05:00
|
|
|
tech_pvt = (private_object_t *) switch_core_session_alloc(session, sizeof(private_object_t));
|
2012-08-22 16:27:02 -05:00
|
|
|
tech_pvt->channel = channel;
|
2010-02-06 03:38:24 +00:00
|
|
|
|
|
|
|
switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
|
|
|
|
switch_mutex_init(&tech_pvt->sofia_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
|
|
|
|
|
2012-12-22 08:36:15 -06:00
|
|
|
tech_pvt->mparams.remote_ip = (char *) switch_channel_get_variable(channel, "sip_network_ip");
|
2012-12-23 21:20:03 -06:00
|
|
|
tech_pvt->mparams.remote_port = atoi(switch_str_nil(switch_channel_get_variable(channel, "sip_network_port")));
|
2010-02-06 03:38:24 +00:00
|
|
|
tech_pvt->caller_profile = switch_channel_get_caller_profile(channel);
|
|
|
|
|
2013-02-16 17:59:59 -06:00
|
|
|
if ((tmp = switch_channel_get_variable(tech_pvt->channel, "rtp_2833_send_payload"))) {
|
2011-09-16 14:30:32 -05:00
|
|
|
int te = atoi(tmp);
|
|
|
|
if (te > 64) {
|
2014-01-22 22:28:53 +01:00
|
|
|
tech_pvt->te = (switch_payload_t)te;
|
2011-09-16 14:30:32 -05:00
|
|
|
}
|
|
|
|
}
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2013-02-16 17:59:59 -06:00
|
|
|
if ((tmp = switch_channel_get_variable(tech_pvt->channel, "rtp_2833_recv_payload"))) {
|
2011-09-16 14:30:32 -05:00
|
|
|
int te = atoi(tmp);
|
|
|
|
if (te > 64) {
|
2014-01-22 22:28:53 +01:00
|
|
|
tech_pvt->recv_te = (switch_payload_t)te;
|
2011-09-16 14:30:32 -05:00
|
|
|
}
|
|
|
|
}
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2011-11-16 09:57:15 -06:00
|
|
|
rr = switch_channel_get_variable(channel, "sip_invite_record_route");
|
|
|
|
|
2010-02-06 03:38:24 +00:00
|
|
|
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
|
2012-07-11 18:12:26 -05:00
|
|
|
int break_rfc = switch_true(switch_channel_get_variable(channel, "sip_recovery_break_rfc"));
|
2010-02-06 03:38:24 +00:00
|
|
|
tech_pvt->dest = switch_core_session_sprintf(session, "sip:%s", switch_channel_get_variable(channel, "sip_req_uri"));
|
2012-12-06 12:22:31 -06:00
|
|
|
switch_channel_set_variable(channel, "sip_handle_full_from", switch_channel_get_variable(channel, break_rfc ? "sip_full_to" : "sip_full_from"));
|
|
|
|
switch_channel_set_variable(channel, "sip_handle_full_to", switch_channel_get_variable(channel, break_rfc ? "sip_full_from" : "sip_full_to"));
|
2010-02-06 03:38:24 +00:00
|
|
|
} else {
|
2011-07-16 11:37:03 -05:00
|
|
|
tech_pvt->redirected = switch_core_session_sprintf(session, "sip:%s", switch_channel_get_variable(channel, "sip_contact_uri"));
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2011-11-16 09:57:15 -06:00
|
|
|
if (zstr(rr)) {
|
2013-07-23 13:52:49 -05:00
|
|
|
switch_channel_set_variable_printf(channel, "sip_invite_route_uri", "<sip:%s@%s:%s;transport=%s>",
|
2011-11-15 15:38:09 -06:00
|
|
|
switch_channel_get_variable(channel, "sip_from_user"),
|
2013-07-23 13:52:49 -05:00
|
|
|
switch_channel_get_variable(channel, "sip_network_ip"),
|
|
|
|
switch_channel_get_variable(channel, "sip_network_port"),
|
|
|
|
switch_channel_get_variable(channel,"sip_via_protocol")
|
2011-11-15 15:38:09 -06:00
|
|
|
);
|
2013-07-23 13:52:49 -05:00
|
|
|
|
2011-11-15 15:38:09 -06:00
|
|
|
}
|
2010-02-06 03:38:24 +00:00
|
|
|
|
|
|
|
tech_pvt->dest = switch_core_session_sprintf(session, "sip:%s", switch_channel_get_variable(channel, "sip_from_uri"));
|
|
|
|
|
2011-05-25 15:42:36 -05:00
|
|
|
if (!switch_channel_get_variable_dup(channel, "sip_handle_full_from", SWITCH_FALSE, -1)) {
|
2012-12-06 12:22:31 -06:00
|
|
|
switch_channel_set_variable(channel, "sip_handle_full_from", switch_channel_get_variable(channel, "sip_full_to"));
|
2010-02-06 03:38:24 +00:00
|
|
|
}
|
|
|
|
|
2011-05-25 15:42:36 -05:00
|
|
|
if (!switch_channel_get_variable_dup(channel, "sip_handle_full_to", SWITCH_FALSE, -1)) {
|
2012-12-06 12:22:31 -06:00
|
|
|
switch_channel_set_variable(channel, "sip_handle_full_to", switch_channel_get_variable(channel, "sip_full_from"));
|
2010-02-06 03:38:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-11-16 09:57:15 -06:00
|
|
|
if (rr) {
|
|
|
|
switch_channel_set_variable(channel, "sip_invite_route_uri", rr);
|
|
|
|
}
|
|
|
|
|
2010-02-06 03:38:24 +00:00
|
|
|
tech_pvt->dest_to = tech_pvt->dest;
|
|
|
|
|
2012-08-22 16:27:02 -05:00
|
|
|
sofia_glue_attach_private(session, profile, tech_pvt, NULL);
|
2010-02-06 03:38:24 +00:00
|
|
|
switch_channel_set_name(tech_pvt->channel, switch_channel_get_variable(channel, "channel_name"));
|
|
|
|
|
2012-12-18 20:35:44 -06:00
|
|
|
|
2010-02-06 03:38:24 +00:00
|
|
|
switch_channel_set_variable(channel, "sip_invite_call_id", switch_channel_get_variable(channel, "sip_call_id"));
|
|
|
|
|
|
|
|
if (switch_true(switch_channel_get_variable(channel, "sip_nat_detected"))) {
|
|
|
|
switch_channel_set_variable_printf(channel, "sip_route_uri", "sip:%s@%s:%s",
|
|
|
|
switch_channel_get_variable(channel, "sip_req_user"),
|
|
|
|
switch_channel_get_variable(channel, "sip_network_ip"), switch_channel_get_variable(channel, "sip_network_port")
|
2010-06-23 13:22:52 -05:00
|
|
|
);
|
2010-02-06 03:38:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if (session) {
|
2010-12-13 09:36:45 -06:00
|
|
|
const char *use_uuid;
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2010-12-13 09:36:45 -06:00
|
|
|
if ((use_uuid = switch_channel_get_variable(channel, "origination_uuid"))) {
|
|
|
|
if (switch_core_session_set_uuid(session, use_uuid) == SWITCH_STATUS_SUCCESS) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s set UUID=%s\n", switch_channel_get_name(channel),
|
|
|
|
use_uuid);
|
|
|
|
} else {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "%s set UUID=%s FAILED\n",
|
|
|
|
switch_channel_get_name(channel), use_uuid);
|
|
|
|
}
|
|
|
|
}
|
2010-02-06 03:38:24 +00:00
|
|
|
}
|
|
|
|
|
2012-08-22 16:27:02 -05:00
|
|
|
r++;
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2013-11-15 21:33:05 +05:00
|
|
|
if (profile) {
|
|
|
|
sofia_glue_release_profile(profile);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-08-22 16:27:02 -05:00
|
|
|
return r;
|
2010-02-06 03:38:24 +00:00
|
|
|
|
|
|
|
}
|
2012-12-23 21:20:03 -06:00
|
|
|
|
2012-12-21 16:57:59 -06:00
|
|
|
|
2010-02-06 03:38:24 +00:00
|
|
|
|
|
|
|
int sofia_glue_recover(switch_bool_t flush)
|
|
|
|
{
|
|
|
|
sofia_profile_t *profile;
|
|
|
|
int r = 0;
|
2011-06-16 14:32:08 -05:00
|
|
|
switch_console_callback_match_t *matches;
|
2010-02-06 03:38:24 +00:00
|
|
|
|
|
|
|
|
2011-07-14 16:01:44 -05:00
|
|
|
if (list_profiles_full(NULL, NULL, &matches, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) {
|
2011-06-16 14:32:08 -05:00
|
|
|
switch_console_callback_match_node_t *m;
|
|
|
|
for (m = matches->head; m; m = m->next) {
|
|
|
|
if ((profile = sofia_glue_find_profile(m->val))) {
|
2011-12-23 16:07:33 -05:00
|
|
|
r += sofia_glue_profile_recover(profile, flush);
|
2012-05-22 07:59:16 -05:00
|
|
|
sofia_glue_release_profile(profile);
|
2011-12-23 16:07:33 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
switch_console_free_matches(&matches);
|
|
|
|
}
|
|
|
|
return r;
|
|
|
|
}
|
2011-06-16 14:32:08 -05:00
|
|
|
|
2011-12-23 16:07:33 -05:00
|
|
|
int sofia_glue_profile_recover(sofia_profile_t *profile, switch_bool_t flush)
|
|
|
|
{
|
|
|
|
int r = 0;
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2011-12-23 16:07:33 -05:00
|
|
|
if (profile) {
|
|
|
|
sofia_clear_pflag_locked(profile, PFLAG_STANDBY);
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2011-12-23 16:07:33 -05:00
|
|
|
if (flush) {
|
2012-08-22 16:27:02 -05:00
|
|
|
switch_core_recovery_flush(SOFIA_RECOVER, profile->name);
|
2011-12-23 16:07:33 -05:00
|
|
|
} else {
|
2012-08-22 16:27:02 -05:00
|
|
|
r = switch_core_recovery_recover(SOFIA_RECOVER, profile->name);
|
2010-02-06 03:38:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return r;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-04-04 03:08:17 +00:00
|
|
|
int sofia_glue_init_sql(sofia_profile_t *profile)
|
|
|
|
{
|
2008-09-18 00:01:03 +00:00
|
|
|
char *test_sql = NULL;
|
|
|
|
|
2007-04-04 03:08:17 +00:00
|
|
|
char reg_sql[] =
|
|
|
|
"CREATE TABLE sip_registrations (\n"
|
2010-02-05 07:05:33 +00:00
|
|
|
" call_id VARCHAR(255),\n"
|
|
|
|
" sip_user VARCHAR(255),\n"
|
|
|
|
" sip_host VARCHAR(255),\n"
|
|
|
|
" presence_hosts VARCHAR(255),\n"
|
|
|
|
" contact VARCHAR(1024),\n"
|
|
|
|
" status VARCHAR(255),\n"
|
2014-09-09 09:43:47 +02:00
|
|
|
" ping_status VARCHAR(255),\n"
|
|
|
|
" ping_count INTEGER,\n"
|
2015-09-18 16:55:10 -05:00
|
|
|
" ping_time BIGINT,\n"
|
|
|
|
" force_ping INTEGER,\n"
|
2010-06-23 13:22:52 -05:00
|
|
|
" rpid VARCHAR(255),\n"
|
2014-07-10 10:17:38 -05:00
|
|
|
" expires BIGINT,\n"
|
2014-09-22 10:44:53 +02:00
|
|
|
" ping_expires INTEGER not null default 0,\n"
|
2010-06-23 13:22:52 -05:00
|
|
|
" user_agent VARCHAR(255),\n"
|
2010-02-05 07:05:33 +00:00
|
|
|
" server_user VARCHAR(255),\n"
|
2010-06-23 13:22:52 -05:00
|
|
|
" server_host VARCHAR(255),\n"
|
|
|
|
" profile_name VARCHAR(255),\n"
|
|
|
|
" hostname VARCHAR(255),\n"
|
|
|
|
" network_ip VARCHAR(255),\n"
|
|
|
|
" network_port VARCHAR(6),\n"
|
|
|
|
" sip_username VARCHAR(255),\n"
|
2010-02-05 07:05:33 +00:00
|
|
|
" sip_realm VARCHAR(255),\n"
|
|
|
|
" mwi_user VARCHAR(255),\n"
|
|
|
|
" mwi_host VARCHAR(255),\n"
|
|
|
|
" orig_server_host VARCHAR(255),\n"
|
2012-01-10 17:33:40 -06:00
|
|
|
" orig_hostname VARCHAR(255),\n"
|
|
|
|
" sub_host VARCHAR(255)\n"
|
2008-11-22 01:34:19 +00:00
|
|
|
");\n";
|
|
|
|
|
|
|
|
char pres_sql[] =
|
|
|
|
"CREATE TABLE sip_presence (\n"
|
|
|
|
" sip_user VARCHAR(255),\n"
|
|
|
|
" sip_host VARCHAR(255),\n"
|
|
|
|
" status VARCHAR(255),\n"
|
2010-02-06 03:38:24 +00:00
|
|
|
" rpid VARCHAR(255),\n"
|
2014-07-10 10:17:38 -05:00
|
|
|
" expires BIGINT,\n"
|
2010-02-06 03:38:24 +00:00
|
|
|
" user_agent VARCHAR(255),\n"
|
|
|
|
" profile_name VARCHAR(255),\n"
|
2010-02-22 23:41:56 +00:00
|
|
|
" hostname VARCHAR(255),\n"
|
|
|
|
" network_ip VARCHAR(255),\n"
|
2010-07-27 19:47:35 -05:00
|
|
|
" network_port VARCHAR(6),\n"
|
2010-07-29 23:39:39 -05:00
|
|
|
" open_closed VARCHAR(255)\n"
|
2010-02-22 23:41:56 +00:00
|
|
|
");\n";
|
2007-04-04 03:08:17 +00:00
|
|
|
|
2007-12-18 01:12:50 +00:00
|
|
|
char dialog_sql[] =
|
|
|
|
"CREATE TABLE sip_dialogs (\n"
|
|
|
|
" call_id VARCHAR(255),\n"
|
|
|
|
" uuid VARCHAR(255),\n"
|
|
|
|
" sip_to_user VARCHAR(255),\n"
|
|
|
|
" sip_to_host VARCHAR(255),\n"
|
|
|
|
" sip_from_user VARCHAR(255),\n"
|
|
|
|
" sip_from_host VARCHAR(255),\n"
|
2008-05-27 04:54:52 +00:00
|
|
|
" contact_user VARCHAR(255),\n"
|
|
|
|
" contact_host VARCHAR(255),\n"
|
2010-02-06 03:38:24 +00:00
|
|
|
" state VARCHAR(255),\n"
|
|
|
|
" direction VARCHAR(255),\n"
|
|
|
|
" user_agent VARCHAR(255),\n"
|
2008-09-18 00:01:03 +00:00
|
|
|
" profile_name VARCHAR(255),\n"
|
2010-02-06 03:38:24 +00:00
|
|
|
" hostname VARCHAR(255),\n"
|
|
|
|
" contact VARCHAR(255),\n"
|
|
|
|
" presence_id VARCHAR(255),\n"
|
|
|
|
" presence_data VARCHAR(255),\n"
|
2010-02-22 23:41:56 +00:00
|
|
|
" call_info VARCHAR(255),\n"
|
2012-02-17 19:47:57 -06:00
|
|
|
" call_info_state VARCHAR(255) default '',\n"
|
2014-07-10 10:17:38 -05:00
|
|
|
" expires BIGINT default 0,\n"
|
2010-07-29 23:39:39 -05:00
|
|
|
" status VARCHAR(255),\n"
|
2011-10-21 20:00:34 -05:00
|
|
|
" rpid VARCHAR(255),\n"
|
|
|
|
" sip_to_tag VARCHAR(255),\n"
|
2011-10-24 18:54:22 -05:00
|
|
|
" sip_from_tag VARCHAR(255),\n"
|
|
|
|
" rcd INTEGER not null default 0\n"
|
2010-02-22 23:41:56 +00:00
|
|
|
");\n";
|
2007-12-18 01:12:50 +00:00
|
|
|
|
2007-04-04 03:08:17 +00:00
|
|
|
char sub_sql[] =
|
|
|
|
"CREATE TABLE sip_subscriptions (\n"
|
|
|
|
" proto VARCHAR(255),\n"
|
2007-11-15 16:55:46 +00:00
|
|
|
" sip_user VARCHAR(255),\n"
|
|
|
|
" sip_host VARCHAR(255),\n"
|
2007-04-04 03:08:17 +00:00
|
|
|
" sub_to_user VARCHAR(255),\n"
|
|
|
|
" sub_to_host VARCHAR(255),\n"
|
2008-09-18 00:01:03 +00:00
|
|
|
" presence_hosts VARCHAR(255),\n"
|
2007-04-04 03:08:17 +00:00
|
|
|
" event VARCHAR(255),\n"
|
|
|
|
" contact VARCHAR(1024),\n"
|
2008-05-27 04:54:52 +00:00
|
|
|
" call_id VARCHAR(255),\n"
|
|
|
|
" full_from VARCHAR(255),\n"
|
|
|
|
" full_via VARCHAR(255),\n"
|
2014-07-10 10:17:38 -05:00
|
|
|
" expires BIGINT,\n"
|
2010-02-06 03:38:24 +00:00
|
|
|
" user_agent VARCHAR(255),\n"
|
2008-09-18 00:01:03 +00:00
|
|
|
" accept VARCHAR(255),\n"
|
|
|
|
" profile_name VARCHAR(255),\n"
|
2010-02-22 23:41:56 +00:00
|
|
|
" hostname VARCHAR(255),\n"
|
|
|
|
" network_port VARCHAR(6),\n"
|
2010-10-01 14:04:06 -05:00
|
|
|
" network_ip VARCHAR(255),\n"
|
2011-10-24 09:49:34 -05:00
|
|
|
" version INTEGER DEFAULT 0 NOT NULL,\n"
|
2011-12-15 16:30:33 -06:00
|
|
|
" orig_proto VARCHAR(255),\n"
|
|
|
|
" full_to VARCHAR(255)\n"
|
2010-02-22 23:41:56 +00:00
|
|
|
");\n";
|
2008-05-28 20:58:57 +00:00
|
|
|
|
2010-02-06 03:38:24 +00:00
|
|
|
char auth_sql[] =
|
|
|
|
"CREATE TABLE sip_authentication (\n"
|
|
|
|
" nonce VARCHAR(255),\n"
|
2014-07-10 10:17:38 -05:00
|
|
|
" expires BIGINT,"
|
2010-02-22 23:41:56 +00:00
|
|
|
" profile_name VARCHAR(255),\n"
|
|
|
|
" hostname VARCHAR(255),\n"
|
|
|
|
" last_nc INTEGER\n"
|
|
|
|
");\n";
|
2008-05-27 04:54:52 +00:00
|
|
|
|
2009-01-30 16:46:37 +00:00
|
|
|
/* should we move this glue to sofia_sla or keep it here where all db init happens? XXX MTK */
|
2010-02-06 03:38:24 +00:00
|
|
|
char shared_appearance_sql[] =
|
2009-01-30 16:46:37 +00:00
|
|
|
"CREATE TABLE sip_shared_appearance_subscriptions (\n"
|
|
|
|
" subscriber VARCHAR(255),\n"
|
|
|
|
" call_id VARCHAR(255),\n"
|
|
|
|
" aor VARCHAR(255),\n"
|
|
|
|
" profile_name VARCHAR(255),\n"
|
2010-02-22 23:41:56 +00:00
|
|
|
" hostname VARCHAR(255),\n"
|
|
|
|
" contact_str VARCHAR(255),\n"
|
|
|
|
" network_ip VARCHAR(255)\n"
|
|
|
|
");\n";
|
2009-01-30 16:46:37 +00:00
|
|
|
|
2010-02-06 03:38:24 +00:00
|
|
|
char shared_appearance_dialogs_sql[] =
|
2009-03-22 05:15:17 +00:00
|
|
|
"CREATE TABLE sip_shared_appearance_dialogs (\n"
|
|
|
|
" profile_name VARCHAR(255),\n"
|
|
|
|
" hostname VARCHAR(255),\n"
|
|
|
|
" contact_str VARCHAR(255),\n"
|
2010-02-22 23:41:56 +00:00
|
|
|
" call_id VARCHAR(255),\n"
|
|
|
|
" network_ip VARCHAR(255),\n"
|
2014-07-10 10:17:38 -05:00
|
|
|
" expires BIGINT\n"
|
2010-02-22 23:41:56 +00:00
|
|
|
");\n";
|
2009-03-22 05:15:17 +00:00
|
|
|
|
2010-08-04 09:56:53 -05:00
|
|
|
|
|
|
|
int x;
|
|
|
|
char *indexes[] = {
|
|
|
|
"create index sr_call_id on sip_registrations (call_id)",
|
|
|
|
"create index sr_sip_user on sip_registrations (sip_user)",
|
|
|
|
"create index sr_sip_host on sip_registrations (sip_host)",
|
2012-01-10 17:33:40 -06:00
|
|
|
"create index sr_sub_host on sip_registrations (sub_host)",
|
2011-10-25 16:55:33 -04:00
|
|
|
"create index sr_mwi_user on sip_registrations (mwi_user)",
|
|
|
|
"create index sr_mwi_host on sip_registrations (mwi_host)",
|
2010-08-04 09:56:53 -05:00
|
|
|
"create index sr_profile_name on sip_registrations (profile_name)",
|
|
|
|
"create index sr_presence_hosts on sip_registrations (presence_hosts)",
|
|
|
|
"create index sr_contact on sip_registrations (contact)",
|
|
|
|
"create index sr_expires on sip_registrations (expires)",
|
2014-09-22 10:44:53 +02:00
|
|
|
"create index sr_ping_expires on sip_registrations (ping_expires)",
|
2010-08-04 09:56:53 -05:00
|
|
|
"create index sr_hostname on sip_registrations (hostname)",
|
|
|
|
"create index sr_status on sip_registrations (status)",
|
2014-09-09 09:43:47 +02:00
|
|
|
"create index sr_ping_status on sip_registrations (ping_status)",
|
2010-08-04 09:56:53 -05:00
|
|
|
"create index sr_network_ip on sip_registrations (network_ip)",
|
|
|
|
"create index sr_network_port on sip_registrations (network_port)",
|
|
|
|
"create index sr_sip_username on sip_registrations (sip_username)",
|
|
|
|
"create index sr_sip_realm on sip_registrations (sip_realm)",
|
|
|
|
"create index sr_orig_server_host on sip_registrations (orig_server_host)",
|
|
|
|
"create index sr_orig_hostname on sip_registrations (orig_hostname)",
|
|
|
|
"create index ss_call_id on sip_subscriptions (call_id)",
|
2013-11-13 21:41:37 +05:00
|
|
|
"create index ss_multi on sip_subscriptions (call_id, profile_name, hostname)",
|
2010-08-04 09:56:53 -05:00
|
|
|
"create index ss_hostname on sip_subscriptions (hostname)",
|
|
|
|
"create index ss_network_ip on sip_subscriptions (network_ip)",
|
|
|
|
"create index ss_sip_user on sip_subscriptions (sip_user)",
|
|
|
|
"create index ss_sip_host on sip_subscriptions (sip_host)",
|
|
|
|
"create index ss_presence_hosts on sip_subscriptions (presence_hosts)",
|
|
|
|
"create index ss_event on sip_subscriptions (event)",
|
|
|
|
"create index ss_proto on sip_subscriptions (proto)",
|
|
|
|
"create index ss_sub_to_user on sip_subscriptions (sub_to_user)",
|
|
|
|
"create index ss_sub_to_host on sip_subscriptions (sub_to_host)",
|
2011-10-25 16:55:33 -04:00
|
|
|
"create index ss_expires on sip_subscriptions (expires)",
|
|
|
|
"create index ss_orig_proto on sip_subscriptions (orig_proto)",
|
|
|
|
"create index ss_network_port on sip_subscriptions (network_port)",
|
|
|
|
"create index ss_profile_name on sip_subscriptions (profile_name)",
|
|
|
|
"create index ss_version on sip_subscriptions (version)",
|
|
|
|
"create index ss_full_from on sip_subscriptions (full_from)",
|
|
|
|
"create index ss_contact on sip_subscriptions (contact)",
|
2010-08-04 09:56:53 -05:00
|
|
|
"create index sd_uuid on sip_dialogs (uuid)",
|
|
|
|
"create index sd_hostname on sip_dialogs (hostname)",
|
|
|
|
"create index sd_presence_data on sip_dialogs (presence_data)",
|
|
|
|
"create index sd_call_info on sip_dialogs (call_info)",
|
|
|
|
"create index sd_call_info_state on sip_dialogs (call_info_state)",
|
|
|
|
"create index sd_expires on sip_dialogs (expires)",
|
2011-10-25 07:42:47 -05:00
|
|
|
"create index sd_rcd on sip_dialogs (rcd)",
|
2011-10-25 16:55:33 -04:00
|
|
|
"create index sd_sip_to_tag on sip_dialogs (sip_to_tag)",
|
|
|
|
"create index sd_sip_from_user on sip_dialogs (sip_from_user)",
|
|
|
|
"create index sd_sip_from_host on sip_dialogs (sip_from_host)",
|
|
|
|
"create index sd_sip_to_host on sip_dialogs (sip_to_host)",
|
|
|
|
"create index sd_presence_id on sip_dialogs (presence_id)",
|
|
|
|
"create index sd_call_id on sip_dialogs (call_id)",
|
|
|
|
"create index sd_sip_from_tag on sip_dialogs (sip_from_tag)",
|
2010-08-04 09:56:53 -05:00
|
|
|
"create index sp_hostname on sip_presence (hostname)",
|
2011-10-25 16:55:33 -04:00
|
|
|
"create index sp_open_closed on sip_presence (open_closed)",
|
|
|
|
"create index sp_sip_user on sip_presence (sip_user)",
|
|
|
|
"create index sp_sip_host on sip_presence (sip_host)",
|
|
|
|
"create index sp_profile_name on sip_presence (profile_name)",
|
|
|
|
"create index sp_expires on sip_presence (expires)",
|
2010-08-04 09:56:53 -05:00
|
|
|
"create index sa_nonce on sip_authentication (nonce)",
|
|
|
|
"create index sa_hostname on sip_authentication (hostname)",
|
2011-10-25 16:55:33 -04:00
|
|
|
"create index sa_expires on sip_authentication (expires)",
|
|
|
|
"create index sa_last_nc on sip_authentication (last_nc)",
|
2010-08-04 09:56:53 -05:00
|
|
|
"create index ssa_hostname on sip_shared_appearance_subscriptions (hostname)",
|
|
|
|
"create index ssa_network_ip on sip_shared_appearance_subscriptions (network_ip)",
|
|
|
|
"create index ssa_subscriber on sip_shared_appearance_subscriptions (subscriber)",
|
|
|
|
"create index ssa_profile_name on sip_shared_appearance_subscriptions (profile_name)",
|
|
|
|
"create index ssa_aor on sip_shared_appearance_subscriptions (aor)",
|
|
|
|
"create index ssd_profile_name on sip_shared_appearance_dialogs (profile_name)",
|
|
|
|
"create index ssd_hostname on sip_shared_appearance_dialogs (hostname)",
|
|
|
|
"create index ssd_contact_str on sip_shared_appearance_dialogs (contact_str)",
|
|
|
|
"create index ssd_call_id on sip_shared_appearance_dialogs (call_id)",
|
|
|
|
"create index ssd_expires on sip_shared_appearance_dialogs (expires)",
|
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
|
|
|
switch_cache_db_handle_t *dbh = sofia_glue_get_db_handle(profile);
|
2012-10-25 11:31:42 -05:00
|
|
|
char *test2;
|
2013-02-08 13:18:13 -06:00
|
|
|
char *err;
|
2012-10-25 11:31:42 -05:00
|
|
|
|
2010-08-04 09:56:53 -05:00
|
|
|
if (!dbh) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2014-03-11 15:17:02 -05:00
|
|
|
test_sql = switch_mprintf("delete from sip_registrations where sub_host is null "
|
|
|
|
"and hostname='%q' "
|
2010-08-04 09:56:53 -05:00
|
|
|
"and network_ip like '%%' and network_port like '%%' and sip_username "
|
|
|
|
"like '%%' and mwi_user like '%%' and mwi_host like '%%' "
|
2012-01-24 17:38:36 -06:00
|
|
|
"and orig_server_host like '%%' and orig_hostname like '%%'", mod_sofia_globals.hostname);
|
2010-02-06 03:38:24 +00:00
|
|
|
|
|
|
|
|
2010-08-04 09:56:53 -05:00
|
|
|
switch_cache_db_test_reactive(dbh, test_sql, "drop table sip_registrations", reg_sql);
|
2014-09-09 09:43:47 +02:00
|
|
|
|
|
|
|
switch_cache_db_test_reactive(dbh, "select ping_count from sip_registrations", NULL, "alter table sip_registrations add column ping_count INTEGER default 0");
|
2015-07-06 12:06:17 -03:00
|
|
|
switch_cache_db_test_reactive(dbh, "select ping_status from sip_registrations", NULL, "alter table sip_registrations add column ping_status VARCHAR(255) default 'Reachable'");
|
2014-09-22 10:44:53 +02:00
|
|
|
switch_cache_db_test_reactive(dbh, "select ping_expires from sip_registrations", NULL, "alter table sip_registrations add column ping_expires INTEGER not null default 0");
|
2015-09-18 16:55:10 -05:00
|
|
|
switch_cache_db_test_reactive(dbh, "select ping_time from sip_registrations", NULL, "alter table sip_registrations add column ping_time BIGINT not null default 0");
|
|
|
|
switch_cache_db_test_reactive(dbh, "select force_ping from sip_registrations", NULL, "alter table sip_registrations add column force_ping INTEGER not null default 0");
|
2012-10-25 11:31:42 -05:00
|
|
|
|
|
|
|
test2 = switch_mprintf("%s;%s", test_sql, test_sql);
|
2010-08-04 09:56:53 -05:00
|
|
|
|
2013-02-08 13:18:13 -06:00
|
|
|
if (switch_cache_db_execute_sql(dbh, test2, &err) != SWITCH_STATUS_SUCCESS) {
|
|
|
|
|
|
|
|
if (switch_stristr("read-only", err)) {
|
|
|
|
free(err);
|
|
|
|
} else {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "GREAT SCOTT!!! Cannot execute batched statements! [%s]\n"
|
|
|
|
"If you are using mysql, make sure you are using MYODBC 3.51.18 or higher and enable FLAG_MULTI_STATEMENTS\n", err);
|
|
|
|
|
|
|
|
switch_cache_db_release_db_handle(&dbh);
|
|
|
|
free(test2);
|
|
|
|
free(test_sql);
|
|
|
|
free(err);
|
|
|
|
return 0;
|
|
|
|
}
|
2010-08-04 09:56:53 -05:00
|
|
|
}
|
2007-04-04 03:08:17 +00:00
|
|
|
|
2012-10-25 11:31:42 -05:00
|
|
|
free(test2);
|
|
|
|
|
|
|
|
|
2010-08-04 09:56:53 -05:00
|
|
|
free(test_sql);
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2011-12-15 16:30:33 -06:00
|
|
|
test_sql = switch_mprintf("delete from sip_subscriptions where hostname='%q' and full_to='XXX'", mod_sofia_globals.hostname);
|
|
|
|
|
2010-08-04 09:56:53 -05:00
|
|
|
switch_cache_db_test_reactive(dbh, test_sql, "DROP TABLE sip_subscriptions", sub_sql);
|
2009-01-30 16:46:37 +00:00
|
|
|
|
2010-08-04 09:56:53 -05:00
|
|
|
free(test_sql);
|
2011-10-26 08:45:04 -05:00
|
|
|
test_sql = switch_mprintf("delete from sip_dialogs where hostname='%q' and (expires <> -9999 or rpid='' or sip_from_tag='' or rcd > 0)",
|
2011-10-24 18:54:22 -05:00
|
|
|
mod_sofia_globals.hostname);
|
2010-02-06 03:38:24 +00:00
|
|
|
|
|
|
|
|
2010-08-04 09:56:53 -05:00
|
|
|
switch_cache_db_test_reactive(dbh, test_sql, "DROP TABLE sip_dialogs", dialog_sql);
|
|
|
|
|
|
|
|
free(test_sql);
|
|
|
|
test_sql = switch_mprintf("delete from sip_presence where hostname='%q' or open_closed=''", mod_sofia_globals.hostname);
|
2009-03-22 05:15:17 +00:00
|
|
|
|
2010-08-04 09:56:53 -05:00
|
|
|
switch_cache_db_test_reactive(dbh, test_sql, "DROP TABLE sip_presence", pres_sql);
|
2009-01-30 16:46:37 +00:00
|
|
|
|
2010-08-04 09:56:53 -05:00
|
|
|
free(test_sql);
|
|
|
|
test_sql = switch_mprintf("delete from sip_authentication where hostname='%q' or last_nc >= 0", mod_sofia_globals.hostname);
|
2009-11-12 03:52:07 +00:00
|
|
|
|
2010-08-04 09:56:53 -05:00
|
|
|
switch_cache_db_test_reactive(dbh, test_sql, "DROP TABLE sip_authentication", auth_sql);
|
2009-11-12 03:52:07 +00:00
|
|
|
|
2010-08-04 09:56:53 -05:00
|
|
|
free(test_sql);
|
|
|
|
test_sql = switch_mprintf("delete from sip_shared_appearance_subscriptions where contact_str='' or hostname='%q' and network_ip like '%%'",
|
|
|
|
mod_sofia_globals.hostname);
|
2009-11-12 03:52:07 +00:00
|
|
|
|
2010-08-04 09:56:53 -05:00
|
|
|
switch_cache_db_test_reactive(dbh, test_sql, "DROP TABLE sip_shared_appearance_subscriptions", shared_appearance_sql);
|
2009-11-12 03:52:07 +00:00
|
|
|
|
2010-08-04 09:56:53 -05:00
|
|
|
free(test_sql);
|
|
|
|
test_sql = switch_mprintf("delete from sip_shared_appearance_dialogs where contact_str='' or hostname='%q' and network_ip like '%%'",
|
|
|
|
mod_sofia_globals.hostname);
|
2009-11-12 03:52:07 +00:00
|
|
|
|
2010-08-04 09:56:53 -05:00
|
|
|
switch_cache_db_test_reactive(dbh, test_sql, "DROP TABLE sip_shared_appearance_dialogs", shared_appearance_dialogs_sql);
|
|
|
|
|
|
|
|
free(test_sql);
|
2007-04-04 03:08:17 +00:00
|
|
|
|
2010-08-04 09:56:53 -05:00
|
|
|
for (x = 0; indexes[x]; x++) {
|
2015-01-22 15:41:22 -05:00
|
|
|
switch_cache_db_create_schema(dbh, indexes[x], NULL);
|
2007-05-03 16:28:23 +00:00
|
|
|
}
|
2009-11-12 19:54:50 +00:00
|
|
|
|
2010-08-04 09:56:53 -05:00
|
|
|
switch_cache_db_release_db_handle(&dbh);
|
2007-05-02 23:39:24 +00:00
|
|
|
|
2010-08-04 09:56:53 -05:00
|
|
|
return 1;
|
2009-11-12 19:54:50 +00:00
|
|
|
|
2007-04-04 03:08:17 +00:00
|
|
|
}
|
|
|
|
|
2008-03-17 16:12:38 +00:00
|
|
|
void sofia_glue_execute_sql(sofia_profile_t *profile, char **sqlp, switch_bool_t sql_already_dynamic)
|
2008-03-04 23:53:23 +00:00
|
|
|
{
|
2012-10-25 11:31:42 -05:00
|
|
|
char *sql;
|
2008-03-05 20:31:18 +00:00
|
|
|
|
|
|
|
switch_assert(sqlp && *sqlp);
|
2012-10-25 11:31:42 -05:00
|
|
|
sql = *sqlp;
|
2008-05-27 04:54:52 +00:00
|
|
|
|
2012-11-16 20:09:38 -06:00
|
|
|
switch_sql_queue_manager_push(profile->qm, sql, 1, !sql_already_dynamic);
|
2008-03-17 16:12:38 +00:00
|
|
|
|
|
|
|
if (sql_already_dynamic) {
|
|
|
|
*sqlp = NULL;
|
|
|
|
}
|
2008-03-04 23:53:23 +00:00
|
|
|
}
|
|
|
|
|
2012-10-25 11:31:42 -05:00
|
|
|
|
2010-01-09 00:34:17 +00:00
|
|
|
void sofia_glue_execute_sql_now(sofia_profile_t *profile, char **sqlp, switch_bool_t sql_already_dynamic)
|
|
|
|
{
|
2012-10-25 11:31:42 -05:00
|
|
|
char *sql;
|
|
|
|
|
|
|
|
switch_assert(sqlp && *sqlp);
|
|
|
|
sql = *sqlp;
|
|
|
|
|
2013-03-06 18:01:55 -06:00
|
|
|
switch_mutex_lock(profile->dbh_mutex);
|
2012-10-25 15:09:09 -05:00
|
|
|
switch_sql_queue_manager_push_confirm(profile->qm, sql, 0, !sql_already_dynamic);
|
2013-03-06 18:01:55 -06:00
|
|
|
switch_mutex_unlock(profile->dbh_mutex);
|
2012-10-25 11:31:42 -05:00
|
|
|
|
2010-01-09 00:34:17 +00:00
|
|
|
if (sql_already_dynamic) {
|
2012-10-25 11:31:42 -05:00
|
|
|
*sqlp = NULL;
|
2010-01-09 00:34:17 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-11-16 20:09:38 -06:00
|
|
|
void sofia_glue_execute_sql_soon(sofia_profile_t *profile, char **sqlp, switch_bool_t sql_already_dynamic)
|
|
|
|
{
|
|
|
|
char *sql;
|
|
|
|
|
|
|
|
switch_assert(sqlp && *sqlp);
|
|
|
|
sql = *sqlp;
|
|
|
|
|
|
|
|
switch_sql_queue_manager_push(profile->qm, sql, 0, !sql_already_dynamic);
|
|
|
|
|
|
|
|
if (sql_already_dynamic) {
|
|
|
|
*sqlp = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-11-12 19:54:50 +00:00
|
|
|
|
2012-10-09 20:20:32 -05:00
|
|
|
switch_cache_db_handle_t *_sofia_glue_get_db_handle(sofia_profile_t *profile, const char *file, const char *func, int line)
|
2009-11-12 19:54:50 +00:00
|
|
|
{
|
2009-11-21 18:57:15 +00:00
|
|
|
switch_cache_db_handle_t *dbh = NULL;
|
2012-10-09 20:20:32 -05:00
|
|
|
char *dsn;
|
|
|
|
|
2010-01-13 18:02:42 +00:00
|
|
|
if (!zstr(profile->odbc_dsn)) {
|
2012-10-09 20:20:32 -05:00
|
|
|
dsn = profile->odbc_dsn;
|
2009-11-21 18:57:15 +00:00
|
|
|
} else {
|
2012-10-09 20:20:32 -05:00
|
|
|
dsn = profile->dbname;
|
2009-11-12 19:54:50 +00:00
|
|
|
}
|
2012-10-09 20:20:32 -05:00
|
|
|
|
|
|
|
if (_switch_cache_db_get_db_handle_dsn(&dbh, dsn, file, func, line) != SWITCH_STATUS_SUCCESS) {
|
|
|
|
dbh = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
return dbh;
|
2009-11-12 19:54:50 +00:00
|
|
|
}
|
|
|
|
|
2009-11-21 18:57:15 +00:00
|
|
|
void sofia_glue_actually_execute_sql_trans(sofia_profile_t *profile, char *sql, switch_mutex_t *mutex)
|
2009-11-12 03:52:07 +00:00
|
|
|
{
|
2009-11-21 18:57:15 +00:00
|
|
|
switch_cache_db_handle_t *dbh = NULL;
|
2009-11-12 19:54:50 +00:00
|
|
|
|
2013-02-25 15:42:21 -06:00
|
|
|
if (mutex) {
|
|
|
|
switch_mutex_lock(mutex);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-11-21 18:57:15 +00:00
|
|
|
if (!(dbh = sofia_glue_get_db_handle(profile))) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB\n");
|
2013-03-06 13:59:02 -06:00
|
|
|
|
|
|
|
goto end;
|
2009-11-21 18:57:15 +00:00
|
|
|
}
|
2009-11-12 19:54:50 +00:00
|
|
|
|
2012-10-09 20:20:32 -05:00
|
|
|
switch_cache_db_persistant_execute_trans_full(dbh, sql, 1,
|
|
|
|
profile->pre_trans_execute,
|
|
|
|
profile->post_trans_execute,
|
|
|
|
profile->inner_pre_trans_execute,
|
|
|
|
profile->inner_post_trans_execute
|
|
|
|
);
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2009-11-21 18:57:15 +00:00
|
|
|
switch_cache_db_release_db_handle(&dbh);
|
2009-11-12 03:52:07 +00:00
|
|
|
|
2013-03-06 13:59:02 -06:00
|
|
|
end:
|
|
|
|
|
2009-11-21 18:57:15 +00:00
|
|
|
if (mutex) {
|
|
|
|
switch_mutex_unlock(mutex);
|
|
|
|
}
|
2009-11-12 03:52:07 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void sofia_glue_actually_execute_sql(sofia_profile_t *profile, char *sql, switch_mutex_t *mutex)
|
2007-03-31 19:01:33 +00:00
|
|
|
{
|
2009-11-21 18:57:15 +00:00
|
|
|
switch_cache_db_handle_t *dbh = NULL;
|
2012-01-26 15:53:05 -06:00
|
|
|
char *err = NULL;
|
2007-03-31 19:01:33 +00:00
|
|
|
|
2013-02-25 15:42:21 -06:00
|
|
|
if (mutex) {
|
|
|
|
switch_mutex_lock(mutex);
|
|
|
|
}
|
|
|
|
|
2009-11-12 19:54:50 +00:00
|
|
|
if (!(dbh = sofia_glue_get_db_handle(profile))) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB\n");
|
2013-03-06 13:59:02 -06:00
|
|
|
|
|
|
|
if (mutex) {
|
|
|
|
switch_mutex_unlock(mutex);
|
|
|
|
}
|
|
|
|
|
2012-10-08 13:28:01 -05:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-01-26 15:53:05 -06:00
|
|
|
switch_cache_db_execute_sql(dbh, sql, &err);
|
|
|
|
|
2012-10-08 13:28:01 -05:00
|
|
|
if (mutex) {
|
|
|
|
switch_mutex_unlock(mutex);
|
|
|
|
}
|
|
|
|
|
2012-01-26 15:53:05 -06:00
|
|
|
if (err) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL ERR: [%s]\n%s\n", err, sql);
|
|
|
|
free(err);
|
|
|
|
}
|
2007-03-31 19:01:33 +00:00
|
|
|
|
2009-11-21 18:57:15 +00:00
|
|
|
switch_cache_db_release_db_handle(&dbh);
|
2007-03-31 19:01:33 +00:00
|
|
|
}
|
|
|
|
|
2007-04-04 03:08:17 +00:00
|
|
|
switch_bool_t sofia_glue_execute_sql_callback(sofia_profile_t *profile,
|
2009-11-12 03:52:07 +00:00
|
|
|
switch_mutex_t *mutex, char *sql, switch_core_db_callback_func_t callback, void *pdata)
|
2007-04-04 03:08:17 +00:00
|
|
|
{
|
|
|
|
switch_bool_t ret = SWITCH_FALSE;
|
|
|
|
char *errmsg = NULL;
|
2009-11-21 18:57:15 +00:00
|
|
|
switch_cache_db_handle_t *dbh = NULL;
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2013-02-25 15:42:21 -06:00
|
|
|
if (mutex) {
|
|
|
|
switch_mutex_lock(mutex);
|
|
|
|
}
|
|
|
|
|
2009-11-12 19:54:50 +00:00
|
|
|
if (!(dbh = sofia_glue_get_db_handle(profile))) {
|
2010-02-06 03:38:24 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB\n");
|
2013-03-06 13:59:02 -06:00
|
|
|
|
|
|
|
if (mutex) {
|
|
|
|
switch_mutex_unlock(mutex);
|
|
|
|
}
|
|
|
|
|
2012-10-08 13:28:01 -05:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2009-11-21 18:57:15 +00:00
|
|
|
switch_cache_db_execute_sql_callback(dbh, sql, callback, pdata, &errmsg);
|
2007-04-04 03:08:17 +00:00
|
|
|
|
2012-10-08 13:28:01 -05:00
|
|
|
if (mutex) {
|
|
|
|
switch_mutex_unlock(mutex);
|
|
|
|
}
|
|
|
|
|
2009-11-21 18:57:15 +00:00
|
|
|
if (errmsg) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL ERR: [%s] %s\n", sql, errmsg);
|
|
|
|
free(errmsg);
|
2008-05-27 04:54:52 +00:00
|
|
|
}
|
2007-04-04 03:08:17 +00:00
|
|
|
|
2009-11-21 18:57:15 +00:00
|
|
|
switch_cache_db_release_db_handle(&dbh);
|
2007-04-04 03:08:17 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
2009-06-24 16:02:43 +00:00
|
|
|
|
2007-04-04 03:08:17 +00:00
|
|
|
char *sofia_glue_execute_sql2str(sofia_profile_t *profile, switch_mutex_t *mutex, char *sql, char *resbuf, size_t len)
|
|
|
|
{
|
|
|
|
char *ret = NULL;
|
2012-01-26 15:53:05 -06:00
|
|
|
char *err = NULL;
|
2009-11-21 18:57:15 +00:00
|
|
|
switch_cache_db_handle_t *dbh = NULL;
|
2009-11-12 19:54:50 +00:00
|
|
|
|
2013-02-25 15:42:21 -06:00
|
|
|
if (mutex) {
|
|
|
|
switch_mutex_lock(mutex);
|
|
|
|
}
|
|
|
|
|
2009-11-12 19:54:50 +00:00
|
|
|
if (!(dbh = sofia_glue_get_db_handle(profile))) {
|
2010-02-06 03:38:24 +00:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Opening DB\n");
|
2013-03-06 13:59:02 -06:00
|
|
|
|
|
|
|
if (mutex) {
|
|
|
|
switch_mutex_unlock(mutex);
|
|
|
|
}
|
|
|
|
|
2009-11-21 18:57:15 +00:00
|
|
|
return NULL;
|
2010-02-06 03:38:24 +00:00
|
|
|
}
|
2007-04-04 03:08:17 +00:00
|
|
|
|
2012-01-26 15:53:05 -06:00
|
|
|
ret = switch_cache_db_execute_sql2str(dbh, sql, resbuf, len, &err);
|
|
|
|
|
2012-10-08 13:28:01 -05:00
|
|
|
if (mutex) {
|
|
|
|
switch_mutex_unlock(mutex);
|
|
|
|
}
|
|
|
|
|
2012-01-26 15:53:05 -06:00
|
|
|
if (err) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SQL ERR: [%s]\n%s\n", err, sql);
|
|
|
|
free(err);
|
|
|
|
}
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2009-11-21 18:57:15 +00:00
|
|
|
switch_cache_db_release_db_handle(&dbh);
|
2009-11-12 19:54:50 +00:00
|
|
|
|
2007-04-04 03:08:17 +00:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2010-11-22 14:59:25 -06:00
|
|
|
char *sofia_glue_get_register_host(const char *uri)
|
|
|
|
{
|
|
|
|
char *register_host = NULL;
|
|
|
|
const char *s;
|
|
|
|
char *p = NULL;
|
|
|
|
|
2010-11-22 15:32:23 -06:00
|
|
|
if (zstr(uri)) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2010-11-22 14:59:25 -06:00
|
|
|
if ((s = switch_stristr("sip:", uri))) {
|
|
|
|
s += 4;
|
|
|
|
} else if ((s = switch_stristr("sips:", uri))) {
|
|
|
|
s += 5;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!s) {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
register_host = strdup(s);
|
|
|
|
|
|
|
|
/* remove port for register_host for testing nat acl take into account
|
|
|
|
ipv6 addresses which are required to have brackets around the addr
|
|
|
|
*/
|
2010-11-22 15:32:23 -06:00
|
|
|
|
|
|
|
if ((p = strchr(register_host, ']'))) {
|
|
|
|
if (*(p + 1) == ':') {
|
|
|
|
*(p + 1) = '\0';
|
|
|
|
}
|
|
|
|
} else {
|
2010-11-22 14:59:25 -06:00
|
|
|
if ((p = strrchr(register_host, ':'))) {
|
|
|
|
*p = '\0';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* register_proxy should always start with "sip:" or "sips:" */
|
|
|
|
assert(register_host);
|
|
|
|
|
|
|
|
return register_host;
|
|
|
|
}
|
|
|
|
|
2008-06-27 23:34:33 +00:00
|
|
|
const char *sofia_glue_strip_proto(const char *uri)
|
|
|
|
{
|
|
|
|
char *p;
|
|
|
|
|
|
|
|
if ((p = strchr(uri, ':'))) {
|
2010-02-06 03:38:24 +00:00
|
|
|
return p + 1;
|
2008-06-27 23:34:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
return uri;
|
|
|
|
}
|
|
|
|
|
2009-03-04 23:03:25 +00:00
|
|
|
sofia_cid_type_t sofia_cid_name2type(const char *name)
|
|
|
|
{
|
|
|
|
if (!strcasecmp(name, "rpid")) {
|
|
|
|
return CID_TYPE_RPID;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!strcasecmp(name, "pid")) {
|
|
|
|
return CID_TYPE_PID;
|
|
|
|
}
|
|
|
|
|
|
|
|
return CID_TYPE_NONE;
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2009-03-04 23:03:25 +00:00
|
|
|
}
|
|
|
|
|
2009-06-19 15:35:26 +00:00
|
|
|
/* all the values of the structure are initialized to NULL */
|
|
|
|
/* in case of failure the function returns NULL */
|
|
|
|
/* sofia_destination->route can be NULL */
|
2010-02-06 03:38:24 +00:00
|
|
|
sofia_destination_t *sofia_glue_get_destination(char *data)
|
2009-06-19 15:35:26 +00:00
|
|
|
{
|
|
|
|
sofia_destination_t *dst = NULL;
|
|
|
|
char *to = NULL;
|
|
|
|
char *contact = NULL;
|
2010-02-06 03:38:24 +00:00
|
|
|
char *route = NULL;
|
|
|
|
char *route_uri = NULL;
|
2009-06-19 15:35:26 +00:00
|
|
|
char *eoc = NULL;
|
|
|
|
char *p = NULL;
|
|
|
|
|
2009-10-23 16:03:42 +00:00
|
|
|
if (zstr(data)) {
|
2009-06-19 15:35:26 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2010-02-06 03:38:24 +00:00
|
|
|
if (!(dst = (sofia_destination_t *) malloc(sizeof(sofia_destination_t)))) {
|
2009-06-19 15:35:26 +00:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* return a copy of what is in the buffer between the first < and > */
|
|
|
|
if (!(contact = sofia_glue_get_url_from_contact(data, 1))) {
|
|
|
|
goto mem_fail;
|
|
|
|
}
|
|
|
|
|
2009-12-11 01:20:26 +00:00
|
|
|
if ((eoc = strstr(contact, ";fs_path="))) {
|
2009-06-19 15:35:26 +00:00
|
|
|
*eoc = '\0';
|
|
|
|
|
2009-12-11 01:20:26 +00:00
|
|
|
if (!(route = strdup(eoc + 9))) {
|
2009-06-19 15:35:26 +00:00
|
|
|
goto mem_fail;
|
|
|
|
}
|
|
|
|
|
2010-02-06 03:38:24 +00:00
|
|
|
for (p = route; p && *p; p++) {
|
2009-06-19 15:35:26 +00:00
|
|
|
if (*p == '>' || *p == ';') {
|
|
|
|
*p = '\0';
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
switch_url_decode(route);
|
|
|
|
|
2010-02-06 03:38:24 +00:00
|
|
|
if (!(route_uri = strdup(route))) {
|
2009-06-19 15:35:26 +00:00
|
|
|
goto mem_fail;
|
|
|
|
}
|
|
|
|
if ((p = strchr(route_uri, ','))) {
|
|
|
|
do {
|
|
|
|
*p = '\0';
|
|
|
|
} while ((--p > route_uri) && *p == ' ');
|
|
|
|
}
|
2010-02-06 03:38:24 +00:00
|
|
|
}
|
|
|
|
|
2009-06-19 15:35:26 +00:00
|
|
|
if (!(to = strdup(data))) {
|
|
|
|
goto mem_fail;
|
|
|
|
}
|
|
|
|
|
2009-12-11 01:20:26 +00:00
|
|
|
if ((eoc = strstr(to, ";fs_path="))) {
|
2010-02-06 03:38:24 +00:00
|
|
|
*eoc++ = '>';
|
|
|
|
*eoc = '\0';
|
2009-06-19 15:35:26 +00:00
|
|
|
}
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2009-06-19 15:35:26 +00:00
|
|
|
if ((p = strstr(contact, ";fs_"))) {
|
|
|
|
*p = '\0';
|
|
|
|
}
|
2010-02-06 03:38:24 +00:00
|
|
|
|
2009-06-19 15:35:26 +00:00
|
|
|
dst->contact = contact;
|
|
|
|
dst->to = to;
|
|
|
|
dst->route = route;
|
|
|
|
dst->route_uri = route_uri;
|
|
|
|
return dst;
|
|
|
|
|
2010-06-30 10:35:03 -05:00
|
|
|
mem_fail:
|
2009-06-19 15:35:26 +00:00
|
|
|
switch_safe_free(contact);
|
|
|
|
switch_safe_free(to);
|
|
|
|
switch_safe_free(route);
|
|
|
|
switch_safe_free(route_uri);
|
|
|
|
switch_safe_free(dst);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
void sofia_glue_free_destination(sofia_destination_t *dst)
|
|
|
|
{
|
|
|
|
if (dst) {
|
|
|
|
switch_safe_free(dst->contact);
|
|
|
|
switch_safe_free(dst->route);
|
|
|
|
switch_safe_free(dst->route_uri);
|
|
|
|
switch_safe_free(dst->to);
|
|
|
|
switch_safe_free(dst);
|
|
|
|
}
|
|
|
|
}
|
2008-06-27 23:34:33 +00:00
|
|
|
|
2010-02-06 03:38:24 +00:00
|
|
|
switch_status_t sofia_glue_send_notify(sofia_profile_t *profile, const char *user, const char *host, const char *event, const char *contenttype,
|
2012-05-21 13:55:50 -05:00
|
|
|
const char *body, const char *o_contact, const char *network_ip, const char *call_id)
|
2009-08-21 00:59:09 +00:00
|
|
|
{
|
|
|
|
char *id = NULL;
|
|
|
|
nua_handle_t *nh;
|
|
|
|
sofia_destination_t *dst = NULL;
|
|
|
|
char *contact_str, *contact, *user_via = NULL;
|
2012-01-26 04:46:48 -06:00
|
|
|
char *route_uri = NULL, *p;
|
2014-04-24 14:05:15 -05:00
|
|
|
char *ptr;
|
2009-08-21 00:59:09 +00:00
|
|
|
|
2010-02-06 03:38:24 +00:00
|
|
|
contact = sofia_glue_get_url_from_contact((char *) o_contact, 1);
|
2012-01-26 04:46:48 -06:00
|
|
|
|
|
|
|
if ((p = strstr(contact, ";fs_"))) {
|
|
|
|
*p = '\0';
|
|
|
|
}
|
|
|
|
|
2010-03-02 16:21:28 +00:00
|
|
|
if (!zstr(network_ip) && sofia_glue_check_nat(profile, network_ip)) {
|
2009-08-21 00:59:09 +00:00
|
|
|
id = switch_mprintf("sip:%s@%s", user, profile->extsipip);
|
|
|
|
switch_assert(id);
|
|
|
|
|
|
|
|
if ((ptr = sofia_glue_find_parameter(o_contact, "transport="))) {
|
2014-04-24 14:05:15 -05:00
|
|
|
sofia_transport_t transport = sofia_glue_str2transport( ptr + 10 );
|
|
|
|
|
2009-08-21 00:59:09 +00:00
|
|
|
switch (transport) {
|
2010-02-06 03:38:24 +00:00
|
|
|
case SOFIA_TRANSPORT_TCP:
|
|
|
|
contact_str = profile->tcp_public_contact;
|
|
|
|
break;
|
|
|
|
case SOFIA_TRANSPORT_TCP_TLS:
|
2014-10-10 18:25:11 +00:00
|
|
|
contact_str = sofia_test_pflag(profile, PFLAG_TLS) ?
|
|
|
|
profile->tls_public_contact : profile->tcp_public_contact;
|
2010-02-06 03:38:24 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
contact_str = profile->public_url;
|
|
|
|
break;
|
2009-08-21 00:59:09 +00:00
|
|
|
}
|
|
|
|
user_via = sofia_glue_create_external_via(NULL, profile, transport);
|
|
|
|
} else {
|
|
|
|
user_via = sofia_glue_create_external_via(NULL, profile, SOFIA_TRANSPORT_UDP);
|
2014-04-24 14:05:15 -05:00
|
|
|
contact_str = profile->public_url;
|
2009-08-21 00:59:09 +00:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
id = switch_mprintf("sip:%s@%s", user, host);
|
2014-04-24 14:05:15 -05:00
|
|
|
switch_assert(id);
|
|
|
|
|
|
|
|
if ((ptr = sofia_glue_find_parameter(o_contact, "transport="))) {
|
|
|
|
sofia_transport_t transport = sofia_glue_str2transport( ptr + 10 );
|
|
|
|
|
|
|
|
switch (transport) {
|
|
|
|
case SOFIA_TRANSPORT_TCP:
|
|
|
|
contact_str = profile->tcp_contact;
|
|
|
|
break;
|
|
|
|
case SOFIA_TRANSPORT_TCP_TLS:
|
2014-10-10 18:25:11 +00:00
|
|
|
contact_str = sofia_test_pflag(profile, PFLAG_TLS) ?
|
|
|
|
profile->tls_contact : profile->tcp_contact;
|
2014-04-24 14:05:15 -05:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
contact_str = profile->url;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
contact_str = profile->url;
|
|
|
|
}
|
2009-08-21 00:59:09 +00:00
|
|
|
}
|
|
|
|
|
2010-02-06 03:38:24 +00:00
|
|
|
dst = sofia_glue_get_destination((char *) o_contact);
|
2009-08-21 00:59:09 +00:00
|
|
|
switch_assert(dst);
|
|
|
|
|
2009-12-11 01:20:26 +00:00
|
|
|
if (dst->route_uri) {
|
2009-09-14 19:43:15 +00:00
|
|
|
route_uri = sofia_glue_strip_uri(dst->route_uri);
|
|
|
|
}
|
|
|
|
|
2010-02-06 03:38:24 +00:00
|
|
|
nh = nua_handle(profile->nua, NULL, NUTAG_URL(contact), SIPTAG_FROM_STR(id), SIPTAG_TO_STR(id), SIPTAG_CONTACT_STR(contact_str), TAG_END());
|
2009-08-21 00:59:09 +00:00
|
|
|
nua_handle_bind(nh, &mod_sofia_globals.destroy_private);
|
|
|
|
|
|
|
|
nua_notify(nh,
|
2009-12-24 05:44:23 +00:00
|
|
|
NUTAG_NEWSUB(1),
|
|
|
|
TAG_IF(dst->route_uri, NUTAG_PROXY(route_uri)), TAG_IF(dst->route, SIPTAG_ROUTE_STR(dst->route)),
|
|
|
|
TAG_IF(user_via, SIPTAG_VIA_STR(user_via)),
|
2012-01-17 09:21:47 -06:00
|
|
|
SIPTAG_SUBSCRIPTION_STATE_STR("terminated;reason=noresource"),
|
2009-12-24 05:44:23 +00:00
|
|
|
TAG_IF(event, SIPTAG_EVENT_STR(event)),
|
2012-05-21 13:55:50 -05:00
|
|
|
TAG_IF(call_id, SIPTAG_CALL_ID_STR(call_id)),
|
2010-02-06 03:38:24 +00:00
|
|
|
TAG_IF(contenttype, SIPTAG_CONTENT_TYPE_STR(contenttype)), TAG_IF(body, SIPTAG_PAYLOAD_STR(body)), TAG_END());
|
2009-08-21 00:59:09 +00:00
|
|
|
|
|
|
|
switch_safe_free(contact);
|
2009-09-14 19:43:15 +00:00
|
|
|
switch_safe_free(route_uri);
|
2009-08-21 00:59:09 +00:00
|
|
|
switch_safe_free(id);
|
|
|
|
sofia_glue_free_destination(dst);
|
|
|
|
switch_safe_free(user_via);
|
|
|
|
|
|
|
|
return SWITCH_STATUS_SUCCESS;
|
|
|
|
}
|
|
|
|
|
2010-06-18 17:09:26 -05:00
|
|
|
|
2012-11-29 18:34:27 -06:00
|
|
|
int sofia_glue_tech_simplify(private_object_t *tech_pvt)
|
2010-06-18 17:09:26 -05:00
|
|
|
{
|
2010-07-05 13:13:28 -05:00
|
|
|
const char *uuid, *network_addr_a = NULL, *network_addr_b = NULL, *simplify, *simplify_other_channel;
|
2010-06-18 17:09:26 -05:00
|
|
|
switch_channel_t *other_channel = NULL, *inbound_channel = NULL;
|
|
|
|
switch_core_session_t *other_session = NULL, *inbound_session = NULL;
|
|
|
|
uint8_t did_simplify = 0;
|
2012-11-29 18:34:27 -06:00
|
|
|
int r = 0;
|
2010-06-18 17:09:26 -05:00
|
|
|
|
2011-07-16 02:33:39 -05:00
|
|
|
if (!switch_channel_test_flag(tech_pvt->channel, CF_ANSWERED) || switch_channel_test_flag(tech_pvt->channel, CF_SIMPLIFY)) {
|
2012-11-29 18:34:27 -06:00
|
|
|
goto end;
|
2010-06-18 17:09:26 -05:00
|
|
|
}
|
|
|
|
|
2013-01-30 14:08:08 -06:00
|
|
|
if (switch_channel_test_flag(tech_pvt->channel, CF_BRIDGED) &&
|
|
|
|
(uuid = switch_channel_get_partner_uuid(tech_pvt->channel)) && (other_session = switch_core_session_locate(uuid))) {
|
2010-06-18 17:09:26 -05:00
|
|
|
|
|
|
|
other_channel = switch_core_session_get_channel(other_session);
|
|
|
|
|
2010-06-23 13:22:52 -05:00
|
|
|
if (switch_channel_test_flag(other_channel, CF_ANSWERED)) { /* Check if the other channel is answered */
|
2010-06-18 17:09:26 -05:00
|
|
|
simplify = switch_channel_get_variable(tech_pvt->channel, "sip_auto_simplify");
|
|
|
|
simplify_other_channel = switch_channel_get_variable(other_channel, "sip_auto_simplify");
|
|
|
|
|
2012-11-29 18:34:27 -06:00
|
|
|
r = 1;
|
|
|
|
|
2010-06-18 17:09:26 -05:00
|
|
|
if (switch_true(simplify) && !switch_channel_test_flag(tech_pvt->channel, CF_BRIDGE_ORIGINATOR)) {
|
|
|
|
network_addr_a = switch_channel_get_variable(tech_pvt->channel, "network_addr");
|
|
|
|
network_addr_b = switch_channel_get_variable(other_channel, "network_addr");
|
|
|
|
inbound_session = other_session;
|
|
|
|
inbound_channel = other_channel;
|
|
|
|
} else if (switch_true(simplify_other_channel) && !switch_channel_test_flag(other_channel, CF_BRIDGE_ORIGINATOR)) {
|
|
|
|
network_addr_a = switch_channel_get_variable(other_channel, "network_addr");
|
|
|
|
network_addr_b = switch_channel_get_variable(tech_pvt->channel, "network_addr");
|
|
|
|
inbound_session = tech_pvt->session;
|
|
|
|
inbound_channel = tech_pvt->channel;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (inbound_channel && inbound_session && !zstr(network_addr_a) && !zstr(network_addr_b) && !strcmp(network_addr_a, network_addr_b)) {
|
2010-06-23 13:22:52 -05:00
|
|
|
if (strcmp(network_addr_a, switch_str_nil(tech_pvt->profile->sipip))
|
|
|
|
&& strcmp(network_addr_a, switch_str_nil(tech_pvt->profile->extsipip))) {
|
2010-06-18 17:09:26 -05:00
|
|
|
|
|
|
|
switch_core_session_message_t *msg;
|
2011-07-16 02:33:39 -05:00
|
|
|
|
2010-06-23 13:22:52 -05:00
|
|
|
switch_log_printf(SWITCH_CHANNEL_ID_LOG, __FILE__, __SWITCH_FUNC__, __LINE__, switch_channel_get_uuid(inbound_channel),
|
|
|
|
SWITCH_LOG_NOTICE, "Will simplify channel [%s]\n", switch_channel_get_name(inbound_channel));
|
2011-07-16 02:33:39 -05:00
|
|
|
|
2010-06-18 17:09:26 -05:00
|
|
|
msg = switch_core_session_alloc(inbound_session, sizeof(*msg));
|
|
|
|
MESSAGE_STAMP_FFL(msg);
|
|
|
|
msg->message_id = SWITCH_MESSAGE_INDICATE_SIMPLIFY;
|
|
|
|
msg->from = __FILE__;
|
|
|
|
switch_core_session_receive_message(inbound_session, msg);
|
|
|
|
|
|
|
|
did_simplify = 1;
|
|
|
|
|
2012-08-22 16:27:02 -05:00
|
|
|
switch_core_recovery_track(inbound_session);
|
2011-07-16 02:33:39 -05:00
|
|
|
|
|
|
|
switch_channel_set_flag(inbound_channel, CF_SIMPLIFY);
|
|
|
|
|
2010-06-18 17:09:26 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!did_simplify && inbound_channel) {
|
|
|
|
switch_log_printf(SWITCH_CHANNEL_ID_LOG, __FILE__, __SWITCH_FUNC__, __LINE__, switch_channel_get_uuid(inbound_channel), SWITCH_LOG_NOTICE,
|
2010-06-23 13:22:52 -05:00
|
|
|
"Could not simplify channel [%s]\n", switch_channel_get_name(inbound_channel));
|
2010-06-18 17:09:26 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
switch_core_session_rwunlock(other_session);
|
|
|
|
}
|
2012-11-29 18:34:27 -06:00
|
|
|
|
|
|
|
|
|
|
|
end:
|
|
|
|
|
|
|
|
return r;
|
2010-06-18 17:09:26 -05:00
|
|
|
}
|
|
|
|
|
2011-01-05 16:25:07 -06:00
|
|
|
void sofia_glue_pause_jitterbuffer(switch_core_session_t *session, switch_bool_t on)
|
|
|
|
{
|
|
|
|
switch_core_session_message_t *msg;
|
|
|
|
msg = switch_core_session_alloc(session, sizeof(*msg));
|
|
|
|
MESSAGE_STAMP_FFL(msg);
|
|
|
|
msg->message_id = SWITCH_MESSAGE_INDICATE_JITTER_BUFFER;
|
|
|
|
msg->string_arg = switch_core_session_strdup(session, on ? "pause" : "resume");
|
|
|
|
msg->from = __FILE__;
|
|
|
|
|
|
|
|
switch_core_session_queue_message(session, msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-09-29 14:14:41 -05:00
|
|
|
void sofia_glue_build_vid_refresh_message(switch_core_session_t *session, const char *pl)
|
|
|
|
{
|
|
|
|
switch_core_session_message_t *msg;
|
|
|
|
msg = switch_core_session_alloc(session, sizeof(*msg));
|
|
|
|
MESSAGE_STAMP_FFL(msg);
|
|
|
|
msg->message_id = SWITCH_MESSAGE_INDICATE_VIDEO_REFRESH_REQ;
|
|
|
|
if (pl) {
|
|
|
|
msg->string_arg = switch_core_session_strdup(session, pl);
|
|
|
|
}
|
|
|
|
msg->from = __FILE__;
|
|
|
|
|
|
|
|
switch_core_session_queue_message(session, msg);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2012-01-26 04:46:48 -06:00
|
|
|
char *sofia_glue_gen_contact_str(sofia_profile_t *profile, sip_t const *sip, nua_handle_t *nh, sofia_dispatch_event_t *de, sofia_nat_parse_t *np)
|
2010-12-30 11:38:23 -06:00
|
|
|
{
|
|
|
|
char *contact_str = NULL;
|
2011-04-22 16:43:29 -05:00
|
|
|
const char *contact_host;//, *contact_user;
|
2010-12-30 11:38:23 -06:00
|
|
|
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;
|
|
|
|
|
2015-02-17 12:20:24 -05:00
|
|
|
if (!sip || !sip->sip_contact) {
|
2010-12-30 11:38:23 -06:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
from = sip->sip_from;
|
|
|
|
contact = sip->sip_contact;
|
|
|
|
|
|
|
|
if (!np) {
|
|
|
|
np = &lnp;
|
|
|
|
}
|
|
|
|
|
2011-06-16 14:37:22 -05:00
|
|
|
sofia_glue_get_addr(de->data->e_msg, np->network_ip, sizeof(np->network_ip), &np->network_port);
|
2010-12-30 11:38:23 -06:00
|
|
|
|
|
|
|
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;
|
2011-04-22 16:43:29 -05:00
|
|
|
//contact_user = sip->sip_contact->m_url->url_user;
|
2010-12-30 11:38:23 -06:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2015-02-17 12:20:24 -05:00
|
|
|
if (sip->sip_record_route) {
|
2013-02-12 09:21:17 -06:00
|
|
|
char *full_contact = sip_header_as_string(nh->nh_home, (void *) contact);
|
|
|
|
char *route = sofia_glue_strip_uri(sip_header_as_string(nh->nh_home, (void *) sip->sip_record_route));
|
|
|
|
char *full_contact_dup;
|
|
|
|
char *route_encoded;
|
|
|
|
int route_encoded_len;
|
|
|
|
full_contact_dup = sofia_glue_get_url_from_contact(full_contact, 1);
|
|
|
|
route_encoded_len = (int)(strlen(route) * 3) + 1;
|
|
|
|
switch_zmalloc(route_encoded, route_encoded_len);
|
|
|
|
switch_url_encode(route, route_encoded, route_encoded_len);
|
|
|
|
contact_str = switch_mprintf("%s <%s;fs_path=%s>", display, full_contact_dup, route_encoded);
|
|
|
|
free(full_contact_dup);
|
|
|
|
free(route_encoded);
|
|
|
|
}
|
|
|
|
else if (np->is_nat && np->fs_path) {
|
2012-01-26 04:46:48 -06:00
|
|
|
char *full_contact = sip_header_as_string(nh->nh_home, (void *) contact);
|
|
|
|
char *full_contact_dup;
|
|
|
|
char *path_encoded;
|
|
|
|
int path_encoded_len;
|
|
|
|
char *path_val;
|
|
|
|
const char *tp;
|
|
|
|
|
|
|
|
full_contact_dup = sofia_glue_get_url_from_contact(full_contact, 1);
|
|
|
|
|
|
|
|
if ((tp = switch_stristr("transport=", full_contact_dup))) {
|
|
|
|
tp += 10;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (zstr(tp)) {
|
|
|
|
tp = "udp";
|
|
|
|
}
|
|
|
|
|
|
|
|
path_val = switch_mprintf("sip:%s:%d;transport=%s", np->network_ip, np->network_port, tp);
|
|
|
|
path_encoded_len = (int)(strlen(path_val) * 3) + 1;
|
|
|
|
|
|
|
|
switch_zmalloc(path_encoded, path_encoded_len);
|
|
|
|
switch_copy_string(path_encoded, ";fs_path=", 10);
|
|
|
|
switch_url_encode(path_val, path_encoded + 9, path_encoded_len - 9);
|
|
|
|
|
|
|
|
contact_str = switch_mprintf("%s <%s;fs_nat=yes%s>", display, full_contact_dup, path_encoded);
|
|
|
|
|
|
|
|
free(full_contact_dup);
|
|
|
|
free(path_encoded);
|
|
|
|
free(path_val);
|
|
|
|
|
2010-12-30 11:38:23 -06:00
|
|
|
} else {
|
2012-02-02 10:21:04 -06:00
|
|
|
|
|
|
|
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, ':');
|
|
|
|
|
|
|
|
|
2012-01-26 04:46:48 -06:00
|
|
|
if (contact->m_url->url_params) {
|
2012-04-10 15:34:50 -05:00
|
|
|
contact_str = switch_mprintf("%s <sip:%s%s%s%s%s%s;%s>%s",
|
2012-01-26 04:46:48 -06:00
|
|
|
display, contact->m_url->url_user,
|
2012-04-10 15:34:50 -05:00
|
|
|
contact->m_url->url_user ? "@" : "",
|
2012-01-26 04:46:48 -06:00
|
|
|
ipv6 ? "[" : "",
|
|
|
|
contact_host, ipv6 ? "]" : "", new_port, contact->m_url->url_params, np->is_nat ? ";fs_nat=yes" : "");
|
|
|
|
} else {
|
2012-04-10 15:34:50 -05:00
|
|
|
contact_str = switch_mprintf("%s <sip:%s%s%s%s%s%s>%s",
|
2012-01-26 04:46:48 -06:00
|
|
|
display,
|
2012-04-10 15:34:50 -05:00
|
|
|
contact->m_url->url_user,
|
|
|
|
contact->m_url->url_user ? "@" : "",
|
|
|
|
ipv6 ? "[" : "", contact_host, ipv6 ? "]" : "", new_port, np->is_nat ? ";fs_nat=yes" : "");
|
2012-01-26 04:46:48 -06:00
|
|
|
}
|
2010-12-30 11:38:23 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
return contact_str;
|
|
|
|
}
|
2010-09-29 14:14:41 -05:00
|
|
|
|
2011-11-22 17:59:04 -06:00
|
|
|
char *sofia_glue_get_host(const char *str, switch_memory_pool_t *pool)
|
|
|
|
{
|
|
|
|
char *s, *p;
|
|
|
|
|
|
|
|
if ((p = strchr(str, '@'))) {
|
|
|
|
p++;
|
|
|
|
} else {
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (pool) {
|
|
|
|
s = switch_core_strdup(pool, p);
|
|
|
|
} else {
|
|
|
|
s = strdup(p);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (p = s; p && *p; p++) {
|
|
|
|
if ((*p == ';') || (*p == '>')) {
|
|
|
|
*p = '\0';
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return s;
|
|
|
|
}
|
2010-09-29 14:14:41 -05:00
|
|
|
|
2012-11-07 12:10:50 -06:00
|
|
|
void sofia_glue_fire_events(sofia_profile_t *profile)
|
|
|
|
{
|
|
|
|
void *pop = NULL;
|
|
|
|
|
|
|
|
while (profile->event_queue && switch_queue_trypop(profile->event_queue, &pop) == SWITCH_STATUS_SUCCESS && pop) {
|
|
|
|
switch_event_t *event = (switch_event_t *) pop;
|
|
|
|
switch_event_fire(&event);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void sofia_event_fire(sofia_profile_t *profile, switch_event_t **event)
|
|
|
|
{
|
|
|
|
switch_queue_push(profile->event_queue, *event);
|
|
|
|
*event = NULL;
|
|
|
|
}
|
|
|
|
|
2010-06-18 17:09:26 -05:00
|
|
|
|
2008-01-27 05:02:52 +00:00
|
|
|
/* For Emacs:
|
|
|
|
* Local Variables:
|
|
|
|
* mode:c
|
2008-02-03 22:14:57 +00:00
|
|
|
* indent-tabs-mode:t
|
2008-01-27 05:02:52 +00:00
|
|
|
* tab-width:4
|
|
|
|
* c-basic-offset:4
|
|
|
|
* End:
|
|
|
|
* For VIM:
|
2013-06-25 11:50:17 -05:00
|
|
|
* vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
|
2008-01-27 05:02:52 +00:00
|
|
|
*/
|