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
2009-02-13 23:37:37 +00:00
* Copyright ( C ) 2005 - 2009 , 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
2009-03-04 23:03:25 +00:00
2008-12-30 19:50:33 +00:00
void sofia_glue_set_image_sdp ( private_object_t * tech_pvt , switch_t38_options_t * t38_options )
{
char buf [ 2048 ] ;
const char * ip = t38_options - > ip ;
uint32_t port = t38_options - > port ;
const char * family = " IP4 " ;
2009-07-10 20:32:23 +00:00
const char * username = tech_pvt - > profile - > username ;
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 ;
}
}
if ( ! port ) {
if ( ! ( port = tech_pvt - > adv_sdp_audio_port ) ) {
port = tech_pvt - > proxy_sdp_audio_port ;
}
}
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 + + ;
family = strchr ( ip , ' : ' ) ? " IP6 " : " IP4 " ;
switch_snprintf ( buf , sizeof ( buf ) ,
" v=0 \n "
2009-07-10 20:32:23 +00:00
" o=%s %010u %010u IN %s %s \n "
" s=%s \n "
2008-12-30 19:50:33 +00:00
" c=IN %s %s \n "
" t=0 0 \n "
2009-01-01 19:11:49 +00:00
" m=image %d udptl t38 \n "
2008-12-30 19:50:33 +00:00
" a=T38MaxBitRate:%d \n "
" %s "
" %s "
" %s "
" a=T38FaxRateManagement:%s \n "
" a=T38FaxMaxBuffer:%d \n "
" a=T38FaxMaxDatagram:%d \n "
" a=T38FaxUdpEC:%s \n "
" a=T38VendorInfo:%s \n " ,
2009-07-10 20:32:23 +00:00
username ,
2008-12-30 19:50:33 +00:00
tech_pvt - > owner_id ,
tech_pvt - > session_id ,
family ,
ip ,
2009-07-10 20:32:23 +00:00
username ,
2008-12-30 19:50:33 +00:00
family ,
ip ,
port ,
t38_options - > T38MaxBitRate ,
t38_options - > T38FaxFillBitRemoval ? " a=T38FaxFillBitRemoval \n " : " " ,
t38_options - > T38FaxTranscodingMMR ? " a=T38FaxTranscodingMMR \n " : " " ,
t38_options - > T38FaxTranscodingJBIG ? " a=T38FaxTranscodingJBIG \n " : " " ,
t38_options - > T38FaxRateManagement ,
t38_options - > T38FaxMaxBuffer ,
t38_options - > T38FaxMaxDatagram ,
t38_options - > T38FaxUdpEC ,
t38_options - > T38VendorInfo
) ;
2009-03-20 01:52:53 +00:00
sofia_glue_tech_set_local_sdp ( tech_pvt , buf , SWITCH_TRUE ) ;
2008-12-30 19:50:33 +00:00
}
2007-03-31 19:01:33 +00:00
2007-11-01 11:28:26 +00:00
void sofia_glue_set_local_sdp ( private_object_t * tech_pvt , const char * ip , uint32_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 " ) ;
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 ;
2007-11-12 20:36:00 +00:00
2008-08-28 16:32:06 +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 ) ) ) {
2007-11-12 20:36:00 +00:00
use_cng = 0 ;
2008-09-18 13:03:58 +00:00
tech_pvt - > cng_pt = 0 ;
2007-11-12 20:36:00 +00:00
}
2007-03-31 19:01:33 +00:00
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 ;
}
}
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
2007-03-31 19:01:33 +00:00
if ( ! sr ) {
sr = " sendrecv " ;
}
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
2009-04-20 17:07:54 +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 ) ) ) {
switch_snprintf ( srbuf , sizeof ( srbuf ) , " a=%s \n " , sr ) ;
sr = NULL ;
}
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 "
2009-07-10 20:32:23 +00:00
" %sm=audio %d RTP/%sAVP " ,
username ,
tech_pvt - > owner_id , tech_pvt - > session_id , family , ip , username , family , ip ,
2009-04-20 17:07:54 +00:00
srbuf ,
port ,
2009-10-23 16:03:42 +00:00
( ! zstr ( tech_pvt - > local_crypto_key )
2009-02-09 17:56:38 +00:00
& & sofia_test_flag ( tech_pvt , TFLAG_SECURE ) ) ? " S " : " " ) ;
2008-01-16 06:01:53 +00:00
2007-03-31 19:01:33 +00:00
if ( tech_pvt - > rm_encoding ) {
2007-12-12 21:53:32 +00:00
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " %d " , tech_pvt - > pt ) ;
2007-03-31 19:01:33 +00:00
} else if ( tech_pvt - > num_codecs ) {
int i ;
2007-10-18 16:44:11 +00:00
int already_did [ 128 ] = { 0 } ;
2007-03-31 19:01:33 +00:00
for ( i = 0 ; i < tech_pvt - > num_codecs ; i + + ) {
const switch_codec_implementation_t * imp = tech_pvt - > codecs [ i ] ;
2007-04-19 21:40:50 +00:00
if ( imp - > codec_type ! = SWITCH_CODEC_TYPE_AUDIO ) {
continue ;
}
2008-05-27 04:54:52 +00:00
2007-10-18 16:44:11 +00:00
if ( imp - > ianacode < 128 ) {
if ( already_did [ imp - > ianacode ] ) {
continue ;
}
2007-10-18 16:32:32 +00:00
2007-10-18 16:44:11 +00:00
already_did [ imp - > ianacode ] = 1 ;
}
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 ) , " %d " , imp - > ianacode ) ;
2007-03-31 19:01:33 +00:00
if ( ! ptime ) {
2008-10-20 17:48:42 +00:00
ptime = imp - > microseconds_per_packet / 1000 ;
2007-03-31 19:01:33 +00:00
}
}
}
2008-03-18 23:20:41 +00:00
if ( tech_pvt - > dtmf_type = = DTMF_2833 & & tech_pvt - > te > 95 ) {
2007-12-12 21:53:32 +00:00
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " %d " , tech_pvt - > te ) ;
2007-03-31 19:01:33 +00:00
}
2008-05-27 04:54:52 +00:00
2009-02-09 17:56:38 +00:00
if ( ! sofia_test_pflag ( tech_pvt - > profile , PFLAG_SUPPRESS_CNG ) & & tech_pvt - > cng_pt & & use_cng ) {
2007-12-12 21:53:32 +00:00
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " %d " , tech_pvt - > cng_pt ) ;
2007-03-31 19:01:33 +00:00
}
2007-12-12 21:53:32 +00:00
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " \n " ) ;
2007-03-31 19:01:33 +00:00
2008-01-16 06:01:53 +00:00
2007-03-31 19:01:33 +00:00
if ( tech_pvt - > rm_encoding ) {
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 ) ;
2007-03-31 19:01:33 +00:00
if ( tech_pvt - > fmtp_out ) {
2008-06-23 18:26:08 +00:00
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " a=fmtp:%d %s \n " , tech_pvt - > agreed_pt , tech_pvt - > fmtp_out ) ;
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
}
} else if ( tech_pvt - > num_codecs ) {
int i ;
2007-10-18 16:44:11 +00:00
int already_did [ 128 ] = { 0 } ;
2007-03-31 19:01:33 +00:00
for ( i = 0 ; i < tech_pvt - > num_codecs ; i + + ) {
const switch_codec_implementation_t * imp = tech_pvt - > codecs [ i ] ;
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
if ( imp - > ianacode < 128 ) {
if ( already_did [ imp - > ianacode ] ) {
continue ;
}
2008-05-27 04:54:52 +00:00
2007-10-18 16:44:11 +00:00
already_did [ imp - > ianacode ] = 1 ;
2007-10-18 16:32:32 +00:00
}
2008-05-27 04:54:52 +00:00
2007-06-11 22:12:10 +00:00
rate = imp - > samples_per_second ;
2008-05-27 04:54:52 +00:00
2007-12-12 21:53:32 +00:00
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " a=rtpmap:%d %s/%d \n " , imp - > ianacode , imp - > iananame , rate ) ;
2007-03-31 19:01:33 +00:00
if ( imp - > fmtp ) {
2007-12-12 21:53:32 +00:00
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " a=fmtp:%d %s \n " , imp - > ianacode , imp - > fmtp ) ;
2007-03-31 19:01:33 +00:00
}
}
}
2008-03-18 23:20:41 +00:00
if ( tech_pvt - > dtmf_type = = DTMF_2833 & & tech_pvt - > te > 95 ) {
2007-12-12 21:53:32 +00: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 ) ;
2007-03-31 19:01:33 +00:00
}
2009-02-09 17:56:38 +00:00
if ( ! sofia_test_pflag ( tech_pvt - > profile , PFLAG_SUPPRESS_CNG ) & & tech_pvt - > cng_pt & & use_cng ) {
2007-12-12 21:53:32 +00:00
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " a=rtpmap:%d CN/8000 \n " , tech_pvt - > cng_pt ) ;
2007-03-31 19:01:33 +00:00
if ( ! tech_pvt - > rm_encoding ) {
tech_pvt - > cng_pt = 0 ;
}
2007-11-12 20:36:00 +00:00
} else {
2007-12-12 21:53:32 +00:00
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " a=silenceSupp:off - - - - \n " ) ;
2007-03-31 19:01:33 +00:00
}
2008-11-10 18:26:41 +00:00
2007-03-31 19:01:33 +00:00
if ( ptime ) {
2007-12-12 21:53:32 +00:00
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " a=ptime:%d \n " , ptime ) ;
2007-03-31 19:01:33 +00:00
}
2008-11-11 15:29:35 +00:00
if ( sr ) {
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " a=%s \n " , sr ) ;
}
2008-01-17 04:16:04 +00:00
2009-10-23 16:03:42 +00:00
if ( ! zstr ( tech_pvt - > local_crypto_key ) & & sofia_test_flag ( tech_pvt , TFLAG_SECURE ) ) {
2008-01-16 06:01:53 +00:00
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " a=crypto:%s \n " , tech_pvt - > local_crypto_key ) ;
2008-01-17 04:16:04 +00:00
//switch_snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), "a=encryption:optional\n");
2008-02-26 17:39:22 +00:00
#if 0
2008-01-17 04:16:04 +00:00
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " m=audio %d RTP/AVP " , port ) ;
2008-05-27 04:54:52 +00:00
2008-01-17 04:16:04 +00:00
if ( tech_pvt - > rm_encoding ) {
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " %d " , tech_pvt - > pt ) ;
} else if ( tech_pvt - > num_codecs ) {
int i ;
int already_did [ 128 ] = { 0 } ;
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
2008-01-17 04:16:04 +00:00
if ( imp - > codec_type ! = SWITCH_CODEC_TYPE_AUDIO ) {
continue ;
}
2008-05-27 04:54:52 +00:00
2008-01-17 04:16:04 +00:00
if ( imp - > ianacode < 128 ) {
if ( already_did [ imp - > ianacode ] ) {
continue ;
}
2008-05-27 04:54:52 +00:00
2008-01-17 04:16:04 +00:00
already_did [ imp - > ianacode ] = 1 ;
}
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " %d " , imp - > ianacode ) ;
}
}
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " \n a=crypto:%s \n " , tech_pvt - > local_crypto_key ) ;
2008-02-26 17:39:22 +00:00
# endif
2008-01-16 06:01:53 +00:00
}
2009-02-09 17:56:38 +00:00
if ( sofia_test_flag ( tech_pvt , TFLAG_VIDEO ) ) {
2008-05-27 04:54:52 +00:00
if ( ! switch_channel_test_flag ( tech_pvt - > channel , CF_ANSWERED ) & & ! switch_channel_test_flag ( tech_pvt - > channel , CF_EARLY_MEDIA ) & &
2008-03-25 18:48:20 +00:00
! 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 ) ;
2008-06-27 23:34:33 +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
2007-10-18 16:44:11 +00:00
if ( imp - > ianacode < 128 ) {
if ( already_did [ imp - > ianacode ] ) {
continue ;
}
already_did [ imp - > ianacode ] = 1 ;
}
2008-05-27 04:54:52 +00:00
2007-12-12 21:53:32 +00:00
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " %d " , imp - > ianacode ) ;
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 " ) ;
2007-04-19 21:40:50 +00: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 ) ;
2008-02-09 00:38:23 +00:00
pass_fmtp = NULL ;
2008-02-07 22:42:27 +00:00
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-05-27 04:54:52 +00:00
}
2008-02-09 00:38:23 +00:00
if ( ov_fmtp ) {
pass_fmtp = ov_fmtp ;
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 ] ;
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 ;
}
2007-10-18 16:44:11 +00:00
if ( imp - > ianacode < 128 ) {
if ( already_did [ imp - > ianacode ] ) {
continue ;
}
already_did [ imp - > 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 ;
}
2007-11-20 02:27:48 +00:00
2008-05-27 04:54:52 +00:00
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " a=rtpmap:%d %s/%d \n " , imp - > ianacode , imp - > iananame ,
imp - > samples_per_second ) ;
2007-04-19 21:40:50 +00:00
if ( imp - > fmtp ) {
2007-12-12 21:53:32 +00:00
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " a=fmtp:%d %s \n " , imp - > ianacode , imp - > fmtp ) ;
2008-02-07 22:42:27 +00:00
} else {
if ( pass_fmtp ) {
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " a=fmtp:%d %s \n " , imp - > ianacode , pass_fmtp ) ;
}
2007-04-19 21:40:50 +00: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 ;
2009-11-24 18:52:57 +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 ;
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
}
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 ;
}
}
}
2009-11-24 18:52:57 +00: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 */
for ( x = 0 ; x < TFLAG_MAX ; x + + ) {
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 ;
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 ) {
tech_pvt - > te = tech_pvt - > bte ;
} else if ( ! tech_pvt - > te ) {
tech_pvt - > te = profile - > te ;
}
2007-12-22 00:32:20 +00:00
tech_pvt - > dtmf_type = profile - > dtmf_type ;
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 ) ;
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 ) ;
2009-10-14 19:26:10 +00:00
2007-03-31 19:01:33 +00:00
switch_core_session_set_private ( session , tech_pvt ) ;
2007-12-12 21:53:32 +00:00
switch_snprintf ( name , sizeof ( name ) , " sofia/%s/%s " , profile - > name , channame ) ;
2009-06-18 15:59:28 +00:00
if ( ( p = strchr ( name , ' ; ' ) ) ) {
* p = ' \0 ' ;
}
2007-05-09 19:30:41 +00:00
switch_channel_set_name ( tech_pvt - > channel , name ) ;
2007-03-31 19:01:33 +00:00
}
2009-08-17 00:32:26 +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 ) ) {
2009-02-10 01:48:21 +00:00
* ip = switch_core_strdup ( pool , profile - > rtpip ) ;
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
}
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 + + ) {
2009-02-09 17:56:38 +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 ) {
if ( myport = = * port & & ! strcmp ( * ip , tech_pvt - > profile - > 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 {
2009-08-17 00:32:26 +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
out :
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
{
2009-08-17 00:32:26 +00:00
char * lookup_rtpip = tech_pvt - > profile - > rtpip ; /* Pointer to externally looked up address */
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 */
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 ) {
switch_rtp_release_port ( tech_pvt - > profile - > 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 */
2007-12-11 19:15:02 +00:00
if ( ! ( tech_pvt - > local_sdp_audio_port = switch_rtp_request_port ( tech_pvt - > profile - > 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
tech_pvt - > local_sdp_audio_ip = tech_pvt - > profile - > rtpip ;
2007-03-31 19:01:33 +00:00
sdp_port = tech_pvt - > local_sdp_audio_port ;
2009-08-17 00:32:26 +00:00
if ( ! ( use_ip = switch_channel_get_variable ( tech_pvt - > channel , " rtp_adv_audio_ip " ) )
2009-10-23 16:03:42 +00:00
& & ! zstr ( tech_pvt - > profile - > extrtpip ) ) {
2008-07-18 16:18:31 +00:00
use_ip = tech_pvt - > profile - > extrtpip ;
}
if ( use_ip ) {
2009-07-29 19:39:28 +00:00
if ( sofia_glue_ext_address_lookup ( tech_pvt - > profile , tech_pvt , & lookup_rtpip , & sdp_port ,
2009-08-17 00:32:26 +00:00
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 ;
} else {
if ( lookup_rtpip = = use_ip ) {
/* sofia_glue_ext_address_lookup didn't return any error, but the return IP is the same as the original one,
which means no lookup was necessary . Check if NAT is detected */
if ( 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 ) ;
} else {
/* No NAT detected */
use_ip = tech_pvt - > profile - > rtpip ;
}
} else {
/* Address properly resolved, use it as external ip */
use_ip = lookup_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 */
use_ip = tech_pvt - > profile - > rtpip ;
2009-06-03 21:08:34 +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
2007-05-09 19:30:41 +00:00
switch_channel_set_variable ( tech_pvt - > channel , SWITCH_LOCAL_MEDIA_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_MEDIA_PORT_VARIABLE , " %d " , sdp_port ) ;
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
{
2009-08-17 00:32:26 +00:00
char * lookup_rtpip = tech_pvt - > profile - > rtpip ; /* Pointer to externally looked up address */
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 ) {
switch_rtp_release_port ( tech_pvt - > profile - > rtpip , tech_pvt - > local_sdp_video_port ) ;
}
2009-08-17 00:32:26 +00:00
/* Request a local port from the core's allocator */
2007-12-11 19:15:02 +00:00
if ( ! ( tech_pvt - > local_sdp_video_port = switch_rtp_request_port ( tech_pvt - > profile - > 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
2009-08-17 00:32:26 +00:00
if ( ! ( use_ip = switch_channel_get_variable ( tech_pvt - > channel , " rtp_adv_video_ip " ) )
2009-10-23 16:03:42 +00:00
& & ! zstr ( tech_pvt - > profile - > extrtpip ) ) {
2009-08-17 00:32:26 +00:00
use_ip = tech_pvt - > profile - > extrtpip ;
2007-04-19 21:40:50 +00:00
}
2009-08-17 00:32:26 +00:00
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 ;
} else {
if ( lookup_rtpip = = use_ip ) {
/* sofia_glue_ext_address_lookup didn't return any error, but the return IP is the same as the original one,
which means no lookup was necessary . Check if NAT is detected */
if ( 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 ) ;
} else {
/* No NAT detected */
use_ip = tech_pvt - > profile - > rtpip ;
}
} else {
/* Address properly resolved, use it as external ip */
use_ip = lookup_rtpip ;
}
}
} else {
/* No NAT traversal required, use the profile's rtp ip */
use_ip = tech_pvt - > profile - > rtpip ;
2009-06-03 21:08:34 +00:00
}
2009-06-05 02:30:44 +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 ;
}
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 ;
}
sofia_transport_t sofia_glue_via2transport ( const sip_via_t * via )
{
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 " ;
}
}
2009-06-03 21:08:34 +00:00
char * sofia_glue_create_external_via ( switch_core_session_t * session , sofia_profile_t * profile , sofia_transport_t transport )
{
return sofia_glue_create_via ( session ,
profile - > extsipip ,
( sofia_glue_transport_has_tls ( transport ) )
? profile - > tls_sip_port : profile - > sip_port ,
transport ) ;
}
char * sofia_glue_create_via ( switch_core_session_t * session , const char * ip , switch_port_t port , sofia_transport_t transport )
{
if ( port & & port ! = 5060 ) {
if ( session ) {
return switch_core_session_sprintf ( session , " SIP/2.0/%s %s:%d;rport " , sofia_glue_transport2str ( transport ) , ip , port ) ;
} else {
return switch_mprintf ( " SIP/2.0/%s %s:%d;rport " , sofia_glue_transport2str ( transport ) , ip , port ) ;
}
} 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 )
{
2009-12-02 18:46:17 +00:00
return ( profile - > extsipip & & ! 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 ;
}
}
2009-06-03 21:08:34 +00:00
void sofia_glue_get_addr ( msg_t * msg , char * buf , size_t buflen , int * port ) {
su_addrinfo_t * addrinfo = msg_addrinfo ( msg ) ;
if ( buf ) {
get_addr ( buf , buflen , addrinfo - > ai_addr , addrinfo - > ai_addrlen ) ;
}
if ( port ) {
* port = get_port ( addrinfo - > ai_addr ) ;
}
}
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 */
if ( ( p = ( char * ) switch_stristr ( " ;fs_ " , stripped ) ) ) {
* p = ' \0 ' ;
}
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 ;
2009-03-20 01:52:53 +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 ;
}
2008-07-03 18:50:15 +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 ) ;
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 ) ) {
2008-09-29 23:03:27 +00:00
if ( switch_rtp_set_remote_address ( tech_pvt - > video_rtp_session , tech_pvt - > remote_sdp_video_ip ,
tech_pvt - > remote_sdp_video_port , SWITCH_TRUE , & err ) ! =
2008-05-23 22:30:50 +00:00
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 ) ;
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 ;
}
2009-03-20 01:52:53 +00:00
if ( switch_rtp_set_remote_address ( tech_pvt - > rtp_session , tech_pvt - > remote_sdp_audio_ip ,
tech_pvt - > remote_sdp_audio_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. */
switch_rtp_set_flag ( tech_pvt - > 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-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 ;
2009-03-20 01:52:53 +00:00
char * p , * q , * pe , * qe ;
2008-07-18 19:18:24 +00:00
int has_video = 0 , has_audio = 0 , has_ip = 0 ;
char port_buf [ 25 ] = " " ;
char vport_buf [ 25 ] = " " ;
2009-03-20 01:52:53 +00:00
char * new_sdp ;
int bad = 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 ;
2009-11-27 19:02:20 +00:00
if ( switch_channel_test_flag ( tech_pvt - > channel , CF_ANSWERED ) & &
( switch_stristr ( " sendonly " , tech_pvt - > local_sdp_str ) | | switch_stristr ( " 0.0.0.0 " , tech_pvt - > local_sdp_str ) ) ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_DEBUG , " Skip patch on hold SDP \n " ) ;
2008-07-18 19:18:24 +00:00
return ;
2008-05-23 12:39:35 +00:00
}
2008-07-18 19:18: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 ) {
2008-07-18 19:18:24 +00:00
if ( sofia_glue_tech_choose_port ( tech_pvt , 1 ) ! = SWITCH_STATUS_SUCCESS ) {
2009-08-13 20:35:02 +00:00
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
}
2008-07-18 19:18: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 ) ;
2009-03-20 01:52:53 +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
2008-07-18 19:18:24 +00:00
while ( p & & * p ) {
2009-03-20 01:52:53 +00:00
if ( p > = pe ) {
bad = 1 ;
goto end ;
}
if ( q > = qe ) {
bad = 2 ;
goto end ;
}
2008-07-19 15:16:29 +00:00
if ( tech_pvt - > adv_sdp_audio_ip & & ! strncmp ( " c=IN IP " , p , 7 ) ) {
2008-07-18 19:18:24 +00:00
strncpy ( q , p , 9 ) ;
p + = 9 ;
q + = 9 ;
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
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 + + ;
}
2008-07-18 19:18:24 +00:00
has_ip + + ;
2008-05-27 04:54:52 +00:00
2008-09-25 20:59:09 +00:00
} else if ( ! strncmp ( " m=audio " , p , 8 ) | | ( ! 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 ;
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
2008-07-18 19:18:24 +00:00
has_audio + + ;
} else if ( ! strncmp ( " m=video " , p , 8 ) ) {
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 + + ;
}
2009-03-20 01:52:53 +00:00
2008-07-18 19:18:24 +00:00
has_video + + ;
}
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 + + ;
}
2009-03-20 01:52:53 +00:00
if ( p > = pe ) {
bad = 14 ;
goto end ;
}
if ( q > = qe ) {
bad = 15 ;
goto end ;
}
2008-07-18 19:18: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
2009-03-20 01:52:53 +00:00
end :
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 ;
}
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 ) ;
tech_pvt - > local_sdp_str = dup ? switch_core_session_strdup ( tech_pvt - > session , sdp_str ) : ( char * ) sdp_str ;
switch_mutex_unlock ( tech_pvt - > sofia_mutex ) ;
2008-02-21 17:48:41 +00:00
}
2009-08-11 00:54:39 +00:00
char * sofia_glue_get_extra_headers ( switch_channel_t * channel , const char * prefix )
{
char * extra_headers = NULL ;
switch_stream_handle_t stream = { 0 } ;
switch_event_header_t * hi = NULL ;
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 ) ;
stream . write_function ( & stream , " %s: %s \r \n " , hname , value ) ;
}
}
switch_channel_variable_last ( channel ) ;
}
2009-10-23 16:03:42 +00:00
if ( ! zstr ( ( char * ) stream . data ) ) {
2009-08-11 00:54:39 +00:00
extra_headers = stream . data ;
} else {
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 ] = " " ;
if ( ! sip | | ! channel ) {
return ;
}
for ( un = sip - > sip_unknown ; un ; un = un - > un_next ) {
if ( ! strncasecmp ( un - > un_name , " X- " , 2 ) | | ! 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-01-21 00:12: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-01-20 19:20:11 +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 ;
}
sofia_glue_set_local_sdp ( tech_pvt , NULL , 0 , NULL , 0 ) ;
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-21 00:12:24 +00:00
char * d_url = NULL , * url = NULL , * dest_host = 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 ;
2007-11-21 00:56:41 +00:00
char * rpid_domain = " cluecon.com " , * 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 " ) ;
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-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 ;
}
if ( ( d_url = sofia_glue_get_url_from_contact ( tech_pvt - > dest , 1 ) ) ) {
url = d_url ;
} else {
url = tech_pvt - > dest ;
}
url_str = url ;
if ( ( dest_host = strchr ( url_str , ' @ ' ) ) ) {
dest_host + + ;
}
if ( ! tech_pvt - > from_str ) {
const char * sipip ;
const char * format ;
const char * alt = NULL ;
sipip = tech_pvt - > profile - > sipip ;
if ( sofia_glue_check_nat ( tech_pvt - > profile , dest_host ) ) {
sipip = tech_pvt - > profile - > extsipip ;
}
format = strchr ( sipip , ' : ' ) ? " \" %s \" <sip:%s%s[%s]> " : " \" %s \" <sip:%s%s%s> " ;
if ( ( alt = switch_channel_get_variable ( channel , " sip_invite_domain " ) ) ) {
sipip = alt ;
}
tech_pvt - > from_str =
switch_core_session_sprintf ( tech_pvt - > session ,
format ,
cid_name ,
cid_num ,
! zstr ( cid_num ) ? " @ " : " " ,
sipip ) ;
}
2009-03-04 18:19:30 +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 ) ) {
2009-03-11 13:15:02 +00:00
rpid_domain = switch_core_session_strdup ( session , tech_pvt - > from_str ) ;
}
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 ' ;
}
}
if ( ! 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
2009-06-03 21:08:34 +00:00
if ( sofia_glue_check_nat ( tech_pvt - > profile , tech_pvt - > remote_ip ) ) {
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 ) ) {
2008-07-28 17:09:51 +00:00
const char * contact ;
if ( ( contact = switch_channel_get_variable ( channel , " sip_contact_user " ) ) ) {
2009-06-03 21:08:34 +00:00
char * ip_addr ;
char * ipv6 ;
if ( sofia_glue_check_nat ( tech_pvt - > profile , tech_pvt - > remote_ip ) ) {
ip_addr = ( switch_check_network_list_ip ( tech_pvt - > remote_ip , tech_pvt - > profile - > local_network ) )
? tech_pvt - > profile - > sipip : tech_pvt - > profile - > extsipip ;
} else {
ip_addr = tech_pvt - > profile - > extsipip ? tech_pvt - > profile - > extsipip : tech_pvt - > profile - > sipip ;
}
ipv6 = strchr ( ip_addr , ' : ' ) ;
2008-07-28 17:09:51 +00:00
if ( sofia_glue_transport_has_tls ( tech_pvt - > transport ) ) {
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 ) ;
} else {
2008-12-01 23:10:15 +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 - > 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 {
2009-06-03 21:08:34 +00:00
if ( sofia_glue_check_nat ( tech_pvt - > profile , tech_pvt - > remote_ip ) ) {
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 ) ;
2009-02-25 20:22:12 +00:00
from_str = sofia_overcome_sip_uri_weakness ( session , 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
2007-12-18 19:12:45 +00:00
/*
2007-11-19 17:09:46 +00: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 ?
2008-05-27 04:54:52 +00:00
*/
2007-11-19 17:09:46 +00:00
use_from_str = 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 {
2009-03-11 15:14:24 +00:00
from_str = switch_core_session_sprintf ( session , " \" %s \" <%s> " , from_display ? from_display :
tech_pvt - > caller_profile - > caller_id_name , use_from_str ) ;
2008-11-24 23:12:36 +00:00
}
2008-05-29 17:35:16 +00:00
2008-11-15 02:46:25 +00:00
if ( ! ( call_id = switch_channel_get_variable ( channel , " sip_outgoing_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
}
2008-06-26 20:19:09 +00:00
tech_pvt - > nh = nua_handle ( tech_pvt - > profile - > nua , NULL ,
NUTAG_URL ( url_str ) ,
2008-11-15 02:46:25 +00:00
TAG_IF ( call_id , SIPTAG_CALL_ID_STR ( call_id ) ) ,
2008-06-26 20:19:09 +00:00
SIPTAG_TO_STR ( to_str ) ,
SIPTAG_FROM_STR ( from_str ) ,
SIPTAG_CONTACT_STR ( invite_contact ) ,
TAG_END ( ) ) ;
2007-03-31 19:01:33 +00:00
2008-07-03 16:48:05 +00:00
if ( tech_pvt - > dest & & ( strstr ( tech_pvt - > dest , " ;fs_nat " ) | | strstr ( tech_pvt - > dest , " ;received " )
| | ( ( 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
}
2009-03-04 16:02:02 +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 ) ;
2009-11-15 02:16:10 +00:00
} else {
cid_type = tech_pvt - > cid_type ;
2009-03-04 23:03:25 +00:00
}
2009-11-15 02:16:10 +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 ) ) {
tech_pvt - > asserted_id = switch_core_session_sprintf ( tech_pvt - > session , " \" %s \" <sip:%s@%s> " ,
tech_pvt - > caller_profile - > caller_id_name ,
tech_pvt - > caller_profile - > caller_id_number ,
rpid_domain ) ;
} else {
tech_pvt - > preferred_id = switch_core_session_sprintf ( tech_pvt - > session , " \" %s \" <sip:%s@%s> " ,
tech_pvt - > caller_profile - > caller_id_name ,
tech_pvt - > caller_profile - > caller_id_number ,
rpid_domain ) ;
}
2009-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 " ;
}
if ( switch_test_flag ( caller_profile , SWITCH_CPF_SCREEN ) ) {
screen = " yes " ;
}
2009-11-11 03:53:50 +00:00
if ( ! strcasecmp ( tech_pvt - > caller_profile - > caller_id_name , " _undef_ " ) ) {
tech_pvt - > rpid = switch_core_session_sprintf ( tech_pvt - > session , " <sip:%s@%s>;party=calling;screen=%s;privacy=%s " ,
tech_pvt - > caller_profile - > caller_id_number , rpid_domain , screen , priv ) ;
} else {
tech_pvt - > rpid = switch_core_session_sprintf ( tech_pvt - > session , " \" %s \" <sip:%s@%s>;party=calling;screen=%s;privacy=%s " ,
tech_pvt - > caller_profile - > caller_id_name ,
tech_pvt - > caller_profile - > caller_id_number , rpid_domain , screen , priv ) ;
}
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
2007-10-03 23:42:40 +00:00
if ( ! ( sofia_private = malloc ( 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 + + ;
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 ) ;
}
2007-09-23 20:08:26 +00:00
if ( tech_pvt - > e_dest ) {
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 ;
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
}
2009-06-19 15:35:26 +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 ;
}
2009-03-04 18:19:30 +00:00
2008-10-21 18:14:37 +00:00
if ( route_uri ) {
2009-08-13 20:35:02 +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-01-22 00:51:32 +00:00
switch_channel_clear_flag ( channel , CF_MEDIA_ACK ) ;
2010-01-07 05:22:02 +00:00
if ( sofia_use_soa ( tech_pvt ) ) {
nua_invite ( tech_pvt - > nh ,
NUTAG_AUTOANSWER ( 0 ) ,
NUTAG_SESSION_TIMER ( session_timeout ) ,
TAG_IF ( tech_pvt - > redirected , NUTAG_URL ( tech_pvt - > redirected ) ) ,
TAG_IF ( ! zstr ( tech_pvt - > user_via ) , SIPTAG_VIA_STR ( tech_pvt - > user_via ) ) ,
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 ) ) ,
TAG_IF ( sofia_test_pflag ( tech_pvt - > profile , PFLAG_PASS_CALLEE_ID ) , SIPTAG_HEADER_STR ( " X-FS-Support: " FREESWITCH_SUPPORT ) ) ,
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 ) ) ,
TAG_IF ( tech_pvt - > profile - > minimum_session_expires , NUTAG_MIN_SE ( tech_pvt - > profile - > minimum_session_expires ) ) ,
SOATAG_ADDRESS ( tech_pvt - > adv_sdp_audio_ip ) ,
SOATAG_USER_SDP_STR ( tech_pvt - > local_sdp_str ) ,
SOATAG_REUSE_REJECTED ( 1 ) ,
SOATAG_ORDERED_USER ( 1 ) ,
SOATAG_RTP_SORT ( SOA_RTP_SORT_REMOTE ) ,
2010-01-12 00:05:11 +00:00
SOATAG_RTP_SELECT ( SOA_RTP_SELECT_ALL ) ,
TAG_IF ( rep , SIPTAG_REPLACES_STR ( rep ) ) ,
SOATAG_HOLD ( holdstr ) ,
TAG_END ( ) ) ;
2010-01-07 05:22:02 +00:00
} else {
nua_invite ( tech_pvt - > nh ,
NUTAG_AUTOANSWER ( 0 ) ,
NUTAG_SESSION_TIMER ( session_timeout ) ,
TAG_IF ( tech_pvt - > redirected , NUTAG_URL ( tech_pvt - > redirected ) ) ,
TAG_IF ( ! zstr ( tech_pvt - > user_via ) , SIPTAG_VIA_STR ( tech_pvt - > user_via ) ) ,
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 ) ) ,
TAG_IF ( sofia_test_pflag ( tech_pvt - > profile , PFLAG_PASS_CALLEE_ID ) , SIPTAG_HEADER_STR ( " X-FS-Support: " FREESWITCH_SUPPORT ) ) ,
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 ) ) ,
TAG_IF ( tech_pvt - > profile - > minimum_session_expires , NUTAG_MIN_SE ( tech_pvt - > profile - > minimum_session_expires ) ) ,
NUTAG_MEDIA_ENABLE ( 0 ) ,
SIPTAG_CONTENT_TYPE_STR ( " application/sdp " ) ,
SIPTAG_PAYLOAD_STR ( tech_pvt - > local_sdp_str ) ,
TAG_IF ( rep , SIPTAG_REPLACES_STR ( rep ) ) ,
2010-01-12 00:05:11 +00:00
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 ) ;
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 ;
2009-06-03 21:08:34 +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 ) ;
2009-06-03 21:08:34 +00:00
if ( sofia_glue_check_nat ( tech_pvt - > profile , tech_pvt - > remote_ip ) ) {
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
2008-07-03 18:50:15 +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 ,
2007-11-20 02:27:48 +00:00
SIPTAG_TO_STR ( tech_pvt - > dest ) ,
2009-06-03 21:08:34 +00:00
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
# define add_stat(_i, _s) \
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 " ) ;
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 " ) ;
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 ) {
set_stats ( tech_pvt - > rtp_session , tech_pvt , " audio " ) ;
}
if ( tech_pvt - > video_rtp_session ) {
set_stats ( tech_pvt - > video_rtp_session , tech_pvt , " video " ) ;
}
}
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 - > rtp_session ) {
2007-03-31 19:01:33 +00:00
switch_rtp_destroy ( & tech_pvt - > rtp_session ) ;
2008-03-10 16:13:12 +00:00
} else if ( tech_pvt - > local_sdp_audio_port ) {
switch_rtp_release_port ( tech_pvt - > profile - > rtpip , tech_pvt - > local_sdp_audio_port ) ;
2007-03-31 19:01:33 +00:00
}
2008-02-15 16:15:32 +00:00
2009-06-03 21:08:34 +00:00
if ( tech_pvt - > local_sdp_audio_port > 0 & & sofia_glue_check_nat ( tech_pvt - > profile , tech_pvt - > remote_ip ) ) {
switch_nat_del_mapping ( ( switch_port_t ) tech_pvt - > local_sdp_audio_port , SWITCH_NAT_UDP ) ;
}
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 ) {
switch_rtp_release_port ( tech_pvt - > profile - > rtpip , tech_pvt - > local_sdp_video_port ) ;
2007-04-19 21:40:50 +00:00
}
2008-02-15 16:15:32 +00:00
2009-06-03 21:08:34 +00:00
if ( tech_pvt - > local_sdp_video_port > 0 & & sofia_glue_check_nat ( tech_pvt - > profile , tech_pvt - > remote_ip ) ) {
switch_nat_del_mapping ( ( switch_port_t ) tech_pvt - > local_sdp_video_port , SWITCH_NAT_UDP ) ;
}
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 {
2009-08-13 20:35:02 +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 {
int ms ;
tech_pvt - > video_read_frame . rate = tech_pvt - > video_rm_rate ;
2008-10-20 17:48:42 +00:00
ms = tech_pvt - > video_write_codec . implementation - > microseconds_per_packet / 1000 ;
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 ) ;
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
{
2007-12-13 04:01:29 +00:00
int ms ;
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 | |
2009-12-22 03:55:29 +00:00
tech_pvt - > codec_ms ! = ( uint32_t ) tech_pvt - > read_impl . microseconds_per_packet / 1000 ) {
2009-12-03 22:51:50 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_DEBUG , " Changing Codec from %s@%dms to %s@%dms \n " ,
tech_pvt - > read_impl . iananame , tech_pvt - > read_impl . microseconds_per_packet / 1000 ,
tech_pvt - > rm_encoding , tech_pvt - > codec_ms ) ;
2009-12-19 18:28:15 +00:00
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 ;
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
}
}
2008-11-10 18:26:41 +00:00
2007-03-31 19:01:33 +00:00
if ( switch_core_codec_init ( & 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 ,
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 " ) ;
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
if ( switch_core_codec_init ( & tech_pvt - > write_codec ,
tech_pvt - > iananame ,
tech_pvt - > rm_fmtp ,
tech_pvt - > rm_rate ,
tech_pvt - > codec_ms ,
1 ,
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 " ) ;
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
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 ) ;
2009-12-03 22:51:50 +00:00
if ( switch_rtp_change_interval ( tech_pvt - > rtp_session ,
tech_pvt - > read_impl . microseconds_per_packet ,
tech_pvt - > read_impl . samples_per_packet
) ! = SWITCH_STATUS_SUCCESS ) {
switch_channel_hangup ( tech_pvt - > channel , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
switch_goto_status ( SWITCH_STATUS_FALSE , end ) ;
}
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 ;
2008-10-20 17:48:42 +00:00
ms = tech_pvt - > write_codec . implementation - > microseconds_per_packet / 1000 ;
2007-12-13 04:01:29 +00:00
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
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_DEBUG , " Set Codec %s %s/%ld %d ms %d samples \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 ,
2009-01-12 18:37:44 +00:00
tech_pvt - > read_impl . samples_per_packet ) ;
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 ) ;
}
2008-12-18 23:07:32 +00:00
end :
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 ] ;
int index ;
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
index = atoi ( key_str ) ;
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
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
{
int bw , ms ;
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
}
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
}
2009-01-12 18:37:44 +00:00
bw = tech_pvt - > read_impl . bits_per_second ;
ms = tech_pvt - > read_impl . microseconds_per_packet ;
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 ) & &
! ( ( 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 ) ;
2008-07-07 17:56:16 +00:00
} else {
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
2007-12-22 00:32:20 +00:00
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 {
tech_pvt - > dtmf_type = tech_pvt - > profile - > dtmf_type ;
}
}
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 ) | |
2007-07-06 16:19:40 +00: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
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 ) {
2009-08-13 20:35:02 +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 ) ) ;
2008-05-14 14:13:40 +00:00
goto video ;
2008-09-18 21:50:18 +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 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 ) ;
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 ) ;
2007-05-09 19:30:41 +00:00
switch_channel_set_variable ( tech_pvt - > channel , SWITCH_LOCAL_MEDIA_IP_VARIABLE , tech_pvt - > adv_sdp_audio_ip ) ;
switch_channel_set_variable ( tech_pvt - > channel , SWITCH_LOCAL_MEDIA_PORT_VARIABLE , tmp ) ;
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 ) ) {
sofia_clear_flag_locked ( tech_pvt , TFLAG_REINVITE ) ;
2008-09-18 21:50:18 +00:00
2008-09-29 23:03:27 +00:00
if ( switch_rtp_set_remote_address ( tech_pvt - > rtp_session , tech_pvt - > remote_sdp_audio_ip , tech_pvt - > remote_sdp_audio_port , SWITCH_TRUE , & err ) ! =
2007-03-31 19:01:33 +00:00
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
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 ,
( switch_rtp_flag_t ) flags , timer_name , & err ,
switch_core_session_get_pool ( tech_pvt - > session ) ) ;
}
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 ;
2009-04-23 13:15:03 +00:00
switch_channel_set_flag ( tech_pvt - > channel , CF_FS_RTP ) ;
2008-07-18 16:18:31 +00:00
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 ) ;
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 ) ;
2009-02-09 17:56:38 +00:00
sofia_set_flag ( tech_pvt , TFLAG_RTP ) ;
sofia_set_flag ( tech_pvt , TFLAG_IO ) ;
2008-12-29 21:23:17 +00:00
switch_rtp_intentional_bugs ( tech_pvt - > rtp_session , tech_pvt - > rtp_bugs ) ;
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 ) {
2009-08-13 20:35:02 +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 ) ;
2008-07-18 20:25:39 +00:00
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
}
2007-05-09 19:30:41 +00:00
if ( ( val = switch_channel_get_variable ( tech_pvt - > channel , " jitterbuffer_msec " ) ) ) {
2007-05-04 23:29:35 +00:00
int len = atoi ( val ) ;
2008-05-27 04:54:52 +00:00
2007-05-04 23:29:35 +00:00
if ( len < 100 | | len > 1000 ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_ERROR , " Invalid Jitterbuffer spec [%d] must be between 100 and 1000 \n " , len ) ;
2007-05-04 23:29:35 +00:00
} else {
int qlen ;
2009-01-12 18:37:44 +00:00
qlen = len / ( tech_pvt - > read_impl . microseconds_per_packet / 1000 ) ;
2008-05-27 04:54:52 +00:00
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_DEBUG , " Setting Jitterbuffer to %dms (%d frames) \n " , len , qlen ) ;
2007-05-04 23:29:35 +00:00
switch_rtp_activate_jitter_buffer ( tech_pvt - > rtp_session , qlen ) ;
}
}
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 ) {
2009-01-12 18:37:44 +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 ) {
2009-01-12 18:37:44 +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 ) {
switch_rtp_set_telephony_event ( tech_pvt - > rtp_session , tech_pvt - > te ) ;
}
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 ) ;
2008-05-27 04:54:52 +00: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 ) {
/******************************************************************************************/
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 ) ;
if ( remote_host & & remote_port & & ! strcmp ( remote_host , tech_pvt - > remote_sdp_video_ip ) & & remote_port = = tech_pvt - > remote_sdp_video_port ) {
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 ) ) ;
goto video_up ;
} else {
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 " ,
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 ) ) {
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 " ,
2009-11-18 19:22:45 +00:00
switch_channel_get_name ( tech_pvt - > channel ) ,
2009-11-20 02:17:08 +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 , tech_pvt - > read_impl . microseconds_per_packet / 1000 ) ;
2009-11-18 19:22:45 +00:00
}
2009-11-20 02:17:08 +00:00
switch_snprintf ( tmp , sizeof ( tmp ) , " %d " , tech_pvt - > local_sdp_video_port ) ;
switch_channel_set_variable ( tech_pvt - > channel , SWITCH_LOCAL_MEDIA_IP_VARIABLE , tech_pvt - > adv_sdp_audio_ip ) ;
switch_channel_set_variable ( tech_pvt - > channel , SWITCH_LOCAL_MEDIA_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 ) ) {
sofia_clear_flag_locked ( tech_pvt , TFLAG_REINVITE ) ;
2009-11-18 19:22:45 +00:00
2009-11-20 02:17:08 +00:00
if ( switch_rtp_set_remote_address ( tech_pvt - > video_rtp_session , tech_pvt - > remote_sdp_video_ip , tech_pvt - > remote_sdp_video_port , SWITCH_TRUE , & err ) ! =
SWITCH_STATUS_SUCCESS ) {
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 ) ;
}
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
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
/******************************************************************************************/
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 ) ) ) {
flags = ( switch_rtp_flag_t ) ( SWITCH_RTP_FLAG_USE_TIMER | SWITCH_RTP_FLAG_AUTOADJ |
2009-11-18 19:22:45 +00:00
SWITCH_RTP_FLAG_DATAWAIT | SWITCH_RTP_FLAG_RAW_WRITE ) ;
2008-07-07 17:56:16 +00:00
} else {
2009-11-18 19:22:45 +00:00
flags = ( switch_rtp_flag_t ) ( SWITCH_RTP_FLAG_USE_TIMER | 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 ) ;
flags | = SWITCH_RTP_FLAG_VIDEO | SWITCH_RTP_FLAG_PROXY_MEDIA ;
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
if ( switch_rtp_ready ( tech_pvt - > video_rtp_session ) ) {
2007-05-09 19:30:41 +00:00
switch_channel_set_flag ( tech_pvt - > channel , CF_VIDEO ) ;
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
}
2009-11-18 19:22:45 +00:00
video_up :
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
end :
2008-02-25 16:35:19 +00:00
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
}
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
{
char buf [ 1024 ] = { 0 } ;
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 ) ;
2009-04-08 06:05:56 +00:00
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 ;
if ( m - > m_type = = sdp_media_image & & m - > m_port ) {
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 ;
}
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 ;
}
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-06-03 21:08:34 +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-06-03 21:08:34 +00:00
if ( ptime > 0 ) {
2009-05-04 22:53:41 +00:00
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " ,%s@%uh@%di " , imp - > iananame , ( unsigned int ) map - > rm_rate , ptime ) ;
} 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 ;
}
}
}
} 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 ) {
if ( map - > rm_pt > 127 | | already_did [ map - > rm_pt ] ) {
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 ) {
2009-05-04 22:53:41 +00:00
switch_snprintf ( buf + strlen ( buf ) , sizeof ( buf ) - strlen ( buf ) , " ,%s@%uh@%di " , imp - > iananame , ( unsigned int ) map - > rm_rate , ptime ) ;
} 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
{
2007-10-05 15:47:48 +00:00
sdp_parser_t * parser = NULL ;
2007-03-31 19:01:33 +00:00
sdp_session_t * sdp ;
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 ;
}
2009-03-20 01:52:53 +00:00
if ( ( parser = sdp_parse ( NULL , r_sdp , ( int ) strlen ( r_sdp ) , 0 ) ) ) {
if ( tech_pvt - > num_codecs ) {
if ( ( sdp = sdp_session ( parser ) ) ) {
match = sofia_glue_negotiate_sdp ( tech_pvt - > session , sdp ) ;
}
2007-03-31 19:01:33 +00:00
}
2009-03-20 01:52:53 +00:00
2007-03-31 19:01:33 +00:00
sdp_parser_free ( parser ) ;
}
if ( match ) {
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 ;
}
2008-09-18 21:50:18 +00:00
void sofia_glue_toggle_hold ( private_object_t * tech_pvt , int sendonly )
2007-03-31 19:01:33 +00:00
{
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 " ;
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-01-13 23:58:00 +00:00
switch_channel_presence ( tech_pvt - > channel , " unknown " , msg , NULL ) ;
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
}
2008-01-03 21:34:44 +00:00
2007-06-24 03:17:21 +00:00
if ( ! ( stream = switch_channel_get_variable ( tech_pvt - > channel , SWITCH_HOLD_MUSIC_VARIABLE ) ) ) {
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 {
2009-12-10 01:29:02 +00:00
switch_ivr_broadcast ( switch_channel_get_variable ( tech_pvt - > channel , SWITCH_SIGNAL_BOND_VARIABLE ) , stream ,
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 ) ;
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 ) ;
2008-09-18 21:50:18 +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 ) ;
2008-08-25 16:30:28 +00:00
switch_channel_presence ( tech_pvt - > channel , " unknown " , " unhold " , NULL ) ;
2007-06-24 03:17:21 +00:00
}
}
2008-09-18 21:50:18 +00:00
}
uint8_t sofia_glue_negotiate_sdp ( switch_core_session_t * session , sdp_session_t * sdp )
{
uint8_t match = 0 ;
switch_payload_t te = 0 , cng_pt = 0 ;
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 ;
2008-09-18 21:50:18 +00:00
int sendonly = 0 ;
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 ;
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 ) ;
if ( ! greedy | | ! scrooge ) {
if ( ( val = switch_channel_get_variable ( channel , " sip_codec_negotiation " ) ) ) {
if ( ! strcasecmp ( val , " greedy " ) ) {
greedy = 1 ;
} else if ( ! strcasecmp ( val , " scrooge " ) ) {
scrooge = 1 ;
greedy = 1 ;
}
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
}
}
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 ;
2009-08-13 20:35:02 +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 "
" Don't worry, DTMF will work but you may want to ask them to fix it...... \n "
) ;
}
2008-12-12 22:34:41 +00:00
}
2008-09-18 21:50:18 +00:00
}
if ( ( m = sdp - > sdp_media ) & & ( m - > m_mode = = sdp_sendonly | | m - > m_mode = = sdp_inactive ) ) {
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 ;
} 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
}
}
if ( ! tech_pvt - > hold_laps ) {
tech_pvt - > hold_laps + + ;
sofia_glue_toggle_hold ( tech_pvt , sendonly ) ;
}
2007-06-24 03:17:21 +00:00
2007-03-31 19:01:33 +00:00
for ( m = sdp - > sdp_media ; m ; m = m - > m_next ) {
sdp_connection_t * connection ;
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 ) {
switch_t38_options_t * t38_options = switch_core_session_alloc ( tech_pvt - > session , sizeof ( switch_t38_options_t ) ) ;
for ( attr = m - > m_attributes ; attr ; attr = attr - > a_next ) {
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 " ) ) {
t38_options - > T38FaxFillBitRemoval = SWITCH_TRUE ;
} else if ( ! strcasecmp ( attr - > a_name , " T38FaxTranscodingMMR " ) ) {
t38_options - > T38FaxTranscodingMMR = SWITCH_TRUE ;
} else if ( ! strcasecmp ( attr - > a_name , " T38FaxTranscodingJBIG " ) ) {
t38_options - > T38FaxTranscodingJBIG = SWITCH_TRUE ;
} 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 ) ;
2009-01-08 19:45:44 +00:00
//switch_channel_set_flag(tech_pvt->channel, CF_PROXY_MEDIA);
//switch_rtp_set_flag(tech_pvt->rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA);
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 ;
2008-01-17 06:23:23 +00:00
for ( attr = m - > m_attributes ; attr ; attr = attr - > a_next ) {
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
}
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 ;
2009-05-14 00:15:06 +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
greed :
2007-06-10 02:52:23 +00:00
x = 0 ;
2008-01-03 00:50:53 +00:00
2009-10-21 23:01:37 +00:00
if ( tech_pvt - > rm_encoding ) { // && !sofia_test_flag(tech_pvt, TFLAG_REINVITE)) {
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 ) ;
}
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
2009-10-21 23:01:37 +00:00
if ( match & & connection - > c_address & & remote_host & &
! strcmp ( connection - > c_address , remote_host ) & & m - > m_port = = remote_port ) {
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 ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG ,
" 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 ;
}
}
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 ;
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
2007-03-31 19:01:33 +00:00
if ( ! te & & ! strcasecmp ( rm_encoding , " telephone-event " ) ) {
te = tech_pvt - > te = ( switch_payload_t ) map - > rm_pt ;
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Set 2833 dtmf payload to %u \n " , te ) ;
2007-03-31 19:01:33 +00:00
if ( tech_pvt - > rtp_session ) {
switch_rtp_set_telephony_event ( tech_pvt - > rtp_session , tech_pvt - > te ) ;
}
}
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 ) {
if ( te & & cng_pt ) {
break ;
}
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
}
2009-01-09 15:34:34 +00:00
if ( maxptime & & ( ! ptime | | ptime > maxptime ) ) {
ptime = maxptime ;
}
2007-03-31 19:01:33 +00:00
2009-12-08 00:05:40 +00:00
if ( ! ptime ) {
ptime = 20 ;
}
2007-06-10 02:52:23 +00:00
for ( i = first ; i < last & & i < tech_pvt - > num_codecs ; i + + ) {
2007-03-31 19:01:33 +00:00
const switch_codec_implementation_t * imp = tech_pvt - > codecs [ i ] ;
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
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Audio Codec Compare [%s:%d:%u:%d]/[%s:%d:%u:%d] \n " ,
2009-02-11 17:43:00 +00:00
rm_encoding , map - > rm_pt , ( int ) map - > rm_rate , ptime ,
imp - > iananame , imp - > ianacode , codec_rate , imp - > microseconds_per_packet / 1000 ) ;
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
2008-03-27 20:36:03 +00:00
if ( match ) {
2009-02-11 17:43:00 +00:00
if ( scrooge ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG ,
2009-02-11 17:43:00 +00:00
" Bah HUMBUG! Sticking with %s@%uh@%ui \n " ,
imp - > iananame , imp - > samples_per_second , imp - > microseconds_per_packet / 1000 ) ;
} else {
if ( ( ptime & & ptime * 1000 ! = imp - > microseconds_per_packet ) | |
map - > rm_rate ! = codec_rate ) {
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
2007-03-31 19:01:33 +00:00
if ( ! match & & near_match ) {
const switch_codec_implementation_t * search [ 1 ] ;
char * prefs [ 1 ] ;
char tmp [ 80 ] ;
int num ;
2009-02-11 17:43:00 +00:00
switch_snprintf ( tmp , sizeof ( tmp ) , " %s@%uh@%ui " , near_match - > iananame , near_rate ? near_rate : near_match - > samples_per_second , ptime ) ;
2007-03-31 19:01:33 +00:00
prefs [ 0 ] = tmp ;
num = switch_loadable_module_get_codecs_sorted ( search , 1 , prefs , 1 ) ;
2009-02-11 17:43:00 +00:00
2007-03-31 19:01:33 +00:00
if ( num ) {
mimp = search [ 0 ] ;
} else {
mimp = near_match ;
}
2009-02-11 17:43:00 +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 ;
}
2009-02-11 17:43:00 +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 ;
tech_pvt - > rm_rate = map - > rm_rate ;
2009-10-23 16:03:42 +00:00
if ( ! strcasecmp ( ( char * ) mimp - > iananame , " ilbc " ) & & zstr ( ( char * ) map - > rm_fmtp ) ) {
2009-02-17 19:50:12 +00:00
/* default to 30 when no mode is defined for ilbc ONLY */
tech_pvt - > codec_ms = 30 ;
} else {
tech_pvt - > codec_ms = mimp - > microseconds_per_packet / 1000 ;
}
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 ;
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 ) ;
2007-03-31 19:01:33 +00:00
}
if ( match ) {
if ( sofia_glue_tech_set_codec ( tech_pvt , 1 ) ! = SWITCH_STATUS_SUCCESS ) {
match = 0 ;
}
}
}
2007-06-10 02:52:23 +00:00
if ( ! match & & greedy & & mine < tech_pvt - > num_codecs ) {
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 ;
int framerate = 0 ;
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 ) {
framerate = atoi ( 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
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 ] ;
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 ) ;
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
}
}
2008-09-27 21:41:09 +00:00
done :
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 :
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 ) ;
2009-02-09 17:56:38 +00:00
if ( ! sofia_test_flag ( tech_pvt , TFLAG_CHANGE_MEDIA ) & & ( switch_channel_test_flag ( other_channel , CF_OUTBOUND ) & &
2007-05-09 19:30:41 +00:00
switch_channel_test_flag ( tech_pvt - > channel , CF_OUTBOUND ) & &
2008-02-21 17:48:41 +00:00
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 ;
}
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
}
2007-05-03 01:55:25 +00:00
if ( switch_thread_rwlock_tryrdlock ( profile - > rwlock ) ! = SWITCH_STATUS_SUCCESS ) {
# 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 locked \n " , profile - > name ) ;
2007-05-03 01:55:25 +00:00
# endif
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
}
2007-05-03 01:55:25 +00:00
# ifdef SOFIA_DEBUG_RWLOCKS
if ( profile ) {
2008-05-02 16:43:07 +00:00
switch_log_printf ( SWITCH_CHANNEL_ID_LOG , file , func , line , NULL , SWITCH_LOG_ERROR , " XXXXXXXXXXXXXX LOCK %s \n " , profile - > name ) ;
2007-05-03 01:55:25 +00:00
}
# endif
2008-04-04 18:53:24 +00:00
2008-05-27 04:54:52 +00: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 ;
}
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 ;
}
}
2008-07-22 22:23:50 +00:00
void sofia_glue_restart_all_profiles ( void )
{
switch_hash_index_t * hi ;
const void * var ;
void * val ;
sofia_profile_t * pptr ;
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 ) {
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 ) ) {
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 ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR ,
" 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 ) ;
}
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 ;
2009-12-10 20:51:13 +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 ) {
2008-07-21 18:42:11 +00:00
switch_core_hash_delete ( mod_sofia_globals . gateway_hash , gp - > name ) ;
switch_core_hash_delete ( mod_sofia_globals . gateway_hash , gp - > register_from ) ;
switch_core_hash_delete ( mod_sofia_globals . gateway_hash , gp - > register_contact ) ;
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_NOTICE , " deleted gateway %s \n " , gp - > name ) ;
profile - > gateways = NULL ;
2008-04-16 21:29:08 +00:00
}
2007-04-30 20:35:35 +00:00
}
switch_mutex_unlock ( mod_sofia_globals . hash_mutex ) ;
2007-03-31 19:01:33 +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 ;
2009-11-12 03:52:07 +00:00
switch_core_db_t * db = NULL ;
2009-11-12 19:54:50 +00:00
switch_odbc_handle_t * odbc_dbh = NULL ;
2008-09-18 00:01:03 +00:00
2007-04-04 03:08:17 +00:00
char reg_sql [ ] =
" CREATE TABLE sip_registrations ( \n "
2007-10-18 16:17:42 +00:00
" call_id VARCHAR(255), \n "
2007-11-15 16:55:46 +00:00
" sip_user VARCHAR(255), \n "
" sip_host VARCHAR(255), \n "
2008-09-18 00:01:03 +00:00
" presence_hosts VARCHAR(255), \n "
2008-05-27 04:54:52 +00:00
" contact VARCHAR(1024), \n "
" status VARCHAR(255), \n "
2008-05-28 20:58:57 +00:00
" rpid VARCHAR(255), \n "
" expires INTEGER, \n "
2008-07-16 19:42:40 +00:00
" user_agent VARCHAR(255), \n "
2008-09-18 00:01:03 +00:00
" server_user VARCHAR(255), \n "
" server_host VARCHAR(255), \n "
" profile_name VARCHAR(255), \n "
2009-03-04 19:45:10 +00:00
" hostname VARCHAR(255), \n "
" network_ip VARCHAR(255), \n "
2009-03-25 20:14:07 +00:00
" network_port VARCHAR(6), \n "
" sip_username VARCHAR(255), \n "
2009-09-25 20:07:40 +00:00
" sip_realm VARCHAR(255), \n "
" mwi_user VARCHAR(255), \n "
" mwi_host VARCHAR(255) \n "
2008-11-22 01:34:19 +00:00
" ); \n " ;
char pres_sql [ ] =
" CREATE TABLE sip_presence ( \n "
" sip_user VARCHAR(255), \n "
" sip_host VARCHAR(255), \n "
" status VARCHAR(255), \n "
" rpid VARCHAR(255), \n "
" expires INTEGER, \n "
" user_agent VARCHAR(255), \n "
" profile_name VARCHAR(255), \n "
2009-03-04 19:45:10 +00:00
" hostname VARCHAR(255), \n "
" network_ip VARCHAR(255), \n "
" network_port VARCHAR(6) \n "
2008-09-18 00:01:03 +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 "
2008-05-28 20:58:57 +00:00
" state VARCHAR(255), \n "
" direction VARCHAR(255), \n "
2008-09-18 00:01:03 +00:00
" user_agent VARCHAR(255), \n "
" profile_name VARCHAR(255), \n "
2009-11-11 02:10:41 +00:00
" hostname VARCHAR(255), \n "
" contact VARCHAR(255), \n "
" presence_id VARCHAR(255), \n "
2009-12-24 05:44:23 +00:00
" presence_data VARCHAR(255), \n "
2010-01-09 00:34:17 +00:00
" call_info VARCHAR(255), \n "
" call_info_state VARCHAR(255), \n "
" expires INTEGER default 0 \n "
2008-05-28 20:58:57 +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 "
2008-05-28 20:58:57 +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 "
2009-06-04 01:18:00 +00:00
" hostname VARCHAR(255), \n "
2009-07-24 15:56:23 +00:00
" network_port VARCHAR(6), \n "
2009-06-04 01:18:00 +00:00
" network_ip VARCHAR(255) \n "
2008-05-28 20:58:57 +00:00
" ); \n " ;
char auth_sql [ ] =
" CREATE TABLE sip_authentication ( \n "
" nonce VARCHAR(255), \n "
2008-09-18 00:01:03 +00:00
" expires INTEGER, "
" profile_name VARCHAR(255), \n "
2009-10-28 16:55:29 +00:00
" hostname VARCHAR(255), \n "
" last_nc INTEGER \n "
2008-09-18 00:01:03 +00:00
" ); \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 */
char shared_appearance_sql [ ] =
" 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 "
2009-02-01 00:06:46 +00:00
" hostname VARCHAR(255), \n "
2009-06-03 21:08:34 +00:00
" contact_str VARCHAR(255), \n "
" network_ip VARCHAR(255) \n "
2009-01-30 16:46:37 +00:00
" ); \n " ;
2009-03-22 05:15:17 +00:00
char shared_appearance_dialogs_sql [ ] =
" CREATE TABLE sip_shared_appearance_dialogs ( \n "
" profile_name VARCHAR(255), \n "
" hostname VARCHAR(255), \n "
" contact_str VARCHAR(255), \n "
" call_id VARCHAR(255), \n "
2009-07-24 15:55:36 +00:00
" network_ip VARCHAR(255), \n "
2009-06-04 04:10:40 +00:00
" expires INTEGER \n "
2009-03-22 05:15:17 +00:00
" ); \n " ;
2009-06-24 16:02:43 +00:00
if ( switch_odbc_available ( ) & & profile - > odbc_dsn ) {
2009-02-23 01:49:49 +00: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) " ,
2009-03-04 19:45:10 +00:00
" create index sr_network_ip on sip_registrations (network_ip) " ,
" create index sr_network_port on sip_registrations (network_port) " ,
2009-03-25 20:14:07 +00:00
" create index sr_sip_username on sip_registrations (sip_username) " ,
" create index sr_sip_realm on sip_registrations (sip_realm) " ,
2009-02-23 01:49:49 +00:00
" create index ss_call_id on sip_subscriptions (call_id) " ,
" create index ss_hostname on sip_subscriptions (hostname) " ,
2009-12-24 05:44:23 +00:00
" create index ss_network_ip on sip_subscriptions (network_ip) " ,
2009-02-23 01:49:49 +00:00
" 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) " ,
2009-12-24 05:44:23 +00:00
" create index sd_presence_data on sip_dialogs (presence_data) " ,
" create index sd_call_info on sip_dialogs (call_info) " ,
2010-01-09 00:34:17 +00:00
" create index sd_call_info_state on sip_dialogs (call_info_state) " ,
" create index sd_expires on sip_dialogs (expires) " ,
2009-02-23 01:49:49 +00:00
" 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) " ,
2009-12-24 05:44:23 +00:00
" create index ssa_network_ip on sip_shared_appearance_subscriptions (network_ip) " ,
2009-02-23 01:49:49 +00:00
" 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) " ,
2009-03-22 05:15:17 +00:00
" 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) " ,
2009-02-23 01:49:49 +00:00
NULL
} ;
2009-11-12 19:54:50 +00:00
if ( ! ( odbc_dbh = switch_odbc_handle_new ( profile - > odbc_dsn , profile - > odbc_user , profile - > odbc_pass ) ) ) {
2007-04-04 03:08:17 +00:00
return 0 ;
}
2009-11-12 19:54:50 +00:00
if ( switch_odbc_handle_connect ( odbc_dbh ) ! = SWITCH_ODBC_SUCCESS ) {
2007-04-04 03:08:17 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Error Connecting ODBC DSN: %s \n " , profile - > odbc_dsn ) ;
2009-11-12 19:54:50 +00:00
switch_odbc_handle_destroy ( & odbc_dbh ) ;
2007-04-04 03:08:17 +00:00
return 0 ;
}
2009-11-12 19:54:50 +00:00
2007-04-04 03:08:17 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_INFO , " Connected ODBC DSN: %s \n " , profile - > odbc_dsn ) ;
2008-09-18 00:01:03 +00:00
2008-11-12 19:28:05 +00:00
test_sql = switch_mprintf ( " delete from sip_registrations where (contact like '%%TCP%%' "
2009-03-04 19:45:10 +00:00
" or status like '%%TCP%%' or status like '%%TLS%%') and hostname='%q' "
2009-11-12 03:52:07 +00:00
" and network_ip like '%%' and network_port like '%%' and sip_username "
" like '%%' and mwi_user like '%%' and mwi_host like '%%' " ,
2008-11-12 19:28:05 +00:00
mod_sofia_globals . hostname ) ;
2010-01-13 01:40:11 +00:00
if ( switch_odbc_handle_exec ( odbc_dbh , test_sql , NULL , NULL ) ! = SWITCH_ODBC_SUCCESS ) {
switch_odbc_handle_exec ( odbc_dbh , " DROP TABLE sip_registrations " , NULL , NULL ) ;
switch_odbc_handle_exec ( odbc_dbh , reg_sql , NULL , NULL ) ;
2007-10-18 16:17:42 +00:00
}
2009-11-13 23:15:15 +00:00
if ( sofia_test_pflag ( profile , PFLAG_SQL_IN_TRANS ) ) {
char * test2 = switch_mprintf ( " %s;%s " , test_sql , test_sql ) ;
2010-01-13 01:40:11 +00:00
if ( switch_odbc_handle_exec ( odbc_dbh , test2 , NULL , NULL ) ! = SWITCH_ODBC_SUCCESS ) {
2009-11-13 23:15:15 +00:00
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 ) ;
}
free ( test2 ) ;
}
free ( test_sql ) ;
2007-10-18 16:17:42 +00:00
2008-09-18 00:01:03 +00:00
2009-11-12 03:52:07 +00:00
test_sql = switch_mprintf ( " delete from sip_subscriptions where hostname='%q' and network_ip like '%%' and network_port like '%%' " ,
mod_sofia_globals . hostname ) ;
2008-09-18 00:01:03 +00:00
2010-01-13 01:40:11 +00:00
if ( switch_odbc_handle_exec ( odbc_dbh , test_sql , NULL , NULL ) ! = SWITCH_ODBC_SUCCESS ) {
switch_odbc_handle_exec ( odbc_dbh , " DROP TABLE sip_subscriptions " , NULL , NULL ) ;
switch_odbc_handle_exec ( odbc_dbh , sub_sql , NULL , NULL ) ;
2007-10-18 16:17:42 +00:00
}
2009-03-03 17:03:48 +00:00
free ( test_sql ) ;
2010-01-20 19:20:11 +00:00
test_sql = switch_mprintf ( " delete from sip_dialogs where hostname='%q' and expires >= 0 " , mod_sofia_globals . hostname ) ;
2008-09-18 00:01:03 +00:00
2010-01-13 01:40:11 +00:00
if ( switch_odbc_handle_exec ( odbc_dbh , test_sql , NULL , NULL ) ! = SWITCH_ODBC_SUCCESS ) {
switch_odbc_handle_exec ( odbc_dbh , " DROP TABLE sip_dialogs " , NULL , NULL ) ;
switch_odbc_handle_exec ( odbc_dbh , dialog_sql , NULL , NULL ) ;
2007-12-18 01:12:50 +00:00
}
2009-12-24 05:44:23 +00:00
test_sql = switch_mprintf ( " delete from sip_presence where hostname='%q' " , mod_sofia_globals . hostname ) ;
2008-11-22 01:34:19 +00:00
2010-01-13 01:40:11 +00:00
if ( switch_odbc_handle_exec ( odbc_dbh , test_sql , NULL , NULL ) ! = SWITCH_ODBC_SUCCESS ) {
switch_odbc_handle_exec ( odbc_dbh , " DROP TABLE sip_presence " , NULL , NULL ) ;
switch_odbc_handle_exec ( odbc_dbh , pres_sql , NULL , NULL ) ;
2008-11-22 01:34:19 +00:00
}
2009-03-03 17:03:48 +00:00
free ( test_sql ) ;
2009-11-12 03:52:07 +00:00
test_sql = switch_mprintf ( " delete from sip_authentication where hostname='%q' or last_nc >= 0 " , mod_sofia_globals . hostname ) ;
2008-09-18 00:01:03 +00:00
2010-01-13 01:40:11 +00:00
if ( switch_odbc_handle_exec ( odbc_dbh , test_sql , NULL , NULL ) ! = SWITCH_ODBC_SUCCESS ) {
switch_odbc_handle_exec ( odbc_dbh , " DROP TABLE sip_authentication " , NULL , NULL ) ;
switch_odbc_handle_exec ( odbc_dbh , auth_sql , NULL , NULL ) ;
2007-10-18 16:17:42 +00:00
}
2009-03-03 17:03:48 +00:00
free ( test_sql ) ;
2008-09-18 00:01:03 +00:00
2009-11-12 03:52:07 +00:00
test_sql = switch_mprintf ( " delete from sip_shared_appearance_subscriptions where contact_str='' or hostname='%q' and network_ip like '%%' " ,
2009-07-10 16:32:48 +00:00
mod_sofia_globals . hostname ) ;
2010-01-13 01:40:11 +00:00
if ( switch_odbc_handle_exec ( odbc_dbh , test_sql , NULL , NULL ) ! = SWITCH_ODBC_SUCCESS ) {
switch_odbc_handle_exec ( odbc_dbh , " DROP TABLE sip_shared_appearance_subscriptions " , NULL , NULL ) ;
switch_odbc_handle_exec ( odbc_dbh , shared_appearance_sql , NULL , NULL ) ;
2009-01-30 16:46:37 +00:00
}
2009-03-03 17:03:48 +00:00
free ( test_sql ) ;
2009-02-23 01:49:49 +00:00
2009-03-22 05:15:17 +00:00
2009-11-12 03:52:07 +00:00
test_sql = switch_mprintf ( " delete from sip_shared_appearance_dialogs where contact_str='' or hostname='%q' and network_ip like '%%' " ,
2009-07-10 16:32:48 +00:00
mod_sofia_globals . hostname ) ;
2010-01-13 01:40:11 +00:00
if ( switch_odbc_handle_exec ( odbc_dbh , test_sql , NULL , NULL ) ! = SWITCH_ODBC_SUCCESS ) {
switch_odbc_handle_exec ( odbc_dbh , " DROP TABLE sip_shared_appearance_dialogs " , NULL , NULL ) ;
switch_odbc_handle_exec ( odbc_dbh , shared_appearance_dialogs_sql , NULL , NULL ) ;
2009-03-22 05:15:17 +00:00
}
free ( test_sql ) ;
2009-02-23 01:49:49 +00:00
for ( x = 0 ; indexes [ x ] ; x + + ) {
2010-01-13 01:40:11 +00:00
switch_odbc_handle_exec ( odbc_dbh , indexes [ x ] , NULL , NULL ) ;
2009-02-23 01:49:49 +00:00
}
2009-01-30 16:46:37 +00:00
2009-06-24 16:02:43 +00:00
} else if ( profile - > odbc_dsn ) {
2007-11-20 02:27:48 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " ODBC IS NOT AVAILABLE! \n " ) ;
2009-02-23 01:49:49 +00:00
} else {
2009-11-12 03:52:07 +00:00
if ( ! ( db = switch_core_db_open_file ( profile - > dbname ) ) ) {
2007-04-04 03:08:17 +00:00
return 0 ;
}
2008-11-12 19:28:05 +00:00
test_sql = switch_mprintf ( " delete from sip_registrations where (contact like '%%TCP%%' "
2009-03-04 19:45:10 +00:00
" or status like '%%TCP%%' or status like '%%TLS%%') and hostname='%q' "
2009-11-12 03:52:07 +00:00
" and network_ip like '%%' and network_port like '%%' and sip_username "
" like '%%' and mwi_user like '%%' and mwi_host like '%%' " ,
2008-11-12 19:28:05 +00:00
mod_sofia_globals . hostname ) ;
2008-09-18 00:01:03 +00:00
2009-11-12 03:52:07 +00:00
switch_core_db_test_reactive ( db , test_sql , " DROP TABLE sip_registrations " , reg_sql ) ;
2009-03-03 17:03:48 +00:00
free ( test_sql ) ;
2008-11-12 19:28:05 +00:00
2009-11-12 03:52:07 +00:00
test_sql = switch_mprintf ( " delete from sip_subscriptions where hostname='%q' and network_ip like '%%' or network_port like '%%' " ,
mod_sofia_globals . hostname ) ;
switch_core_db_test_reactive ( db , test_sql , " DROP TABLE sip_subscriptions " , sub_sql ) ;
2009-03-03 17:03:48 +00:00
free ( test_sql ) ;
2009-07-10 16:32:48 +00:00
2010-01-09 00:34:17 +00:00
test_sql = switch_mprintf ( " delete from sip_dialogs where hostname='%q' and expires > 0 " , mod_sofia_globals . hostname ) ;
2009-11-12 03:52:07 +00:00
switch_core_db_test_reactive ( db , test_sql , " DROP TABLE sip_dialogs " , dialog_sql ) ;
2009-03-03 17:03:48 +00:00
free ( test_sql ) ;
2008-11-22 01:34:19 +00:00
2009-12-24 05:44:23 +00:00
test_sql = switch_mprintf ( " delete from sip_presence where hostname='%q' " , mod_sofia_globals . hostname ) ;
2009-11-12 03:52:07 +00:00
switch_core_db_test_reactive ( db , test_sql , " DROP TABLE sip_presence " , pres_sql ) ;
2009-03-03 17:03:48 +00:00
free ( test_sql ) ;
2008-11-22 01:34:19 +00:00
2009-11-12 03:52:07 +00:00
test_sql = switch_mprintf ( " delete from sip_authentication where hostname='%q' or last_nc >= 0 " , mod_sofia_globals . hostname ) ;
switch_core_db_test_reactive ( db , test_sql , " DROP TABLE sip_authentication " , auth_sql ) ;
2009-03-03 17:03:48 +00:00
free ( test_sql ) ;
2008-12-17 21:05:52 +00:00
2009-02-23 01:49:49 +00:00
2009-11-12 03:52:07 +00:00
test_sql = switch_mprintf ( " delete from sip_shared_appearance_subscriptions where contact_str = '' or hostname='%q' and network_ip like '%%' " ,
2009-07-10 16:32:48 +00:00
mod_sofia_globals . hostname ) ;
2009-11-12 03:52:07 +00:00
switch_core_db_test_reactive ( db , test_sql , " DROP TABLE sip_shared_appearance_subscriptions " , shared_appearance_sql ) ;
2009-03-03 17:03:48 +00:00
free ( test_sql ) ;
2009-03-22 05:15:17 +00:00
2009-06-04 04:10:40 +00:00
test_sql = switch_mprintf ( " delete from sip_shared_appearance_dialogs where contact_str = '' or hostname='%q' " , mod_sofia_globals . hostname ) ;
2009-11-12 03:52:07 +00:00
switch_core_db_test_reactive ( db , test_sql , " DROP TABLE sip_shared_appearance_dialogs " , shared_appearance_dialogs_sql ) ;
2009-03-22 05:15:17 +00:00
free ( test_sql ) ;
2009-02-23 01:49:49 +00:00
2009-11-12 03:52:07 +00:00
switch_core_db_exec ( db , " create index if not exists ssa_hostname on sip_shared_appearance_subscriptions (hostname) " ,
2009-02-23 01:49:49 +00:00
NULL , NULL , NULL ) ;
2009-11-12 03:52:07 +00:00
switch_core_db_exec ( db , " create index if not exists ssa_subscriber on sip_shared_appearance_subscriptions (subscriber) " ,
2009-02-23 01:49:49 +00:00
NULL , NULL , NULL ) ;
2009-11-12 03:52:07 +00:00
switch_core_db_exec ( db , " create index if not exists ssa_profile_name on sip_shared_appearance_subscriptions (profile_name) " ,
2009-02-23 01:49:49 +00:00
NULL , NULL , NULL ) ;
2009-11-12 03:52:07 +00:00
switch_core_db_exec ( db , " create index if not exists ssa_aor on sip_shared_appearance_subscriptions (aor) " , NULL , NULL , NULL ) ;
2009-02-23 01:49:49 +00:00
2009-01-30 16:46:37 +00:00
2009-11-12 03:52:07 +00:00
switch_core_db_exec ( db , " create index if not exists ssd_profile_name on sip_shared_appearance_dialogs (profile_name) " ,
2009-03-22 05:15:17 +00:00
NULL , NULL , NULL ) ;
2009-11-12 03:52:07 +00:00
switch_core_db_exec ( db , " create index if not exists ssd_hostname on sip_shared_appearance_dialogs (hostname) " ,
2009-03-22 05:15:17 +00:00
NULL , NULL , NULL ) ;
2009-12-24 05:44:23 +00:00
switch_core_db_exec ( db , " create index if not exists ssd_network_ip on sip_shared_appearance_dialogs (network_ip) " ,
2009-06-04 01:18:00 +00:00
NULL , NULL , NULL ) ;
2009-11-12 03:52:07 +00:00
switch_core_db_exec ( db , " create index if not exists ssd_contact_str on sip_shared_appearance_dialogs (contact_str) " ,
2009-03-22 05:15:17 +00:00
NULL , NULL , NULL ) ;
2009-11-12 03:52:07 +00:00
switch_core_db_exec ( db , " create index if not exists ssd_call_id on sip_shared_appearance_dialogs (call_id) " ,
2009-03-22 05:15:17 +00:00
NULL , NULL , NULL ) ;
2009-11-12 03:52:07 +00:00
switch_core_db_exec ( db , " create index if not exists ssd_expires on sip_shared_appearance_dialogs (expires) " ,
2009-03-22 05:15:17 +00:00
NULL , NULL , NULL ) ;
2009-01-30 16:46:37 +00:00
2009-11-12 03:52:07 +00:00
switch_core_db_exec ( db , " create index if not exists sr_call_id on sip_registrations (call_id) " , NULL , NULL , NULL ) ;
switch_core_db_exec ( db , " create index if not exists sr_sip_user on sip_registrations (sip_user) " , NULL , NULL , NULL ) ;
switch_core_db_exec ( db , " create index if not exists sr_sip_host on sip_registrations (sip_host) " , NULL , NULL , NULL ) ;
switch_core_db_exec ( db , " create index if not exists sr_profile_name on sip_registrations (profile_name) " , NULL , NULL , NULL ) ;
switch_core_db_exec ( db , " create index if not exists sr_presence_hosts on sip_registrations (presence_hosts) " , NULL , NULL , NULL ) ;
switch_core_db_exec ( db , " create index if not exists sr_contact on sip_registrations (contact) " , NULL , NULL , NULL ) ;
switch_core_db_exec ( db , " create index if not exists sr_expires on sip_registrations (expires) " , NULL , NULL , NULL ) ;
switch_core_db_exec ( db , " create index if not exists sr_hostname on sip_registrations (hostname) " , NULL , NULL , NULL ) ;
switch_core_db_exec ( db , " create index if not exists sr_status on sip_registrations (status) " , NULL , NULL , NULL ) ;
switch_core_db_exec ( db , " create index if not exists sr_network_ip on sip_registrations (network_ip) " , NULL , NULL , NULL ) ;
switch_core_db_exec ( db , " create index if not exists sr_network_port on sip_registrations (network_port) " , NULL , NULL , NULL ) ;
switch_core_db_exec ( db , " create index if not exists sr_sip_username on sip_registrations (sip_username) " , NULL , NULL , NULL ) ;
switch_core_db_exec ( db , " create index if not exists sr_sip_realm on sip_registrations (sip_realm) " , NULL , NULL , NULL ) ;
switch_core_db_exec ( db , " create index if not exists ss_call_id on sip_subscriptions (call_id) " , NULL , NULL , NULL ) ;
switch_core_db_exec ( db , " create index if not exists ss_hostname on sip_subscriptions (hostname) " , NULL , NULL , NULL ) ;
2009-12-24 05:44:23 +00:00
switch_core_db_exec ( db , " create index if not exists ss_network_ip on sip_subscriptions (network_ip) " , NULL , NULL , NULL ) ;
2009-11-12 03:52:07 +00:00
switch_core_db_exec ( db , " create index if not exists ss_sip_user on sip_subscriptions (sip_user) " , NULL , NULL , NULL ) ;
switch_core_db_exec ( db , " create index if not exists ss_sip_host on sip_subscriptions (sip_host) " , NULL , NULL , NULL ) ;
switch_core_db_exec ( db , " create index if not exists ss_presence_hosts on sip_subscriptions (presence_hosts) " , NULL , NULL , NULL ) ;
switch_core_db_exec ( db , " create index if not exists ss_event on sip_subscriptions (event) " , NULL , NULL , NULL ) ;
switch_core_db_exec ( db , " create index if not exists ss_proto on sip_subscriptions (proto) " , NULL , NULL , NULL ) ;
switch_core_db_exec ( db , " create index if not exists ss_sub_to_user on sip_subscriptions (sub_to_user) " , NULL , NULL , NULL ) ;
switch_core_db_exec ( db , " create index if not exists ss_sub_to_host on sip_subscriptions (sub_to_host) " , NULL , NULL , NULL ) ;
switch_core_db_exec ( db , " create index if not exists sd_uuid on sip_dialogs (uuid) " , NULL , NULL , NULL ) ;
switch_core_db_exec ( db , " create index if not exists sd_hostname on sip_dialogs (hostname) " , NULL , NULL , NULL ) ;
2009-12-24 05:44:23 +00:00
switch_core_db_exec ( db , " create index if not exists sd_contact on sip_dialogs (contact) " , NULL , NULL , NULL ) ;
switch_core_db_exec ( db , " create index if not exists sd_presence_id on sip_dialogs (presence_id) " , NULL , NULL , NULL ) ;
switch_core_db_exec ( db , " create index if not exists sd_presence_data on sip_dialogs (presence_data) " , NULL , NULL , NULL ) ;
switch_core_db_exec ( db , " create index if not exists sd_call_info on sip_dialogs (call_info) " , NULL , NULL , NULL ) ;
2010-01-09 00:34:17 +00:00
switch_core_db_exec ( db , " create index if not exists sd_call_info_state on sip_dialogs (call_info_state) " , NULL , NULL , NULL ) ;
switch_core_db_exec ( db , " create index if not exists sd_expires on sip_dialogs (expires) " , NULL , NULL , NULL ) ;
2009-11-12 03:52:07 +00:00
switch_core_db_exec ( db , " create index if not exists sp_hostname on sip_presence (hostname) " , NULL , NULL , NULL ) ;
switch_core_db_exec ( db , " create index if not exists sa_nonce on sip_authentication (nonce) " , NULL , NULL , NULL ) ;
switch_core_db_exec ( db , " create index if not exists sa_hostname on sip_authentication (hostname) " , NULL , NULL , NULL ) ;
2007-04-04 03:08:17 +00:00
}
2009-11-12 19:54:50 +00:00
if ( odbc_dbh ) {
switch_odbc_handle_destroy ( & odbc_dbh ) ;
return 1 ;
2007-05-03 16:28:23 +00:00
}
2009-11-12 19:54:50 +00:00
2009-11-12 03:52:07 +00:00
if ( db ) {
switch_core_db_close ( db ) ;
return 1 ;
}
2007-05-02 23:39:24 +00:00
2009-11-12 19:54:50 +00:00
return 0 ;
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
{
2009-11-21 18:57:15 +00:00
switch_cache_db_connection_options_t options = { { 0 } } ;
switch_cache_db_handle_t * dbh = NULL ;
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 ;
if ( switch_cache_db_get_db_handle ( & dbh , SCDB_TYPE_ODBC , & options ) ! = SWITCH_STATUS_SUCCESS ) dbh = NULL ;
return dbh ;
} else {
options . core_db_options . db_path = profile - > dbname ;
if ( switch_cache_db_get_db_handle ( & dbh , SCDB_TYPE_CORE_DB , & options ) ! = SWITCH_STATUS_SUCCESS ) dbh = NULL ;
return dbh ;
2009-11-12 19:54:50 +00:00
}
}
2009-11-21 18:57:15 +00:00
void sofia_glue_actually_execute_sql_trans ( sofia_profile_t * profile , char * sql , switch_mutex_t * mutex )
2009-11-12 03:52:07 +00:00
{
2009-11-21 18:57:15 +00:00
switch_cache_db_handle_t * dbh = NULL ;
2009-11-12 19:54:50 +00:00
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
2009-11-21 18:57:15 +00:00
end :
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
end :
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 ;
2009-11-12 19:54:50 +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 ) ) ) {
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
2008-05-27 04:54:52 +00: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 ) ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Error Opening DB \n " ) ;
2009-11-21 18:57:15 +00:00
return NULL ;
2009-11-12 19:54:50 +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 ) ;
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 ;
}
2007-04-02 19:54:25 +00:00
int sofia_glue_get_user_host ( char * in , char * * user , char * * host )
{
2009-09-25 20:07:40 +00:00
char * p = NULL , * h = NULL , * u = in ;
2007-04-02 19:54:25 +00:00
2009-09-25 20:07:40 +00:00
if ( ! in ) {
return 0 ;
2009-06-03 21:08:34 +00:00
}
2009-06-02 00:54:38 +00:00
/* First isolate the host part from the user part */
2007-04-02 19:54:25 +00:00
if ( ( h = strchr ( u , ' @ ' ) ) ) {
* h + + = ' \0 ' ;
}
2007-03-31 19:01:33 +00:00
2009-06-02 00:54:38 +00:00
/* Clean out the user part of its protocol prefix (if any) */
2009-09-25 20:07:40 +00:00
if ( ( p = strchr ( u , ' : ' ) ) ) {
2009-06-02 00:54:38 +00:00
* p + + = ' \0 ' ;
u = p ;
}
2007-04-02 19:54:25 +00:00
2009-06-02 00:54:38 +00:00
/* Clean out the host part of any suffix */
2009-09-25 20:07:40 +00:00
if ( h ) {
if ( ( p = strchr ( h , ' : ' ) ) ) {
* p = ' \0 ' ;
}
if ( ( p = strchr ( h , ' ; ' ) ) ) {
* p = ' \0 ' ;
}
2007-04-02 19:54:25 +00:00
2009-09-25 20:07:40 +00:00
if ( ( p = strchr ( h , ' ' ) ) ) {
* p = ' \0 ' ;
}
}
2009-06-03 21:08:34 +00:00
if ( user ) {
2009-09-25 20:07:40 +00:00
* user = u ;
}
if ( host ) {
* host = h ;
2009-06-03 21:08:34 +00:00
}
2007-04-02 19:54:25 +00:00
return 1 ;
}
2008-01-27 05:02:52 +00:00
2008-06-27 23:34:33 +00:00
const char * sofia_glue_strip_proto ( const char * uri )
{
char * p ;
if ( ( p = strchr ( uri , ' : ' ) ) ) {
return p + 1 ;
}
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 ;
}
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 */
sofia_destination_t * sofia_glue_get_destination ( char * data )
{
sofia_destination_t * dst = NULL ;
char * to = NULL ;
char * contact = NULL ;
char * route = NULL ;
char * route_uri = NULL ;
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 ;
}
if ( ! ( dst = ( sofia_destination_t * ) malloc ( sizeof ( sofia_destination_t ) ) ) ) {
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 ;
}
for ( p = route ; p & & * p ; p + + ) {
if ( * p = = ' > ' | | * p = = ' ; ' ) {
* p = ' \0 ' ;
break ;
}
}
switch_url_decode ( route ) ;
if ( ! ( route_uri = strdup ( route ) ) ) {
goto mem_fail ;
}
if ( ( p = strchr ( route_uri , ' , ' ) ) ) {
do {
* p = ' \0 ' ;
} while ( ( - - p > route_uri ) & & * p = = ' ' ) ;
}
2009-06-25 16:50:13 +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= " ) ) ) {
2009-06-19 15:35:26 +00:00
* eoc + + = ' > ' ;
* eoc = ' \0 ' ;
}
if ( ( p = strstr ( contact , " ;fs_ " ) ) ) {
* p = ' \0 ' ;
}
dst - > contact = contact ;
dst - > to = to ;
dst - > route = route ;
dst - > route_uri = route_uri ;
return dst ;
mem_fail :
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
2009-08-21 00:59:09 +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 , const char * body , const char * o_contact , const char * network_ip )
{
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
contact = sofia_glue_get_url_from_contact ( ( char * ) o_contact , 1 ) ;
if ( sofia_glue_check_nat ( profile , network_ip ) ) {
char * ptr = NULL ;
const char * transport_str = NULL ;
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 ) ;
transport_str = sofia_glue_transport2str ( transport ) ;
switch ( transport ) {
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 ;
}
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 ) ;
}
dst = sofia_glue_get_destination ( ( char * ) o_contact ) ;
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 ) ;
}
2009-08-21 00:59:09 +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 ( ) ) ;
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 ) ) ,
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 ;
}
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
*/