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
2011-01-05 10:08:55 -06:00
* Copyright ( C ) 2005 - 2011 , 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 >
2007-04-02 19:54:25 +00:00
* Ken Rice , Asteria Solutions Group , Inc < ken @ asteriasgi . com >
* 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
2010-08-04 09:56:53 -05:00
switch_cache_db_handle_t * sofia_glue_get_db_handle ( sofia_profile_t * profile ) ;
2009-03-04 23:03:25 +00:00
2010-05-12 21:25:54 -05:00
void sofia_glue_set_image_sdp ( private_object_t * tech_pvt , switch_t38_options_t * t38_options , int insist )
2008-12-30 19:50:33 +00:00
{
2010-09-21 19:22:20 -05:00
char buf [ 2048 ] = " " ;
char max_buf [ 128 ] = " " ;
char max_data [ 128 ] = " " ;
2010-06-17 10:23:37 -05:00
const char * ip = t38_options - > local_ip ;
uint32_t port = t38_options - > local_port ;
2008-12-30 19:50:33 +00:00
const char * family = " IP4 " ;
2009-07-10 20:32:23 +00:00
const char * username = tech_pvt - > profile - > username ;
2011-09-19 20:11:23 -05:00
const char * bit_removal_on = " a=T38FaxFillBitRemoval \n " ;
const char * bit_removal_off = " " ;
const char * mmr_on = " a=T38FaxTranscodingMMR \n " ;
const char * mmr_off = " " ;
const char * jbig_on = " a=T38FaxTranscodingJBIG \n " ;
const char * jbig_off = " " ;
const char * var ;
int broken_boolean ;
2008-12-30 19:50:33 +00:00
2010-05-12 21:25:54 -05:00
//sofia_clear_flag(tech_pvt, TFLAG_ENABLE_SOA);
2010-06-23 13:22:52 -05:00
2011-09-19 20:11:23 -05:00
var = switch_channel_get_variable ( tech_pvt - > channel , " t38_broken_boolean " ) ;
broken_boolean = switch_true ( var ) ;
2008-12-30 19:50:33 +00:00
if ( ! ip ) {
if ( ! ( ip = tech_pvt - > adv_sdp_audio_ip ) ) {
ip = tech_pvt - > proxy_sdp_audio_ip ;
}
}
2010-01-23 03:59:01 +00:00
if ( ! ip ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " %s NO IP! \n " , switch_channel_get_name ( tech_pvt - > channel ) ) ;
return ;
}
2008-12-30 19:50:33 +00:00
if ( ! port ) {
if ( ! ( port = tech_pvt - > adv_sdp_audio_port ) ) {
port = tech_pvt - > proxy_sdp_audio_port ;
}
}
2011-01-14 17:42:31 -06:00
2010-01-23 03:59:01 +00:00
if ( ! port ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " %s NO PORT! \n " , switch_channel_get_name ( tech_pvt - > channel ) ) ;
return ;
}
2008-12-30 19:50:33 +00:00
if ( ! tech_pvt - > owner_id ) {
2009-01-25 21:23:07 +00:00
tech_pvt - > owner_id = ( uint32_t ) switch_epoch_time_now ( NULL ) - port ;
2008-12-30 19:50:33 +00:00
}
if ( ! tech_pvt - > session_id ) {
tech_pvt - > session_id = tech_pvt - > owner_id ;
}
tech_pvt - > session_id + + ;
2010-06-23 13:22:52 -05:00
2008-12-30 19:50:33 +00:00
family = strchr ( ip , ' : ' ) ? " IP6 " : " IP4 " ;
2010-06-23 13:22:52 -05:00
2010-05-12 21:25:54 -05:00
2008-12-30 19:50:33 +00:00
switch_snprintf ( buf , sizeof ( buf ) ,
" v=0 \n "
2009-07-10 20:32:23 +00:00
" o=%s %010u %010u IN %s %s \n "
2010-06-23 13:22:52 -05:00
" s=%s \n " " c=IN %s %s \n " " t=0 0 \n " , username , tech_pvt - > owner_id , tech_pvt - > session_id , family , ip , username , family , ip ) ;
2010-09-21 19:22:20 -05:00
if ( t38_options - > T38FaxMaxBuffer ) {
switch_snprintf ( max_buf , sizeof ( max_buf ) , " a=T38FaxMaxBuffer:%d \n " , t38_options - > T38FaxMaxBuffer ) ;
} ;
if ( t38_options - > T38FaxMaxDatagram ) {
switch_snprintf ( max_data , sizeof ( max_data ) , " a=T38FaxMaxDatagram:%d \n " , t38_options - > T38FaxMaxDatagram ) ;
} ;
2010-05-12 21:25:54 -05:00
2011-09-19 20:11:23 -05:00
if ( broken_boolean ) {
bit_removal_on = " a=T38FaxFillBitRemoval:1 \n " ;
bit_removal_off = " a=T38FaxFillBitRemoval:0 \n " ;
mmr_on = " a=T38FaxTranscodingMMR:1 \n " ;
mmr_off = " a=T38FaxTranscodingMMR:0 \n " ;
jbig_on = " a=T38FaxTranscodingJBIG:1 \n " ;
jbig_off = " a=T38FaxTranscodingJBIG:0 \n " ;
}
2010-05-12 21:25:54 -05:00
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) ,
2009-01-01 19:11:49 +00:00
" m=image %d udptl t38 \n "
2010-05-12 21:25:54 -05:00
" a=T38FaxVersion:%d \n "
2008-12-30 19:50:33 +00:00
" a=T38MaxBitRate:%d \n "
" %s "
" %s "
" %s "
" a=T38FaxRateManagement:%s \n "
2010-09-21 19:22:20 -05:00
" %s "
" %s "
2010-08-10 09:19:51 -05:00
" a=T38FaxUdpEC:%s \n " ,
//"a=T38VendorInfo:%s\n",
2008-12-30 19:50:33 +00:00
port ,
2010-05-12 21:25:54 -05:00
t38_options - > T38FaxVersion ,
2008-12-30 19:50:33 +00:00
t38_options - > T38MaxBitRate ,
2011-09-19 20:11:23 -05:00
t38_options - > T38FaxFillBitRemoval ? bit_removal_on : bit_removal_off ,
t38_options - > T38FaxTranscodingMMR ? mmr_on : mmr_off ,
t38_options - > T38FaxTranscodingJBIG ? jbig_on : jbig_off ,
2008-12-30 19:50:33 +00:00
t38_options - > T38FaxRateManagement ,
2010-09-21 19:22:20 -05:00
max_buf ,
max_data ,
t38_options - > T38FaxUdpEC
2010-08-10 09:19:51 -05:00
//t38_options->T38VendorInfo ? t38_options->T38VendorInfo : "0 0 0"
) ;
2010-06-23 13:22:52 -05:00
2010-05-12 21:25:54 -05:00
if ( insist ) {
2010-06-23 13:22:52 -05:00
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " m=audio 0 RTP/AVP 19 \n " ) ;
2010-05-12 21:25:54 -05:00
}
2010-02-06 03:38:24 +00:00
2009-03-20 01:52:53 +00:00
sofia_glue_tech_set_local_sdp ( tech_pvt , buf , SWITCH_TRUE ) ;
2010-05-12 21:25:54 -05:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_DEBUG , " %s image media sdp: \n %s \n " ,
switch_channel_get_name ( tech_pvt - > channel ) , tech_pvt - > local_sdp_str ) ;
2010-06-23 13:22:52 -05:00
2010-05-12 21:25:54 -05:00
2008-12-30 19:50:33 +00:00
}
2007-03-31 19:01:33 +00:00
2010-10-13 19:27:45 -05:00
static void generate_m ( private_object_t * tech_pvt , char * buf , size_t buflen ,
switch_port_t port ,
2011-04-15 11:17:36 -05:00
int cur_ptime , const char * append_audio , const char * sr , int use_cng , int cng_type , switch_event_t * map , int verbose_sdp , int secure )
2010-10-13 19:27:45 -05:00
{
int i = 0 ;
int rate ;
int already_did [ 128 ] = { 0 } ;
int ptime = 0 , noptime = 0 ;
switch_snprintf ( buf + strlen ( buf ) , buflen - strlen ( buf ) , " m=audio %d RTP/%sAVP " ,
2011-04-15 11:17:36 -05:00
port , secure ? " S " : " " ) ;
2010-10-13 19:27:45 -05:00
for ( i = 0 ; i < tech_pvt - > num_codecs ; i + + ) {
const switch_codec_implementation_t * imp = tech_pvt - > codecs [ i ] ;
2011-09-08 09:48:21 -05:00
int this_ptime = ( imp - > microseconds_per_packet / 1000 ) ;
if ( ! strcasecmp ( imp - > iananame , " ilbc " ) ) {
this_ptime = 20 ;
}
2010-10-13 19:27:45 -05:00
if ( imp - > codec_type ! = SWITCH_CODEC_TYPE_AUDIO ) {
continue ;
}
if ( ! noptime ) {
if ( ! cur_ptime ) {
2011-08-01 10:22:55 -05:00
#if 0
2010-10-13 19:27:45 -05:00
if ( ptime ) {
2011-09-08 09:48:21 -05:00
if ( ptime ! = this_ptime ) {
2010-10-13 19:27:45 -05:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING ,
" Codec %s payload %d added to sdp wanting ptime %d but it's already %d (%s:%d:%d), disabling ptime. \n " ,
imp - > iananame ,
tech_pvt - > ianacodes [ i ] ,
2011-09-08 09:48:21 -05:00
this_ptime ,
2010-10-13 19:27:45 -05:00
ptime ,
tech_pvt - > codecs [ 0 ] - > iananame ,
tech_pvt - > codecs [ 0 ] - > ianacode ,
ptime ) ;
ptime = 0 ;
noptime = 1 ;
}
} else {
2011-09-08 09:48:21 -05:00
ptime = this_ptime ;
2010-10-13 19:27:45 -05:00
}
2011-08-01 10:22:55 -05:00
# else
if ( ! ptime ) {
2011-09-08 09:48:21 -05:00
ptime = this_ptime ;
2011-08-01 10:22:55 -05:00
}
# endif
2010-10-13 19:27:45 -05:00
} else {
2011-09-08 09:48:21 -05:00
if ( this_ptime ! = cur_ptime ) {
2010-10-13 19:27:45 -05:00
continue ;
}
}
}
if ( tech_pvt - > ianacodes [ i ] < 128 ) {
if ( already_did [ tech_pvt - > ianacodes [ i ] ] ) {
continue ;
}
already_did [ tech_pvt - > ianacodes [ i ] ] = 1 ;
}
switch_snprintf ( buf + strlen ( buf ) , buflen - strlen ( buf ) , " %d " , tech_pvt - > ianacodes [ i ] ) ;
}
if ( tech_pvt - > dtmf_type = = DTMF_2833 & & tech_pvt - > te > 95 ) {
switch_snprintf ( buf + strlen ( buf ) , buflen - strlen ( buf ) , " %d " , tech_pvt - > te ) ;
}
if ( ! sofia_test_pflag ( tech_pvt - > profile , PFLAG_SUPPRESS_CNG ) & & cng_type & & use_cng ) {
switch_snprintf ( buf + strlen ( buf ) , buflen - strlen ( buf ) , " %d " , cng_type ) ;
}
switch_snprintf ( buf + strlen ( buf ) , buflen - strlen ( buf ) , " \n " ) ;
memset ( already_did , 0 , sizeof ( already_did ) ) ;
for ( i = 0 ; i < tech_pvt - > num_codecs ; i + + ) {
const switch_codec_implementation_t * imp = tech_pvt - > codecs [ i ] ;
char * fmtp = imp - > fmtp ;
2011-09-08 09:48:21 -05:00
int this_ptime = imp - > microseconds_per_packet / 1000 ;
2010-10-13 19:27:45 -05:00
if ( imp - > codec_type ! = SWITCH_CODEC_TYPE_AUDIO ) {
continue ;
}
2011-09-08 09:48:21 -05:00
if ( ! strcasecmp ( imp - > iananame , " ilbc " ) ) {
this_ptime = 20 ;
}
2010-10-13 19:27:45 -05:00
if ( ! noptime ) {
if ( ! cur_ptime ) {
if ( ! ptime ) {
2011-09-08 09:48:21 -05:00
ptime = this_ptime ;
2010-10-13 19:27:45 -05:00
}
} else {
2011-09-08 09:48:21 -05:00
if ( this_ptime ! = cur_ptime ) {
2010-10-13 19:27:45 -05:00
continue ;
}
}
}
if ( tech_pvt - > ianacodes [ i ] < 128 ) {
if ( already_did [ tech_pvt - > ianacodes [ i ] ] ) {
continue ;
}
already_did [ tech_pvt - > ianacodes [ i ] ] = 1 ;
}
rate = imp - > samples_per_second ;
if ( map ) {
char key [ 128 ] = " " ;
char * check = NULL ;
switch_snprintf ( key , sizeof ( key ) , " %s:%u " , imp - > iananame , imp - > bits_per_second ) ;
if ( ( check = switch_event_get_header ( map , key ) ) | | ( check = switch_event_get_header ( map , imp - > iananame ) ) ) {
fmtp = check ;
}
}
2010-11-19 13:46:01 -06:00
if ( tech_pvt - > ianacodes [ i ] > 95 | | verbose_sdp ) {
2010-10-13 19:27:45 -05:00
switch_snprintf ( buf + strlen ( buf ) , buflen - strlen ( buf ) , " a=rtpmap:%d %s/%d \n " , tech_pvt - > ianacodes [ i ] , imp - > iananame , rate ) ;
}
if ( fmtp ) {
switch_snprintf ( buf + strlen ( buf ) , buflen - strlen ( buf ) , " a=fmtp:%d %s \n " , tech_pvt - > ianacodes [ i ] , fmtp ) ;
}
}
2011-06-23 17:57:10 -05:00
if ( ( tech_pvt - > dtmf_type = = DTMF_2833 | | sofia_test_pflag ( tech_pvt - > profile , PFLAG_LIBERAL_DTMF ) | | sofia_test_flag ( tech_pvt , TFLAG_LIBERAL_DTMF ) )
& & tech_pvt - > te > 95 ) {
2010-10-13 19:27:45 -05:00
switch_snprintf ( buf + strlen ( buf ) , buflen - strlen ( buf ) , " a=rtpmap:%d telephone-event/8000 \n a=fmtp:%d 0-16 \n " , tech_pvt - > te , tech_pvt - > te ) ;
}
2011-04-15 11:17:36 -05:00
if ( secure ) {
switch_snprintf ( buf + strlen ( buf ) , buflen - strlen ( buf ) , " a=crypto:%s \n " , tech_pvt - > local_crypto_key ) ;
//switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=encryption:optional\n");
}
2010-10-13 19:27:45 -05:00
if ( ! cng_type ) {
//switch_snprintf(buf + strlen(buf), buflen - strlen(buf), "a=rtpmap:%d CN/8000\n", cng_type);
//} else {
switch_snprintf ( buf + strlen ( buf ) , buflen - strlen ( buf ) , " a=silenceSupp:off - - - - \n " ) ;
}
if ( append_audio ) {
switch_snprintf ( buf + strlen ( buf ) , buflen - strlen ( buf ) , " %s%s " , append_audio , end_of ( append_audio ) = = ' \n ' ? " " : " \n " ) ;
}
if ( ! cur_ptime ) {
cur_ptime = ptime ;
}
if ( ! noptime & & cur_ptime ) {
switch_snprintf ( buf + strlen ( buf ) , buflen - strlen ( buf ) , " a=ptime:%d \n " , cur_ptime ) ;
}
if ( sr ) {
switch_snprintf ( buf + strlen ( buf ) , buflen - strlen ( buf ) , " a=%s \n " , sr ) ;
}
}
2010-10-26 15:43:14 -05:00
void sofia_glue_check_dtmf_type ( private_object_t * tech_pvt )
{
const char * val ;
if ( ( val = switch_channel_get_variable ( tech_pvt - > channel , " dtmf_type " ) ) ) {
if ( ! strcasecmp ( val , " rfc2833 " ) ) {
tech_pvt - > dtmf_type = DTMF_2833 ;
} else if ( ! strcasecmp ( val , " info " ) ) {
tech_pvt - > dtmf_type = DTMF_INFO ;
} else if ( ! strcasecmp ( val , " none " ) ) {
tech_pvt - > dtmf_type = DTMF_NONE ;
} else {
tech_pvt - > dtmf_type = tech_pvt - > profile - > dtmf_type ;
}
}
}
2010-10-13 19:27:45 -05:00
2011-05-29 09:46:02 -05:00
void sofia_glue_set_local_sdp ( private_object_t * tech_pvt , const char * ip , switch_port_t port , const char * sr , int force )
2007-03-31 19:01:33 +00:00
{
char buf [ 2048 ] ;
int ptime = 0 ;
2007-06-11 22:12:10 +00:00
uint32_t rate = 0 ;
2007-04-19 21:40:50 +00:00
uint32_t v_port ;
2007-11-12 20:36:00 +00:00
int use_cng = 1 ;
const char * val ;
2008-07-03 18:50:15 +00:00
const char * family ;
2008-02-07 22:42:27 +00:00
const char * pass_fmtp = switch_channel_get_variable ( tech_pvt - > channel , " sip_video_fmtp " ) ;
2008-02-09 00:38:23 +00:00
const char * ov_fmtp = switch_channel_get_variable ( tech_pvt - > channel , " sip_force_video_fmtp " ) ;
2010-01-28 22:30:34 +00:00
const char * append_audio = switch_channel_get_variable ( tech_pvt - > channel , " sip_append_audio_sdp " ) ;
2009-04-20 17:07:54 +00:00
char srbuf [ 128 ] = " " ;
const char * var_val ;
2009-07-10 20:32:23 +00:00
const char * username = tech_pvt - > profile - > username ;
2010-06-01 14:04:55 -05:00
const char * fmtp_out = tech_pvt - > fmtp_out ;
const char * fmtp_out_var = switch_channel_get_variable ( tech_pvt - > channel , " sip_force_audio_fmtp " ) ;
2010-09-29 14:14:41 -05:00
switch_event_t * map = NULL , * ptmap = NULL ;
const char * b_sdp = NULL ;
2010-11-19 13:46:01 -06:00
int verbose_sdp = 0 ;
2010-09-29 14:14:41 -05:00
2010-10-26 15:43:14 -05:00
sofia_glue_check_dtmf_type ( tech_pvt ) ;
2010-10-13 19:27:45 -05:00
2011-01-17 13:10:53 -06:00
if ( sofia_test_pflag ( tech_pvt - > profile , PFLAG_SUPPRESS_CNG ) | |
( ( val = switch_channel_get_variable ( tech_pvt - > channel , " supress_cng " ) ) & & switch_true ( val ) ) | |
( ( val = switch_channel_get_variable ( tech_pvt - > channel , " suppress_cng " ) ) & & switch_true ( val ) ) ) {
use_cng = 0 ;
tech_pvt - > cng_pt = 0 ;
}
2010-10-13 19:27:45 -05:00
if ( ! tech_pvt - > payload_space ) {
int i ;
tech_pvt - > payload_space = 98 ;
for ( i = 0 ; i < tech_pvt - > num_codecs ; i + + ) {
const switch_codec_implementation_t * imp = tech_pvt - > codecs [ i ] ;
tech_pvt - > ianacodes [ i ] = imp - > ianacode ;
if ( tech_pvt - > ianacodes [ i ] > 64 ) {
2011-01-17 13:10:53 -06:00
if ( tech_pvt - > dtmf_type = = DTMF_2833 & & tech_pvt - > te > 95 & & tech_pvt - > te = = tech_pvt - > payload_space ) {
tech_pvt - > payload_space + + ;
}
if ( ! sofia_test_pflag ( tech_pvt - > profile , PFLAG_SUPPRESS_CNG ) & &
tech_pvt - > cng_pt & & use_cng & & tech_pvt - > cng_pt = = tech_pvt - > payload_space ) {
tech_pvt - > payload_space + + ;
}
2010-10-13 19:27:45 -05:00
tech_pvt - > ianacodes [ i ] = tech_pvt - > payload_space + + ;
}
}
}
2010-06-01 14:04:55 -05:00
if ( fmtp_out_var ) {
fmtp_out = fmtp_out_var ;
}
2007-11-12 20:36:00 +00:00
2010-11-19 13:46:01 -06:00
if ( ( val = switch_channel_get_variable ( tech_pvt - > channel , " verbose_sdp " ) ) & & switch_true ( val ) ) {
verbose_sdp = 1 ;
}
2008-05-27 04:54:52 +00:00
if ( ! force & & ! ip & & ! sr
& & ( switch_channel_test_flag ( tech_pvt - > channel , CF_PROXY_MODE ) | | switch_channel_test_flag ( tech_pvt - > channel , CF_PROXY_MEDIA ) ) ) {
2007-03-31 19:01:33 +00:00
return ;
}
if ( ! ip ) {
if ( ! ( ip = tech_pvt - > adv_sdp_audio_ip ) ) {
ip = tech_pvt - > proxy_sdp_audio_ip ;
}
}
2010-01-23 03:59:01 +00:00
if ( ! ip ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " %s NO IP! \n " , switch_channel_get_name ( tech_pvt - > channel ) ) ;
return ;
}
2007-03-31 19:01:33 +00:00
if ( ! port ) {
if ( ! ( port = tech_pvt - > adv_sdp_audio_port ) ) {
port = tech_pvt - > proxy_sdp_audio_port ;
}
}
2007-04-19 21:40:50 +00:00
2010-01-23 03:59:01 +00:00
if ( ! port ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " %s NO PORT! \n " , switch_channel_get_name ( tech_pvt - > channel ) ) ;
return ;
}
2010-11-01 10:03:10 -05:00
if ( ! tech_pvt - > rm_encoding & & ( b_sdp = switch_channel_get_variable ( tech_pvt - > channel , SWITCH_B_SDP_VARIABLE ) ) ) {
sofia_glue_sdp_map ( b_sdp , & map , & ptmap ) ;
}
2007-03-31 19:01:33 +00:00
if ( ! sr ) {
2010-06-23 13:22:52 -05:00
if ( ( var_val = switch_channel_get_variable ( tech_pvt - > channel , " media_audio_mode " ) ) ) {
sr = var_val ;
2010-05-01 19:50:53 -05:00
} else {
sr = " sendrecv " ;
}
2007-03-31 19:01:33 +00:00
}
2007-04-19 22:49:01 +00:00
if ( ! tech_pvt - > owner_id ) {
2009-01-25 21:23:07 +00:00
tech_pvt - > owner_id = ( uint32_t ) switch_epoch_time_now ( NULL ) - port ;
2007-04-19 22:49:01 +00:00
}
if ( ! tech_pvt - > session_id ) {
2008-05-27 04:54:52 +00:00
tech_pvt - > session_id = tech_pvt - > owner_id ;
2007-04-19 22:49:01 +00:00
}
tech_pvt - > session_id + + ;
2008-05-27 04:54:52 +00:00
2010-02-06 03:38:24 +00:00
if ( ( tech_pvt - > profile - > ndlb & PFLAG_NDLB_SENDRECV_IN_SESSION ) | |
( ( var_val = switch_channel_get_variable ( tech_pvt - > channel , " ndlb_sendrecv_in_session " ) ) & & switch_true ( var_val ) ) ) {
2009-04-20 17:07:54 +00:00
switch_snprintf ( srbuf , sizeof ( srbuf ) , " a=%s \n " , sr ) ;
sr = NULL ;
}
2010-02-06 03:38:24 +00:00
2008-07-03 18:50:15 +00:00
family = strchr ( ip , ' : ' ) ? " IP6 " : " IP4 " ;
2007-12-12 21:53:32 +00:00
switch_snprintf ( buf , sizeof ( buf ) ,
2008-01-17 04:16:04 +00:00
" v=0 \n "
2009-07-10 20:32:23 +00:00
" o=%s %010u %010u IN %s %s \n "
" s=%s \n "
2008-07-03 18:50:15 +00:00
" c=IN %s %s \n " " t=0 0 \n "
2010-10-13 19:27:45 -05:00
" %s " ,
username , tech_pvt - > owner_id , tech_pvt - > session_id , family , ip , username , family , ip , srbuf ) ;
2008-01-16 06:01:53 +00:00
2007-03-31 19:01:33 +00:00
if ( tech_pvt - > rm_encoding ) {
2010-10-13 19:27:45 -05:00
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " m=audio %d RTP/%sAVP " ,
port , ( ! zstr ( tech_pvt - > local_crypto_key ) & & sofia_test_flag ( tech_pvt , TFLAG_SECURE ) ) ? " S " : " " ) ;
2008-05-27 04:54:52 +00:00
2010-10-13 19:27:45 -05:00
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " %d " , tech_pvt - > pt ) ;
2007-04-19 21:40:50 +00:00
2011-08-25 08:25:47 -05:00
if ( ( tech_pvt - > dtmf_type = = DTMF_2833 | | sofia_test_pflag ( tech_pvt - > profile , PFLAG_LIBERAL_DTMF ) | | sofia_test_flag ( tech_pvt , TFLAG_LIBERAL_DTMF ) ) & & tech_pvt - > te > 95 ) {
2010-10-13 19:27:45 -05:00
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " %d " , tech_pvt - > te ) ;
2007-03-31 19:01:33 +00:00
}
2010-10-13 19:27:45 -05:00
if ( ! sofia_test_pflag ( tech_pvt - > profile , PFLAG_SUPPRESS_CNG ) & & tech_pvt - > cng_pt & & use_cng ) {
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " %d " , tech_pvt - > cng_pt ) ;
}
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " \n " ) ;
2008-01-16 06:01:53 +00:00
2007-03-31 19:01:33 +00:00
rate = tech_pvt - > rm_rate ;
2008-06-23 18:26:08 +00:00
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " a=rtpmap:%d %s/%d \n " , tech_pvt - > agreed_pt , tech_pvt - > rm_encoding , rate ) ;
2010-06-01 14:04:55 -05:00
if ( fmtp_out ) {
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " a=fmtp:%d %s \n " , tech_pvt - > agreed_pt , fmtp_out ) ;
2007-03-31 19:01:33 +00:00
}
2010-10-13 19:27:45 -05:00
2007-03-31 19:01:33 +00:00
if ( tech_pvt - > read_codec . implementation & & ! ptime ) {
2008-10-20 17:48:42 +00:00
ptime = tech_pvt - > read_codec . implementation - > microseconds_per_packet / 1000 ;
2007-03-31 19:01:33 +00:00
}
2011-03-30 11:26:14 -05:00
2011-06-23 17:57:10 -05:00
if ( ( tech_pvt - > dtmf_type = = DTMF_2833 | | sofia_test_pflag ( tech_pvt - > profile , PFLAG_LIBERAL_DTMF ) | | sofia_test_flag ( tech_pvt , TFLAG_LIBERAL_DTMF ) )
& & tech_pvt - > te > 95 ) {
2010-10-13 19:27:45 -05:00
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " a=rtpmap:%d telephone-event/8000 \n a=fmtp:%d 0-16 \n " , tech_pvt - > te , tech_pvt - > te ) ;
}
if ( ! sofia_test_pflag ( tech_pvt - > profile , PFLAG_SUPPRESS_CNG ) & & tech_pvt - > cng_pt & & use_cng ) {
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " a=rtpmap:%d CN/8000 \n " , tech_pvt - > cng_pt ) ;
if ( ! tech_pvt - > rm_encoding ) {
tech_pvt - > cng_pt = 0 ;
2007-04-19 21:40:50 +00:00
}
2010-10-13 19:27:45 -05:00
} else {
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " a=silenceSupp:off - - - - \n " ) ;
}
2007-04-19 21:40:50 +00:00
2010-10-13 19:27:45 -05:00
if ( append_audio ) {
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " %s%s " , append_audio , end_of ( append_audio ) = = ' \n ' ? " " : " \n " ) ;
}
2008-05-27 04:54:52 +00:00
2010-10-13 19:27:45 -05:00
if ( ptime ) {
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " a=ptime:%d \n " , ptime ) ;
}
2008-05-27 04:54:52 +00:00
2010-10-13 19:27:45 -05:00
if ( sr ) {
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " a=%s \n " , sr ) ;
}
2011-04-15 11:17:36 -05:00
if ( ! zstr ( tech_pvt - > local_crypto_key ) & & sofia_test_flag ( tech_pvt , TFLAG_SECURE ) ) {
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " a=crypto:%s \n " , tech_pvt - > local_crypto_key ) ;
//switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=encryption:optional\n");
}
2008-05-27 04:54:52 +00:00
2010-10-13 19:27:45 -05:00
} else if ( tech_pvt - > num_codecs ) {
int i ;
int cur_ptime = 0 , this_ptime = 0 , cng_type = 0 ;
2011-08-01 10:22:55 -05:00
const char * mult ;
2010-09-29 16:52:34 -05:00
2010-10-13 19:27:45 -05:00
if ( ! sofia_test_pflag ( tech_pvt - > profile , PFLAG_SUPPRESS_CNG ) & & tech_pvt - > cng_pt & & use_cng ) {
cng_type = tech_pvt - > cng_pt ;
2007-03-31 19:01:33 +00:00
2010-10-13 19:27:45 -05:00
if ( ! tech_pvt - > rm_encoding ) {
tech_pvt - > cng_pt = 0 ;
}
2007-03-31 19:01:33 +00:00
}
2011-08-01 10:22:55 -05:00
mult = switch_channel_get_variable ( tech_pvt - > channel , " sdp_m_per_ptime " ) ;
if ( mult & & switch_false ( mult ) ) {
2011-04-15 11:17:36 -05:00
char * bp = buf ;
if ( ( ! zstr ( tech_pvt - > local_crypto_key ) & & sofia_test_flag ( tech_pvt , TFLAG_SECURE ) ) ) {
generate_m ( tech_pvt , buf , sizeof ( buf ) , port , 0 , append_audio , sr , use_cng , cng_type , map , verbose_sdp , 1 ) ;
bp = ( buf + strlen ( buf ) ) ;
}
generate_m ( tech_pvt , bp , sizeof ( buf ) - strlen ( buf ) , port , 0 , append_audio , sr , use_cng , cng_type , map , verbose_sdp , 0 ) ;
2010-10-13 19:27:45 -05:00
} else {
2008-01-17 04:16:04 +00:00
for ( i = 0 ; i < tech_pvt - > num_codecs ; i + + ) {
const switch_codec_implementation_t * imp = tech_pvt - > codecs [ i ] ;
2010-10-13 19:27:45 -05:00
2008-01-17 04:16:04 +00:00
if ( imp - > codec_type ! = SWITCH_CODEC_TYPE_AUDIO ) {
continue ;
}
2010-10-13 19:27:45 -05:00
this_ptime = imp - > microseconds_per_packet / 1000 ;
2011-09-07 08:07:04 -05:00
if ( ! strcasecmp ( imp - > iananame , " ilbc " ) ) {
this_ptime = 20 ;
}
2010-10-13 19:27:45 -05:00
if ( cur_ptime ! = this_ptime ) {
2011-04-15 11:17:36 -05:00
char * bp = buf ;
cur_ptime = this_ptime ;
if ( ( ! zstr ( tech_pvt - > local_crypto_key ) & & sofia_test_flag ( tech_pvt , TFLAG_SECURE ) ) ) {
generate_m ( tech_pvt , buf , sizeof ( buf ) , port , cur_ptime , append_audio , sr , use_cng , cng_type , map , verbose_sdp , 1 ) ;
bp = ( buf + strlen ( buf ) ) ;
}
generate_m ( tech_pvt , bp , sizeof ( buf ) - strlen ( buf ) , port , cur_ptime , append_audio , sr , use_cng , cng_type , map , verbose_sdp , 0 ) ;
2008-01-17 04:16:04 +00:00
}
2010-10-13 19:27:45 -05:00
2008-01-17 04:16:04 +00:00
}
}
2010-10-13 19:27:45 -05:00
}
2009-02-09 17:56:38 +00:00
if ( sofia_test_flag ( tech_pvt , TFLAG_VIDEO ) ) {
2010-05-31 09:14:53 -04:00
if ( ! tech_pvt - > local_sdp_video_port ) {
2008-05-23 19:41:23 +00:00
sofia_glue_tech_choose_video_port ( tech_pvt , 0 ) ;
2008-03-10 16:13:12 +00:00
}
2008-02-07 22:42:27 +00:00
2007-04-19 21:40:50 +00:00
if ( ( v_port = tech_pvt - > adv_sdp_video_port ) ) {
2007-12-12 21:53:32 +00:00
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " m=video %d RTP/AVP " , v_port ) ;
2010-02-06 03:38:24 +00:00
2007-04-19 21:40:50 +00:00
/*****************************/
if ( tech_pvt - > video_rm_encoding ) {
2008-02-07 22:42:27 +00:00
sofia_glue_tech_set_video_codec ( tech_pvt , 0 ) ;
2008-06-23 18:26:08 +00:00
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " %d " , tech_pvt - > video_agreed_pt ) ;
2007-04-19 21:40:50 +00:00
} else if ( tech_pvt - > num_codecs ) {
int i ;
2007-10-18 16:44:11 +00:00
int already_did [ 128 ] = { 0 } ;
2007-04-19 21:40:50 +00:00
for ( i = 0 ; i < tech_pvt - > num_codecs ; i + + ) {
const switch_codec_implementation_t * imp = tech_pvt - > codecs [ i ] ;
2008-05-27 04:54:52 +00:00
2007-04-19 21:40:50 +00:00
if ( imp - > codec_type ! = SWITCH_CODEC_TYPE_VIDEO ) {
continue ;
}
2008-05-27 04:54:52 +00:00
2010-10-13 19:27:45 -05:00
if ( tech_pvt - > ianacodes [ i ] < 128 ) {
if ( already_did [ tech_pvt - > ianacodes [ i ] ] ) {
2007-10-18 16:44:11 +00:00
continue ;
}
2010-10-13 19:27:45 -05:00
already_did [ tech_pvt - > ianacodes [ i ] ] = 1 ;
2007-10-18 16:44:11 +00:00
}
2008-05-27 04:54:52 +00:00
2010-10-13 19:27:45 -05:00
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " %d " , tech_pvt - > ianacodes [ i ] ) ;
2007-04-19 21:40:50 +00:00
if ( ! ptime ) {
2008-10-20 17:48:42 +00:00
ptime = imp - > microseconds_per_packet / 1000 ;
2007-04-19 21:40:50 +00:00
}
}
}
2007-12-12 21:53:32 +00:00
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " \n " ) ;
2010-06-23 13:22:52 -05:00
2008-02-07 22:42:27 +00:00
if ( tech_pvt - > video_rm_encoding ) {
const char * of ;
2007-04-19 21:40:50 +00:00
rate = tech_pvt - > video_rm_rate ;
2008-05-27 04:54:52 +00:00
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " a=rtpmap:%d %s/%ld \n " , tech_pvt - > video_pt , tech_pvt - > video_rm_encoding ,
tech_pvt - > video_rm_rate ) ;
2010-02-06 03:38:24 +00:00
if ( sofia_test_flag ( tech_pvt , TFLAG_RECOVERING ) ) {
pass_fmtp = tech_pvt - > video_rm_fmtp ;
} else {
2008-02-09 00:38:23 +00:00
2010-02-06 03:38:24 +00:00
pass_fmtp = NULL ;
if ( switch_channel_get_variable ( tech_pvt - > channel , SWITCH_SIGNAL_BOND_VARIABLE ) ) {
if ( ( of = switch_channel_get_variable_partner ( tech_pvt - > channel , " sip_video_fmtp " ) ) ) {
pass_fmtp = of ;
}
2008-02-07 22:42:27 +00:00
}
2008-05-27 04:54:52 +00:00
2010-02-06 03:38:24 +00:00
if ( ov_fmtp ) {
pass_fmtp = ov_fmtp ;
2011-08-25 09:24:17 -05:00
} else {
pass_fmtp = switch_channel_get_variable ( tech_pvt - > channel , " sip_video_fmtp " ) ;
2010-02-06 03:38:24 +00:00
}
2007-04-19 21:40:50 +00:00
}
2008-02-07 22:42:27 +00:00
if ( pass_fmtp ) {
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " a=fmtp:%d %s \n " , tech_pvt - > video_pt , pass_fmtp ) ;
}
2008-02-09 00:38:23 +00:00
2007-04-19 21:40:50 +00:00
} else if ( tech_pvt - > num_codecs ) {
int i ;
2007-10-18 16:44:11 +00:00
int already_did [ 128 ] = { 0 } ;
2008-02-07 22:42:27 +00:00
2007-04-19 21:40:50 +00:00
for ( i = 0 ; i < tech_pvt - > num_codecs ; i + + ) {
const switch_codec_implementation_t * imp = tech_pvt - > codecs [ i ] ;
2010-09-29 14:14:41 -05:00
char * fmtp = NULL ;
2010-10-13 19:27:45 -05:00
uint32_t ianacode = tech_pvt - > ianacodes [ i ] ;
2010-09-29 14:14:41 -05:00
2007-04-19 21:40:50 +00:00
if ( imp - > codec_type ! = SWITCH_CODEC_TYPE_VIDEO ) {
continue ;
}
2010-09-29 14:14:41 -05:00
if ( ianacode < 128 ) {
if ( already_did [ ianacode ] ) {
2007-10-18 16:44:11 +00:00
continue ;
}
2010-09-29 14:14:41 -05:00
already_did [ ianacode ] = 1 ;
2007-10-18 16:32:32 +00:00
}
2008-05-27 04:54:52 +00:00
2007-04-19 21:40:50 +00:00
if ( ! rate ) {
rate = imp - > samples_per_second ;
}
2010-09-29 14:14:41 -05:00
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " a=rtpmap:%d %s/%d \n " , ianacode , imp - > iananame ,
2008-05-27 04:54:52 +00:00
imp - > samples_per_second ) ;
2010-09-29 14:14:41 -05:00
if ( ! zstr ( ov_fmtp ) ) {
fmtp = ( char * ) ov_fmtp ;
2008-02-07 22:42:27 +00:00
} else {
2010-09-29 14:14:41 -05:00
if ( map ) {
fmtp = switch_event_get_header ( map , imp - > iananame ) ;
2008-02-07 22:42:27 +00:00
}
2010-09-29 14:14:41 -05:00
if ( zstr ( fmtp ) ) fmtp = imp - > fmtp ;
if ( zstr ( fmtp ) ) fmtp = ( char * ) pass_fmtp ;
}
if ( ! zstr ( fmtp ) & & strcasecmp ( fmtp , " _blank_ " ) ) {
2010-10-13 19:27:45 -05:00
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " a=fmtp:%d %s \n " , ianacode , fmtp ) ;
2007-04-19 21:40:50 +00:00
}
}
2010-09-29 14:14:41 -05:00
2007-04-19 21:40:50 +00:00
}
}
}
2010-02-06 03:38:24 +00:00
2010-09-29 14:14:41 -05:00
if ( map ) {
switch_event_destroy ( & map ) ;
}
if ( ptmap ) {
switch_event_destroy ( & ptmap ) ;
}
2010-10-13 19:27:45 -05:00
2009-03-20 01:52:53 +00:00
sofia_glue_tech_set_local_sdp ( tech_pvt , buf , SWITCH_TRUE ) ;
2007-03-31 19:01:33 +00:00
}
2009-11-24 18:52:57 +00:00
const char * sofia_glue_get_codec_string ( private_object_t * tech_pvt )
{
2009-11-25 22:21:02 +00:00
const char * codec_string = NULL , * preferred = NULL , * fallback = NULL ;
2010-02-06 03:38:24 +00:00
2009-11-25 21:34:51 +00:00
if ( switch_channel_direction ( tech_pvt - > channel ) = = SWITCH_CALL_DIRECTION_OUTBOUND ) {
2009-11-25 22:21:02 +00:00
preferred = tech_pvt - > profile - > outbound_codec_string ;
fallback = tech_pvt - > profile - > inbound_codec_string ;
2009-11-25 21:34:51 +00:00
} else {
2009-11-25 22:21:02 +00:00
preferred = tech_pvt - > profile - > inbound_codec_string ;
fallback = tech_pvt - > profile - > outbound_codec_string ;
2009-11-24 18:52:57 +00:00
}
2009-11-25 22:21:02 +00:00
codec_string = ! zstr ( preferred ) ? preferred : fallback ;
2010-02-06 03:38:24 +00:00
2009-11-24 18:52:57 +00:00
return codec_string ;
}
2007-04-17 06:08:39 +00:00
void sofia_glue_tech_prepare_codecs ( private_object_t * tech_pvt )
2007-03-31 19:01:33 +00:00
{
2009-03-21 02:31:15 +00:00
const char * abs , * codec_string = NULL ;
2007-11-01 11:28:26 +00:00
const char * ocodec = NULL ;
2007-03-31 19:01:33 +00:00
2008-02-21 17:48:41 +00:00
if ( switch_channel_test_flag ( tech_pvt - > channel , CF_PROXY_MODE ) | | switch_channel_test_flag ( tech_pvt - > channel , CF_PROXY_MEDIA ) ) {
2008-03-19 19:02:26 +00:00
return ;
2007-03-31 19:01:33 +00:00
}
if ( tech_pvt - > num_codecs ) {
2008-03-19 19:02:26 +00:00
return ;
2007-03-31 19:01:33 +00:00
}
2011-04-04 11:55:05 -05:00
tech_pvt - > payload_space = 0 ;
2007-12-12 23:21:45 +00:00
switch_assert ( tech_pvt - > session ! = NULL ) ;
2007-03-31 19:01:33 +00:00
2009-03-21 02:31:15 +00:00
if ( ( abs = switch_channel_get_variable ( tech_pvt - > channel , " absolute_codec_string " ) ) ) {
2007-03-31 19:01:33 +00:00
codec_string = abs ;
2009-11-24 18:52:57 +00:00
goto ready ;
}
if ( ! ( codec_string = switch_channel_get_variable ( tech_pvt - > channel , " codec_string " ) ) ) {
codec_string = sofia_glue_get_codec_string ( tech_pvt ) ;
if ( codec_string & & * codec_string = = ' = ' ) {
codec_string + + ;
goto ready ;
2007-03-31 19:01:33 +00:00
}
2009-11-24 18:52:57 +00:00
}
2008-05-27 04:54:52 +00:00
2009-11-24 18:52:57 +00:00
if ( ( ocodec = switch_channel_get_variable ( tech_pvt - > channel , SWITCH_ORIGINATOR_CODEC_VARIABLE ) ) ) {
if ( ! codec_string | | sofia_test_pflag ( tech_pvt - > profile , PFLAG_DISABLE_TRANSCODING ) ) {
codec_string = ocodec ;
} else {
if ( ! ( codec_string = switch_core_session_sprintf ( tech_pvt - > session , " %s,%s " , ocodec , codec_string ) ) ) {
2007-03-31 19:01:33 +00:00
codec_string = ocodec ;
}
}
}
2010-02-06 03:38:24 +00:00
2010-06-23 13:22:52 -05:00
ready :
2009-10-03 22:21:52 +00:00
2007-03-31 19:01:33 +00:00
if ( codec_string ) {
char * tmp_codec_string ;
if ( ( tmp_codec_string = switch_core_session_strdup ( tech_pvt - > session , codec_string ) ) ) {
tech_pvt - > codec_order_last = switch_separate_string ( tmp_codec_string , ' , ' , tech_pvt - > codec_order , SWITCH_MAX_CODECS ) ;
tech_pvt - > num_codecs =
switch_loadable_module_get_codecs_sorted ( tech_pvt - > codecs , SWITCH_MAX_CODECS , tech_pvt - > codec_order , tech_pvt - > codec_order_last ) ;
}
} else {
2008-05-27 04:54:52 +00:00
tech_pvt - > num_codecs = switch_loadable_module_get_codecs ( tech_pvt - > codecs , sizeof ( tech_pvt - > codecs ) / sizeof ( tech_pvt - > codecs [ 0 ] ) ) ;
2007-03-31 19:01:33 +00:00
}
2008-05-27 04:54:52 +00:00
2008-03-19 19:02:26 +00:00
2007-04-19 21:40:50 +00:00
}
2008-05-27 04:54:52 +00:00
void sofia_glue_check_video_codecs ( private_object_t * tech_pvt )
2007-04-19 21:40:50 +00:00
{
2009-02-09 17:56:38 +00:00
if ( tech_pvt - > num_codecs & & ! sofia_test_flag ( tech_pvt , TFLAG_VIDEO ) ) {
2007-04-19 21:40:50 +00:00
int i ;
2007-04-19 22:49:01 +00:00
tech_pvt - > video_count = 0 ;
2007-04-19 21:40:50 +00:00
for ( i = 0 ; i < tech_pvt - > num_codecs ; i + + ) {
if ( tech_pvt - > codecs [ i ] - > codec_type = = SWITCH_CODEC_TYPE_VIDEO ) {
tech_pvt - > video_count + + ;
}
}
if ( tech_pvt - > video_count ) {
2009-02-09 17:56:38 +00:00
sofia_set_flag_locked ( tech_pvt , TFLAG_VIDEO ) ;
2007-04-19 21:40:50 +00:00
}
}
2007-03-31 19:01:33 +00:00
}
2007-04-13 22:15:58 +00:00
void sofia_glue_attach_private ( switch_core_session_t * session , sofia_profile_t * profile , private_object_t * tech_pvt , const char * channame )
2007-03-31 19:01:33 +00:00
{
char name [ 256 ] ;
2009-02-11 20:49:45 +00:00
unsigned int x ;
2009-06-18 15:59:28 +00:00
char * p ;
2007-03-31 19:01:33 +00:00
2007-12-12 23:21:45 +00:00
switch_assert ( session ! = NULL ) ;
switch_assert ( profile ! = NULL ) ;
switch_assert ( tech_pvt ! = NULL ) ;
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
tech_pvt - > rtpip = switch_core_session_strdup ( session , profile - > rtpip [ profile - > rtpip_next + + ] ) ;
if ( profile - > rtpip_next > = profile - > rtpip_index ) {
profile - > rtpip_next = 0 ;
}
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 ) {
2010-03-25 03:51:04 +00:00
tech_pvt - > recv_te = tech_pvt - > te = profile - > te ;
2007-03-31 19:01:33 +00:00
}
2011-02-18 20:13:37 -06:00
tech_pvt - > dtmf_type = tech_pvt - > profile - > dtmf_type ;
2011-02-18 19:03:07 -06:00
2009-02-09 17:56:38 +00:00
if ( ! sofia_test_pflag ( tech_pvt - > profile , PFLAG_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 ) ;
2011-02-18 20:16:11 -06:00
sofia_glue_check_dtmf_type ( tech_pvt ) ;
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
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 ) {
switch_snprintf ( name , sizeof ( name ) , " sofia/%s/%s " , profile - > name , channame ) ;
if ( ( p = strchr ( name , ' ; ' ) ) ) {
* p = ' \0 ' ;
}
switch_channel_set_name ( tech_pvt - > channel , name ) ;
2009-06-18 15:59:28 +00:00
}
2007-03-31 19:01:33 +00:00
}
2010-02-06 03:38:24 +00:00
switch_status_t sofia_glue_ext_address_lookup ( sofia_profile_t * profile , private_object_t * tech_pvt , char * * ip , switch_port_t * port ,
const char * sourceip , switch_memory_pool_t * pool )
2007-03-31 19:01:33 +00:00
{
2008-02-07 18:54:20 +00:00
char * error = " " ;
switch_status_t status = SWITCH_STATUS_FALSE ;
2008-02-04 22:38:01 +00:00
int x ;
2008-07-18 16:18:31 +00:00
switch_port_t myport = * port ;
const char * var ;
int funny = 0 ;
2008-07-18 20:25:39 +00:00
switch_port_t stun_port = SWITCH_STUN_DEFAULT_PORT ;
char * stun_ip = NULL ;
2007-03-31 19:01:33 +00:00
if ( ! sourceip ) {
2008-02-07 18:54:20 +00:00
return status ;
2007-03-31 19:01:33 +00:00
}
2008-11-27 02:30:11 +00:00
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 ) ) {
2008-07-18 20:25:39 +00:00
char * p ;
2008-07-21 16:40:28 +00:00
2009-02-09 17:56:38 +00:00
if ( ! sofia_test_pflag ( profile , PFLAG_STUN_ENABLED ) ) {
2010-06-10 17:08:29 -05:00
* ip = switch_core_strdup ( pool , tech_pvt - > rtpip ) ;
2009-02-10 01:48:21 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Trying to use STUN but its disabled! \n " ) ;
2009-08-17 00:32:26 +00:00
goto out ;
2008-07-21 16:40:28 +00:00
}
2010-02-06 03:38:24 +00:00
2008-07-18 20:25:39 +00:00
stun_ip = strdup ( sourceip + 5 ) ;
if ( ( p = strchr ( stun_ip , ' : ' ) ) ) {
int iport ;
* p + + = ' \0 ' ;
iport = atoi ( p ) ;
2008-07-18 20:45:07 +00:00
if ( iport > 0 & & iport < 0xFFFF ) {
stun_port = ( switch_port_t ) iport ;
2008-07-18 20:25:39 +00:00
}
}
2009-10-23 16:03:42 +00:00
if ( zstr ( stun_ip ) ) {
2008-10-11 05:42:52 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " STUN Failed! NO STUN SERVER \n " ) ;
2008-07-18 20:25:39 +00:00
goto out ;
2008-02-07 18:54:20 +00:00
}
2008-07-18 20:25:39 +00:00
2008-02-04 22:38:01 +00:00
for ( x = 0 ; x < 5 ; x + + ) {
2010-02-06 03:38:24 +00:00
if ( sofia_test_pflag ( profile , PFLAG_FUNNY_STUN ) | |
2008-07-18 16:18:31 +00:00
( tech_pvt & & ( var = switch_channel_get_variable ( tech_pvt - > channel , " funny_stun " ) ) & & switch_true ( var ) ) ) {
error = " funny " ;
funny + + ;
}
2008-07-18 20:25:39 +00:00
if ( ( status = switch_stun_lookup ( ip , port , stun_ip , stun_port , & error , pool ) ) ! = SWITCH_STATUS_SUCCESS ) {
2008-02-04 22:38:01 +00:00
switch_yield ( 100000 ) ;
} else {
break ;
}
2007-03-31 19:01:33 +00:00
}
2008-02-04 22:38:01 +00:00
if ( status ! = SWITCH_STATUS_SUCCESS ) {
2008-10-11 05:42:52 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " STUN Failed! %s:%d [%s] \n " , stun_ip , stun_port , error ) ;
2008-07-18 20:25:39 +00:00
goto out ;
2007-03-31 19:01:33 +00:00
}
2008-02-07 18:54:20 +00:00
if ( ! * ip ) {
2008-10-11 05:42:52 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " STUN Failed! No IP returned \n " ) ;
2008-07-18 20:25:39 +00:00
goto out ;
2008-02-07 18:54:20 +00:00
}
2008-10-11 05:42:52 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " STUN Success [%s]:[%d] \n " , * ip , * port ) ;
2008-07-18 20:25:39 +00:00
status = SWITCH_STATUS_SUCCESS ;
2008-07-18 16:18:31 +00:00
if ( tech_pvt ) {
2010-06-10 17:08:29 -05:00
if ( myport = = * port & & ! strcmp ( * ip , tech_pvt - > rtpip ) ) {
2008-10-11 05:42:52 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " STUN Not Required ip and port match. [%s]:[%d] \n " , * ip , * port ) ;
2009-02-09 17:56:38 +00:00
if ( sofia_test_pflag ( profile , PFLAG_STUN_AUTO_DISABLE ) ) {
sofia_clear_pflag ( profile , PFLAG_STUN_ENABLED ) ;
2008-10-11 05:42:52 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " STUN completely disabled. \n " ) ;
2008-07-21 16:40:28 +00:00
}
2008-07-18 16:18:31 +00:00
} else {
tech_pvt - > stun_ip = switch_core_session_strdup ( tech_pvt - > session , stun_ip ) ;
2008-07-18 20:25:39 +00:00
tech_pvt - > stun_port = stun_port ;
2008-07-18 16:18:31 +00:00
tech_pvt - > stun_flags | = STUN_FLAG_SET ;
if ( funny ) {
tech_pvt - > stun_flags | = STUN_FLAG_FUNNY ;
}
}
}
2007-03-31 19:01:33 +00:00
} else {
2010-02-06 03:38:24 +00:00
* ip = ( char * ) sourceip ;
2008-07-18 20:25:39 +00:00
status = SWITCH_STATUS_SUCCESS ;
2007-03-31 19:01:33 +00:00
}
2008-07-18 20:25:39 +00:00
2010-06-23 13:22:52 -05:00
out :
2008-07-18 20:25:39 +00:00
switch_safe_free ( stun_ip ) ;
return status ;
2007-03-31 19:01:33 +00:00
}
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-02-21 17:48:41 +00:00
switch_status_t sofia_glue_tech_choose_port ( private_object_t * tech_pvt , int force )
2007-03-31 19:01:33 +00:00
{
2010-06-10 17:08:29 -05:00
char * lookup_rtpip = tech_pvt - > rtpip ; /* Pointer to externally looked up address */
2010-06-23 13:22:52 -05:00
switch_port_t sdp_port , rtcp_port ; /* The external port to be sent in the SDP */
2009-08-17 00:32:26 +00:00
const char * use_ip = NULL ; /* The external IP to be sent in the SDP */
2007-03-31 19:01:33 +00:00
2009-08-17 00:32:26 +00:00
/* Don't do anything if we're in proxy mode or if a (remote) port already has been found */
2008-02-21 17:48:41 +00:00
if ( ! force ) {
2008-05-27 04:54:52 +00:00
if ( switch_channel_test_flag ( tech_pvt - > channel , CF_PROXY_MODE ) | |
2008-02-21 17:48:41 +00:00
switch_channel_test_flag ( tech_pvt - > channel , CF_PROXY_MEDIA ) | | tech_pvt - > adv_sdp_audio_port ) {
return SWITCH_STATUS_SUCCESS ;
}
2007-03-31 19:01:33 +00:00
}
2008-03-08 21:37:17 +00:00
2009-08-17 00:32:26 +00:00
/* Release the local sdp port */
2008-03-08 21:37:17 +00:00
if ( tech_pvt - > local_sdp_audio_port ) {
2010-06-10 17:08:29 -05:00
switch_rtp_release_port ( tech_pvt - > rtpip , tech_pvt - > local_sdp_audio_port ) ;
2008-02-21 17:48:41 +00:00
}
2009-08-17 00:32:26 +00:00
/* Request a local port from the core's allocator */
2010-06-10 17:08:29 -05:00
if ( ! ( tech_pvt - > local_sdp_audio_port = switch_rtp_request_port ( tech_pvt - > rtpip ) ) ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_CRIT , " No RTP ports available! \n " ) ;
2007-12-11 19:15:02 +00:00
return SWITCH_STATUS_FALSE ;
}
2009-08-17 00:32:26 +00:00
2010-06-10 17:08:29 -05:00
tech_pvt - > local_sdp_audio_ip = tech_pvt - > rtpip ;
2010-02-06 03:38:24 +00:00
2007-03-31 19:01:33 +00:00
sdp_port = tech_pvt - > local_sdp_audio_port ;
2010-09-30 10:08:20 -05:00
/* Check if NAT is detected */
if ( ! zstr ( tech_pvt - > remote_ip ) & & sofia_glue_check_nat ( tech_pvt - > profile , tech_pvt - > remote_ip ) ) {
/* Yes, map the port through switch_nat */
switch_nat_add_mapping ( tech_pvt - > local_sdp_audio_port , SWITCH_NAT_UDP , & sdp_port , SWITCH_FALSE ) ;
switch_nat_add_mapping ( tech_pvt - > local_sdp_audio_port + 1 , SWITCH_NAT_UDP , & rtcp_port , SWITCH_FALSE ) ;
/* Find an IP address to use */
if ( ! ( use_ip = switch_channel_get_variable ( tech_pvt - > channel , " rtp_adv_audio_ip " ) )
& & ! zstr ( tech_pvt - > profile - > extrtpip ) ) {
use_ip = tech_pvt - > profile - > extrtpip ;
}
if ( use_ip ) {
if ( sofia_glue_ext_address_lookup ( tech_pvt - > profile , tech_pvt , & lookup_rtpip , & sdp_port ,
use_ip , switch_core_session_get_pool ( tech_pvt - > session ) ) ! = SWITCH_STATUS_SUCCESS ) {
/* Address lookup was required and fail (external ip was "host:..." or "stun:...") */
return SWITCH_STATUS_FALSE ;
2009-08-17 00:32:26 +00:00
} else {
2010-02-06 03:38:24 +00:00
/* Address properly resolved, use it as external ip */
2009-08-17 00:32:26 +00:00
use_ip = lookup_rtpip ;
}
2010-09-30 10:08:20 -05:00
} else {
/* No external ip found, use the profile's rtp ip */
use_ip = tech_pvt - > rtpip ;
2007-03-31 19:01:33 +00:00
}
2009-06-03 21:08:34 +00:00
} else {
2009-08-17 00:32:26 +00:00
/* No NAT traversal required, use the profile's rtp ip */
2010-06-10 17:08:29 -05:00
use_ip = tech_pvt - > rtpip ;
2009-06-03 21:08:34 +00:00
}
2010-02-06 03:38:24 +00:00
2009-08-17 00:32:26 +00:00
tech_pvt - > adv_sdp_audio_port = sdp_port ;
tech_pvt - > adv_sdp_audio_ip = tech_pvt - > extrtpip = switch_core_session_strdup ( tech_pvt - > session , use_ip ) ;
2007-03-31 19:01:33 +00:00
2011-09-08 17:13:28 -05:00
switch_channel_set_variable ( tech_pvt - > channel , SWITCH_LOCAL_MEDIA_IP_VARIABLE , tech_pvt - > local_sdp_audio_ip ) ;
2009-08-17 00:32:26 +00:00
switch_channel_set_variable_printf ( tech_pvt - > channel , SWITCH_LOCAL_MEDIA_PORT_VARIABLE , " %d " , sdp_port ) ;
2011-09-09 02:47:56 -05:00
switch_channel_set_variable ( tech_pvt - > channel , SWITCH_ADVERTISED_MEDIA_IP_VARIABLE , tech_pvt - > adv_sdp_audio_ip ) ;
2007-03-31 19:01:33 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2009-08-17 00:32:26 +00:00
2008-05-23 19:41:23 +00:00
switch_status_t sofia_glue_tech_choose_video_port ( private_object_t * tech_pvt , int force )
2007-04-19 21:40:50 +00:00
{
2010-06-10 17:08:29 -05:00
char * lookup_rtpip = tech_pvt - > rtpip ; /* Pointer to externally looked up address */
2009-08-17 00:32:26 +00:00
switch_port_t sdp_port ; /* The external port to be sent in the SDP */
const char * use_ip = NULL ; /* The external IP to be sent in the SDP */
2008-05-27 04:54:52 +00:00
2009-08-17 00:32:26 +00:00
/* Don't do anything if we're in proxy mode or if a (remote) port already has been found */
2008-05-24 01:27:19 +00:00
if ( ! force ) {
2009-08-17 00:32:26 +00:00
if ( switch_channel_test_flag ( tech_pvt - > channel , CF_PROXY_MODE ) | |
switch_channel_test_flag ( tech_pvt - > channel , CF_PROXY_MEDIA ) | | tech_pvt - > adv_sdp_video_port ) {
2008-05-24 01:27:19 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2007-04-19 21:40:50 +00:00
}
2009-08-17 00:32:26 +00:00
/* Release the local sdp port */
2008-03-08 21:37:17 +00:00
if ( tech_pvt - > local_sdp_video_port ) {
2010-06-10 17:08:29 -05:00
switch_rtp_release_port ( tech_pvt - > rtpip , tech_pvt - > local_sdp_video_port ) ;
2008-03-08 21:37:17 +00:00
}
2009-08-17 00:32:26 +00:00
/* Request a local port from the core's allocator */
2010-06-10 17:08:29 -05:00
if ( ! ( tech_pvt - > local_sdp_video_port = switch_rtp_request_port ( tech_pvt - > rtpip ) ) ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_CRIT , " No RTP ports available! \n " ) ;
2007-12-11 19:15:02 +00:00
return SWITCH_STATUS_FALSE ;
}
2008-05-27 04:54:52 +00:00
2009-08-17 00:32:26 +00:00
sdp_port = tech_pvt - > local_sdp_video_port ;
2007-04-19 21:40:50 +00:00
2010-09-30 10:08:20 -05:00
/* Check if NAT is detected */
if ( ! zstr ( tech_pvt - > remote_ip ) & & sofia_glue_check_nat ( tech_pvt - > profile , tech_pvt - > remote_ip ) ) {
/* Yes, map the port through switch_nat */
switch_nat_add_mapping ( tech_pvt - > local_sdp_video_port , SWITCH_NAT_UDP , & sdp_port , SWITCH_FALSE ) ;
2007-04-19 21:40:50 +00:00
2010-09-30 10:08:20 -05:00
/* Find an IP address to use */
if ( ! ( use_ip = switch_channel_get_variable ( tech_pvt - > channel , " rtp_adv_video_ip " ) )
& & ! zstr ( tech_pvt - > profile - > extrtpip ) ) {
use_ip = tech_pvt - > profile - > extrtpip ;
}
if ( use_ip ) {
if ( sofia_glue_ext_address_lookup ( tech_pvt - > profile , tech_pvt , & lookup_rtpip , & sdp_port ,
use_ip , switch_core_session_get_pool ( tech_pvt - > session ) ) ! = SWITCH_STATUS_SUCCESS ) {
/* Address lookup was required and fail (external ip was "host:..." or "stun:...") */
return SWITCH_STATUS_FALSE ;
2009-08-17 00:32:26 +00:00
} else {
2010-02-06 03:38:24 +00:00
/* Address properly resolved, use it as external ip */
2009-08-17 00:32:26 +00:00
use_ip = lookup_rtpip ;
}
2010-09-30 10:08:20 -05:00
} else {
/* No external ip found, use the profile's rtp ip */
use_ip = tech_pvt - > rtpip ;
2009-08-17 00:32:26 +00:00
}
} else {
/* No NAT traversal required, use the profile's rtp ip */
2010-06-10 17:08:29 -05:00
use_ip = tech_pvt - > rtpip ;
2009-06-03 21:08:34 +00:00
}
2010-02-06 03:38:24 +00:00
2009-08-17 00:32:26 +00:00
tech_pvt - > adv_sdp_video_port = sdp_port ;
2007-05-09 19:30:41 +00:00
switch_channel_set_variable ( tech_pvt - > channel , SWITCH_LOCAL_VIDEO_IP_VARIABLE , tech_pvt - > adv_sdp_audio_ip ) ;
2009-08-17 00:32:26 +00:00
switch_channel_set_variable_printf ( tech_pvt - > channel , SWITCH_LOCAL_VIDEO_PORT_VARIABLE , " %d " , sdp_port ) ;
2007-04-19 21:40:50 +00:00
return SWITCH_STATUS_SUCCESS ;
}
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 ;
}
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 ;
}
}
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 " ;
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 ) )
? profile - > tls_sip_port : profile - > sip_port , 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
{
if ( port & & port ! = 5060 ) {
if ( session ) {
2010-02-06 03:38:24 +00:00
return switch_core_session_sprintf ( session , " SIP/2.0/%s %s:%d;rport " , sofia_glue_transport2str ( transport ) , ip , port ) ;
2009-06-03 21:08:34 +00:00
} else {
2010-02-06 03:38:24 +00:00
return switch_mprintf ( " SIP/2.0/%s %s:%d;rport " , sofia_glue_transport2str ( transport ) , ip , port ) ;
2009-06-03 21:08:34 +00:00
}
} else {
if ( session ) {
return switch_core_session_sprintf ( session , " SIP/2.0/%s %s;rport " , sofia_glue_transport2str ( transport ) , ip ) ;
} else {
return switch_mprintf ( " SIP/2.0/%s %s;rport " , sofia_glue_transport2str ( transport ) , ip ) ;
}
}
}
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 ;
}
2009-06-03 21:08:34 +00:00
int sofia_glue_check_nat ( sofia_profile_t * profile , const char * network_ip )
{
2010-02-19 22:08:10 +00:00
switch_assert ( network_ip ) ;
2011-04-29 10:28:56 -05:00
return ( profile - > extsipip & &
! switch_check_network_list_ip ( network_ip , " loopback.auto " ) & &
! switch_check_network_list_ip ( network_ip , profile - > local_network ) ) ;
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 ) {
get_addr ( buf , buflen , addrinfo - > ai_addr , addrinfo - > ai_addrlen ) ;
}
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 ,
const char * 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 ;
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
2007-11-15 16:22:18 +00:00
return new_uri ;
}
2009-03-20 01:52:53 +00:00
# define RA_PTR_LEN 512
2008-05-27 04:54:52 +00:00
switch_status_t sofia_glue_tech_proxy_remote_addr ( private_object_t * tech_pvt )
2008-02-22 15:27:40 +00:00
{
const char * err ;
2009-03-20 01:52:53 +00:00
char rip [ RA_PTR_LEN ] = " " ;
char rp [ RA_PTR_LEN ] = " " ;
char rvp [ RA_PTR_LEN ] = " " ;
char * p , * ip_ptr = NULL , * port_ptr = NULL , * vid_port_ptr = NULL , * pe ;
2008-02-21 17:48:41 +00:00
int x ;
2008-07-07 17:56:16 +00:00
const char * val ;
2010-02-06 03:38:24 +00:00
2009-10-23 16:03:42 +00:00
if ( zstr ( tech_pvt - > remote_sdp_str ) ) {
2008-02-21 17:48:41 +00:00
return SWITCH_STATUS_FALSE ;
}
2010-02-06 03:38:24 +00:00
if ( ( p = ( char * ) switch_stristr ( " c=IN IP4 " , tech_pvt - > remote_sdp_str ) ) | | ( p = ( char * ) switch_stristr ( " c=IN IP6 " , tech_pvt - > remote_sdp_str ) ) ) {
2008-02-21 17:48:41 +00:00
ip_ptr = p + 9 ;
}
2008-05-27 04:54:52 +00:00
if ( ( p = ( char * ) switch_stristr ( " m=audio " , tech_pvt - > remote_sdp_str ) ) ) {
2008-02-21 17:48:41 +00:00
port_ptr = p + 8 ;
}
2008-05-23 19:41:23 +00:00
2008-09-25 20:59:09 +00:00
if ( ( p = ( char * ) switch_stristr ( " m=image " , tech_pvt - > remote_sdp_str ) ) ) {
port_ptr = p + 8 ;
}
2008-05-27 04:54:52 +00:00
if ( ( p = ( char * ) switch_stristr ( " m=video " , tech_pvt - > remote_sdp_str ) ) ) {
2008-05-23 19:41:23 +00:00
vid_port_ptr = p + 8 ;
}
2008-05-27 04:54:52 +00:00
2008-02-21 17:48:41 +00:00
if ( ! ( ip_ptr & & port_ptr ) ) {
return SWITCH_STATUS_FALSE ;
}
p = ip_ptr ;
2009-03-20 01:52:53 +00:00
pe = p + strlen ( p ) ;
2008-02-21 17:48:41 +00:00
x = 0 ;
2009-03-20 01:52:53 +00:00
while ( x < sizeof ( rip ) - 1 & & p & & * p & & ( ( * p > = ' 0 ' & & * p < = ' 9 ' ) | | * p = = ' . ' | | * p = = ' : ' | | ( * p > = ' a ' & & * p < = ' f ' ) | | ( * p > = ' A ' & & * p < = ' F ' ) ) ) {
2008-02-21 17:48:41 +00:00
rip [ x + + ] = * p ;
p + + ;
2009-03-20 01:52:53 +00:00
if ( p > = pe ) {
return SWITCH_STATUS_FALSE ;
}
2008-02-21 17:48:41 +00:00
}
p = port_ptr ;
x = 0 ;
2009-03-20 01:52:53 +00:00
while ( x < sizeof ( rp ) - 1 & & p & & * p & & ( * p > = ' 0 ' & & * p < = ' 9 ' ) ) {
2008-02-21 17:48:41 +00:00
rp [ x + + ] = * p ;
p + + ;
2009-03-20 01:52:53 +00:00
if ( p > = pe ) {
return SWITCH_STATUS_FALSE ;
}
2008-02-21 17:48:41 +00:00
}
2008-05-23 19:41:23 +00:00
p = vid_port_ptr ;
x = 0 ;
2009-03-20 01:52:53 +00:00
while ( x < sizeof ( rvp ) - 1 & & p & & * p & & ( * p > = ' 0 ' & & * p < = ' 9 ' ) ) {
2008-05-23 19:41:23 +00:00
rvp [ x + + ] = * p ;
p + + ;
2009-03-20 01:52:53 +00:00
if ( p > = pe ) {
return SWITCH_STATUS_FALSE ;
}
2008-05-23 19:41:23 +00:00
}
2008-10-20 15:10:46 +00:00
if ( ! ( * rip & & * rp ) ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_ERROR , " invalid SDP \n " ) ;
2008-10-20 15:10:46 +00:00
return SWITCH_STATUS_FALSE ;
2008-02-22 15:27:40 +00:00
}
2008-10-20 15:10:46 +00:00
tech_pvt - > remote_sdp_audio_ip = switch_core_session_strdup ( tech_pvt - > session , rip ) ;
tech_pvt - > remote_sdp_audio_port = ( switch_port_t ) atoi ( rp ) ;
2010-02-06 03:38:24 +00:00
2008-05-23 19:41:23 +00:00
if ( * rvp ) {
tech_pvt - > remote_sdp_video_ip = switch_core_session_strdup ( tech_pvt - > session , rip ) ;
tech_pvt - > remote_sdp_video_port = ( switch_port_t ) atoi ( rvp ) ;
}
2008-05-27 04:54:52 +00:00
2008-05-23 22:30:50 +00:00
if ( tech_pvt - > remote_sdp_video_ip & & tech_pvt - > remote_sdp_video_port ) {
if ( ! strcmp ( tech_pvt - > remote_sdp_video_ip , rip ) & & atoi ( rvp ) = = tech_pvt - > remote_sdp_video_port ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_DEBUG , " Remote video address:port [%s:%d] has not changed. \n " ,
2008-05-23 22:30:50 +00:00
tech_pvt - > remote_sdp_audio_ip , tech_pvt - > remote_sdp_audio_port ) ;
} else {
2009-02-09 17:56:38 +00:00
sofia_set_flag_locked ( tech_pvt , TFLAG_VIDEO ) ;
2008-05-23 22:30:50 +00:00
switch_channel_set_flag ( tech_pvt - > channel , CF_VIDEO ) ;
if ( switch_rtp_ready ( tech_pvt - > video_rtp_session ) ) {
2010-04-22 10:22:28 -05:00
const char * rport = NULL ;
2010-06-23 13:22:52 -05:00
switch_port_t remote_rtcp_port = 0 ;
2010-04-22 10:22:28 -05:00
if ( ( rport = switch_channel_get_variable ( tech_pvt - > channel , " sip_remote_video_rtcp_port " ) ) ) {
2010-09-29 15:47:58 -05:00
remote_rtcp_port = ( switch_port_t ) atoi ( rport ) ;
2010-04-22 10:22:28 -05:00
}
2010-02-06 03:38:24 +00:00
if ( switch_rtp_set_remote_address ( tech_pvt - > video_rtp_session , tech_pvt - > remote_sdp_video_ip ,
2010-04-22 10:22:28 -05:00
tech_pvt - > remote_sdp_video_port , remote_rtcp_port , SWITCH_TRUE , & err ) ! = SWITCH_STATUS_SUCCESS ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_ERROR , " VIDEO RTP REPORTS ERROR: [%s] \n " , err ) ;
2008-05-23 22:30:50 +00:00
} else {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_DEBUG , " VIDEO RTP CHANGING DEST TO: [%s:%d] \n " ,
2008-05-23 22:30:50 +00:00
tech_pvt - > remote_sdp_video_ip , tech_pvt - > remote_sdp_video_port ) ;
2008-09-18 21:50:18 +00:00
if ( ! sofia_test_pflag ( tech_pvt - > profile , PFLAG_DISABLE_RTP_AUTOADJ ) & & ! switch_channel_test_flag ( tech_pvt - > channel , CF_PROXY_MODE ) & &
2008-07-07 17:56:16 +00:00
! ( ( val = switch_channel_get_variable ( tech_pvt - > channel , " disable_rtp_auto_adjust " ) ) & & switch_true ( val ) ) ) {
/* Reactivate the NAT buster flag. */
switch_rtp_set_flag ( tech_pvt - > video_rtp_session , SWITCH_RTP_FLAG_AUTOADJ ) ;
}
2009-11-21 06:54:16 +00:00
if ( sofia_test_pflag ( tech_pvt - > profile , PFLAG_AUTOFIX_TIMING ) ) {
tech_pvt - > check_frames = 0 ;
}
2008-05-23 22:30:50 +00:00
}
2008-05-23 19:41:23 +00:00
}
}
}
2008-10-20 15:10:46 +00:00
if ( switch_rtp_ready ( tech_pvt - > rtp_session ) ) {
2008-10-17 19:25:00 +00:00
char * remote_host = switch_rtp_get_remote_host ( tech_pvt - > rtp_session ) ;
2008-10-20 15:10:46 +00:00
switch_port_t remote_port = switch_rtp_get_remote_port ( tech_pvt - > rtp_session ) ;
2010-04-22 10:22:28 -05:00
const char * rport = NULL ;
switch_port_t remote_rtcp_port = 0 ;
2010-02-06 03:38:24 +00:00
2008-10-20 15:10:46 +00:00
if ( remote_host & & remote_port & & ! strcmp ( remote_host , tech_pvt - > remote_sdp_audio_ip ) & & remote_port = = tech_pvt - > remote_sdp_audio_port ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_DEBUG , " Remote address:port [%s:%d] has not changed. \n " ,
2008-10-17 19:25:00 +00:00
tech_pvt - > remote_sdp_audio_ip , tech_pvt - > remote_sdp_audio_port ) ;
return SWITCH_STATUS_SUCCESS ;
}
2010-02-06 03:38:24 +00:00
2010-04-22 10:22:28 -05:00
if ( ( rport = switch_channel_get_variable ( tech_pvt - > channel , " sip_remote_audio_rtcp_port " ) ) ) {
2010-09-29 15:47:58 -05:00
remote_rtcp_port = ( switch_port_t ) atoi ( rport ) ;
2010-04-22 10:22:28 -05:00
}
2010-06-23 13:22:52 -05:00
2010-02-06 03:38:24 +00:00
if ( switch_rtp_set_remote_address ( tech_pvt - > rtp_session , tech_pvt - > remote_sdp_audio_ip ,
2010-04-22 10:22:28 -05:00
tech_pvt - > remote_sdp_audio_port , remote_rtcp_port , SWITCH_TRUE , & err ) ! = SWITCH_STATUS_SUCCESS ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_ERROR , " AUDIO RTP REPORTS ERROR: [%s] \n " , err ) ;
2008-02-22 15:27:40 +00:00
} else {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_DEBUG , " AUDIO RTP CHANGING DEST TO: [%s:%d] \n " ,
2008-02-22 15:27:40 +00:00
tech_pvt - > remote_sdp_audio_ip , tech_pvt - > remote_sdp_audio_port ) ;
2008-07-07 17:56:16 +00:00
if ( ! sofia_test_pflag ( tech_pvt - > profile , PFLAG_DISABLE_RTP_AUTOADJ ) & &
! ( ( val = switch_channel_get_variable ( tech_pvt - > channel , " disable_rtp_auto_adjust " ) ) & & switch_true ( val ) ) ) {
/* Reactivate the NAT buster flag. */
2010-02-06 03:38:24 +00:00
switch_rtp_set_flag ( tech_pvt - > rtp_session , SWITCH_RTP_FLAG_AUTOADJ ) ;
2008-07-07 17:56:16 +00:00
}
2009-11-21 06:54:16 +00:00
if ( sofia_test_pflag ( tech_pvt - > profile , PFLAG_AUTOFIX_TIMING ) ) {
tech_pvt - > check_frames = 0 ;
}
2008-02-22 15:27:40 +00:00
}
}
2008-05-27 04:54:52 +00:00
2008-02-21 17:48:41 +00:00
return SWITCH_STATUS_SUCCESS ;
}
void sofia_glue_tech_patch_sdp ( private_object_t * tech_pvt )
{
switch_size_t len ;
2010-02-06 03:38:24 +00:00
char * p , * q , * pe , * qe ;
int has_video = 0 , has_audio = 0 , has_ip = 0 ;
2008-07-18 19:18:24 +00:00
char port_buf [ 25 ] = " " ;
char vport_buf [ 25 ] = " " ;
2009-03-20 01:52:53 +00:00
char * new_sdp ;
int bad = 0 ;
2011-06-24 18:28:56 -05:00
int skip_video = 0 , skip_audio = 0 , skip_image = 0 ;
2008-02-21 17:48:41 +00:00
2009-10-23 16:03:42 +00:00
if ( zstr ( tech_pvt - > local_sdp_str ) ) {
2008-02-21 17:48:41 +00:00
return ;
}
2009-03-20 01:52:53 +00:00
len = strlen ( tech_pvt - > local_sdp_str ) * 2 ;
2010-02-06 03:38:24 +00:00
if ( switch_channel_test_flag ( tech_pvt - > channel , CF_ANSWERED ) & &
2009-11-27 19:02:20 +00:00
( switch_stristr ( " sendonly " , tech_pvt - > local_sdp_str ) | | switch_stristr ( " 0.0.0.0 " , tech_pvt - > local_sdp_str ) ) ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_DEBUG , " Skip patch on hold SDP \n " ) ;
return ;
2008-05-23 12:39:35 +00:00
}
2010-02-06 03:38:24 +00:00
2009-10-23 16:03:42 +00:00
if ( zstr ( tech_pvt - > adv_sdp_audio_ip ) | | ! tech_pvt - > adv_sdp_audio_port ) {
2010-02-06 03:38:24 +00:00
if ( sofia_glue_tech_choose_port ( tech_pvt , 1 ) ! = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_ERROR , " %s I/O Error \n " ,
switch_channel_get_name ( tech_pvt - > channel ) ) ;
2008-02-22 14:06:13 +00:00
return ;
}
2008-03-07 18:43:28 +00:00
tech_pvt - > iananame = switch_core_session_strdup ( tech_pvt - > session , " PROXY " ) ;
2008-02-22 14:06:13 +00:00
tech_pvt - > rm_rate = 8000 ;
tech_pvt - > codec_ms = 20 ;
2008-02-21 17:48:41 +00:00
}
2010-02-06 03:38:24 +00:00
2009-03-20 01:52:53 +00:00
new_sdp = switch_core_session_alloc ( tech_pvt - > session , len ) ;
2008-07-18 19:18:24 +00:00
switch_snprintf ( port_buf , sizeof ( port_buf ) , " %u " , tech_pvt - > adv_sdp_audio_port ) ;
2010-02-06 03:38:24 +00:00
2008-05-27 04:54:52 +00:00
2009-03-20 01:52:53 +00:00
p = tech_pvt - > local_sdp_str ;
q = new_sdp ;
pe = p + strlen ( p ) ;
qe = q + len - 1 ;
2008-02-21 17:48:41 +00:00
2011-06-24 18:28:56 -05:00
if ( switch_stristr ( " m=video 0 " , p ) ) {
skip_video = 1 ;
} else if ( switch_stristr ( " m=audio 0 " , p ) ) {
skip_audio = 1 ;
} else if ( switch_stristr ( " m=image 0 " , p ) ) {
skip_image = 1 ;
}
2010-02-06 03:38:24 +00:00
while ( p & & * p ) {
2009-03-20 01:52:53 +00:00
if ( p > = pe ) {
bad = 1 ;
goto end ;
}
2010-02-06 03:38:24 +00:00
2009-03-20 01:52:53 +00:00
if ( q > = qe ) {
bad = 2 ;
goto end ;
}
2010-02-06 03:38:24 +00:00
if ( tech_pvt - > adv_sdp_audio_ip & & ! strncmp ( " c=IN IP " , p , 7 ) ) {
2010-10-12 09:32:15 -05:00
strncpy ( q , p , 7 ) ;
p + = 7 ;
q + = 7 ;
strncpy ( q , strchr ( tech_pvt - > adv_sdp_audio_ip , ' : ' ) ? " 6 " : " 4 " , 2 ) ;
p + = 2 ;
q + = 2 ;
2008-02-21 17:48:41 +00:00
strncpy ( q , tech_pvt - > adv_sdp_audio_ip , strlen ( tech_pvt - > adv_sdp_audio_ip ) ) ;
q + = strlen ( tech_pvt - > adv_sdp_audio_ip ) ;
2008-07-18 19:18:24 +00:00
2010-02-06 03:38:24 +00:00
while ( p & & * p & & ( ( * p > = ' 0 ' & & * p < = ' 9 ' ) | | * p = = ' . ' | | * p = = ' : ' | | ( * p > = ' A ' & & * p < = ' F ' ) | | ( * p > = ' a ' & & * p < = ' f ' ) ) ) {
2009-03-20 01:52:53 +00:00
if ( p > = pe ) {
bad = 3 ;
goto end ;
}
2008-02-21 17:48:41 +00:00
p + + ;
}
2010-02-06 03:38:24 +00:00
has_ip + + ;
2008-05-27 04:54:52 +00:00
2010-02-25 00:07:25 +00:00
} else if ( ! strncmp ( " o= " , p , 2 ) ) {
char * oe = strchr ( p , ' \n ' ) ;
switch_size_t len ;
2010-06-23 13:22:52 -05:00
2010-02-25 00:07:25 +00:00
if ( oe ) {
const char * family = " IP4 " ;
char o_line [ 1024 ] = " " ;
if ( oe > = pe ) {
bad = 5 ;
goto end ;
}
2010-03-05 21:41:03 +00:00
len = ( oe - p ) ;
2010-02-25 00:07:25 +00:00
p + = len ;
2010-06-23 13:22:52 -05:00
2010-02-25 00:07:25 +00:00
family = strchr ( tech_pvt - > profile - > sipip , ' : ' ) ? " IP6 " : " IP4 " ;
if ( ! tech_pvt - > owner_id ) {
tech_pvt - > owner_id = ( uint32_t ) switch_epoch_time_now ( NULL ) * 31821U + 13849U ;
}
2010-06-23 13:22:52 -05:00
2010-02-25 00:07:25 +00:00
if ( ! tech_pvt - > session_id ) {
tech_pvt - > session_id = tech_pvt - > owner_id ;
}
2010-06-23 13:22:52 -05:00
2010-02-25 00:07:25 +00:00
tech_pvt - > session_id + + ;
2010-06-23 13:22:52 -05:00
snprintf ( o_line , sizeof ( o_line ) , " o=%s %010u %010u IN %s %s \n " ,
tech_pvt - > profile - > username , tech_pvt - > owner_id , tech_pvt - > session_id , family , tech_pvt - > profile - > sipip ) ;
2010-02-25 00:07:25 +00:00
strncpy ( q , o_line , strlen ( o_line ) ) ;
2010-03-05 21:41:03 +00:00
q + = strlen ( o_line ) - 1 ;
2010-06-23 13:22:52 -05:00
2010-02-25 00:07:25 +00:00
}
2010-06-23 13:22:52 -05:00
2010-03-05 21:41:03 +00:00
} else if ( ! strncmp ( " s= " , p , 2 ) ) {
char * se = strchr ( p , ' \n ' ) ;
switch_size_t len ;
if ( se ) {
char s_line [ 1024 ] = " " ;
if ( se > = pe ) {
bad = 5 ;
goto end ;
}
len = ( se - p ) ;
p + = len ;
snprintf ( s_line , sizeof ( s_line ) , " s=%s \n " , tech_pvt - > profile - > username ) ;
strncpy ( q , s_line , strlen ( s_line ) ) ;
q + = strlen ( s_line ) - 1 ;
}
2010-02-25 00:07:25 +00:00
2011-06-24 18:28:56 -05:00
} else if ( ( ! skip_audio & & ! strncmp ( " m=audio " , p , 8 ) ) | | ( ! skip_image & & ! strncmp ( " m=image " , p , 8 ) ) ) {
2009-03-20 01:52:53 +00:00
strncpy ( q , p , 8 ) ;
2008-07-18 19:18:24 +00:00
p + = 8 ;
2009-03-20 01:52:53 +00:00
if ( p > = pe ) {
bad = 4 ;
goto end ;
}
2008-07-18 19:18:24 +00:00
q + = 8 ;
2010-02-06 03:38:24 +00:00
2009-03-20 01:52:53 +00:00
if ( q > = qe ) {
bad = 5 ;
goto end ;
}
2008-02-21 17:48:41 +00:00
strncpy ( q , port_buf , strlen ( port_buf ) ) ;
q + = strlen ( port_buf ) ;
2008-07-18 19:18:24 +00:00
2009-03-20 01:52:53 +00:00
if ( q > = qe ) {
bad = 6 ;
goto end ;
}
2008-05-27 04:54:52 +00:00
while ( p & & * p & & ( * p > = ' 0 ' & & * p < = ' 9 ' ) ) {
2009-03-20 01:52:53 +00:00
if ( p > = pe ) {
bad = 7 ;
goto end ;
}
2008-02-21 17:48:41 +00:00
p + + ;
}
2008-05-27 04:54:52 +00:00
2010-02-06 03:38:24 +00:00
has_audio + + ;
2008-07-18 19:18:24 +00:00
2011-06-24 18:28:56 -05:00
} else if ( ! skip_video & & ! strncmp ( " m=video " , p , 8 ) ) {
2008-07-18 19:18:24 +00:00
if ( ! has_video ) {
sofia_glue_tech_choose_video_port ( tech_pvt , 1 ) ;
tech_pvt - > video_rm_encoding = " PROXY-VID " ;
tech_pvt - > video_rm_rate = 90000 ;
tech_pvt - > video_codec_ms = 0 ;
switch_snprintf ( vport_buf , sizeof ( vport_buf ) , " %u " , tech_pvt - > adv_sdp_video_port ) ;
}
strncpy ( q , p , 8 ) ;
p + = 8 ;
2009-03-20 01:52:53 +00:00
if ( p > = pe ) {
bad = 8 ;
goto end ;
}
2008-07-18 19:18:24 +00:00
q + = 8 ;
2009-03-20 01:52:53 +00:00
if ( q > = qe ) {
bad = 9 ;
goto end ;
}
2008-07-18 19:18:24 +00:00
strncpy ( q , vport_buf , strlen ( vport_buf ) ) ;
q + = strlen ( vport_buf ) ;
2009-03-20 01:52:53 +00:00
if ( q > = qe ) {
bad = 10 ;
goto end ;
}
2008-05-27 04:54:52 +00:00
while ( p & & * p & & ( * p > = ' 0 ' & & * p < = ' 9 ' ) ) {
2009-03-20 01:52:53 +00:00
if ( p > = pe ) {
bad = 11 ;
goto end ;
}
2008-05-23 12:39:35 +00:00
p + + ;
}
2010-02-06 03:38:24 +00:00
2008-07-18 19:18:24 +00:00
has_video + + ;
2010-02-06 03:38:24 +00:00
}
while ( p & & * p & & * p ! = ' \n ' ) {
2009-03-20 01:52:53 +00:00
if ( p > = pe ) {
bad = 12 ;
goto end ;
}
if ( q > = qe ) {
bad = 13 ;
goto end ;
}
2008-07-18 19:18:24 +00:00
* q + + = * p + + ;
2010-02-06 03:38:24 +00:00
}
2009-03-20 01:52:53 +00:00
if ( p > = pe ) {
2010-02-06 03:38:24 +00:00
bad = 14 ;
goto end ;
}
2009-03-20 01:52:53 +00:00
if ( q > = qe ) {
bad = 15 ;
goto end ;
}
2008-07-18 19:18:24 +00:00
2010-02-06 03:38:24 +00:00
* q + + = * p + + ;
2009-03-20 01:52:53 +00:00
2008-02-21 17:48:41 +00:00
}
2008-05-27 04:54:52 +00:00
2010-06-23 13:22:52 -05:00
end :
2009-03-20 01:52:53 +00:00
if ( bad ) {
return ;
}
if ( switch_channel_down ( tech_pvt - > channel ) | | sofia_test_flag ( tech_pvt , TFLAG_BYE ) ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_DEBUG , " %s too late. \n " , switch_channel_get_name ( tech_pvt - > channel ) ) ;
2009-03-20 01:52:53 +00:00
return ;
}
2008-07-18 19:18:24 +00:00
if ( ! has_ip & & ! has_audio ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_DEBUG , " %s SDP has no audio in it. \n %s \n " ,
2008-07-18 19:18:24 +00:00
switch_channel_get_name ( tech_pvt - > channel ) , tech_pvt - > local_sdp_str ) ;
return ;
}
2010-02-06 03:38:24 +00:00
2009-03-20 01:52:53 +00:00
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_DEBUG , " %s Patched SDP \n --- \n %s \n +++ \n %s \n " ,
2009-03-20 01:52:53 +00:00
switch_channel_get_name ( tech_pvt - > channel ) , tech_pvt - > local_sdp_str , new_sdp ) ;
sofia_glue_tech_set_local_sdp ( tech_pvt , new_sdp , SWITCH_FALSE ) ;
}
void sofia_glue_tech_set_local_sdp ( private_object_t * tech_pvt , const char * sdp_str , switch_bool_t dup )
{
switch_mutex_lock ( tech_pvt - > sofia_mutex ) ;
2010-02-06 03:38:24 +00:00
tech_pvt - > local_sdp_str = dup ? switch_core_session_strdup ( tech_pvt - > session , sdp_str ) : ( char * ) sdp_str ;
switch_channel_set_variable ( tech_pvt - > channel , " sip_local_sdp_str " , tech_pvt - > local_sdp_str ) ;
switch_mutex_unlock ( tech_pvt - > sofia_mutex ) ;
2008-02-21 17:48:41 +00:00
}
2010-06-01 17:13:22 -05:00
char * sofia_glue_get_multipart ( switch_core_session_t * session , const char * prefix , const char * sdp , char * * mp_type )
{
char * extra_headers = NULL ;
switch_stream_handle_t stream = { 0 } ;
switch_event_header_t * hi = NULL ;
int x = 0 ;
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
const char * boundary = switch_core_session_get_uuid ( session ) ;
2010-06-23 13:22:52 -05:00
2010-06-01 17:13:22 -05: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 ;
if ( ! strncasecmp ( name , prefix , strlen ( prefix ) ) ) {
const char * hname = name + strlen ( prefix ) ;
2010-09-22 16:05:44 -05:00
if ( * value = = ' ~ ' ) {
stream . write_function ( & stream , " --%s \n Content-Type: %s \n Content-Length: %d \n %s \n " , boundary , hname , strlen ( value ) , value + 1 ) ;
} else {
stream . write_function ( & stream , " --%s \n Content-Type: %s \n Content-Length: %d \n \n %s \n " , boundary , hname , strlen ( value ) + 1 , value ) ;
}
2010-06-01 17:13:22 -05:00
x + + ;
}
}
switch_channel_variable_last ( channel ) ;
}
if ( x ) {
* mp_type = switch_core_session_sprintf ( session , " multipart/mixed; boundary=%s " , boundary ) ;
if ( sdp ) {
stream . write_function ( & stream , " --%s \n Content-Type: application/sdp \n Content-Length: %d \n \n %s \n " , boundary , strlen ( sdp ) + 1 , sdp ) ;
}
stream . write_function ( & stream , " --%s-- \n " , boundary ) ;
}
if ( ! zstr ( ( char * ) stream . data ) ) {
extra_headers = stream . data ;
} else {
switch_safe_free ( stream . data ) ;
}
return extra_headers ;
}
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 ;
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 ;
}
void sofia_glue_set_extra_headers ( switch_channel_t * channel , sip_t const * sip , const char * prefix )
{
sip_unknown_t * un ;
char name [ 512 ] = " " ;
2010-02-06 03:38:24 +00: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 ) ;
}
}
}
}
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 ;
const char * invite_full_via = switch_channel_get_variable ( tech_pvt - > channel , " sip_invite_full_via " ) ;
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 " ) ;
2010-06-01 17:13:22 -05:00
char * mp = NULL , * mp_type = NULL ;
2010-02-06 03:38:24 +00:00
2007-03-31 19:01:33 +00:00
rep = switch_channel_get_variable ( channel , SOFIA_REPLACES_HEADER ) ;
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 ) ;
2007-11-01 11:28:26 +00:00
cid_name = caller_profile - > caller_id_name ;
cid_num = caller_profile - > caller_id_number ;
2007-04-17 06:08:39 +00:00
sofia_glue_tech_prepare_codecs ( tech_pvt ) ;
2008-03-19 19:02:26 +00:00
sofia_glue_check_video_codecs ( tech_pvt ) ;
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
2008-02-21 17:48:41 +00:00
if ( ( status = sofia_glue_tech_choose_port ( tech_pvt , 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 ;
}
2010-05-12 21:25:54 -05:00
if ( ! switch_channel_get_private ( tech_pvt - > channel , " t38_options " ) | | zstr ( tech_pvt - > local_sdp_str ) ) {
sofia_glue_set_local_sdp ( tech_pvt , NULL , 0 , NULL , 0 ) ;
}
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 " ) ;
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 " ) ;
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
2010-03-02 16:21:28 +00:00
if ( ! zstr ( tech_pvt - > remote_ip ) & & sofia_glue_check_nat ( tech_pvt - > profile , tech_pvt - > remote_ip ) ) {
2010-01-21 00:12:24 +00:00
sipip = tech_pvt - > profile - > extsipip ;
}
2010-02-06 03:38:24 +00:00
2010-01-21 00:12:24 +00:00
format = strchr ( sipip , ' : ' ) ? " \" %s \" <sip:%s%s[%s]> " : " \" %s \" <sip:%s%s%s> " ;
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
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 ) ) {
2010-06-14 13:43:51 -05:00
if ( ! zstr ( tech_pvt - > remote_ip ) & & ! zstr ( tech_pvt - > profile - > extsipip ) & & sofia_glue_check_nat ( tech_pvt - > profile , tech_pvt - > 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
2010-03-02 16:21:28 +00:00
if ( ! zstr ( tech_pvt - > remote_ip ) & & sofia_glue_check_nat ( tech_pvt - > profile , tech_pvt - > 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
2011-08-26 14:10:23 -05:00
if ( ! zstr ( tech_pvt - > remote_ip ) & & sofia_glue_check_nat ( tech_pvt - > profile , tech_pvt - > 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 ,
2008-12-01 23:10:15 +00:00
ipv6 ? " [ " : " " , ip_addr , ipv6 ? " ] " : " " , tech_pvt - > profile - > sip_port ) ;
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 {
2010-03-02 16:21:28 +00:00
if ( ! zstr ( tech_pvt - > remote_ip ) & & sofia_glue_check_nat ( tech_pvt - > profile , tech_pvt - > 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
}
2008-03-11 18:36:56 +00:00
url_str = sofia_overcome_sip_uri_weakness ( session , url , tech_pvt - > transport , SWITCH_TRUE , invite_params ) ;
2009-02-25 23:07:45 +00:00
invite_contact = sofia_overcome_sip_uri_weakness ( session , tech_pvt - > invite_contact , tech_pvt - > transport , SWITCH_FALSE , invite_contact_params ) ;
2010-02-06 03:38:24 +00:00
from_str = sofia_overcome_sip_uri_weakness ( session , invite_from_uri ? invite_from_uri : use_from_str , 0 , SWITCH_TRUE , invite_from_params ) ;
2009-09-14 19:34:35 +00:00
to_str = sofia_overcome_sip_uri_weakness ( session , invite_to_uri ? invite_to_uri : tech_pvt - > dest_to , 0 , SWITCH_FALSE , invite_to_params ) ;
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 ) ;
}
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 ) ) ,
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! \n url_str=[%s] \n call_id=[%s] \n to_str=[%s] \n from_str=[%s] \n invite_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
2010-02-06 03:38:24 +00:00
if ( sofia_test_flag ( tech_pvt , TFLAG_RECOVERING ) & & switch_channel_direction ( tech_pvt - > channel ) = = SWITCH_CALL_DIRECTION_INBOUND ) {
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 ) ) {
2010-02-06 03:38:24 +00:00
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 {
tech_pvt - > preferred_id = switch_core_session_sprintf ( tech_pvt - > session , " \" %s \" <sip:%s@%s> " ,
tech_pvt - > caller_profile - > caller_id_name ,
2010-02-06 03:38:24 +00:00
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 {
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 ) ) ;
2008-07-29 17:54:42 +00:00
sofia_private - > is_call + + ;
2011-07-16 11:30:36 -05:00
sofia_private - > is_static + + ;
2011-07-16 01:02:22 -05:00
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 ) ;
}
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 ) ) {
2008-02-22 15:27:40 +00:00
if ( switch_rtp_ready ( tech_pvt - > rtp_session ) ) {
sofia_glue_tech_proxy_remote_addr ( tech_pvt ) ;
}
2008-02-21 17:48:41 +00:00
sofia_glue_tech_patch_sdp ( tech_pvt ) ;
}
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 ) {
2009-06-25 15:40:38 +00:00
route_uri = sofia_overcome_sip_uri_weakness ( tech_pvt - > session , dst - > route_uri , tech_pvt - > transport , SWITCH_TRUE , 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 ;
}
2010-06-01 17:13:22 -05:00
if ( ( mp = sofia_glue_get_multipart ( session , SOFIA_MULTIPART_PREFIX , tech_pvt - > local_sdp_str , & mp_type ) ) ) {
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
}
2011-08-22 10:59:33 -05:00
2010-01-07 05:22:02 +00:00
if ( sofia_use_soa ( tech_pvt ) ) {
nua_invite ( tech_pvt - > nh ,
NUTAG_AUTOANSWER ( 0 ) ,
2011-08-04 00:01:26 -05:00
//TAG_IF(zstr(tech_pvt->local_sdp_str), NUTAG_AUTOACK(0)),
//TAG_IF(!zstr(tech_pvt->local_sdp_str), NUTAG_AUTOACK(1)),
// 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 ) ) ,
TAG_IF ( ! zstr ( tech_pvt - > user_via ) , SIPTAG_VIA_STR ( tech_pvt - > user_via ) ) ,
2010-02-06 03:38:24 +00:00
TAG_IF ( ! zstr ( invite_full_via ) , SIPTAG_VIA_STR ( invite_full_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 ) ) ,
2011-06-15 10:29:07 -05:00
TAG_IF ( zstr ( tech_pvt - > local_sdp_str ) , SIPTAG_PAYLOAD_STR ( " " ) ) ,
TAG_IF ( ! zstr ( tech_pvt - > local_sdp_str ) , SOATAG_ADDRESS ( tech_pvt - > adv_sdp_audio_ip ) ) ,
TAG_IF ( ! zstr ( tech_pvt - > local_sdp_str ) , SOATAG_USER_SDP_STR ( tech_pvt - > local_sdp_str ) ) ,
TAG_IF ( ! zstr ( tech_pvt - > local_sdp_str ) , SOATAG_REUSE_REJECTED ( 1 ) ) ,
TAG_IF ( ! zstr ( tech_pvt - > local_sdp_str ) , SOATAG_ORDERED_USER ( 1 ) ) ,
TAG_IF ( ! zstr ( tech_pvt - > local_sdp_str ) , SOATAG_RTP_SORT ( SOA_RTP_SORT_REMOTE ) ) ,
TAG_IF ( ! zstr ( tech_pvt - > local_sdp_str ) , SOATAG_RTP_SELECT ( SOA_RTP_SELECT_ALL ) ) ,
TAG_IF ( rep , SIPTAG_REPLACES_STR ( rep ) ) ,
TAG_IF ( ! zstr ( tech_pvt - > 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 ) ) ,
TAG_IF ( ! zstr ( tech_pvt - > user_via ) , SIPTAG_VIA_STR ( tech_pvt - > user_via ) ) ,
2010-02-06 03:38:24 +00:00
TAG_IF ( ! zstr ( invite_full_via ) , SIPTAG_VIA_STR ( invite_full_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 ) ) ,
2010-02-06 03:38:24 +00:00
TAG_IF ( cseq , SIPTAG_CSEQ ( cseq ) ) ,
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 " ) ,
2010-06-23 13:22:52 -05:00
SIPTAG_PAYLOAD_STR ( mp ? mp : tech_pvt - > 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 ) ;
2010-03-02 16:21:28 +00:00
if ( ! zstr ( tech_pvt - > remote_ip ) & & sofia_glue_check_nat ( tech_pvt - > profile , tech_pvt - > 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 ) ) ,
2008-10-06 20:10:14 +00:00
SOATAG_ADDRESS ( tech_pvt - > adv_sdp_audio_ip ) ,
2007-03-31 19:01:33 +00:00
SOATAG_USER_SDP_STR ( tech_pvt - > local_sdp_str ) ,
2008-03-05 22:39:22 +00:00
SOATAG_REUSE_REJECTED ( 1 ) ,
SOATAG_ORDERED_USER ( 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-04-13 22:15:58 +00:00
void sofia_glue_tech_absorb_sdp ( private_object_t * tech_pvt )
2007-03-31 19:01:33 +00:00
{
2007-11-01 11:28:26 +00:00
const char * sdp_str ;
2007-03-31 19:01:33 +00:00
2007-05-09 19:30:41 +00:00
if ( ( sdp_str = switch_channel_get_variable ( tech_pvt - > channel , SWITCH_B_SDP_VARIABLE ) ) ) {
2007-03-31 19:01:33 +00:00
sdp_parser_t * parser ;
sdp_session_t * sdp ;
sdp_media_t * m ;
sdp_connection_t * connection ;
2007-04-14 00:13:19 +00:00
if ( ( parser = sdp_parse ( NULL , sdp_str , ( int ) strlen ( sdp_str ) , 0 ) ) ) {
2007-03-31 19:01:33 +00:00
if ( ( sdp = sdp_session ( parser ) ) ) {
for ( m = sdp - > sdp_media ; m ; m = m - > m_next ) {
2008-02-26 21:13:47 +00:00
if ( m - > m_type ! = sdp_media_audio | | ! m - > m_port ) {
2007-03-31 19:01:33 +00:00
continue ;
}
connection = sdp - > sdp_connection ;
if ( m - > m_connections ) {
connection = m - > m_connections ;
}
if ( connection ) {
tech_pvt - > proxy_sdp_audio_ip = switch_core_session_strdup ( tech_pvt - > session , connection - > c_address ) ;
}
tech_pvt - > proxy_sdp_audio_port = ( switch_port_t ) m - > m_port ;
if ( tech_pvt - > proxy_sdp_audio_ip & & tech_pvt - > proxy_sdp_audio_port ) {
break ;
}
}
}
sdp_parser_free ( parser ) ;
}
2009-03-20 01:52:53 +00:00
sofia_glue_tech_set_local_sdp ( tech_pvt , sdp_str , SWITCH_TRUE ) ;
2007-03-31 19:01:33 +00:00
}
}
2009-04-03 21:48:52 +00:00
2010-06-23 13:22:52 -05:00
# define add_stat(_i, _s) \
2009-04-03 21:48:52 +00:00
switch_snprintf ( var_name , sizeof ( var_name ) , " rtp_%s_%s " , switch_str_nil ( prefix ) , _s ) ; \
switch_snprintf ( var_val , sizeof ( var_val ) , " % " SWITCH_SIZE_T_FMT , _i ) ; \
switch_channel_set_variable ( tech_pvt - > channel , var_name , var_val )
static void set_stats ( switch_rtp_t * rtp_session , private_object_t * tech_pvt , const char * prefix )
{
switch_rtp_stats_t * stats = switch_rtp_get_stats ( rtp_session , NULL ) ;
char var_name [ 256 ] = " " , var_val [ 35 ] = " " ;
if ( stats ) {
2009-04-15 15:08:21 +00:00
add_stat ( stats - > inbound . raw_bytes , " in_raw_bytes " ) ;
add_stat ( stats - > inbound . media_bytes , " in_media_bytes " ) ;
add_stat ( stats - > inbound . packet_count , " in_packet_count " ) ;
add_stat ( stats - > inbound . media_packet_count , " in_media_packet_count " ) ;
add_stat ( stats - > inbound . skip_packet_count , " in_skip_packet_count " ) ;
add_stat ( stats - > inbound . jb_packet_count , " in_jb_packet_count " ) ;
add_stat ( stats - > inbound . dtmf_packet_count , " in_dtmf_packet_count " ) ;
add_stat ( stats - > inbound . cng_packet_count , " in_cng_packet_count " ) ;
2009-11-17 15:20:40 +00:00
add_stat ( stats - > inbound . flush_packet_count , " in_flush_packet_count " ) ;
2011-05-06 15:25:00 -05:00
add_stat ( stats - > inbound . largest_jb_size , " in_largest_jb_size " ) ;
2009-04-15 15:08:21 +00:00
add_stat ( stats - > outbound . raw_bytes , " out_raw_bytes " ) ;
add_stat ( stats - > outbound . media_bytes , " out_media_bytes " ) ;
add_stat ( stats - > outbound . packet_count , " out_packet_count " ) ;
add_stat ( stats - > outbound . media_packet_count , " out_media_packet_count " ) ;
add_stat ( stats - > outbound . skip_packet_count , " out_skip_packet_count " ) ;
add_stat ( stats - > outbound . dtmf_packet_count , " out_dtmf_packet_count " ) ;
add_stat ( stats - > outbound . cng_packet_count , " out_cng_packet_count " ) ;
2010-02-06 03:38:24 +00:00
2010-09-10 11:59:47 -05:00
add_stat ( stats - > rtcp . packet_count , " rtcp_packet_count " ) ;
add_stat ( stats - > rtcp . octet_count , " rtcp_octet_count " ) ;
2009-04-03 21:48:52 +00:00
}
}
2009-04-14 16:55:10 +00:00
void sofia_glue_set_rtp_stats ( private_object_t * tech_pvt )
{
if ( tech_pvt - > rtp_session ) {
2010-02-06 03:38:24 +00:00
set_stats ( tech_pvt - > rtp_session , tech_pvt , " audio " ) ;
2009-04-14 16:55:10 +00:00
}
if ( tech_pvt - > video_rtp_session ) {
2010-02-06 03:38:24 +00:00
set_stats ( tech_pvt - > video_rtp_session , tech_pvt , " video " ) ;
2009-04-14 16:55:10 +00:00
}
}
2007-04-13 22:15:58 +00:00
void sofia_glue_deactivate_rtp ( private_object_t * tech_pvt )
2007-03-31 19:01:33 +00:00
{
2008-01-16 06:01:53 +00:00
int loops = 0 ;
2007-03-31 19:01:33 +00:00
if ( switch_rtp_ready ( tech_pvt - > rtp_session ) ) {
2009-02-09 17:56:38 +00:00
while ( loops < 10 & & ( sofia_test_flag ( tech_pvt , TFLAG_READING ) | | sofia_test_flag ( tech_pvt , TFLAG_WRITING ) ) ) {
2007-03-31 19:01:33 +00:00
switch_yield ( 10000 ) ;
loops + + ;
}
2008-02-15 16:15:32 +00:00
}
if ( tech_pvt - > video_rtp_session ) {
2007-04-19 21:40:50 +00:00
switch_rtp_destroy ( & tech_pvt - > video_rtp_session ) ;
2008-03-10 16:13:12 +00:00
} else if ( tech_pvt - > local_sdp_video_port ) {
2010-06-10 17:08:29 -05:00
switch_rtp_release_port ( tech_pvt - > rtpip , tech_pvt - > local_sdp_video_port ) ;
2007-04-19 21:40:50 +00:00
}
2008-02-15 16:15:32 +00:00
2010-02-06 03:38:24 +00:00
2010-03-02 16:21:28 +00:00
if ( tech_pvt - > local_sdp_video_port > 0 & & ! zstr ( tech_pvt - > remote_ip ) & & sofia_glue_check_nat ( tech_pvt - > profile , tech_pvt - > remote_ip ) ) {
2010-02-06 03:38:24 +00:00
switch_nat_del_mapping ( ( switch_port_t ) tech_pvt - > local_sdp_video_port , SWITCH_NAT_UDP ) ;
2010-04-24 15:05:04 -05:00
switch_nat_del_mapping ( ( switch_port_t ) tech_pvt - > local_sdp_video_port + 1 , SWITCH_NAT_UDP ) ;
2009-06-03 21:08:34 +00:00
}
2010-02-03 19:19:10 +00:00
if ( tech_pvt - > rtp_session ) {
switch_rtp_destroy ( & tech_pvt - > rtp_session ) ;
} else if ( tech_pvt - > local_sdp_audio_port ) {
2010-06-10 17:08:29 -05:00
switch_rtp_release_port ( tech_pvt - > rtpip , tech_pvt - > local_sdp_audio_port ) ;
2010-02-03 19:19:10 +00:00
}
2010-03-02 16:21:28 +00:00
if ( tech_pvt - > local_sdp_audio_port > 0 & & ! zstr ( tech_pvt - > remote_ip ) & & sofia_glue_check_nat ( tech_pvt - > profile , tech_pvt - > remote_ip ) ) {
2010-02-06 03:38:24 +00:00
switch_nat_del_mapping ( ( switch_port_t ) tech_pvt - > local_sdp_audio_port , SWITCH_NAT_UDP ) ;
2010-04-24 15:05:04 -05:00
switch_nat_del_mapping ( ( switch_port_t ) tech_pvt - > local_sdp_audio_port + 1 , SWITCH_NAT_UDP ) ;
2010-02-03 19:19:10 +00:00
}
2010-02-06 03:38:24 +00:00
2007-04-19 21:40:50 +00:00
}
switch_status_t sofia_glue_tech_set_video_codec ( private_object_t * tech_pvt , int force )
{
2009-04-09 17:17:12 +00:00
if ( tech_pvt - > video_read_codec . implementation & & switch_core_codec_ready ( & tech_pvt - > video_read_codec ) ) {
2007-04-19 21:40:50 +00:00
if ( ! force ) {
return SWITCH_STATUS_SUCCESS ;
}
if ( strcasecmp ( tech_pvt - > video_read_codec . implementation - > iananame , tech_pvt - > video_rm_encoding ) | |
tech_pvt - > video_read_codec . implementation - > samples_per_second ! = tech_pvt - > video_rm_rate ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_DEBUG , " Changing Codec from %s to %s \n " ,
2007-04-19 21:40:50 +00:00
tech_pvt - > video_read_codec . implementation - > iananame , tech_pvt - > video_rm_encoding ) ;
switch_core_codec_destroy ( & tech_pvt - > video_read_codec ) ;
switch_core_codec_destroy ( & tech_pvt - > video_write_codec ) ;
} else {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_DEBUG , " Already using %s \n " ,
tech_pvt - > video_read_codec . implementation - > iananame ) ;
2007-04-19 21:40:50 +00:00
return SWITCH_STATUS_SUCCESS ;
}
}
if ( ! tech_pvt - > video_rm_encoding ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_ERROR , " Can't load codec with no name? \n " ) ;
2007-04-19 21:40:50 +00:00
return SWITCH_STATUS_FALSE ;
}
if ( switch_core_codec_init ( & tech_pvt - > video_read_codec ,
tech_pvt - > video_rm_encoding ,
tech_pvt - > video_rm_fmtp ,
tech_pvt - > video_rm_rate ,
0 ,
1 ,
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE ,
NULL , switch_core_session_get_pool ( tech_pvt - > session ) ) ! = SWITCH_STATUS_SUCCESS ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_ERROR , " Can't load codec? \n " ) ;
2007-04-19 21:40:50 +00:00
return SWITCH_STATUS_FALSE ;
} else {
if ( switch_core_codec_init ( & tech_pvt - > video_write_codec ,
tech_pvt - > video_rm_encoding ,
tech_pvt - > video_rm_fmtp ,
tech_pvt - > video_rm_rate ,
2007-11-20 02:27:48 +00:00
0 ,
2007-04-19 21:40:50 +00:00
1 ,
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE ,
NULL , switch_core_session_get_pool ( tech_pvt - > session ) ) ! = SWITCH_STATUS_SUCCESS ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_ERROR , " Can't load codec? \n " ) ;
2007-04-19 21:40:50 +00:00
return SWITCH_STATUS_FALSE ;
} else {
tech_pvt - > video_read_frame . rate = tech_pvt - > video_rm_rate ;
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_DEBUG , " Set VIDEO Codec %s %s/%ld %d ms \n " ,
2007-05-09 19:30:41 +00:00
switch_channel_get_name ( tech_pvt - > channel ) , tech_pvt - > video_rm_encoding , tech_pvt - > video_rm_rate , tech_pvt - > video_codec_ms ) ;
2007-04-19 21:40:50 +00:00
tech_pvt - > video_read_frame . codec = & tech_pvt - > video_read_codec ;
2008-05-27 04:54:52 +00:00
2008-02-07 22:42:27 +00:00
tech_pvt - > video_fmtp_out = switch_core_session_strdup ( tech_pvt - > session , tech_pvt - > video_write_codec . fmtp_out ) ;
2008-02-11 17:14:14 +00:00
tech_pvt - > video_write_codec . agreed_pt = tech_pvt - > video_agreed_pt ;
tech_pvt - > video_read_codec . agreed_pt = tech_pvt - > video_agreed_pt ;
2008-02-09 00:38:23 +00:00
switch_core_session_set_video_read_codec ( tech_pvt - > session , & tech_pvt - > video_read_codec ) ;
switch_core_session_set_video_write_codec ( tech_pvt - > session , & tech_pvt - > video_write_codec ) ;
2010-02-06 03:38:24 +00:00
switch_channel_set_variable ( tech_pvt - > channel , " sip_use_video_codec_name " , tech_pvt - > video_rm_encoding ) ;
switch_channel_set_variable ( tech_pvt - > channel , " sip_use_video_codec_fmtp " , tech_pvt - > video_rm_fmtp ) ;
switch_channel_set_variable_printf ( tech_pvt - > channel , " sip_use_video_codec_rate " , " %d " , tech_pvt - > video_rm_rate ) ;
switch_channel_set_variable_printf ( tech_pvt - > channel , " sip_use_video_codec_ptime " , " %d " , 0 ) ;
2007-04-19 21:40:50 +00:00
}
}
return SWITCH_STATUS_SUCCESS ;
2007-03-31 19:01:33 +00:00
}
2007-04-13 22:15:58 +00:00
switch_status_t sofia_glue_tech_set_codec ( private_object_t * tech_pvt , int force )
2007-03-31 19:01:33 +00:00
{
2008-12-18 23:07:32 +00:00
switch_status_t status = SWITCH_STATUS_SUCCESS ;
int resetting = 0 ;
2009-12-03 22:51:50 +00:00
2008-02-15 19:48:16 +00:00
if ( ! tech_pvt - > iananame ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_ERROR , " No audio codec available \n " ) ;
2008-12-18 23:07:32 +00:00
switch_goto_status ( SWITCH_STATUS_FALSE , end ) ;
2008-02-15 19:48:16 +00:00
}
2009-12-03 22:51:50 +00:00
if ( switch_core_codec_ready ( & tech_pvt - > read_codec ) ) {
2007-03-31 19:01:33 +00:00
if ( ! force ) {
2008-12-18 23:07:32 +00:00
switch_goto_status ( SWITCH_STATUS_SUCCESS , end ) ;
2007-03-31 19:01:33 +00:00
}
2009-12-03 22:51:50 +00:00
if ( strcasecmp ( tech_pvt - > read_impl . iananame , tech_pvt - > iananame ) | |
tech_pvt - > read_impl . samples_per_second ! = tech_pvt - > rm_rate | |
2010-02-06 03:38:24 +00:00
tech_pvt - > codec_ms ! = ( uint32_t ) tech_pvt - > read_impl . microseconds_per_packet / 1000 ) {
2010-10-27 16:37:22 -05:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_DEBUG ,
" Changing Codec from %s@%dms@%dhz to %s@%dms@%luhz \n " ,
tech_pvt - > read_impl . iananame , tech_pvt - > read_impl . microseconds_per_packet / 1000 ,
tech_pvt - > read_impl . samples_per_second ,
tech_pvt - > rm_encoding ,
tech_pvt - > codec_ms ,
tech_pvt - > rm_rate ) ;
2010-12-17 17:27:23 -06:00
switch_yield ( tech_pvt - > read_impl . microseconds_per_packet ) ;
2008-12-18 23:07:32 +00:00
switch_core_session_lock_codec_write ( tech_pvt - > session ) ;
switch_core_session_lock_codec_read ( tech_pvt - > session ) ;
resetting = 1 ;
2010-12-03 20:22:02 -06:00
switch_yield ( tech_pvt - > read_impl . microseconds_per_packet ) ;
2007-03-31 19:01:33 +00:00
switch_core_codec_destroy ( & tech_pvt - > read_codec ) ;
switch_core_codec_destroy ( & tech_pvt - > write_codec ) ;
} else {
2009-12-03 22:51:50 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_DEBUG , " Already using %s \n " , tech_pvt - > read_impl . iananame ) ;
2008-12-18 23:07:32 +00:00
switch_goto_status ( SWITCH_STATUS_SUCCESS , end ) ;
2007-03-31 19:01:33 +00:00
}
}
2010-02-06 03:38:24 +00:00
2010-09-29 16:52:34 -05:00
if ( switch_core_codec_init_with_bitrate ( & tech_pvt - > read_codec ,
2007-11-21 17:07:41 +00:00
tech_pvt - > iananame ,
2007-03-31 19:01:33 +00:00
tech_pvt - > rm_fmtp ,
tech_pvt - > rm_rate ,
tech_pvt - > codec_ms ,
1 ,
2010-09-29 16:52:34 -05:00
tech_pvt - > bitrate ,
2007-03-31 19:01:33 +00:00
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE | tech_pvt - > profile - > codec_flags ,
NULL , switch_core_session_get_pool ( tech_pvt - > session ) ) ! = SWITCH_STATUS_SUCCESS ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_ERROR , " Can't load codec? \n " ) ;
2010-10-15 17:53:38 -05:00
switch_channel_hangup ( tech_pvt - > channel , SWITCH_CAUSE_INCOMPATIBLE_DESTINATION ) ;
2011-01-13 18:41:43 -06:00
switch_goto_status ( SWITCH_STATUS_FALSE , end ) ;
2008-05-27 04:54:52 +00:00
}
2007-12-13 04:01:29 +00:00
2010-09-29 16:52:34 -05:00
if ( switch_core_codec_init_with_bitrate ( & tech_pvt - > write_codec ,
2007-12-13 04:01:29 +00:00
tech_pvt - > iananame ,
tech_pvt - > rm_fmtp ,
tech_pvt - > rm_rate ,
tech_pvt - > codec_ms ,
1 ,
2010-09-29 16:52:34 -05:00
tech_pvt - > bitrate ,
2007-12-13 04:01:29 +00:00
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE | tech_pvt - > profile - > codec_flags ,
NULL , switch_core_session_get_pool ( tech_pvt - > session ) ) ! = SWITCH_STATUS_SUCCESS ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_ERROR , " Can't load codec? \n " ) ;
2010-10-15 17:53:38 -05:00
switch_channel_hangup ( tech_pvt - > channel , SWITCH_CAUSE_INCOMPATIBLE_DESTINATION ) ;
2008-12-18 23:07:32 +00:00
switch_goto_status ( SWITCH_STATUS_FALSE , end ) ;
2008-05-27 04:54:52 +00:00
}
2007-12-13 04:01:29 +00:00
2010-02-06 03:38:24 +00:00
switch_channel_set_variable ( tech_pvt - > channel , " sip_use_codec_name " , tech_pvt - > iananame ) ;
switch_channel_set_variable ( tech_pvt - > channel , " sip_use_codec_fmtp " , tech_pvt - > rm_fmtp ) ;
switch_channel_set_variable_printf ( tech_pvt - > channel , " sip_use_codec_rate " , " %d " , tech_pvt - > rm_rate ) ;
switch_channel_set_variable_printf ( tech_pvt - > channel , " sip_use_codec_ptime " , " %d " , tech_pvt - > codec_ms ) ;
2009-01-14 15:28:17 +00:00
switch_assert ( tech_pvt - > read_codec . implementation ) ;
switch_assert ( tech_pvt - > write_codec . implementation ) ;
2009-01-12 18:37:44 +00:00
tech_pvt - > read_impl = * tech_pvt - > read_codec . implementation ;
tech_pvt - > write_impl = * tech_pvt - > write_codec . implementation ;
2009-09-16 04:22:24 +00:00
switch_core_session_set_read_impl ( tech_pvt - > session , tech_pvt - > read_codec . implementation ) ;
switch_core_session_set_write_impl ( tech_pvt - > session , tech_pvt - > write_codec . implementation ) ;
2009-01-12 18:37:44 +00:00
2008-11-13 18:06:40 +00:00
if ( switch_rtp_ready ( tech_pvt - > rtp_session ) ) {
2008-11-13 20:47:45 +00:00
switch_assert ( tech_pvt - > read_codec . implementation ) ;
2010-09-29 14:14:41 -05:00
2010-02-06 03:38:24 +00:00
if ( switch_rtp_change_interval ( tech_pvt - > rtp_session ,
2010-09-29 14:14:41 -05:00
tech_pvt - > read_impl . microseconds_per_packet ,
tech_pvt - > read_impl . samples_per_packet ) ! = SWITCH_STATUS_SUCCESS ) {
2009-12-03 22:51:50 +00:00
switch_channel_hangup ( tech_pvt - > channel , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
2010-02-06 03:38:24 +00:00
switch_goto_status ( SWITCH_STATUS_FALSE , end ) ;
2009-12-03 22:51:50 +00:00
}
2008-11-13 18:06:40 +00:00
}
2007-12-13 04:01:29 +00:00
tech_pvt - > read_frame . rate = tech_pvt - > rm_rate ;
2009-04-09 17:17:12 +00:00
if ( ! switch_core_codec_ready ( & tech_pvt - > read_codec ) ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_ERROR , " Can't load codec? \n " ) ;
2008-12-18 23:07:32 +00:00
switch_goto_status ( SWITCH_STATUS_FALSE , end ) ;
2007-03-31 19:01:33 +00:00
}
2007-12-13 04:01:29 +00:00
2010-09-29 16:52:34 -05:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_DEBUG , " Set Codec %s %s/%ld %d ms %d samples %d bits \n " ,
2007-12-13 04:01:29 +00:00
switch_channel_get_name ( tech_pvt - > channel ) , tech_pvt - > iananame , tech_pvt - > rm_rate , tech_pvt - > codec_ms ,
2010-09-29 16:52:34 -05:00
tech_pvt - > read_impl . samples_per_packet , tech_pvt - > read_impl . bits_per_second ) ;
2007-12-13 04:01:29 +00:00
tech_pvt - > read_frame . codec = & tech_pvt - > read_codec ;
2008-05-27 04:54:52 +00:00
2008-02-11 17:14:14 +00:00
tech_pvt - > write_codec . agreed_pt = tech_pvt - > agreed_pt ;
tech_pvt - > read_codec . agreed_pt = tech_pvt - > agreed_pt ;
2008-11-10 18:26:41 +00:00
if ( force ! = 2 ) {
switch_core_session_set_read_codec ( tech_pvt - > session , & tech_pvt - > read_codec ) ;
switch_core_session_set_write_codec ( tech_pvt - > session , & tech_pvt - > write_codec ) ;
}
2007-12-13 04:01:29 +00:00
tech_pvt - > fmtp_out = switch_core_session_strdup ( tech_pvt - > session , tech_pvt - > write_codec . fmtp_out ) ;
2008-01-03 00:50:53 +00:00
if ( switch_rtp_ready ( tech_pvt - > rtp_session ) ) {
switch_rtp_set_default_payload ( tech_pvt - > rtp_session , tech_pvt - > pt ) ;
}
2010-06-23 13:22:52 -05:00
end :
2008-12-18 23:07:32 +00:00
if ( resetting ) {
switch_core_session_unlock_codec_write ( tech_pvt - > session ) ;
switch_core_session_unlock_codec_read ( tech_pvt - > session ) ;
}
2010-01-22 00:51:32 +00:00
2008-12-18 23:07:32 +00:00
return status ;
2007-03-31 19:01:33 +00:00
}
2008-01-16 06:01:53 +00:00
switch_status_t sofia_glue_build_crypto ( private_object_t * tech_pvt , int index , switch_rtp_crypto_key_type_t type , switch_rtp_crypto_direction_t direction )
{
unsigned char b64_key [ 512 ] = " " ;
const char * type_str ;
unsigned char * key ;
2008-07-07 17:56:16 +00:00
const char * val ;
2008-01-16 06:01:53 +00:00
char * p ;
if ( type = = AES_CM_128_HMAC_SHA1_80 ) {
type_str = SWITCH_RTP_CRYPTO_KEY_80 ;
} else {
type_str = SWITCH_RTP_CRYPTO_KEY_32 ;
}
if ( direction = = SWITCH_RTP_CRYPTO_SEND ) {
key = tech_pvt - > local_raw_key ;
} else {
key = tech_pvt - > remote_raw_key ;
}
2008-05-27 04:54:52 +00:00
2008-01-16 06:01:53 +00:00
switch_rtp_get_random ( key , SWITCH_RTP_KEY_LEN ) ;
switch_b64_encode ( key , SWITCH_RTP_KEY_LEN , b64_key , sizeof ( b64_key ) ) ;
2008-05-27 04:54:52 +00:00
p = strrchr ( ( char * ) b64_key , ' = ' ) ;
2008-01-16 06:01:53 +00:00
2008-05-27 04:54:52 +00:00
while ( p & & * p & & * p = = ' = ' ) {
2008-01-16 06:01:53 +00:00
* p - - = ' \0 ' ;
}
tech_pvt - > local_crypto_key = switch_core_session_sprintf ( tech_pvt - > session , " %d %s inline:%s " , index , type_str , b64_key ) ;
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_DEBUG , " Set Local Key [%s] \n " , tech_pvt - > local_crypto_key ) ;
2008-01-16 06:01:53 +00:00
2008-07-07 17:56:16 +00:00
if ( ! sofia_test_pflag ( tech_pvt - > profile , PFLAG_DISABLE_SRTP_AUTH ) & &
! ( ( val = switch_channel_get_variable ( tech_pvt - > channel , " NDLB_support_asterisk_missing_srtp_auth " ) ) & & switch_true ( val ) ) ) {
tech_pvt - > crypto_type = type ;
} else {
tech_pvt - > crypto_type = AES_CM_128_NULL_AUTH ;
}
2008-01-16 06:01:53 +00:00
return SWITCH_STATUS_SUCCESS ;
}
switch_status_t sofia_glue_add_crypto ( private_object_t * tech_pvt , const char * key_str , switch_rtp_crypto_direction_t direction )
{
unsigned char key [ SWITCH_RTP_MAX_CRYPTO_LEN ] ;
switch_rtp_crypto_key_type_t type ;
char * p ;
if ( ! switch_rtp_ready ( tech_pvt - > rtp_session ) ) {
goto bad ;
}
2008-05-27 04:54:52 +00:00
2008-01-16 06:01:53 +00:00
p = strchr ( key_str , ' ' ) ;
2008-05-27 04:54:52 +00:00
if ( p & & * p & & * ( p + 1 ) ) {
2008-01-16 06:01:53 +00:00
p + + ;
if ( ! strncasecmp ( p , SWITCH_RTP_CRYPTO_KEY_32 , strlen ( SWITCH_RTP_CRYPTO_KEY_32 ) ) ) {
type = AES_CM_128_HMAC_SHA1_32 ;
} else if ( ! strncasecmp ( p , SWITCH_RTP_CRYPTO_KEY_80 , strlen ( SWITCH_RTP_CRYPTO_KEY_80 ) ) ) {
type = AES_CM_128_HMAC_SHA1_80 ;
} else {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_ERROR , " Parse Error near [%s] \n " , p ) ;
2008-01-16 06:01:53 +00:00
goto bad ;
}
p = strchr ( p , ' ' ) ;
2008-05-27 04:54:52 +00:00
if ( p & & * p & & * ( p + 1 ) ) {
2008-01-16 06:01:53 +00:00
p + + ;
if ( strncasecmp ( p , " inline: " , 7 ) ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_ERROR , " Parse Error near [%s] \n " , p ) ;
2008-01-16 06:01:53 +00:00
goto bad ;
}
p + = 7 ;
2008-05-27 04:54:52 +00:00
switch_b64_decode ( p , ( char * ) key , sizeof ( key ) ) ;
2008-01-16 06:01:53 +00:00
if ( direction = = SWITCH_RTP_CRYPTO_SEND ) {
tech_pvt - > crypto_send_type = type ;
memcpy ( tech_pvt - > local_raw_key , key , SWITCH_RTP_KEY_LEN ) ;
} else {
tech_pvt - > crypto_recv_type = type ;
memcpy ( tech_pvt - > remote_raw_key , key , SWITCH_RTP_KEY_LEN ) ;
}
return SWITCH_STATUS_SUCCESS ;
}
}
2008-05-27 04:54:52 +00:00
2010-06-23 13:22:52 -05:00
bad :
2008-01-16 06:01:53 +00:00
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_ERROR , " Error! \n " ) ;
2008-01-16 06:01:53 +00:00
return SWITCH_STATUS_FALSE ;
}
2007-10-25 18:36:40 +00:00
switch_status_t sofia_glue_activate_rtp ( private_object_t * tech_pvt , switch_rtp_flag_t myflags )
2007-03-31 19:01:33 +00:00
{
const char * err = NULL ;
2007-11-01 11:28:26 +00:00
const char * val = NULL ;
2007-03-31 19:01:33 +00:00
switch_rtp_flag_t flags ;
switch_status_t status ;
char tmp [ 50 ] ;
2007-10-31 02:12:30 +00:00
uint32_t rtp_timeout_sec = tech_pvt - > profile - > rtp_timeout_sec ;
2008-01-21 00:35:33 +00:00
uint32_t rtp_hold_timeout_sec = tech_pvt - > profile - > rtp_hold_timeout_sec ;
2008-09-05 20:34:18 +00:00
char * timer_name = NULL ;
2008-03-04 00:52:54 +00:00
const char * var ;
2007-03-31 19:01:33 +00:00
2008-02-21 17:48:41 +00:00
switch_assert ( tech_pvt ! = NULL ) ;
2009-03-20 01:52:53 +00:00
if ( switch_channel_down ( tech_pvt - > channel ) | | sofia_test_flag ( tech_pvt , TFLAG_BYE ) ) {
return SWITCH_STATUS_FALSE ;
}
2008-10-30 22:40:39 +00:00
switch_mutex_lock ( tech_pvt - > sofia_mutex ) ;
2008-03-04 00:52:54 +00:00
2009-01-13 19:02:48 +00:00
if ( switch_rtp_ready ( tech_pvt - > rtp_session ) ) {
switch_rtp_reset_media_timer ( tech_pvt - > rtp_session ) ;
}
2008-03-04 00:52:54 +00:00
if ( ( var = switch_channel_get_variable ( tech_pvt - > channel , SOFIA_SECURE_MEDIA_VARIABLE ) ) & & switch_true ( var ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_flag_locked ( tech_pvt , TFLAG_SECURE ) ;
2008-03-04 00:52:54 +00:00
}
2011-06-23 17:57:10 -05:00
if ( ( var = switch_channel_get_variable ( tech_pvt - > channel , " sip_liberal_dtmf " ) ) & & switch_true ( var ) ) {
sofia_set_flag_locked ( tech_pvt , TFLAG_LIBERAL_DTMF ) ;
}
2008-02-21 17:48:41 +00:00
if ( switch_channel_test_flag ( tech_pvt - > channel , CF_PROXY_MODE ) ) {
2008-02-25 16:35:19 +00:00
status = SWITCH_STATUS_SUCCESS ;
goto end ;
2007-03-31 19:01:33 +00:00
}
2009-02-09 17:56:38 +00:00
if ( switch_rtp_ready ( tech_pvt - > rtp_session ) & & ! sofia_test_flag ( tech_pvt , TFLAG_REINVITE ) ) {
2008-02-25 16:35:19 +00:00
status = SWITCH_STATUS_SUCCESS ;
goto end ;
2007-03-31 19:01:33 +00:00
}
if ( ( status = sofia_glue_tech_set_codec ( tech_pvt , 0 ) ) ! = SWITCH_STATUS_SUCCESS ) {
2008-02-25 16:35:19 +00:00
goto end ;
2007-03-31 19:01:33 +00:00
}
2008-05-27 04:54:52 +00:00
if ( myflags ) {
2007-10-25 18:36:40 +00:00
flags = myflags ;
2008-07-07 17:56:16 +00:00
} else if ( ! sofia_test_pflag ( tech_pvt - > profile , PFLAG_DISABLE_RTP_AUTOADJ ) & &
2010-02-06 03:38:24 +00:00
! ( ( val = switch_channel_get_variable ( tech_pvt - > channel , " disable_rtp_auto_adjust " ) ) & & switch_true ( val ) ) ) {
2007-10-25 18:36:40 +00:00
flags = ( switch_rtp_flag_t ) ( SWITCH_RTP_FLAG_AUTOADJ | SWITCH_RTP_FLAG_DATAWAIT ) ;
2010-02-06 03:38:24 +00:00
} else {
2008-07-07 17:56:16 +00:00
flags = ( switch_rtp_flag_t ) ( SWITCH_RTP_FLAG_DATAWAIT ) ;
2007-10-25 18:36:40 +00:00
}
2007-03-31 19:01:33 +00:00
2009-02-09 17:56:38 +00:00
if ( sofia_test_pflag ( tech_pvt - > profile , PFLAG_PASS_RFC2833 )
2007-05-09 19:30:41 +00:00
| | ( ( val = switch_channel_get_variable ( tech_pvt - > channel , " pass_rfc2833 " ) ) & & switch_true ( val ) ) ) {
2009-04-23 13:15:03 +00:00
sofia_set_flag ( tech_pvt , TFLAG_PASS_RFC2833 ) ;
2007-03-31 19:01:33 +00:00
}
2009-03-31 19:10:43 +00:00
if ( sofia_test_pflag ( tech_pvt - > profile , PFLAG_AUTOFLUSH )
| | ( ( val = switch_channel_get_variable ( tech_pvt - > channel , " rtp_autoflush " ) ) & & switch_true ( val ) ) ) {
flags | = SWITCH_RTP_FLAG_AUTOFLUSH ;
}
2009-02-09 17:56:38 +00:00
if ( ! ( sofia_test_pflag ( tech_pvt - > profile , PFLAG_REWRITE_TIMESTAMPS ) | |
2011-09-01 12:25:08 -05:00
( ( val = switch_channel_get_variable ( tech_pvt - > channel , " rtp_rewrite_timestamps " ) ) & & switch_true ( val ) ) ) ) {
2007-04-05 19:29:48 +00:00
flags | = SWITCH_RTP_FLAG_RAW_WRITE ;
}
2009-02-09 17:56:38 +00:00
if ( sofia_test_pflag ( tech_pvt - > profile , PFLAG_SUPPRESS_CNG ) ) {
2008-09-23 13:54:06 +00:00
tech_pvt - > cng_pt = 0 ;
} else if ( tech_pvt - > cng_pt ) {
2007-03-31 19:01:33 +00:00
flags | = SWITCH_RTP_FLAG_AUTO_CNG ;
}
2008-05-27 04:54:52 +00:00
2011-03-21 14:31:10 -05:00
# if __BYTE_ORDER == __LITTLE_ENDIAN
if ( ! strcasecmp ( tech_pvt - > read_impl . iananame , " L16 " ) ) {
flags | = SWITCH_RTP_FLAG_BYTESWAP ;
}
# endif
if ( ( flags & SWITCH_RTP_FLAG_BYTESWAP ) & & ( val = switch_channel_get_variable ( tech_pvt - > channel , " rtp_disable_byteswap " ) ) & & switch_true ( val ) ) {
flags & = ~ SWITCH_RTP_FLAG_BYTESWAP ;
}
2009-02-09 17:56:38 +00:00
if ( tech_pvt - > rtp_session & & sofia_test_flag ( tech_pvt , TFLAG_REINVITE ) ) {
2008-09-18 21:50:18 +00:00
//const char *ip = switch_channel_get_variable(tech_pvt->channel, SWITCH_LOCAL_MEDIA_IP_VARIABLE);
//const char *port = switch_channel_get_variable(tech_pvt->channel, SWITCH_LOCAL_MEDIA_PORT_VARIABLE);
char * remote_host = switch_rtp_get_remote_host ( tech_pvt - > rtp_session ) ;
switch_port_t remote_port = switch_rtp_get_remote_port ( tech_pvt - > rtp_session ) ;
2009-10-21 23:01:37 +00:00
2008-09-18 21:50:18 +00:00
if ( remote_host & & remote_port & & ! strcmp ( remote_host , tech_pvt - > remote_sdp_audio_ip ) & & remote_port = = tech_pvt - > remote_sdp_audio_port ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_DEBUG , " Audio params are unchanged for %s. \n " ,
switch_channel_get_name ( tech_pvt - > channel ) ) ;
2011-05-20 12:49:16 -05:00
if ( switch_rtp_ready ( tech_pvt - > rtp_session ) ) {
if ( tech_pvt - > audio_recv_pt ! = tech_pvt - > agreed_pt ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_DEBUG ,
" %s Set audio receive payload in Re-INVITE for non-matching dynamic PT to %u \n " ,
switch_channel_get_name ( tech_pvt - > channel ) , tech_pvt - > audio_recv_pt ) ;
switch_rtp_set_recv_pt ( tech_pvt - > rtp_session , tech_pvt - > audio_recv_pt ) ;
} else {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_DEBUG ,
" %s Setting audio receive payload in Re-INVITE to %u \n " ,
switch_channel_get_name ( tech_pvt - > channel ) , tech_pvt - > audio_recv_pt ) ;
switch_rtp_set_recv_pt ( tech_pvt - > rtp_session , tech_pvt - > agreed_pt ) ;
}
}
2008-05-14 14:13:40 +00:00
goto video ;
2008-09-18 21:50:18 +00:00
} else {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_DEBUG , " Audio params changed for %s from %s:%d to %s:%d \n " ,
2008-09-18 21:50:18 +00:00
switch_channel_get_name ( tech_pvt - > channel ) ,
remote_host , remote_port , tech_pvt - > remote_sdp_audio_ip , tech_pvt - > remote_sdp_audio_port ) ;
2009-11-25 23:09:23 +00:00
switch_snprintf ( tmp , sizeof ( tmp ) , " %d " , tech_pvt - > remote_sdp_audio_port ) ;
switch_channel_set_variable ( tech_pvt - > channel , SWITCH_REMOTE_MEDIA_IP_VARIABLE , tech_pvt - > remote_sdp_audio_ip ) ;
switch_channel_set_variable ( tech_pvt - > channel , SWITCH_REMOTE_MEDIA_PORT_VARIABLE , tmp ) ;
2008-05-14 14:13:40 +00:00
}
}
2007-03-31 19:01:33 +00:00
2008-05-23 19:41:23 +00:00
if ( ! switch_channel_test_flag ( tech_pvt - > channel , CF_PROXY_MEDIA ) ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_DEBUG , " AUDIO RTP [%s] %s port %d -> %s port %d codec: %u ms: %d \n " ,
2008-05-23 19:41:23 +00:00
switch_channel_get_name ( tech_pvt - > channel ) ,
tech_pvt - > local_sdp_audio_ip ,
tech_pvt - > local_sdp_audio_port ,
tech_pvt - > remote_sdp_audio_ip ,
2009-01-12 18:37:44 +00:00
tech_pvt - > remote_sdp_audio_port , tech_pvt - > agreed_pt , tech_pvt - > read_impl . microseconds_per_packet / 1000 ) ;
2010-09-29 14:14:41 -05:00
if ( switch_rtp_ready ( tech_pvt - > rtp_session ) ) {
switch_rtp_set_default_payload ( tech_pvt - > rtp_session , tech_pvt - > agreed_pt ) ;
2011-03-07 12:15:46 -06:00
if ( tech_pvt - > audio_recv_pt ! = tech_pvt - > agreed_pt ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_DEBUG ,
" %s Set audio receive payload to %u \n " , switch_channel_get_name ( tech_pvt - > channel ) , tech_pvt - > audio_recv_pt ) ;
switch_rtp_set_recv_pt ( tech_pvt - > rtp_session , tech_pvt - > audio_recv_pt ) ;
} else {
switch_rtp_set_recv_pt ( tech_pvt - > rtp_session , tech_pvt - > agreed_pt ) ;
}
2010-09-29 14:14:41 -05:00
}
2008-05-23 19:41:23 +00:00
}
2007-03-31 19:01:33 +00:00
2008-12-03 20:10:54 +00:00
switch_snprintf ( tmp , sizeof ( tmp ) , " %d " , tech_pvt - > local_sdp_audio_port ) ;
2011-09-09 02:47:56 -05:00
switch_channel_set_variable ( tech_pvt - > channel , SWITCH_LOCAL_MEDIA_IP_VARIABLE , tech_pvt - > local_sdp_audio_ip ) ;
2007-05-09 19:30:41 +00:00
switch_channel_set_variable ( tech_pvt - > channel , SWITCH_LOCAL_MEDIA_PORT_VARIABLE , tmp ) ;
2011-09-09 02:47:56 -05:00
switch_channel_set_variable ( tech_pvt - > channel , SWITCH_ADVERTISED_MEDIA_IP_VARIABLE , tech_pvt - > adv_sdp_audio_ip ) ;
2007-03-31 19:01:33 +00:00
2009-02-09 17:56:38 +00:00
if ( tech_pvt - > rtp_session & & sofia_test_flag ( tech_pvt , TFLAG_REINVITE ) ) {
2010-04-22 10:22:28 -05:00
const char * rport = NULL ;
2010-06-23 13:22:52 -05:00
switch_port_t remote_rtcp_port = 0 ;
2010-04-22 10:22:28 -05:00
2011-08-01 20:08:04 -05:00
2010-02-06 03:38:24 +00:00
2010-04-22 10:22:28 -05:00
if ( ( rport = switch_channel_get_variable ( tech_pvt - > channel , " sip_remote_audio_rtcp_port " ) ) ) {
2010-09-29 15:47:58 -05:00
remote_rtcp_port = ( switch_port_t ) atoi ( rport ) ;
2010-04-22 10:22:28 -05:00
}
2010-06-23 13:22:52 -05:00
if ( switch_rtp_set_remote_address ( tech_pvt - > rtp_session , tech_pvt - > remote_sdp_audio_ip , tech_pvt - > remote_sdp_audio_port ,
remote_rtcp_port , SWITCH_TRUE , & err ) ! = SWITCH_STATUS_SUCCESS ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_ERROR , " AUDIO RTP REPORTS ERROR: [%s] \n " , err ) ;
2007-03-31 19:01:33 +00:00
} else {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_DEBUG , " AUDIO RTP CHANGING DEST TO: [%s:%d] \n " ,
2007-03-31 19:01:33 +00:00
tech_pvt - > remote_sdp_audio_ip , tech_pvt - > remote_sdp_audio_port ) ;
2008-07-07 17:56:16 +00:00
if ( ! sofia_test_pflag ( tech_pvt - > profile , PFLAG_DISABLE_RTP_AUTOADJ ) & &
! ( ( val = switch_channel_get_variable ( tech_pvt - > channel , " disable_rtp_auto_adjust " ) ) & & switch_true ( val ) ) ) {
/* Reactivate the NAT buster flag. */
switch_rtp_set_flag ( tech_pvt - > rtp_session , SWITCH_RTP_FLAG_AUTOADJ ) ;
}
2007-03-31 19:01:33 +00:00
}
2008-05-27 04:54:52 +00:00
goto video ;
2007-03-31 19:01:33 +00:00
}
2008-05-27 04:54:52 +00:00
2008-02-21 17:48:41 +00:00
if ( switch_channel_test_flag ( tech_pvt - > channel , CF_PROXY_MEDIA ) ) {
if ( ( status = sofia_glue_tech_proxy_remote_addr ( tech_pvt ) ) ! = SWITCH_STATUS_SUCCESS ) {
2008-02-25 16:35:19 +00:00
goto end ;
2008-02-21 17:48:41 +00:00
}
2009-03-20 01:52:53 +00:00
2008-07-07 17:56:16 +00:00
if ( ! sofia_test_pflag ( tech_pvt - > profile , PFLAG_DISABLE_RTP_AUTOADJ ) & &
! ( ( val = switch_channel_get_variable ( tech_pvt - > channel , " disable_rtp_auto_adjust " ) ) & & switch_true ( val ) ) ) {
flags = ( switch_rtp_flag_t ) ( SWITCH_RTP_FLAG_PROXY_MEDIA | SWITCH_RTP_FLAG_AUTOADJ | SWITCH_RTP_FLAG_DATAWAIT ) ;
} else {
flags = ( switch_rtp_flag_t ) ( SWITCH_RTP_FLAG_PROXY_MEDIA | SWITCH_RTP_FLAG_DATAWAIT ) ;
}
2008-02-21 17:48:41 +00:00
timer_name = NULL ;
2008-05-23 19:41:23 +00:00
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_DEBUG ,
2009-03-20 01:52:53 +00:00
" PROXY AUDIO RTP [%s] %s:%d->%s:%d codec: %u ms: %d \n " ,
2008-05-23 19:41:23 +00:00
switch_channel_get_name ( tech_pvt - > channel ) ,
tech_pvt - > local_sdp_audio_ip ,
tech_pvt - > local_sdp_audio_port ,
tech_pvt - > remote_sdp_audio_ip ,
2009-01-12 18:37:44 +00:00
tech_pvt - > remote_sdp_audio_port , tech_pvt - > agreed_pt , tech_pvt - > read_impl . microseconds_per_packet / 1000 ) ;
2008-05-23 19:41:23 +00:00
2010-09-29 14:14:41 -05:00
if ( switch_rtp_ready ( tech_pvt - > rtp_session ) ) {
switch_rtp_set_default_payload ( tech_pvt - > rtp_session , tech_pvt - > agreed_pt ) ;
}
2008-02-21 17:48:41 +00:00
} else {
timer_name = tech_pvt - > profile - > timer_name ;
2009-03-20 01:52:53 +00:00
if ( ( var = switch_channel_get_variable ( tech_pvt - > channel , " rtp_timer_name " ) ) ) {
timer_name = ( char * ) var ;
}
2008-09-05 20:34:18 +00:00
}
2009-03-20 01:52:53 +00:00
if ( switch_channel_up ( tech_pvt - > channel ) & & ! sofia_test_flag ( tech_pvt , TFLAG_BYE ) ) {
tech_pvt - > rtp_session = switch_rtp_new ( tech_pvt - > local_sdp_audio_ip ,
tech_pvt - > local_sdp_audio_port ,
tech_pvt - > remote_sdp_audio_ip ,
tech_pvt - > remote_sdp_audio_port ,
tech_pvt - > agreed_pt ,
tech_pvt - > read_impl . samples_per_packet ,
tech_pvt - > codec_ms * 1000 ,
2010-02-06 03:38:24 +00:00
( switch_rtp_flag_t ) flags , timer_name , & err , switch_core_session_get_pool ( tech_pvt - > session ) ) ;
2009-03-20 01:52:53 +00:00
}
2008-05-27 04:54:52 +00:00
2007-03-31 19:01:33 +00:00
if ( switch_rtp_ready ( tech_pvt - > rtp_session ) ) {
2009-02-09 17:56:38 +00:00
uint8_t vad_in = sofia_test_flag ( tech_pvt , TFLAG_VAD_IN ) ? 1 : 0 ;
uint8_t vad_out = sofia_test_flag ( tech_pvt , TFLAG_VAD_OUT ) ? 1 : 0 ;
uint8_t inb = sofia_test_flag ( tech_pvt , TFLAG_OUTBOUND ) ? 0 : 1 ;
2008-07-18 16:18:31 +00:00
uint32_t stun_ping = 0 ;
2010-02-06 03:38:24 +00:00
const char * ssrc ;
if ( ( ssrc = switch_channel_get_variable ( tech_pvt - > channel , " rtp_use_ssrc " ) ) ) {
uint32_t ssrc_ul = ( uint32_t ) strtoul ( ssrc , NULL , 10 ) ;
switch_rtp_set_ssrc ( tech_pvt - > rtp_session , ssrc_ul ) ;
}
2009-04-23 13:15:03 +00:00
switch_channel_set_flag ( tech_pvt - > channel , CF_FS_RTP ) ;
2010-02-06 03:38:24 +00:00
switch_channel_set_variable_printf ( tech_pvt - > channel , " sip_use_pt " , " %d " , tech_pvt - > agreed_pt ) ;
2007-06-14 21:03:17 +00:00
if ( ( val = switch_channel_get_variable ( tech_pvt - > channel , " rtp_enable_vad_in " ) ) & & switch_true ( val ) ) {
vad_in = 1 ;
}
if ( ( val = switch_channel_get_variable ( tech_pvt - > channel , " rtp_enable_vad_out " ) ) & & switch_true ( val ) ) {
vad_out = 1 ;
}
if ( ( val = switch_channel_get_variable ( tech_pvt - > channel , " rtp_disable_vad_in " ) ) & & switch_true ( val ) ) {
vad_in = 0 ;
}
if ( ( val = switch_channel_get_variable ( tech_pvt - > channel , " rtp_disable_vad_out " ) ) & & switch_true ( val ) ) {
vad_out = 0 ;
}
2008-07-18 16:18:31 +00:00
if ( ( tech_pvt - > stun_flags & STUN_FLAG_SET ) & & ( val = switch_channel_get_variable ( tech_pvt - > channel , " rtp_stun_ping " ) ) ) {
int ival = atoi ( val ) ;
2010-02-06 03:38:24 +00:00
2008-07-18 16:18:31 +00:00
if ( ival < = 0 ) {
if ( switch_true ( val ) ) {
ival = 6 ;
}
}
2009-01-12 18:37:44 +00:00
stun_ping = ( ival * tech_pvt - > read_impl . samples_per_second ) / tech_pvt - > read_impl . samples_per_packet ;
2008-07-18 16:18:31 +00:00
}
2007-03-31 19:01:33 +00:00
tech_pvt - > ssrc = switch_rtp_get_ssrc ( tech_pvt - > rtp_session ) ;
2010-02-06 03:38:24 +00:00
switch_channel_set_variable_printf ( tech_pvt - > channel , " rtp_use_ssrc " , " %u " , tech_pvt - > ssrc ) ;
2009-02-09 17:56:38 +00:00
sofia_set_flag ( tech_pvt , TFLAG_RTP ) ;
sofia_set_flag ( tech_pvt , TFLAG_IO ) ;
2010-02-06 03:38:24 +00:00
2010-06-07 15:28:32 -05:00
if ( tech_pvt - > profile - > auto_rtp_bugs & RTP_BUG_IGNORE_MARK_BIT ) {
tech_pvt - > rtp_bugs | = RTP_BUG_IGNORE_MARK_BIT ;
}
2010-06-23 13:22:52 -05:00
2010-11-10 16:55:56 -06:00
if ( ( val = switch_channel_get_variable ( tech_pvt - > channel , " rtp_manual_rtp_bugs " ) ) ) {
sofia_glue_parse_rtp_bugs ( & tech_pvt - > rtp_bugs , val ) ;
}
switch_rtp_intentional_bugs ( tech_pvt - > rtp_session , tech_pvt - > rtp_bugs | tech_pvt - > profile - > manual_rtp_bugs ) ;
2010-02-06 03:38:24 +00:00
2007-03-31 19:01:33 +00:00
if ( ( vad_in & & inb ) | | ( vad_out & & ! inb ) ) {
switch_rtp_enable_vad ( tech_pvt - > rtp_session , tech_pvt - > session , & tech_pvt - > read_codec , SWITCH_VAD_FLAG_TALKING ) ;
2009-02-09 17:56:38 +00:00
sofia_set_flag ( tech_pvt , TFLAG_VAD ) ;
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_DEBUG , " AUDIO RTP Engage VAD for %s ( %s %s ) \n " ,
2007-03-31 19:01:33 +00:00
switch_channel_get_name ( switch_core_session_get_channel ( tech_pvt - > session ) ) , vad_in ? " in " : " " , vad_out ? " out " : " " ) ;
}
2008-07-18 16:18:31 +00:00
if ( stun_ping ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_DEBUG , " Setting stun ping to %s:%d \n " , tech_pvt - > stun_ip ,
stun_ping ) ;
switch_rtp_activate_stun_ping ( tech_pvt - > rtp_session , tech_pvt - > stun_ip , tech_pvt - > stun_port , stun_ping ,
( tech_pvt - > stun_flags & STUN_FLAG_FUNNY ) ? 1 : 0 ) ;
2008-07-18 16:18:31 +00:00
}
2010-06-23 13:22:52 -05:00
2010-04-20 16:15:37 -05:00
if ( ( val = switch_channel_get_variable ( tech_pvt - > channel , " rtcp_audio_interval_msec " ) ) | | ( val = tech_pvt - > profile - > rtcp_audio_interval_msec ) ) {
const char * rport = switch_channel_get_variable ( tech_pvt - > channel , " sip_remote_audio_rtcp_port " ) ;
switch_port_t remote_port = 0 ;
if ( rport ) {
2010-09-29 15:47:58 -05:00
remote_port = ( switch_port_t ) atoi ( rport ) ;
2010-04-20 16:15:37 -05:00
}
if ( ! strcasecmp ( val , " passthru " ) ) {
switch_rtp_activate_rtcp ( tech_pvt - > rtp_session , - 1 , remote_port ) ;
2010-04-19 19:07:23 -05:00
} else {
2010-04-20 16:15:37 -05:00
int interval = atoi ( val ) ;
if ( interval < 100 | | interval > 5000 ) {
2010-06-23 13:22:52 -05:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_ERROR ,
" Invalid rtcp interval spec [%d] must be between 100 and 5000 \n " , interval ) ;
2010-04-20 16:15:37 -05:00
} else {
switch_rtp_activate_rtcp ( tech_pvt - > rtp_session , interval , remote_port ) ;
}
2010-04-19 19:07:23 -05:00
}
}
2008-07-18 16:18:31 +00:00
2011-01-05 16:25:07 -06:00
if ( ( val = switch_channel_get_variable ( tech_pvt - > channel , " jitterbuffer_msec " ) ) | | ( val = tech_pvt - > profile - > jb_msec ) ) {
int jb_msec = atoi ( val ) ;
2011-03-10 15:32:09 -06:00
int maxlen = 0 , max_drift = 0 ;
2011-02-25 11:59:45 -06:00
char * p , * q ;
2010-12-10 17:47:24 -06:00
if ( ( p = strchr ( val , ' : ' ) ) ) {
p + + ;
2010-12-14 00:15:36 -06:00
maxlen = atoi ( p ) ;
2011-02-25 11:59:45 -06:00
if ( ( q = strchr ( p , ' : ' ) ) ) {
q + + ;
max_drift = abs ( atoi ( q ) ) ;
}
2010-12-10 17:47:24 -06:00
}
2011-01-05 16:25:07 -06:00
if ( jb_msec < 20 | | jb_msec > 10000 ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_ERROR ,
2011-01-05 16:25:07 -06:00
" Invalid Jitterbuffer spec [%d] must be between 20 and 10000 \n " , jb_msec ) ;
2007-05-04 23:29:35 +00:00
} else {
2010-12-14 00:15:36 -06:00
int qlen , maxqlen = 50 ;
2010-12-10 17:47:24 -06:00
2011-01-05 16:25:07 -06:00
qlen = jb_msec / ( tech_pvt - > read_impl . microseconds_per_packet / 1000 ) ;
2008-05-27 04:54:52 +00:00
2011-03-17 22:29:16 -05:00
if ( qlen < 1 ) {
qlen = 3 ;
}
2010-12-10 17:47:24 -06:00
if ( maxlen ) {
maxqlen = maxlen / ( tech_pvt - > read_impl . microseconds_per_packet / 1000 ) ;
}
2011-03-17 22:29:16 -05:00
if ( maxqlen < qlen ) {
maxqlen = qlen * 5 ;
}
2010-12-10 17:47:24 -06:00
if ( switch_rtp_activate_jitter_buffer ( tech_pvt - > rtp_session , qlen , maxqlen ,
tech_pvt - > read_impl . samples_per_packet ,
2011-02-25 11:59:45 -06:00
tech_pvt - > read_impl . samples_per_second , max_drift ) = = SWITCH_STATUS_SUCCESS ) {
2010-12-10 17:47:24 -06:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) ,
2011-01-05 16:25:07 -06:00
SWITCH_LOG_DEBUG , " Setting Jitterbuffer to %dms (%d frames) \n " , jb_msec , qlen ) ;
2010-12-10 17:47:24 -06:00
switch_channel_set_flag ( tech_pvt - > channel , CF_JITTERBUFFER ) ;
} else {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) ,
2011-01-05 16:25:07 -06:00
SWITCH_LOG_WARNING , " Error Setting Jitterbuffer to %dms (%d frames) \n " , jb_msec , qlen ) ;
2010-12-10 17:47:24 -06:00
}
2007-05-04 23:29:35 +00:00
}
}
2007-10-31 02:12:30 +00:00
if ( ( val = switch_channel_get_variable ( tech_pvt - > channel , " rtp_timeout_sec " ) ) ) {
int v = atoi ( val ) ;
if ( v > = 0 ) {
rtp_timeout_sec = v ;
}
}
2008-01-21 00:35:33 +00:00
if ( ( val = switch_channel_get_variable ( tech_pvt - > channel , " rtp_hold_timeout_sec " ) ) ) {
int v = atoi ( val ) ;
if ( v > = 0 ) {
rtp_hold_timeout_sec = v ;
}
}
2008-05-27 04:54:52 +00:00
2007-10-31 02:12:30 +00:00
if ( rtp_timeout_sec ) {
2010-02-06 03:38:24 +00:00
tech_pvt - > max_missed_packets = ( tech_pvt - > read_impl . samples_per_second * rtp_timeout_sec ) / tech_pvt - > read_impl . samples_per_packet ;
2008-05-27 04:54:52 +00:00
2007-10-31 17:30:50 +00:00
switch_rtp_set_max_missed_packets ( tech_pvt - > rtp_session , tech_pvt - > max_missed_packets ) ;
2008-01-21 00:35:33 +00:00
if ( ! rtp_hold_timeout_sec ) {
rtp_hold_timeout_sec = rtp_timeout_sec * 10 ;
}
}
if ( rtp_hold_timeout_sec ) {
2010-02-06 03:38:24 +00:00
tech_pvt - > max_missed_hold_packets = ( tech_pvt - > read_impl . samples_per_second * rtp_hold_timeout_sec ) / tech_pvt - > read_impl . samples_per_packet ;
2007-10-31 02:12:30 +00:00
}
2007-05-04 23:29:35 +00:00
2007-03-31 19:01:33 +00:00
if ( tech_pvt - > te ) {
2010-03-25 03:51:04 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_DEBUG , " Set 2833 dtmf send payload to %u \n " , tech_pvt - > te ) ;
2007-03-31 19:01:33 +00:00
switch_rtp_set_telephony_event ( tech_pvt - > rtp_session , tech_pvt - > te ) ;
2011-09-16 14:30:32 -05:00
switch_channel_set_variable_printf ( tech_pvt - > channel , " sip_2833_send_payload " , " %d " , tech_pvt - > te ) ;
2010-03-25 03:51:04 +00:00
}
if ( tech_pvt - > recv_te ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_DEBUG , " Set 2833 dtmf receive payload to %u \n " , tech_pvt - > recv_te ) ;
switch_rtp_set_telephony_recv_event ( tech_pvt - > rtp_session , tech_pvt - > recv_te ) ;
2011-09-16 14:30:32 -05:00
switch_channel_set_variable_printf ( tech_pvt - > channel , " sip_2833_recv_payload " , " %d " , tech_pvt - > recv_te ) ;
2007-03-31 19:01:33 +00:00
}
2008-09-25 17:39:08 +00:00
2011-02-15 16:09:48 -06:00
if ( tech_pvt - > audio_recv_pt ! = tech_pvt - > agreed_pt ) {
2011-02-25 15:20:04 -06:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_DEBUG ,
" %s Set audio receive payload to %u \n " , switch_channel_get_name ( tech_pvt - > channel ) , tech_pvt - > audio_recv_pt ) ;
2011-02-15 16:09:48 -06:00
switch_rtp_set_recv_pt ( tech_pvt - > rtp_session , tech_pvt - > audio_recv_pt ) ;
}
2008-09-25 17:39:08 +00:00
if ( sofia_test_pflag ( tech_pvt - > profile , PFLAG_SUPPRESS_CNG ) | |
( ( val = switch_channel_get_variable ( tech_pvt - > channel , " supress_cng " ) ) & & switch_true ( val ) ) | |
( ( val = switch_channel_get_variable ( tech_pvt - > channel , " suppress_cng " ) ) & & switch_true ( val ) ) ) {
tech_pvt - > cng_pt = 0 ;
}
2009-02-09 17:56:38 +00:00
if ( tech_pvt - > cng_pt & & ! sofia_test_pflag ( tech_pvt - > profile , PFLAG_SUPPRESS_CNG ) ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_DEBUG , " Set comfort noise payload to %u \n " , tech_pvt - > cng_pt ) ;
2007-03-31 19:01:33 +00:00
switch_rtp_set_cng_pt ( tech_pvt - > rtp_session , tech_pvt - > cng_pt ) ;
}
2008-05-27 04:54:52 +00:00
2009-02-09 17:56:38 +00:00
if ( tech_pvt - > remote_crypto_key & & sofia_test_flag ( tech_pvt , TFLAG_SECURE ) ) {
2008-01-16 06:01:53 +00:00
sofia_glue_add_crypto ( tech_pvt , tech_pvt - > remote_crypto_key , SWITCH_RTP_CRYPTO_RECV ) ;
2008-05-27 04:54:52 +00:00
switch_rtp_add_crypto_key ( tech_pvt - > rtp_session , SWITCH_RTP_CRYPTO_SEND , 1 , tech_pvt - > crypto_type , tech_pvt - > local_raw_key ,
SWITCH_RTP_KEY_LEN ) ;
switch_rtp_add_crypto_key ( tech_pvt - > rtp_session , SWITCH_RTP_CRYPTO_RECV , tech_pvt - > crypto_tag , tech_pvt - > crypto_type , tech_pvt - > remote_raw_key ,
SWITCH_RTP_KEY_LEN ) ;
2008-01-16 06:01:53 +00:00
switch_channel_set_variable ( tech_pvt - > channel , SOFIA_SECURE_MEDIA_CONFIRMED_VARIABLE , " true " ) ;
}
2009-11-25 23:09:23 +00:00
switch_snprintf ( tmp , sizeof ( tmp ) , " %d " , tech_pvt - > remote_sdp_audio_port ) ;
switch_channel_set_variable ( tech_pvt - > channel , SWITCH_REMOTE_MEDIA_IP_VARIABLE , tech_pvt - > remote_sdp_audio_ip ) ;
switch_channel_set_variable ( tech_pvt - > channel , SWITCH_REMOTE_MEDIA_PORT_VARIABLE , tmp ) ;
2010-06-23 13:22:52 -05:00
video :
2008-01-16 06:01:53 +00:00
2007-04-19 21:40:50 +00:00
sofia_glue_check_video_codecs ( tech_pvt ) ;
2009-11-20 02:17:08 +00:00
if ( sofia_test_flag ( tech_pvt , TFLAG_VIDEO ) & & tech_pvt - > video_rm_encoding & & tech_pvt - > remote_sdp_video_port ) {
2010-09-29 14:14:41 -05:00
2009-11-20 02:17:08 +00:00
/******************************************************************************************/
if ( tech_pvt - > video_rtp_session & & sofia_test_flag ( tech_pvt , TFLAG_REINVITE ) ) {
//const char *ip = switch_channel_get_variable(tech_pvt->channel, SWITCH_LOCAL_MEDIA_IP_VARIABLE);
//const char *port = switch_channel_get_variable(tech_pvt->channel, SWITCH_LOCAL_MEDIA_PORT_VARIABLE);
char * remote_host = switch_rtp_get_remote_host ( tech_pvt - > video_rtp_session ) ;
switch_port_t remote_port = switch_rtp_get_remote_port ( tech_pvt - > video_rtp_session ) ;
2010-09-29 14:14:41 -05:00
2009-11-20 02:17:08 +00:00
if ( remote_host & & remote_port & & ! strcmp ( remote_host , tech_pvt - > remote_sdp_video_ip ) & & remote_port = = tech_pvt - > remote_sdp_video_port ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_DEBUG , " Video params are unchanged for %s. \n " ,
switch_channel_get_name ( tech_pvt - > channel ) ) ;
2009-11-20 02:17:08 +00:00
goto video_up ;
} else {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_DEBUG , " Video params changed for %s from %s:%d to %s:%d \n " ,
2009-11-20 02:17:08 +00:00
switch_channel_get_name ( tech_pvt - > channel ) ,
remote_host , remote_port , tech_pvt - > remote_sdp_video_ip , tech_pvt - > remote_sdp_video_port ) ;
}
}
2007-04-19 21:40:50 +00:00
2009-11-20 02:17:08 +00:00
if ( ! switch_channel_test_flag ( tech_pvt - > channel , CF_PROXY_MEDIA ) ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_DEBUG ,
" VIDEO RTP [%s] %s port %d -> %s port %d codec: %u ms: %d \n " , switch_channel_get_name ( tech_pvt - > channel ) ,
tech_pvt - > local_sdp_audio_ip , tech_pvt - > local_sdp_video_port , tech_pvt - > remote_sdp_video_ip ,
2009-11-20 02:17:08 +00:00
tech_pvt - > remote_sdp_video_port , tech_pvt - > video_agreed_pt , tech_pvt - > read_impl . microseconds_per_packet / 1000 ) ;
2009-11-18 19:22:45 +00:00
2010-09-29 14:14:41 -05:00
if ( switch_rtp_ready ( tech_pvt - > video_rtp_session ) ) {
switch_rtp_set_default_payload ( tech_pvt - > video_rtp_session , tech_pvt - > video_agreed_pt ) ;
}
}
2009-11-20 02:17:08 +00:00
switch_snprintf ( tmp , sizeof ( tmp ) , " %d " , tech_pvt - > local_sdp_video_port ) ;
2010-02-06 03:38:24 +00:00
switch_channel_set_variable ( tech_pvt - > channel , SWITCH_LOCAL_VIDEO_IP_VARIABLE , tech_pvt - > adv_sdp_audio_ip ) ;
switch_channel_set_variable ( tech_pvt - > channel , SWITCH_LOCAL_VIDEO_PORT_VARIABLE , tmp ) ;
2009-11-18 19:22:45 +00:00
2009-11-20 02:17:08 +00:00
if ( tech_pvt - > video_rtp_session & & sofia_test_flag ( tech_pvt , TFLAG_REINVITE ) ) {
2010-04-22 10:22:28 -05:00
const char * rport = NULL ;
switch_port_t remote_rtcp_port = 0 ;
2009-11-20 02:17:08 +00:00
sofia_clear_flag_locked ( tech_pvt , TFLAG_REINVITE ) ;
2010-02-06 03:38:24 +00:00
2010-04-22 10:22:28 -05:00
if ( ( rport = switch_channel_get_variable ( tech_pvt - > channel , " sip_remote_video_rtcp_port " ) ) ) {
2010-09-29 15:47:58 -05:00
remote_rtcp_port = ( switch_port_t ) atoi ( rport ) ;
2010-04-22 10:22:28 -05:00
}
2011-02-15 16:09:48 -06:00
2010-02-06 03:38:24 +00:00
if ( switch_rtp_set_remote_address
2010-04-22 10:22:28 -05:00
( tech_pvt - > video_rtp_session , tech_pvt - > remote_sdp_video_ip , tech_pvt - > remote_sdp_video_port , remote_rtcp_port , SWITCH_TRUE ,
2010-02-06 03:38:24 +00:00
& err ) ! = SWITCH_STATUS_SUCCESS ) {
2009-11-20 02:17:08 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_ERROR , " VIDEO RTP REPORTS ERROR: [%s] \n " , err ) ;
} else {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_DEBUG , " VIDEO RTP CHANGING DEST TO: [%s:%d] \n " ,
tech_pvt - > remote_sdp_video_ip , tech_pvt - > remote_sdp_video_port ) ;
if ( ! sofia_test_pflag ( tech_pvt - > profile , PFLAG_DISABLE_RTP_AUTOADJ ) & &
! ( ( val = switch_channel_get_variable ( tech_pvt - > channel , " disable_rtp_auto_adjust " ) ) & & switch_true ( val ) ) ) {
/* Reactivate the NAT buster flag. */
switch_rtp_set_flag ( tech_pvt - > video_rtp_session , SWITCH_RTP_FLAG_AUTOADJ ) ;
}
2010-09-29 14:14:41 -05:00
2009-11-18 19:22:45 +00:00
}
2009-11-20 02:17:08 +00:00
goto video_up ;
2009-11-18 19:22:45 +00:00
}
2009-11-20 02:17:08 +00:00
if ( switch_channel_test_flag ( tech_pvt - > channel , CF_PROXY_MEDIA ) ) {
if ( ( status = sofia_glue_tech_proxy_remote_addr ( tech_pvt ) ) ! = SWITCH_STATUS_SUCCESS ) {
goto end ;
}
2009-11-18 19:22:45 +00:00
2009-11-20 02:17:08 +00:00
if ( ! sofia_test_pflag ( tech_pvt - > profile , PFLAG_DISABLE_RTP_AUTOADJ ) & &
! ( ( val = switch_channel_get_variable ( tech_pvt - > channel , " disable_rtp_auto_adjust " ) ) & & switch_true ( val ) ) ) {
flags = ( switch_rtp_flag_t ) ( SWITCH_RTP_FLAG_PROXY_MEDIA | SWITCH_RTP_FLAG_AUTOADJ | SWITCH_RTP_FLAG_DATAWAIT ) ;
} else {
flags = ( switch_rtp_flag_t ) ( SWITCH_RTP_FLAG_PROXY_MEDIA | SWITCH_RTP_FLAG_DATAWAIT ) ;
}
timer_name = NULL ;
2009-11-18 19:22:45 +00:00
2009-11-20 02:17:08 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_DEBUG ,
" PROXY VIDEO RTP [%s] %s:%d->%s:%d codec: %u ms: %d \n " ,
switch_channel_get_name ( tech_pvt - > channel ) ,
tech_pvt - > local_sdp_audio_ip ,
tech_pvt - > local_sdp_video_port ,
tech_pvt - > remote_sdp_video_ip ,
tech_pvt - > remote_sdp_video_port , tech_pvt - > video_agreed_pt , tech_pvt - > read_impl . microseconds_per_packet / 1000 ) ;
2009-11-18 19:22:45 +00:00
2010-09-29 14:14:41 -05:00
if ( switch_rtp_ready ( tech_pvt - > video_rtp_session ) ) {
switch_rtp_set_default_payload ( tech_pvt - > video_rtp_session , tech_pvt - > video_agreed_pt ) ;
}
2009-11-20 02:17:08 +00:00
} else {
timer_name = tech_pvt - > profile - > timer_name ;
2009-11-18 19:22:45 +00:00
2009-11-20 02:17:08 +00:00
if ( ( var = switch_channel_get_variable ( tech_pvt - > channel , " rtp_timer_name " ) ) ) {
timer_name = ( char * ) var ;
}
2009-11-18 19:22:45 +00:00
}
2009-11-20 02:17:08 +00:00
/******************************************************************************************/
2010-02-06 03:38:24 +00:00
2010-02-02 22:58:45 +00:00
if ( tech_pvt - > video_rtp_session ) {
goto video_up ;
}
2009-11-18 19:22:45 +00:00
2008-03-08 21:37:17 +00:00
if ( ! tech_pvt - > local_sdp_video_port ) {
2008-05-24 01:27:19 +00:00
sofia_glue_tech_choose_video_port ( tech_pvt , 1 ) ;
2008-03-08 21:37:17 +00:00
}
2008-09-18 21:50:18 +00:00
if ( ! sofia_test_pflag ( tech_pvt - > profile , PFLAG_DISABLE_RTP_AUTOADJ ) & & ! switch_channel_test_flag ( tech_pvt - > channel , CF_PROXY_MODE ) & &
2008-07-07 17:56:16 +00:00
! ( ( val = switch_channel_get_variable ( tech_pvt - > channel , " disable_rtp_auto_adjust " ) ) & & switch_true ( val ) ) ) {
2011-05-12 10:32:39 -05:00
flags = ( switch_rtp_flag_t ) ( SWITCH_RTP_FLAG_AUTOADJ | SWITCH_RTP_FLAG_DATAWAIT | SWITCH_RTP_FLAG_RAW_WRITE ) ;
2008-07-07 17:56:16 +00:00
} else {
2011-05-12 10:32:39 -05:00
flags = ( switch_rtp_flag_t ) ( SWITCH_RTP_FLAG_DATAWAIT | SWITCH_RTP_FLAG_RAW_WRITE ) ;
2008-07-07 17:56:16 +00:00
}
2008-05-23 19:41:23 +00:00
if ( switch_channel_test_flag ( tech_pvt - > channel , CF_PROXY_MEDIA ) ) {
flags | = SWITCH_RTP_FLAG_PROXY_MEDIA ;
}
2007-04-19 21:40:50 +00:00
sofia_glue_tech_set_video_codec ( tech_pvt , 0 ) ;
2009-11-18 19:22:45 +00:00
flags & = ~ ( SWITCH_RTP_FLAG_USE_TIMER | SWITCH_RTP_FLAG_NOBLOCK ) ;
2010-02-03 19:19:10 +00:00
flags | = SWITCH_RTP_FLAG_VIDEO ;
2009-11-18 19:22:45 +00:00
2007-04-19 21:40:50 +00:00
tech_pvt - > video_rtp_session = switch_rtp_new ( tech_pvt - > local_sdp_audio_ip ,
2008-01-16 06:01:53 +00:00
tech_pvt - > local_sdp_video_port ,
tech_pvt - > remote_sdp_video_ip ,
tech_pvt - > remote_sdp_video_port ,
tech_pvt - > video_agreed_pt ,
2009-11-18 19:22:45 +00:00
1 , 90000 , ( switch_rtp_flag_t ) flags , NULL , & err , switch_core_session_get_pool ( tech_pvt - > session ) ) ;
2007-11-20 02:27:48 +00:00
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_DEBUG , " %sVIDEO RTP [%s] %s:%d->%s:%d codec: %u ms: %d [%s] \n " ,
2008-05-23 19:41:23 +00:00
switch_channel_test_flag ( tech_pvt - > channel , CF_PROXY_MEDIA ) ? " PROXY " : " " ,
2007-05-09 19:30:41 +00:00
switch_channel_get_name ( tech_pvt - > channel ) ,
2007-04-19 21:40:50 +00:00
tech_pvt - > local_sdp_audio_ip ,
tech_pvt - > local_sdp_video_port ,
tech_pvt - > remote_sdp_video_ip ,
tech_pvt - > remote_sdp_video_port , tech_pvt - > video_agreed_pt ,
2008-05-27 04:54:52 +00:00
0 , switch_rtp_ready ( tech_pvt - > video_rtp_session ) ? " SUCCESS " : err ) ;
2007-04-19 21:40:50 +00:00
2010-09-29 14:14:41 -05:00
if ( switch_rtp_ready ( tech_pvt - > video_rtp_session ) ) {
switch_rtp_set_default_payload ( tech_pvt - > video_rtp_session , tech_pvt - > video_agreed_pt ) ;
}
2007-04-19 21:40:50 +00:00
if ( switch_rtp_ready ( tech_pvt - > video_rtp_session ) ) {
2010-02-06 03:38:24 +00:00
const char * ssrc ;
2007-05-09 19:30:41 +00:00
switch_channel_set_flag ( tech_pvt - > channel , CF_VIDEO ) ;
2010-02-06 03:38:24 +00:00
if ( ( ssrc = switch_channel_get_variable ( tech_pvt - > channel , " rtp_use_video_ssrc " ) ) ) {
uint32_t ssrc_ul = ( uint32_t ) strtoul ( ssrc , NULL , 10 ) ;
switch_rtp_set_ssrc ( tech_pvt - > video_rtp_session , ssrc_ul ) ;
}
2011-02-15 16:09:48 -06:00
if ( tech_pvt - > video_recv_pt ! = tech_pvt - > video_agreed_pt ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_DEBUG ,
2011-02-25 15:20:04 -06:00
" %s Set video receive payload to %u \n " , switch_channel_get_name ( tech_pvt - > channel ) , tech_pvt - > video_recv_pt ) ;
switch_rtp_set_recv_pt ( tech_pvt - > video_rtp_session , tech_pvt - > video_recv_pt ) ;
2011-02-15 16:09:48 -06:00
}
2010-02-06 03:38:24 +00:00
switch_channel_set_variable_printf ( tech_pvt - > channel , " sip_use_video_pt " , " %d " , tech_pvt - > video_agreed_pt ) ;
tech_pvt - > video_ssrc = switch_rtp_get_ssrc ( tech_pvt - > rtp_session ) ;
switch_channel_set_variable_printf ( tech_pvt - > channel , " rtp_use_video_ssrc " , " %u " , tech_pvt - > ssrc ) ;
2010-04-20 16:15:37 -05:00
2010-06-23 13:22:52 -05:00
if ( ( val = switch_channel_get_variable ( tech_pvt - > channel , " rtcp_audio_interval_msec " ) )
| | ( val = tech_pvt - > profile - > rtcp_audio_interval_msec ) ) {
2010-04-20 16:15:37 -05:00
const char * rport = switch_channel_get_variable ( tech_pvt - > channel , " sip_remote_video_rtcp_port " ) ;
switch_port_t remote_port = 0 ;
if ( rport ) {
2010-09-29 15:47:58 -05:00
remote_port = ( switch_port_t ) atoi ( rport ) ;
2010-04-20 16:15:37 -05:00
}
if ( ! strcasecmp ( val , " passthru " ) ) {
switch_rtp_activate_rtcp ( tech_pvt - > rtp_session , - 1 , remote_port ) ;
} else {
int interval = atoi ( val ) ;
if ( interval < 100 | | interval > 5000 ) {
2010-06-23 13:22:52 -05:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_ERROR ,
" Invalid rtcp interval spec [%d] must be between 100 and 5000 \n " , interval ) ;
2010-04-20 16:15:37 -05:00
} else {
switch_rtp_activate_rtcp ( tech_pvt - > rtp_session , interval , remote_port ) ;
}
}
}
2008-03-07 20:13:40 +00:00
} else {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_ERROR , " VIDEO RTP REPORTS ERROR: [%s] \n " , switch_str_nil ( err ) ) ;
2008-03-07 20:13:40 +00:00
switch_channel_hangup ( tech_pvt - > channel , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
goto end ;
2007-04-19 21:40:50 +00:00
}
}
2009-11-18 19:22:45 +00:00
2007-03-31 19:01:33 +00:00
} else {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_ERROR , " AUDIO RTP REPORTS ERROR: [%s] \n " , switch_str_nil ( err ) ) ;
2007-05-09 19:30:41 +00:00
switch_channel_hangup ( tech_pvt - > channel , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
2009-02-09 17:56:38 +00:00
sofia_clear_flag_locked ( tech_pvt , TFLAG_IO ) ;
2008-02-25 16:35:19 +00:00
status = SWITCH_STATUS_FALSE ;
goto end ;
2007-03-31 19:01:33 +00:00
}
2010-06-23 13:22:52 -05:00
video_up :
2009-11-18 19:22:45 +00:00
2009-02-09 17:56:38 +00:00
sofia_set_flag ( tech_pvt , TFLAG_IO ) ;
2008-02-25 16:35:19 +00:00
status = SWITCH_STATUS_SUCCESS ;
2008-05-27 04:54:52 +00:00
2010-06-23 13:22:52 -05:00
end :
2008-02-25 16:35:19 +00:00
2011-08-01 20:08:04 -05:00
sofia_clear_flag_locked ( tech_pvt , TFLAG_REINVITE ) ;
2010-02-06 03:38:24 +00:00
sofia_glue_tech_track ( tech_pvt - > profile , tech_pvt - > session ) ;
2008-10-30 22:40:39 +00:00
switch_mutex_unlock ( tech_pvt - > sofia_mutex ) ;
2008-02-26 20:31:53 +00:00
2008-02-25 16:35:19 +00:00
return status ;
2008-05-27 04:54:52 +00:00
2007-03-31 19:01:33 +00:00
}
2011-03-04 12:28:41 -06:00
static void add_audio_codec ( sdp_rtpmap_t * map , int ptime , char * buf , switch_size_t buflen )
{
int codec_ms = ptime ;
uint32_t map_bit_rate = 0 ;
char ptstr [ 20 ] = " " ;
char ratestr [ 20 ] = " " ;
char bitstr [ 20 ] = " " ;
switch_codec_fmtp_t codec_fmtp = { 0 } ;
if ( ! codec_ms ) {
codec_ms = switch_default_ptime ( map - > rm_encoding , map - > rm_pt ) ;
}
2011-05-29 09:46:02 -05:00
map_bit_rate = switch_known_bitrate ( ( switch_payload_t ) map - > rm_pt ) ;
2011-03-04 12:28:41 -06:00
if ( ! ptime & & ! strcasecmp ( map - > rm_encoding , " g723 " ) ) {
ptime = codec_ms = 30 ;
}
if ( zstr ( map - > rm_fmtp ) ) {
if ( ! strcasecmp ( map - > rm_encoding , " ilbc " ) ) {
ptime = codec_ms = 30 ;
map_bit_rate = 13330 ;
}
} else {
if ( ( switch_core_codec_parse_fmtp ( map - > rm_encoding , map - > rm_fmtp , map - > rm_rate , & codec_fmtp ) ) = = SWITCH_STATUS_SUCCESS ) {
if ( codec_fmtp . bits_per_second ) {
map_bit_rate = codec_fmtp . bits_per_second ;
}
if ( codec_fmtp . microseconds_per_packet ) {
codec_ms = ( codec_fmtp . microseconds_per_packet / 1000 ) ;
}
}
}
if ( map - > rm_rate ) {
switch_snprintf ( ratestr , sizeof ( ratestr ) , " @%uh " , ( unsigned int ) map - > rm_rate ) ;
}
if ( codec_ms ) {
switch_snprintf ( ptstr , sizeof ( ptstr ) , " @%di " , codec_ms ) ;
}
if ( map_bit_rate ) {
switch_snprintf ( bitstr , sizeof ( bitstr ) , " @%db " , map_bit_rate ) ;
}
switch_snprintf ( buf + strlen ( buf ) , buflen - strlen ( buf ) , " ,%s%s%s%s " , map - > rm_encoding , ratestr , ptstr , bitstr ) ;
}
2009-11-03 21:32:18 +00:00
void sofia_glue_set_r_sdp_codec_string ( switch_core_session_t * session , const char * codec_string , sdp_session_t * sdp )
2009-04-08 06:05:56 +00:00
{
2010-02-06 03:38:24 +00:00
char buf [ 1024 ] = { 0 } ;
2009-04-08 06:05:56 +00:00
sdp_media_t * m ;
sdp_attribute_t * attr ;
int ptime = 0 , dptime = 0 ;
sdp_connection_t * connection ;
sdp_rtpmap_t * map ;
short int match = 0 ;
int i ;
int already_did [ 128 ] = { 0 } ;
int num_codecs = 0 ;
char * codec_order [ SWITCH_MAX_CODECS ] ;
const switch_codec_implementation_t * codecs [ SWITCH_MAX_CODECS ] = { 0 } ;
2009-11-03 21:32:18 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
private_object_t * tech_pvt = switch_core_session_get_private ( session ) ;
2011-03-04 12:28:41 -06:00
int prefer_sdp = 0 ;
const char * var ;
2009-04-08 06:05:56 +00:00
2011-03-04 12:28:41 -06:00
if ( ( var = switch_channel_get_variable ( channel , " ep_codec_prefer_sdp " ) ) & & switch_true ( var ) ) {
prefer_sdp = 1 ;
}
2009-10-23 16:03:42 +00:00
if ( ! zstr ( codec_string ) ) {
2009-04-08 06:05:56 +00:00
char * tmp_codec_string ;
if ( ( tmp_codec_string = strdup ( codec_string ) ) ) {
num_codecs = switch_separate_string ( tmp_codec_string , ' , ' , codec_order , SWITCH_MAX_CODECS ) ;
num_codecs = switch_loadable_module_get_codecs_sorted ( codecs , SWITCH_MAX_CODECS , codec_order , num_codecs ) ;
switch_safe_free ( tmp_codec_string ) ;
}
} else {
num_codecs = switch_loadable_module_get_codecs ( codecs , SWITCH_MAX_CODECS ) ;
}
if ( ! channel | | ! num_codecs ) {
return ;
}
for ( attr = sdp - > sdp_attributes ; attr ; attr = attr - > a_next ) {
2009-10-23 16:03:42 +00:00
if ( zstr ( attr - > a_name ) ) {
2009-04-08 06:05:56 +00:00
continue ;
}
if ( ! strcasecmp ( attr - > a_name , " ptime " ) ) {
dptime = atoi ( attr - > a_value ) ;
break ;
}
}
for ( m = sdp - > sdp_media ; m ; m = m - > m_next ) {
ptime = dptime ;
2010-02-06 03:38:24 +00:00
if ( m - > m_type = = sdp_media_image & & m - > m_port ) {
2009-04-08 06:05:56 +00:00
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " ,t38 " ) ;
} else if ( m - > m_type = = sdp_media_audio & & m - > m_port ) {
for ( attr = m - > m_attributes ; attr ; attr = attr - > a_next ) {
2009-10-23 16:03:42 +00:00
if ( zstr ( attr - > a_name ) ) {
2009-04-08 06:05:56 +00:00
continue ;
}
if ( ! strcasecmp ( attr - > a_name , " ptime " ) & & attr - > a_value ) {
ptime = atoi ( attr - > a_value ) ;
break ;
}
}
connection = sdp - > sdp_connection ;
if ( m - > m_connections ) {
connection = m - > m_connections ;
}
if ( ! connection ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_CHANNEL_LOG ( channel ) , SWITCH_LOG_ERROR , " Cannot find a c= line in the sdp at media or session level! \n " ) ;
2009-04-08 06:05:56 +00:00
break ;
}
2011-03-04 12:28:41 -06:00
if ( switch_channel_direction ( channel ) = = SWITCH_CALL_DIRECTION_INBOUND | | prefer_sdp ) {
2009-04-08 06:05:56 +00:00
for ( map = m - > m_rtpmaps ; map ; map = map - > rm_next ) {
2010-02-06 03:38:24 +00:00
if ( map - > rm_pt > 127 | | already_did [ map - > rm_pt ] ) {
2009-04-08 06:05:56 +00:00
continue ;
}
2011-03-04 12:28:41 -06:00
for ( i = 0 ; i < num_codecs ; i + + ) {
const switch_codec_implementation_t * imp = codecs [ i ] ;
2011-01-06 17:15:45 -06:00
2011-03-04 12:28:41 -06:00
if ( ( zstr ( map - > rm_encoding ) | | ( tech_pvt - > profile - > ndlb & PFLAG_NDLB_ALLOW_BAD_IANANAME ) ) & & map - > rm_pt < 96 ) {
match = ( map - > rm_pt = = imp - > ianacode ) ? 1 : 0 ;
2009-05-04 22:53:41 +00:00
} else {
2011-03-04 12:28:41 -06:00
if ( map - > rm_encoding ) {
match = strcasecmp ( map - > rm_encoding , imp - > iananame ) ? 0 : 1 ;
} else {
match = 0 ;
2011-01-06 17:15:45 -06:00
}
2009-05-04 22:53:41 +00:00
}
2011-01-06 17:15:45 -06:00
2011-03-04 12:28:41 -06:00
if ( match ) {
add_audio_codec ( map , ptime , buf , sizeof ( buf ) ) ;
break ;
2011-01-06 17:15:45 -06:00
}
2011-03-04 12:28:41 -06:00
}
}
2011-01-06 17:15:45 -06:00
2011-03-04 12:28:41 -06:00
} else {
for ( i = 0 ; i < num_codecs ; i + + ) {
const switch_codec_implementation_t * imp = codecs [ i ] ;
if ( imp - > codec_type ! = SWITCH_CODEC_TYPE_AUDIO | | imp - > ianacode > 127 | | already_did [ imp - > ianacode ] ) {
continue ;
}
for ( map = m - > m_rtpmaps ; map ; map = map - > rm_next ) {
if ( map - > rm_pt > 127 | | already_did [ map - > rm_pt ] ) {
continue ;
2011-01-06 17:15:45 -06:00
}
2011-03-04 12:28:41 -06:00
if ( ( zstr ( map - > rm_encoding ) | | ( tech_pvt - > profile - > ndlb & PFLAG_NDLB_ALLOW_BAD_IANANAME ) ) & & map - > rm_pt < 96 ) {
match = ( map - > rm_pt = = imp - > ianacode ) ? 1 : 0 ;
} else {
if ( map - > rm_encoding ) {
match = strcasecmp ( map - > rm_encoding , imp - > iananame ) ? 0 : 1 ;
} else {
match = 0 ;
}
2011-01-06 17:15:45 -06:00
}
2011-03-04 12:28:41 -06:00
if ( match ) {
add_audio_codec ( map , ptime , buf , sizeof ( buf ) ) ;
break ;
}
2009-04-08 06:05:56 +00:00
}
}
}
2011-03-04 12:28:41 -06:00
2009-04-08 06:05:56 +00:00
} else if ( m - > m_type = = sdp_media_video & & m - > m_port ) {
connection = sdp - > sdp_connection ;
if ( m - > m_connections ) {
connection = m - > m_connections ;
}
if ( ! connection ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_CHANNEL_LOG ( channel ) , SWITCH_LOG_ERROR , " Cannot find a c= line in the sdp at media or session level! \n " ) ;
2009-04-08 06:05:56 +00:00
break ;
}
for ( i = 0 ; i < num_codecs ; i + + ) {
const switch_codec_implementation_t * imp = codecs [ i ] ;
if ( imp - > codec_type ! = SWITCH_CODEC_TYPE_VIDEO | | imp - > ianacode > 127 | | already_did [ imp - > ianacode ] ) {
continue ;
}
for ( map = m - > m_rtpmaps ; map ; map = map - > rm_next ) {
2010-02-06 03:38:24 +00:00
if ( map - > rm_pt > 127 | | already_did [ map - > rm_pt ] ) {
2009-04-08 06:05:56 +00:00
continue ;
}
2009-11-03 21:32:18 +00:00
if ( ( zstr ( map - > rm_encoding ) | | ( tech_pvt - > profile - > ndlb & PFLAG_NDLB_ALLOW_BAD_IANANAME ) ) & & map - > rm_pt < 96 ) {
2009-04-08 06:05:56 +00:00
match = ( map - > rm_pt = = imp - > ianacode ) ? 1 : 0 ;
} else {
2009-12-11 01:20:26 +00:00
if ( map - > rm_encoding ) {
2009-04-08 06:05:56 +00:00
match = strcasecmp ( map - > rm_encoding , imp - > iananame ) ? 0 : 1 ;
} else {
match = 0 ;
}
}
if ( match ) {
2009-12-11 01:20:26 +00:00
if ( ptime > 0 ) {
2010-02-06 03:38:24 +00:00
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " ,%s@%uh@%di " , imp - > iananame , ( unsigned int ) map - > rm_rate ,
ptime ) ;
2009-05-04 22:53:41 +00:00
} else {
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " ,%s@%uh " , imp - > iananame , ( unsigned int ) map - > rm_rate ) ;
}
2009-04-08 06:05:56 +00:00
already_did [ imp - > ianacode ] = 1 ;
break ;
}
}
}
}
}
if ( buf [ 0 ] = = ' , ' ) {
switch_channel_set_variable ( channel , " ep_codec_string " , buf + 1 ) ;
}
}
2007-11-01 11:28:26 +00:00
switch_status_t sofia_glue_tech_media ( private_object_t * tech_pvt , const char * r_sdp )
2007-03-31 19:01:33 +00:00
{
uint8_t match = 0 ;
2007-12-12 23:21:45 +00:00
switch_assert ( tech_pvt ! = NULL ) ;
switch_assert ( r_sdp ! = NULL ) ;
2007-10-05 15:47:48 +00:00
2009-10-23 16:03:42 +00:00
if ( zstr ( r_sdp ) ) {
2007-03-31 19:01:33 +00:00
return SWITCH_STATUS_FALSE ;
}
2010-05-26 20:12:54 -05:00
if ( ( match = sofia_glue_negotiate_sdp ( tech_pvt - > session , r_sdp ) ) ) {
2008-02-21 17:48:41 +00:00
if ( sofia_glue_tech_choose_port ( tech_pvt , 0 ) ! = SWITCH_STATUS_SUCCESS ) {
2007-03-31 19:01:33 +00:00
return SWITCH_STATUS_FALSE ;
}
2007-10-25 18:36:40 +00:00
if ( sofia_glue_activate_rtp ( tech_pvt , 0 ) ! = SWITCH_STATUS_SUCCESS ) {
2007-04-17 06:08:39 +00:00
return SWITCH_STATUS_FALSE ;
}
2007-05-09 19:30:41 +00:00
switch_channel_set_variable ( tech_pvt - > channel , SWITCH_ENDPOINT_DISPOSITION_VARIABLE , " EARLY MEDIA " ) ;
2009-02-09 17:56:38 +00:00
sofia_set_flag_locked ( tech_pvt , TFLAG_EARLY_MEDIA ) ;
2007-05-09 19:30:41 +00:00
switch_channel_mark_pre_answered ( tech_pvt - > channel ) ;
2007-03-31 19:01:33 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2009-03-20 17:03:46 +00:00
2007-03-31 19:01:33 +00:00
return SWITCH_STATUS_FALSE ;
}
2011-03-07 13:02:21 -06:00
int sofia_glue_toggle_hold ( private_object_t * tech_pvt , int sendonly )
2007-03-31 19:01:33 +00:00
{
2011-03-07 13:02:21 -06:00
int changed = 0 ;
2008-09-18 21:50:18 +00:00
if ( sendonly & & switch_channel_test_flag ( tech_pvt - > channel , CF_ANSWERED ) ) {
2009-02-09 17:56:38 +00:00
if ( ! sofia_test_flag ( tech_pvt , TFLAG_SIP_HOLD ) ) {
2007-11-01 11:28:26 +00:00
const char * stream ;
2010-01-13 23:58:00 +00:00
const char * msg = " hold " ;
2010-02-06 03:38:24 +00:00
2010-01-13 23:58:00 +00:00
if ( sofia_test_pflag ( tech_pvt - > profile , PFLAG_MANAGE_SHARED_APPEARANCE ) ) {
const char * info = switch_channel_get_variable ( tech_pvt - > channel , " presence_call_info " ) ;
if ( info ) {
if ( switch_stristr ( " private " , info ) ) {
msg = " hold-private " ;
}
}
}
2008-01-03 21:34:44 +00:00
2009-02-09 17:56:38 +00:00
sofia_set_flag_locked ( tech_pvt , TFLAG_SIP_HOLD ) ;
2009-11-24 18:18:09 +00:00
switch_channel_set_flag ( tech_pvt - > channel , CF_LEG_HOLDING ) ;
2010-06-04 19:03:36 -05:00
switch_channel_mark_hold ( tech_pvt - > channel , SWITCH_TRUE ) ;
2010-01-13 23:58:00 +00:00
switch_channel_presence ( tech_pvt - > channel , " unknown " , msg , NULL ) ;
2011-03-07 13:02:21 -06:00
changed = 1 ;
2008-01-03 21:34:44 +00:00
2008-03-19 21:43:13 +00:00
if ( tech_pvt - > max_missed_hold_packets ) {
2008-01-21 00:35:33 +00:00
switch_rtp_set_max_missed_packets ( tech_pvt - > rtp_session , tech_pvt - > max_missed_hold_packets ) ;
2007-10-31 17:30:50 +00:00
}
2010-06-23 13:22:52 -05:00
2011-01-05 18:58:56 -06:00
if ( ! ( stream = switch_channel_get_hold_music ( tech_pvt - > channel ) ) ) {
2007-06-24 03:17:21 +00:00
stream = tech_pvt - > profile - > hold_music ;
}
2008-05-27 04:54:52 +00:00
2009-05-14 18:55:17 +00:00
if ( stream & & strcasecmp ( stream , " silence " ) ) {
2008-05-01 16:41:46 +00:00
if ( ! strcasecmp ( stream , " indicate_hold " ) ) {
switch_channel_set_flag ( tech_pvt - > channel , CF_SUSPEND ) ;
switch_channel_set_flag ( tech_pvt - > channel , CF_HOLD ) ;
switch_ivr_hold_uuid ( switch_channel_get_variable ( tech_pvt - > channel , SWITCH_SIGNAL_BOND_VARIABLE ) , NULL , 0 ) ;
} else {
2010-02-06 03:38:24 +00:00
switch_ivr_broadcast ( switch_channel_get_variable ( tech_pvt - > channel , SWITCH_SIGNAL_BOND_VARIABLE ) , stream ,
2009-12-10 01:29:02 +00:00
SMF_ECHO_ALEG | SMF_LOOP | SMF_PRIORITY ) ;
2008-06-27 16:20:20 +00:00
switch_yield ( 250000 ) ;
2008-05-01 16:41:46 +00:00
}
2007-06-24 03:17:21 +00:00
}
}
} else {
2009-02-09 17:56:38 +00:00
if ( sofia_test_flag ( tech_pvt , TFLAG_HOLD_LOCK ) ) {
sofia_set_flag ( tech_pvt , TFLAG_SIP_HOLD ) ;
2009-11-24 18:18:09 +00:00
switch_channel_set_flag ( tech_pvt - > channel , CF_LEG_HOLDING ) ;
2010-06-04 19:03:36 -05:00
switch_channel_mark_hold ( tech_pvt - > channel , SWITCH_TRUE ) ;
2011-03-07 13:02:21 -06:00
changed = 1 ;
2008-09-18 21:50:18 +00:00
}
2009-02-09 17:56:38 +00:00
sofia_clear_flag_locked ( tech_pvt , TFLAG_HOLD_LOCK ) ;
2010-02-06 03:38:24 +00:00
2009-02-09 17:56:38 +00:00
if ( sofia_test_flag ( tech_pvt , TFLAG_SIP_HOLD ) ) {
2008-01-05 22:17:26 +00:00
const char * uuid ;
switch_core_session_t * b_session ;
2008-05-27 04:54:52 +00:00
2008-06-27 16:20:20 +00:00
switch_yield ( 250000 ) ;
2007-10-31 17:30:50 +00:00
if ( tech_pvt - > max_missed_packets ) {
2009-03-16 02:15:12 +00:00
switch_rtp_reset_media_timer ( tech_pvt - > rtp_session ) ;
2007-10-31 17:30:50 +00:00
switch_rtp_set_max_missed_packets ( tech_pvt - > rtp_session , tech_pvt - > max_missed_packets ) ;
}
2008-01-03 21:34:44 +00:00
2008-01-05 22:17:26 +00:00
if ( ( uuid = switch_channel_get_variable ( tech_pvt - > channel , SWITCH_SIGNAL_BOND_VARIABLE ) ) & & ( b_session = switch_core_session_locate ( uuid ) ) ) {
switch_channel_t * b_channel = switch_core_session_get_channel ( b_session ) ;
2008-05-01 16:41:46 +00:00
if ( switch_channel_test_flag ( tech_pvt - > channel , CF_HOLD ) ) {
switch_ivr_unhold ( b_session ) ;
switch_channel_clear_flag ( tech_pvt - > channel , CF_SUSPEND ) ;
switch_channel_clear_flag ( tech_pvt - > channel , CF_HOLD ) ;
} else {
switch_channel_stop_broadcast ( b_channel ) ;
2008-09-09 16:31:53 +00:00
switch_channel_wait_for_flag ( b_channel , CF_BROADCAST , SWITCH_FALSE , 5000 , NULL ) ;
2008-05-01 16:41:46 +00:00
}
2008-01-05 22:17:26 +00:00
switch_core_session_rwunlock ( b_session ) ;
}
2008-01-03 21:34:44 +00:00
2009-02-09 17:56:38 +00:00
sofia_clear_flag_locked ( tech_pvt , TFLAG_SIP_HOLD ) ;
2009-11-24 18:18:09 +00:00
switch_channel_clear_flag ( tech_pvt - > channel , CF_LEG_HOLDING ) ;
2010-06-04 19:03:36 -05:00
switch_channel_mark_hold ( tech_pvt - > channel , SWITCH_FALSE ) ;
2008-08-25 16:30:28 +00:00
switch_channel_presence ( tech_pvt - > channel , " unknown " , " unhold " , NULL ) ;
2011-03-07 13:02:21 -06:00
changed = 1 ;
2007-06-24 03:17:21 +00:00
}
}
2011-03-07 13:02:21 -06:00
return changed ;
2008-09-18 21:50:18 +00:00
}
2010-05-26 20:12:54 -05:00
void sofia_glue_copy_t38_options ( switch_t38_options_t * t38_options , switch_core_session_t * session )
{
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
switch_t38_options_t * local_t38_options = switch_channel_get_private ( channel , " t38_options " ) ;
2010-08-17 11:16:55 -05:00
switch_assert ( t38_options ) ;
2010-05-26 20:12:54 -05:00
if ( ! local_t38_options ) {
local_t38_options = switch_core_session_alloc ( session , sizeof ( switch_t38_options_t ) ) ;
}
local_t38_options - > T38MaxBitRate = t38_options - > T38MaxBitRate ;
local_t38_options - > T38FaxFillBitRemoval = t38_options - > T38FaxFillBitRemoval ;
local_t38_options - > T38FaxTranscodingMMR = t38_options - > T38FaxTranscodingMMR ;
local_t38_options - > T38FaxTranscodingJBIG = t38_options - > T38FaxTranscodingJBIG ;
2010-06-17 10:23:37 -05:00
local_t38_options - > T38FaxRateManagement = switch_core_session_strdup ( session , t38_options - > T38FaxRateManagement ) ;
2010-05-26 20:12:54 -05:00
local_t38_options - > T38FaxMaxBuffer = t38_options - > T38FaxMaxBuffer ;
local_t38_options - > T38FaxMaxDatagram = t38_options - > T38FaxMaxDatagram ;
2010-06-17 10:23:37 -05:00
local_t38_options - > T38FaxUdpEC = switch_core_session_strdup ( session , t38_options - > T38FaxUdpEC ) ;
local_t38_options - > T38VendorInfo = switch_core_session_strdup ( session , t38_options - > T38VendorInfo ) ;
local_t38_options - > remote_ip = switch_core_session_strdup ( session , t38_options - > remote_ip ) ;
local_t38_options - > remote_port = t38_options - > remote_port ;
2010-06-23 13:22:52 -05:00
2010-05-26 20:12:54 -05:00
switch_channel_set_private ( channel , " t38_options " , local_t38_options ) ;
2010-06-23 13:22:52 -05:00
2010-05-26 20:12:54 -05:00
}
2011-09-19 20:11:23 -05:00
2010-05-26 20:12:54 -05:00
static switch_t38_options_t * tech_process_udptl ( private_object_t * tech_pvt , sdp_session_t * sdp , sdp_media_t * m )
{
switch_t38_options_t * t38_options = switch_channel_get_private ( tech_pvt - > channel , " t38_options " ) ;
sdp_attribute_t * attr ;
if ( ! t38_options ) {
t38_options = switch_core_session_alloc ( tech_pvt - > session , sizeof ( switch_t38_options_t ) ) ;
2010-12-01 09:46:06 -06:00
// set some default value
t38_options - > T38FaxVersion = 0 ;
t38_options - > T38MaxBitRate = 9600 ;
t38_options - > T38FaxRateManagement = switch_core_session_strdup ( tech_pvt - > session , " transferredTCF " ) ;
t38_options - > T38FaxUdpEC = switch_core_session_strdup ( tech_pvt - > session , " t38UDPRedundancy " ) ;
t38_options - > T38FaxMaxBuffer = 500 ;
t38_options - > T38FaxMaxDatagram = 500 ;
2010-05-26 20:12:54 -05:00
}
2010-06-23 13:22:52 -05:00
2010-09-29 15:47:58 -05:00
t38_options - > remote_port = ( switch_port_t ) m - > m_port ;
2010-06-23 13:22:52 -05:00
2011-09-19 20:11:23 -05:00
if ( sdp - > sdp_origin ) {
t38_options - > sdp_o_line = switch_core_session_strdup ( tech_pvt - > session , sdp - > sdp_origin - > o_username ) ;
} else {
t38_options - > sdp_o_line = " unknown " ;
}
2010-09-23 11:16:47 -05:00
if ( m - > m_connections & & m - > m_connections - > c_address ) {
2010-06-17 10:23:37 -05:00
t38_options - > remote_ip = switch_core_session_strdup ( tech_pvt - > session , m - > m_connections - > c_address ) ;
2010-09-23 11:16:47 -05:00
} else if ( sdp & & sdp - > sdp_connection & & sdp - > sdp_connection - > c_address ) {
2010-06-17 10:23:37 -05:00
t38_options - > remote_ip = switch_core_session_strdup ( tech_pvt - > session , sdp - > sdp_connection - > c_address ) ;
2010-05-26 20:12:54 -05:00
}
2010-06-23 13:22:52 -05:00
2010-05-26 20:12:54 -05:00
for ( attr = m - > m_attributes ; attr ; attr = attr - > a_next ) {
if ( ! strcasecmp ( attr - > a_name , " T38FaxVersion " ) & & attr - > a_value ) {
t38_options - > T38FaxVersion = ( uint16_t ) atoi ( attr - > a_value ) ;
} else if ( ! strcasecmp ( attr - > a_name , " T38MaxBitRate " ) & & attr - > a_value ) {
t38_options - > T38MaxBitRate = ( uint32_t ) atoi ( attr - > a_value ) ;
} else if ( ! strcasecmp ( attr - > a_name , " T38FaxFillBitRemoval " ) ) {
2011-09-19 20:11:23 -05:00
t38_options - > T38FaxFillBitRemoval = switch_safe_atoi ( attr - > a_value , 1 ) ;
2010-05-26 20:12:54 -05:00
} else if ( ! strcasecmp ( attr - > a_name , " T38FaxTranscodingMMR " ) ) {
2011-09-19 20:11:23 -05:00
t38_options - > T38FaxTranscodingMMR = switch_safe_atoi ( attr - > a_value , 1 ) ;
2010-05-26 20:12:54 -05:00
} else if ( ! strcasecmp ( attr - > a_name , " T38FaxTranscodingJBIG " ) ) {
2011-09-19 20:11:23 -05:00
t38_options - > T38FaxTranscodingJBIG = switch_safe_atoi ( attr - > a_value , 1 ) ;
2010-05-26 20:12:54 -05:00
} else if ( ! strcasecmp ( attr - > a_name , " T38FaxRateManagement " ) & & attr - > a_value ) {
t38_options - > T38FaxRateManagement = switch_core_session_strdup ( tech_pvt - > session , attr - > a_value ) ;
} else if ( ! strcasecmp ( attr - > a_name , " T38FaxMaxBuffer " ) & & attr - > a_value ) {
t38_options - > T38FaxMaxBuffer = ( uint32_t ) atoi ( attr - > a_value ) ;
} else if ( ! strcasecmp ( attr - > a_name , " T38FaxMaxDatagram " ) & & attr - > a_value ) {
t38_options - > T38FaxMaxDatagram = ( uint32_t ) atoi ( attr - > a_value ) ;
} else if ( ! strcasecmp ( attr - > a_name , " T38FaxUdpEC " ) & & attr - > a_value ) {
t38_options - > T38FaxUdpEC = switch_core_session_strdup ( tech_pvt - > session , attr - > a_value ) ;
} else if ( ! strcasecmp ( attr - > a_name , " T38VendorInfo " ) & & attr - > a_value ) {
t38_options - > T38VendorInfo = switch_core_session_strdup ( tech_pvt - > session , attr - > a_value ) ;
}
}
switch_channel_set_variable ( tech_pvt - > channel , " has_t38 " , " true " ) ;
switch_channel_set_private ( tech_pvt - > channel , " t38_options " , t38_options ) ;
2010-07-22 14:37:21 -05:00
switch_channel_set_app_flag_key ( " T38 " , tech_pvt - > channel , CF_APP_T38 ) ;
2010-06-23 13:22:52 -05:00
2011-08-18 09:11:45 -05:00
switch_channel_execute_on ( tech_pvt - > channel , " sip_execute_on_image " ) ;
switch_channel_api_on ( tech_pvt - > channel , " sip_api_on_image " ) ;
2011-02-28 12:43:05 -06:00
2010-05-26 20:12:54 -05:00
return t38_options ;
}
2010-09-29 14:14:41 -05:00
switch_status_t sofia_glue_sdp_map ( const char * r_sdp , switch_event_t * * fmtp , switch_event_t * * pt )
{
sdp_media_t * m ;
sdp_parser_t * parser = NULL ;
sdp_session_t * sdp ;
if ( ! ( parser = sdp_parse ( NULL , r_sdp , ( int ) strlen ( r_sdp ) , 0 ) ) ) {
return SWITCH_STATUS_FALSE ;
}
if ( ! ( sdp = sdp_session ( parser ) ) ) {
sdp_parser_free ( parser ) ;
return SWITCH_STATUS_FALSE ;
}
switch_event_create ( & ( * fmtp ) , SWITCH_EVENT_REQUEST_PARAMS ) ;
switch_event_create ( & ( * pt ) , SWITCH_EVENT_REQUEST_PARAMS ) ;
for ( m = sdp - > sdp_media ; m ; m = m - > m_next ) {
if ( m - > m_proto = = sdp_proto_rtp ) {
sdp_rtpmap_t * map ;
for ( map = m - > m_rtpmaps ; map ; map = map - > rm_next ) {
if ( map - > rm_encoding ) {
char buf [ 25 ] = " " ;
2010-09-29 16:52:34 -05:00
char key [ 128 ] = " " ;
char * br = NULL ;
if ( map - > rm_fmtp ) {
if ( ( br = strstr ( map - > rm_fmtp , " bitrate= " ) ) ) {
br + = 8 ;
}
}
2010-09-29 14:14:41 -05:00
switch_snprintf ( buf , sizeof ( buf ) , " %d " , map - > rm_pt ) ;
2010-09-29 16:52:34 -05:00
if ( br ) {
switch_snprintf ( key , sizeof ( key ) , " %s:%s " , map - > rm_encoding , br ) ;
} else {
switch_snprintf ( key , sizeof ( key ) , " %s " , map - > rm_encoding ) ;
}
2010-09-29 14:14:41 -05:00
2010-09-29 16:52:34 -05:00
switch_event_add_header_string ( * pt , SWITCH_STACK_BOTTOM , key , buf ) ;
2010-09-29 14:14:41 -05:00
if ( map - > rm_fmtp ) {
2010-09-29 16:52:34 -05:00
switch_event_add_header_string ( * fmtp , SWITCH_STACK_BOTTOM , key , map - > rm_fmtp ) ;
2010-09-29 14:14:41 -05:00
}
}
}
}
}
sdp_parser_free ( parser ) ;
return SWITCH_STATUS_SUCCESS ;
}
void sofia_glue_proxy_codec ( switch_core_session_t * session , const char * r_sdp )
{
sdp_media_t * m ;
sdp_parser_t * parser = NULL ;
sdp_session_t * sdp ;
private_object_t * tech_pvt = switch_core_session_get_private ( session ) ;
sdp_attribute_t * attr ;
2011-04-22 16:43:29 -05:00
int ptime = 0 , dptime = 0 ;
2010-09-29 14:14:41 -05:00
if ( ! ( parser = sdp_parse ( NULL , r_sdp , ( int ) strlen ( r_sdp ) , 0 ) ) ) {
return ;
}
if ( ! ( sdp = sdp_session ( parser ) ) ) {
sdp_parser_free ( parser ) ;
return ;
}
switch_assert ( tech_pvt ! = NULL ) ;
for ( attr = sdp - > sdp_attributes ; attr ; attr = attr - > a_next ) {
if ( zstr ( attr - > a_name ) ) {
continue ;
}
if ( ! strcasecmp ( attr - > a_name , " ptime " ) ) {
dptime = atoi ( attr - > a_value ) ;
}
}
for ( m = sdp - > sdp_media ; m ; m = m - > m_next ) {
ptime = dptime ;
2011-04-22 16:43:29 -05:00
//maxptime = dmaxptime;
2010-09-29 14:14:41 -05:00
if ( m - > m_proto = = sdp_proto_rtp ) {
sdp_rtpmap_t * map ;
for ( attr = m - > m_attributes ; attr ; attr = attr - > a_next ) {
if ( ! strcasecmp ( attr - > a_name , " ptime " ) & & attr - > a_value ) {
ptime = atoi ( attr - > a_value ) ;
} else if ( ! strcasecmp ( attr - > a_name , " maxptime " ) & & attr - > a_value ) {
2011-04-22 16:43:29 -05:00
//maxptime = atoi(attr->a_value);
2010-09-29 14:14:41 -05:00
}
}
for ( map = m - > m_rtpmaps ; map ; map = map - > rm_next ) {
tech_pvt - > iananame = switch_core_session_strdup ( tech_pvt - > session , map - > rm_encoding ) ;
tech_pvt - > rm_rate = map - > rm_rate ;
tech_pvt - > codec_ms = ptime ;
sofia_glue_tech_set_codec ( tech_pvt , 0 ) ;
break ;
}
break ;
}
}
sdp_parser_free ( parser ) ;
}
2010-05-26 20:12:54 -05:00
switch_t38_options_t * sofia_glue_extract_t38_options ( switch_core_session_t * session , const char * r_sdp )
{
sdp_media_t * m ;
sdp_parser_t * parser = NULL ;
sdp_session_t * sdp ;
private_object_t * tech_pvt = switch_core_session_get_private ( session ) ;
switch_t38_options_t * t38_options = NULL ;
if ( ! ( parser = sdp_parse ( NULL , r_sdp , ( int ) strlen ( r_sdp ) , 0 ) ) ) {
return 0 ;
}
if ( ! ( sdp = sdp_session ( parser ) ) ) {
sdp_parser_free ( parser ) ;
return 0 ;
}
switch_assert ( tech_pvt ! = NULL ) ;
for ( m = sdp - > sdp_media ; m ; m = m - > m_next ) {
if ( m - > m_proto = = sdp_proto_udptl & & m - > m_type = = sdp_media_image & & m - > m_port ) {
t38_options = tech_process_udptl ( tech_pvt , sdp , m ) ;
break ;
}
}
2010-06-23 13:22:52 -05:00
2010-05-26 20:12:54 -05:00
sdp_parser_free ( parser ) ;
return t38_options ;
}
2011-02-15 16:09:48 -06:00
switch_status_t sofia_glue_get_offered_pt ( private_object_t * tech_pvt , const switch_codec_implementation_t * mimp , switch_payload_t * pt )
{
int i = 0 ;
for ( i = 0 ; i < tech_pvt - > num_codecs ; i + + ) {
const switch_codec_implementation_t * imp = tech_pvt - > codecs [ i ] ;
if ( ! strcasecmp ( imp - > iananame , mimp - > iananame ) ) {
* pt = tech_pvt - > ianacodes [ i ] ;
return SWITCH_STATUS_SUCCESS ;
}
}
return SWITCH_STATUS_FALSE ;
}
2010-05-26 20:12:54 -05:00
uint8_t sofia_glue_negotiate_sdp ( switch_core_session_t * session , const char * r_sdp )
2008-09-18 21:50:18 +00:00
{
uint8_t match = 0 ;
2010-07-05 14:26:38 -05:00
switch_payload_t best_te = 0 , te = 0 , cng_pt = 0 ;
2008-09-18 21:50:18 +00:00
private_object_t * tech_pvt = switch_core_session_get_private ( session ) ;
sdp_media_t * m ;
sdp_attribute_t * attr ;
int first = 0 , last = 0 ;
2009-01-09 15:34:34 +00:00
int ptime = 0 , dptime = 0 , maxptime = 0 , dmaxptime = 0 ;
2011-01-14 18:42:38 -06:00
int sendonly = 0 , recvonly = 0 ;
2008-09-18 21:50:18 +00:00
int greedy = 0 , x = 0 , skip = 0 , mine = 0 ;
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
const char * val ;
const char * crypto = NULL ;
2008-12-30 19:50:33 +00:00
int got_crypto = 0 , got_audio = 0 , got_avp = 0 , got_savp = 0 , got_udptl = 0 ;
2009-02-11 17:43:00 +00:00
int scrooge = 0 ;
2010-05-26 20:12:54 -05:00
sdp_parser_t * parser = NULL ;
sdp_session_t * sdp ;
2011-03-08 10:37:16 -06:00
int reneg = 1 ;
const switch_codec_implementation_t * * codec_array ;
int total_codecs ;
codec_array = tech_pvt - > codecs ;
total_codecs = tech_pvt - > num_codecs ;
2010-06-23 13:22:52 -05:00
2010-05-26 20:12:54 -05:00
if ( ! ( parser = sdp_parse ( NULL , r_sdp , ( int ) strlen ( r_sdp ) , 0 ) ) ) {
return 0 ;
}
if ( ! ( sdp = sdp_session ( parser ) ) ) {
sdp_parser_free ( parser ) ;
return 0 ;
}
2008-09-18 21:50:18 +00:00
switch_assert ( tech_pvt ! = NULL ) ;
2009-02-09 17:56:38 +00:00
greedy = ! ! sofia_test_pflag ( tech_pvt - > profile , PFLAG_GREEDY ) ;
2009-02-11 17:43:00 +00:00
scrooge = ! ! sofia_test_pflag ( tech_pvt - > profile , PFLAG_SCROOGE ) ;
2010-02-06 03:38:24 +00:00
2011-02-03 10:19:04 -06:00
if ( ( val = switch_channel_get_variable ( channel , " sip_codec_negotiation " ) ) ) {
if ( ! strcasecmp ( val , " generous " ) ) {
greedy = 0 ;
scrooge = 0 ;
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " sip_codec_negotiation overriding sofia inbound-codec-negotiation : generous \n " ) ;
} else if ( ! strcasecmp ( val , " greedy " ) ) {
greedy = 1 ;
scrooge = 0 ;
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " sip_codec_negotiation overriding sofia inbound-codec-negotiation : greedy \n " ) ;
} else if ( ! strcasecmp ( val , " scrooge " ) ) {
scrooge = 1 ;
greedy = 1 ;
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " sip_codec_negotiation overriding sofia inbound-codec-negotiation : scrooge \n " ) ;
} else {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " sip_codec_negotiation ignored invalid value : '%s' \n " , val ) ;
}
2008-09-18 21:50:18 +00:00
}
if ( ( tech_pvt - > origin = switch_core_session_strdup ( session , ( char * ) sdp - > sdp_origin - > o_username ) ) ) {
2009-01-12 19:36:04 +00:00
if ( tech_pvt - > profile - > auto_rtp_bugs & RTP_BUG_CISCO_SKIP_MARK_BIT_2833 ) {
if ( strstr ( tech_pvt - > origin , " CiscoSystemsSIP-GW-UserAgent " ) ) {
tech_pvt - > rtp_bugs | = RTP_BUG_CISCO_SKIP_MARK_BIT_2833 ;
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Activate Buggy RFC2833 Mode! \n " ) ;
2009-01-12 19:36:04 +00:00
}
}
2010-02-06 03:38:24 +00:00
2009-01-12 19:36:04 +00:00
if ( tech_pvt - > profile - > auto_rtp_bugs & RTP_BUG_SONUS_SEND_INVALID_TIMESTAMP_2833 ) {
if ( strstr ( tech_pvt - > origin , " Sonus_UAC " ) ) {
tech_pvt - > rtp_bugs | = RTP_BUG_SONUS_SEND_INVALID_TIMESTAMP_2833 ;
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING ,
2009-01-12 19:36:04 +00:00
" Hello, \n I see you have a Sonus! \n "
" FYI, Sonus cannot follow the RFC on the proper way to send DTMF. \n "
" Sadly, my creator had to spend several hours figuring this out so I thought you'd like to know that! \n "
2010-02-06 03:38:24 +00:00
" Don't worry, DTMF will work but you may want to ask them to fix it...... \n " ) ;
2009-01-12 19:36:04 +00:00
}
2008-12-12 22:34:41 +00:00
}
2008-09-18 21:50:18 +00:00
}
2011-09-08 10:24:05 -05:00
if ( ( m = sdp - > sdp_media ) & &
( m - > m_mode = = sdp_sendonly | | m - > m_mode = = sdp_inactive | |
( m - > m_connections & & m - > m_connections - > c_address & & ! strcmp ( m - > m_connections - > c_address , " 0.0.0.0 " ) ) ) ) {
2008-09-18 21:50:18 +00:00
sendonly = 2 ; /* global sendonly always wins */
}
for ( attr = sdp - > sdp_attributes ; attr ; attr = attr - > a_next ) {
2009-10-23 16:03:42 +00:00
if ( zstr ( attr - > a_name ) ) {
2008-09-18 21:50:18 +00:00
continue ;
}
if ( ! strcasecmp ( attr - > a_name , " sendonly " ) | | ! strcasecmp ( attr - > a_name , " inactive " ) ) {
sendonly = 1 ;
2011-01-14 18:42:38 -06:00
switch_channel_set_variable ( tech_pvt - > channel , " media_audio_mode " , " recvonly " ) ;
2011-01-14 17:42:31 -06:00
} else if ( ! strcasecmp ( attr - > a_name , " recvonly " ) ) {
2011-01-14 18:42:38 -06:00
switch_channel_set_variable ( tech_pvt - > channel , " media_audio_mode " , " sendonly " ) ;
recvonly = 1 ;
2011-01-14 17:42:31 -06:00
if ( switch_rtp_ready ( tech_pvt - > rtp_session ) ) {
switch_rtp_set_max_missed_packets ( tech_pvt - > rtp_session , 0 ) ;
tech_pvt - > max_missed_hold_packets = 0 ;
tech_pvt - > max_missed_packets = 0 ;
} else {
switch_channel_set_variable ( tech_pvt - > channel , " rtp_timeout_sec " , " 0 " ) ;
switch_channel_set_variable ( tech_pvt - > channel , " rtp_hold_timeout_sec " , " 0 " ) ;
}
2008-09-18 21:50:18 +00:00
} else if ( sendonly < 2 & & ! strcasecmp ( attr - > a_name , " sendrecv " ) ) {
sendonly = 0 ;
} else if ( ! strcasecmp ( attr - > a_name , " ptime " ) ) {
dptime = atoi ( attr - > a_value ) ;
2009-01-09 15:34:34 +00:00
} else if ( ! strcasecmp ( attr - > a_name , " maxptime " ) ) {
dmaxptime = atoi ( attr - > a_value ) ;
2008-09-18 21:50:18 +00:00
}
}
2011-01-14 18:42:38 -06:00
if ( sendonly ! = 1 & & recvonly ! = 1 ) {
switch_channel_set_variable ( tech_pvt - > channel , " media_audio_mode " , NULL ) ;
}
2010-05-03 16:57:17 -04:00
if ( sofia_test_pflag ( tech_pvt - > profile , PFLAG_DISABLE_HOLD ) | |
2010-04-30 19:14:39 -05:00
( ( val = switch_channel_get_variable ( tech_pvt - > channel , " sip_disable_hold " ) ) & & switch_true ( val ) ) ) {
sendonly = 0 ;
2010-09-13 10:57:52 -05:00
} else {
2010-04-30 19:14:39 -05:00
2010-09-13 10:57:52 -05:00
if ( ! tech_pvt - > hold_laps ) {
tech_pvt - > hold_laps + + ;
2011-03-07 13:02:21 -06:00
if ( sofia_glue_toggle_hold ( tech_pvt , sendonly ) ) {
2011-03-08 10:37:16 -06:00
reneg = sofia_test_pflag ( tech_pvt - > profile , PFLAG_RENEG_ON_HOLD ) ;
2011-03-07 13:02:21 -06:00
if ( ( val = switch_channel_get_variable ( tech_pvt - > channel , " sip_renegotiate_codec_on_hold " ) ) ) {
reneg = switch_true ( val ) ;
}
}
2010-09-13 10:57:52 -05:00
}
2008-09-18 21:50:18 +00:00
}
2007-06-24 03:17:21 +00:00
2011-03-10 00:18:06 -06:00
if ( reneg ) {
reneg = sofia_test_pflag ( tech_pvt - > profile , PFLAG_RENEG_ON_REINVITE ) ;
if ( ( val = switch_channel_get_variable ( tech_pvt - > channel , " sip_renegotiate_codec_on_reinvite " ) ) ) {
reneg = switch_true ( val ) ;
}
}
if ( ! reneg & & tech_pvt - > num_negotiated_codecs ) {
2011-03-08 10:37:16 -06:00
codec_array = tech_pvt - > negotiated_codecs ;
total_codecs = tech_pvt - > num_negotiated_codecs ;
}
2011-09-19 20:11:23 -05:00
if ( switch_stristr ( " T38FaxFillBitRemoval: " , r_sdp ) | | switch_stristr ( " T38FaxTranscodingMMR: " , r_sdp ) | |
switch_stristr ( " T38FaxTranscodingJBIG: " , r_sdp ) ) {
switch_channel_set_variable ( tech_pvt - > channel , " t38_broken_boolean " , " true " ) ;
}
2007-03-31 19:01:33 +00:00
for ( m = sdp - > sdp_media ; m ; m = m - > m_next ) {
sdp_connection_t * connection ;
2010-05-26 20:12:54 -05:00
switch_core_session_t * other_session ;
2007-03-31 19:01:33 +00:00
ptime = dptime ;
2009-01-09 15:34:34 +00:00
maxptime = dmaxptime ;
2007-04-19 21:40:50 +00:00
2008-02-26 21:13:47 +00:00
if ( m - > m_proto = = sdp_proto_srtp ) {
got_savp + + ;
} else if ( m - > m_proto = = sdp_proto_rtp ) {
got_avp + + ;
2008-12-30 19:50:33 +00:00
} else if ( m - > m_proto = = sdp_proto_udptl ) {
got_udptl + + ;
2008-02-26 21:13:47 +00:00
}
2008-12-30 19:50:33 +00:00
if ( got_udptl & & m - > m_type = = sdp_media_image & & m - > m_port ) {
2010-05-26 20:12:54 -05:00
switch_t38_options_t * t38_options = tech_process_udptl ( tech_pvt , sdp , m ) ;
2011-06-09 10:22:40 -05:00
2011-09-21 14:56:49 -05:00
if ( switch_channel_test_app_flag_key ( " T38 " , tech_pvt - > channel , CF_APP_T38_NEGOTIATED ) ) {
match = 1 ;
goto done ;
}
2011-06-09 10:22:40 -05:00
if ( switch_channel_test_app_flag_key ( " T38 " , tech_pvt - > channel , CF_APP_T38 ) ) {
sofia_set_flag ( tech_pvt , TFLAG_NOREPLY ) ;
}
2010-09-21 19:22:20 -05:00
2010-05-26 20:12:54 -05:00
if ( switch_true ( switch_channel_get_variable ( channel , " refuse_t38 " ) ) ) {
2011-06-08 18:50:21 -05:00
switch_channel_clear_app_flag_key ( " T38 " , tech_pvt - > channel , CF_APP_T38 ) ;
2010-05-26 20:12:54 -05:00
match = 0 ;
goto done ;
} else {
const char * var = switch_channel_get_variable ( channel , " t38_passthru " ) ;
int pass = sofia_test_pflag ( tech_pvt - > profile , PFLAG_T38_PASSTHRU ) ;
2010-05-12 21:25:54 -05:00
2010-05-26 20:12:54 -05:00
if ( var ) {
pass = switch_true ( var ) ;
}
2010-06-23 13:22:52 -05:00
2011-09-23 08:20:53 -05:00
/* can't remember if this is necessary but its causing a bug so i'll leave this comment here to remind me
2010-05-26 20:12:54 -05:00
if ( sofia_test_flag ( tech_pvt , TFLAG_T38_PASSTHRU ) ) {
pass = 0 ;
}
2011-09-23 08:20:53 -05:00
*/
2010-09-27 13:09:03 -05:00
if ( switch_channel_test_flag ( tech_pvt - > channel , CF_PROXY_MODE ) | |
switch_channel_test_flag ( tech_pvt - > channel , CF_PROXY_MEDIA ) | | ! switch_rtp_ready ( tech_pvt - > rtp_session ) ) {
pass = 0 ;
}
2010-05-26 20:12:54 -05:00
if ( pass & & switch_core_session_get_partner ( session , & other_session ) = = SWITCH_STATUS_SUCCESS ) {
private_object_t * other_tech_pvt = switch_core_session_get_private ( other_session ) ;
2011-10-12 15:28:08 -05:00
switch_channel_t * other_channel = switch_core_session_get_channel ( other_session ) ;
2010-05-26 20:12:54 -05:00
switch_core_session_message_t * msg ;
2010-09-21 19:22:20 -05:00
char * remote_host = switch_rtp_get_remote_host ( tech_pvt - > rtp_session ) ;
switch_port_t remote_port = switch_rtp_get_remote_port ( tech_pvt - > rtp_session ) ;
char tmp [ 32 ] = " " ;
2011-10-12 15:28:08 -05:00
if ( switch_true ( switch_channel_get_variable ( tech_pvt - > channel , " t38_broken_boolean " ) ) & &
switch_true ( switch_channel_get_variable ( tech_pvt - > channel , " t38_pass_broken_boolean " ) ) ) {
switch_channel_set_variable ( other_channel , " t38_broken_boolean " , " true " ) ;
}
2010-09-21 19:22:20 -05:00
tech_pvt - > remote_sdp_audio_ip = switch_core_session_strdup ( tech_pvt - > session , t38_options - > remote_ip ) ;
tech_pvt - > remote_sdp_audio_port = t38_options - > remote_port ;
if ( remote_host & & remote_port & & ! strcmp ( remote_host , tech_pvt - > remote_sdp_audio_ip ) & & remote_port = = tech_pvt - > remote_sdp_audio_port ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_DEBUG , " Audio params are unchanged for %s. \n " ,
switch_channel_get_name ( tech_pvt - > channel ) ) ;
} else {
const char * err = NULL ;
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_DEBUG , " Audio params changed for %s from %s:%d to %s:%d \n " ,
switch_channel_get_name ( tech_pvt - > channel ) ,
remote_host , remote_port , tech_pvt - > remote_sdp_audio_ip , tech_pvt - > remote_sdp_audio_port ) ;
switch_snprintf ( tmp , sizeof ( tmp ) , " %d " , tech_pvt - > remote_sdp_audio_port ) ;
switch_channel_set_variable ( tech_pvt - > channel , SWITCH_REMOTE_MEDIA_IP_VARIABLE , tech_pvt - > remote_sdp_audio_ip ) ;
switch_channel_set_variable ( tech_pvt - > channel , SWITCH_REMOTE_MEDIA_PORT_VARIABLE , tmp ) ;
if ( switch_rtp_set_remote_address ( tech_pvt - > rtp_session , tech_pvt - > remote_sdp_audio_ip ,
tech_pvt - > remote_sdp_audio_port , 0 , SWITCH_TRUE , & err ) ! = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_ERROR , " AUDIO RTP REPORTS ERROR: [%s] \n " , err ) ;
switch_channel_hangup ( channel , SWITCH_CAUSE_INCOMPATIBLE_DESTINATION ) ;
}
}
2011-10-12 15:28:08 -05:00
2010-09-21 19:22:20 -05:00
2010-05-26 20:12:54 -05:00
sofia_glue_copy_t38_options ( t38_options , other_session ) ;
2010-06-23 13:22:52 -05:00
2010-05-26 20:12:54 -05:00
sofia_set_flag ( tech_pvt , TFLAG_T38_PASSTHRU ) ;
sofia_set_flag ( other_tech_pvt , TFLAG_T38_PASSTHRU ) ;
2010-06-23 13:22:52 -05:00
2010-05-26 20:12:54 -05:00
msg = switch_core_session_alloc ( other_session , sizeof ( * msg ) ) ;
msg - > message_id = SWITCH_MESSAGE_INDICATE_REQUEST_IMAGE_MEDIA ;
msg - > from = __FILE__ ;
msg - > string_arg = switch_core_session_strdup ( other_session , r_sdp ) ;
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Passing T38 req to other leg. \n %s \n " , r_sdp ) ;
switch_core_session_queue_message ( other_session , msg ) ;
switch_core_session_rwunlock ( other_session ) ;
2008-12-30 19:50:33 +00:00
}
}
2010-05-26 20:12:54 -05:00
2010-06-23 13:22:52 -05:00
/* do nothing here, mod_fax will trigger a response (if it's listening =/) */
2010-05-12 21:25:54 -05:00
match = 1 ;
goto done ;
2008-12-30 19:50:33 +00:00
} else if ( m - > m_type = = sdp_media_audio & & m - > m_port & & ! got_audio ) {
2007-03-31 19:01:33 +00:00
sdp_rtpmap_t * map ;
2011-03-08 10:37:16 -06:00
2008-01-17 06:23:23 +00:00
for ( attr = m - > m_attributes ; attr ; attr = attr - > a_next ) {
2010-06-23 13:22:52 -05:00
2010-04-20 16:15:37 -05:00
if ( ! strcasecmp ( attr - > a_name , " rtcp " ) & & attr - > a_value ) {
switch_channel_set_variable ( tech_pvt - > channel , " sip_remote_audio_rtcp_port " , attr - > a_value ) ;
}
2008-01-17 06:23:23 +00:00
if ( ! strcasecmp ( attr - > a_name , " ptime " ) & & attr - > a_value ) {
ptime = atoi ( attr - > a_value ) ;
2009-01-09 15:34:34 +00:00
} else if ( ! strcasecmp ( attr - > a_name , " maxptime " ) & & attr - > a_value ) {
maxptime = atoi ( attr - > a_value ) ;
2009-10-23 16:03:42 +00:00
} else if ( ! got_crypto & & ! strcasecmp ( attr - > a_name , " crypto " ) & & ! zstr ( attr - > a_value ) ) {
2008-01-17 06:23:23 +00:00
int crypto_tag ;
2008-09-27 21:05:18 +00:00
if ( m - > m_proto ! = sdp_proto_srtp ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " a=crypto in RTP/AVP, refer to rfc3711 \n " ) ;
2008-09-27 21:05:18 +00:00
match = 0 ;
2008-09-27 21:41:09 +00:00
goto done ;
2008-09-27 21:05:18 +00:00
}
2008-01-17 06:23:23 +00:00
crypto = attr - > a_value ;
crypto_tag = atoi ( crypto ) ;
2008-01-17 04:16:04 +00:00
2008-01-17 21:59:35 +00:00
if ( tech_pvt - > remote_crypto_key & & switch_rtp_ready ( tech_pvt - > rtp_session ) ) {
2008-01-16 21:28:20 +00:00
if ( crypto_tag & & crypto_tag = = tech_pvt - > crypto_tag ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Existing key is still valid. \n " ) ;
2008-01-16 21:28:20 +00:00
} else {
2008-01-17 04:16:04 +00:00
const char * a = switch_stristr ( " AES " , tech_pvt - > remote_crypto_key ) ;
const char * b = switch_stristr ( " AES " , crypto ) ;
2008-01-29 22:14:59 +00:00
2009-05-14 00:15:06 +00:00
/* Change our key every time we can */
if ( switch_stristr ( SWITCH_RTP_CRYPTO_KEY_32 , crypto ) ) {
switch_channel_set_variable ( tech_pvt - > channel , SOFIA_HAS_CRYPTO_VARIABLE , SWITCH_RTP_CRYPTO_KEY_32 ) ;
sofia_glue_build_crypto ( tech_pvt , atoi ( crypto ) , AES_CM_128_HMAC_SHA1_32 , SWITCH_RTP_CRYPTO_SEND ) ;
switch_rtp_add_crypto_key ( tech_pvt - > rtp_session , SWITCH_RTP_CRYPTO_SEND , atoi ( crypto ) , tech_pvt - > crypto_type ,
tech_pvt - > local_raw_key , SWITCH_RTP_KEY_LEN ) ;
} else if ( switch_stristr ( SWITCH_RTP_CRYPTO_KEY_80 , crypto ) ) {
switch_channel_set_variable ( tech_pvt - > channel , SOFIA_HAS_CRYPTO_VARIABLE , SWITCH_RTP_CRYPTO_KEY_80 ) ;
sofia_glue_build_crypto ( tech_pvt , atoi ( crypto ) , AES_CM_128_HMAC_SHA1_80 , SWITCH_RTP_CRYPTO_SEND ) ;
switch_rtp_add_crypto_key ( tech_pvt - > rtp_session , SWITCH_RTP_CRYPTO_SEND , atoi ( crypto ) , tech_pvt - > crypto_type ,
tech_pvt - > local_raw_key , SWITCH_RTP_KEY_LEN ) ;
} else {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Crypto Setup Failed!. \n " ) ;
2009-05-14 00:15:06 +00:00
}
2010-02-06 03:38:24 +00:00
2008-01-29 22:14:59 +00:00
if ( a & & b & & ! strncasecmp ( a , b , 23 ) ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Change Remote key to [%s] \n " , crypto ) ;
2008-01-17 04:16:04 +00:00
tech_pvt - > remote_crypto_key = switch_core_session_strdup ( tech_pvt - > session , crypto ) ;
tech_pvt - > crypto_tag = crypto_tag ;
2010-02-06 03:38:24 +00:00
2009-02-09 17:56:38 +00:00
if ( switch_rtp_ready ( tech_pvt - > rtp_session ) & & sofia_test_flag ( tech_pvt , TFLAG_SECURE ) ) {
2008-01-17 21:59:35 +00:00
sofia_glue_add_crypto ( tech_pvt , tech_pvt - > remote_crypto_key , SWITCH_RTP_CRYPTO_RECV ) ;
2008-05-27 04:54:52 +00:00
switch_rtp_add_crypto_key ( tech_pvt - > rtp_session , SWITCH_RTP_CRYPTO_RECV , tech_pvt - > crypto_tag ,
2008-01-17 21:59:35 +00:00
tech_pvt - > crypto_type , tech_pvt - > remote_raw_key , SWITCH_RTP_KEY_LEN ) ;
}
2008-01-17 04:16:04 +00:00
got_crypto + + ;
} else {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Ignoring unacceptable key \n " ) ;
2008-01-17 04:16:04 +00:00
}
2008-01-16 21:28:20 +00:00
}
2008-01-17 22:57:17 +00:00
} else if ( ! switch_rtp_ready ( tech_pvt - > rtp_session ) ) {
2008-01-16 06:01:53 +00:00
tech_pvt - > remote_crypto_key = switch_core_session_strdup ( tech_pvt - > session , crypto ) ;
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Set Remote Key [%s] \n " , tech_pvt - > remote_crypto_key ) ;
2008-01-16 21:28:20 +00:00
tech_pvt - > crypto_tag = crypto_tag ;
2008-01-17 04:16:04 +00:00
got_crypto + + ;
2008-05-27 04:54:52 +00:00
2009-10-23 16:03:42 +00:00
if ( zstr ( tech_pvt - > local_crypto_key ) ) {
2008-01-16 06:01:53 +00:00
if ( switch_stristr ( SWITCH_RTP_CRYPTO_KEY_32 , crypto ) ) {
switch_channel_set_variable ( tech_pvt - > channel , SOFIA_HAS_CRYPTO_VARIABLE , SWITCH_RTP_CRYPTO_KEY_32 ) ;
sofia_glue_build_crypto ( tech_pvt , atoi ( crypto ) , AES_CM_128_HMAC_SHA1_32 , SWITCH_RTP_CRYPTO_SEND ) ;
} else if ( switch_stristr ( SWITCH_RTP_CRYPTO_KEY_80 , crypto ) ) {
switch_channel_set_variable ( tech_pvt - > channel , SOFIA_HAS_CRYPTO_VARIABLE , SWITCH_RTP_CRYPTO_KEY_80 ) ;
sofia_glue_build_crypto ( tech_pvt , atoi ( crypto ) , AES_CM_128_HMAC_SHA1_80 , SWITCH_RTP_CRYPTO_SEND ) ;
} else {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Crypto Setup Failed!. \n " ) ;
2008-01-16 06:01:53 +00:00
}
}
}
2007-04-19 21:40:50 +00:00
}
}
2008-02-26 21:13:47 +00:00
if ( got_crypto & & ! got_avp ) {
switch_channel_set_variable ( tech_pvt - > channel , SOFIA_CRYPTO_MANDATORY_VARIABLE , " true " ) ;
switch_channel_set_variable ( tech_pvt - > channel , SOFIA_SECURE_MEDIA_VARIABLE , " true " ) ;
}
2007-03-31 19:01:33 +00:00
connection = sdp - > sdp_connection ;
if ( m - > m_connections ) {
connection = m - > m_connections ;
}
if ( ! connection ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Cannot find a c= line in the sdp at media or session level! \n " ) ;
2007-03-31 19:01:33 +00:00
match = 0 ;
break ;
}
2008-05-27 04:54:52 +00:00
2010-06-23 13:22:52 -05:00
greed :
2007-06-10 02:52:23 +00:00
x = 0 ;
2008-01-03 00:50:53 +00:00
2011-08-25 08:25:47 -05:00
if ( tech_pvt - > rm_encoding & & ! ( sofia_test_pflag ( tech_pvt - > profile , PFLAG_LIBERAL_DTMF ) | | sofia_test_flag ( tech_pvt , TFLAG_LIBERAL_DTMF ) ) ) { // && !sofia_test_flag(tech_pvt, TFLAG_REINVITE)) {
2009-10-21 23:01:37 +00:00
char * remote_host = tech_pvt - > remote_sdp_audio_ip ;
switch_port_t remote_port = tech_pvt - > remote_sdp_audio_port ;
int same = 0 ;
if ( switch_rtp_ready ( tech_pvt - > rtp_session ) ) {
remote_host = switch_rtp_get_remote_host ( tech_pvt - > rtp_session ) ;
remote_port = switch_rtp_get_remote_port ( tech_pvt - > rtp_session ) ;
}
2010-02-06 03:38:24 +00:00
2008-01-03 00:50:53 +00:00
for ( map = m - > m_rtpmaps ; map ; map = map - > rm_next ) {
2009-11-03 21:32:18 +00:00
if ( ( zstr ( map - > rm_encoding ) | | ( tech_pvt - > profile - > ndlb & PFLAG_NDLB_ALLOW_BAD_IANANAME ) ) & & map - > rm_pt < 96 ) {
2008-01-03 00:50:53 +00:00
match = ( map - > rm_pt = = tech_pvt - > pt ) ? 1 : 0 ;
} else {
match = strcasecmp ( switch_str_nil ( map - > rm_encoding ) , tech_pvt - > iananame ) ? 0 : 1 ;
}
2008-05-27 04:54:52 +00:00
2010-02-06 03:38:24 +00:00
if ( match & & connection - > c_address & & remote_host & & ! strcmp ( connection - > c_address , remote_host ) & & m - > m_port = = remote_port ) {
2009-10-21 23:01:37 +00:00
same = 1 ;
} else {
same = 0 ;
2008-05-27 04:54:52 +00:00
break ;
2008-01-03 00:50:53 +00:00
}
}
2009-10-21 23:01:37 +00:00
if ( same ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG ,
2009-10-21 23:01:37 +00:00
" Our existing sdp is still good [%s %s:%d], let's keep it. \n " ,
tech_pvt - > rm_encoding , tech_pvt - > remote_sdp_audio_ip , tech_pvt - > remote_sdp_audio_port ) ;
got_audio = 1 ;
} else {
match = 0 ;
got_audio = 0 ;
}
}
2010-02-06 03:38:24 +00:00
2007-03-31 19:01:33 +00:00
for ( map = m - > m_rtpmaps ; map ; map = map - > rm_next ) {
int32_t i ;
2008-03-27 20:36:03 +00:00
uint32_t near_rate = 0 ;
2007-03-31 19:01:33 +00:00
const switch_codec_implementation_t * mimp = NULL , * near_match = NULL ;
const char * rm_encoding ;
2010-09-29 16:52:34 -05:00
uint32_t map_bit_rate = 0 ;
int codec_ms = 0 ;
2010-10-01 12:22:06 -05:00
switch_codec_fmtp_t codec_fmtp = { 0 } ;
2008-05-27 04:54:52 +00:00
2007-06-10 02:52:23 +00:00
if ( x + + < skip ) {
continue ;
}
2007-03-31 19:01:33 +00:00
if ( ! ( rm_encoding = map - > rm_encoding ) ) {
rm_encoding = " " ;
}
2008-05-27 04:54:52 +00:00
2010-07-05 14:26:38 -05:00
if ( ! strcasecmp ( rm_encoding , " telephone-event " ) ) {
if ( ! best_te | | map - > rm_rate = = tech_pvt - > rm_rate ) {
best_te = ( switch_payload_t ) map - > rm_pt ;
2007-03-31 19:01:33 +00:00
}
}
2010-07-05 14:26:38 -05:00
2009-02-09 17:56:38 +00:00
if ( ! sofia_test_pflag ( tech_pvt - > profile , PFLAG_SUPPRESS_CNG ) & & ! cng_pt & & ! strcasecmp ( rm_encoding , " CN " ) ) {
2008-10-23 22:05:00 +00:00
cng_pt = ( switch_payload_t ) map - > rm_pt ;
2007-03-31 19:01:33 +00:00
if ( tech_pvt - > rtp_session ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Set comfort noise payload to %u \n " , cng_pt ) ;
2007-03-31 19:01:33 +00:00
switch_rtp_set_cng_pt ( tech_pvt - > rtp_session , tech_pvt - > cng_pt ) ;
}
}
2008-05-27 04:54:52 +00:00
2007-03-31 19:01:33 +00:00
if ( match ) {
continue ;
}
2008-05-27 04:54:52 +00:00
2007-06-10 02:52:23 +00:00
if ( greedy ) {
first = mine ;
last = first + 1 ;
} else {
2008-05-27 04:54:52 +00:00
first = 0 ;
last = tech_pvt - > num_codecs ;
2007-06-10 02:52:23 +00:00
}
2010-02-06 03:38:24 +00:00
2010-10-13 19:27:45 -05:00
codec_ms = ptime ;
if ( maxptime & & ( ! codec_ms | | codec_ms > maxptime ) ) {
codec_ms = maxptime ;
2009-01-09 15:34:34 +00:00
}
2007-03-31 19:01:33 +00:00
2010-10-13 19:27:45 -05:00
if ( ! codec_ms ) {
codec_ms = switch_default_ptime ( rm_encoding , map - > rm_pt ) ;
2009-12-08 00:05:40 +00:00
}
2011-05-29 09:46:02 -05:00
map_bit_rate = switch_known_bitrate ( ( switch_payload_t ) map - > rm_pt ) ;
2010-10-13 19:27:45 -05:00
if ( ! ptime & & ! strcasecmp ( map - > rm_encoding , " g723 " ) ) {
2010-10-15 17:53:38 -05:00
ptime = codec_ms = 30 ;
2010-10-13 19:27:45 -05:00
}
if ( zstr ( map - > rm_fmtp ) ) {
if ( ! strcasecmp ( map - > rm_encoding , " ilbc " ) ) {
2010-10-15 17:53:38 -05:00
ptime = codec_ms = 30 ;
2011-01-06 17:15:45 -06:00
map_bit_rate = 13330 ;
2010-10-13 19:27:45 -05:00
}
} else {
2010-10-01 12:22:06 -05:00
if ( ( switch_core_codec_parse_fmtp ( map - > rm_encoding , map - > rm_fmtp , map - > rm_rate , & codec_fmtp ) ) = = SWITCH_STATUS_SUCCESS ) {
if ( codec_fmtp . bits_per_second ) {
map_bit_rate = codec_fmtp . bits_per_second ;
}
if ( codec_fmtp . microseconds_per_packet ) {
2010-10-13 19:27:45 -05:00
codec_ms = ( codec_fmtp . microseconds_per_packet / 1000 ) ;
2010-10-01 12:22:06 -05:00
}
}
2010-09-29 16:52:34 -05:00
}
2010-03-04 17:16:19 +00:00
2011-03-08 10:37:16 -06:00
for ( i = first ; i < last & & i < total_codecs ; i + + ) {
const switch_codec_implementation_t * imp = codec_array [ i ] ;
2010-09-29 16:52:34 -05:00
uint32_t bit_rate = imp - > bits_per_second ;
2007-06-07 21:46:45 +00:00
uint32_t codec_rate = imp - > samples_per_second ;
2007-04-19 21:40:50 +00:00
if ( imp - > codec_type ! = SWITCH_CODEC_TYPE_AUDIO ) {
continue ;
}
2007-10-18 16:44:11 +00:00
2010-09-29 16:52:34 -05:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Audio Codec Compare [%s:%d:%u:%d:%u]/[%s:%d:%u:%d:%u] \n " ,
2011-01-06 17:15:45 -06:00
rm_encoding , map - > rm_pt , ( int ) map - > rm_rate , codec_ms , map_bit_rate ,
2010-09-29 16:52:34 -05:00
imp - > iananame , imp - > ianacode , codec_rate , imp - > microseconds_per_packet / 1000 , bit_rate ) ;
2009-11-03 21:32:18 +00:00
if ( ( zstr ( map - > rm_encoding ) | | ( tech_pvt - > profile - > ndlb & PFLAG_NDLB_ALLOW_BAD_IANANAME ) ) & & map - > rm_pt < 96 ) {
2007-03-31 19:01:33 +00:00
match = ( map - > rm_pt = = imp - > ianacode ) ? 1 : 0 ;
} else {
match = strcasecmp ( rm_encoding , imp - > iananame ) ? 0 : 1 ;
}
2008-05-27 04:54:52 +00:00
2011-02-03 16:27:22 -06:00
if ( match & & bit_rate & & map_bit_rate & & map_bit_rate ! = bit_rate & & strcasecmp ( map - > rm_encoding , " ilbc " ) ) {
2010-09-30 15:15:33 -05:00
/* nevermind */
match = 0 ;
}
2008-03-27 20:36:03 +00:00
if ( match ) {
2009-02-11 17:43:00 +00:00
if ( scrooge ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG ,
" Bah HUMBUG! Sticking with %s@%uh@%ui \n " ,
2009-02-11 17:43:00 +00:00
imp - > iananame , imp - > samples_per_second , imp - > microseconds_per_packet / 1000 ) ;
} else {
2010-10-13 19:27:45 -05:00
if ( ( ptime & & codec_ms & & codec_ms * 1000 ! = imp - > microseconds_per_packet ) | | map - > rm_rate ! = codec_rate ) {
2009-02-11 17:43:00 +00:00
near_rate = map - > rm_rate ;
near_match = imp ;
match = 0 ;
continue ;
}
2007-03-31 19:01:33 +00:00
}
mimp = imp ;
break ;
} else {
match = 0 ;
}
}
2008-05-27 04:54:52 +00:00
2010-09-30 15:15:33 -05:00
if ( ! match & & near_match ) {
2007-03-31 19:01:33 +00:00
const switch_codec_implementation_t * search [ 1 ] ;
char * prefs [ 1 ] ;
char tmp [ 80 ] ;
int num ;
2010-02-06 03:38:24 +00:00
2010-06-23 13:22:52 -05:00
switch_snprintf ( tmp , sizeof ( tmp ) , " %s@%uh@%ui " , near_match - > iananame , near_rate ? near_rate : near_match - > samples_per_second ,
codec_ms ) ;
2010-02-06 03:38:24 +00:00
2007-03-31 19:01:33 +00:00
prefs [ 0 ] = tmp ;
num = switch_loadable_module_get_codecs_sorted ( search , 1 , prefs , 1 ) ;
2010-02-06 03:38:24 +00:00
2007-03-31 19:01:33 +00:00
if ( num ) {
mimp = search [ 0 ] ;
} else {
mimp = near_match ;
}
2010-02-06 03:38:24 +00:00
2009-01-09 15:34:34 +00:00
if ( ! maxptime | | mimp - > microseconds_per_packet / 1000 < = maxptime ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Substituting codec %s@%ui@%uh \n " ,
2009-01-09 15:34:34 +00:00
mimp - > iananame , mimp - > microseconds_per_packet / 1000 , mimp - > samples_per_second ) ;
match = 1 ;
} else {
mimp = NULL ;
match = 0 ;
}
2010-02-06 03:38:24 +00:00
2007-03-31 19:01:33 +00:00
}
2008-02-21 02:27:27 +00:00
if ( ! match & & greedy ) {
skip + + ;
continue ;
}
2007-03-31 19:01:33 +00:00
if ( mimp ) {
2007-11-21 17:07:41 +00:00
char tmp [ 50 ] ;
tech_pvt - > rm_encoding = switch_core_session_strdup ( session , ( char * ) map - > rm_encoding ) ;
tech_pvt - > iananame = switch_core_session_strdup ( session , ( char * ) mimp - > iananame ) ;
tech_pvt - > pt = ( switch_payload_t ) map - > rm_pt ;
2010-10-27 16:37:22 -05:00
tech_pvt - > rm_rate = mimp - > samples_per_second ;
2010-03-04 17:16:19 +00:00
tech_pvt - > codec_ms = mimp - > microseconds_per_packet / 1000 ;
2010-09-29 16:52:34 -05:00
tech_pvt - > bitrate = mimp - > bits_per_second ;
2007-11-21 17:07:41 +00:00
tech_pvt - > remote_sdp_audio_ip = switch_core_session_strdup ( session , ( char * ) connection - > c_address ) ;
tech_pvt - > rm_fmtp = switch_core_session_strdup ( session , ( char * ) map - > rm_fmtp ) ;
tech_pvt - > remote_sdp_audio_port = ( switch_port_t ) m - > m_port ;
tech_pvt - > agreed_pt = ( switch_payload_t ) map - > rm_pt ;
2011-03-10 00:18:06 -06:00
tech_pvt - > num_negotiated_codecs = 0 ;
2011-03-08 10:37:16 -06:00
tech_pvt - > negotiated_codecs [ tech_pvt - > num_negotiated_codecs + + ] = mimp ;
2007-12-12 21:53:32 +00:00
switch_snprintf ( tmp , sizeof ( tmp ) , " %d " , tech_pvt - > remote_sdp_audio_port ) ;
2007-11-21 17:07:41 +00:00
switch_channel_set_variable ( tech_pvt - > channel , SWITCH_REMOTE_MEDIA_IP_VARIABLE , tech_pvt - > remote_sdp_audio_ip ) ;
switch_channel_set_variable ( tech_pvt - > channel , SWITCH_REMOTE_MEDIA_PORT_VARIABLE , tmp ) ;
2011-05-29 09:46:02 -05:00
tech_pvt - > audio_recv_pt = ( switch_payload_t ) map - > rm_pt ;
2011-02-15 16:09:48 -06:00
2011-03-07 12:15:46 -06:00
if ( switch_channel_direction ( channel ) = = SWITCH_CALL_DIRECTION_OUTBOUND & & ! sofia_test_flag ( tech_pvt , TFLAG_REINVITE ) ) {
2011-02-15 16:09:48 -06:00
sofia_glue_get_offered_pt ( tech_pvt , mimp , & tech_pvt - > audio_recv_pt ) ;
}
switch_snprintf ( tmp , sizeof ( tmp ) , " %d " , tech_pvt - > audio_recv_pt ) ;
switch_channel_set_variable ( tech_pvt - > channel , " sip_audio_recv_pt " , tmp ) ;
2007-03-31 19:01:33 +00:00
}
2011-02-15 16:09:48 -06:00
2007-03-31 19:01:33 +00:00
if ( match ) {
2010-10-13 19:27:45 -05:00
if ( sofia_glue_tech_set_codec ( tech_pvt , 1 ) = = SWITCH_STATUS_SUCCESS ) {
got_audio = 1 ;
} else {
2007-03-31 19:01:33 +00:00
match = 0 ;
}
}
}
2007-06-10 02:52:23 +00:00
2011-08-23 12:38:22 -05:00
if ( ! best_te & & ( sofia_test_pflag ( tech_pvt - > profile , PFLAG_LIBERAL_DTMF ) | | sofia_test_flag ( tech_pvt , TFLAG_LIBERAL_DTMF ) ) ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG ,
2011-08-25 08:25:47 -05:00
" No 2833 in SDP. Liberal DTMF mode adding %d as telephone-event. \n " , tech_pvt - > profile - > te ) ;
2011-08-23 12:38:22 -05:00
best_te = tech_pvt - > profile - > te ;
}
2010-07-05 14:26:38 -05:00
if ( best_te ) {
if ( switch_channel_direction ( channel ) = = SWITCH_CALL_DIRECTION_OUTBOUND ) {
te = tech_pvt - > te = ( switch_payload_t ) best_te ;
2010-07-05 16:48:07 -05:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Set 2833 dtmf send payload to %u \n " , best_te ) ;
2010-07-05 14:26:38 -05:00
if ( tech_pvt - > rtp_session ) {
switch_rtp_set_telephony_event ( tech_pvt - > rtp_session , ( switch_payload_t ) best_te ) ;
2011-09-16 14:30:32 -05:00
switch_channel_set_variable_printf ( tech_pvt - > channel , " sip_2833_send_payload " , " %d " , best_te ) ;
2010-07-05 14:26:38 -05:00
}
} else {
te = tech_pvt - > recv_te = tech_pvt - > te = ( switch_payload_t ) best_te ;
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Set 2833 dtmf send/recv payload to %u \n " , te ) ;
if ( tech_pvt - > rtp_session ) {
switch_rtp_set_telephony_event ( tech_pvt - > rtp_session , te ) ;
2011-09-16 14:30:32 -05:00
switch_channel_set_variable_printf ( tech_pvt - > channel , " sip_2833_send_payload " , " %d " , te ) ;
2010-07-05 14:26:38 -05:00
switch_rtp_set_telephony_recv_event ( tech_pvt - > rtp_session , te ) ;
2011-09-16 14:30:32 -05:00
switch_channel_set_variable_printf ( tech_pvt - > channel , " sip_2833_recv_payload " , " %d " , te ) ;
2010-07-05 14:26:38 -05:00
}
}
2011-03-30 11:26:14 -05:00
} else {
2011-08-25 13:29:44 -05:00
/* by default, use SIP INFO if 2833 is not in the SDP */
if ( ! switch_false ( switch_channel_get_variable ( channel , " sip_info_when_no_2833 " ) ) ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " No 2833 in SDP. Disable 2833 dtmf and switch to INFO \n " ) ;
switch_channel_set_variable ( tech_pvt - > channel , " dtmf_type " , " info " ) ;
tech_pvt - > dtmf_type = DTMF_INFO ;
te = tech_pvt - > recv_te = tech_pvt - > te = 0 ;
} else {
switch_channel_set_variable ( tech_pvt - > channel , " dtmf_type " , " none " ) ;
tech_pvt - > dtmf_type = DTMF_NONE ;
te = tech_pvt - > recv_te = tech_pvt - > te = 0 ;
}
2010-07-05 14:26:38 -05:00
}
2011-02-15 16:09:48 -06:00
2011-03-08 10:37:16 -06:00
if ( ! match & & greedy & & mine < total_codecs ) {
2007-06-10 02:52:23 +00:00
mine + + ;
skip = 0 ;
goto greed ;
}
2008-05-27 04:54:52 +00:00
} else if ( m - > m_type = = sdp_media_video & & m - > m_port ) {
2007-04-19 21:40:50 +00:00
sdp_rtpmap_t * map ;
const char * rm_encoding ;
const switch_codec_implementation_t * mimp = NULL ;
int vmatch = 0 , i ;
2008-05-23 19:41:23 +00:00
switch_channel_set_variable ( tech_pvt - > channel , " video_possible " , " true " ) ;
2008-05-27 04:54:52 +00:00
2007-04-19 21:40:50 +00:00
connection = sdp - > sdp_connection ;
if ( m - > m_connections ) {
connection = m - > m_connections ;
}
if ( ! connection ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Cannot find a c= line in the sdp at media or session level! \n " ) ;
2007-04-19 21:40:50 +00:00
match = 0 ;
break ;
}
for ( map = m - > m_rtpmaps ; map ; map = map - > rm_next ) {
2008-01-17 06:23:23 +00:00
for ( attr = m - > m_attributes ; attr ; attr = attr - > a_next ) {
if ( ! strcasecmp ( attr - > a_name , " framerate " ) & & attr - > a_value ) {
2011-04-22 16:43:29 -05:00
//framerate = atoi(attr->a_value);
2007-04-19 21:40:50 +00:00
}
2010-04-20 16:15:37 -05:00
if ( ! strcasecmp ( attr - > a_name , " rtcp " ) & & attr - > a_value ) {
switch_channel_set_variable ( tech_pvt - > channel , " sip_remote_video_rtcp_port " , attr - > a_value ) ;
}
2007-04-19 21:40:50 +00:00
}
if ( ! ( rm_encoding = map - > rm_encoding ) ) {
rm_encoding = " " ;
}
2008-05-27 04:54:52 +00:00
2011-03-08 10:37:16 -06:00
for ( i = 0 ; i < total_codecs ; i + + ) {
const switch_codec_implementation_t * imp = codec_array [ i ] ;
2007-04-19 21:40:50 +00:00
if ( imp - > codec_type ! = SWITCH_CODEC_TYPE_VIDEO ) {
continue ;
}
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Video Codec Compare [%s:%d]/[%s:%d] \n " ,
2007-04-19 21:40:50 +00:00
rm_encoding , map - > rm_pt , imp - > iananame , imp - > ianacode ) ;
2009-11-03 21:32:18 +00:00
if ( ( zstr ( map - > rm_encoding ) | | ( tech_pvt - > profile - > ndlb & PFLAG_NDLB_ALLOW_BAD_IANANAME ) ) & & map - > rm_pt < 96 ) {
2007-04-19 21:40:50 +00:00
vmatch = ( map - > rm_pt = = imp - > ianacode ) ? 1 : 0 ;
} else {
vmatch = strcasecmp ( rm_encoding , imp - > iananame ) ? 0 : 1 ;
}
2008-05-27 04:54:52 +00:00
2007-04-19 21:40:50 +00:00
if ( vmatch & & ( map - > rm_rate = = imp - > samples_per_second ) ) {
mimp = imp ;
break ;
} else {
vmatch = 0 ;
}
}
2008-02-01 21:22:27 +00:00
2008-05-27 04:54:52 +00:00
2007-04-19 21:40:50 +00:00
if ( mimp ) {
if ( ( tech_pvt - > video_rm_encoding = switch_core_session_strdup ( session , ( char * ) rm_encoding ) ) ) {
char tmp [ 50 ] ;
tech_pvt - > video_pt = ( switch_payload_t ) map - > rm_pt ;
tech_pvt - > video_rm_rate = map - > rm_rate ;
2008-10-20 17:48:42 +00:00
tech_pvt - > video_codec_ms = mimp - > microseconds_per_packet / 1000 ;
2007-04-19 21:40:50 +00:00
tech_pvt - > remote_sdp_video_ip = switch_core_session_strdup ( session , ( char * ) connection - > c_address ) ;
tech_pvt - > video_rm_fmtp = switch_core_session_strdup ( session , ( char * ) map - > rm_fmtp ) ;
tech_pvt - > remote_sdp_video_port = ( switch_port_t ) m - > m_port ;
tech_pvt - > video_agreed_pt = ( switch_payload_t ) map - > rm_pt ;
2007-12-12 21:53:32 +00:00
switch_snprintf ( tmp , sizeof ( tmp ) , " %d " , tech_pvt - > remote_sdp_video_port ) ;
2007-05-09 19:30:41 +00:00
switch_channel_set_variable ( tech_pvt - > channel , SWITCH_REMOTE_VIDEO_IP_VARIABLE , tech_pvt - > remote_sdp_audio_ip ) ;
switch_channel_set_variable ( tech_pvt - > channel , SWITCH_REMOTE_VIDEO_PORT_VARIABLE , tmp ) ;
2008-02-07 22:42:27 +00:00
switch_channel_set_variable ( tech_pvt - > channel , " sip_video_fmtp " , tech_pvt - > video_rm_fmtp ) ;
2008-02-11 17:14:14 +00:00
switch_snprintf ( tmp , sizeof ( tmp ) , " %d " , tech_pvt - > video_agreed_pt ) ;
switch_channel_set_variable ( tech_pvt - > channel , " sip_video_pt " , tmp ) ;
2008-03-19 19:02:26 +00:00
sofia_glue_check_video_codecs ( tech_pvt ) ;
2011-02-15 16:09:48 -06:00
2011-05-29 09:46:02 -05:00
tech_pvt - > video_recv_pt = ( switch_payload_t ) map - > rm_pt ;
2011-02-15 16:09:48 -06:00
if ( switch_channel_direction ( channel ) = = SWITCH_CALL_DIRECTION_OUTBOUND ) {
sofia_glue_get_offered_pt ( tech_pvt , mimp , & tech_pvt - > video_recv_pt ) ;
}
switch_snprintf ( tmp , sizeof ( tmp ) , " %d " , tech_pvt - > video_recv_pt ) ;
switch_channel_set_variable ( tech_pvt - > channel , " sip_video_recv_pt " , tmp ) ;
2008-05-27 04:54:52 +00:00
break ;
2007-04-19 21:40:50 +00:00
} else {
vmatch = 0 ;
}
}
}
2007-03-31 19:01:33 +00:00
}
}
2010-02-06 03:38:24 +00:00
2010-06-23 13:22:52 -05:00
done :
2010-05-26 20:12:54 -05:00
2011-03-08 10:37:16 -06:00
if ( parser ) {
2010-06-23 13:22:52 -05:00
sdp_parser_free ( parser ) ;
2011-03-08 10:37:16 -06:00
}
2010-05-26 20:12:54 -05:00
2008-10-23 22:05:00 +00:00
tech_pvt - > cng_pt = cng_pt ;
2009-02-09 17:56:38 +00:00
sofia_set_flag_locked ( tech_pvt , TFLAG_SDP ) ;
2007-04-19 21:40:50 +00:00
2007-03-31 19:01:33 +00:00
return match ;
}
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 ;
2007-05-09 19:30:41 +00:00
if ( ( val = switch_channel_get_variable ( tech_pvt - > channel , SWITCH_SIGNAL_BOND_VARIABLE ) )
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 ) ;
2010-02-06 03:38:24 +00:00
if ( ! sofia_test_flag ( tech_pvt , TFLAG_CHANGE_MEDIA ) & & ! sofia_test_flag ( tech_pvt , TFLAG_RECOVERING ) & &
2010-12-15 20:59:23 -06:00
( switch_channel_direction ( other_channel ) = = SWITCH_CALL_DIRECTION_OUTBOUND & &
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
}
switch_core_session_rwunlock ( other_session ) ;
}
}
char * sofia_glue_get_url_from_contact ( char * buf , uint8_t to_dup )
{
char * url = NULL , * e ;
if ( ( url = strchr ( buf , ' < ' ) ) & & ( e = strchr ( url , ' > ' ) ) ) {
url + + ;
if ( to_dup ) {
url = strdup ( url ) ;
e = strchr ( url , ' > ' ) ;
}
* e = ' \0 ' ;
2007-10-28 16:07:23 +00:00
} else {
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 ) {
2010-02-06 03:38:24 +00:00
for ( hi = switch_hash_first ( NULL , mod_sofia_globals . profile_hash ) ; hi ; hi = switch_hash_next ( hi ) ) {
2008-07-22 22:23:50 +00:00
switch_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. \n Please 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 ) {
for ( hi = switch_hash_first ( NULL , mod_sofia_globals . profile_hash ) ; hi ; hi = switch_hash_next ( hi ) ) {
switch_hash_this ( hi , & var , NULL , & val ) ;
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-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 ) {
for ( hi = switch_hash_first ( NULL , mod_sofia_globals . profile_hash ) ; hi ; hi = switch_hash_next ( hi ) ) {
switch_hash_this ( hi , & var , NULL , & val ) ;
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 ) {
for ( hi = switch_hash_first ( NULL , mod_sofia_globals . profile_hash ) ; hi ; hi = switch_hash_next ( hi ) ) {
switch_hash_this ( hi , & var , NULL , & val ) ;
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 ) {
for ( hi = switch_hash_first ( NULL , mod_sofia_globals . profile_hash ) ; hi ; hi = switch_hash_next ( hi ) ) {
switch_hash_this ( hi , & var , NULL , & val ) ;
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
}
2010-02-06 03:38:24 +00:00
struct recover_helper {
sofia_profile_t * profile ;
int total ;
} ;
static int recover_callback ( void * pArg , int argc , char * * argv , char * * columnNames )
{
struct recover_helper * h = ( struct recover_helper * ) pArg ;
switch_xml_t xml ;
switch_core_session_t * session ;
switch_channel_t * channel ;
private_object_t * tech_pvt = NULL ;
const char * tmp ;
xml = switch_xml_parse_str_dynamic ( argv [ 3 ] , SWITCH_TRUE ) ;
if ( ! xml )
return 0 ;
if ( ! ( session = switch_core_session_request_xml ( sofia_endpoint_interface , NULL , xml ) ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " skipping non-bridged entry \n " ) ;
return 0 ;
}
if ( ! ( tech_pvt = ( private_object_t * ) switch_core_session_alloc ( session , sizeof ( private_object_t ) ) ) ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_CRIT , " Hey where is my memory pool? \n " ) ;
switch_core_session_destroy ( & session ) ;
return 0 ;
}
channel = tech_pvt - > channel = switch_core_session_get_channel ( session ) ;
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 ) ) ;
tech_pvt - > remote_ip = ( char * ) switch_channel_get_variable ( channel , " sip_network_ip " ) ;
tech_pvt - > remote_port = atoi ( switch_str_nil ( switch_channel_get_variable ( channel , " sip_network_port " ) ) ) ;
tech_pvt - > caller_profile = switch_channel_get_caller_profile ( channel ) ;
2011-09-16 14:30:32 -05:00
if ( ( tmp = switch_channel_get_variable ( tech_pvt - > channel , " sip_2833_send_payload " ) ) ) {
int te = atoi ( tmp ) ;
if ( te > 64 ) {
tech_pvt - > te = te ;
}
}
2010-02-06 03:38:24 +00:00
2011-09-16 14:30:32 -05:00
if ( ( tmp = switch_channel_get_variable ( tech_pvt - > channel , " sip_2833_recv_payload " ) ) ) {
int te = atoi ( tmp ) ;
if ( te > 64 ) {
tech_pvt - > recv_te = te ;
}
}
2010-02-06 03:38:24 +00:00
if ( switch_channel_direction ( channel ) = = SWITCH_CALL_DIRECTION_OUTBOUND ) {
tech_pvt - > dest = switch_core_session_sprintf ( session , " sip:%s " , switch_channel_get_variable ( channel , " sip_req_uri " ) ) ;
switch_channel_set_variable ( channel , " sip_invite_full_via " , switch_channel_get_variable ( channel , " sip_full_via " ) ) ;
switch_channel_set_variable ( channel , " sip_handle_full_from " , switch_channel_get_variable ( channel , " sip_full_from " ) ) ;
switch_channel_set_variable ( channel , " sip_handle_full_to " , switch_channel_get_variable ( channel , " sip_full_to " ) ) ;
} 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
switch_channel_set_variable_printf ( channel , " sip_invite_route_uri " , " <sip:%s@%s:%s;lr> " ,
switch_channel_get_variable ( channel , " sip_from_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
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 ) ) {
2010-02-06 03:38:24 +00:00
switch_channel_set_variable ( channel , " sip_handle_full_from " , switch_channel_get_variable ( channel , " sip_full_to " ) ) ;
}
2011-05-25 15:42:36 -05:00
if ( ! switch_channel_get_variable_dup ( channel , " sip_handle_full_to " , SWITCH_FALSE , - 1 ) ) {
2010-02-06 03:38:24 +00:00
switch_channel_set_variable ( channel , " sip_handle_full_to " , switch_channel_get_variable ( channel , " sip_full_from " ) ) ;
}
}
tech_pvt - > dest_to = tech_pvt - > dest ;
sofia_glue_attach_private ( session , h - > profile , tech_pvt , NULL ) ;
switch_channel_set_name ( tech_pvt - > channel , switch_channel_get_variable ( channel , " channel_name " ) ) ;
if ( ( tmp = switch_channel_get_variable ( channel , " sip_local_sdp_str " ) ) ) {
tech_pvt - > local_sdp_str = switch_core_session_strdup ( session , tmp ) ;
}
2011-03-01 00:22:31 +01:00
if ( ( tmp = switch_channel_get_variable ( channel , SWITCH_R_SDP_VARIABLE ) ) ) {
2010-02-06 03:38:24 +00:00
tech_pvt - > remote_sdp_str = switch_core_session_strdup ( session , tmp ) ;
}
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 ) {
switch_caller_extension_t * extension = NULL ;
const char * ip = switch_channel_get_variable ( channel , SWITCH_LOCAL_MEDIA_IP_VARIABLE ) ;
2011-09-09 02:47:56 -05:00
const char * a_ip = switch_channel_get_variable ( channel , SWITCH_ADVERTISED_MEDIA_IP_VARIABLE ) ;
2010-02-06 03:38:24 +00:00
const char * port = switch_channel_get_variable ( channel , SWITCH_LOCAL_MEDIA_PORT_VARIABLE ) ;
const char * r_ip = switch_channel_get_variable ( channel , SWITCH_REMOTE_MEDIA_IP_VARIABLE ) ;
const char * r_port = switch_channel_get_variable ( channel , SWITCH_REMOTE_MEDIA_PORT_VARIABLE ) ;
2010-12-13 09:36:45 -06:00
const char * use_uuid ;
2010-02-06 03:38:24 +00:00
2010-06-17 14:28:31 -05:00
sofia_set_flag ( tech_pvt , TFLAG_RECOVERING ) ;
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
if ( ! switch_channel_test_flag ( channel , CF_PROXY_MODE ) & & ip & & port ) {
const char * tmp ;
tech_pvt - > iananame = tech_pvt - > rm_encoding = ( char * ) switch_channel_get_variable ( channel , " sip_use_codec_name " ) ;
tech_pvt - > rm_fmtp = ( char * ) switch_channel_get_variable ( channel , " sip_use_codec_fmtp " ) ;
if ( ( tmp = switch_channel_get_variable ( channel , " sip_use_codec_rate " ) ) ) {
tech_pvt - > rm_rate = atoi ( tmp ) ;
}
if ( ( tmp = switch_channel_get_variable ( channel , " sip_use_codec_ptime " ) ) ) {
tech_pvt - > codec_ms = atoi ( tmp ) ;
}
if ( ( tmp = switch_channel_get_variable ( channel , " sip_use_pt " ) ) ) {
2010-09-29 15:47:58 -05:00
tech_pvt - > pt = tech_pvt - > agreed_pt = ( switch_payload_t ) atoi ( tmp ) ;
2010-02-06 03:38:24 +00:00
}
2011-02-15 16:09:48 -06:00
2010-02-06 03:38:24 +00:00
sofia_glue_tech_set_codec ( tech_pvt , 1 ) ;
tech_pvt - > adv_sdp_audio_ip = tech_pvt - > extrtpip = ( char * ) ip ;
2010-09-29 15:47:58 -05:00
tech_pvt - > adv_sdp_audio_port = tech_pvt - > local_sdp_audio_port = ( switch_port_t ) atoi ( port ) ;
2010-06-17 14:28:31 -05:00
2011-09-08 17:13:28 -05:00
if ( ! zstr ( ip ) ) {
tech_pvt - > local_sdp_audio_ip = switch_core_session_strdup ( session , ip ) ;
2010-06-17 14:28:31 -05:00
tech_pvt - > rtpip = tech_pvt - > local_sdp_audio_ip ;
}
2010-02-06 03:38:24 +00:00
2011-09-09 02:47:56 -05:00
if ( ! zstr ( a_ip ) ) {
tech_pvt - > adv_sdp_audio_ip = switch_core_session_strdup ( session , a_ip ) ;
}
2010-02-06 03:38:24 +00:00
if ( r_ip & & r_port ) {
tech_pvt - > remote_sdp_audio_ip = ( char * ) r_ip ;
2010-09-29 15:47:58 -05:00
tech_pvt - > remote_sdp_audio_port = ( switch_port_t ) atoi ( r_port ) ;
2010-02-06 03:38:24 +00:00
}
2010-06-23 13:22:52 -05:00
if ( switch_channel_test_flag ( channel , CF_VIDEO ) ) {
2010-02-06 03:38:24 +00:00
if ( ( tmp = switch_channel_get_variable ( channel , " sip_use_video_pt " ) ) ) {
2010-09-29 15:47:58 -05:00
tech_pvt - > video_pt = tech_pvt - > video_agreed_pt = ( switch_payload_t ) atoi ( tmp ) ;
2010-02-06 03:38:24 +00:00
}
2010-06-23 13:22:52 -05:00
2010-02-06 03:38:24 +00:00
tech_pvt - > video_rm_encoding = ( char * ) switch_channel_get_variable ( channel , " sip_use_video_codec_name " ) ;
tech_pvt - > video_rm_fmtp = ( char * ) switch_channel_get_variable ( channel , " sip_use_video_codec_fmtp " ) ;
ip = switch_channel_get_variable ( channel , SWITCH_LOCAL_VIDEO_IP_VARIABLE ) ;
port = switch_channel_get_variable ( channel , SWITCH_LOCAL_VIDEO_PORT_VARIABLE ) ;
r_ip = switch_channel_get_variable ( channel , SWITCH_REMOTE_VIDEO_IP_VARIABLE ) ;
r_port = switch_channel_get_variable ( channel , SWITCH_REMOTE_VIDEO_PORT_VARIABLE ) ;
2010-06-23 13:22:52 -05:00
2010-02-06 03:38:24 +00:00
sofia_set_flag ( tech_pvt , TFLAG_VIDEO ) ;
if ( ( tmp = switch_channel_get_variable ( channel , " sip_use_video_codec_rate " ) ) ) {
tech_pvt - > video_rm_rate = atoi ( tmp ) ;
}
2010-06-23 13:22:52 -05:00
2010-02-06 03:38:24 +00:00
if ( ( tmp = switch_channel_get_variable ( channel , " sip_use_video_codec_ptime " ) ) ) {
tech_pvt - > video_codec_ms = atoi ( tmp ) ;
}
2010-09-29 15:47:58 -05:00
tech_pvt - > adv_sdp_video_port = tech_pvt - > local_sdp_video_port = ( switch_port_t ) atoi ( port ) ;
2010-06-23 13:22:52 -05:00
2010-02-06 03:38:24 +00:00
if ( r_ip & & r_port ) {
tech_pvt - > remote_sdp_video_ip = ( char * ) r_ip ;
2010-09-29 15:47:58 -05:00
tech_pvt - > remote_sdp_video_port = ( switch_port_t ) atoi ( r_port ) ;
2010-02-06 03:38:24 +00:00
}
//sofia_glue_tech_set_video_codec(tech_pvt, 1);
}
sofia_glue_set_local_sdp ( tech_pvt , NULL , 0 , NULL , 1 ) ;
2010-06-23 13:22:52 -05:00
2010-06-17 14:28:31 -05:00
if ( sofia_glue_activate_rtp ( tech_pvt , 0 ) ! = SWITCH_STATUS_SUCCESS ) {
switch_xml_free ( xml ) ;
return 0 ;
}
2011-02-15 16:09:48 -06:00
if ( switch_rtp_ready ( tech_pvt - > rtp_session ) ) {
if ( ( tmp = switch_channel_get_variable ( channel , " sip_audio_recv_pt " ) ) ) {
2011-05-29 09:46:02 -05:00
switch_rtp_set_recv_pt ( tech_pvt - > rtp_session , ( switch_payload_t ) atoi ( tmp ) ) ;
2011-02-15 16:09:48 -06:00
}
}
if ( switch_rtp_ready ( tech_pvt - > video_rtp_session ) ) {
if ( ( tmp = switch_channel_get_variable ( channel , " sip_video_recv_pt " ) ) ) {
2011-05-29 09:46:02 -05:00
switch_rtp_set_recv_pt ( tech_pvt - > rtp_session , ( switch_payload_t ) atoi ( tmp ) ) ;
2011-02-15 16:09:48 -06:00
}
}
2011-09-16 15:35:16 -05:00
if ( tech_pvt - > te ) {
switch_rtp_set_telephony_event ( tech_pvt - > rtp_session , tech_pvt - > te ) ;
}
if ( tech_pvt - > recv_te ) {
switch_rtp_set_telephony_recv_event ( tech_pvt - > rtp_session , tech_pvt - > recv_te ) ;
}
2010-02-06 03:38:24 +00:00
}
2010-06-23 13:22:52 -05:00
2011-09-16 14:16:31 -05:00
if ( switch_channel_get_variable ( channel , SWITCH_SIGNAL_BOND_VARIABLE ) ) {
2010-02-06 03:38:24 +00:00
sofia_set_flag ( tech_pvt , TFLAG_RECOVERING_BRIDGE ) ;
} else {
switch_xml_t callflow , param , x_extension ;
if ( ( extension = switch_caller_extension_new ( session , " recovery " , " recovery " ) ) = = 0 ) {
abort ( ) ;
}
if ( ( callflow = switch_xml_child ( xml , " callflow " ) ) & & ( x_extension = switch_xml_child ( callflow , " extension " ) ) ) {
for ( param = switch_xml_child ( x_extension , " application " ) ; param ; param = param - > next ) {
const char * var = switch_xml_attr_soft ( param , " app_name " ) ;
const char * val = switch_xml_attr_soft ( param , " app_data " ) ;
2010-10-13 16:17:36 -05:00
/* skip announcement type apps */
2010-10-13 16:21:53 -05:00
if ( strcasecmp ( var , " speak " ) & & strcasecmp ( var , " playback " ) & & strcasecmp ( var , " gentones " ) & & strcasecmp ( var , " say " ) ) {
2010-10-13 16:17:36 -05:00
switch_caller_extension_add_application ( session , extension , var , val ) ;
}
2010-02-06 03:38:24 +00:00
}
}
2010-06-23 13:22:52 -05:00
2010-02-06 03:38:24 +00:00
switch_channel_set_caller_extension ( channel , extension ) ;
}
switch_channel_set_state ( channel , CS_INIT ) ;
2010-06-23 13:22:52 -05:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_NOTICE , " Resurrecting fallen channel %s \n " , switch_channel_get_name ( channel ) ) ;
switch_core_session_thread_launch ( session ) ;
2010-02-06 03:38:24 +00:00
}
switch_xml_free ( xml ) ;
h - > total + + ;
return 0 ;
}
int sofia_glue_recover ( switch_bool_t flush )
{
sofia_profile_t * profile ;
char * sql ;
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 ) ) ) {
2010-02-06 03:38:24 +00:00
struct recover_helper h = { 0 } ;
h . profile = profile ;
h . total = 0 ;
if ( flush ) {
sql = switch_mprintf ( " delete from sip_recovery where profile_name='%q' " , profile - > name ) ;
sofia_glue_execute_sql_now ( profile , & sql , SWITCH_TRUE ) ;
} else {
sql = switch_mprintf ( " select profile_name, hostname, uuid, metadata "
" from sip_recovery where runtime_uuid!='%q' and profile_name='%q' " , switch_core_get_uuid ( ) , profile - > name ) ;
sofia_glue_execute_sql_callback ( profile , profile - > ireg_mutex , sql , recover_callback , & h ) ;
r + = h . total ;
free ( sql ) ;
sql = NULL ;
sql = switch_mprintf ( " delete "
" from sip_recovery where runtime_uuid!='%q' and profile_name='%q' " , switch_core_get_uuid ( ) , profile - > name ) ;
sofia_glue_execute_sql_now ( profile , & sql , SWITCH_TRUE ) ;
}
}
}
2011-06-16 14:32:08 -05:00
switch_console_free_matches ( & matches ) ;
2010-02-06 03:38:24 +00:00
}
return r ;
}
2010-06-30 10:35:03 -05:00
void sofia_glue_track_event_handler ( switch_event_t * event )
{
char * sql , * buf = NULL ;
char * profile_name = NULL ;
switch_assert ( event ) ; // Just a sanity check
if ( ( buf = switch_event_get_header_nil ( event , " sql " ) ) & & ( profile_name = switch_event_get_header_nil ( event , " profile_name " ) ) ) {
sofia_profile_t * profile ;
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " %s \n " , switch_event_get_header_nil ( event , " Event-Calling-Function " ) ) ;
if ( ( profile = sofia_glue_find_profile ( profile_name ) ) ) {
sql = switch_mprintf ( " %s " , buf ) ;
sofia_glue_execute_sql_now ( profile , & sql , SWITCH_TRUE ) ;
sofia_glue_release_profile ( profile ) ;
}
}
return ;
}
2010-02-06 03:38:24 +00:00
void sofia_glue_tech_untrack ( sofia_profile_t * profile , switch_core_session_t * session , switch_bool_t force )
{
2010-06-30 10:35:03 -05:00
char * sql = NULL ;
2010-02-06 03:38:24 +00:00
private_object_t * tech_pvt = ( private_object_t * ) switch_core_session_get_private ( session ) ;
if ( ! sofia_test_pflag ( profile , PFLAG_TRACK_CALLS ) | | ( sofia_test_flag ( tech_pvt , TFLAG_RECOVERING ) ) ) {
return ;
}
if ( sofia_test_pflag ( profile , PFLAG_TRACK_CALLS ) & & ( sofia_test_flag ( tech_pvt , TFLAG_TRACKED ) | | force ) ) {
2010-06-30 10:35:03 -05:00
switch_event_t * event = NULL ;
2010-02-06 03:38:24 +00:00
if ( force ) {
sql = switch_mprintf ( " delete from sip_recovery where uuid='%q' " , switch_core_session_get_uuid ( session ) ) ;
2010-06-30 10:35:03 -05:00
2010-02-06 03:38:24 +00:00
} else {
sql = switch_mprintf ( " delete from sip_recovery where runtime_uuid='%q' and uuid='%q' " ,
switch_core_get_uuid ( ) , switch_core_session_get_uuid ( session ) ) ;
}
2010-06-30 10:35:03 -05:00
if ( sofia_test_pflag ( profile , PFLAG_TRACK_CALLS_EVENTS ) ) {
if ( switch_event_create_subclass ( & event , SWITCH_EVENT_CUSTOM , MY_EVENT_RECOVERY_SEND ) = = SWITCH_STATUS_SUCCESS ) {
2010-07-01 09:37:49 -05:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " profile_name " , profile - > name ) ;
2010-06-30 10:35:03 -05:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " sql " , sql ) ;
switch_event_fire ( & event ) ;
}
}
2010-09-08 15:32:34 -05:00
sofia_glue_execute_sql ( profile , & sql , SWITCH_TRUE ) ;
2010-02-06 03:38:24 +00:00
sofia_clear_flag ( tech_pvt , TFLAG_TRACKED ) ;
2010-06-30 10:35:03 -05:00
switch_safe_free ( sql ) ;
2010-02-06 03:38:24 +00:00
}
2010-06-30 10:35:03 -05:00
2010-02-06 03:38:24 +00:00
}
void sofia_glue_tech_track ( sofia_profile_t * profile , switch_core_session_t * session )
{
private_object_t * tech_pvt = ( private_object_t * ) switch_core_session_get_private ( session ) ;
2010-06-30 10:35:03 -05:00
switch_xml_t cdr = NULL ;
char * xml_cdr_text = NULL ;
char * sql = NULL ;
2010-02-06 03:38:24 +00:00
if ( ! sofia_test_pflag ( profile , PFLAG_TRACK_CALLS ) | | sofia_test_flag ( tech_pvt , TFLAG_RECOVERING ) ) {
return ;
}
2010-06-30 10:35:03 -05:00
if ( switch_ivr_generate_xml_cdr ( session , & cdr ) = = SWITCH_STATUS_SUCCESS ) {
xml_cdr_text = switch_xml_toxml ( cdr , SWITCH_FALSE ) ;
switch_xml_free ( cdr ) ;
}
2010-02-06 03:38:24 +00:00
2010-06-30 10:35:03 -05:00
if ( xml_cdr_text ) {
2010-09-07 21:16:00 -05:00
if ( sofia_test_flag ( tech_pvt , TFLAG_TRACKED ) ) {
sql = switch_mprintf ( " update sip_recovery set metadata='%q' where uuid='%q' " , xml_cdr_text , switch_core_session_get_uuid ( session ) ) ;
} else {
sql = switch_mprintf ( " insert into sip_recovery (runtime_uuid, profile_name, hostname, uuid, metadata) values ('%q','%q','%q','%q','%q') " ,
switch_core_get_uuid ( ) , profile - > name , mod_sofia_globals . hostname , switch_core_session_get_uuid ( session ) , xml_cdr_text ) ;
}
2010-06-30 10:35:03 -05:00
if ( sofia_test_pflag ( profile , PFLAG_TRACK_CALLS_EVENTS ) ) {
switch_event_t * event = NULL ;
if ( switch_event_create_subclass ( & event , SWITCH_EVENT_CUSTOM , MY_EVENT_RECOVERY_SEND ) = = SWITCH_STATUS_SUCCESS ) {
2010-07-01 09:37:49 -05:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " profile_name " , profile - > name ) ;
2010-06-30 10:35:03 -05:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " sql " , sql ) ;
switch_event_fire ( & event ) ;
}
2010-02-06 03:38:24 +00:00
}
2010-09-07 21:16:00 -05:00
sofia_glue_execute_sql ( profile , & sql , SWITCH_TRUE ) ;
2010-06-30 10:35:03 -05:00
free ( xml_cdr_text ) ;
sofia_set_flag ( tech_pvt , TFLAG_TRACKED ) ;
2010-02-06 03:38:24 +00:00
}
2010-06-30 10:35:03 -05:00
switch_safe_free ( sql ) ;
2010-02-06 03:38:24 +00:00
}
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 "
2010-06-23 13:22:52 -05:00
" rpid VARCHAR(255), \n "
" expires INTEGER, \n "
" 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 "
" orig_hostname VARCHAR(255) \n "
2008-11-22 01:34:19 +00:00
" ); \n " ;
2010-02-06 03:38:24 +00:00
char recovery_sql [ ] =
" CREATE TABLE sip_recovery ( \n "
" runtime_uuid VARCHAR(255), \n "
2010-02-22 23:41:56 +00:00
" profile_name VARCHAR(255), \n "
" hostname VARCHAR(255), \n "
" uuid VARCHAR(255), \n "
2010-06-23 13:22:52 -05:00
" metadata text \n "
" ); \n " ;
2008-11-22 01:34:19 +00:00
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 "
" expires INTEGER, \n "
" 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 "
" call_info_state VARCHAR(255), \n "
2010-07-29 23:39:39 -05:00
" expires INTEGER default 0, \n "
" status VARCHAR(255), \n "
2011-10-21 20:00:34 -05:00
" rpid VARCHAR(255), \n "
" sip_to_tag VARCHAR(255), \n "
" sip_from_tag VARCHAR(255) \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 "
2010-02-06 03:38:24 +00:00
" expires INTEGER, \n "
" 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 "
" orig_proto 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 "
2010-02-22 23:41:56 +00:00
" expires INTEGER, "
" 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 "
" expires INTEGER \n "
" ); \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) " ,
" 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) " ,
" create index sr_hostname on sip_registrations (hostname) " ,
" create index sr_status on sip_registrations (status) " ,
" 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) " ,
" 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) " ,
" 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) " ,
" create index sp_hostname on sip_presence (hostname) " ,
" create index sa_nonce on sip_authentication (nonce) " ,
" create index sa_hostname on sip_authentication (hostname) " ,
" 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) " ,
" create index sr_1 on sip_recovery (runtime_uuid) " ,
" create index sr_2 on sip_recovery (profile_name) " ,
" create index sr_3 on sip_recovery (hostname) " ,
" create index sr_4 on sip_recovery (uuid) " ,
NULL
} ;
switch_cache_db_handle_t * dbh = sofia_glue_get_db_handle ( profile ) ;
if ( ! dbh ) {
return 0 ;
}
2010-02-06 03:38:24 +00:00
2010-08-04 09:56:53 -05:00
test_sql = switch_mprintf ( " delete from sip_registrations where (contact like '%%TCP%%' "
" or status like '%%TCP%%' or status like '%%TLS%%') and hostname='%q' "
" and network_ip like '%%' and network_port like '%%' and sip_username "
" like '%%' and mwi_user like '%%' and mwi_host like '%%' "
" 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 ) ;
2010-02-06 03:38:24 +00:00
2009-02-23 01:49:49 +00:00
2010-08-04 09:56:53 -05:00
if ( sofia_test_pflag ( profile , PFLAG_SQL_IN_TRANS ) ) {
char * test2 = switch_mprintf ( " %s;%s " , test_sql , test_sql ) ;
if ( switch_cache_db_execute_sql ( dbh , test2 , NULL ) ! = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " GREAT SCOTT!!! Cannot execute batched statements! \n "
" If you are using mysql, make sure you are using MYODBC 3.51.18 or higher and enable FLAG_MULTI_STATEMENTS \n " ) ;
sofia_clear_pflag ( profile , PFLAG_SQL_IN_TRANS ) ;
2009-01-30 16:46:37 +00:00
2007-04-04 03:08:17 +00:00
}
2010-08-04 09:56:53 -05:00
free ( test2 ) ;
}
2007-04-04 03:08:17 +00:00
2010-08-04 09:56:53 -05:00
free ( test_sql ) ;
2010-02-06 03:38:24 +00:00
2011-10-24 09:57:11 -05:00
test_sql = switch_mprintf ( " delete from sip_subscriptions where hostname='%q' and version < 0 and orig_proto like '%%' and network_ip like '%%' and network_port like '%%' " ,
2010-08-04 09:56:53 -05:00
mod_sofia_globals . hostname ) ;
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-24 07:34:38 -05:00
test_sql = switch_mprintf ( " delete from sip_dialogs where hostname='%q' and expires <> -9999 or rpid='' or sip_from_tag='' " , 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 ) ;
test_sql = switch_mprintf ( " select count(profile_name) from sip_recovery where hostname='%q' " , mod_sofia_globals . hostname ) ;
2010-03-25 00:28:56 +00:00
2010-06-23 13:22:52 -05:00
2010-08-04 09:56:53 -05:00
switch_cache_db_test_reactive ( dbh , test_sql , " DROP TABLE sip_recovery " , recovery_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 + + ) {
switch_cache_db_execute_sql ( 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
{
switch_status_t status = SWITCH_STATUS_FALSE ;
2008-03-05 20:31:18 +00:00
char * d_sql = NULL , * sql ;
switch_assert ( sqlp & & * sqlp ) ;
sql = * sqlp ;
2008-05-27 04:54:52 +00:00
2008-03-04 23:53:23 +00:00
if ( profile - > sql_queue ) {
2008-03-17 16:12:38 +00:00
if ( sql_already_dynamic ) {
2008-03-05 20:31:18 +00:00
d_sql = sql ;
} else {
d_sql = strdup ( sql ) ;
}
2008-03-04 23:53:23 +00:00
2008-03-05 20:31:18 +00:00
switch_assert ( d_sql ) ;
2008-03-17 17:43:25 +00:00
if ( ( status = switch_queue_trypush ( profile - > sql_queue , d_sql ) ) = = SWITCH_STATUS_SUCCESS ) {
d_sql = NULL ;
}
2008-03-17 16:12:38 +00:00
} else if ( sql_already_dynamic ) {
d_sql = sql ;
2008-03-04 23:53:23 +00:00
}
2008-03-17 17:43:25 +00:00
2008-03-17 16:12:38 +00:00
if ( status ! = SWITCH_STATUS_SUCCESS ) {
2009-11-12 03:52:07 +00:00
sofia_glue_actually_execute_sql ( profile , sql , profile - > ireg_mutex ) ;
2008-03-04 23:53:23 +00:00
}
2008-03-17 17:43:25 +00:00
switch_safe_free ( d_sql ) ;
2008-03-17 16:12:38 +00:00
if ( sql_already_dynamic ) {
* sqlp = NULL ;
}
2008-03-04 23:53:23 +00: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 )
{
sofia_glue_actually_execute_sql ( profile , * sqlp , profile - > ireg_mutex ) ;
if ( sql_already_dynamic ) {
switch_safe_free ( * sqlp ) ;
}
* sqlp = NULL ;
}
2009-11-12 19:54:50 +00:00
2009-11-21 18:57:15 +00:00
switch_cache_db_handle_t * sofia_glue_get_db_handle ( sofia_profile_t * profile )
2009-11-12 19:54:50 +00:00
{
2010-02-16 00:49:42 +00:00
switch_cache_db_connection_options_t options = { { 0 } } ;
2009-11-21 18:57:15 +00:00
switch_cache_db_handle_t * dbh = NULL ;
2010-02-06 03:38:24 +00:00
2010-01-13 18:02:42 +00:00
if ( ! zstr ( profile - > odbc_dsn ) ) {
2009-11-21 18:57:15 +00:00
options . odbc_options . dsn = profile - > odbc_dsn ;
options . odbc_options . user = profile - > odbc_user ;
options . odbc_options . pass = profile - > odbc_pass ;
2010-02-06 03:38:24 +00:00
if ( switch_cache_db_get_db_handle ( & dbh , SCDB_TYPE_ODBC , & options ) ! = SWITCH_STATUS_SUCCESS )
dbh = NULL ;
2009-11-21 18:57:15 +00:00
return dbh ;
} else {
options . core_db_options . db_path = profile - > dbname ;
2010-02-06 03:38:24 +00:00
if ( switch_cache_db_get_db_handle ( & dbh , SCDB_TYPE_CORE_DB , & options ) ! = SWITCH_STATUS_SUCCESS )
dbh = NULL ;
2009-11-21 18:57:15 +00:00
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
2009-11-21 18:57:15 +00:00
if ( mutex ) {
switch_mutex_lock ( mutex ) ;
2009-11-12 03:52:07 +00:00
}
2009-11-12 19:54:50 +00:00
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 " ) ;
goto end ;
}
2009-11-12 19:54:50 +00:00
2009-11-21 18:57:15 +00:00
switch_cache_db_persistant_execute_trans ( dbh , sql , 1 ) ;
2009-11-12 19:54:50 +00:00
2010-06-30 10:35:03 -05:00
end :
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
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 ;
2007-03-31 19:01:33 +00: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 " ) ;
goto end ;
}
2009-11-21 18:57:15 +00:00
switch_cache_db_execute_sql ( dbh , sql , NULL ) ;
2007-03-31 19:01:33 +00:00
2010-06-30 10:35:03 -05:00
end :
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-03-31 19:01:33 +00:00
if ( mutex ) {
switch_mutex_unlock ( mutex ) ;
}
}
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
2007-04-04 03:08:17 +00:00
if ( mutex ) {
2008-05-27 04:54:52 +00:00
switch_mutex_lock ( mutex ) ;
}
2007-04-04 03:08:17 +00:00
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 " ) ;
goto end ;
}
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
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
2010-06-30 10:35:03 -05:00
end :
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
2009-11-12 19:54:50 +00:00
if ( mutex ) {
switch_mutex_unlock ( mutex ) ;
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 ;
2009-11-21 18:57:15 +00:00
switch_cache_db_handle_t * dbh = NULL ;
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 " ) ;
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
if ( mutex ) {
switch_mutex_lock ( mutex ) ;
}
2009-11-21 18:57:15 +00:00
ret = switch_cache_db_execute_sql2str ( dbh , sql , resbuf , len , NULL ) ;
2010-02-06 03:38:24 +00:00
2007-04-04 03:08:17 +00:00
if ( mutex ) {
switch_mutex_unlock ( mutex ) ;
}
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 ,
2011-08-19 17:29:42 -05:00
const char * body , const char * o_contact , const char * network_ip )
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 ;
2009-09-14 19:43:15 +00:00
char * route_uri = NULL ;
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 ) ;
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
char * ptr = NULL ;
2011-04-22 16:43:29 -05:00
//const char *transport_str = NULL;
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= " ) ) ) {
sofia_transport_t transport = sofia_glue_str2transport ( ptr ) ;
2011-04-22 16:43:29 -05:00
//transport_str = sofia_glue_transport2str(transport);
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 :
contact_str = profile - > tls_public_contact ;
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 ) ;
contact_str = profile - > public_url ;
}
} else {
contact_str = profile - > url ;
id = switch_mprintf ( " sip:%s@%s " , user , host ) ;
}
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 ) ) ,
TAG_IF ( event , SIPTAG_EVENT_STR ( event ) ) ,
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
void sofia_glue_tech_simplify ( private_object_t * tech_pvt )
{
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 ;
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 ) ) {
2010-06-18 17:09:26 -05:00
return ;
}
2011-07-16 02:33:39 -05:00
2010-06-18 17:09:26 -05:00
if ( ( uuid = switch_channel_get_variable ( tech_pvt - > channel , SWITCH_SIGNAL_BOND_VARIABLE ) )
& & ( other_session = switch_core_session_locate ( uuid ) ) ) {
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 " ) ;
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 ;
sofia_glue_tech_track ( tech_pvt - > profile , 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 ) ;
}
}
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 ) ;
}
2011-05-29 09:46:02 -05:00
void sofia_glue_parse_rtp_bugs ( switch_rtp_bug_flag_t * flag_pole , const char * str )
2010-11-10 16:55:56 -06:00
{
if ( switch_stristr ( " clear " , str ) ) {
* flag_pole = 0 ;
}
if ( switch_stristr ( " CISCO_SKIP_MARK_BIT_2833 " , str ) ) {
* flag_pole | = RTP_BUG_CISCO_SKIP_MARK_BIT_2833 ;
}
if ( switch_stristr ( " ~CISCO_SKIP_MARK_BIT_2833 " , str ) ) {
* flag_pole & = ~ RTP_BUG_CISCO_SKIP_MARK_BIT_2833 ;
}
if ( switch_stristr ( " SONUS_SEND_INVALID_TIMESTAMP_2833 " , str ) ) {
* flag_pole | = RTP_BUG_SONUS_SEND_INVALID_TIMESTAMP_2833 ;
}
if ( switch_stristr ( " ~SONUS_SEND_INVALID_TIMESTAMP_2833 " , str ) ) {
* flag_pole & = ~ RTP_BUG_SONUS_SEND_INVALID_TIMESTAMP_2833 ;
}
if ( switch_stristr ( " IGNORE_MARK_BIT " , str ) ) {
* flag_pole | = RTP_BUG_IGNORE_MARK_BIT ;
}
if ( switch_stristr ( " ~IGNORE_MARK_BIT " , str ) ) {
* flag_pole & = ~ RTP_BUG_IGNORE_MARK_BIT ;
}
if ( switch_stristr ( " SEND_LINEAR_TIMESTAMPS " , str ) ) {
* flag_pole | = RTP_BUG_SEND_LINEAR_TIMESTAMPS ;
}
if ( switch_stristr ( " ~SEND_LINEAR_TIMESTAMPS " , str ) ) {
* flag_pole & = ~ RTP_BUG_SEND_LINEAR_TIMESTAMPS ;
}
if ( switch_stristr ( " START_SEQ_AT_ZERO " , str ) ) {
* flag_pole | = RTP_BUG_START_SEQ_AT_ZERO ;
}
if ( switch_stristr ( " ~START_SEQ_AT_ZERO " , str ) ) {
* flag_pole & = ~ RTP_BUG_START_SEQ_AT_ZERO ;
}
if ( switch_stristr ( " NEVER_SEND_MARKER " , str ) ) {
* flag_pole | = RTP_BUG_NEVER_SEND_MARKER ;
}
if ( switch_stristr ( " ~NEVER_SEND_MARKER " , str ) ) {
* flag_pole & = ~ RTP_BUG_NEVER_SEND_MARKER ;
}
2011-01-07 16:04:24 -06:00
if ( switch_stristr ( " IGNORE_DTMF_DURATION " , str ) ) {
* flag_pole | = RTP_BUG_IGNORE_DTMF_DURATION ;
}
if ( switch_stristr ( " ~IGNORE_DTMF_DURATION " , str ) ) {
* flag_pole & = ~ RTP_BUG_IGNORE_DTMF_DURATION ;
}
2011-09-08 08:57:28 -05:00
if ( switch_stristr ( " ACCEPT_ANY_PACKETS " , str ) ) {
* flag_pole | = RTP_BUG_ACCEPT_ANY_PACKETS ;
}
if ( switch_stristr ( " ~ACCEPT_ANY_PACKETS " , str ) ) {
* flag_pole & = ~ RTP_BUG_ACCEPT_ANY_PACKETS ;
}
2011-10-07 10:40:30 -05:00
if ( switch_stristr ( " GEN_ONE_GEN_ALL " , str ) ) {
* flag_pole | = RTP_BUG_GEN_ONE_GEN_ALL ;
}
if ( switch_stristr ( " ~GEN_ONE_GEN_ALL " , str ) ) {
* flag_pole & = ~ RTP_BUG_GEN_ONE_GEN_ALL ;
}
2010-11-10 16:55:56 -06:00
}
2011-06-16 14:37:22 -05:00
char * sofia_glue_gen_contact_str ( sofia_profile_t * profile , sip_t const * sip , 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 ;
if ( ! sip | | ! sip - > sip_contact | | ! sip - > sip_contact - > m_url ) {
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 ;
}
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 , ' : ' ) ;
if ( contact - > m_url - > url_params ) {
contact_str = switch_mprintf ( " %s <sip:%s@%s%s%s%s;%s>%s " ,
display , contact - > m_url - > url_user ,
ipv6 ? " [ " : " " ,
contact_host , ipv6 ? " ] " : " " , new_port , contact - > m_url - > url_params , np - > is_nat ? " ;fs_nat=yes " : " " ) ;
} else {
contact_str = switch_mprintf ( " %s <sip:%s@%s%s%s%s>%s " ,
display ,
contact - > m_url - > url_user , ipv6 ? " [ " : " " , contact_host , ipv6 ? " ] " : " " , new_port , np - > is_nat ? " ;fs_nat=yes " : " " ) ;
}
return contact_str ;
}
2010-09-29 14:14:41 -05:00
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 :
2008-07-03 19:12:26 +00:00
* vim : set softtabstop = 4 shiftwidth = 4 tabstop = 4 :
2008-01-27 05:02:52 +00:00
*/