2006-08-25 23:55:59 +00:00
/*
* FreeSWITCH Modular Media Switching Software Library / Soft - Switch Application
2010-02-06 03:38:24 +00:00
* Copyright ( C ) 2005 - 2010 , Anthony Minessale II < anthm @ freeswitch . org >
2006-08-25 23:55:59 +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 >
2006-08-25 23:55:59 +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 >
2008-07-30 18:50:47 +00:00
* Ken Rice < krice at cometsig . com >
2006-10-24 22:11:25 +00:00
* Paul D . Tinsley < pdt at jackhammer . org >
2007-02-25 21:00:26 +00:00
* Bret McDanel < trixter AT 0xdecafbad . com >
2006-08-25 23:55:59 +00:00
*
*
* mod_sofia . c - - SOFIA SIP Endpoint
*
*/
/* Best viewed in a 160 x 60 VT100 Terminal or so the line below at least fits across your screen*/
/*************************************************************************************************************************************************************/
2007-03-31 19:01:33 +00:00
# include "mod_sofia.h"
2009-03-07 17:00:48 +00:00
# include "sofia-sip/sip_extra.h"
2007-06-13 14:35:55 +00:00
SWITCH_MODULE_LOAD_FUNCTION ( mod_sofia_load ) ;
SWITCH_MODULE_SHUTDOWN_FUNCTION ( mod_sofia_shutdown ) ;
SWITCH_MODULE_DEFINITION ( mod_sofia , mod_sofia_load , mod_sofia_shutdown , NULL ) ;
2007-04-01 01:16:16 +00:00
struct mod_sofia_globals mod_sofia_globals ;
2007-06-20 07:15:53 +00:00
switch_endpoint_interface_t * sofia_endpoint_interface ;
2006-10-31 21:46:42 +00:00
static switch_frame_t silence_frame = { 0 } ;
2006-10-31 21:38:06 +00:00
static char silence_data [ 13 ] = " " ;
2006-08-25 23:55:59 +00:00
# define STRLEN 15
static switch_status_t sofia_on_init ( switch_core_session_t * session ) ;
2008-05-05 15:30:55 +00:00
static switch_status_t sofia_on_exchange_media ( switch_core_session_t * session ) ;
static switch_status_t sofia_on_soft_execute ( switch_core_session_t * session ) ;
2008-05-15 19:29:35 +00:00
static switch_call_cause_t sofia_outgoing_channel ( switch_core_session_t * session , switch_event_t * var_event ,
2007-03-30 00:15:25 +00:00
switch_caller_profile_t * outbound_profile , switch_core_session_t * * new_session ,
2009-11-20 02:17:08 +00:00
switch_memory_pool_t * * pool , switch_originate_flag_t flags , switch_call_cause_t * cancel_cause ) ;
2008-05-08 19:19:47 +00:00
static switch_status_t sofia_read_frame ( switch_core_session_t * session , switch_frame_t * * frame , switch_io_flag_t flags , int stream_id ) ;
static switch_status_t sofia_write_frame ( switch_core_session_t * session , switch_frame_t * frame , switch_io_flag_t flags , int stream_id ) ;
static switch_status_t sofia_read_video_frame ( switch_core_session_t * session , switch_frame_t * * frame , switch_io_flag_t flags , int stream_id ) ;
static switch_status_t sofia_write_video_frame ( switch_core_session_t * session , switch_frame_t * frame , switch_io_flag_t flags , int stream_id ) ;
2006-08-25 23:55:59 +00:00
static switch_status_t sofia_kill_channel ( switch_core_session_t * session , int sig ) ;
2007-03-31 19:01:33 +00:00
/* BODY OF THE MODULE */
/*************************************************************************************************************************************************************/
2007-03-29 22:31:56 +00:00
2007-03-31 19:01:33 +00:00
/*
State methods they get called when the state changes to the specific state
returning SWITCH_STATUS_SUCCESS tells the core to execute the standard state method next
so if you fully implement the state you can return SWITCH_STATUS_FALSE to skip it .
*/
static switch_status_t sofia_on_init ( switch_core_session_t * session )
{
2008-01-28 07:26:10 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
private_object_t * tech_pvt = ( private_object_t * ) switch_core_session_get_private ( session ) ;
2008-11-03 21:54:03 +00:00
switch_status_t status = SWITCH_STATUS_SUCCESS ;
2007-12-12 23:21:45 +00:00
switch_assert ( tech_pvt ! = NULL ) ;
2006-08-25 23:55:59 +00:00
2007-03-31 19:01:33 +00:00
tech_pvt - > read_frame . buflen = SWITCH_RTP_MAX_BUF_LEN ;
2008-11-03 21:54:03 +00:00
switch_mutex_lock ( tech_pvt - > sofia_mutex ) ;
2006-08-25 23:55:59 +00:00
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " %s SOFIA INIT \n " , switch_channel_get_name ( channel ) ) ;
2008-02-21 17:48:41 +00:00
if ( switch_channel_test_flag ( channel , CF_PROXY_MODE ) | | switch_channel_test_flag ( channel , CF_PROXY_MEDIA ) ) {
2007-03-31 19:01:33 +00:00
sofia_glue_tech_absorb_sdp ( tech_pvt ) ;
}
2006-08-25 23:55:59 +00:00
2010-09-08 15:32:34 -05:00
if ( sofia_test_flag ( tech_pvt , TFLAG_RECOVERING ) | | sofia_test_flag ( tech_pvt , TFLAG_RECOVERING_BRIDGE ) ) {
sofia_set_flag ( tech_pvt , TFLAG_RECOVERED ) ;
}
2010-02-06 03:38:24 +00:00
if ( sofia_test_flag ( tech_pvt , TFLAG_OUTBOUND ) | | sofia_test_flag ( tech_pvt , TFLAG_RECOVERING ) ) {
2008-01-16 06:01:53 +00:00
const char * var ;
2009-10-23 16:03:42 +00:00
if ( ( var = switch_channel_get_variable ( channel , SOFIA_SECURE_MEDIA_VARIABLE ) ) & & ! zstr ( var ) ) {
2008-01-16 06:01:53 +00:00
if ( switch_true ( var ) | | ! strcasecmp ( var , SWITCH_RTP_CRYPTO_KEY_32 ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_flag_locked ( tech_pvt , TFLAG_SECURE ) ;
2008-01-16 06:01:53 +00:00
sofia_glue_build_crypto ( tech_pvt , 1 , AES_CM_128_HMAC_SHA1_32 , SWITCH_RTP_CRYPTO_SEND ) ;
} else if ( ! strcasecmp ( var , SWITCH_RTP_CRYPTO_KEY_80 ) ) {
2009-02-09 17:56:38 +00:00
sofia_set_flag_locked ( tech_pvt , TFLAG_SECURE ) ;
2008-01-16 06:01:53 +00:00
sofia_glue_build_crypto ( tech_pvt , 1 , AES_CM_128_HMAC_SHA1_80 , SWITCH_RTP_CRYPTO_SEND ) ;
}
}
2007-03-31 19:01:33 +00:00
if ( sofia_glue_do_invite ( session ) ! = SWITCH_STATUS_SUCCESS ) {
2007-04-17 14:44:22 +00:00
switch_channel_hangup ( channel , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
2008-05-27 04:54:52 +00:00
assert ( switch_channel_get_state ( channel ) ! = CS_INIT ) ;
2008-11-03 21:54:03 +00:00
status = SWITCH_STATUS_FALSE ;
goto end ;
2007-03-31 19:01:33 +00:00
}
}
2006-08-25 23:55:59 +00:00
2008-11-03 21:54:03 +00:00
2010-02-06 03:38:24 +00:00
2010-06-23 13:22:52 -05:00
if ( sofia_test_flag ( tech_pvt , TFLAG_RECOVERING_BRIDGE ) ) {
switch_channel_set_state ( channel , CS_RESET ) ;
} else {
2010-02-06 03:38:24 +00:00
if ( sofia_test_flag ( tech_pvt , TFLAG_RECOVERING ) ) {
switch_channel_set_state ( channel , CS_EXECUTE ) ;
} else {
/* Move channel's state machine to ROUTING */
switch_channel_set_state ( channel , CS_ROUTING ) ;
assert ( switch_channel_get_state ( channel ) ! = CS_INIT ) ;
}
}
2010-06-30 10:35:03 -05:00
end :
2008-11-03 21:54:03 +00:00
switch_mutex_unlock ( tech_pvt - > sofia_mutex ) ;
return status ;
2007-03-31 19:01:33 +00:00
}
2006-09-28 21:21:44 +00:00
2008-05-05 15:30:55 +00:00
static switch_status_t sofia_on_routing ( switch_core_session_t * session )
2007-03-31 19:01:33 +00:00
{
2008-01-28 07:26:10 +00:00
private_object_t * tech_pvt = ( private_object_t * ) switch_core_session_get_private ( session ) ;
2009-11-24 18:18:09 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
2007-12-12 23:21:45 +00:00
switch_assert ( tech_pvt ! = NULL ) ;
2007-03-19 21:09:53 +00:00
2009-02-09 17:56:38 +00:00
if ( ! sofia_test_flag ( tech_pvt , TFLAG_HOLD_LOCK ) ) {
sofia_clear_flag_locked ( tech_pvt , TFLAG_SIP_HOLD ) ;
2009-11-24 18:18:09 +00:00
switch_channel_clear_flag ( channel , CF_LEG_HOLDING ) ;
2008-09-18 21:50:18 +00:00
}
2008-05-27 04:54:52 +00:00
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " %s SOFIA ROUTING \n " ,
switch_channel_get_name ( switch_core_session_get_channel ( session ) ) ) ;
2007-12-24 18:26:39 +00:00
return SWITCH_STATUS_SUCCESS ;
}
static switch_status_t sofia_on_reset ( switch_core_session_t * session )
{
2008-01-28 07:26:10 +00:00
private_object_t * tech_pvt = ( private_object_t * ) switch_core_session_get_private ( session ) ;
2009-11-24 18:18:09 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
2007-12-24 18:26:39 +00:00
switch_assert ( tech_pvt ! = NULL ) ;
2009-02-09 17:56:38 +00:00
if ( ! sofia_test_flag ( tech_pvt , TFLAG_HOLD_LOCK ) ) {
sofia_clear_flag_locked ( tech_pvt , TFLAG_SIP_HOLD ) ;
2009-11-24 18:18:09 +00:00
switch_channel_clear_flag ( channel , CF_LEG_HOLDING ) ;
2008-09-18 21:50:18 +00:00
}
2008-05-27 04:54:52 +00:00
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " %s SOFIA RESET \n " ,
switch_channel_get_name ( switch_core_session_get_channel ( session ) ) ) ;
if ( sofia_test_flag ( tech_pvt , TFLAG_RECOVERING_BRIDGE ) ) {
2010-04-23 15:53:30 -05:00
switch_core_session_t * other_session = NULL ;
2010-02-06 03:38:24 +00:00
const char * uuid = switch_core_session_get_uuid ( session ) ;
if ( switch_channel_test_flag ( channel , CF_BRIDGE_ORIGINATOR ) ) {
const char * other_uuid = switch_channel_get_variable ( channel , SWITCH_SIGNAL_BOND_VARIABLE ) ;
2010-04-23 15:53:30 -05:00
int x = 0 ;
2010-02-06 03:38:24 +00:00
2010-04-23 15:53:30 -05:00
if ( other_uuid ) {
2010-06-23 13:22:52 -05:00
for ( x = 0 ; other_session = = NULL & & x < 20 ; x + + ) {
if ( ! switch_channel_up ( channel ) ) {
break ;
}
2010-04-23 15:53:30 -05:00
other_session = switch_core_session_locate ( other_uuid ) ;
switch_yield ( 100000 ) ;
}
}
2010-02-06 03:38:24 +00:00
2010-04-23 15:53:30 -05:00
if ( other_session ) {
switch_channel_t * other_channel = switch_core_session_get_channel ( other_session ) ;
2010-02-06 03:38:24 +00:00
switch_channel_clear_flag ( channel , CF_BRIDGE_ORIGINATOR ) ;
switch_channel_wait_for_state_timeout ( other_channel , CS_RESET , 5000 ) ;
2010-06-23 13:22:52 -05:00
switch_channel_wait_for_flag ( other_channel , CF_MEDIA_ACK , SWITCH_TRUE , 2000 , NULL ) ;
2010-02-06 03:38:24 +00:00
if ( switch_channel_test_flag ( channel , CF_PROXY_MODE ) & & switch_channel_test_flag ( other_channel , CF_PROXY_MODE ) ) {
switch_ivr_signal_bridge ( session , other_session ) ;
} else {
switch_ivr_uuid_bridge ( uuid , other_uuid ) ;
}
switch_core_session_rwunlock ( other_session ) ;
}
}
sofia_clear_flag ( tech_pvt , TFLAG_RECOVERING_BRIDGE ) ;
}
2007-12-24 18:26:39 +00:00
return SWITCH_STATUS_SUCCESS ;
}
static switch_status_t sofia_on_hibernate ( switch_core_session_t * session )
{
2008-01-28 07:26:10 +00:00
private_object_t * tech_pvt = switch_core_session_get_private ( session ) ;
2009-11-24 18:18:09 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
2007-12-24 18:26:39 +00:00
switch_assert ( tech_pvt ! = NULL ) ;
2009-02-09 17:56:38 +00:00
if ( ! sofia_test_flag ( tech_pvt , TFLAG_HOLD_LOCK ) ) {
sofia_clear_flag_locked ( tech_pvt , TFLAG_SIP_HOLD ) ;
2009-11-24 18:18:09 +00:00
switch_channel_clear_flag ( channel , CF_LEG_HOLDING ) ;
2008-09-18 21:50:18 +00:00
}
2008-05-27 04:54:52 +00:00
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " %s SOFIA HIBERNATE \n " ,
switch_channel_get_name ( switch_core_session_get_channel ( session ) ) ) ;
2007-03-19 21:09:53 +00:00
2007-03-31 19:01:33 +00:00
return SWITCH_STATUS_SUCCESS ;
2007-03-19 21:09:53 +00:00
}
2007-03-31 19:01:33 +00:00
static switch_status_t sofia_on_execute ( switch_core_session_t * session )
2007-03-19 21:09:53 +00:00
{
2008-01-28 07:26:10 +00:00
private_object_t * tech_pvt = ( private_object_t * ) switch_core_session_get_private ( session ) ;
2009-11-24 18:18:09 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
2007-12-12 23:21:45 +00:00
switch_assert ( tech_pvt ! = NULL ) ;
2007-03-19 21:09:53 +00:00
2010-02-06 03:38:24 +00:00
sofia_clear_flag ( tech_pvt , TFLAG_RECOVERING ) ;
2009-02-09 17:56:38 +00:00
if ( ! sofia_test_flag ( tech_pvt , TFLAG_HOLD_LOCK ) ) {
sofia_clear_flag_locked ( tech_pvt , TFLAG_SIP_HOLD ) ;
2009-11-24 18:18:09 +00:00
switch_channel_clear_flag ( channel , CF_LEG_HOLDING ) ;
2008-09-18 21:50:18 +00:00
}
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " %s SOFIA EXECUTE \n " ,
switch_channel_get_name ( switch_core_session_get_channel ( session ) ) ) ;
2007-03-31 19:01:33 +00:00
return SWITCH_STATUS_SUCCESS ;
2007-03-19 21:09:53 +00:00
}
2010-02-06 03:38:24 +00:00
char * generate_pai_str ( switch_core_session_t * session )
2009-05-28 22:46:17 +00:00
{
private_object_t * tech_pvt = ( private_object_t * ) switch_core_session_get_private ( session ) ;
const char * callee_name = NULL , * callee_number = NULL ;
2010-06-29 09:32:41 -05:00
const char * var , * header , * ua = switch_channel_get_variable ( tech_pvt - > channel , " sip_user_agent " ) ;
2009-11-17 22:25:47 +00:00
char * pai = NULL ;
2009-06-01 13:45:50 +00:00
2010-06-30 10:35:03 -05:00
if ( ! sofia_test_pflag ( tech_pvt - > profile , PFLAG_CID_IN_1XX ) | |
2010-06-29 09:32:41 -05:00
( ( var = switch_channel_get_variable ( tech_pvt - > channel , " sip_cid_in_1xx " ) ) & & switch_false ( var ) ) ) {
return NULL ;
}
2009-11-06 22:21:14 +00:00
if ( zstr ( ( callee_name = switch_channel_get_variable ( tech_pvt - > channel , " effective_callee_id_name " ) ) ) & &
zstr ( ( callee_name = switch_channel_get_variable ( tech_pvt - > channel , " sip_callee_id_name " ) ) ) ) {
2009-10-21 18:48:28 +00:00
callee_name = switch_channel_get_variable ( tech_pvt - > channel , " callee_id_name " ) ;
}
2010-02-06 03:38:24 +00:00
2009-11-15 02:16:10 +00:00
if ( zstr ( ( callee_number = switch_channel_get_variable ( tech_pvt - > channel , " effective_callee_id_number " ) ) ) & &
2010-04-12 13:37:40 -05:00
zstr ( ( callee_number = switch_channel_get_variable ( tech_pvt - > channel , " sip_callee_id_number " ) ) ) & &
zstr ( ( callee_number = switch_channel_get_variable ( tech_pvt - > channel , " callee_id_number " ) ) ) ) {
2010-06-23 13:22:52 -05:00
2009-11-06 22:21:14 +00:00
callee_number = tech_pvt - > caller_profile - > destination_number ;
2009-10-21 18:48:28 +00:00
}
2009-10-07 22:35:21 +00:00
2009-10-23 16:03:42 +00:00
if ( zstr ( callee_name ) & & ! zstr ( callee_number ) ) {
2009-10-23 15:50:51 +00:00
callee_name = callee_number ;
}
2009-11-17 22:25:47 +00:00
callee_number = switch_sanitize_number ( switch_core_session_strdup ( session , callee_number ) ) ;
callee_name = switch_sanitize_number ( switch_core_session_strdup ( session , callee_name ) ) ;
2009-11-15 02:16:10 +00:00
2009-10-27 19:19:07 +00:00
if ( ! zstr ( callee_number ) & & ( zstr ( ua ) | | ! switch_stristr ( " polycom " , ua ) ) ) {
2010-06-14 14:10:15 -05:00
callee_number = switch_core_session_sprintf ( session , " sip:%s@%s " , callee_number , tech_pvt - > profile - > sipip ) ;
2009-10-26 18:16:38 +00:00
}
2010-02-06 03:38:24 +00:00
2009-12-24 05:44:23 +00:00
header = ( tech_pvt - > cid_type = = CID_TYPE_RPID & & ! switch_stristr ( " aastra " , ua ) ) ? " Remote-Party-ID " : " P-Asserted-Identity " ;
2009-10-26 18:16:38 +00:00
2009-10-23 16:03:42 +00:00
if ( ! zstr ( callee_name ) & & ! zstr ( callee_number ) ) {
2009-10-26 18:16:38 +00:00
if ( switch_stristr ( " update_display " , tech_pvt - > x_freeswitch_support_remote ) ) {
2010-03-22 16:39:15 +00:00
pai = switch_core_session_sprintf ( tech_pvt - > session , " %s: \" %s \" <%s>%s \n "
2010-02-06 03:38:24 +00:00
" X-FS-Display-Name: %s \n X-FS-Display-Number: %s \n " ,
2010-03-22 16:39:15 +00:00
header , callee_name , callee_number ,
tech_pvt - > cid_type = = CID_TYPE_RPID ? " ;party=calling;privacy=off;screen=no " : " " ,
callee_name , callee_number ) ;
2009-10-26 18:16:38 +00:00
} else {
2010-03-22 16:39:15 +00:00
pai = switch_core_session_sprintf ( tech_pvt - > session , " %s: \" %s \" <%s>%s \n " , header , callee_name , callee_number ,
tech_pvt - > cid_type = = CID_TYPE_RPID ? " ;party=calling;privacy=off;screen=no " : " " ) ;
2009-10-26 18:16:38 +00:00
}
2009-11-15 02:16:10 +00:00
2009-05-28 22:46:17 +00:00
}
2009-11-15 02:16:10 +00:00
2009-06-01 13:55:17 +00:00
return pai ;
2009-05-28 22:46:17 +00:00
}
2007-11-20 01:44:07 +00:00
/* map QSIG cause codes to SIP from RFC4497 section 8.4.1 */
2007-03-31 19:01:33 +00:00
static int hangup_cause_to_sip ( switch_call_cause_t cause )
2008-05-27 04:54:52 +00:00
{
2007-03-31 19:01:33 +00:00
switch ( cause ) {
2008-08-10 01:41:46 +00:00
case SWITCH_CAUSE_UNALLOCATED_NUMBER :
2007-03-31 19:01:33 +00:00
case SWITCH_CAUSE_NO_ROUTE_TRANSIT_NET :
case SWITCH_CAUSE_NO_ROUTE_DESTINATION :
return 404 ;
case SWITCH_CAUSE_USER_BUSY :
return 486 ;
case SWITCH_CAUSE_NO_USER_RESPONSE :
return 408 ;
case SWITCH_CAUSE_NO_ANSWER :
case SWITCH_CAUSE_SUBSCRIBER_ABSENT :
return 480 ;
case SWITCH_CAUSE_CALL_REJECTED :
return 603 ;
case SWITCH_CAUSE_NUMBER_CHANGED :
case SWITCH_CAUSE_REDIRECTION_TO_NEW_DESTINATION :
return 410 ;
case SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER :
return 502 ;
case SWITCH_CAUSE_INVALID_NUMBER_FORMAT :
return 484 ;
case SWITCH_CAUSE_FACILITY_REJECTED :
return 501 ;
case SWITCH_CAUSE_NORMAL_UNSPECIFIED :
return 480 ;
case SWITCH_CAUSE_REQUESTED_CHAN_UNAVAIL :
case SWITCH_CAUSE_NORMAL_CIRCUIT_CONGESTION :
case SWITCH_CAUSE_NETWORK_OUT_OF_ORDER :
case SWITCH_CAUSE_NORMAL_TEMPORARY_FAILURE :
case SWITCH_CAUSE_SWITCH_CONGESTION :
return 503 ;
case SWITCH_CAUSE_OUTGOING_CALL_BARRED :
case SWITCH_CAUSE_INCOMING_CALL_BARRED :
case SWITCH_CAUSE_BEARERCAPABILITY_NOTAUTH :
return 403 ;
case SWITCH_CAUSE_BEARERCAPABILITY_NOTAVAIL :
return 503 ;
case SWITCH_CAUSE_BEARERCAPABILITY_NOTIMPL :
2007-04-17 18:53:18 +00:00
case SWITCH_CAUSE_INCOMPATIBLE_DESTINATION :
2007-03-31 19:01:33 +00:00
return 488 ;
case SWITCH_CAUSE_FACILITY_NOT_IMPLEMENTED :
case SWITCH_CAUSE_SERVICE_NOT_IMPLEMENTED :
return 501 ;
case SWITCH_CAUSE_RECOVERY_ON_TIMER_EXPIRE :
return 504 ;
case SWITCH_CAUSE_ORIGINATOR_CANCEL :
return 487 ;
2007-12-24 19:23:36 +00:00
case SWITCH_CAUSE_EXCHANGE_ROUTING_ERROR :
return 483 ;
2007-03-31 19:01:33 +00:00
default :
return 480 ;
2006-11-14 18:12:17 +00:00
}
}
2009-04-10 17:43:18 +00:00
switch_status_t sofia_on_destroy ( switch_core_session_t * session )
{
private_object_t * tech_pvt = ( private_object_t * ) switch_core_session_get_private ( session ) ;
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " %s SOFIA DESTROY \n " , switch_channel_get_name ( channel ) ) ;
2009-04-10 17:43:18 +00:00
2009-04-10 20:14:02 +00:00
if ( tech_pvt ) {
if ( switch_core_codec_ready ( & tech_pvt - > read_codec ) ) {
switch_core_codec_destroy ( & tech_pvt - > read_codec ) ;
}
2010-02-06 03:38:24 +00:00
2009-04-10 20:14:02 +00:00
if ( switch_core_codec_ready ( & tech_pvt - > write_codec ) ) {
switch_core_codec_destroy ( & tech_pvt - > write_codec ) ;
}
2009-04-10 17:43:18 +00:00
2009-11-18 19:22:45 +00:00
if ( switch_core_codec_ready ( & tech_pvt - > video_read_codec ) ) {
switch_core_codec_destroy ( & tech_pvt - > video_read_codec ) ;
}
2010-02-06 03:38:24 +00:00
2009-11-18 19:22:45 +00:00
if ( switch_core_codec_ready ( & tech_pvt - > video_write_codec ) ) {
switch_core_codec_destroy ( & tech_pvt - > video_write_codec ) ;
}
2009-04-10 20:14:02 +00:00
switch_core_session_unset_read_codec ( session ) ;
switch_core_session_unset_write_codec ( session ) ;
2009-04-10 17:43:18 +00:00
2009-04-10 20:14:02 +00:00
switch_mutex_lock ( tech_pvt - > profile - > flag_mutex ) ;
tech_pvt - > profile - > inuse - - ;
switch_mutex_unlock ( tech_pvt - > profile - > flag_mutex ) ;
2009-04-10 17:43:18 +00:00
2009-04-10 20:14:02 +00:00
sofia_glue_deactivate_rtp ( tech_pvt ) ;
2010-06-23 13:22:52 -05:00
2010-02-16 00:07:50 +00:00
if ( sofia_test_pflag ( tech_pvt - > profile , PFLAG_DESTROY ) & & ! tech_pvt - > profile - > inuse ) {
sofia_profile_destroy ( tech_pvt - > profile ) ;
}
2009-04-10 20:14:02 +00:00
}
2009-04-10 17:43:18 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2007-03-31 19:01:33 +00:00
switch_status_t sofia_on_hangup ( switch_core_session_t * session )
2006-09-29 18:12:31 +00:00
{
2007-03-31 19:01:33 +00:00
switch_core_session_t * a_session ;
2008-01-28 07:26:10 +00:00
private_object_t * tech_pvt = ( private_object_t * ) switch_core_session_get_private ( session ) ;
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
2008-01-29 19:35:06 +00:00
switch_call_cause_t cause = switch_channel_get_cause ( channel ) ;
int sip_cause = hangup_cause_to_sip ( cause ) ;
2008-10-21 16:27:57 +00:00
const char * ps_cause = NULL , * use_my_cause ;
2010-04-26 04:14:57 -04:00
const char * gateway_name = NULL ;
sofia_gateway_t * gateway_ptr = NULL ;
2010-06-17 14:28:31 -05:00
int rec ;
2008-10-21 16:27:57 +00:00
2010-04-26 04:14:57 -04:00
if ( ( gateway_name = switch_channel_get_variable ( channel , " sip_gateway_name " ) ) ) {
gateway_ptr = sofia_reg_find_gateway ( gateway_name ) ;
}
2010-06-23 13:22:52 -05:00
2008-11-03 21:54:03 +00:00
switch_mutex_lock ( tech_pvt - > sofia_mutex ) ;
2010-06-17 14:28:31 -05:00
rec = sofia_test_flag ( tech_pvt , TFLAG_RECOVERING ) ;
2010-02-06 03:38:24 +00:00
sofia_clear_flag ( tech_pvt , TFLAG_RECOVERING ) ;
2010-02-16 00:49:42 +00:00
2010-06-17 14:28:31 -05:00
if ( ! rec ) {
sofia_glue_tech_untrack ( tech_pvt - > profile , session , SWITCH_TRUE ) ;
}
2010-02-06 03:38:24 +00:00
2009-04-21 17:47:22 +00:00
if ( ! switch_channel_test_flag ( channel , CF_ANSWERED ) ) {
if ( switch_channel_direction ( channel ) = = SWITCH_CALL_DIRECTION_OUTBOUND ) {
tech_pvt - > profile - > ob_failed_calls + + ;
} else {
tech_pvt - > profile - > ib_failed_calls + + ;
}
2010-06-23 13:22:52 -05:00
2010-04-26 04:14:57 -04:00
if ( gateway_ptr ) {
if ( switch_channel_direction ( channel ) = = SWITCH_CALL_DIRECTION_OUTBOUND ) {
gateway_ptr - > ob_failed_calls + + ;
} else {
gateway_ptr - > ib_failed_calls + + ;
}
2010-06-23 13:22:52 -05:00
}
2010-04-26 04:14:57 -04:00
}
2010-06-23 13:22:52 -05:00
2010-04-26 04:14:57 -04:00
if ( gateway_ptr ) {
sofia_reg_release_gateway ( gateway_ptr ) ;
2009-04-21 17:47:22 +00:00
}
2008-10-21 16:27:57 +00:00
if ( ! ( ( use_my_cause = switch_channel_get_variable ( channel , " sip_ignore_remote_cause " ) ) & & switch_true ( use_my_cause ) ) ) {
ps_cause = switch_channel_get_variable ( channel , SWITCH_PROTO_SPECIFIC_HANGUP_CAUSE_VARIABLE ) ;
}
2008-05-27 04:54:52 +00:00
2009-10-23 16:03:42 +00:00
if ( ! zstr ( ps_cause ) & & ( ! strncasecmp ( ps_cause , " sip: " , 4 ) | | ! strncasecmp ( ps_cause , " sips: " , 5 ) ) ) {
2008-06-27 23:34:33 +00:00
int new_cause = atoi ( sofia_glue_strip_proto ( ps_cause ) ) ;
2008-05-13 00:50:12 +00:00
if ( new_cause ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " %s Overriding SIP cause %d with %d from the other leg \n " ,
2008-05-13 00:50:12 +00:00
switch_channel_get_name ( channel ) , sip_cause , new_cause ) ;
sip_cause = new_cause ;
}
2008-05-01 18:35:45 +00:00
}
2007-12-20 02:55:36 +00:00
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Channel %s hanging up, cause: %s \n " ,
2008-05-27 04:54:52 +00:00
switch_channel_get_name ( channel ) , switch_channel_cause2str ( cause ) ) ;
2006-09-29 18:12:31 +00:00
2010-02-16 00:49:42 +00:00
if ( tech_pvt - > hash_key & & ! sofia_test_pflag ( tech_pvt - > profile , PFLAG_DESTROY ) ) {
2007-03-31 19:01:33 +00:00
switch_core_hash_delete ( tech_pvt - > profile - > chat_hash , tech_pvt - > hash_key ) ;
2006-09-29 18:12:31 +00:00
}
2008-09-18 00:01:03 +00:00
if ( session & & tech_pvt - > profile - > pres_type ) {
2010-08-27 14:04:45 -05:00
char * sql = switch_mprintf ( " delete from sip_dialogs where uuid='%q' " , switch_core_session_get_uuid ( session ) ) ;
2007-12-18 01:12:50 +00:00
switch_assert ( sql ) ;
2010-01-09 00:34:17 +00:00
sofia_glue_execute_sql_now ( tech_pvt - > profile , & sql , SWITCH_TRUE ) ;
2007-12-18 01:12:50 +00:00
}
2007-03-31 19:01:33 +00:00
if ( tech_pvt - > kick & & ( a_session = switch_core_session_locate ( tech_pvt - > kick ) ) ) {
switch_channel_t * a_channel = switch_core_session_get_channel ( a_session ) ;
switch_channel_hangup ( a_channel , switch_channel_get_cause ( channel ) ) ;
switch_core_session_rwunlock ( a_session ) ;
}
2006-12-13 20:10:00 +00:00
2010-02-16 00:49:42 +00:00
if ( sofia_test_pflag ( tech_pvt - > profile , PFLAG_DESTROY ) ) {
2010-06-23 13:22:52 -05:00
sofia_set_flag ( tech_pvt , TFLAG_BYE ) ;
2010-02-16 00:49:42 +00:00
} else if ( tech_pvt - > nh & & ! sofia_test_flag ( tech_pvt , TFLAG_BYE ) ) {
2008-02-22 15:02:16 +00:00
char reason [ 128 ] = " " ;
2009-08-11 00:54:39 +00:00
char * bye_headers = sofia_glue_get_extra_headers ( channel , SOFIA_SIP_BYE_HEADER_PREFIX ) ;
2010-02-06 03:38:24 +00:00
const char * val = NULL ;
2009-12-08 21:23:13 +00:00
val = switch_channel_get_variable ( tech_pvt - > channel , " disable_q850_reason " ) ;
2009-12-11 01:20:26 +00:00
if ( ! val | | switch_true ( val ) ) {
2009-12-08 21:23:13 +00:00
if ( cause > 0 & & cause < 128 ) {
switch_snprintf ( reason , sizeof ( reason ) , " Q.850;cause=%d;text= \" %s \" " , cause , switch_channel_cause2str ( cause ) ) ;
} else if ( cause = = SWITCH_CAUSE_PICKED_OFF | | cause = = SWITCH_CAUSE_LOSE_RACE ) {
switch_snprintf ( reason , sizeof ( reason ) , " SIP;cause=200;text= \" Call completed elsewhere \" " ) ;
} else {
2010-02-06 03:38:24 +00:00
switch_snprintf ( reason , sizeof ( reason ) , " %s;cause=%d;text= \" %s \" " , tech_pvt - > profile - > username , cause , switch_channel_cause2str ( cause ) ) ;
2009-12-08 21:23:13 +00:00
}
2008-02-22 15:02:16 +00:00
}
2009-06-25 18:56:37 +00:00
2009-12-07 03:32:56 +00:00
if ( switch_channel_test_flag ( channel , CF_ANSWERED ) | | sofia_test_flag ( tech_pvt , TFLAG_ANS ) ) {
2010-01-28 20:35:17 +00:00
const char * call_info = switch_channel_get_variable ( channel , " presence_call_info_full " ) ;
2008-08-01 16:21:51 +00:00
if ( ! tech_pvt - > got_bye ) {
switch_channel_set_variable ( channel , " sip_hangup_disposition " , " send_bye " ) ;
}
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Sending BYE to %s \n " , switch_channel_get_name ( channel ) ) ;
2009-03-20 20:51:19 +00:00
if ( ! sofia_test_flag ( tech_pvt , TFLAG_BYE ) ) {
2010-02-06 03:38:24 +00:00
nua_bye ( tech_pvt - > nh ,
2009-12-08 21:23:13 +00:00
TAG_IF ( ! zstr ( reason ) , SIPTAG_REASON_STR ( reason ) ) ,
2009-12-24 05:44:23 +00:00
TAG_IF ( call_info , SIPTAG_CALL_INFO_STR ( call_info ) ) ,
2009-10-23 16:03:42 +00:00
TAG_IF ( ! zstr ( tech_pvt - > user_via ) , SIPTAG_VIA_STR ( tech_pvt - > user_via ) ) ,
2010-02-06 03:38:24 +00:00
TAG_IF ( ! zstr ( bye_headers ) , SIPTAG_HEADER_STR ( bye_headers ) ) , TAG_END ( ) ) ;
2009-03-20 20:51:19 +00:00
}
2007-11-20 01:44:07 +00:00
} else {
2009-03-20 01:52:53 +00:00
if ( switch_channel_test_flag ( channel , CF_OUTBOUND ) ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Sending CANCEL to %s \n " , switch_channel_get_name ( channel ) ) ;
2008-08-01 16:21:51 +00:00
if ( ! tech_pvt - > got_bye ) {
switch_channel_set_variable ( channel , " sip_hangup_disposition " , " send_cancel " ) ;
}
2009-03-20 20:51:19 +00:00
if ( ! sofia_test_flag ( tech_pvt , TFLAG_BYE ) ) {
2010-02-06 03:38:24 +00:00
nua_cancel ( tech_pvt - > nh ,
TAG_IF ( ! zstr ( reason ) , SIPTAG_REASON_STR ( reason ) ) , TAG_IF ( ! zstr ( bye_headers ) , SIPTAG_HEADER_STR ( bye_headers ) ) , TAG_END ( ) ) ;
2009-03-20 20:51:19 +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 ( session ) , SWITCH_LOG_DEBUG , " Responding to INVITE with: %d \n " , sip_cause ) ;
2008-08-01 16:21:51 +00:00
if ( ! tech_pvt - > got_bye ) {
switch_channel_set_variable ( channel , " sip_hangup_disposition " , " send_refuse " ) ;
}
2009-03-20 01:52:53 +00:00
if ( ! sofia_test_flag ( tech_pvt , TFLAG_BYE ) ) {
2010-06-29 09:32:41 -05:00
char * cid = generate_pai_str ( session ) ;
2010-06-30 10:35:03 -05:00
2010-02-06 03:38:24 +00:00
nua_respond ( tech_pvt - > nh , sip_cause , sip_status_phrase ( sip_cause ) ,
TAG_IF ( ! zstr ( reason ) , SIPTAG_REASON_STR ( reason ) ) ,
2010-06-29 09:32:41 -05:00
TAG_IF ( cid , SIPTAG_HEADER_STR ( cid ) ) , TAG_IF ( ! zstr ( bye_headers ) , SIPTAG_HEADER_STR ( bye_headers ) ) , TAG_END ( ) ) ;
2009-03-20 01:52:53 +00:00
}
2007-03-31 19:01:33 +00:00
}
2006-09-29 18:12:31 +00:00
}
2009-03-20 20:51:19 +00:00
sofia_set_flag_locked ( tech_pvt , TFLAG_BYE ) ;
2009-08-11 00:54:39 +00:00
switch_safe_free ( bye_headers ) ;
2006-09-29 18:12:31 +00:00
}
2009-02-11 20:49:45 +00:00
sofia_clear_flag ( tech_pvt , TFLAG_IO ) ;
2008-12-16 20:59:00 +00:00
2007-03-31 19:01:33 +00:00
if ( tech_pvt - > sofia_private ) {
* tech_pvt - > sofia_private - > uuid = ' \0 ' ;
2006-09-28 21:21:44 +00:00
}
2010-02-06 03:38:24 +00:00
2009-04-14 16:55:10 +00:00
sofia_glue_set_rtp_stats ( tech_pvt ) ;
2008-11-03 21:54:03 +00:00
switch_mutex_unlock ( tech_pvt - > sofia_mutex ) ;
2006-09-28 21:21:44 +00:00
2007-03-31 19:01:33 +00:00
return SWITCH_STATUS_SUCCESS ;
2006-09-28 21:21:44 +00:00
}
2008-05-05 15:30:55 +00:00
static switch_status_t sofia_on_exchange_media ( switch_core_session_t * session )
2007-03-29 22:31:56 +00:00
{
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " SOFIA EXCHANGE_MEDIA \n " ) ;
2007-03-31 19:01:33 +00:00
return SWITCH_STATUS_SUCCESS ;
2006-09-27 03:44:14 +00:00
}
2008-05-05 15:30:55 +00:00
static switch_status_t sofia_on_soft_execute ( switch_core_session_t * session )
2007-03-29 22:31:56 +00:00
{
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " SOFIA SOFT_EXECUTE \n " ) ;
2007-03-31 19:01:33 +00:00
return SWITCH_STATUS_SUCCESS ;
2006-09-27 03:44:14 +00:00
}
2007-03-31 19:01:33 +00:00
static switch_status_t sofia_answer_channel ( switch_core_session_t * session )
2006-09-27 03:44:14 +00:00
{
2008-01-28 07:26:10 +00:00
private_object_t * tech_pvt = ( private_object_t * ) 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_status_t status ;
2008-04-02 20:49:42 +00:00
uint32_t session_timeout = tech_pvt - > profile - > session_timeout ;
2007-11-01 11:28:26 +00:00
const char * val ;
2008-05-12 21:05:14 +00:00
const char * b_sdp = NULL ;
int is_proxy = 0 ;
2008-05-13 23:22:21 +00:00
char * sticky = NULL ;
2010-01-28 20:35:17 +00:00
const char * call_info = switch_channel_get_variable ( channel , " presence_call_info_full " ) ;
2006-09-27 03:44:14 +00:00
2009-02-09 17:56:38 +00:00
if ( sofia_test_flag ( tech_pvt , TFLAG_ANS ) | | switch_channel_test_flag ( channel , CF_OUTBOUND ) ) {
2007-11-20 01:44:07 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2006-09-27 03:44:14 +00:00
2007-03-05 06:04:37 +00:00
2008-05-12 21:05:14 +00:00
b_sdp = switch_channel_get_variable ( channel , SWITCH_B_SDP_VARIABLE ) ;
is_proxy = ( switch_channel_test_flag ( channel , CF_PROXY_MODE ) | | switch_channel_test_flag ( channel , CF_PROXY_MEDIA ) ) ;
2008-05-27 04:54:52 +00:00
2008-05-12 21:05:14 +00:00
if ( b_sdp & & is_proxy ) {
2009-03-20 01:52:53 +00:00
sofia_glue_tech_set_local_sdp ( tech_pvt , b_sdp , SWITCH_TRUE ) ;
2008-05-12 21:05:14 +00:00
2008-02-21 17:48:41 +00:00
if ( switch_channel_test_flag ( channel , CF_PROXY_MEDIA ) ) {
sofia_glue_tech_patch_sdp ( tech_pvt ) ;
if ( sofia_glue_activate_rtp ( tech_pvt , 0 ) ! = SWITCH_STATUS_SUCCESS ) {
return SWITCH_STATUS_FALSE ;
}
}
2007-11-20 01:44:07 +00:00
} else {
2008-10-10 16:15:45 +00:00
/* This if statement check and handles the 3pcc proxy mode */
2009-02-09 22:35:54 +00:00
if ( sofia_test_pflag ( tech_pvt - > profile , PFLAG_3PCC_PROXY ) & & sofia_test_flag ( tech_pvt , TFLAG_3PCC ) ) {
2009-10-26 17:03:05 +00:00
tech_pvt - > num_codecs = 0 ;
sofia_glue_tech_prepare_codecs ( tech_pvt ) ;
tech_pvt - > local_sdp_str = NULL ;
sofia_glue_tech_choose_port ( tech_pvt , 0 ) ;
sofia_glue_set_local_sdp ( tech_pvt , NULL , 0 , NULL , 0 ) ;
2010-02-06 03:38:24 +00:00
2008-10-10 16:15:45 +00:00
/* Send the 200 OK */
2009-03-20 01:52:53 +00:00
if ( ! sofia_test_flag ( tech_pvt , TFLAG_BYE ) ) {
2010-01-21 00:12:24 +00:00
char * extra_headers = sofia_glue_get_extra_headers ( channel , SOFIA_SIP_RESPONSE_HEADER_PREFIX ) ;
2009-12-19 17:43:05 +00:00
if ( sofia_use_soa ( tech_pvt ) ) {
nua_respond ( tech_pvt - > nh , SIP_200_OK ,
SIPTAG_CONTACT_STR ( tech_pvt - > profile - > url ) ,
SOATAG_USER_SDP_STR ( tech_pvt - > local_sdp_str ) ,
2009-12-24 05:44:23 +00:00
TAG_IF ( call_info , SIPTAG_CALL_INFO_STR ( call_info ) ) ,
2009-12-19 17:43:05 +00:00
SOATAG_REUSE_REJECTED ( 1 ) ,
2010-02-06 03:38:24 +00:00
SOATAG_ORDERED_USER ( 1 ) , SOATAG_AUDIO_AUX ( " cn telephone-event " ) , NUTAG_INCLUDE_EXTRA_SDP ( 1 ) ,
2009-12-19 17:43:05 +00:00
TAG_IF ( ! zstr ( extra_headers ) , SIPTAG_HEADER_STR ( extra_headers ) ) ,
2010-02-06 03:38:24 +00:00
TAG_IF ( switch_stristr ( " update_display " , tech_pvt - > x_freeswitch_support_remote ) ,
SIPTAG_HEADER_STR ( " X-FS-Support: " FREESWITCH_SUPPORT ) ) , TAG_END ( ) ) ;
2009-12-19 17:43:05 +00:00
} else {
nua_respond ( tech_pvt - > nh , SIP_200_OK ,
NUTAG_MEDIA_ENABLE ( 0 ) ,
SIPTAG_CONTACT_STR ( tech_pvt - > profile - > url ) ,
TAG_IF ( ! zstr ( extra_headers ) , SIPTAG_HEADER_STR ( extra_headers ) ) ,
2009-12-24 05:44:23 +00:00
TAG_IF ( call_info , SIPTAG_CALL_INFO_STR ( call_info ) ) ,
2009-12-19 17:43:05 +00:00
SIPTAG_CONTENT_TYPE_STR ( " application/sdp " ) ,
2010-02-06 03:38:24 +00:00
SIPTAG_PAYLOAD_STR ( tech_pvt - > local_sdp_str ) ,
TAG_IF ( switch_stristr ( " update_display " , tech_pvt - > x_freeswitch_support_remote ) ,
SIPTAG_HEADER_STR ( " X-FS-Support: " FREESWITCH_SUPPORT ) ) , TAG_END ( ) ) ;
2009-12-19 17:43:05 +00:00
}
2009-03-20 01:52:53 +00:00
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " 3PCC-PROXY, Sent a 200 OK, waiting for ACK \n " ) ;
2009-08-11 00:54:39 +00:00
switch_safe_free ( extra_headers ) ;
2009-03-20 01:52:53 +00:00
}
2008-10-10 16:15:45 +00:00
/* Unlock the session signal to allow the ack to make it in */
// Maybe we should timeout?
2008-11-18 01:23:48 +00:00
switch_mutex_unlock ( tech_pvt - > sofia_mutex ) ;
2010-02-06 03:38:24 +00:00
while ( switch_channel_ready ( channel ) & & ! sofia_test_flag ( tech_pvt , TFLAG_3PCC_HAS_ACK ) ) {
2008-11-14 23:31:21 +00:00
switch_cond_next ( ) ;
2008-10-10 16:15:45 +00:00
}
2010-02-06 03:38:24 +00:00
2008-11-18 01:23:48 +00:00
/* Regain lock on sofia */
switch_mutex_lock ( tech_pvt - > sofia_mutex ) ;
2010-02-06 03:38:24 +00:00
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " 3PCC-PROXY, Done waiting for ACK \n " ) ;
2009-10-26 17:03:05 +00:00
return SWITCH_STATUS_SUCCESS ;
2008-10-10 16:15:45 +00:00
}
2009-02-09 17:56:38 +00:00
if ( ( is_proxy & & ! b_sdp ) | | sofia_test_flag ( tech_pvt , TFLAG_LATE_NEGOTIATION ) | | ! tech_pvt - > iananame ) {
sofia_clear_flag_locked ( tech_pvt , TFLAG_LATE_NEGOTIATION ) ;
2008-05-12 21:05:14 +00:00
if ( is_proxy ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Disabling proxy mode due to call answer with no bridge \n " ) ;
2008-05-12 21:05:14 +00:00
switch_channel_clear_flag ( channel , CF_PROXY_MEDIA ) ;
switch_channel_clear_flag ( channel , CF_PROXY_MODE ) ;
}
2007-11-20 01:44:07 +00:00
if ( ! switch_channel_test_flag ( tech_pvt - > channel , CF_OUTBOUND ) ) {
const char * r_sdp = switch_channel_get_variable ( channel , SWITCH_R_SDP_VARIABLE ) ;
tech_pvt - > num_codecs = 0 ;
sofia_glue_tech_prepare_codecs ( tech_pvt ) ;
2008-05-27 04:54:52 +00:00
2007-11-20 01:44:07 +00:00
if ( sofia_glue_tech_media ( tech_pvt , r_sdp ) ! = SWITCH_STATUS_SUCCESS ) {
switch_channel_set_variable ( channel , SWITCH_ENDPOINT_DISPOSITION_VARIABLE , " CODEC NEGOTIATION ERROR " ) ;
2008-10-30 22:40:39 +00:00
//switch_mutex_lock(tech_pvt->sofia_mutex);
2008-02-20 03:57:01 +00:00
//nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE, TAG_END());
2008-10-30 22:40:39 +00:00
//switch_mutex_unlock(tech_pvt->sofia_mutex);
2007-11-20 01:44:07 +00:00
return SWITCH_STATUS_FALSE ;
2007-03-31 19:01:33 +00:00
}
}
}
2007-04-29 01:16:49 +00:00
2008-02-21 17:48:41 +00:00
if ( ( status = sofia_glue_tech_choose_port ( tech_pvt , 0 ) ) ! = SWITCH_STATUS_SUCCESS ) {
2007-11-20 01:44:07 +00:00
switch_channel_hangup ( channel , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
return status ;
}
2010-02-06 03:38:24 +00:00
2007-11-20 01:44:07 +00:00
sofia_glue_set_local_sdp ( tech_pvt , NULL , 0 , NULL , 0 ) ;
if ( sofia_glue_activate_rtp ( tech_pvt , 0 ) ! = SWITCH_STATUS_SUCCESS ) {
switch_channel_hangup ( channel , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
}
2007-10-19 21:06:09 +00:00
2007-11-20 01:44:07 +00:00
if ( tech_pvt - > nh ) {
if ( tech_pvt - > local_sdp_str ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Local SDP %s: \n %s \n " , switch_channel_get_name ( channel ) ,
tech_pvt - > local_sdp_str ) ;
2007-10-19 21:06:09 +00:00
}
}
2007-11-20 01:44:07 +00:00
}
2007-10-19 21:06:09 +00:00
2007-11-20 01:44:07 +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 ;
}
2006-09-27 03:44:14 +00:00
}
2008-05-27 04:54:52 +00:00
2009-02-09 17:56:38 +00:00
if ( sofia_test_flag ( tech_pvt , TFLAG_NAT ) | |
2008-05-27 04:54:52 +00:00
( val = switch_channel_get_variable ( channel , " sip-force-contact " ) ) | |
2008-05-13 23:22:21 +00:00
( ( val = switch_channel_get_variable ( channel , " sip_sticky_contact " ) ) & & switch_true ( val ) ) ) {
sticky = 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-20 01:52:53 +00:00
if ( ! sofia_test_flag ( tech_pvt , TFLAG_BYE ) ) {
2010-04-20 13:34:51 -05:00
char * extra_headers = sofia_glue_get_extra_headers ( channel , SOFIA_SIP_RESPONSE_HEADER_PREFIX ) ;
2010-09-08 10:41:50 -05:00
char * cid = NULL ;
if ( sofia_test_pflag ( tech_pvt - > profile , PFLAG_PASS_CALLEE_ID ) ) {
cid = generate_pai_str ( session ) ;
}
2010-06-18 15:42:14 -05:00
if ( switch_channel_test_flag ( tech_pvt - > channel , CF_PROXY_MODE ) & & tech_pvt - > early_sdp & & strcmp ( tech_pvt - > early_sdp , tech_pvt - > local_sdp_str ) ) {
/* The SIP RFC for SOA forbids sending a 183 with one sdp then a 200 with another but it won't do us much good unless
we do so in this case we will abandon the SOA rules and go rogue .
2010-06-30 10:35:03 -05:00
*/
2010-06-18 15:42:14 -05:00
sofia_clear_flag ( tech_pvt , TFLAG_ENABLE_SOA ) ;
}
2009-12-19 17:43:05 +00:00
if ( sofia_use_soa ( tech_pvt ) ) {
nua_respond ( tech_pvt - > nh , SIP_200_OK ,
NUTAG_AUTOANSWER ( 0 ) ,
2010-01-28 20:35:17 +00:00
TAG_IF ( call_info , SIPTAG_CALL_INFO_STR ( call_info ) ) ,
2009-12-19 17:43:05 +00:00
TAG_IF ( sticky , NUTAG_PROXY ( tech_pvt - > record_route ) ) ,
2010-06-29 09:32:41 -05:00
TAG_IF ( cid , SIPTAG_HEADER_STR ( cid ) ) ,
2009-12-19 17:43:05 +00:00
NUTAG_SESSION_TIMER ( session_timeout ) ,
2010-09-08 22:53:57 -05:00
TAG_IF ( session_timeout , NUTAG_SESSION_REFRESHER ( nua_remote_refresher ) ) ,
2009-12-19 17:43:05 +00:00
SIPTAG_CONTACT_STR ( tech_pvt - > reply_contact ) ,
SIPTAG_CALL_INFO_STR ( switch_channel_get_variable ( tech_pvt - > channel , SOFIA_SIP_HEADER_PREFIX " call_info " ) ) ,
SOATAG_USER_SDP_STR ( tech_pvt - > local_sdp_str ) ,
2010-02-06 03:38:24 +00:00
SOATAG_REUSE_REJECTED ( 1 ) , SOATAG_ORDERED_USER ( 1 ) , SOATAG_AUDIO_AUX ( " cn telephone-event " ) , NUTAG_INCLUDE_EXTRA_SDP ( 1 ) ,
2009-12-19 17:43:05 +00:00
TAG_IF ( ! zstr ( extra_headers ) , SIPTAG_HEADER_STR ( extra_headers ) ) ,
2010-02-06 03:38:24 +00:00
TAG_IF ( switch_stristr ( " update_display " , tech_pvt - > x_freeswitch_support_remote ) ,
SIPTAG_HEADER_STR ( " X-FS-Support: " FREESWITCH_SUPPORT ) ) , TAG_END ( ) ) ;
2009-12-19 17:43:05 +00:00
} else {
nua_respond ( tech_pvt - > nh , SIP_200_OK ,
NUTAG_AUTOANSWER ( 0 ) ,
NUTAG_MEDIA_ENABLE ( 0 ) ,
2010-01-28 20:35:17 +00:00
TAG_IF ( call_info , SIPTAG_CALL_INFO_STR ( call_info ) ) ,
2009-12-19 17:43:05 +00:00
TAG_IF ( sticky , NUTAG_PROXY ( tech_pvt - > record_route ) ) ,
2010-06-29 09:32:41 -05:00
TAG_IF ( cid , SIPTAG_HEADER_STR ( cid ) ) ,
2009-12-19 17:43:05 +00:00
NUTAG_SESSION_TIMER ( session_timeout ) ,
2010-09-08 22:53:57 -05:00
TAG_IF ( session_timeout , NUTAG_SESSION_REFRESHER ( nua_remote_refresher ) ) ,
2009-12-19 17:43:05 +00:00
SIPTAG_CONTACT_STR ( tech_pvt - > reply_contact ) ,
SIPTAG_CALL_INFO_STR ( switch_channel_get_variable ( tech_pvt - > channel , SOFIA_SIP_HEADER_PREFIX " call_info " ) ) ,
SIPTAG_CONTENT_TYPE_STR ( " application/sdp " ) ,
2010-02-06 03:38:24 +00:00
SIPTAG_PAYLOAD_STR ( tech_pvt - > local_sdp_str ) ,
2009-12-19 17:43:05 +00:00
TAG_IF ( ! zstr ( extra_headers ) , SIPTAG_HEADER_STR ( extra_headers ) ) ,
2010-02-06 03:38:24 +00:00
TAG_IF ( switch_stristr ( " update_display " , tech_pvt - > x_freeswitch_support_remote ) ,
SIPTAG_HEADER_STR ( " X-FS-Support: " FREESWITCH_SUPPORT ) ) , TAG_END ( ) ) ;
2009-12-19 17:43:05 +00:00
}
2009-08-11 00:54:39 +00:00
switch_safe_free ( extra_headers ) ;
2009-03-20 01:52:53 +00:00
sofia_set_flag_locked ( tech_pvt , TFLAG_ANS ) ;
}
2008-09-27 21:41:09 +00:00
2007-03-31 19:01:33 +00:00
return SWITCH_STATUS_SUCCESS ;
2006-09-27 03:44:14 +00:00
}
2008-05-08 19:19:47 +00:00
static switch_status_t sofia_read_video_frame ( switch_core_session_t * session , switch_frame_t * * frame , switch_io_flag_t flags , int stream_id )
2006-08-25 23:55:59 +00:00
{
2008-01-28 07:26:10 +00:00
private_object_t * tech_pvt = ( private_object_t * ) switch_core_session_get_private ( session ) ;
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
2007-03-31 19:01:33 +00:00
int payload = 0 ;
2006-10-06 22:39:49 +00:00
2007-12-12 23:21:45 +00:00
switch_assert ( tech_pvt ! = NULL ) ;
2006-10-31 21:38:06 +00:00
2009-02-09 17:56:38 +00:00
if ( sofia_test_flag ( tech_pvt , TFLAG_HUP ) ) {
2007-03-31 19:01:33 +00:00
return SWITCH_STATUS_FALSE ;
2006-08-25 23:55:59 +00:00
}
2007-04-19 21:40:50 +00:00
while ( ! ( tech_pvt - > video_read_codec . implementation & & switch_rtp_ready ( tech_pvt - > video_rtp_session ) ) ) {
2007-03-31 19:01:33 +00:00
if ( switch_channel_ready ( channel ) ) {
switch_yield ( 10000 ) ;
} else {
return SWITCH_STATUS_GENERR ;
}
2006-08-25 23:55:59 +00:00
}
2007-04-19 21:40:50 +00:00
tech_pvt - > video_read_frame . datalen = 0 ;
2006-08-25 23:55:59 +00:00
2009-02-09 17:56:38 +00:00
if ( sofia_test_flag ( tech_pvt , TFLAG_IO ) ) {
2007-04-19 21:40:50 +00:00
switch_status_t status ;
2009-02-09 17:56:38 +00:00
if ( ! sofia_test_flag ( tech_pvt , TFLAG_RTP ) ) {
2007-04-19 21:40:50 +00:00
return SWITCH_STATUS_GENERR ;
}
2007-12-12 23:21:45 +00:00
switch_assert ( tech_pvt - > rtp_session ! = NULL ) ;
2007-04-19 21:40:50 +00:00
tech_pvt - > video_read_frame . datalen = 0 ;
2009-02-09 17:56:38 +00:00
while ( sofia_test_flag ( tech_pvt , TFLAG_IO ) & & tech_pvt - > video_read_frame . datalen = = 0 ) {
2007-04-19 21:40:50 +00:00
tech_pvt - > video_read_frame . flags = SFF_NONE ;
2008-05-08 19:19:47 +00:00
status = switch_rtp_zerocopy_read_frame ( tech_pvt - > video_rtp_session , & tech_pvt - > video_read_frame , flags ) ;
2007-04-19 21:40:50 +00:00
if ( status ! = SWITCH_STATUS_SUCCESS & & status ! = SWITCH_STATUS_BREAK ) {
2007-10-31 13:08:45 +00:00
if ( status = = SWITCH_STATUS_TIMEOUT ) {
2009-06-25 18:56:37 +00:00
if ( sofia_test_flag ( tech_pvt , TFLAG_SIP_HOLD ) ) {
sofia_glue_toggle_hold ( tech_pvt , 0 ) ;
sofia_clear_flag_locked ( tech_pvt , TFLAG_SIP_HOLD ) ;
2009-11-24 18:18:09 +00:00
switch_channel_clear_flag ( channel , CF_LEG_HOLDING ) ;
2009-06-25 18:56:37 +00:00
}
2007-10-31 13:08:45 +00:00
switch_channel_hangup ( tech_pvt - > channel , SWITCH_CAUSE_MEDIA_TIMEOUT ) ;
}
return status ;
2007-04-19 21:40:50 +00:00
}
2008-05-27 04:54:52 +00:00
2007-04-19 21:40:50 +00:00
payload = tech_pvt - > video_read_frame . payload ;
if ( tech_pvt - > video_read_frame . datalen > 0 ) {
break ;
}
2006-10-09 02:24:43 +00:00
}
2007-03-31 19:01:33 +00:00
}
2006-10-09 02:24:43 +00:00
2007-04-19 21:40:50 +00:00
if ( tech_pvt - > video_read_frame . datalen = = 0 ) {
* frame = NULL ;
return SWITCH_STATUS_GENERR ;
}
* frame = & tech_pvt - > video_read_frame ;
return SWITCH_STATUS_SUCCESS ;
}
2008-05-08 19:19:47 +00:00
static switch_status_t sofia_write_video_frame ( switch_core_session_t * session , switch_frame_t * frame , switch_io_flag_t flags , int stream_id )
2007-04-19 21:40:50 +00:00
{
2008-01-28 07:26:10 +00:00
private_object_t * tech_pvt = ( private_object_t * ) switch_core_session_get_private ( session ) ;
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
2009-11-18 19:22:45 +00:00
int wrote = 0 ;
2007-04-19 21:40:50 +00:00
2007-12-12 23:21:45 +00:00
switch_assert ( tech_pvt ! = NULL ) ;
2007-04-19 21:40:50 +00:00
while ( ! ( tech_pvt - > video_read_codec . implementation & & switch_rtp_ready ( tech_pvt - > video_rtp_session ) ) ) {
if ( switch_channel_ready ( channel ) ) {
switch_yield ( 10000 ) ;
} else {
return SWITCH_STATUS_GENERR ;
}
}
2009-02-09 17:56:38 +00:00
if ( sofia_test_flag ( tech_pvt , TFLAG_HUP ) ) {
2007-04-19 21:40:50 +00:00
return SWITCH_STATUS_FALSE ;
}
2009-02-09 17:56:38 +00:00
if ( ! sofia_test_flag ( tech_pvt , TFLAG_RTP ) ) {
2007-04-19 21:40:50 +00:00
return SWITCH_STATUS_GENERR ;
}
2009-02-09 17:56:38 +00:00
if ( ! sofia_test_flag ( tech_pvt , TFLAG_IO ) ) {
2007-04-19 21:40:50 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2009-02-11 20:49:45 +00:00
if ( ! switch_test_flag ( frame , SFF_CNG ) ) {
2009-11-18 19:22:45 +00:00
wrote = switch_rtp_write_frame ( tech_pvt - > video_rtp_session , frame ) ;
2007-04-19 21:40:50 +00:00
}
2008-05-27 04:54:52 +00:00
2009-11-18 19:22:45 +00:00
return wrote > 0 ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_GENERR ;
2007-04-19 21:40:50 +00:00
}
2008-05-08 19:19:47 +00:00
static switch_status_t sofia_read_frame ( switch_core_session_t * session , switch_frame_t * * frame , switch_io_flag_t flags , int stream_id )
2007-04-19 21:40:50 +00:00
{
2008-05-27 04:54:52 +00:00
private_object_t * tech_pvt = switch_core_session_get_private ( session ) ;
2008-01-28 07:26:10 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
2007-04-19 21:40:50 +00:00
int payload = 0 ;
2009-08-21 16:22:16 +00:00
uint32_t sanity = 1000 ;
2010-04-19 19:07:23 -05:00
switch_rtcp_frame_t rtcp_frame ;
2007-04-19 21:40:50 +00:00
2007-12-12 23:21:45 +00:00
switch_assert ( tech_pvt ! = NULL ) ;
2007-04-19 21:40:50 +00:00
2009-02-09 17:56:38 +00:00
if ( ! sofia_test_pflag ( tech_pvt - > profile , PFLAG_RUNNING ) ) {
2008-01-08 16:35:20 +00:00
switch_channel_hangup ( tech_pvt - > channel , SWITCH_CAUSE_NORMAL_CLEARING ) ;
return SWITCH_STATUS_FALSE ;
}
2009-02-09 17:56:38 +00:00
if ( sofia_test_flag ( tech_pvt , TFLAG_HUP ) ) {
2007-04-19 21:40:50 +00:00
return SWITCH_STATUS_FALSE ;
}
2008-03-24 20:58:44 +00:00
while ( ! ( tech_pvt - > read_codec . implementation & & switch_rtp_ready ( tech_pvt - > rtp_session ) & & ! switch_channel_test_flag ( channel , CF_REQ_MEDIA ) ) ) {
2009-11-09 23:49:35 +00:00
if ( - - sanity & & switch_channel_up ( channel ) ) {
2007-04-19 21:40:50 +00:00
switch_yield ( 10000 ) ;
} else {
2009-08-21 16:30:40 +00:00
switch_channel_hangup ( tech_pvt - > channel , SWITCH_CAUSE_RECOVERY_ON_TIMER_EXPIRE ) ;
2007-04-19 21:40:50 +00:00
return SWITCH_STATUS_GENERR ;
}
}
tech_pvt - > read_frame . datalen = 0 ;
2009-02-09 17:56:38 +00:00
sofia_set_flag_locked ( tech_pvt , TFLAG_READING ) ;
2007-03-20 23:11:20 +00:00
2010-02-06 03:38:24 +00:00
if ( sofia_test_flag ( tech_pvt , TFLAG_HUP ) | | sofia_test_flag ( tech_pvt , TFLAG_BYE ) | | ! tech_pvt - > read_codec . implementation | |
2009-04-09 17:17:12 +00:00
! switch_core_codec_ready ( & tech_pvt - > read_codec ) ) {
2008-12-16 20:59:00 +00:00
return SWITCH_STATUS_FALSE ;
}
2009-02-09 17:56:38 +00:00
if ( sofia_test_flag ( tech_pvt , TFLAG_IO ) ) {
2007-03-31 19:01:33 +00:00
switch_status_t status ;
2008-05-27 04:54:52 +00:00
2009-02-09 17:56:38 +00:00
if ( ! sofia_test_flag ( tech_pvt , TFLAG_RTP ) ) {
2007-03-31 19:01:33 +00:00
return SWITCH_STATUS_GENERR ;
2007-03-08 02:52:31 +00:00
}
2007-02-03 19:47:21 +00:00
2007-12-12 23:21:45 +00:00
switch_assert ( tech_pvt - > rtp_session ! = NULL ) ;
2007-03-31 19:01:33 +00:00
tech_pvt - > read_frame . datalen = 0 ;
2010-02-06 03:38:24 +00:00
2009-02-09 17:56:38 +00:00
while ( sofia_test_flag ( tech_pvt , TFLAG_IO ) & & tech_pvt - > read_frame . datalen = = 0 ) {
2007-03-31 19:01:33 +00:00
tech_pvt - > read_frame . flags = SFF_NONE ;
2006-10-06 22:39:49 +00:00
2008-05-08 19:19:47 +00:00
status = switch_rtp_zerocopy_read_frame ( tech_pvt - > rtp_session , & tech_pvt - > read_frame , flags ) ;
2008-05-27 04:54:52 +00:00
2007-03-31 19:01:33 +00:00
if ( status ! = SWITCH_STATUS_SUCCESS & & status ! = SWITCH_STATUS_BREAK ) {
2007-10-31 13:08:45 +00:00
if ( status = = SWITCH_STATUS_TIMEOUT ) {
2010-02-06 03:38:24 +00:00
2009-06-25 18:56:37 +00:00
if ( sofia_test_flag ( tech_pvt , TFLAG_SIP_HOLD ) ) {
sofia_glue_toggle_hold ( tech_pvt , 0 ) ;
sofia_clear_flag_locked ( tech_pvt , TFLAG_SIP_HOLD ) ;
2009-11-24 18:18:09 +00:00
switch_channel_clear_flag ( channel , CF_LEG_HOLDING ) ;
2009-06-25 18:56:37 +00:00
}
2010-02-06 03:38:24 +00:00
2007-10-31 13:08:45 +00:00
switch_channel_hangup ( tech_pvt - > channel , SWITCH_CAUSE_MEDIA_TIMEOUT ) ;
}
return status ;
2007-03-31 19:01:33 +00:00
}
2010-06-23 13:22:52 -05:00
2010-04-19 19:07:23 -05:00
/* Try to read an RTCP frame, if successful raise an event */
if ( switch_rtcp_zerocopy_read_frame ( tech_pvt - > rtp_session , & rtcp_frame ) = = SWITCH_STATUS_SUCCESS ) {
switch_event_t * event ;
if ( switch_event_create ( & event , SWITCH_EVENT_RECV_RTCP_MESSAGE ) = = SWITCH_STATUS_SUCCESS ) {
char buf [ 30 ] ;
2010-06-23 13:22:52 -05:00
char * uuid = switch_core_session_get_uuid ( session ) ;
2010-04-19 19:07:23 -05:00
if ( uuid ) {
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Unique-ID " , switch_core_session_get_uuid ( session ) ) ;
}
snprintf ( buf , sizeof ( buf ) , " %.8x " , rtcp_frame . ssrc ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " SSRC " , buf ) ;
snprintf ( buf , sizeof ( buf ) , " %u " , rtcp_frame . ntp_msw ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " NTP-Most-Significant-Word " , buf ) ;
snprintf ( buf , sizeof ( buf ) , " %u " , rtcp_frame . ntp_lsw ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " NTP-Least-Significant-Word " , buf ) ;
snprintf ( buf , sizeof ( buf ) , " %u " , rtcp_frame . timestamp ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " RTP-Timestamp " , buf ) ;
2010-06-23 13:22:52 -05:00
snprintf ( buf , sizeof ( buf ) , " %u " , rtcp_frame . packet_count ) ;
2010-04-19 19:07:23 -05:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Sender-Packet-Count " , buf ) ;
2010-06-23 13:22:52 -05:00
snprintf ( buf , sizeof ( buf ) , " %u " , rtcp_frame . octect_count ) ;
2010-04-19 19:07:23 -05:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Octect-Packet-Count " , buf ) ;
2010-04-20 12:21:46 -05:00
snprintf ( buf , sizeof ( buf ) , " % " SWITCH_SIZE_T_FMT , tech_pvt - > read_frame . timestamp ) ;
2010-04-19 19:07:23 -05:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Last-RTP-Timestamp " , buf ) ;
snprintf ( buf , sizeof ( buf ) , " %u " , tech_pvt - > read_frame . rate ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " RTP-Rate " , buf ) ;
2010-04-20 12:33:10 -05:00
snprintf ( buf , sizeof ( buf ) , " % " SWITCH_TIME_T_FMT , switch_time_now ( ) ) ;
2010-04-19 19:07:23 -05:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Capture-Time " , buf ) ;
switch_event_fire ( & event ) ;
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG10 , " Dispatched RTCP event \n " ) ;
}
}
2008-05-27 04:54:52 +00:00
2008-10-22 17:12:04 +00:00
/* Fast PASS! */
2009-02-11 20:49:45 +00:00
if ( switch_test_flag ( ( & tech_pvt - > read_frame ) , SFF_PROXY_PACKET ) ) {
2009-02-09 17:56:38 +00:00
sofia_clear_flag_locked ( tech_pvt , TFLAG_READING ) ;
2008-10-22 17:12:04 +00:00
* frame = & tech_pvt - > read_frame ;
return SWITCH_STATUS_SUCCESS ;
}
2007-03-31 19:01:33 +00:00
payload = tech_pvt - > read_frame . payload ;
2007-01-28 17:37:51 +00:00
2007-03-31 19:01:33 +00:00
if ( switch_rtp_has_dtmf ( tech_pvt - > rtp_session ) ) {
2008-05-27 04:54:52 +00:00
switch_dtmf_t dtmf = { 0 } ;
2007-12-22 00:32:20 +00:00
switch_rtp_dequeue_dtmf ( tech_pvt - > rtp_session , & dtmf ) ;
switch_channel_queue_dtmf ( channel , & dtmf ) ;
2007-03-29 22:31:56 +00:00
}
2008-05-27 04:54:52 +00:00
2007-03-31 19:01:33 +00:00
if ( tech_pvt - > read_frame . datalen > 0 ) {
2009-11-09 17:15:46 +00:00
uint32_t bytes = 0 ;
2007-03-31 19:01:33 +00:00
int frames = 1 ;
2009-12-03 22:51:50 +00:00
2009-02-11 20:49:45 +00:00
if ( ! switch_test_flag ( ( & tech_pvt - > read_frame ) , SFF_CNG ) ) {
2009-04-09 17:17:12 +00:00
if ( ! tech_pvt - > read_codec . implementation | | ! switch_core_codec_ready ( & tech_pvt - > read_codec ) ) {
2008-08-06 23:25:24 +00:00
* frame = NULL ;
return SWITCH_STATUS_GENERR ;
}
2010-02-06 03:38:24 +00:00
2009-09-25 18:25:45 +00:00
if ( ( tech_pvt - > read_frame . datalen % 10 ) = = 0 & &
2009-11-21 06:54:16 +00:00
sofia_test_pflag ( tech_pvt - > profile , PFLAG_AUTOFIX_TIMING ) & & tech_pvt - > check_frames < MAX_CODEC_CHECK_FRAMES ) {
tech_pvt - > check_frames + + ;
2010-02-06 03:38:24 +00:00
2009-01-12 18:37:44 +00:00
if ( ! tech_pvt - > read_impl . encoded_bytes_per_packet ) {
2008-11-21 16:14:02 +00:00
tech_pvt - > check_frames = MAX_CODEC_CHECK_FRAMES ;
goto skip ;
}
2010-02-06 03:38:24 +00:00
2009-01-12 18:37:44 +00:00
if ( tech_pvt - > last_ts & & tech_pvt - > read_frame . datalen ! = tech_pvt - > read_impl . encoded_bytes_per_packet ) {
2010-02-06 03:38:24 +00:00
uint32_t codec_ms = ( int ) ( tech_pvt - > read_frame . timestamp -
tech_pvt - > last_ts ) / ( tech_pvt - > read_impl . samples_per_second / 1000 ) ;
2009-12-03 22:51:50 +00:00
if ( ( codec_ms % 10 ) ! = 0 | | codec_ms > tech_pvt - > read_impl . samples_per_packet * 10 ) {
tech_pvt - > last_ts = 0 ;
2008-12-02 21:33:01 +00:00
goto skip ;
}
2010-02-06 03:38:24 +00:00
2009-12-03 22:51:50 +00:00
2009-12-04 20:40:53 +00:00
if ( tech_pvt - > last_codec_ms & & tech_pvt - > last_codec_ms = = codec_ms ) {
2008-12-02 21:33:01 +00:00
tech_pvt - > mismatch_count + + ;
}
2010-06-23 13:22:52 -05:00
2008-12-05 15:40:34 +00:00
tech_pvt - > last_codec_ms = codec_ms ;
2010-06-23 13:22:52 -05:00
2008-12-02 21:33:01 +00:00
if ( tech_pvt - > mismatch_count > MAX_MISMATCH_FRAMES ) {
if ( switch_rtp_ready ( tech_pvt - > rtp_session ) & & codec_ms ! = tech_pvt - > codec_ms ) {
const char * val ;
int rtp_timeout_sec = 0 ;
int rtp_hold_timeout_sec = 0 ;
2010-02-06 03:38:24 +00:00
if ( codec_ms > 120 ) { /* yeah right */
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING ,
2009-03-17 16:39:12 +00:00
" Your phone is trying to send timestamps that suggest an increment of %dms per packet \n "
2010-02-06 03:38:24 +00:00
" That seems hard to believe so I am going to go on ahead and um ignore that, mmkay? " ,
( int ) codec_ms ) ;
2009-03-17 16:39:12 +00:00
tech_pvt - > check_frames = MAX_CODEC_CHECK_FRAMES ;
goto skip ;
}
2008-12-30 20:19:06 +00:00
tech_pvt - > read_frame . datalen = 0 ;
2009-12-03 22:51:50 +00:00
2010-05-12 21:25:54 -05:00
if ( codec_ms ! = tech_pvt - > codec_ms ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING ,
" We were told to use ptime %d but what they meant to say was %d \n "
" This issue has so far been identified to happen on the following broken platforms/devices: \n "
" Linksys/Sipura aka Cisco \n "
" ShoreTel \n "
" Sonus/L3 \n "
" We will try to fix it but some of the devices on this list are so broken, \n "
2010-06-23 13:22:52 -05:00
" who knows what will happen.. \n " , ( int ) tech_pvt - > codec_ms , ( int ) codec_ms ) ;
2010-05-12 21:25:54 -05:00
switch_channel_set_variable_printf ( channel , " sip_h_X-Broken-PTIME " , " Adv=%d;Sent=%d " ,
( int ) tech_pvt - > codec_ms , ( int ) codec_ms ) ;
tech_pvt - > codec_ms = codec_ms ;
}
2010-02-06 03:38:24 +00:00
2008-12-02 21:33:01 +00:00
if ( sofia_glue_tech_set_codec ( tech_pvt , 2 ) ! = SWITCH_STATUS_SUCCESS ) {
* frame = NULL ;
return SWITCH_STATUS_GENERR ;
}
2010-02-06 03:38:24 +00:00
2008-12-02 21:33:01 +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-11-18 22:15:51 +00:00
}
2008-12-02 21:33:01 +00:00
}
2010-02-06 03:38:24 +00:00
2008-12-02 21:33:01 +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-11-18 22:15:51 +00:00
}
2008-12-02 21:33:01 +00:00
}
2010-02-06 03:38:24 +00:00
2008-12-02 21:33:01 +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 ;
2010-02-06 03:38:24 +00:00
2008-12-02 21:33:01 +00:00
switch_rtp_set_max_missed_packets ( tech_pvt - > rtp_session , tech_pvt - > max_missed_packets ) ;
if ( ! rtp_hold_timeout_sec ) {
rtp_hold_timeout_sec = rtp_timeout_sec * 10 ;
2008-11-18 22:15:51 +00:00
}
2008-12-02 21:33:01 +00:00
}
2010-02-06 03:38:24 +00:00
2008-12-02 21:33:01 +00:00
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 ;
2008-12-02 21:33:01 +00:00
}
2010-02-06 03:38:24 +00:00
2009-12-04 20:54:15 +00:00
tech_pvt - > check_frames = 0 ;
2009-12-03 22:51:50 +00:00
tech_pvt - > last_ts = 0 ;
2009-12-04 20:54:15 +00:00
2009-02-11 16:36:55 +00:00
/* inform them of the codec they are actually sending */
2010-05-12 21:25:54 -05:00
2009-12-04 20:54:15 +00:00
if ( + + tech_pvt - > codec_reinvites > 2 ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING ,
2009-12-04 20:54:15 +00:00
" Ok, some devices *cough* X-lite *cough* \n "
" seem to continue to lie over and over again so I guess we'll \n "
" leave well-enough alone and let them lie \n " ) ;
} else {
sofia_glue_do_invite ( session ) ;
}
2008-12-18 23:07:32 +00:00
2008-11-19 01:01:42 +00:00
}
2010-02-06 03:38:24 +00:00
2008-11-10 18:26:41 +00:00
}
2010-02-06 03:38:24 +00:00
2008-11-19 01:05:36 +00:00
} else {
tech_pvt - > mismatch_count = 0 ;
2008-11-10 18:26:41 +00:00
}
2010-05-12 21:25:54 -05:00
2008-11-17 18:42:48 +00:00
tech_pvt - > last_ts = tech_pvt - > read_frame . timestamp ;
2010-05-12 21:25:54 -05:00
2009-09-25 18:25:45 +00:00
} else {
tech_pvt - > mismatch_count = 0 ;
tech_pvt - > last_ts = 0 ;
2008-11-10 18:26:41 +00:00
}
2010-06-30 10:35:03 -05:00
skip :
2010-02-06 03:38:24 +00:00
2009-01-12 18:37:44 +00:00
if ( ( bytes = tech_pvt - > read_impl . encoded_bytes_per_packet ) ) {
2007-03-31 19:01:33 +00:00
frames = ( tech_pvt - > read_frame . datalen / bytes ) ;
}
2009-01-12 18:37:44 +00:00
tech_pvt - > read_frame . samples = ( int ) ( frames * tech_pvt - > read_impl . samples_per_packet ) ;
2008-12-30 20:19:06 +00:00
if ( tech_pvt - > read_frame . datalen = = 0 ) {
continue ;
}
2007-03-31 19:01:33 +00:00
}
break ;
}
2007-03-08 20:05:09 +00:00
}
2006-08-25 23:55:59 +00:00
}
2007-03-29 22:31:56 +00:00
2009-02-09 17:56:38 +00:00
sofia_clear_flag_locked ( tech_pvt , TFLAG_READING ) ;
2006-08-25 23:55:59 +00:00
2007-03-31 19:01:33 +00:00
if ( tech_pvt - > read_frame . datalen = = 0 ) {
* frame = NULL ;
return SWITCH_STATUS_GENERR ;
2006-08-25 23:55:59 +00:00
}
2007-03-31 19:01:33 +00:00
* frame = & tech_pvt - > read_frame ;
2006-10-31 21:38:06 +00:00
2006-08-25 23:55:59 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2008-05-08 19:19:47 +00:00
static switch_status_t sofia_write_frame ( switch_core_session_t * session , switch_frame_t * frame , switch_io_flag_t flags , int stream_id )
2006-08-25 23:55:59 +00:00
{
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_status_t status = SWITCH_STATUS_SUCCESS ;
int bytes = 0 , samples = 0 , frames = 0 ;
2006-08-25 23:55:59 +00:00
2007-12-12 23:21:45 +00:00
switch_assert ( tech_pvt ! = NULL ) ;
2006-08-25 23:55:59 +00:00
2008-03-24 20:58:44 +00:00
while ( ! ( tech_pvt - > read_codec . implementation & & switch_rtp_ready ( tech_pvt - > rtp_session ) & & ! switch_channel_test_flag ( channel , CF_REQ_MEDIA ) ) ) {
2007-03-31 19:01:33 +00:00
if ( switch_channel_ready ( channel ) ) {
switch_yield ( 10000 ) ;
} else {
return SWITCH_STATUS_GENERR ;
}
2007-03-19 21:09:53 +00:00
}
2006-10-05 04:06:07 +00:00
2009-04-09 17:17:12 +00:00
if ( ! tech_pvt - > read_codec . implementation | | ! switch_core_codec_ready ( & tech_pvt - > read_codec ) ) {
2007-12-13 04:01:29 +00:00
return SWITCH_STATUS_GENERR ;
}
2009-02-09 17:56:38 +00:00
if ( sofia_test_flag ( tech_pvt , TFLAG_HUP ) ) {
2007-03-19 21:09:53 +00:00
return SWITCH_STATUS_FALSE ;
}
2006-10-19 16:42:41 +00:00
2009-02-09 17:56:38 +00:00
if ( ! sofia_test_flag ( tech_pvt , TFLAG_RTP ) ) {
2007-03-31 19:01:33 +00:00
return SWITCH_STATUS_GENERR ;
2007-03-19 21:09:53 +00:00
}
2009-02-09 17:56:38 +00:00
if ( ! sofia_test_flag ( tech_pvt , TFLAG_IO ) ) {
2007-03-31 19:01:33 +00:00
return SWITCH_STATUS_SUCCESS ;
2007-03-19 21:09:53 +00:00
}
2007-03-29 22:31:56 +00:00
2009-04-09 17:17:12 +00:00
if ( sofia_test_flag ( tech_pvt , TFLAG_BYE ) | | ! tech_pvt - > read_codec . implementation | | ! switch_core_codec_ready ( & tech_pvt - > read_codec ) ) {
2008-12-16 20:59:00 +00:00
return SWITCH_STATUS_FALSE ;
}
2009-02-09 17:56:38 +00:00
sofia_set_flag_locked ( tech_pvt , TFLAG_WRITING ) ;
2006-10-16 04:39:00 +00:00
2009-02-11 20:49:45 +00:00
if ( ! switch_test_flag ( frame , SFF_CNG ) & & ! switch_test_flag ( frame , SFF_PROXY_PACKET ) ) {
2009-01-12 18:37:44 +00:00
if ( tech_pvt - > read_impl . encoded_bytes_per_packet ) {
bytes = tech_pvt - > read_impl . encoded_bytes_per_packet ;
2007-03-31 19:01:33 +00:00
frames = ( ( int ) frame - > datalen / bytes ) ;
} else
frames = 1 ;
2007-03-29 22:31:56 +00:00
2009-01-12 18:37:44 +00:00
samples = frames * tech_pvt - > read_impl . samples_per_packet ;
2007-03-19 21:09:53 +00:00
}
2006-10-06 22:39:49 +00:00
2007-03-31 19:01:33 +00:00
tech_pvt - > timestamp_send + = samples ;
2008-01-11 04:23:09 +00:00
switch_rtp_write_frame ( tech_pvt - > rtp_session , frame ) ;
2006-10-18 22:57:35 +00:00
2009-02-09 17:56:38 +00:00
sofia_clear_flag_locked ( tech_pvt , TFLAG_WRITING ) ;
2007-03-31 19:01:33 +00:00
return status ;
}
2006-10-18 22:57:35 +00:00
2007-03-31 19:01:33 +00:00
static switch_status_t sofia_kill_channel ( switch_core_session_t * session , int sig )
{
2008-01-28 07:26:10 +00:00
private_object_t * tech_pvt = switch_core_session_get_private ( session ) ;
2007-02-06 18:11:25 +00:00
2008-03-10 19:04:01 +00:00
if ( ! tech_pvt ) {
return SWITCH_STATUS_FALSE ;
}
2007-02-13 01:22:17 +00:00
2007-03-31 19:01:33 +00:00
switch ( sig ) {
case SWITCH_SIG_BREAK :
if ( switch_rtp_ready ( tech_pvt - > rtp_session ) ) {
2008-03-07 18:21:08 +00:00
switch_rtp_break ( tech_pvt - > rtp_session ) ;
2007-02-13 01:22:17 +00:00
}
2007-04-19 21:40:50 +00:00
if ( switch_rtp_ready ( tech_pvt - > video_rtp_session ) ) {
2008-07-31 19:03:13 +00:00
switch_rtp_break ( tech_pvt - > video_rtp_session ) ;
2007-04-19 21:40:50 +00:00
}
2007-03-31 19:01:33 +00:00
break ;
case SWITCH_SIG_KILL :
default :
2009-02-09 17:56:38 +00:00
sofia_clear_flag_locked ( tech_pvt , TFLAG_IO ) ;
sofia_set_flag_locked ( tech_pvt , TFLAG_HUP ) ;
2007-03-29 22:31:56 +00:00
2007-03-31 19:01:33 +00:00
if ( switch_rtp_ready ( tech_pvt - > rtp_session ) ) {
switch_rtp_kill_socket ( tech_pvt - > rtp_session ) ;
}
2007-04-19 21:40:50 +00:00
if ( switch_rtp_ready ( tech_pvt - > video_rtp_session ) ) {
switch_rtp_kill_socket ( tech_pvt - > video_rtp_session ) ;
}
2007-03-31 19:01:33 +00:00
break ;
2007-03-19 21:09:53 +00:00
}
return SWITCH_STATUS_SUCCESS ;
2006-10-06 22:39:49 +00:00
}
2010-06-17 10:23:37 -05:00
static void start_udptl ( private_object_t * tech_pvt , switch_t38_options_t * t38_options )
{
if ( switch_rtp_ready ( tech_pvt - > rtp_session ) ) {
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 ) ;
const char * err , * val ;
switch_rtp_udptl_mode ( tech_pvt - > rtp_session ) ;
2010-09-23 11:16:47 -05:00
if ( ! t38_options | | ! t38_options - > remote_ip ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_DEBUG , " No remote address \n " ) ;
return ;
}
if ( remote_host & & remote_port & & remote_port = = t38_options - > remote_port & & ! strcmp ( remote_host , t38_options - > remote_ip ) ) {
2010-06-17 10:23:37 -05:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_DEBUG , " Remote address:port [%s:%d] has not changed. \n " ,
t38_options - > remote_ip , t38_options - > remote_port ) ;
return ;
}
2010-06-23 13:22:52 -05:00
2010-06-17 10:23:37 -05:00
if ( switch_rtp_set_remote_address ( tech_pvt - > rtp_session , t38_options - > remote_ip ,
t38_options - > remote_port , 0 , SWITCH_TRUE , & err ) ! = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_ERROR , " IMAGE UDPTL REPORTS ERROR: [%s] \n " , err ) ;
} else {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( tech_pvt - > session ) , SWITCH_LOG_DEBUG , " IMAGE UDPTL CHANGING DEST TO: [%s:%d] \n " ,
t38_options - > remote_ip , t38_options - > remote_port ) ;
if ( ! sofia_test_pflag ( tech_pvt - > profile , PFLAG_DISABLE_RTP_AUTOADJ ) & &
! ( ( val = switch_channel_get_variable ( tech_pvt - > channel , " disable_udptl_auto_adjust " ) ) & & switch_true ( val ) ) ) {
/* Reactivate the NAT buster flag. */
switch_rtp_set_flag ( tech_pvt - > rtp_session , SWITCH_RTP_FLAG_AUTOADJ ) ;
}
}
}
}
2007-12-22 00:32:20 +00:00
static switch_status_t sofia_send_dtmf ( switch_core_session_t * session , const switch_dtmf_t * dtmf )
2006-08-25 23:55:59 +00:00
{
2007-03-31 19:01:33 +00:00
private_object_t * tech_pvt ;
2007-12-22 00:32:20 +00:00
char message [ 128 ] = " " ;
2009-03-06 17:45:32 +00:00
sofia_dtmf_t dtmf_type ;
2006-08-25 23:55:59 +00:00
tech_pvt = ( private_object_t * ) switch_core_session_get_private ( session ) ;
2007-12-12 23:21:45 +00:00
switch_assert ( tech_pvt ! = NULL ) ;
2006-08-25 23:55:59 +00:00
2009-03-06 17:45:32 +00:00
dtmf_type = tech_pvt - > dtmf_type ;
/* We only can send INFO when we have no media */
if ( ! tech_pvt - > rtp_session | | ! switch_channel_media_ready ( tech_pvt - > channel ) | | switch_channel_test_flag ( tech_pvt - > channel , CF_PROXY_MODE ) ) {
dtmf_type = DTMF_INFO ;
}
switch ( dtmf_type ) {
2007-12-22 00:32:20 +00:00
case DTMF_2833 :
2009-05-29 18:11:07 +00:00
{
return switch_rtp_queue_rfc2833 ( tech_pvt - > rtp_session , dtmf ) ;
}
2007-12-22 00:32:20 +00:00
case DTMF_INFO :
2009-05-29 18:11:07 +00:00
{
snprintf ( message , sizeof ( message ) , " Signal=%c \r \n Duration=%d \r \n " , dtmf - > digit , dtmf - > duration / 8 ) ;
switch_mutex_lock ( tech_pvt - > sofia_mutex ) ;
nua_info ( tech_pvt - > nh , SIPTAG_CONTENT_TYPE_STR ( " application/dtmf-relay " ) , SIPTAG_PAYLOAD_STR ( message ) , TAG_END ( ) ) ;
switch_mutex_unlock ( tech_pvt - > sofia_mutex ) ;
}
break ;
case DTMF_NONE :
2007-12-22 00:32:20 +00:00
break ;
default :
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING , " Unhandled DTMF type! \n " ) ;
2007-12-22 00:32:20 +00:00
break ;
}
return SWITCH_STATUS_SUCCESS ;
2006-09-12 22:24:39 +00:00
}
2007-03-31 19:01:33 +00:00
static switch_status_t sofia_receive_message ( switch_core_session_t * session , switch_core_session_message_t * msg )
2006-08-25 23:55:59 +00:00
{
2008-01-28 07:26:10 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
private_object_t * tech_pvt = switch_core_session_get_private ( session ) ;
2008-02-25 16:35:19 +00:00
switch_status_t status = SWITCH_STATUS_SUCCESS ;
2009-03-20 01:52:53 +00:00
if ( switch_channel_down ( channel ) | | ! tech_pvt | | sofia_test_flag ( tech_pvt , TFLAG_BYE ) ) {
2008-02-25 16:35:19 +00:00
status = SWITCH_STATUS_FALSE ;
goto end ;
2008-02-15 19:48:16 +00:00
}
2006-08-25 23:55:59 +00:00
2008-11-03 21:54:03 +00:00
/* ones that do not need to lock sofia mutex */
switch ( msg - > message_id ) {
2010-02-06 03:38:24 +00:00
case SWITCH_MESSAGE_INDICATE_APPLICATION_EXEC :
{
sofia_glue_tech_track ( tech_pvt - > profile , session ) ;
}
break ;
2010-01-21 18:03:54 +00:00
case SWITCH_MESSAGE_INDICATE_PROXY_MEDIA :
{
if ( switch_rtp_ready ( tech_pvt - > rtp_session ) ) {
if ( msg - > numeric_arg ) {
switch_rtp_set_flag ( tech_pvt - > rtp_session , SWITCH_RTP_FLAG_PROXY_MEDIA ) ;
} else {
switch_rtp_clear_flag ( tech_pvt - > rtp_session , SWITCH_RTP_FLAG_PROXY_MEDIA ) ;
}
}
}
break ;
2009-10-29 17:29:05 +00:00
case SWITCH_MESSAGE_INDICATE_DEBUG_AUDIO :
{
2009-10-29 17:52:52 +00:00
if ( switch_rtp_ready ( tech_pvt - > rtp_session ) & & ! zstr ( msg - > string_array_arg [ 0 ] ) & & ! zstr ( msg - > string_array_arg [ 1 ] ) ) {
int32_t flags = 0 ;
if ( ! strcasecmp ( msg - > string_array_arg [ 0 ] , " read " ) ) {
flags | = SWITCH_RTP_FLAG_DEBUG_RTP_READ ;
} else if ( ! strcasecmp ( msg - > string_array_arg [ 0 ] , " write " ) ) {
flags | = SWITCH_RTP_FLAG_DEBUG_RTP_WRITE ;
} else if ( ! strcasecmp ( msg - > string_array_arg [ 0 ] , " both " ) ) {
flags | = SWITCH_RTP_FLAG_DEBUG_RTP_READ | SWITCH_RTP_FLAG_DEBUG_RTP_WRITE ;
}
if ( flags ) {
if ( switch_true ( msg - > string_array_arg [ 1 ] ) ) {
switch_rtp_set_flag ( tech_pvt - > rtp_session , flags ) ;
} else {
switch_rtp_clear_flag ( tech_pvt - > rtp_session , flags ) ;
}
2009-10-29 17:29:05 +00:00
} else {
2009-10-29 17:52:52 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Invalid Options \n " ) ;
2009-10-29 17:29:05 +00:00
}
}
}
2009-10-29 17:52:52 +00:00
status = SWITCH_STATUS_FALSE ;
2009-10-29 17:29:05 +00:00
goto end ;
2008-11-03 21:54:03 +00:00
case SWITCH_MESSAGE_INDICATE_TRANSCODING_NECESSARY :
if ( tech_pvt - > rtp_session & & switch_rtp_test_flag ( tech_pvt - > rtp_session , SWITCH_RTP_FLAG_PASS_RFC2833 ) ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING , " Pass 2833 mode may not work on a transcoded call. \n " ) ;
2008-03-04 23:53:23 +00:00
}
2008-11-03 21:54:03 +00:00
goto end ;
case SWITCH_MESSAGE_INDICATE_BRIDGE :
2010-01-20 19:20:11 +00:00
{
2009-05-07 15:07:04 +00:00
2010-06-18 17:09:26 -05:00
sofia_glue_tech_simplify ( tech_pvt ) ;
2010-02-06 03:38:24 +00:00
2010-01-20 19:20:11 +00:00
if ( switch_rtp_ready ( tech_pvt - > rtp_session ) ) {
const char * val ;
int ok = 0 ;
if ( sofia_test_flag ( tech_pvt , TFLAG_PASS_RFC2833 ) & & switch_channel_test_flag_partner ( channel , CF_FS_RTP ) ) {
switch_rtp_set_flag ( tech_pvt - > rtp_session , SWITCH_RTP_FLAG_PASS_RFC2833 ) ;
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG ,
2010-01-20 19:20:11 +00:00
" %s activate passthru 2833 mode. \n " , switch_channel_get_name ( channel ) ) ;
}
if ( ( val = switch_channel_get_variable ( channel , " rtp_autoflush_during_bridge " ) ) ) {
ok = switch_true ( val ) ;
} else {
ok = sofia_test_pflag ( tech_pvt - > profile , PFLAG_RTP_AUTOFLUSH_DURING_BRIDGE ) ;
}
2010-07-29 17:41:23 -05:00
2010-01-20 19:20:11 +00:00
if ( ok ) {
rtp_flush_read_buffer ( tech_pvt - > rtp_session , SWITCH_RTP_FLUSH_STICK ) ;
} else {
rtp_flush_read_buffer ( tech_pvt - > rtp_session , SWITCH_RTP_FLUSH_ONCE ) ;
}
2009-05-07 15:07:04 +00:00
}
2009-04-16 22:13:55 +00:00
}
goto end ;
2008-11-03 21:54:03 +00:00
case SWITCH_MESSAGE_INDICATE_UNBRIDGE :
2009-04-16 22:13:55 +00:00
if ( switch_rtp_ready ( tech_pvt - > rtp_session ) ) {
2009-05-07 15:07:04 +00:00
const char * val ;
int ok = 0 ;
2009-04-23 13:15:03 +00:00
if ( switch_rtp_test_flag ( tech_pvt - > rtp_session , SWITCH_RTP_FLAG_PASS_RFC2833 ) ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " %s deactivate passthru 2833 mode. \n " ,
switch_channel_get_name ( channel ) ) ;
2009-04-23 13:15:03 +00:00
switch_rtp_clear_flag ( tech_pvt - > rtp_session , SWITCH_RTP_FLAG_PASS_RFC2833 ) ;
}
2009-05-07 15:07:04 +00:00
if ( ( val = switch_channel_get_variable ( channel , " rtp_autoflush_during_bridge " ) ) ) {
ok = switch_true ( val ) ;
} else {
ok = sofia_test_pflag ( tech_pvt - > profile , PFLAG_RTP_AUTOFLUSH_DURING_BRIDGE ) ;
}
2010-02-06 03:38:24 +00:00
2009-05-07 15:07:04 +00:00
if ( ok ) {
2009-05-07 15:07:48 +00:00
rtp_flush_read_buffer ( tech_pvt - > rtp_session , SWITCH_RTP_FLUSH_UNSTICK ) ;
2009-05-07 15:07:04 +00:00
} else {
rtp_flush_read_buffer ( tech_pvt - > rtp_session , SWITCH_RTP_FLUSH_ONCE ) ;
}
2010-02-06 03:38:24 +00:00
//sofia_glue_tech_untrack(tech_pvt->profile, session);
2009-04-16 22:13:55 +00:00
}
goto end ;
2008-11-25 17:53:35 +00:00
case SWITCH_MESSAGE_INDICATE_AUDIO_SYNC :
if ( switch_rtp_ready ( tech_pvt - > rtp_session ) ) {
2009-04-16 22:13:55 +00:00
rtp_flush_read_buffer ( tech_pvt - > rtp_session , SWITCH_RTP_FLUSH_ONCE ) ;
2008-11-25 17:53:35 +00:00
}
2008-11-03 21:54:03 +00:00
goto end ;
2010-06-18 16:52:39 -05:00
case SWITCH_MESSAGE_INDICATE_CLEAR_PROGRESS :
if ( ! switch_channel_test_flag ( channel , CF_ANSWERED ) ) {
sofia_clear_flag ( tech_pvt , TFLAG_EARLY_MEDIA ) ;
}
goto end ;
2008-11-03 21:54:03 +00:00
case SWITCH_MESSAGE_INDICATE_ANSWER :
case SWITCH_MESSAGE_INDICATE_PROGRESS :
{
2009-11-11 04:29:17 +00:00
const char * var ;
2009-11-11 02:10:41 +00:00
const char * presence_data = switch_channel_get_variable ( channel , " presence_data " ) ;
const char * presence_id = switch_channel_get_variable ( channel , " presence_id " ) ;
2010-01-21 00:12:24 +00:00
if ( ( var = switch_channel_get_variable ( channel , " sip_enable_soa " ) ) ) {
if ( switch_true ( var ) ) {
sofia_set_flag ( tech_pvt , TFLAG_ENABLE_SOA ) ;
} else {
sofia_clear_flag ( tech_pvt , TFLAG_ENABLE_SOA ) ;
}
}
2010-02-06 03:38:24 +00:00
2009-11-11 02:10:41 +00:00
if ( presence_id | | presence_data ) {
2009-11-11 15:11:55 +00:00
char * sql = switch_mprintf ( " update sip_dialogs set presence_id='%q',presence_data='%q' "
2010-02-06 03:38:24 +00:00
" where uuid='%s'; \n " , switch_str_nil ( presence_id ) , switch_str_nil ( presence_data ) ,
switch_core_session_get_uuid ( session ) ) ;
2009-11-11 15:11:55 +00:00
switch_assert ( sql ) ;
2010-01-09 00:34:17 +00:00
sofia_glue_execute_sql_now ( tech_pvt - > profile , & sql , SWITCH_TRUE ) ;
2009-11-11 02:10:41 +00:00
}
2008-11-03 21:54:03 +00:00
if ( ( var = switch_channel_get_variable ( 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-11-03 21:54:03 +00:00
}
2010-02-06 03:38:24 +00:00
2009-12-03 22:51:50 +00:00
if ( sofia_test_pflag ( tech_pvt - > profile , PFLAG_AUTOFIX_TIMING ) ) {
tech_pvt - > check_frames = 0 ;
tech_pvt - > last_ts = 0 ;
}
2008-11-03 21:54:03 +00:00
}
break ;
default :
break ;
2008-03-04 23:53:23 +00:00
}
2009-03-20 01:52:53 +00:00
2008-11-03 21:54:03 +00:00
/* ones that do need to lock sofia mutex */
switch_mutex_lock ( tech_pvt - > sofia_mutex ) ;
2008-11-05 00:20:30 +00:00
2009-03-20 01:52:53 +00:00
if ( switch_channel_down ( channel ) | | ! tech_pvt | | sofia_test_flag ( tech_pvt , TFLAG_BYE ) ) {
2008-11-05 00:20:30 +00:00
status = SWITCH_STATUS_FALSE ;
goto end_lock ;
}
2007-03-31 19:01:33 +00:00
switch ( msg - > message_id ) {
2008-02-07 00:04:14 +00:00
case SWITCH_MESSAGE_INDICATE_VIDEO_REFRESH_REQ :
{
2010-09-29 14:14:41 -05:00
const char * pl = " <media_control><vc_primitive><to_encoder><picture_fast_update/></to_encoder></vc_primitive></media_control> " ;
if ( ! zstr ( msg - > string_arg ) ) {
pl = msg - > string_arg ;
}
2008-05-27 04:54:52 +00:00
nua_info ( tech_pvt - > nh , SIPTAG_CONTENT_TYPE_STR ( " application/media_control+xml " ) , SIPTAG_PAYLOAD_STR ( pl ) , TAG_END ( ) ) ;
2008-02-07 00:04:14 +00:00
}
break ;
2008-11-03 21:54:03 +00:00
case SWITCH_MESSAGE_INDICATE_BROADCAST :
{
2008-05-27 04:54:52 +00:00
const char * ip = NULL , * port = NULL ;
ip = switch_channel_get_variable ( channel , SWITCH_REMOTE_MEDIA_IP_VARIABLE ) ;
port = switch_channel_get_variable ( channel , SWITCH_REMOTE_MEDIA_PORT_VARIABLE ) ;
if ( ip & & port ) {
sofia_glue_set_local_sdp ( tech_pvt , ip , atoi ( port ) , msg - > string_arg , 1 ) ;
}
2008-11-03 21:54:03 +00:00
2009-03-20 01:52:53 +00:00
if ( ! sofia_test_flag ( tech_pvt , TFLAG_BYE ) ) {
2009-12-19 17:43:05 +00:00
if ( sofia_use_soa ( tech_pvt ) ) {
nua_respond ( tech_pvt - > nh , SIP_200_OK ,
SIPTAG_CONTACT_STR ( tech_pvt - > reply_contact ) ,
SOATAG_USER_SDP_STR ( tech_pvt - > local_sdp_str ) ,
2010-02-06 03:38:24 +00:00
SOATAG_REUSE_REJECTED ( 1 ) , SOATAG_ORDERED_USER ( 1 ) , SOATAG_AUDIO_AUX ( " cn telephone-event " ) , NUTAG_INCLUDE_EXTRA_SDP ( 1 ) ,
2009-12-19 17:43:05 +00:00
TAG_END ( ) ) ;
} else {
nua_respond ( tech_pvt - > nh , SIP_200_OK ,
NUTAG_MEDIA_ENABLE ( 0 ) ,
SIPTAG_CONTACT_STR ( tech_pvt - > reply_contact ) ,
2010-02-06 03:38:24 +00:00
SIPTAG_CONTENT_TYPE_STR ( " application/sdp " ) , SIPTAG_PAYLOAD_STR ( tech_pvt - > local_sdp_str ) , TAG_END ( ) ) ;
2009-12-19 17:43:05 +00:00
}
2009-03-20 01:52:53 +00:00
switch_channel_mark_answered ( channel ) ;
}
2008-05-27 04:54:52 +00:00
}
2007-05-01 21:21:35 +00:00
break ;
2008-05-27 04:54:52 +00:00
case SWITCH_MESSAGE_INDICATE_NOMEDIA :
2007-09-19 18:24:47 +00:00
{
2007-11-01 11:28:26 +00:00
const char * uuid ;
2007-03-31 19:01:33 +00:00
switch_core_session_t * other_session ;
switch_channel_t * other_channel ;
2007-11-01 11:28:26 +00:00
const char * ip = NULL , * port = NULL ;
2008-05-27 04:54:52 +00:00
2008-02-21 17:48:41 +00:00
switch_channel_set_flag ( channel , CF_PROXY_MODE ) ;
2009-03-20 01:52:53 +00:00
sofia_glue_tech_set_local_sdp ( tech_pvt , NULL , SWITCH_FALSE ) ;
2007-03-31 19:01:33 +00:00
if ( ( uuid = switch_channel_get_variable ( channel , SWITCH_SIGNAL_BOND_VARIABLE ) )
& & ( other_session = switch_core_session_locate ( uuid ) ) ) {
other_channel = switch_core_session_get_channel ( other_session ) ;
ip = switch_channel_get_variable ( other_channel , SWITCH_REMOTE_MEDIA_IP_VARIABLE ) ;
port = switch_channel_get_variable ( other_channel , SWITCH_REMOTE_MEDIA_PORT_VARIABLE ) ;
switch_core_session_rwunlock ( other_session ) ;
if ( ip & & port ) {
sofia_glue_set_local_sdp ( tech_pvt , ip , atoi ( port ) , NULL , 1 ) ;
2006-09-18 16:32:47 +00:00
}
2006-09-08 03:28:49 +00:00
}
2008-11-03 21:54:03 +00:00
2007-03-31 19:01:33 +00:00
if ( ! tech_pvt - > local_sdp_str ) {
sofia_glue_tech_absorb_sdp ( tech_pvt ) ;
}
2010-02-06 03:38:24 +00:00
2007-03-31 19:01:33 +00:00
sofia_glue_do_invite ( session ) ;
2007-09-19 18:24:47 +00:00
}
2007-03-31 19:01:33 +00:00
break ;
2007-05-14 23:50:38 +00:00
2007-09-19 18:24:47 +00:00
case SWITCH_MESSAGE_INDICATE_MEDIA_REDIRECT :
{
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " %s Sending media re-direct: \n %s \n " ,
2008-12-30 19:50:33 +00:00
switch_channel_get_name ( channel ) , msg - > string_arg ) ;
2009-03-20 01:52:53 +00:00
sofia_glue_tech_set_local_sdp ( tech_pvt , msg - > string_arg , SWITCH_TRUE ) ;
2009-02-09 17:56:38 +00:00
sofia_set_flag_locked ( tech_pvt , TFLAG_SENT_UPDATE ) ;
2010-01-21 18:38:26 +00:00
switch_channel_set_flag ( channel , CF_REQ_MEDIA ) ;
2007-09-19 18:24:47 +00:00
sofia_glue_do_invite ( session ) ;
2007-05-14 23:50:38 +00:00
}
2007-09-19 18:24:47 +00:00
break ;
2010-05-12 21:25:54 -05:00
case SWITCH_MESSAGE_INDICATE_UDPTL_MODE :
{
switch_t38_options_t * t38_options = switch_channel_get_private ( tech_pvt - > channel , " t38_options " ) ;
2010-06-23 13:22:52 -05:00
2010-05-12 21:25:54 -05:00
if ( ! t38_options ) {
nua_respond ( tech_pvt - > nh , SIP_488_NOT_ACCEPTABLE , TAG_END ( ) ) ;
goto end_lock ;
}
2010-06-23 13:22:52 -05:00
2010-06-17 10:23:37 -05:00
start_udptl ( tech_pvt , t38_options ) ;
2008-12-30 19:50:33 +00:00
2010-05-12 21:25:54 -05:00
}
case SWITCH_MESSAGE_INDICATE_T38_DESCRIPTION :
2008-12-30 19:50:33 +00:00
{
2010-05-12 21:25:54 -05:00
switch_t38_options_t * t38_options = switch_channel_get_private ( tech_pvt - > channel , " t38_options " ) ;
2010-06-23 13:22:52 -05:00
2010-05-12 21:25:54 -05:00
if ( ! t38_options ) {
nua_respond ( tech_pvt - > nh , SIP_488_NOT_ACCEPTABLE , TAG_END ( ) ) ;
goto end_lock ;
}
2010-06-17 10:23:37 -05:00
start_udptl ( tech_pvt , t38_options ) ;
2010-05-12 21:25:54 -05:00
sofia_glue_set_image_sdp ( tech_pvt , t38_options , msg - > numeric_arg ) ;
2010-06-23 13:22:52 -05:00
2010-05-12 21:25:54 -05:00
if ( ! sofia_test_flag ( tech_pvt , TFLAG_BYE ) ) {
char * extra_headers = sofia_glue_get_extra_headers ( channel , SOFIA_SIP_RESPONSE_HEADER_PREFIX ) ;
if ( sofia_use_soa ( tech_pvt ) ) {
nua_respond ( tech_pvt - > nh , SIP_200_OK ,
NUTAG_AUTOANSWER ( 0 ) ,
SIPTAG_CONTACT_STR ( tech_pvt - > reply_contact ) ,
SIPTAG_CALL_INFO_STR ( switch_channel_get_variable ( tech_pvt - > channel , SOFIA_SIP_HEADER_PREFIX " call_info " ) ) ,
SOATAG_USER_SDP_STR ( tech_pvt - > local_sdp_str ) ,
SOATAG_REUSE_REJECTED ( 1 ) , SOATAG_ORDERED_USER ( 1 ) , SOATAG_AUDIO_AUX ( " cn telephone-event " ) , NUTAG_INCLUDE_EXTRA_SDP ( 1 ) ,
2010-06-23 13:22:52 -05:00
TAG_IF ( ! zstr ( extra_headers ) , SIPTAG_HEADER_STR ( extra_headers ) ) , TAG_END ( ) ) ;
2010-05-12 21:25:54 -05:00
} else {
nua_respond ( tech_pvt - > nh , SIP_200_OK ,
NUTAG_AUTOANSWER ( 0 ) ,
NUTAG_MEDIA_ENABLE ( 0 ) ,
SIPTAG_CONTACT_STR ( tech_pvt - > reply_contact ) ,
SIPTAG_CALL_INFO_STR ( switch_channel_get_variable ( tech_pvt - > channel , SOFIA_SIP_HEADER_PREFIX " call_info " ) ) ,
SIPTAG_CONTENT_TYPE_STR ( " application/sdp " ) ,
2010-06-23 13:22:52 -05:00
SIPTAG_PAYLOAD_STR ( tech_pvt - > local_sdp_str ) , TAG_IF ( ! zstr ( extra_headers ) , SIPTAG_HEADER_STR ( extra_headers ) ) , TAG_END ( ) ) ;
2010-05-12 21:25:54 -05:00
}
switch_safe_free ( extra_headers ) ;
sofia_set_flag_locked ( tech_pvt , TFLAG_ANS ) ;
2010-06-23 13:22:52 -05:00
}
2010-05-12 21:25:54 -05:00
}
break ;
2008-12-30 19:50:33 +00:00
2010-05-12 21:25:54 -05:00
case SWITCH_MESSAGE_INDICATE_REQUEST_IMAGE_MEDIA :
{
switch_t38_options_t * t38_options = switch_channel_get_private ( tech_pvt - > channel , " t38_options " ) ;
2010-02-06 03:38:24 +00:00
2010-05-12 21:25:54 -05:00
sofia_glue_set_image_sdp ( tech_pvt , t38_options , msg - > numeric_arg ) ;
2010-06-23 13:22:52 -05:00
2010-01-21 18:38:26 +00:00
switch_channel_set_flag ( channel , CF_REQ_MEDIA ) ;
2009-02-09 17:56:38 +00:00
sofia_set_flag_locked ( tech_pvt , TFLAG_SENT_UPDATE ) ;
2008-12-30 19:50:33 +00:00
sofia_glue_do_invite ( session ) ;
}
break ;
2007-09-19 18:24:47 +00:00
case SWITCH_MESSAGE_INDICATE_MEDIA :
{
2010-02-06 03:38:24 +00:00
uint32_t send_invite = 1 ;
2008-05-27 04:54:52 +00:00
2010-01-23 03:59:01 +00:00
switch_channel_clear_flag ( channel , CF_PROXY_MODE ) ;
2009-03-20 01:52:53 +00:00
sofia_glue_tech_set_local_sdp ( tech_pvt , NULL , SWITCH_FALSE ) ;
2008-03-04 00:52:54 +00:00
2010-02-06 03:38:24 +00:00
if ( ! ( switch_channel_test_flag ( channel , CF_ANSWERED ) | | switch_channel_test_flag ( channel , CF_EARLY_MEDIA ) ) ) {
if ( ! switch_channel_test_flag ( tech_pvt - > channel , CF_OUTBOUND ) ) {
const char * r_sdp = switch_channel_get_variable ( channel , SWITCH_R_SDP_VARIABLE ) ;
2010-01-23 03:59:01 +00:00
2010-02-06 03:38:24 +00:00
tech_pvt - > num_codecs = 0 ;
2008-03-04 00:52:54 +00:00
sofia_glue_tech_prepare_codecs ( tech_pvt ) ;
2010-02-06 03:38:24 +00:00
if ( sofia_glue_tech_media ( tech_pvt , r_sdp ) ! = SWITCH_STATUS_SUCCESS ) {
2008-03-04 00:52:54 +00:00
switch_channel_set_variable ( channel , SWITCH_ENDPOINT_DISPOSITION_VARIABLE , " CODEC NEGOTIATION ERROR " ) ;
2010-02-06 03:38:24 +00:00
status = SWITCH_STATUS_FALSE ;
goto end_lock ;
}
send_invite = 0 ;
}
}
if ( ! switch_rtp_ready ( tech_pvt - > rtp_session ) ) {
2007-04-17 06:08:39 +00:00
sofia_glue_tech_prepare_codecs ( tech_pvt ) ;
2010-02-06 03:38:24 +00:00
if ( ( status = sofia_glue_tech_choose_port ( tech_pvt , 0 ) ) ! = SWITCH_STATUS_SUCCESS ) {
2007-04-17 14:44:22 +00:00
switch_channel_hangup ( channel , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
2010-02-06 03:38:24 +00:00
goto end_lock ;
}
}
2007-03-31 19:01:33 +00:00
sofia_glue_set_local_sdp ( tech_pvt , NULL , 0 , NULL , 1 ) ;
2007-05-09 19:30:41 +00:00
2010-02-06 03:38:24 +00:00
if ( send_invite ) {
2008-03-25 00:24:23 +00:00
switch_channel_set_flag ( channel , CF_REQ_MEDIA ) ;
2008-03-04 00:52:54 +00:00
sofia_glue_do_invite ( session ) ;
2010-05-04 11:24:35 -05:00
} else {
status = SWITCH_STATUS_FALSE ;
2010-02-06 03:38:24 +00:00
}
}
break ;
2006-08-25 23:55:59 +00:00
2010-04-16 10:01:00 -05:00
case SWITCH_MESSAGE_INDICATE_PHONE_EVENT :
2010-04-16 09:35:41 -05:00
{
2010-04-16 10:01:00 -05:00
const char * event = " talk " ;
if ( ! zstr ( msg - > string_arg ) & & strcasecmp ( msg - > string_arg , event ) ) {
if ( ! strcasecmp ( msg - > string_arg , " hold " ) ) {
event = " hold " ;
} else {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING , " Invalid event. \n " ) ;
}
}
nua_notify ( tech_pvt - > nh , NUTAG_NEWSUB ( 1 ) , NUTAG_SUBSTATE ( nua_substate_active ) , SIPTAG_EVENT_STR ( event ) , TAG_END ( ) ) ;
2010-04-16 09:35:41 -05:00
}
break ;
2010-01-20 19:20:11 +00:00
case SWITCH_MESSAGE_INDICATE_SIMPLIFY :
2009-10-23 23:02:14 +00:00
{
2010-01-20 19:20:11 +00:00
char * ref_to , * ref_by ;
const char * uuid ;
2010-01-24 21:12:04 +00:00
const char * call_id = NULL , * to_user = NULL , * to_host = NULL , * to_tag = NULL , * from_tag = NULL , * from_user = NULL , * from_host = NULL ;
2010-02-06 03:38:24 +00:00
2010-01-20 19:20:11 +00:00
if ( ( uuid = switch_channel_get_variable ( channel , SWITCH_SIGNAL_BOND_VARIABLE ) ) ) {
switch_core_session_t * rsession ;
if ( ( rsession = switch_core_session_locate ( uuid ) ) ) {
switch_channel_t * rchannel = switch_core_session_get_channel ( rsession ) ;
call_id = switch_channel_get_variable ( rchannel , " sip_call_id " ) ;
to_user = switch_channel_get_variable ( rchannel , " sip_to_user " ) ;
if ( switch_channel_direction ( rchannel ) = = SWITCH_CALL_DIRECTION_OUTBOUND ) {
to_host = switch_channel_get_variable ( rchannel , " sip_to_host " ) ;
from_user = switch_channel_get_variable ( channel , " sip_from_user " ) ;
from_host = switch_channel_get_variable ( channel , " sip_from_host " ) ;
2010-08-17 09:41:21 -05:00
to_tag = switch_channel_get_variable ( rchannel , " sip_to_tag " ) ;
from_tag = switch_channel_get_variable ( rchannel , " sip_from_tag " ) ;
2010-01-20 19:20:11 +00:00
} else {
to_host = switch_channel_get_variable ( channel , " sip_to_host " ) ;
from_user = switch_channel_get_variable ( rchannel , " sip_from_user " ) ;
from_host = switch_channel_get_variable ( rchannel , " sip_from_host " ) ;
2010-08-17 09:41:21 -05:00
from_tag = switch_channel_get_variable ( rchannel , " sip_to_tag " ) ;
to_tag = switch_channel_get_variable ( rchannel , " sip_from_tag " ) ;
2009-10-23 23:02:14 +00:00
}
2010-01-20 19:20:11 +00:00
switch_core_session_rwunlock ( rsession ) ;
2009-10-23 23:02:14 +00:00
}
}
2010-02-06 03:38:24 +00:00
2010-01-20 19:20:11 +00:00
if ( to_user & & to_host & & from_user & & from_host & & call_id & & to_tag & & from_tag ) {
char in [ 512 ] = " " , out [ 1536 ] = " " ;
switch_snprintf ( in , sizeof ( in ) , " %s;to-tag=%s;from-tag=%s " , call_id , to_tag , from_tag ) ;
switch_url_encode ( in , out , sizeof ( out ) ) ;
2010-02-06 03:38:24 +00:00
ref_to = switch_mprintf ( " <sip:%s@%s?Replaces=%s> " , to_user , to_host , out ) ;
2010-01-20 19:20:11 +00:00
ref_by = switch_mprintf ( " <sip:%s@%s> " , from_user , from_host ) ;
nua_refer ( tech_pvt - > nh , SIPTAG_REFER_TO_STR ( ref_to ) , SIPTAG_REFERRED_BY_STR ( ref_by ) , TAG_END ( ) ) ;
switch_safe_free ( ref_to ) ;
switch_safe_free ( ref_by ) ;
}
2009-10-23 23:02:14 +00:00
}
break ;
2008-03-11 03:45:16 +00:00
case SWITCH_MESSAGE_INDICATE_DISPLAY :
{
2009-10-07 22:35:21 +00:00
const char * name = msg - > string_array_arg [ 0 ] , * number = msg - > string_array_arg [ 1 ] ;
char * arg = NULL ;
char * argv [ 2 ] = { 0 } ;
int argc ;
2010-02-06 03:38:24 +00:00
2009-10-23 16:03:42 +00:00
if ( zstr ( name ) & & ! zstr ( msg - > string_arg ) ) {
2009-10-07 22:35:21 +00:00
arg = strdup ( msg - > string_arg ) ;
switch_assert ( arg ) ;
argc = switch_separate_string ( arg , ' | ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ;
name = argv [ 0 ] ;
number = argv [ 1 ] ;
}
2010-02-06 03:38:24 +00:00
2009-10-23 16:03:42 +00:00
if ( ! zstr ( name ) ) {
2008-03-11 03:45:16 +00:00
char message [ 256 ] = " " ;
2009-05-28 22:46:17 +00:00
const char * ua = switch_channel_get_variable ( tech_pvt - > channel , " sip_user_agent " ) ;
2009-10-08 16:52:55 +00:00
switch_event_t * event ;
2009-05-28 22:46:17 +00:00
2009-10-23 16:03:42 +00:00
if ( zstr ( number ) ) {
2009-10-07 22:35:21 +00:00
number = tech_pvt - > caller_profile - > destination_number ;
}
2009-10-23 14:31:24 +00:00
if ( ! sofia_test_flag ( tech_pvt , TFLAG_UPDATING_DISPLAY ) ) {
2009-10-23 16:03:42 +00:00
if ( zstr ( tech_pvt - > last_sent_callee_id_name ) | | strcmp ( tech_pvt - > last_sent_callee_id_name , name ) | |
zstr ( tech_pvt - > last_sent_callee_id_number ) | | strcmp ( tech_pvt - > last_sent_callee_id_number , number ) ) {
2010-02-06 03:38:24 +00:00
2009-10-21 18:48:28 +00:00
if ( switch_stristr ( " update_display " , tech_pvt - > x_freeswitch_support_remote ) ) {
snprintf ( message , sizeof ( message ) , " X-FS-Display-Name: %s \n X-FS-Display-Number: %s \n " , name , number ) ;
nua_info ( tech_pvt - > nh , SIPTAG_CONTENT_TYPE_STR ( " message/update_display " ) ,
2009-10-23 16:03:42 +00:00
TAG_IF ( ! zstr_buf ( message ) , SIPTAG_HEADER_STR ( message ) ) ,
2010-02-06 03:38:24 +00:00
TAG_IF ( ! zstr ( tech_pvt - > user_via ) , SIPTAG_VIA_STR ( tech_pvt - > user_via ) ) , TAG_END ( ) ) ;
2009-10-21 18:48:28 +00:00
} else if ( ua & & switch_stristr ( " snom " , ua ) ) {
2009-10-14 19:26:10 +00:00
snprintf ( message , sizeof ( message ) , " From: \r \n To: \" %s \" %s \r \n " , name , number ) ;
nua_info ( tech_pvt - > nh , SIPTAG_CONTENT_TYPE_STR ( " message/sipfrag " ) ,
2010-02-06 03:38:24 +00:00
TAG_IF ( ! zstr ( tech_pvt - > user_via ) , SIPTAG_VIA_STR ( tech_pvt - > user_via ) ) , SIPTAG_PAYLOAD_STR ( message ) , TAG_END ( ) ) ;
2009-10-21 18:48:28 +00:00
} else if ( ( ua & & ( switch_stristr ( " polycom " , ua ) ) ) ) {
2009-10-14 19:26:10 +00:00
snprintf ( message , sizeof ( message ) , " P-Asserted-Identity: \" %s \" <%s> " , name , number ) ;
2009-12-24 05:44:23 +00:00
sofia_set_flag_locked ( tech_pvt , TFLAG_UPDATING_DISPLAY ) ;
nua_update ( tech_pvt - > nh ,
TAG_IF ( ! zstr_buf ( message ) , SIPTAG_HEADER_STR ( message ) ) ,
2010-02-06 03:38:24 +00:00
TAG_IF ( ! zstr ( tech_pvt - > user_via ) , SIPTAG_VIA_STR ( tech_pvt - > user_via ) ) , TAG_END ( ) ) ;
2009-12-24 05:44:23 +00:00
} else if ( ( ua & & ( switch_stristr ( " aastra " , ua ) ) ) ) {
snprintf ( message , sizeof ( message ) , " P-Asserted-Identity: \" %s \" <sip:%s@%s> " , name , number , tech_pvt - > profile - > sipip ) ;
2010-02-06 03:38:24 +00:00
2009-10-21 18:48:28 +00:00
sofia_set_flag_locked ( tech_pvt , TFLAG_UPDATING_DISPLAY ) ;
2009-10-14 19:26:10 +00:00
nua_update ( tech_pvt - > nh ,
2009-10-23 16:03:42 +00:00
TAG_IF ( ! zstr_buf ( message ) , SIPTAG_HEADER_STR ( message ) ) ,
2010-02-06 03:38:24 +00:00
TAG_IF ( ! zstr ( tech_pvt - > user_via ) , SIPTAG_VIA_STR ( tech_pvt - > user_via ) ) , TAG_END ( ) ) ;
2010-10-01 10:33:00 -05:00
} else if ( ( ua & & ( switch_stristr ( " cisco/spa50 " , ua ) | | switch_stristr ( " cisco/spa525 " , ua ) ) ) ) {
2010-09-08 09:44:40 -05:00
snprintf ( message , sizeof ( message ) , " P-Asserted-Identity: \" %s \" <sip:%s@%s> " , name , number , tech_pvt - > profile - > sipip ) ;
sofia_set_flag_locked ( tech_pvt , TFLAG_UPDATING_DISPLAY ) ;
nua_update ( tech_pvt - > nh ,
TAG_IF ( ! zstr_buf ( message ) , SIPTAG_HEADER_STR ( message ) ) ,
TAG_IF ( ! zstr ( tech_pvt - > user_via ) , SIPTAG_VIA_STR ( tech_pvt - > user_via ) ) , TAG_END ( ) ) ;
}
2009-10-08 16:52:55 +00:00
2009-10-14 19:26:10 +00:00
tech_pvt - > last_sent_callee_id_name = switch_core_session_strdup ( tech_pvt - > session , name ) ;
tech_pvt - > last_sent_callee_id_number = switch_core_session_strdup ( tech_pvt - > session , number ) ;
2010-02-06 03:38:24 +00:00
2009-10-14 19:26:10 +00:00
if ( switch_event_create ( & event , SWITCH_EVENT_CALL_UPDATE ) = = SWITCH_STATUS_SUCCESS ) {
const char * uuid = switch_channel_get_variable ( channel , SWITCH_SIGNAL_BOND_VARIABLE ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Direction " , " SEND " ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Callee-Name " , name ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Callee-Number " , number ) ;
if ( uuid ) {
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Bridged-To " , uuid ) ;
}
switch_channel_event_set_data ( channel , event ) ;
switch_event_fire ( & event ) ;
2009-10-13 21:52:47 +00:00
}
2009-10-14 19:26:10 +00:00
} else {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Not sending same id again \" %s \" <%s> \n " , name , number ) ;
2009-10-08 16:52:55 +00:00
}
}
2008-03-11 03:45:16 +00:00
}
2009-10-07 22:35:21 +00:00
switch_safe_free ( arg ) ;
2008-03-11 03:45:16 +00:00
}
break ;
2007-09-19 18:24:47 +00:00
case SWITCH_MESSAGE_INDICATE_HOLD :
{
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 ( channel , CF_LEG_HOLDING ) ;
2007-03-31 19:01:33 +00:00
sofia_glue_do_invite ( session ) ;
2009-10-23 16:03:42 +00:00
if ( ! zstr ( msg - > string_arg ) ) {
2008-03-11 03:45:16 +00:00
char message [ 256 ] = " " ;
2009-06-01 13:45:50 +00:00
const char * ua = switch_channel_get_variable ( tech_pvt - > channel , " sip_user_agent " ) ;
if ( ua & & switch_stristr ( " snom " , ua ) ) {
snprintf ( message , sizeof ( message ) , " From: \r \n To: \" %s \" %s \r \n " , msg - > string_arg , tech_pvt - > caller_profile - > destination_number ) ;
2009-10-07 22:35:21 +00:00
nua_info ( tech_pvt - > nh , SIPTAG_CONTENT_TYPE_STR ( " message/sipfrag " ) ,
2010-02-06 03:38:24 +00:00
TAG_IF ( ! zstr ( tech_pvt - > user_via ) , SIPTAG_VIA_STR ( tech_pvt - > user_via ) ) , SIPTAG_PAYLOAD_STR ( message ) , TAG_END ( ) ) ;
2009-06-01 13:45:50 +00:00
} else if ( ua & & switch_stristr ( " polycom " , ua ) ) {
snprintf ( message , sizeof ( message ) , " P-Asserted-Identity: \" %s \" <%s> " , msg - > string_arg , tech_pvt - > caller_profile - > destination_number ) ;
nua_update ( tech_pvt - > nh ,
2009-10-23 16:03:42 +00:00
TAG_IF ( ! zstr_buf ( message ) , SIPTAG_HEADER_STR ( message ) ) ,
2010-02-06 03:38:24 +00:00
TAG_IF ( ! zstr ( tech_pvt - > user_via ) , SIPTAG_VIA_STR ( tech_pvt - > user_via ) ) , TAG_END ( ) ) ;
2009-06-01 13:45:50 +00:00
}
2008-03-11 03:45:16 +00:00
}
2007-03-31 19:01:33 +00:00
}
break ;
2008-05-27 04:54:52 +00:00
2007-09-19 18:24:47 +00:00
case SWITCH_MESSAGE_INDICATE_UNHOLD :
{
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 ( channel , CF_LEG_HOLDING ) ;
2007-03-31 19:01:33 +00:00
sofia_glue_do_invite ( session ) ;
}
break ;
case SWITCH_MESSAGE_INDICATE_REDIRECT :
2009-10-23 16:03:42 +00:00
if ( ! zstr ( msg - > string_arg ) ) {
2009-03-20 01:52:53 +00:00
if ( ! switch_channel_test_flag ( channel , CF_ANSWERED ) & & ! sofia_test_flag ( tech_pvt , TFLAG_BYE ) ) {
2009-11-09 17:07:21 +00:00
char * extra_headers = sofia_glue_get_extra_headers ( channel , SOFIA_SIP_RESPONSE_HEADER_PREFIX ) ;
2009-09-30 21:06:01 +00:00
char * dest = ( char * ) msg - > string_arg ;
2010-05-19 16:24:52 -05:00
char * argv [ 128 ] = { 0 } ;
char * mydata = NULL , * newdest = NULL ;
int argc = 0 , i ;
switch_size_t len = 0 ;
if ( strchr ( dest , ' , ' ) ) {
mydata = switch_core_session_strdup ( session , dest ) ;
len = strlen ( mydata ) * 2 ;
newdest = switch_core_session_alloc ( session , len ) ;
2010-06-23 13:22:52 -05:00
2010-05-19 16:24:52 -05:00
argc = switch_split ( mydata , ' , ' , argv ) ;
2010-06-23 13:22:52 -05:00
for ( i = 0 ; i < argc ; i + + ) {
2010-05-19 16:24:52 -05:00
if ( ! strchr ( argv [ i ] , ' < ' ) & & ! strchr ( argv [ i ] , ' > ' ) ) {
if ( i = = argc - 1 ) {
switch_snprintf ( newdest + strlen ( newdest ) , len - strlen ( newdest ) , " \" unknown \" <%s> " , argv [ i ] ) ;
} else {
switch_snprintf ( newdest + strlen ( newdest ) , len - strlen ( newdest ) , " \" unknown \" <%s>, " , argv [ i ] ) ;
}
} else {
if ( i = = argc - 1 ) {
switch_snprintf ( newdest + strlen ( newdest ) , len - strlen ( newdest ) , " %s " , argv [ i ] ) ;
} else {
switch_snprintf ( newdest + strlen ( newdest ) , len - strlen ( newdest ) , " %s, " , argv [ i ] ) ;
}
}
}
2010-06-23 13:22:52 -05:00
2010-05-19 16:24:52 -05:00
dest = newdest ;
} else {
2009-09-30 21:06:01 +00:00
2010-05-19 16:24:52 -05:00
if ( ! strchr ( dest , ' < ' ) & & ! strchr ( dest , ' > ' ) ) {
dest = switch_core_session_sprintf ( session , " \" unknown \" <%s> " , dest ) ;
}
2009-09-30 21:06:01 +00:00
}
2010-06-23 13:22:52 -05:00
2009-09-30 21:06:01 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Redirecting to %s \n " , dest ) ;
2010-05-19 16:24:52 -05:00
if ( argc > 1 ) {
nua_respond ( tech_pvt - > nh , SIP_300_MULTIPLE_CHOICES , SIPTAG_CONTACT_STR ( dest ) ,
TAG_IF ( ! zstr ( extra_headers ) , SIPTAG_HEADER_STR ( extra_headers ) ) , TAG_END ( ) ) ;
} else {
nua_respond ( tech_pvt - > nh , SIP_302_MOVED_TEMPORARILY , SIPTAG_CONTACT_STR ( dest ) ,
TAG_IF ( ! zstr ( extra_headers ) , SIPTAG_HEADER_STR ( extra_headers ) ) , TAG_END ( ) ) ;
}
2009-02-09 17:56:38 +00:00
sofia_set_flag_locked ( tech_pvt , TFLAG_BYE ) ;
2009-11-09 17:05:13 +00:00
switch_safe_free ( extra_headers ) ;
2008-10-15 22:16:18 +00:00
} else {
2010-05-19 16:24:52 -05:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING , " Too late for redirecting, already answered \n " ) ;
2010-06-23 13:22:52 -05:00
2008-10-15 22:16:18 +00:00
}
2007-03-29 22:31:56 +00:00
}
2006-08-25 23:55:59 +00:00
break ;
2008-01-03 23:42:15 +00:00
case SWITCH_MESSAGE_INDICATE_DEFLECT :
{
2009-11-09 17:05:13 +00:00
char ref_to [ 1024 ] = " " ;
2008-11-20 02:07:59 +00:00
const char * var ;
2008-01-03 23:42:15 +00:00
if ( ! strstr ( msg - > string_arg , " sip: " ) ) {
2008-07-03 18:50:15 +00:00
const char * format = strchr ( tech_pvt - > profile - > sipip , ' : ' ) ? " sip:%s@[%s] " : " sip:%s@%s " ;
switch_snprintf ( ref_to , sizeof ( ref_to ) , format , msg - > string_arg , tech_pvt - > profile - > sipip ) ;
2008-01-03 23:42:15 +00:00
} else {
switch_set_string ( ref_to , msg - > string_arg ) ;
}
nua_refer ( tech_pvt - > nh , SIPTAG_REFER_TO_STR ( ref_to ) , SIPTAG_REFERRED_BY_STR ( tech_pvt - > contact_url ) , TAG_END ( ) ) ;
2008-11-20 02:07:59 +00:00
switch_mutex_unlock ( tech_pvt - > sofia_mutex ) ;
sofia_wait_for_reply ( tech_pvt , 9999 , 300 ) ;
switch_mutex_lock ( tech_pvt - > sofia_mutex ) ;
if ( ( var = switch_channel_get_variable ( tech_pvt - > channel , " sip_refer_reply " ) ) ) {
2010-02-06 03:38:24 +00:00
msg - > string_reply = switch_core_session_strdup ( session , var ) ;
2008-11-20 02:07:59 +00:00
} else {
msg - > string_reply = " no reply " ;
}
2008-01-03 23:42:15 +00:00
}
break ;
2008-01-03 00:50:53 +00:00
case SWITCH_MESSAGE_INDICATE_RESPOND :
if ( msg - > numeric_arg | | msg - > string_arg ) {
int code = msg - > numeric_arg ;
const char * reason = NULL ;
2010-02-06 03:38:24 +00:00
2008-01-03 00:50:53 +00:00
if ( code ) {
reason = msg - > string_arg ;
} else {
2009-10-23 16:03:42 +00:00
if ( ! zstr ( msg - > string_arg ) ) {
2008-01-26 03:56:40 +00:00
if ( ( code = atoi ( msg - > string_arg ) ) ) {
if ( ( reason = strchr ( msg - > string_arg , ' ' ) ) ) {
reason + + ;
}
2008-01-03 00:50:53 +00:00
}
2007-06-08 22:28:32 +00:00
}
2008-01-03 00:50:53 +00:00
}
2007-06-08 22:28:32 +00:00
2008-01-07 18:02:01 +00:00
if ( ! code ) {
2008-01-03 00:50:53 +00:00
code = 488 ;
}
2008-05-27 04:54:52 +00:00
2009-03-20 01:52:53 +00:00
if ( ! switch_channel_test_flag ( channel , CF_ANSWERED ) & & code > = 300 ) {
if ( sofia_test_flag ( tech_pvt , TFLAG_BYE ) ) {
goto end_lock ;
}
}
2010-02-06 03:38:24 +00:00
2009-10-23 16:03:42 +00:00
if ( zstr ( reason ) & & code ! = 407 & & code ! = 302 ) {
2008-04-09 16:27:01 +00:00
reason = sip_status_phrase ( code ) ;
2009-10-23 16:03:42 +00:00
if ( zstr ( reason ) ) {
2008-04-09 16:27:01 +00:00
reason = " Because " ;
2008-01-26 03:56:40 +00:00
}
}
2008-05-27 04:54:52 +00:00
2008-01-26 03:56:40 +00:00
if ( code = = 407 & & ! msg - > numeric_arg ) {
2008-01-03 00:50:53 +00:00
const char * to_uri = switch_channel_get_variable ( channel , " sip_to_uri " ) ;
const char * to_host = reason ;
2008-05-20 16:41:57 +00:00
2009-10-23 16:03:42 +00:00
if ( zstr ( to_host ) ) {
2008-01-03 00:50:53 +00:00
to_host = switch_channel_get_variable ( channel , " sip_to_host " ) ;
2007-06-08 22:28:32 +00:00
}
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Challenging call %s \n " , to_uri ) ;
2008-09-02 03:46:27 +00:00
sofia_reg_auth_challenge ( NULL , tech_pvt - > profile , tech_pvt - > nh , REG_INVITE , to_host , 0 ) ;
2008-01-03 00:50:53 +00:00
switch_channel_hangup ( channel , SWITCH_CAUSE_USER_CHALLENGE ) ;
2008-01-26 03:56:40 +00:00
} else if ( code = = 484 & & msg - > numeric_arg ) {
2008-01-24 20:49:53 +00:00
const char * to = switch_channel_get_variable ( channel , " sip_to_uri " ) ;
const char * max_forwards = switch_channel_get_variable ( channel , SWITCH_MAX_FORWARDS_VARIABLE ) ;
2010-06-29 09:32:41 -05:00
char * cid = generate_pai_str ( session ) ;
2008-01-24 20:49:53 +00:00
char * to_uri = NULL ;
2008-05-27 04:54:52 +00:00
2008-01-24 20:49:53 +00:00
if ( to ) {
char * p ;
to_uri = switch_core_session_sprintf ( session , " sip:%s " , to ) ;
if ( ( p = strstr ( to_uri , " :5060 " ) ) ) {
* p = ' \0 ' ;
}
}
2009-03-20 01:52:53 +00:00
if ( ! switch_channel_test_flag ( channel , CF_ANSWERED ) & & ! sofia_test_flag ( tech_pvt , TFLAG_BYE ) ) {
2009-11-09 17:05:13 +00:00
char * extra_headers = sofia_glue_get_extra_headers ( channel , SOFIA_SIP_RESPONSE_HEADER_PREFIX ) ;
2009-11-09 17:15:46 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Overlap Dial with %d %s \n " , code , reason ) ;
2009-11-09 17:05:13 +00:00
2009-03-24 17:57:00 +00:00
nua_respond ( tech_pvt - > nh , code , su_strdup ( nua_handle_home ( tech_pvt - > nh ) , reason ) , TAG_IF ( to_uri , SIPTAG_CONTACT_STR ( to_uri ) ) ,
2009-03-20 01:52:53 +00:00
SIPTAG_SUPPORTED_STR ( NULL ) , SIPTAG_ACCEPT_STR ( NULL ) ,
2010-06-29 09:32:41 -05:00
TAG_IF ( cid , SIPTAG_HEADER_STR ( cid ) ) ,
2009-10-23 16:03:42 +00:00
TAG_IF ( ! zstr ( extra_headers ) , SIPTAG_HEADER_STR ( extra_headers ) ) ,
TAG_IF ( ! zstr ( max_forwards ) , SIPTAG_MAX_FORWARDS_STR ( max_forwards ) ) , TAG_END ( ) ) ;
2010-02-06 03:38:24 +00:00
2009-02-09 17:56:38 +00:00
sofia_set_flag_locked ( tech_pvt , TFLAG_BYE ) ;
2009-11-09 17:05:13 +00:00
switch_safe_free ( extra_headers ) ;
2008-04-09 16:27:01 +00:00
}
2009-10-23 16:03:42 +00:00
} else if ( code = = 302 & & ! zstr ( msg - > string_arg ) ) {
2009-06-15 16:01:45 +00:00
char * p ;
if ( ( p = strchr ( msg - > string_arg , ' ' ) ) ) {
* p = ' \0 ' ;
msg - > string_arg = p ;
}
2010-02-06 03:38:24 +00:00
2008-10-15 22:16:18 +00:00
msg - > message_id = SWITCH_MESSAGE_INDICATE_REDIRECT ;
switch_core_session_receive_message ( session , msg ) ;
2008-11-05 00:20:30 +00:00
goto end_lock ;
2009-04-22 18:38:55 +00:00
} else {
2009-03-20 01:52:53 +00:00
if ( ! sofia_test_flag ( tech_pvt , TFLAG_BYE ) ) {
2009-11-09 17:05:13 +00:00
char * extra_headers = sofia_glue_get_extra_headers ( channel , SOFIA_SIP_PROGRESS_HEADER_PREFIX ) ;
2010-05-26 20:12:54 -05:00
char * sdp = ( char * ) msg - > pointer_arg ;
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Responding with %d [%s] \n " , code , reason ) ;
2010-05-26 20:12:54 -05:00
if ( ! zstr ( ( sdp ) ) ) {
if ( ! strcasecmp ( sdp , " t38 " ) ) {
switch_t38_options_t * t38_options = switch_channel_get_private ( tech_pvt - > channel , " t38_options " ) ;
if ( t38_options ) {
sofia_glue_set_image_sdp ( tech_pvt , t38_options , 0 ) ;
2010-09-27 12:44:36 -05:00
if ( switch_rtp_ready ( tech_pvt - > rtp_session ) ) {
switch_rtp_udptl_mode ( tech_pvt - > rtp_session ) ;
}
2010-05-26 20:12:54 -05:00
}
} else {
sofia_glue_tech_set_local_sdp ( tech_pvt , sdp , SWITCH_TRUE ) ;
}
2010-02-06 03:38:24 +00:00
2009-03-20 01:52:53 +00:00
if ( switch_channel_test_flag ( channel , CF_PROXY_MEDIA ) ) {
sofia_glue_tech_patch_sdp ( tech_pvt ) ;
sofia_glue_tech_proxy_remote_addr ( tech_pvt ) ;
}
2009-12-19 17:43:05 +00:00
if ( sofia_use_soa ( tech_pvt ) ) {
nua_respond ( tech_pvt - > nh , code , su_strdup ( nua_handle_home ( tech_pvt - > nh ) , reason ) , SIPTAG_CONTACT_STR ( tech_pvt - > reply_contact ) ,
SOATAG_USER_SDP_STR ( tech_pvt - > local_sdp_str ) ,
SOATAG_REUSE_REJECTED ( 1 ) ,
2010-02-06 03:38:24 +00:00
SOATAG_ORDERED_USER ( 1 ) , SOATAG_AUDIO_AUX ( " cn telephone-event " ) , NUTAG_INCLUDE_EXTRA_SDP ( 1 ) ,
TAG_IF ( ! zstr ( extra_headers ) , SIPTAG_HEADER_STR ( extra_headers ) ) , TAG_END ( ) ) ;
2009-12-19 17:43:05 +00:00
} else {
nua_respond ( tech_pvt - > nh , code , su_strdup ( nua_handle_home ( tech_pvt - > nh ) , reason ) , SIPTAG_CONTACT_STR ( tech_pvt - > reply_contact ) ,
NUTAG_MEDIA_ENABLE ( 0 ) ,
SIPTAG_CONTENT_TYPE_STR ( " application/sdp " ) ,
2010-02-06 03:38:24 +00:00
SIPTAG_PAYLOAD_STR ( tech_pvt - > local_sdp_str ) ,
TAG_IF ( ! zstr ( extra_headers ) , SIPTAG_HEADER_STR ( extra_headers ) ) , TAG_END ( ) ) ;
2009-12-19 17:43:05 +00:00
}
2009-03-20 01:52:53 +00:00
} else {
2010-02-06 03:38:24 +00:00
nua_respond ( tech_pvt - > nh , code , su_strdup ( nua_handle_home ( tech_pvt - > nh ) , reason ) , SIPTAG_CONTACT_STR ( tech_pvt - > reply_contact ) ,
TAG_IF ( ! zstr ( extra_headers ) , SIPTAG_HEADER_STR ( extra_headers ) ) , TAG_END ( ) ) ;
2008-02-22 14:06:13 +00:00
}
2009-11-09 17:05:13 +00:00
switch_safe_free ( extra_headers ) ;
2008-04-09 16:27:01 +00:00
}
2007-04-21 15:04:01 +00:00
}
2008-05-27 04:54:52 +00:00
2007-04-21 15:04:01 +00:00
}
break ;
2007-03-31 19:01:33 +00:00
case SWITCH_MESSAGE_INDICATE_RINGING :
2010-06-15 15:48:12 -05:00
{
switch_ring_ready_t ring_ready_val = msg - > numeric_arg ;
2009-10-26 17:03:05 +00:00
2010-06-15 15:48:12 -05:00
if ( sofia_test_pflag ( tech_pvt - > profile , PFLAG_3PCC_PROXY ) & & sofia_test_flag ( tech_pvt , TFLAG_3PCC ) ) {
switch_channel_mark_ring_ready ( channel ) ;
status = SWITCH_STATUS_SUCCESS ;
switch_log_printf ( SWITCH_CHANNEL_ID_LOG , msg - > _file , msg - > _func , msg - > _line , NULL , SWITCH_LOG_INFO ,
" Pretending to send ringing. Not available for 3pcc calls \n " ) ;
goto end_lock ;
}
2009-10-26 17:03:05 +00:00
2010-06-15 15:48:12 -05:00
if ( ! switch_channel_test_flag ( channel , CF_RING_READY ) & & ! sofia_test_flag ( tech_pvt , TFLAG_BYE ) & &
! switch_channel_test_flag ( channel , CF_EARLY_MEDIA ) & & ! switch_channel_test_flag ( channel , CF_ANSWERED ) ) {
char * extra_header = sofia_glue_get_extra_headers ( channel , SOFIA_SIP_PROGRESS_HEADER_PREFIX ) ;
const char * call_info = switch_channel_get_variable ( channel , " presence_call_info_full " ) ;
2010-06-29 09:32:41 -05:00
char * cid = generate_pai_str ( session ) ;
2010-06-23 13:22:52 -05:00
2010-06-15 15:48:12 -05:00
switch ( ring_ready_val ) {
case SWITCH_RING_READY_QUEUED :
nua_respond ( tech_pvt - > nh , SIP_182_QUEUED ,
SIPTAG_CONTACT_STR ( tech_pvt - > reply_contact ) ,
2010-06-29 09:32:41 -05:00
TAG_IF ( cid , SIPTAG_HEADER_STR ( cid ) ) ,
2010-06-15 15:48:12 -05:00
TAG_IF ( call_info , SIPTAG_CALL_INFO_STR ( call_info ) ) ,
TAG_IF ( ! zstr ( extra_header ) , SIPTAG_HEADER_STR ( extra_header ) ) ,
TAG_IF ( switch_stristr ( " update_display " , tech_pvt - > x_freeswitch_support_remote ) ,
SIPTAG_HEADER_STR ( " X-FS-Support: " FREESWITCH_SUPPORT ) ) , TAG_END ( ) ) ;
break ;
case SWITCH_RING_READY_RINGING :
default :
nua_respond ( tech_pvt - > nh , SIP_180_RINGING ,
SIPTAG_CONTACT_STR ( tech_pvt - > reply_contact ) ,
2010-06-29 09:32:41 -05:00
TAG_IF ( cid , SIPTAG_HEADER_STR ( cid ) ) ,
2010-06-15 15:48:12 -05:00
TAG_IF ( call_info , SIPTAG_CALL_INFO_STR ( call_info ) ) ,
TAG_IF ( ! zstr ( extra_header ) , SIPTAG_HEADER_STR ( extra_header ) ) ,
TAG_IF ( switch_stristr ( " update_display " , tech_pvt - > x_freeswitch_support_remote ) ,
SIPTAG_HEADER_STR ( " X-FS-Support: " FREESWITCH_SUPPORT ) ) , TAG_END ( ) ) ;
break ;
}
switch_safe_free ( extra_header ) ;
switch_channel_mark_ring_ready ( channel ) ;
}
2008-01-05 16:20:39 +00:00
}
2007-04-16 16:53:30 +00:00
break ;
case SWITCH_MESSAGE_INDICATE_ANSWER :
2008-02-25 16:35:19 +00:00
status = sofia_answer_channel ( session ) ;
2010-09-29 14:14:41 -05:00
if ( switch_channel_test_flag ( tech_pvt - > channel , CF_VIDEO ) ) {
sofia_glue_build_vid_refresh_message ( session , NULL ) ;
}
2006-08-25 23:55:59 +00:00
break ;
2008-02-15 19:48:16 +00:00
case SWITCH_MESSAGE_INDICATE_PROGRESS :
{
2008-05-13 23:22:21 +00:00
char * sticky = NULL ;
const char * val = NULL ;
2010-01-28 20:35:17 +00:00
const char * call_info = switch_channel_get_variable ( channel , " presence_call_info_full " ) ;
2008-05-13 23:22:21 +00:00
2009-10-26 17:03:05 +00:00
if ( sofia_test_pflag ( tech_pvt - > profile , PFLAG_3PCC_PROXY ) & & sofia_test_flag ( tech_pvt , TFLAG_3PCC ) ) {
sofia_set_flag_locked ( tech_pvt , TFLAG_EARLY_MEDIA ) ;
switch_channel_mark_pre_answered ( channel ) ;
status = SWITCH_STATUS_SUCCESS ;
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_ID_LOG , msg - > _file , msg - > _func , msg - > _line , NULL , SWITCH_LOG_INFO ,
2009-10-26 17:03:05 +00:00
" Pretending to send early media. Not available for 3pcc calls \n " ) ;
goto end_lock ;
}
2009-02-09 17:56:38 +00:00
if ( ! sofia_test_flag ( tech_pvt , TFLAG_ANS ) & & ! sofia_test_flag ( tech_pvt , TFLAG_EARLY_MEDIA ) ) {
2008-05-27 04:54:52 +00:00
2009-02-09 17:56:38 +00:00
sofia_set_flag_locked ( tech_pvt , TFLAG_EARLY_MEDIA ) ;
2009-05-13 16:34:39 +00:00
switch_log_printf ( SWITCH_CHANNEL_ID_LOG , msg - > _file , msg - > _func , msg - > _line , NULL , SWITCH_LOG_INFO , " Sending early media \n " ) ;
2008-05-27 04:54:52 +00:00
2007-03-31 19:01:33 +00:00
/* Transmit 183 Progress with SDP */
2008-02-21 17:48:41 +00:00
if ( switch_channel_test_flag ( channel , CF_PROXY_MODE ) | | switch_channel_test_flag ( channel , CF_PROXY_MEDIA ) ) {
2007-11-01 11:28:26 +00:00
const char * sdp = NULL ;
2007-03-31 19:01:33 +00:00
if ( ( sdp = switch_channel_get_variable ( channel , SWITCH_B_SDP_VARIABLE ) ) ) {
2009-03-20 01:52:53 +00:00
sofia_glue_tech_set_local_sdp ( tech_pvt , sdp , SWITCH_TRUE ) ;
2006-08-25 23:55:59 +00:00
}
2008-02-21 17:48:41 +00:00
if ( switch_channel_test_flag ( channel , CF_PROXY_MEDIA ) ) {
2010-02-06 03:38:24 +00:00
2008-02-21 17:48:41 +00:00
sofia_glue_tech_patch_sdp ( tech_pvt ) ;
2010-02-06 03:38:24 +00:00
2008-02-21 17:48:41 +00:00
if ( sofia_glue_activate_rtp ( tech_pvt , 0 ) ! = SWITCH_STATUS_SUCCESS ) {
2008-02-25 16:35:19 +00:00
status = SWITCH_STATUS_FALSE ;
2008-11-05 00:20:30 +00:00
goto end_lock ;
2008-02-21 17:48:41 +00:00
}
}
2007-01-15 19:00:47 +00:00
} else {
2009-02-09 17:56:38 +00:00
if ( sofia_test_flag ( tech_pvt , TFLAG_LATE_NEGOTIATION ) | | ! tech_pvt - > iananame ) {
sofia_clear_flag_locked ( tech_pvt , TFLAG_LATE_NEGOTIATION ) ;
2007-11-03 00:46:23 +00:00
if ( ! switch_channel_test_flag ( tech_pvt - > channel , CF_OUTBOUND ) ) {
const char * r_sdp = switch_channel_get_variable ( channel , SWITCH_R_SDP_VARIABLE ) ;
2008-02-20 03:57:01 +00:00
2007-11-03 00:46:23 +00:00
tech_pvt - > num_codecs = 0 ;
sofia_glue_tech_prepare_codecs ( tech_pvt ) ;
2009-10-23 16:47:52 +00:00
if ( zstr ( r_sdp ) | | sofia_glue_tech_media ( tech_pvt , r_sdp ) ! = SWITCH_STATUS_SUCCESS ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR ,
" CODEC NEGOTIATION ERROR. SDP: \n %s \n " , r_sdp ? r_sdp : " NO SDP! " ) ;
2007-11-03 00:46:23 +00:00
switch_channel_set_variable ( channel , SWITCH_ENDPOINT_DISPOSITION_VARIABLE , " CODEC NEGOTIATION ERROR " ) ;
2008-02-20 03:57:01 +00:00
//nua_respond(tech_pvt->nh, SIP_488_NOT_ACCEPTABLE, TAG_END());
2008-02-25 16:35:19 +00:00
status = SWITCH_STATUS_FALSE ;
2008-11-05 00:20:30 +00:00
goto end_lock ;
2007-11-03 00:46:23 +00:00
}
}
2007-03-31 19:01:33 +00:00
}
2006-10-19 07:13:34 +00:00
2008-02-21 17:48:41 +00:00
if ( ( status = sofia_glue_tech_choose_port ( tech_pvt , 0 ) ) ! = SWITCH_STATUS_SUCCESS ) {
2007-04-17 14:44:22 +00:00
switch_channel_hangup ( channel , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
2008-11-05 00:20:30 +00:00
goto end_lock ;
2007-03-31 19:01:33 +00:00
}
sofia_glue_set_local_sdp ( tech_pvt , NULL , 0 , NULL , 0 ) ;
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
switch_channel_hangup ( channel , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
}
2007-03-31 19:01:33 +00:00
if ( tech_pvt - > local_sdp_str ) {
2010-03-16 03:49:18 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Ring SDP: \n %s \n " , tech_pvt - > local_sdp_str ) ;
2007-03-31 19:01:33 +00:00
}
}
2007-04-16 16:53:30 +00:00
switch_channel_mark_pre_answered ( channel ) ;
2008-05-13 23:22:21 +00:00
2009-02-09 17:56:38 +00:00
if ( sofia_test_flag ( tech_pvt , TFLAG_NAT ) | |
2008-05-27 04:54:52 +00:00
( val = switch_channel_get_variable ( channel , " sip-force-contact " ) ) | |
2008-05-13 23:22:21 +00:00
( ( val = switch_channel_get_variable ( channel , " sip_sticky_contact " ) ) & & switch_true ( val ) ) ) {
sticky = tech_pvt - > record_route ;
2008-05-14 14:13:40 +00:00
switch_channel_set_variable ( channel , " sip_nat_detected " , " true " ) ;
2008-05-13 23:22:21 +00:00
}
2009-03-20 01:52:53 +00:00
if ( ! sofia_test_flag ( tech_pvt , TFLAG_BYE ) ) {
2009-09-28 17:16:31 +00:00
char * extra_header = sofia_glue_get_extra_headers ( channel , SOFIA_SIP_PROGRESS_HEADER_PREFIX ) ;
2010-09-08 10:41:50 -05:00
char * cid = NULL ;
if ( sofia_test_pflag ( tech_pvt - > profile , PFLAG_PASS_CALLEE_ID ) ) {
cid = generate_pai_str ( session ) ;
}
2010-02-06 03:38:24 +00:00
2010-06-23 13:22:52 -05:00
if ( switch_channel_test_flag ( tech_pvt - > channel , CF_PROXY_MODE ) & &
2010-06-18 16:52:39 -05:00
tech_pvt - > early_sdp & & strcmp ( tech_pvt - > early_sdp , tech_pvt - > local_sdp_str ) ) {
/* The SIP RFC for SOA forbids sending a 183 with one sdp then a 200 with another but it won't do us much good unless
we do so in this case we will abandon the SOA rules and go rogue .
2010-06-30 10:35:03 -05:00
*/
2010-06-18 16:52:39 -05:00
sofia_clear_flag ( tech_pvt , TFLAG_ENABLE_SOA ) ;
}
2010-06-18 15:42:14 -05:00
tech_pvt - > early_sdp = switch_core_session_strdup ( tech_pvt - > session , tech_pvt - > local_sdp_str ) ;
2009-12-19 17:43:05 +00:00
if ( sofia_use_soa ( tech_pvt ) ) {
nua_respond ( tech_pvt - > nh ,
SIP_183_SESSION_PROGRESS ,
NUTAG_AUTOANSWER ( 0 ) ,
TAG_IF ( sticky , NUTAG_PROXY ( tech_pvt - > record_route ) ) ,
2010-06-29 09:32:41 -05:00
TAG_IF ( cid , SIPTAG_HEADER_STR ( cid ) ) ,
2009-12-19 17:43:05 +00:00
SIPTAG_CONTACT_STR ( tech_pvt - > reply_contact ) ,
SOATAG_REUSE_REJECTED ( 1 ) ,
SOATAG_ORDERED_USER ( 1 ) ,
SOATAG_ADDRESS ( tech_pvt - > adv_sdp_audio_ip ) ,
2010-02-06 03:38:24 +00:00
SOATAG_USER_SDP_STR ( tech_pvt - > local_sdp_str ) , SOATAG_AUDIO_AUX ( " cn telephone-event " ) ,
2009-12-24 05:44:23 +00:00
TAG_IF ( call_info , SIPTAG_CALL_INFO_STR ( call_info ) ) ,
2009-12-19 17:43:05 +00:00
TAG_IF ( ! zstr ( extra_header ) , SIPTAG_HEADER_STR ( extra_header ) ) ,
2010-02-06 03:38:24 +00:00
TAG_IF ( switch_stristr ( " update_display " , tech_pvt - > x_freeswitch_support_remote ) ,
SIPTAG_HEADER_STR ( " X-FS-Support: " FREESWITCH_SUPPORT ) ) , TAG_END ( ) ) ;
2009-12-19 17:43:05 +00:00
} else {
nua_respond ( tech_pvt - > nh ,
SIP_183_SESSION_PROGRESS ,
NUTAG_AUTOANSWER ( 0 ) ,
NUTAG_MEDIA_ENABLE ( 0 ) ,
TAG_IF ( sticky , NUTAG_PROXY ( tech_pvt - > record_route ) ) ,
2010-06-29 09:32:41 -05:00
TAG_IF ( cid , SIPTAG_HEADER_STR ( cid ) ) ,
2009-12-19 17:43:05 +00:00
SIPTAG_CONTACT_STR ( tech_pvt - > reply_contact ) ,
SIPTAG_CONTENT_TYPE_STR ( " application/sdp " ) ,
2010-02-06 03:38:24 +00:00
SIPTAG_PAYLOAD_STR ( tech_pvt - > local_sdp_str ) ,
2009-12-24 05:44:23 +00:00
TAG_IF ( call_info , SIPTAG_CALL_INFO_STR ( call_info ) ) ,
2009-12-19 17:43:05 +00:00
TAG_IF ( ! zstr ( extra_header ) , SIPTAG_HEADER_STR ( extra_header ) ) ,
2010-02-06 03:38:24 +00:00
TAG_IF ( switch_stristr ( " update_display " , tech_pvt - > x_freeswitch_support_remote ) ,
SIPTAG_HEADER_STR ( " X-FS-Support: " FREESWITCH_SUPPORT ) ) , TAG_END ( ) ) ;
2009-12-19 17:43:05 +00:00
}
2009-09-28 17:16:31 +00:00
switch_safe_free ( extra_header ) ;
2009-03-20 01:52:53 +00:00
}
2006-10-20 22:11:26 +00:00
}
2006-10-18 22:57:35 +00:00
}
2007-03-31 19:01:33 +00:00
break ;
default :
break ;
2006-10-18 22:57:35 +00:00
}
2008-11-05 00:20:30 +00:00
2010-06-30 10:35:03 -05:00
end_lock :
2008-11-05 00:20:30 +00:00
2010-05-12 22:19:54 -05:00
//if (msg->message_id == SWITCH_MESSAGE_INDICATE_ANSWER || msg->message_id == SWITCH_MESSAGE_INDICATE_PROGRESS) {
//sofia_send_callee_id(session, NULL, NULL);
//}
2009-10-07 22:35:21 +00:00
2008-11-03 21:54:03 +00:00
switch_mutex_unlock ( tech_pvt - > sofia_mutex ) ;
2007-03-29 22:31:56 +00:00
2010-06-30 10:35:03 -05:00
end :
2008-05-27 04:54:52 +00:00
2009-03-20 01:52:53 +00:00
if ( switch_channel_down ( channel ) | | ! tech_pvt | | sofia_test_flag ( tech_pvt , TFLAG_BYE ) ) {
status = SWITCH_STATUS_FALSE ;
}
2008-02-25 16:35:19 +00:00
return status ;
2008-05-27 04:54:52 +00:00
2006-10-18 22:57:35 +00:00
}
2007-03-31 19:01:33 +00:00
static switch_status_t sofia_receive_event ( switch_core_session_t * session , switch_event_t * event )
2006-10-19 19:39:18 +00:00
{
2008-01-28 07:26:10 +00:00
struct private_object * tech_pvt = switch_core_session_get_private ( session ) ;
2007-03-31 19:01:33 +00:00
char * body ;
nua_handle_t * msg_nh ;
2006-10-19 19:39:18 +00:00
2007-12-12 23:21:45 +00:00
switch_assert ( tech_pvt ! = NULL ) ;
2006-10-20 22:11:26 +00:00
2007-03-31 19:01:33 +00:00
if ( ! ( body = switch_event_get_body ( event ) ) ) {
body = " " ;
2006-10-22 04:37:19 +00:00
}
2007-03-31 19:01:33 +00:00
if ( tech_pvt - > hash_key ) {
2008-10-30 22:40:39 +00:00
switch_mutex_lock ( tech_pvt - > sofia_mutex ) ;
2007-03-31 19:01:33 +00:00
msg_nh = nua_handle ( tech_pvt - > profile - > nua , NULL ,
SIPTAG_FROM_STR ( tech_pvt - > chat_from ) ,
NUTAG_URL ( tech_pvt - > chat_to ) , SIPTAG_TO_STR ( tech_pvt - > chat_to ) , SIPTAG_CONTACT_STR ( tech_pvt - > profile - > url ) , TAG_END ( ) ) ;
2008-05-07 14:22:36 +00:00
nua_handle_bind ( msg_nh , & mod_sofia_globals . destroy_private ) ;
2007-03-31 19:01:33 +00:00
nua_message ( msg_nh , SIPTAG_CONTENT_TYPE_STR ( " text/html " ) , SIPTAG_PAYLOAD_STR ( body ) , TAG_END ( ) ) ;
2008-10-30 22:40:39 +00:00
switch_mutex_unlock ( tech_pvt - > sofia_mutex ) ;
2007-03-31 19:01:33 +00:00
}
2006-10-20 22:11:26 +00:00
2007-03-31 19:01:33 +00:00
return SWITCH_STATUS_SUCCESS ;
2006-10-20 22:11:26 +00:00
}
2007-04-29 01:16:49 +00:00
typedef switch_status_t ( * sofia_command_t ) ( char * * argv , int argc , switch_stream_handle_t * stream ) ;
2010-02-06 03:38:24 +00:00
static const char * sofia_state_names [ ] = {
2008-10-10 15:36:02 +00:00
" UNREGED " ,
2008-05-27 04:54:52 +00:00
" TRYING " ,
" REGISTER " ,
" REGED " ,
" UNREGISTER " ,
" FAILED " ,
2008-11-24 16:56:21 +00:00
" FAIL_WAIT " ,
2008-05-27 04:54:52 +00:00
" EXPIRED " ,
" NOREG " ,
NULL
} ;
2007-05-01 15:22:57 +00:00
2010-02-06 03:38:24 +00:00
const char * sofia_state_string ( int state )
2008-10-10 15:36:02 +00:00
{
return sofia_state_names [ state ] ;
}
2010-04-26 05:24:05 -04:00
struct cb_helper_sql2str {
2010-06-23 13:22:52 -05:00
char * buf ;
size_t len ;
int matches ;
2010-04-26 05:24:05 -04:00
} ;
2007-05-01 15:22:57 +00:00
struct cb_helper {
2010-04-26 05:26:54 -04:00
uint32_t row_process ;
2007-05-01 15:22:57 +00:00
sofia_profile_t * profile ;
switch_stream_handle_t * stream ;
} ;
2008-11-07 00:24:31 +00:00
2007-05-01 15:22:57 +00:00
static int show_reg_callback ( void * pArg , int argc , char * * argv , char * * columnNames )
{
struct cb_helper * cb = ( struct cb_helper * ) pArg ;
char exp_buf [ 128 ] = " " ;
2010-04-26 05:26:54 -04:00
int exp_secs = 0 ;
2007-05-01 15:22:57 +00:00
switch_time_exp_t tm ;
2010-04-26 05:26:54 -04:00
cb - > row_process + + ;
2007-10-19 03:27:03 +00:00
if ( argv [ 6 ] ) {
2010-04-26 05:26:54 -04:00
time_t now = switch_epoch_time_now ( NULL ) ;
2007-10-19 03:27:03 +00:00
switch_time_t etime = atoi ( argv [ 6 ] ) ;
2007-05-01 15:22:57 +00:00
switch_size_t retsize ;
2010-06-23 13:22:52 -05:00
2010-09-29 15:47:58 -05:00
exp_secs = ( int ) ( etime - now ) ;
2007-05-01 15:22:57 +00:00
switch_time_exp_lt ( & tm , switch_time_from_sec ( etime ) ) ;
2008-10-12 21:51:51 +00:00
switch_strftime_nocheck ( exp_buf , & retsize , sizeof ( exp_buf ) , " %Y-%m-%d %T " , & tm ) ;
2007-05-01 15:22:57 +00:00
}
2007-11-20 01:44:07 +00:00
2008-05-27 04:54:52 +00:00
cb - > stream - > write_function ( cb - > stream ,
2009-03-25 20:14:07 +00:00
" Call-ID: \t %s \n "
" User: \t %s@%s \n "
" Contact: \t %s \n "
" Agent: \t %s \n "
2010-04-26 05:26:54 -04:00
" Status: \t %s(%s) EXP(%s) EXPSECS(%d) \n "
2009-03-25 20:14:07 +00:00
" Host: \t %s \n "
" IP: \t %s \n "
" Port: \t %s \n "
" Auth-User: \t %s \n "
2009-09-25 20:07:40 +00:00
" Auth-Realm: \t %s \n "
" MWI-Account: \t %s@%s \n \n " ,
2008-05-27 04:54:52 +00:00
switch_str_nil ( argv [ 0 ] ) , switch_str_nil ( argv [ 1 ] ) , switch_str_nil ( argv [ 2 ] ) , switch_str_nil ( argv [ 3 ] ) ,
2010-04-26 05:26:54 -04:00
switch_str_nil ( argv [ 7 ] ) , switch_str_nil ( argv [ 4 ] ) , switch_str_nil ( argv [ 5 ] ) , exp_buf , exp_secs , switch_str_nil ( argv [ 11 ] ) ,
2009-09-25 20:07:40 +00:00
switch_str_nil ( argv [ 12 ] ) , switch_str_nil ( argv [ 13 ] ) , switch_str_nil ( argv [ 14 ] ) , switch_str_nil ( argv [ 15 ] ) ,
switch_str_nil ( argv [ 16 ] ) , switch_str_nil ( argv [ 17 ] ) ) ;
2007-05-01 15:22:57 +00:00
return 0 ;
}
2008-12-03 15:44:31 +00:00
static int show_reg_callback_xml ( void * pArg , int argc , char * * argv , char * * columnNames )
{
struct cb_helper * cb = ( struct cb_helper * ) pArg ;
char exp_buf [ 128 ] = " " ;
switch_time_exp_t tm ;
2008-12-04 21:40:44 +00:00
const int buflen = 2048 ;
char xmlbuf [ 2048 ] ;
2010-04-26 05:26:54 -04:00
int exp_secs = 0 ;
cb - > row_process + + ;
2010-02-06 03:38:24 +00:00
2008-12-03 15:44:31 +00:00
if ( argv [ 6 ] ) {
2010-04-26 05:26:54 -04:00
time_t now = switch_epoch_time_now ( NULL ) ;
2008-12-03 15:44:31 +00:00
switch_time_t etime = atoi ( argv [ 6 ] ) ;
switch_size_t retsize ;
2010-09-29 15:47:58 -05:00
exp_secs = ( int ) ( etime - now ) ;
2008-12-03 15:44:31 +00:00
switch_time_exp_lt ( & tm , switch_time_from_sec ( etime ) ) ;
switch_strftime_nocheck ( exp_buf , & retsize , sizeof ( exp_buf ) , " %Y-%m-%d %T " , & tm ) ;
}
2010-06-23 13:22:52 -05:00
cb - > stream - > write_function ( cb - > stream , " <registration> \n " ) ;
cb - > stream - > write_function ( cb - > stream , " <call-id>%s</call-id> \n " , switch_str_nil ( argv [ 0 ] ) ) ;
cb - > stream - > write_function ( cb - > stream , " <user>%s@%s</user> \n " , switch_str_nil ( argv [ 1 ] ) , switch_str_nil ( argv [ 2 ] ) ) ;
cb - > stream - > write_function ( cb - > stream , " <contact>%s</contact> \n " , switch_amp_encode ( switch_str_nil ( argv [ 3 ] ) , xmlbuf , buflen ) ) ;
cb - > stream - > write_function ( cb - > stream , " <agent>%s</agent> \n " , switch_str_nil ( argv [ 7 ] ) ) ;
cb - > stream - > write_function ( cb - > stream , " <status>%s(%s) exp(%s) expsecs(%d)</status> \n " , switch_str_nil ( argv [ 4 ] ) , switch_str_nil ( argv [ 5 ] ) ,
exp_buf , exp_secs ) ;
cb - > stream - > write_function ( cb - > stream , " <host>%s</host> \n " , switch_str_nil ( argv [ 11 ] ) ) ;
cb - > stream - > write_function ( cb - > stream , " <network-ip>%s</network-ip> \n " , switch_str_nil ( argv [ 12 ] ) ) ;
cb - > stream - > write_function ( cb - > stream , " <network-port>%s</network-port> \n " , switch_str_nil ( argv [ 13 ] ) ) ;
cb - > stream - > write_function ( cb - > stream , " <sip-auth-user>%s</sip-auth-user> \n " ,
switch_url_encode ( switch_str_nil ( argv [ 14 ] ) , xmlbuf , sizeof ( xmlbuf ) ) ) ;
cb - > stream - > write_function ( cb - > stream , " <sip-auth-realm>%s</sip-auth-realm> \n " , switch_str_nil ( argv [ 15 ] ) ) ;
cb - > stream - > write_function ( cb - > stream , " <mwi-account>%s@%s</mwi-account> \n " , switch_str_nil ( argv [ 16 ] ) , switch_str_nil ( argv [ 17 ] ) ) ;
cb - > stream - > write_function ( cb - > stream , " </registration> \n " ) ;
2010-03-24 19:04:19 +00:00
2008-12-03 15:44:31 +00:00
return 0 ;
}
2008-04-30 22:09:54 +00:00
static const char * status_names [ ] = { " DOWN " , " UP " , NULL } ;
2010-02-06 03:38:24 +00:00
2007-04-29 01:16:49 +00:00
static switch_status_t cmd_status ( char * * argv , int argc , switch_stream_handle_t * stream )
{
sofia_profile_t * profile = NULL ;
2007-05-01 15:22:57 +00:00
sofia_gateway_t * gp ;
2007-04-29 01:16:49 +00:00
switch_hash_index_t * hi ;
void * val ;
2007-04-30 20:35:35 +00:00
const void * vvar ;
2007-04-29 01:16:49 +00:00
int c = 0 ;
2007-04-30 20:35:35 +00:00
int ac = 0 ;
2007-05-02 23:32:45 +00:00
const char * line = " ================================================================================================= " ;
2007-04-29 01:16:49 +00:00
2007-05-01 15:22:57 +00:00
if ( argc > 0 ) {
if ( argc = = 1 ) {
2010-06-23 13:22:52 -05:00
/* show summary of all gateways */
2010-04-26 04:14:57 -04:00
uint32_t ib_failed = 0 ;
uint32_t ib = 0 ;
uint32_t ob_failed = 0 ;
uint32_t ob = 0 ;
stream - > write_function ( stream , " %25s \t %32s \t %s \t %s \t %s \n " , " Profile::Gateway-Name " , " Data " , " State " , " IB Calls(F/T) " , " OB Calls(F/T) " ) ;
stream - > write_function ( stream , " %s \n " , line ) ;
switch_mutex_lock ( mod_sofia_globals . hash_mutex ) ;
for ( hi = switch_hash_first ( NULL , mod_sofia_globals . profile_hash ) ; hi ; hi = switch_hash_next ( hi ) ) {
switch_hash_this ( hi , & vvar , NULL , & val ) ;
profile = ( sofia_profile_t * ) val ;
if ( sofia_test_pflag ( profile , PFLAG_RUNNING ) ) {
2010-06-23 13:22:52 -05:00
if ( ! strcmp ( vvar , profile - > name ) ) { /* not an alias */
2010-04-26 04:14:57 -04:00
for ( gp = profile - > gateways ; gp ; gp = gp - > next ) {
char * pkey = switch_mprintf ( " %s::%s " , profile - > name , gp - > name ) ;
switch_assert ( gp - > state < REG_STATE_LAST ) ;
c + + ;
ib_failed + = gp - > ib_failed_calls ;
ib + = gp - > ib_calls ;
ob_failed + = gp - > ob_failed_calls ;
ob + = gp - > ob_calls ;
2010-09-21 15:08:26 -05:00
stream - > write_function ( stream , " %25s \t %32s \t %s \t %u/%u \t %u/%u " ,
2010-06-23 13:22:52 -05:00
pkey , gp - > register_to , sofia_state_names [ gp - > state ] ,
gp - > ib_failed_calls , gp - > ib_calls , gp - > ob_failed_calls , gp - > ob_calls ) ;
2010-04-26 04:14:57 -04:00
if ( gp - > state = = REG_STATE_FAILED | | gp - > state = = REG_STATE_TRYING ) {
time_t now = switch_epoch_time_now ( NULL ) ;
if ( gp - > retry > now ) {
stream - > write_function ( stream , " (retry: %ds) " , gp - > retry - now ) ;
} else {
stream - > write_function ( stream , " (retry: NEVER) " ) ;
}
}
stream - > write_function ( stream , " \n " ) ;
}
}
}
}
switch_mutex_unlock ( mod_sofia_globals . hash_mutex ) ;
stream - > write_function ( stream , " %s \n " , line ) ;
2010-09-21 15:08:26 -05:00
stream - > write_function ( stream , " %d gateway%s: Inbound(Failed/Total): %u/%u, "
" Outbound(Failed/Total):%u/%u \n " , c , c = = 1 ? " " : " s " , ib_failed , ib , ob_failed , ob ) ;
2010-04-26 04:14:57 -04:00
2007-05-01 15:22:57 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2010-02-06 03:38:24 +00:00
2007-05-01 15:22:57 +00:00
if ( ! strcasecmp ( argv [ 0 ] , " gateway " ) ) {
if ( ( gp = sofia_reg_find_gateway ( argv [ 1 ] ) ) ) {
2007-12-12 23:21:45 +00:00
switch_assert ( gp - > state < REG_STATE_LAST ) ;
2008-04-30 22:09:54 +00:00
2007-05-01 15:22:57 +00:00
stream - > write_function ( stream , " %s \n " , line ) ;
2009-01-23 20:33:30 +00:00
stream - > write_function ( stream , " Name \t %s \n " , switch_str_nil ( gp - > name ) ) ;
2009-08-14 19:31:00 +00:00
stream - > write_function ( stream , " Profile \t %s \n " , gp - > profile - > name ) ;
2009-01-23 20:33:30 +00:00
stream - > write_function ( stream , " Scheme \t %s \n " , switch_str_nil ( gp - > register_scheme ) ) ;
stream - > write_function ( stream , " Realm \t %s \n " , switch_str_nil ( gp - > register_realm ) ) ;
stream - > write_function ( stream , " Username \t %s \n " , switch_str_nil ( gp - > register_username ) ) ;
2009-10-23 16:03:42 +00:00
stream - > write_function ( stream , " Password \t %s \n " , zstr ( gp - > register_password ) ? " no " : " yes " ) ;
2009-01-23 20:33:30 +00:00
stream - > write_function ( stream , " From \t %s \n " , switch_str_nil ( gp - > register_from ) ) ;
stream - > write_function ( stream , " Contact \t %s \n " , switch_str_nil ( gp - > register_contact ) ) ;
stream - > write_function ( stream , " Exten \t %s \n " , switch_str_nil ( gp - > extension ) ) ;
stream - > write_function ( stream , " To \t %s \n " , switch_str_nil ( gp - > register_to ) ) ;
stream - > write_function ( stream , " Proxy \t %s \n " , switch_str_nil ( gp - > register_proxy ) ) ;
stream - > write_function ( stream , " Context \t %s \n " , switch_str_nil ( gp - > register_context ) ) ;
stream - > write_function ( stream , " Expires \t %s \n " , switch_str_nil ( gp - > expires_str ) ) ;
stream - > write_function ( stream , " Freq \t %d \n " , gp - > freq ) ;
stream - > write_function ( stream , " Ping \t %d \n " , gp - > ping ) ;
stream - > write_function ( stream , " PingFreq \t %d \n " , gp - > ping_freq ) ;
2009-11-23 19:46:37 +00:00
stream - > write_function ( stream , " PingState \t %d/%d/%d \n " , gp - > ping_min , gp - > ping_count , gp - > ping_max ) ;
2009-01-23 20:33:30 +00:00
stream - > write_function ( stream , " State \t %s \n " , sofia_state_names [ gp - > state ] ) ;
stream - > write_function ( stream , " Status \t %s%s \n " , status_names [ gp - > status ] , gp - > pinging ? " (ping) " : " " ) ;
2010-09-21 15:08:26 -05:00
stream - > write_function ( stream , " CallsIN \t %u \n " , gp - > ib_calls ) ;
stream - > write_function ( stream , " CallsOUT \t %u \n " , gp - > ob_calls ) ;
stream - > write_function ( stream , " FailedCallsIN \t %u \n " , gp - > ib_failed_calls ) ;
stream - > write_function ( stream , " FailedCallsOUT \t %u \n " , gp - > ob_failed_calls ) ;
2007-05-01 15:22:57 +00:00
stream - > write_function ( stream , " %s \n " , line ) ;
sofia_reg_release_gateway ( gp ) ;
} else {
stream - > write_function ( stream , " Invalid Gateway! \n " ) ;
}
} else if ( ! strcasecmp ( argv [ 0 ] , " profile " ) ) {
struct cb_helper cb ;
2008-09-26 19:17:03 +00:00
char * sql = NULL ;
2010-09-29 15:47:58 -05:00
uint32_t x = 0 ;
2010-06-10 17:08:29 -05:00
2010-04-26 05:26:54 -04:00
cb . row_process = 0 ;
2010-06-10 17:08:29 -05:00
2008-07-24 08:06:39 +00:00
if ( ( argv [ 1 ] ) & & ( profile = sofia_glue_find_profile ( argv [ 1 ] ) ) ) {
2009-08-21 14:48:42 +00:00
if ( ! argv [ 2 ] | | ( strcasecmp ( argv [ 2 ] , " reg " ) & & strcasecmp ( argv [ 2 ] , " user " ) ) ) {
2008-09-26 19:17:03 +00:00
stream - > write_function ( stream , " %s \n " , line ) ;
2009-01-23 20:33:30 +00:00
stream - > write_function ( stream , " Name \t %s \n " , switch_str_nil ( argv [ 1 ] ) ) ;
stream - > write_function ( stream , " Domain Name \t %s \n " , profile - > domain_name ? profile - > domain_name : " N/A " ) ;
2008-09-26 19:17:03 +00:00
if ( strcasecmp ( argv [ 1 ] , profile - > name ) ) {
2010-02-06 03:38:24 +00:00
stream - > write_function ( stream , " Alias Of \t %s \n " , switch_str_nil ( profile - > name ) ) ;
2008-09-26 19:17:03 +00:00
}
2009-12-02 18:46:17 +00:00
stream - > write_function ( stream , " Auto-NAT \t %s \n " , sofia_test_pflag ( profile , PFLAG_AUTO_NAT ) ? " true " : " false " ) ;
stream - > write_function ( stream , " DBName \t %s \n " , profile - > dbname ? profile - > dbname : switch_str_nil ( profile - > odbc_dsn ) ) ;
2009-01-23 20:33:30 +00:00
stream - > write_function ( stream , " Pres Hosts \t %s \n " , switch_str_nil ( profile - > presence_hosts ) ) ;
stream - > write_function ( stream , " Dialplan \t %s \n " , switch_str_nil ( profile - > dialplan ) ) ;
stream - > write_function ( stream , " Context \t %s \n " , switch_str_nil ( profile - > context ) ) ;
2010-02-06 03:38:24 +00:00
stream - > write_function ( stream , " Challenge Realm \t %s \n " , zstr ( profile - > challenge_realm ) ? " auto_to " : profile - > challenge_realm ) ;
2010-06-10 17:08:29 -05:00
for ( x = 0 ; x < profile - > rtpip_index ; x + + ) {
stream - > write_function ( stream , " RTP-IP \t %s \n " , switch_str_nil ( profile - > rtpip [ x ] ) ) ;
}
2008-09-26 19:17:03 +00:00
if ( profile - > extrtpip ) {
2010-02-06 03:38:24 +00:00
stream - > write_function ( stream , " Ext-RTP-IP \t %s \n " , profile - > extrtpip ) ;
2008-09-26 19:17:03 +00:00
}
2008-05-27 04:54:52 +00:00
2009-01-23 20:33:30 +00:00
stream - > write_function ( stream , " SIP-IP \t %s \n " , switch_str_nil ( profile - > sipip ) ) ;
2008-09-26 19:17:03 +00:00
if ( profile - > extsipip ) {
2010-02-06 03:38:24 +00:00
stream - > write_function ( stream , " Ext-SIP-IP \t %s \n " , profile - > extsipip ) ;
2008-09-26 19:17:03 +00:00
}
2009-01-23 20:33:30 +00:00
stream - > write_function ( stream , " URL \t %s \n " , switch_str_nil ( profile - > url ) ) ;
stream - > write_function ( stream , " BIND-URL \t %s \n " , switch_str_nil ( profile - > bindurl ) ) ;
2008-09-26 19:17:03 +00:00
if ( sofia_test_pflag ( profile , PFLAG_TLS ) ) {
2010-02-06 03:38:24 +00:00
stream - > write_function ( stream , " TLS-URL \t %s \n " , switch_str_nil ( profile - > tls_url ) ) ;
stream - > write_function ( stream , " TLS-BIND-URL \t %s \n " , switch_str_nil ( profile - > tls_bindurl ) ) ;
2008-09-26 19:17:03 +00:00
}
2009-10-23 16:03:42 +00:00
stream - > write_function ( stream , " HOLD-MUSIC \t %s \n " , zstr ( profile - > hold_music ) ? " N/A " : profile - > hold_music ) ;
stream - > write_function ( stream , " OUTBOUND-PROXY \t %s \n " , zstr ( profile - > outbound_proxy ) ? " N/A " : profile - > outbound_proxy ) ;
2009-11-24 18:52:57 +00:00
stream - > write_function ( stream , " CODECS IN \t %s \n " , switch_str_nil ( profile - > inbound_codec_string ) ) ;
stream - > write_function ( stream , " CODECS OUT \t %s \n " , switch_str_nil ( profile - > outbound_codec_string ) ) ;
2009-01-23 20:33:30 +00:00
stream - > write_function ( stream , " TEL-EVENT \t %d \n " , profile - > te ) ;
2008-09-26 19:17:03 +00:00
if ( profile - > dtmf_type = = DTMF_2833 ) {
2010-02-06 03:38:24 +00:00
stream - > write_function ( stream , " DTMF-MODE \t rfc2833 \n " ) ;
2008-09-26 19:17:03 +00:00
} else if ( profile - > dtmf_type = = DTMF_INFO ) {
2010-02-06 03:38:24 +00:00
stream - > write_function ( stream , " DTMF-MODE \t info \n " ) ;
2008-09-26 19:17:03 +00:00
} else {
2010-02-06 03:38:24 +00:00
stream - > write_function ( stream , " DTMF-MODE \t none \n " ) ;
2008-09-26 19:17:03 +00:00
}
2009-01-23 20:33:30 +00:00
stream - > write_function ( stream , " CNG \t %d \n " , profile - > cng_pt ) ;
stream - > write_function ( stream , " SESSION-TO \t %d \n " , profile - > session_timeout ) ;
stream - > write_function ( stream , " MAX-DIALOG \t %d \n " , profile - > max_proceeding ) ;
2009-02-09 17:56:38 +00:00
stream - > write_function ( stream , " NOMEDIA \t %s \n " , sofia_test_flag ( profile , TFLAG_INB_NOMEDIA ) ? " true " : " false " ) ;
stream - > write_function ( stream , " LATE-NEG \t %s \n " , sofia_test_flag ( profile , TFLAG_LATE_NEGOTIATION ) ? " true " : " false " ) ;
stream - > write_function ( stream , " PROXY-MEDIA \t %s \n " , sofia_test_flag ( profile , TFLAG_PROXY_MEDIA ) ? " true " : " false " ) ;
2010-02-06 03:38:24 +00:00
stream - > write_function ( stream , " AGGRESSIVENAT \t %s \n " ,
sofia_test_pflag ( profile , PFLAG_AGGRESSIVE_NAT_DETECTION ) ? " true " : " false " ) ;
2009-04-21 22:26:21 +00:00
stream - > write_function ( stream , " STUN-ENABLED \t %s \n " , sofia_test_pflag ( profile , PFLAG_STUN_ENABLED ) ? " true " : " false " ) ;
stream - > write_function ( stream , " STUN-AUTO-DISABLE \t %s \n " , sofia_test_pflag ( profile , PFLAG_STUN_AUTO_DISABLE ) ? " true " : " false " ) ;
2010-02-02 21:04:41 +00:00
if ( profile - > user_agent_filter ) {
2010-02-06 03:38:24 +00:00
stream - > write_function ( stream , " USER-AGENT-FILTER \t %s \n " , switch_str_nil ( profile - > user_agent_filter ) ) ;
2010-02-02 21:04:41 +00:00
}
if ( profile - > max_registrations_perext > 0 ) {
2010-02-06 03:38:24 +00:00
stream - > write_function ( stream , " MAX-REG-PEREXT \t %d \n " , profile - > max_registrations_perext ) ;
2010-02-02 21:04:41 +00:00
}
2010-09-21 15:08:26 -05:00
stream - > write_function ( stream , " CALLS-IN \t %u \n " , profile - > ib_calls ) ;
stream - > write_function ( stream , " FAILED-CALLS-IN \t %u \n " , profile - > ib_failed_calls ) ;
stream - > write_function ( stream , " CALLS-OUT \t %u \n " , profile - > ob_calls ) ;
stream - > write_function ( stream , " FAILED-CALLS-OUT \t %u \n " , profile - > ob_failed_calls ) ;
2008-07-14 23:58:07 +00:00
}
2007-05-01 15:22:57 +00:00
stream - > write_function ( stream , " \n Registrations: \n %s \n " , line ) ;
cb . profile = profile ;
cb . stream = stream ;
2010-02-06 03:38:24 +00:00
2009-08-21 19:27:35 +00:00
if ( ! sql & & argv [ 2 ] & & ! strcasecmp ( argv [ 2 ] , " pres " ) & & argv [ 3 ] ) {
sql = switch_mprintf ( " select call_id,sip_user,sip_host,contact,status, "
2010-02-06 03:38:24 +00:00
" rpid,expires,user_agent,server_user,server_host,profile_name,hostname, "
" network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host "
" from sip_registrations where profile_name='%q' and presence_hosts like '%%%q%%' " , profile - > name , argv [ 3 ] ) ;
2009-08-21 19:27:35 +00:00
}
if ( ! sql & & argv [ 2 ] & & ! strcasecmp ( argv [ 2 ] , " reg " ) & & argv [ 3 ] ) {
sql = switch_mprintf ( " select call_id,sip_user,sip_host,contact,status, "
2010-02-06 03:38:24 +00:00
" rpid,expires,user_agent,server_user,server_host,profile_name,hostname, "
" network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host "
" from sip_registrations where profile_name='%q' and contact like '%%%q%%' " , profile - > name , argv [ 3 ] ) ;
2008-09-26 19:17:03 +00:00
}
2009-08-21 14:48:42 +00:00
if ( ! sql & & argv [ 2 ] & & ! strcasecmp ( argv [ 2 ] , " user " ) & & argv [ 3 ] ) {
char * dup = strdup ( argv [ 3 ] ) ;
char * host = NULL , * user = NULL ;
char * sqlextra = NULL ;
switch_assert ( dup ) ;
if ( ( host = strchr ( dup , ' @ ' ) ) ) {
* host + + = ' \0 ' ;
user = dup ;
} else {
host = dup ;
}
2010-02-06 03:38:24 +00:00
if ( zstr ( user ) ) {
2009-08-21 14:48:42 +00:00
sqlextra = switch_mprintf ( " (sip_host='%q') " , host ) ;
2009-10-23 16:03:42 +00:00
} else if ( zstr ( host ) ) {
2009-08-21 14:48:42 +00:00
sqlextra = switch_mprintf ( " (sip_user='%q') " , user ) ;
} else {
sqlextra = switch_mprintf ( " (sip_user='%q' and sip_host='%q') " , user , host ) ;
}
sql = switch_mprintf ( " select call_id,sip_user,sip_host,contact,status, "
2010-02-06 03:38:24 +00:00
" rpid,expires,user_agent,server_user,server_host,profile_name,hostname, "
" network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host "
" from sip_registrations where profile_name='%q' and %s " , profile - > name , sqlextra ) ;
2009-08-21 14:48:42 +00:00
switch_safe_free ( dup ) ;
switch_safe_free ( sqlextra ) ;
}
2008-09-26 19:17:03 +00:00
if ( ! sql ) {
sql = switch_mprintf ( " select call_id,sip_user,sip_host,contact,status, "
2009-03-25 20:14:07 +00:00
" rpid,expires,user_agent,server_user,server_host,profile_name,hostname, "
2009-09-25 20:07:40 +00:00
" network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host "
2010-02-06 03:38:24 +00:00
" from sip_registrations where profile_name='%q' " , profile - > name ) ;
2008-09-26 19:17:03 +00:00
}
2008-05-27 04:54:52 +00:00
2009-11-12 03:52:07 +00:00
sofia_glue_execute_sql_callback ( profile , profile - > ireg_mutex , sql , show_reg_callback , & cb ) ;
2009-08-21 19:27:35 +00:00
switch_safe_free ( sql ) ;
2007-05-01 15:22:57 +00:00
2010-04-26 05:26:54 -04:00
stream - > write_function ( stream , " Total items returned: %d \n " , cb . row_process ) ;
2007-05-01 15:22:57 +00:00
stream - > write_function ( stream , " %s \n " , line ) ;
2007-05-03 01:55:25 +00:00
sofia_glue_release_profile ( profile ) ;
2007-05-01 15:22:57 +00:00
} else {
stream - > write_function ( stream , " Invalid Profile! \n " ) ;
}
} else {
stream - > write_function ( stream , " Invalid Syntax! \n " ) ;
}
return SWITCH_STATUS_SUCCESS ;
}
2010-02-18 22:39:08 +00:00
stream - > write_function ( stream , " %25s \t %s \t %40s \t %s \n " , " Name " , " Type " , " Data " , " State " ) ;
2007-04-30 20:35:35 +00:00
stream - > write_function ( stream , " %s \n " , line ) ;
2007-04-29 01:16:49 +00:00
switch_mutex_lock ( mod_sofia_globals . hash_mutex ) ;
2007-09-24 19:34:25 +00:00
for ( hi = switch_hash_first ( NULL , mod_sofia_globals . profile_hash ) ; hi ; hi = switch_hash_next ( hi ) ) {
2007-04-30 20:35:35 +00:00
switch_hash_this ( hi , & vvar , NULL , & val ) ;
2007-04-29 01:16:49 +00:00
profile = ( sofia_profile_t * ) val ;
if ( sofia_test_pflag ( profile , PFLAG_RUNNING ) ) {
2008-05-27 04:54:52 +00:00
2007-04-30 20:35:35 +00:00
if ( strcmp ( vvar , profile - > name ) ) {
ac + + ;
2010-02-18 22:39:08 +00:00
stream - > write_function ( stream , " %25s \t %s \t %40s \t %s \n " , vvar , " alias " , profile - > name , " ALIASED " ) ;
2007-04-30 20:35:35 +00:00
} else {
2010-02-18 22:39:08 +00:00
stream - > write_function ( stream , " %25s \t %s \t %40s \t %s (%u) \n " , profile - > name , " profile " , profile - > url ,
2007-05-03 01:55:25 +00:00
sofia_test_pflag ( profile , PFLAG_RUNNING ) ? " RUNNING " : " DOWN " , profile - > inuse ) ;
2008-01-19 01:28:36 +00:00
if ( sofia_test_pflag ( profile , PFLAG_TLS ) ) {
2010-02-18 22:39:08 +00:00
stream - > write_function ( stream , " %25s \t %s \t %40s \t %s (%u) (TLS) \n " , profile - > name , " profile " , profile - > tls_url ,
2008-05-27 04:54:52 +00:00
sofia_test_pflag ( profile , PFLAG_RUNNING ) ? " RUNNING " : " DOWN " , profile - > inuse ) ;
2008-01-19 01:28:36 +00:00
}
2007-04-30 20:35:35 +00:00
c + + ;
2007-05-01 15:22:57 +00:00
for ( gp = profile - > gateways ; gp ; gp = gp - > next ) {
2010-02-18 22:39:08 +00:00
char * pkey = switch_mprintf ( " %s::%s " , profile - > name , gp - > name ) ;
2007-12-12 23:21:45 +00:00
switch_assert ( gp - > state < REG_STATE_LAST ) ;
2010-06-23 13:22:52 -05:00
stream - > write_function ( stream , " %25s \t %s \t %40s \t %s " , pkey , " gateway " , gp - > register_to , sofia_state_names [ gp - > state ] ) ;
2010-02-18 22:39:08 +00:00
free ( pkey ) ;
2007-05-10 16:15:07 +00:00
if ( gp - > state = = REG_STATE_FAILED | | gp - > state = = REG_STATE_TRYING ) {
2009-01-25 21:23:07 +00:00
time_t now = switch_epoch_time_now ( NULL ) ;
2008-09-22 21:53:50 +00:00
if ( gp - > retry > now ) {
stream - > write_function ( stream , " (retry: %ds) " , gp - > retry - now ) ;
} else {
stream - > write_function ( stream , " (retry: NEVER) " ) ;
}
2007-05-10 16:15:07 +00:00
}
stream - > write_function ( stream , " \n " ) ;
2007-05-01 15:22:57 +00:00
}
2007-04-30 20:35:35 +00:00
}
2007-04-29 01:16:49 +00:00
}
}
switch_mutex_unlock ( mod_sofia_globals . hash_mutex ) ;
2007-04-30 20:35:35 +00:00
stream - > write_function ( stream , " %s \n " , line ) ;
2007-05-02 23:32:45 +00:00
stream - > write_function ( stream , " %d profile%s %d alias%s \n " , c , c = = 1 ? " " : " s " , ac , ac = = 1 ? " " : " es " ) ;
2007-04-29 01:16:49 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2010-08-26 18:35:22 -04:00
static void xml_gateway_status ( sofia_gateway_t * gp , switch_stream_handle_t * stream )
{
char xmlbuf [ 2096 ] ;
const int buflen = 2096 ;
stream - > write_function ( stream , " <gateway> \n " ) ;
stream - > write_function ( stream , " <name>%s</name> \n " , switch_str_nil ( gp - > name ) ) ;
stream - > write_function ( stream , " <profile>%s</profile> \n " , gp - > profile - > name ) ;
stream - > write_function ( stream , " <scheme>%s</scheme> \n " , switch_str_nil ( gp - > register_scheme ) ) ;
stream - > write_function ( stream , " <realm>%s</realm> \n " , switch_str_nil ( gp - > register_realm ) ) ;
stream - > write_function ( stream , " <username>%s</username> \n " , switch_str_nil ( gp - > register_username ) ) ;
stream - > write_function ( stream , " <password>%s</password> \n " , zstr ( gp - > register_password ) ? " no " : " yes " ) ;
stream - > write_function ( stream , " <from>%s</from> \n " , switch_amp_encode ( switch_str_nil ( gp - > register_from ) , xmlbuf , buflen ) ) ;
stream - > write_function ( stream , " <contact>%s</contact> \n " , switch_amp_encode ( switch_str_nil ( gp - > register_contact ) , xmlbuf , buflen ) ) ;
stream - > write_function ( stream , " <exten>%s</exten> \n " , switch_amp_encode ( switch_str_nil ( gp - > extension ) , xmlbuf , buflen ) ) ;
stream - > write_function ( stream , " <to>%s</to> \n " , switch_str_nil ( gp - > register_to ) ) ;
stream - > write_function ( stream , " <proxy>%s</proxy> \n " , switch_str_nil ( gp - > register_proxy ) ) ;
stream - > write_function ( stream , " <context>%s</context> \n " , switch_str_nil ( gp - > register_context ) ) ;
stream - > write_function ( stream , " <expires>%s</expires> \n " , switch_str_nil ( gp - > expires_str ) ) ;
stream - > write_function ( stream , " <freq>%d</freq> \n " , gp - > freq ) ;
stream - > write_function ( stream , " <ping>%d</ping> \n " , gp - > ping ) ;
stream - > write_function ( stream , " <pingfreq>%d</pingfreq> \n " , gp - > ping_freq ) ;
stream - > write_function ( stream , " <state>%s</state> \n " , sofia_state_names [ gp - > state ] ) ;
stream - > write_function ( stream , " <status>%s%s</status> \n " , status_names [ gp - > status ] , gp - > pinging ? " (ping) " : " " ) ;
2010-09-21 15:08:26 -05:00
stream - > write_function ( stream , " <calls-in>%u</calls-in> \n " , gp - > ib_calls ) ;
stream - > write_function ( stream , " <calls-out>%u</calls-out> \n " , gp - > ob_calls ) ;
stream - > write_function ( stream , " <failed-calls-in>%u</failed-calls-in> \n " , gp - > ib_failed_calls ) ;
stream - > write_function ( stream , " <failed-calls-out>%u</failed-calls-out> \n " , gp - > ob_failed_calls ) ;
2010-08-26 18:35:22 -04:00
if ( gp - > state = = REG_STATE_FAILED | | gp - > state = = REG_STATE_TRYING ) {
time_t now = switch_epoch_time_now ( NULL ) ;
if ( gp - > retry > now ) {
stream - > write_function ( stream , " <retry>%ds</retry> \n " , gp - > retry - now ) ;
} else {
stream - > write_function ( stream , " <retry>NEVER</retry> \n " ) ;
}
}
stream - > write_function ( stream , " </gateway> \n " ) ;
}
2008-12-03 15:44:31 +00:00
static switch_status_t cmd_xml_status ( char * * argv , int argc , switch_stream_handle_t * stream )
{
sofia_profile_t * profile = NULL ;
sofia_gateway_t * gp ;
switch_hash_index_t * hi ;
void * val ;
const void * vvar ;
int c = 0 ;
int ac = 0 ;
2010-02-06 03:38:24 +00:00
const char * header = " <?xml version= \" 1.0 \" encoding= \" ISO-8859-1 \" ?> " ;
if ( argc > 0 ) {
2008-12-03 15:44:31 +00:00
if ( argc = = 1 ) {
2010-06-23 13:22:52 -05:00
/* show summary of all gateways */
stream - > write_function ( stream , " %s \n " , header ) ;
stream - > write_function ( stream , " <gateways> \n " , header ) ;
switch_mutex_lock ( mod_sofia_globals . hash_mutex ) ;
for ( hi = switch_hash_first ( NULL , mod_sofia_globals . profile_hash ) ; hi ; hi = switch_hash_next ( hi ) ) {
switch_hash_this ( hi , & vvar , NULL , & val ) ;
profile = ( sofia_profile_t * ) val ;
if ( sofia_test_pflag ( profile , PFLAG_RUNNING ) ) {
if ( ! strcmp ( vvar , profile - > name ) ) { /* not an alias */
for ( gp = profile - > gateways ; gp ; gp = gp - > next ) {
switch_assert ( gp - > state < REG_STATE_LAST ) ;
2010-08-26 18:35:22 -04:00
xml_gateway_status ( gp , stream ) ;
2010-06-23 13:22:52 -05:00
}
}
}
}
switch_mutex_unlock ( mod_sofia_globals . hash_mutex ) ;
stream - > write_function ( stream , " </gateways> \n " ) ;
2010-04-26 04:14:57 -04:00
2010-08-26 18:35:22 -04:00
} else if ( argc = = 1 & & ! strcasecmp ( argv [ 0 ] , " profile " ) ) {
} else if ( ! strcasecmp ( argv [ 0 ] , " gateway " ) ) {
2008-12-03 15:44:31 +00:00
if ( ( gp = sofia_reg_find_gateway ( argv [ 1 ] ) ) ) {
switch_assert ( gp - > state < REG_STATE_LAST ) ;
2009-03-25 20:14:07 +00:00
stream - > write_function ( stream , " %s \n " , header ) ;
2010-08-26 18:35:22 -04:00
xml_gateway_status ( gp , stream ) ;
2008-12-03 15:44:31 +00:00
sofia_reg_release_gateway ( gp ) ;
} else {
stream - > write_function ( stream , " Invalid Gateway! \n " ) ;
}
} else if ( ! strcasecmp ( argv [ 0 ] , " profile " ) ) {
struct cb_helper cb ;
char * sql = NULL ;
2010-09-29 15:47:58 -05:00
uint32_t x = 0 ;
2010-06-10 17:08:29 -05:00
2010-04-26 05:26:54 -04:00
cb . row_process = 0 ;
2008-12-03 15:44:31 +00:00
if ( ( argv [ 1 ] ) & & ( profile = sofia_glue_find_profile ( argv [ 1 ] ) ) ) {
2009-05-09 15:05:33 +00:00
stream - > write_function ( stream , " %s \n " , header ) ;
stream - > write_function ( stream , " <profile> \n " ) ;
2009-08-21 14:48:42 +00:00
if ( ! argv [ 2 ] | | ( strcasecmp ( argv [ 2 ] , " reg " ) & & strcasecmp ( argv [ 2 ] , " user " ) ) ) {
2009-05-09 15:05:33 +00:00
stream - > write_function ( stream , " <profile-info> \n " ) ;
2009-03-25 20:14:07 +00:00
stream - > write_function ( stream , " <name>%s</name> \n " , switch_str_nil ( argv [ 1 ] ) ) ;
stream - > write_function ( stream , " <domain-name>%s</domain-name> \n " , profile - > domain_name ? profile - > domain_name : " N/A " ) ;
2008-12-03 15:44:31 +00:00
if ( strcasecmp ( argv [ 1 ] , profile - > name ) ) {
2009-03-25 20:14:07 +00:00
stream - > write_function ( stream , " <alias-of>%s</alias-of> \n " , switch_str_nil ( profile - > name ) ) ;
2008-12-03 15:44:31 +00:00
}
2009-12-02 18:46:17 +00:00
stream - > write_function ( stream , " <auto-nat>%s</auto-nat> \n " , sofia_test_pflag ( profile , PFLAG_AUTO_NAT ) ? " true " : " false " ) ;
stream - > write_function ( stream , " <db-name>%s</db-name> \n " , profile - > dbname ? profile - > dbname : switch_str_nil ( profile - > odbc_dsn ) ) ;
2009-03-25 20:14:07 +00:00
stream - > write_function ( stream , " <pres-hosts>%s</pres-hosts> \n " , switch_str_nil ( profile - > presence_hosts ) ) ;
stream - > write_function ( stream , " <dialplan>%s</dialplan> \n " , switch_str_nil ( profile - > dialplan ) ) ;
stream - > write_function ( stream , " <context>%s</context> \n " , switch_str_nil ( profile - > context ) ) ;
2010-02-06 03:38:24 +00:00
stream - > write_function ( stream , " <challenge-realm>%s</challenge-realm> \n " ,
2009-10-23 16:03:42 +00:00
zstr ( profile - > challenge_realm ) ? " auto_to " : profile - > challenge_realm ) ;
2010-06-10 17:08:29 -05:00
for ( x = 0 ; x < profile - > rtpip_index ; x + + ) {
stream - > write_function ( stream , " <rtp-ip>%s</rtp-ip> \n " , switch_str_nil ( profile - > rtpip [ x ] ) ) ;
}
2009-03-25 20:14:07 +00:00
stream - > write_function ( stream , " <ext-rtp-ip>%s</ext-rtp-ip> \n " , profile - > extrtpip ) ;
stream - > write_function ( stream , " <sip-ip>%s</sip-ip> \n " , switch_str_nil ( profile - > sipip ) ) ;
stream - > write_function ( stream , " <ext-sip-ip>%s</ext-sip-ip> \n " , profile - > extsipip ) ;
stream - > write_function ( stream , " <url>%s</url> \n " , switch_str_nil ( profile - > url ) ) ;
stream - > write_function ( stream , " <bind-url>%s</bind-url> \n " , switch_str_nil ( profile - > bindurl ) ) ;
stream - > write_function ( stream , " <tls-url>%s</tls-url> \n " , switch_str_nil ( profile - > tls_url ) ) ;
stream - > write_function ( stream , " <tls-bind-url>%s</tls-bind-url> \n " , switch_str_nil ( profile - > tls_bindurl ) ) ;
2009-10-23 16:03:42 +00:00
stream - > write_function ( stream , " <hold-music>%s</hold-music> \n " , zstr ( profile - > hold_music ) ? " N/A " : profile - > hold_music ) ;
2010-02-06 03:38:24 +00:00
stream - > write_function ( stream , " <outbound-proxy>%s</outbound-proxy> \n " ,
zstr ( profile - > outbound_proxy ) ? " N/A " : profile - > outbound_proxy ) ;
2009-11-24 18:52:57 +00:00
stream - > write_function ( stream , " <inbound-codecs>%s</inbound-codecs> \n " , switch_str_nil ( profile - > inbound_codec_string ) ) ;
stream - > write_function ( stream , " <outbound-codecs>%s</outbound-codecs> \n " , switch_str_nil ( profile - > outbound_codec_string ) ) ;
2009-03-25 20:14:07 +00:00
stream - > write_function ( stream , " <tel-event>%d</tel-event> \n " , profile - > te ) ;
stream - > write_function ( stream , " <dtmf-mode>rfc2833</dtmf-mode> \n " ) ;
stream - > write_function ( stream , " <dtmf-mode>info</dtmf-mode> \n " ) ;
stream - > write_function ( stream , " <dtmf-mode>none</dtmf-mode> \n " ) ;
stream - > write_function ( stream , " <cng>%d</cng> \n " , profile - > cng_pt ) ;
stream - > write_function ( stream , " <session-to>%d</session-to> \n " , profile - > session_timeout ) ;
stream - > write_function ( stream , " <max-dialog>%d</max-dialog> \n " , profile - > max_proceeding ) ;
stream - > write_function ( stream , " <nomedia>%s</nomedia> \n " , sofia_test_flag ( profile , TFLAG_INB_NOMEDIA ) ? " true " : " false " ) ;
stream - > write_function ( stream , " <late-neg>%s</late-neg> \n " , sofia_test_flag ( profile , TFLAG_LATE_NEGOTIATION ) ? " true " : " false " ) ;
stream - > write_function ( stream , " <proxy-media>%s</proxy-media> \n " , sofia_test_flag ( profile , TFLAG_PROXY_MEDIA ) ? " true " : " false " ) ;
2010-02-06 03:38:24 +00:00
stream - > write_function ( stream , " <aggressive-nat>%s</aggressive-nat> \n " ,
2009-04-21 17:47:22 +00:00
sofia_test_pflag ( profile , PFLAG_AGGRESSIVE_NAT_DETECTION ) ? " true " : " false " ) ;
2010-02-06 03:38:24 +00:00
stream - > write_function ( stream , " <stun-enabled>%s</stun-enabled> \n " ,
sofia_test_pflag ( profile , PFLAG_STUN_ENABLED ) ? " true " : " false " ) ;
stream - > write_function ( stream , " <stun-auto-disable>%s</stun-auto-disable> \n " ,
2009-04-21 17:47:22 +00:00
sofia_test_pflag ( profile , PFLAG_STUN_AUTO_DISABLE ) ? " true " : " false " ) ;
2010-02-02 21:04:41 +00:00
stream - > write_function ( stream , " <user-agent-filter>%s</user-agent-filter> \n " , switch_str_nil ( profile - > user_agent_filter ) ) ;
2010-02-06 03:38:24 +00:00
stream - > write_function ( stream , " <max-registrations-per-extension>%d</max-registrations-per-extension> \n " ,
profile - > max_registrations_perext ) ;
2010-09-21 15:08:26 -05:00
stream - > write_function ( stream , " <calls-in>%u</calls-in> \n " , profile - > ib_calls ) ;
stream - > write_function ( stream , " <calls-out>%u</calls-out> \n " , profile - > ob_calls ) ;
stream - > write_function ( stream , " <failed-calls-in>%u</failed-calls-in> \n " , profile - > ib_failed_calls ) ;
stream - > write_function ( stream , " <failed-calls-out>%u</failed-calls-out> \n " , profile - > ob_failed_calls ) ;
2009-05-09 15:05:33 +00:00
stream - > write_function ( stream , " </profile-info> \n " ) ;
2008-12-03 15:44:31 +00:00
}
2009-03-25 20:14:07 +00:00
stream - > write_function ( stream , " <registrations> \n " ) ;
2008-12-03 15:44:31 +00:00
cb . profile = profile ;
cb . stream = stream ;
2009-08-21 19:27:35 +00:00
if ( ! sql & & argv [ 2 ] & & ! strcasecmp ( argv [ 2 ] , " pres " ) & & argv [ 3 ] ) {
sql = switch_mprintf ( " select call_id,sip_user,sip_host,contact,status, "
2010-02-06 03:38:24 +00:00
" rpid,expires,user_agent,server_user,server_host,profile_name,hostname, "
" network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host "
" from sip_registrations where profile_name='%q' and presence_hosts like '%%%q%%' " , profile - > name , argv [ 3 ] ) ;
2009-08-21 19:27:35 +00:00
}
if ( ! sql & & argv [ 2 ] & & ! strcasecmp ( argv [ 2 ] , " reg " ) & & argv [ 3 ] ) {
sql = switch_mprintf ( " select call_id,sip_user,sip_host,contact,status, "
2010-02-06 03:38:24 +00:00
" rpid,expires,user_agent,server_user,server_host,profile_name,hostname, "
" network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host "
" from sip_registrations where profile_name='%q' and contact like '%%%q%%' " , profile - > name , argv [ 3 ] ) ;
2008-12-03 15:44:31 +00:00
}
2009-08-21 14:48:42 +00:00
if ( ! sql & & argv [ 2 ] & & ! strcasecmp ( argv [ 2 ] , " user " ) & & argv [ 3 ] ) {
char * dup = strdup ( argv [ 3 ] ) ;
char * host = NULL , * user = NULL ;
char * sqlextra = NULL ;
switch_assert ( dup ) ;
if ( ( host = strchr ( dup , ' @ ' ) ) ) {
* host + + = ' \0 ' ;
user = dup ;
} else {
host = dup ;
}
2009-10-23 16:03:42 +00:00
if ( zstr ( user ) ) {
2009-08-21 14:48:42 +00:00
sqlextra = switch_mprintf ( " (sip_host='%q') " , host ) ;
2009-10-23 16:03:42 +00:00
} else if ( zstr ( host ) ) {
2009-08-21 14:48:42 +00:00
sqlextra = switch_mprintf ( " (sip_user='%q') " , user ) ;
} else {
sqlextra = switch_mprintf ( " (sip_user='%q' and sip_host='%q') " , user , host ) ;
}
sql = switch_mprintf ( " select call_id,sip_user,sip_host,contact,status, "
2010-02-06 03:38:24 +00:00
" rpid,expires,user_agent,server_user,server_host,profile_name,hostname, "
" network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host "
" from sip_registrations where profile_name='%q' and %s " , profile - > name , sqlextra ) ;
2009-08-21 14:48:42 +00:00
switch_safe_free ( dup ) ;
switch_safe_free ( sqlextra ) ;
}
2008-12-03 15:44:31 +00:00
if ( ! sql ) {
sql = switch_mprintf ( " select call_id,sip_user,sip_host,contact,status, "
2009-03-25 20:14:07 +00:00
" rpid,expires,user_agent,server_user,server_host,profile_name,hostname, "
2009-09-25 20:07:40 +00:00
" network_ip,network_port,sip_username,sip_realm,mwi_user,mwi_host "
2010-02-06 03:38:24 +00:00
" from sip_registrations where profile_name='%q' " , profile - > name ) ;
2008-12-03 15:44:31 +00:00
}
2009-11-12 03:52:07 +00:00
sofia_glue_execute_sql_callback ( profile , profile - > ireg_mutex , sql , show_reg_callback_xml , & cb ) ;
2009-08-21 19:27:35 +00:00
switch_safe_free ( sql ) ;
2008-12-03 15:44:31 +00:00
2009-05-09 15:05:33 +00:00
stream - > write_function ( stream , " </registrations> \n " ) ;
2009-03-25 20:14:07 +00:00
stream - > write_function ( stream , " </profile> \n " ) ;
2008-12-03 15:44:31 +00:00
sofia_glue_release_profile ( profile ) ;
} else {
stream - > write_function ( stream , " Invalid Profile! \n " ) ;
}
} else {
stream - > write_function ( stream , " Invalid Syntax! \n " ) ;
}
return SWITCH_STATUS_SUCCESS ;
}
2010-02-06 03:38:24 +00:00
stream - > write_function ( stream , " %s \n " , header ) ;
stream - > write_function ( stream , " <profiles> \n " ) ;
2008-12-03 15:44:31 +00:00
switch_mutex_lock ( mod_sofia_globals . hash_mutex ) ;
for ( hi = switch_hash_first ( NULL , mod_sofia_globals . profile_hash ) ; hi ; hi = switch_hash_next ( hi ) ) {
switch_hash_this ( hi , & vvar , NULL , & val ) ;
profile = ( sofia_profile_t * ) val ;
if ( sofia_test_pflag ( profile , PFLAG_RUNNING ) ) {
if ( strcmp ( vvar , profile - > name ) ) {
ac + + ;
2010-02-06 03:38:24 +00:00
stream - > write_function ( stream , " <alias> \n <name>%s</name> \n <type>%s</type> \n <data>%s</data> \n <state>%s</state> \n </alias> \n " , vvar , " alias " ,
profile - > name , " ALIASED " ) ;
2008-12-03 15:44:31 +00:00
} else {
2010-02-06 03:38:24 +00:00
stream - > write_function ( stream , " <profile> \n <name>%s</name> \n <type>%s</type> \n <data>%s</data> \n <state>%s (%u)</state> \n </profile> \n " ,
profile - > name , " profile " , profile - > url , sofia_test_pflag ( profile , PFLAG_RUNNING ) ? " RUNNING " : " DOWN " ,
profile - > inuse ) ;
2008-12-03 15:44:31 +00:00
if ( sofia_test_pflag ( profile , PFLAG_TLS ) ) {
2010-02-06 03:38:24 +00:00
stream - > write_function ( stream ,
" <profile> \n <name>%s</name> \n <type>%s</type> \n <data>%s</data> \n <state>%s (%u) (TLS)</state> \n </profile> \n " ,
profile - > name , " profile " , profile - > tls_url , sofia_test_pflag ( profile , PFLAG_RUNNING ) ? " RUNNING " : " DOWN " ,
profile - > inuse ) ;
2008-12-03 15:44:31 +00:00
}
c + + ;
for ( gp = profile - > gateways ; gp ; gp = gp - > next ) {
switch_assert ( gp - > state < REG_STATE_LAST ) ;
2010-02-06 03:38:24 +00:00
stream - > write_function ( stream , " <gateway> \n <name>%s</name> \n <type>%s</type> \n <data>%s</data> \n <state>%s</state> \n </gateway> \n " ,
gp - > name , " gateway " , gp - > register_to , sofia_state_names [ gp - > state ] ) ;
2008-12-03 15:44:31 +00:00
if ( gp - > state = = REG_STATE_FAILED | | gp - > state = = REG_STATE_TRYING ) {
2009-01-25 21:23:07 +00:00
time_t now = switch_epoch_time_now ( NULL ) ;
2008-12-03 15:44:31 +00:00
if ( gp - > retry > now ) {
stream - > write_function ( stream , " (retry: %ds) " , gp - > retry - now ) ;
} else {
stream - > write_function ( stream , " (retry: NEVER) " ) ;
}
}
stream - > write_function ( stream , " \n " ) ;
}
}
}
}
switch_mutex_unlock ( mod_sofia_globals . hash_mutex ) ;
2009-04-21 20:24:44 +00:00
stream - > write_function ( stream , " </profiles> \n " ) ;
2008-12-03 15:44:31 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2007-04-29 01:16:49 +00:00
static switch_status_t cmd_profile ( char * * argv , int argc , switch_stream_handle_t * stream )
{
sofia_profile_t * profile = NULL ;
char * profile_name = argv [ 0 ] ;
2007-05-03 01:55:25 +00:00
const char * err ;
2007-04-29 01:16:49 +00:00
if ( argc < 2 ) {
stream - > write_function ( stream , " Invalid Args! \n " ) ;
return SWITCH_STATUS_SUCCESS ;
}
if ( ! strcasecmp ( argv [ 1 ] , " start " ) ) {
2010-09-16 18:17:52 -05:00
switch_xml_reload ( & err ) ;
stream - > write_function ( stream , " Reload XML [%s] \n " , err ) ;
2007-04-29 01:16:49 +00:00
if ( config_sofia ( 1 , argv [ 0 ] ) = = SWITCH_STATUS_SUCCESS ) {
stream - > write_function ( stream , " %s started successfully \n " , argv [ 0 ] ) ;
} else {
stream - > write_function ( stream , " Failure starting %s \n " , argv [ 0 ] ) ;
}
return SWITCH_STATUS_SUCCESS ;
}
2008-05-27 04:54:52 +00:00
2008-07-22 22:23:50 +00:00
if ( argv [ 1 ] & & ! strcasecmp ( argv [ 0 ] , " restart " ) & & ! strcasecmp ( argv [ 1 ] , " all " ) ) {
sofia_glue_restart_all_profiles ( ) ;
return SWITCH_STATUS_SUCCESS ;
}
2010-02-06 03:38:24 +00:00
2009-10-23 16:03:42 +00:00
if ( zstr ( profile_name ) | | ! ( profile = sofia_glue_find_profile ( profile_name ) ) ) {
2007-04-29 01:16:49 +00:00
stream - > write_function ( stream , " Invalid Profile [%s] " , switch_str_nil ( profile_name ) ) ;
return SWITCH_STATUS_SUCCESS ;
}
2008-05-27 04:54:52 +00:00
2008-07-08 22:05:34 +00:00
if ( ! strcasecmp ( argv [ 1 ] , " killgw " ) ) {
sofia_gateway_t * gateway_ptr ;
2009-02-18 13:53:15 +00:00
if ( argc < 3 ) {
2008-07-08 22:05:34 +00:00
stream - > write_function ( stream , " -ERR missing gw name \n " ) ;
goto done ;
}
2010-03-31 15:02:50 -05:00
if ( ! strcasecmp ( argv [ 2 ] , " _all_ " ) ) {
sofia_glue_del_every_gateway ( profile ) ;
stream - > write_function ( stream , " +OK every gateway marked for deletion. \n " ) ;
2008-07-08 22:05:34 +00:00
} else {
2010-03-31 15:02:50 -05:00
if ( ( gateway_ptr = sofia_reg_find_gateway ( argv [ 2 ] ) ) ) {
sofia_glue_del_gateway ( gateway_ptr ) ;
sofia_reg_release_gateway ( gateway_ptr ) ;
stream - > write_function ( stream , " +OK gateway marked for deletion. \n " ) ;
} else {
stream - > write_function ( stream , " -ERR no such gateway. \n " ) ;
}
2008-07-08 22:05:34 +00:00
}
goto done ;
}
2008-07-21 16:40:28 +00:00
if ( ! strcasecmp ( argv [ 1 ] , " stun-auto-disable " ) ) {
if ( argv [ 2 ] ) {
int is_true = switch_true ( argv [ 2 ] ) ;
if ( is_true ) {
2009-02-09 17:56:38 +00:00
sofia_set_pflag ( profile , PFLAG_STUN_AUTO_DISABLE ) ;
2008-07-21 16:40:28 +00:00
} else {
2009-02-09 17:56:38 +00:00
sofia_clear_pflag ( profile , PFLAG_STUN_AUTO_DISABLE ) ;
2008-07-21 16:40:28 +00:00
}
}
2009-02-09 22:35:54 +00:00
stream - > write_function ( stream , " +OK stun-auto-disable=%s " , sofia_test_pflag ( profile , PFLAG_STUN_AUTO_DISABLE ) ? " true " : " false " ) ;
2010-02-06 03:38:24 +00:00
2008-07-21 16:40:28 +00:00
goto done ;
}
if ( ! strcasecmp ( argv [ 1 ] , " stun-enabled " ) ) {
if ( argv [ 2 ] ) {
int is_true = switch_true ( argv [ 2 ] ) ;
if ( is_true ) {
2009-02-09 17:56:38 +00:00
sofia_set_pflag ( profile , PFLAG_STUN_ENABLED ) ;
2008-07-21 16:40:28 +00:00
} else {
2009-02-09 17:56:38 +00:00
sofia_clear_pflag ( profile , PFLAG_STUN_ENABLED ) ;
2008-07-21 16:40:28 +00:00
}
}
2009-02-09 22:35:54 +00:00
stream - > write_function ( stream , " +OK stun-enabled=%s " , sofia_test_pflag ( profile , PFLAG_STUN_ENABLED ) ? " true " : " false " ) ;
2010-02-06 03:38:24 +00:00
2008-07-21 16:40:28 +00:00
goto done ;
}
2008-07-08 22:05:34 +00:00
if ( ! strcasecmp ( argv [ 1 ] , " rescan " ) ) {
2010-09-16 18:17:52 -05:00
switch_xml_reload ( & err ) ;
stream - > write_function ( stream , " Reload XML [%s] \n " , err ) ;
2010-02-06 03:38:24 +00:00
2008-07-08 22:05:34 +00:00
if ( reconfig_sofia ( profile ) = = SWITCH_STATUS_SUCCESS ) {
stream - > write_function ( stream , " +OK scan complete \n " ) ;
} else {
stream - > write_function ( stream , " -ERR cannot find config for profile %s \n " , profile - > name ) ;
}
goto done ;
}
2007-11-07 19:39:24 +00:00
if ( ! strcasecmp ( argv [ 1 ] , " flush_inbound_reg " ) ) {
2008-07-17 20:47:42 +00:00
int reboot = 0 ;
2008-03-25 22:06:48 +00:00
if ( argc > 2 ) {
2008-07-17 20:47:42 +00:00
if ( ! strcasecmp ( argv [ 2 ] , " reboot " ) ) {
reboot = 1 ;
argc = 2 ;
}
}
if ( argc > 2 ) {
if ( argc > 3 & & ! strcasecmp ( argv [ 3 ] , " reboot " ) ) {
reboot = 1 ;
}
sofia_reg_expire_call_id ( profile , argv [ 2 ] , reboot ) ;
stream - > write_function ( stream , " +OK %s all registrations matching specified call_id \n " , reboot ? " rebooting " : " flushing " ) ;
2008-03-25 22:06:48 +00:00
} else {
2008-07-17 20:47:42 +00:00
sofia_reg_check_expire ( profile , 0 , reboot ) ;
stream - > write_function ( stream , " +OK %s all registrations \n " , reboot ? " rebooting " : " flushing " ) ;
2008-03-25 22:06:48 +00:00
}
2007-11-07 19:39:24 +00:00
goto done ;
}
2007-05-10 16:15:07 +00:00
if ( ! strcasecmp ( argv [ 1 ] , " register " ) ) {
char * gname = argv [ 2 ] ;
sofia_gateway_t * gateway_ptr ;
2009-10-23 16:03:42 +00:00
if ( zstr ( gname ) ) {
2007-05-10 16:15:07 +00:00
stream - > write_function ( stream , " No gateway name provided! \n " ) ;
goto done ;
}
if ( ! strcasecmp ( gname , " all " ) ) {
for ( gateway_ptr = profile - > gateways ; gateway_ptr ; gateway_ptr = gateway_ptr - > next ) {
gateway_ptr - > retry = 0 ;
gateway_ptr - > state = REG_STATE_UNREGED ;
}
stream - > write_function ( stream , " +OK \n " ) ;
} else if ( ( gateway_ptr = sofia_reg_find_gateway ( gname ) ) ) {
gateway_ptr - > retry = 0 ;
gateway_ptr - > state = REG_STATE_UNREGED ;
stream - > write_function ( stream , " +OK \n " ) ;
sofia_reg_release_gateway ( gateway_ptr ) ;
} else {
stream - > write_function ( stream , " Invalid gateway! \n " ) ;
}
2008-05-27 04:54:52 +00:00
2007-05-10 16:15:07 +00:00
goto done ;
}
2007-09-18 17:31:36 +00:00
if ( ! strcasecmp ( argv [ 1 ] , " unregister " ) ) {
char * gname = argv [ 2 ] ;
sofia_gateway_t * gateway_ptr ;
2009-10-23 16:03:42 +00:00
if ( zstr ( gname ) ) {
2007-09-18 17:31:36 +00:00
stream - > write_function ( stream , " No gateway name provided! \n " ) ;
goto done ;
}
if ( ! strcasecmp ( gname , " all " ) ) {
for ( gateway_ptr = profile - > gateways ; gateway_ptr ; gateway_ptr = gateway_ptr - > next ) {
gateway_ptr - > retry = 0 ;
gateway_ptr - > state = REG_STATE_UNREGISTER ;
}
stream - > write_function ( stream , " +OK \n " ) ;
} else if ( ( gateway_ptr = sofia_reg_find_gateway ( gname ) ) ) {
gateway_ptr - > retry = 0 ;
gateway_ptr - > state = REG_STATE_UNREGISTER ;
stream - > write_function ( stream , " +OK \n " ) ;
sofia_reg_release_gateway ( gateway_ptr ) ;
} else {
stream - > write_function ( stream , " Invalid gateway! \n " ) ;
}
goto done ;
}
2007-05-03 01:55:25 +00:00
if ( ! strcasecmp ( argv [ 1 ] , " stop " ) | | ! strcasecmp ( argv [ 1 ] , " restart " ) ) {
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 ) - profile - > started ) ;
2007-05-03 01:55:25 +00:00
int remain = rsec - diff ;
if ( diff < rsec ) {
2008-05-27 04:54:52 +00:00
stream - > write_function ( stream , " Profile %s must be up for at least %d seconds to stop/restart. \n Please wait %d second%s \n " ,
2007-05-03 01:55:25 +00:00
profile - > name , rsec , remain , remain = = 1 ? " " : " s " ) ;
2007-05-02 23:32:45 +00:00
} else {
2007-05-03 01:55:25 +00:00
2010-09-16 18:17:52 -05:00
switch_xml_reload ( & err ) ;
stream - > write_function ( stream , " Reload XML [%s] \n " , err ) ;
2007-05-03 01:55:25 +00:00
if ( ! strcasecmp ( argv [ 1 ] , " stop " ) ) {
sofia_clear_pflag_locked ( profile , PFLAG_RUNNING ) ;
stream - > write_function ( stream , " stopping: %s " , profile - > name ) ;
} else {
sofia_set_pflag_locked ( profile , PFLAG_RESPAWN ) ;
sofia_clear_pflag_locked ( profile , PFLAG_RUNNING ) ;
stream - > write_function ( stream , " restarting: %s " , profile - > name ) ;
}
2007-05-02 23:32:45 +00:00
}
2007-11-07 19:39:24 +00:00
goto done ;
2007-05-01 00:26:41 +00:00
}
2010-02-06 03:38:24 +00:00
2009-03-04 18:54:43 +00:00
if ( ! strcasecmp ( argv [ 1 ] , " siptrace " ) ) {
if ( argc > 2 ) {
int value = switch_true ( argv [ 2 ] ) ;
nua_set_params ( profile - > nua , TPTAG_LOG ( value ) , TAG_END ( ) ) ;
stream - > write_function ( stream , " %s sip debugging on %s " , value ? " Enabled " : " Disabled " , profile - > name ) ;
} else {
stream - > write_function ( stream , " Usage: sofia profile <name> siptrace <on/off> \n " ) ;
}
goto done ;
}
2007-04-29 01:16:49 +00:00
2010-09-17 14:11:57 -05:00
if ( ! strcasecmp ( argv [ 1 ] , " gwlist " ) ) {
int up = 1 ;
if ( argc > 2 ) {
if ( ! strcasecmp ( argv [ 2 ] , " down " ) ) {
up = 0 ;
}
}
sofia_glue_gateway_list ( profile , stream , up ) ;
goto done ;
}
2007-11-07 19:39:24 +00:00
stream - > write_function ( stream , " -ERR Unknown command! \n " ) ;
2010-06-30 10:35:03 -05:00
done :
2007-04-29 01:16:49 +00:00
if ( profile ) {
2007-05-03 01:55:25 +00:00
sofia_glue_release_profile ( profile ) ;
2007-04-29 01:16:49 +00:00
}
return SWITCH_STATUS_SUCCESS ;
}
2007-10-18 01:02:01 +00:00
static int contact_callback ( void * pArg , int argc , char * * argv , char * * columnNames )
{
struct cb_helper * cb = ( struct cb_helper * ) pArg ;
char * contact ;
2010-04-26 05:26:54 -04:00
cb - > row_process + + ;
2010-02-06 03:38:24 +00:00
if ( ! zstr ( argv [ 0 ] ) & & ( contact = sofia_glue_get_url_from_contact ( argv [ 0 ] , 1 ) ) ) {
2008-11-14 00:20:22 +00:00
cb - > stream - > write_function ( cb - > stream , " %ssofia/%s/sip:%s, " , argv [ 2 ] , argv [ 1 ] , sofia_glue_strip_proto ( contact ) ) ;
2007-10-18 01:02:01 +00:00
free ( contact ) ;
}
return 0 ;
}
2010-04-26 05:24:05 -04:00
static int sql2str_callback ( void * pArg , int argc , char * * argv , char * * columnNames )
{
2010-06-23 13:22:52 -05:00
struct cb_helper_sql2str * cbt = ( struct cb_helper_sql2str * ) pArg ;
2010-04-26 05:24:05 -04:00
2010-06-23 13:22:52 -05:00
switch_copy_string ( cbt - > buf , argv [ 0 ] , cbt - > len ) ;
cbt - > matches + + ;
return 0 ;
2010-04-26 05:24:05 -04:00
}
2010-06-23 13:22:52 -05:00
SWITCH_STANDARD_API ( sofia_count_reg_function )
{
2010-04-26 05:24:05 -04:00
char * data ;
char * user = NULL ;
char * domain = NULL ;
char * concat = NULL ;
char * profile_name = NULL ;
char * p ;
char * reply = " -1 " ;
sofia_profile_t * profile = NULL ;
2010-06-23 13:22:52 -05:00
2010-04-26 05:24:05 -04:00
if ( ! cmd ) {
stream - > write_function ( stream , " %s " , " " ) ;
return SWITCH_STATUS_SUCCESS ;
}
data = strdup ( cmd ) ;
switch_assert ( data ) ;
if ( ( p = strchr ( data , ' / ' ) ) ) {
profile_name = data ;
* p + + = ' \0 ' ;
user = p ;
} else {
user = data ;
}
if ( ( domain = strchr ( user , ' @ ' ) ) ) {
* domain + + = ' \0 ' ;
2010-06-23 13:22:52 -05:00
if ( ( concat = strchr ( domain , ' / ' ) ) ) {
* concat + + = ' \0 ' ;
2010-04-26 05:24:05 -04:00
}
2010-06-23 13:22:52 -05:00
} else {
if ( ( concat = strchr ( user , ' / ' ) ) ) {
* concat + + = ' \0 ' ;
2010-04-26 05:24:05 -04:00
}
}
if ( ! profile_name & & domain ) {
profile_name = domain ;
}
if ( user & & profile_name ) {
char * sql ;
if ( ! ( profile = sofia_glue_find_profile ( profile_name ) ) ) {
profile_name = domain ;
domain = NULL ;
}
if ( ! profile & & profile_name ) {
profile = sofia_glue_find_profile ( profile_name ) ;
}
2007-10-18 01:02:01 +00:00
2010-04-26 05:24:05 -04:00
if ( profile ) {
struct cb_helper_sql2str cb ;
char reg_count [ 80 ] = " " ;
cb . buf = reg_count ;
cb . len = sizeof ( reg_count ) ;
if ( ! domain | | ! strchr ( domain , ' . ' ) ) {
domain = profile - > name ;
}
if ( zstr ( user ) ) {
sql = switch_mprintf ( " select count(*) "
2010-06-23 13:22:52 -05:00
" from sip_registrations where (sip_host='%q' or presence_hosts like '%%%q%%') " ,
( concat ! = NULL ) ? concat : " " , domain , domain ) ;
2010-04-26 05:24:05 -04:00
} else {
sql = switch_mprintf ( " select count(*) "
2010-06-23 13:22:52 -05:00
" from sip_registrations where (sip_user='%q' or dir_user='%q') and (sip_host='%q' or presence_hosts like '%%%q%%') " ,
( concat ! = NULL ) ? concat : " " , user , user , domain , domain ) ;
2010-04-26 05:24:05 -04:00
}
switch_assert ( sql ) ;
sofia_glue_execute_sql_callback ( profile , profile - > ireg_mutex , sql , sql2str_callback , & cb ) ;
switch_safe_free ( sql ) ;
if ( ! zstr ( reg_count ) ) {
stream - > write_function ( stream , " %s " , reg_count ) ;
} else {
stream - > write_function ( stream , " 0 " ) ;
}
reply = NULL ;
2010-06-23 13:22:52 -05:00
2010-04-26 05:24:05 -04:00
}
}
if ( reply ) {
stream - > write_function ( stream , " %s " , reply ) ;
}
switch_safe_free ( data ) ;
if ( profile ) {
sofia_glue_release_profile ( profile ) ;
}
return SWITCH_STATUS_SUCCESS ;
}
2010-06-23 13:22:52 -05:00
2007-10-18 01:02:01 +00:00
SWITCH_STANDARD_API ( sofia_contact_function )
{
char * data ;
char * user = NULL ;
char * domain = NULL ;
2008-06-06 14:52:41 +00:00
char * concat = NULL ;
2007-10-18 01:02:01 +00:00
char * profile_name = NULL ;
char * p ;
2008-02-11 21:20:43 +00:00
sofia_profile_t * profile = NULL ;
2008-03-14 19:07:24 +00:00
const char * exclude_contact = NULL ;
2008-08-11 16:12:55 +00:00
char * reply = " error/facility_not_subscribed " ;
2010-02-06 03:38:24 +00:00
2007-10-18 01:02:01 +00:00
if ( ! cmd ) {
stream - > write_function ( stream , " %s " , " " ) ;
return SWITCH_STATUS_SUCCESS ;
}
2008-03-14 19:07:24 +00:00
if ( session ) {
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
2008-03-14 19:09:15 +00:00
exclude_contact = switch_channel_get_variable ( channel , " sip_exclude_contact " ) ;
2008-03-14 19:07:24 +00:00
}
2007-10-18 01:02:01 +00:00
data = strdup ( cmd ) ;
2007-12-12 23:21:45 +00:00
switch_assert ( data ) ;
2007-10-18 01:02:01 +00:00
if ( ( p = strchr ( data , ' / ' ) ) ) {
profile_name = data ;
* p + + = ' \0 ' ;
user = p ;
} else {
user = data ;
}
if ( ( domain = strchr ( user , ' @ ' ) ) ) {
* domain + + = ' \0 ' ;
2010-02-06 03:38:24 +00:00
if ( ( concat = strchr ( domain , ' / ' ) ) ) {
* concat + + = ' \0 ' ;
2008-06-06 14:52:41 +00:00
}
2010-02-06 03:38:24 +00:00
} else {
if ( ( concat = strchr ( user , ' / ' ) ) ) {
* concat + + = ' \0 ' ;
2008-06-06 14:52:41 +00:00
}
2007-10-18 01:02:01 +00:00
}
2008-05-27 04:54:52 +00:00
2007-10-18 01:02:01 +00:00
if ( ! profile_name & & domain ) {
profile_name = domain ;
}
if ( user & & profile_name ) {
char * sql ;
2008-05-27 04:54:52 +00:00
2007-10-18 01:02:01 +00:00
if ( ! ( profile = sofia_glue_find_profile ( profile_name ) ) ) {
profile_name = domain ;
domain = NULL ;
}
if ( ! profile & & profile_name ) {
profile = sofia_glue_find_profile ( profile_name ) ;
}
if ( profile ) {
struct cb_helper cb ;
switch_stream_handle_t mystream = { 0 } ;
2008-05-27 04:54:52 +00:00
2010-04-26 05:26:54 -04:00
cb . row_process = 0 ;
2010-02-23 19:13:12 +00:00
if ( ! domain | | ( ! strchr ( domain , ' . ' ) & & strcmp ( profile_name , domain ) ) ) {
2007-10-18 01:02:01 +00:00
domain = profile - > name ;
}
SWITCH_STANDARD_STREAM ( mystream ) ;
2008-05-22 14:41:11 +00:00
switch_assert ( mystream . data ) ;
2007-10-18 01:02:01 +00:00
cb . profile = profile ;
cb . stream = & mystream ;
2008-05-27 04:54:52 +00:00
2008-03-14 19:07:24 +00:00
if ( exclude_contact ) {
2008-09-18 00:01:03 +00:00
sql = switch_mprintf ( " select contact, profile_name, '%q' "
" from sip_registrations where sip_user='%q' and (sip_host='%q' or presence_hosts like '%%%q%%') "
2010-02-06 03:38:24 +00:00
" and contact not like '%%%s%%' " , ( concat ! = NULL ) ? concat : " " , user , domain , domain , exclude_contact ) ;
2008-03-14 19:07:24 +00:00
} else {
2008-09-18 00:01:03 +00:00
sql = switch_mprintf ( " select contact, profile_name, '%q' "
2010-02-06 03:38:24 +00:00
" from sip_registrations where sip_user='%q' and (sip_host='%q' or presence_hosts like '%%%q%%') " ,
( concat ! = NULL ) ? concat : " " , user , domain , domain ) ;
2008-03-14 19:07:24 +00:00
}
2007-12-12 23:21:45 +00:00
switch_assert ( sql ) ;
2009-11-12 03:52:07 +00:00
sofia_glue_execute_sql_callback ( profile , profile - > ireg_mutex , sql , contact_callback , & cb ) ;
2007-10-18 01:02:01 +00:00
switch_safe_free ( sql ) ;
2008-05-22 14:41:11 +00:00
reply = ( char * ) mystream . data ;
2009-10-23 16:03:42 +00:00
if ( ! zstr ( reply ) & & end_of ( reply ) = = ' , ' ) {
2008-05-22 14:41:11 +00:00
end_of ( reply ) = ' \0 ' ;
2007-10-18 01:02:01 +00:00
}
2008-08-11 16:12:55 +00:00
2009-10-23 16:03:42 +00:00
if ( zstr ( reply ) ) {
2008-08-11 16:12:55 +00:00
reply = " error/user_not_registered " ;
}
2008-05-22 14:41:11 +00:00
stream - > write_function ( stream , " %s " , reply ) ;
reply = NULL ;
2010-02-06 03:38:24 +00:00
2007-10-18 01:02:01 +00:00
switch_safe_free ( mystream . data ) ;
}
}
2008-05-27 04:54:52 +00:00
2008-05-22 14:41:11 +00:00
if ( reply ) {
stream - > write_function ( stream , " %s " , reply ) ;
}
2007-10-18 01:02:01 +00:00
switch_safe_free ( data ) ;
2008-02-11 21:20:43 +00:00
if ( profile ) {
sofia_glue_release_profile ( profile ) ;
}
2007-10-18 01:02:01 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2009-07-29 22:48:43 +00:00
/* <gateway_name> [ivar|ovar|var] <name> */
SWITCH_STANDARD_API ( sofia_gateway_data_function )
{
char * argv [ 4 ] ;
char * mydata ;
int argc ;
sofia_gateway_t * gateway ;
char * gwname , * param , * varname ;
const char * val = NULL ;
2010-02-06 03:38:24 +00:00
2009-10-23 16:03:42 +00:00
if ( zstr ( cmd ) ) {
2009-09-07 23:13:45 +00:00
stream - > write_function ( stream , " -ERR Parameter missing \n " ) ;
return SWITCH_STATUS_SUCCESS ;
}
2009-07-29 22:48:43 +00:00
if ( ! ( mydata = strdup ( cmd ) ) ) {
return SWITCH_STATUS_FALSE ;
}
2010-02-06 03:38:24 +00:00
2009-07-29 22:48:43 +00:00
if ( ! ( argc = switch_separate_string ( mydata , ' ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ) | | ! argv [ 0 ] ) {
goto end ;
}
2010-02-06 03:38:24 +00:00
2009-07-29 22:48:43 +00:00
gwname = argv [ 0 ] ;
param = argv [ 1 ] ;
varname = argv [ 2 ] ;
2010-02-06 03:38:24 +00:00
2009-10-23 16:03:42 +00:00
if ( zstr ( gwname ) | | zstr ( param ) | | zstr ( varname ) ) {
2009-07-29 22:48:43 +00:00
goto end ;
}
2010-02-06 03:38:24 +00:00
2009-07-29 22:48:43 +00:00
if ( ! ( gateway = sofia_reg_find_gateway ( gwname ) ) ) {
goto end ;
}
2010-02-06 03:38:24 +00:00
2009-07-29 22:48:43 +00:00
if ( ! strcasecmp ( param , " ivar " ) & & gateway - > ib_vars & & ( val = switch_event_get_header ( gateway - > ib_vars , varname ) ) ) {
stream - > write_function ( stream , " %s " , val ) ;
} else if ( ! strcasecmp ( param , " ovar " ) & & gateway - > ob_vars & & ( val = switch_event_get_header ( gateway - > ob_vars , varname ) ) ) {
2010-02-06 03:38:24 +00:00
stream - > write_function ( stream , " %s " , val ) ;
2009-07-29 22:48:43 +00:00
} else if ( ! strcasecmp ( param , " var " ) ) {
if ( gateway - > ib_vars & & ( val = switch_event_get_header ( gateway - > ib_vars , varname ) ) ) {
stream - > write_function ( stream , " %s " , val ) ;
} else if ( gateway - > ob_vars & & ( val = switch_event_get_header ( gateway - > ob_vars , varname ) ) ) {
stream - > write_function ( stream , " %s " , val ) ;
}
}
2010-02-06 03:38:24 +00:00
2009-07-29 22:48:43 +00:00
sofia_reg_release_gateway ( gateway ) ;
2010-02-06 03:38:24 +00:00
2010-06-30 10:35:03 -05:00
end :
2009-07-29 22:48:43 +00:00
switch_safe_free ( mydata ) ;
return SWITCH_STATUS_SUCCESS ;
}
2007-05-12 21:36:15 +00:00
SWITCH_STANDARD_API ( sofia_function )
2007-04-29 01:16:49 +00:00
{
char * argv [ 1024 ] = { 0 } ;
int argc = 0 ;
char * mycmd = NULL ;
switch_status_t status = SWITCH_STATUS_SUCCESS ;
sofia_command_t func = NULL ;
int lead = 1 ;
const char * usage_string = " USAGE: \n "
" -------------------------------------------------------------------------------- \n "
" sofia help \n "
2010-09-16 18:17:52 -05:00
" sofia profile <profile_name> [[start|stop|restart|rescan]| "
2010-06-23 13:22:52 -05:00
" flush_inbound_reg [<call_id>] [reboot]| "
" [register|unregister] [<gateway name>|all]| "
" killgw <gateway name>| "
" [stun-auto-disable|stun-enabled] [true|false]]| "
" siptrace [on|off] \n "
2010-01-12 16:13:03 +00:00
" sofia status|xmlstatus profile <name> [ reg <contact str> ] | [ pres <pres str> ] | [ user <user@domain> ] \n "
" sofia status|xmlstatus gateway <name> \n "
2009-03-04 18:54:43 +00:00
" sofia loglevel <all|default|tport|iptsec|nea|nta|nth_client|nth_server|nua|soa|sresolv|stun> [0-9] \n "
2010-02-10 14:49:32 +00:00
" sofia tracelevel <console|alert|crit|err|warning|notice|info|debug> \n "
2010-09-20 16:55:09 -05:00
" sofa global siptrace [on|off] \n "
2009-03-04 18:54:43 +00:00
" -------------------------------------------------------------------------------- \n " ;
2008-05-27 04:54:52 +00:00
2007-05-12 21:36:15 +00:00
if ( session ) {
2007-04-29 01:16:49 +00:00
return SWITCH_STATUS_FALSE ;
}
2008-05-27 04:54:52 +00:00
2009-10-23 16:03:42 +00:00
if ( zstr ( cmd ) ) {
2007-04-29 01:16:49 +00:00
stream - > write_function ( stream , " %s " , usage_string ) ;
goto done ;
}
if ( ! ( mycmd = strdup ( cmd ) ) ) {
status = SWITCH_STATUS_MEMERR ;
goto done ;
}
2007-12-13 04:01:29 +00:00
if ( ! ( argc = switch_separate_string ( mycmd , ' ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ) | | ! argv [ 0 ] ) {
2007-04-29 01:16:49 +00:00
stream - > write_function ( stream , " %s " , usage_string ) ;
goto done ;
}
2008-05-27 04:54:52 +00:00
2007-04-29 01:16:49 +00:00
if ( ! strcasecmp ( argv [ 0 ] , " profile " ) ) {
func = cmd_profile ;
} else if ( ! strcasecmp ( argv [ 0 ] , " status " ) ) {
func = cmd_status ;
2008-12-03 15:44:31 +00:00
} else if ( ! strcasecmp ( argv [ 0 ] , " xmlstatus " ) ) {
func = cmd_xml_status ;
2009-06-09 19:52:07 +00:00
} else if ( ! strcasecmp ( argv [ 0 ] , " tracelevel " ) ) {
if ( argv [ 1 ] ) {
mod_sofia_globals . tracelevel = switch_log_str2level ( argv [ 1 ] ) ;
}
stream - > write_function ( stream , " +OK tracelevel is %s " , switch_log_level2str ( mod_sofia_globals . tracelevel ) ) ;
2010-02-06 03:38:24 +00:00
goto done ;
2007-12-13 02:42:00 +00:00
} else if ( ! strcasecmp ( argv [ 0 ] , " loglevel " ) ) {
2009-03-04 18:54:43 +00:00
if ( argc > 2 & & argv [ 2 ] & & switch_is_number ( argv [ 2 ] ) ) {
int level = atoi ( argv [ 2 ] ) ;
if ( sofia_set_loglevel ( argv [ 1 ] , level ) = = SWITCH_STATUS_SUCCESS ) {
stream - > write_function ( stream , " Sofia log level for component [%s] has been set to [%d] " , argv [ 1 ] , level ) ;
} else {
stream - > write_function ( stream , " %s " , usage_string ) ;
}
} else if ( argc > 1 & & argv [ 1 ] ) {
int level = sofia_get_loglevel ( argv [ 1 ] ) ;
if ( level > = 0 ) {
stream - > write_function ( stream , " Sofia-sip loglevel for [%s] is [%d] " , argv [ 1 ] , level ) ;
2007-12-13 02:42:00 +00:00
} else {
stream - > write_function ( stream , " %s " , usage_string ) ;
}
} else {
stream - > write_function ( stream , " %s " , usage_string ) ;
}
goto done ;
2007-04-29 01:16:49 +00:00
} else if ( ! strcasecmp ( argv [ 0 ] , " help " ) ) {
stream - > write_function ( stream , " %s " , usage_string ) ;
2010-02-06 03:38:24 +00:00
goto done ;
2010-09-20 16:55:09 -05:00
} else if ( ! strcasecmp ( argv [ 0 ] , " global " ) ) {
int on = - 1 ;
if ( argc > 1 ) {
if ( ! strcasecmp ( argv [ 1 ] , " siptrace " ) ) {
if ( argc > 2 ) {
on = switch_true ( argv [ 2 ] ) ;
}
}
}
if ( on ! = - 1 ) {
sofia_glue_global_siptrace ( on ) ;
stream - > write_function ( stream , " +OK Global siptrace %s " , on ? " on " : " off " ) ;
} else {
stream - > write_function ( stream , " -ERR Usage: siptrace on|off " ) ;
}
goto done ;
2010-02-06 03:38:24 +00:00
} else if ( ! strcasecmp ( argv [ 0 ] , " recover " ) ) {
if ( argv [ 1 ] & & ! strcasecmp ( argv [ 1 ] , " flush " ) ) {
sofia_glue_recover ( SWITCH_TRUE ) ;
stream - > write_function ( stream , " Flushing recovery database. \n " ) ;
} else {
2010-08-26 14:50:50 -04:00
int x = sofia_glue_recover ( SWITCH_FALSE ) ;
2010-08-18 15:33:18 -05:00
2010-02-06 03:38:24 +00:00
if ( x ) {
stream - > write_function ( stream , " Recovered %d call(s) \n " , x ) ;
} else {
stream - > write_function ( stream , " No calls to recover. \n " ) ;
}
}
2007-04-29 01:16:49 +00:00
goto done ;
}
if ( func ) {
status = func ( & argv [ lead ] , argc - lead , stream ) ;
} else {
stream - > write_function ( stream , " Unknown Command [%s] \n " , argv [ 0 ] ) ;
}
2010-06-30 10:35:03 -05:00
done :
2007-04-29 01:16:49 +00:00
switch_safe_free ( mycmd ) ;
return status ;
}
2007-10-29 18:10:06 +00:00
switch_io_routines_t sofia_io_routines = {
2007-03-31 19:01:33 +00:00
/*.outgoing_channel */ sofia_outgoing_channel ,
/*.read_frame */ sofia_read_frame ,
/*.write_frame */ sofia_write_frame ,
/*.kill_channel */ sofia_kill_channel ,
/*.send_dtmf */ sofia_send_dtmf ,
/*.receive_message */ sofia_receive_message ,
2007-04-19 21:40:50 +00:00
/*.receive_event */ sofia_receive_event ,
2008-05-27 04:54:52 +00:00
/*.state_change */ NULL ,
/*.read_video_frame */ sofia_read_video_frame ,
/*.write_video_frame */ sofia_write_video_frame
2007-03-31 19:01:33 +00:00
} ;
2007-10-29 18:10:06 +00:00
switch_state_handler_table_t sofia_event_handlers = {
2007-03-31 19:01:33 +00:00
/*.on_init */ sofia_on_init ,
2008-05-05 15:30:55 +00:00
/*.on_routing */ sofia_on_routing ,
2007-03-31 19:01:33 +00:00
/*.on_execute */ sofia_on_execute ,
/*.on_hangup */ sofia_on_hangup ,
2008-05-05 15:30:55 +00:00
/*.on_exchange_media */ sofia_on_exchange_media ,
/*.on_soft_execute */ sofia_on_soft_execute ,
/*.on_consume_media */ NULL ,
2008-05-27 04:54:52 +00:00
/*.on_hibernate */ sofia_on_hibernate ,
2009-04-10 17:43:18 +00:00
/*.on_reset */ sofia_on_reset ,
2010-02-06 03:38:24 +00:00
/*.on_park */ NULL ,
/*.on_reporting */ NULL ,
/*.on_destroy */ sofia_on_destroy
2007-03-31 19:01:33 +00:00
} ;
2006-10-20 22:11:26 +00:00
2007-03-31 19:01:33 +00:00
static switch_status_t sofia_manage ( char * relative_oid , switch_management_action_t action , char * data , switch_size_t datalen )
{
return SWITCH_STATUS_SUCCESS ;
}
2006-10-20 06:17:00 +00:00
2008-05-15 19:29:35 +00:00
static switch_call_cause_t sofia_outgoing_channel ( switch_core_session_t * session , switch_event_t * var_event ,
2007-03-31 19:01:33 +00:00
switch_caller_profile_t * outbound_profile , switch_core_session_t * * new_session ,
2009-11-20 02:17:08 +00:00
switch_memory_pool_t * * pool , switch_originate_flag_t flags , switch_call_cause_t * cancel_cause )
2006-10-12 00:59:09 +00:00
{
2007-03-31 19:01:33 +00:00
switch_call_cause_t cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ;
2007-12-21 04:29:41 +00:00
switch_core_session_t * nsession = NULL ;
2010-02-06 03:38:24 +00:00
char * data , * profile_name , * dest ; //, *dest_num = NULL;
2007-04-29 01:16:49 +00:00
sofia_profile_t * profile = NULL ;
2007-03-31 19:01:33 +00:00
switch_caller_profile_t * caller_profile = NULL ;
private_object_t * tech_pvt = NULL ;
switch_channel_t * nchannel ;
2009-11-15 02:16:10 +00:00
char * host = NULL , * dest_to = NULL ;
2008-12-31 01:08:51 +00:00
const char * hval = NULL ;
2009-11-17 00:12:54 +00:00
char * not_const = NULL ;
2010-06-04 19:37:04 -05:00
int cid_locked = 0 ;
2010-02-06 03:38:24 +00:00
2007-03-31 19:01:33 +00:00
* new_session = NULL ;
2006-10-20 06:17:00 +00:00
2009-10-23 16:17:05 +00:00
if ( ! outbound_profile | | zstr ( outbound_profile - > destination_number ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Invalid Destination \n " ) ;
goto error ;
}
2010-08-26 12:19:49 -05:00
if ( ! ( nsession = switch_core_session_request ( sofia_endpoint_interface , SWITCH_CALL_DIRECTION_OUTBOUND , flags , pool ) ) ) {
2007-03-31 19:01:33 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Error Creating Session \n " ) ;
2007-12-21 04:29:41 +00:00
goto error ;
2007-03-29 22:31:56 +00:00
}
2006-10-20 06:17:00 +00:00
2007-03-31 19:01:33 +00:00
if ( ! ( tech_pvt = ( struct private_object * ) switch_core_session_alloc ( nsession , sizeof ( * tech_pvt ) ) ) ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_CRIT , " Error Creating Session \n " ) ;
2007-12-21 04:29:41 +00:00
goto error ;
2006-10-20 06:17:00 +00:00
}
2007-04-13 22:15:58 +00:00
switch_mutex_init ( & tech_pvt - > flag_mutex , SWITCH_MUTEX_NESTED , switch_core_session_get_pool ( nsession ) ) ;
2008-10-30 22:40:39 +00:00
switch_mutex_init ( & tech_pvt - > sofia_mutex , SWITCH_MUTEX_NESTED , switch_core_session_get_pool ( nsession ) ) ;
2006-10-18 22:57:35 +00:00
2007-03-31 19:01:33 +00:00
data = switch_core_session_strdup ( nsession , outbound_profile - > destination_number ) ;
2008-10-29 18:00:27 +00:00
if ( ( dest_to = strchr ( data , ' ^ ' ) ) ) {
* dest_to + + = ' \0 ' ;
}
2007-03-31 19:01:33 +00:00
profile_name = data ;
2006-10-20 22:11:26 +00:00
2007-12-04 13:48:20 +00:00
nchannel = switch_core_session_get_channel ( nsession ) ;
2009-03-02 19:43:17 +00:00
if ( ( hval = switch_event_get_header ( var_event , " sip_invite_to_uri " ) ) ) {
dest_to = switch_core_session_strdup ( nsession , hval ) ;
}
2009-11-02 15:41:01 +00:00
if ( ! strncasecmp ( profile_name , " gateway/ " , 8 ) ) {
2008-01-17 17:37:49 +00:00
char * gw , * params ;
2007-04-29 01:16:49 +00:00
sofia_gateway_t * gateway_ptr = NULL ;
2006-10-20 06:17:00 +00:00
2007-03-31 19:01:33 +00:00
if ( ! ( gw = strchr ( profile_name , ' / ' ) ) ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Invalid URL \n " ) ;
2007-03-31 19:01:33 +00:00
cause = SWITCH_CAUSE_INVALID_NUMBER_FORMAT ;
2007-12-21 04:29:41 +00:00
goto error ;
2007-03-31 19:01:33 +00:00
}
2006-10-18 22:57:35 +00:00
2007-03-31 19:01:33 +00:00
* gw + + = ' \0 ' ;
2006-10-18 22:57:35 +00:00
2007-03-31 19:01:33 +00:00
if ( ! ( dest = strchr ( gw , ' / ' ) ) ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Invalid URL \n " ) ;
2007-03-31 19:01:33 +00:00
cause = SWITCH_CAUSE_INVALID_NUMBER_FORMAT ;
2007-12-21 04:29:41 +00:00
goto error ;
2006-10-18 22:57:35 +00:00
}
2007-03-31 19:01:33 +00:00
* dest + + = ' \0 ' ;
2006-10-15 05:10:34 +00:00
2007-03-31 19:01:33 +00:00
if ( ! ( gateway_ptr = sofia_reg_find_gateway ( gw ) ) ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Invalid Gateway \n " ) ;
2007-03-31 19:01:33 +00:00
cause = SWITCH_CAUSE_INVALID_NUMBER_FORMAT ;
2007-12-21 04:29:41 +00:00
goto error ;
2006-10-15 05:10:34 +00:00
}
2007-03-31 19:01:33 +00:00
2008-04-30 22:09:54 +00:00
if ( gateway_ptr - > status ! = SOFIA_GATEWAY_UP ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Gateway is down! \n " ) ;
2008-04-30 22:09:54 +00:00
cause = SWITCH_CAUSE_NETWORK_OUT_OF_ORDER ;
2010-04-26 04:14:57 -04:00
gateway_ptr - > ob_failed_calls + + ;
2008-04-30 22:09:54 +00:00
sofia_reg_release_gateway ( gateway_ptr ) ;
gateway_ptr = NULL ;
goto error ;
}
2008-01-17 17:37:49 +00:00
tech_pvt - > transport = gateway_ptr - > register_transport ;
2010-06-04 19:37:04 -05:00
tech_pvt - > cid_type = gateway_ptr - > cid_type ;
cid_locked = 1 ;
2009-10-06 15:30:30 +00:00
2008-01-17 17:37:49 +00:00
/*
* Handle params , strip them off the destination and add them to the
* invite contact .
*
* TODO :
2008-05-27 04:54:52 +00:00
* - Add parameters back to destination url ?
2008-01-17 17:37:49 +00:00
*/
if ( ( params = strchr ( dest , ' ; ' ) ) ) {
char * tp_param ;
* params + + = ' \0 ' ;
2008-05-27 04:54:52 +00:00
if ( ( tp_param = ( char * ) switch_stristr ( " port= " , params ) ) ) {
2008-01-17 17:37:49 +00:00
tp_param + = 5 ;
tech_pvt - > transport = sofia_glue_str2transport ( tp_param ) ;
if ( tech_pvt - > transport = = SOFIA_TRANSPORT_UNKNOWN ) {
cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ;
2010-04-26 04:14:57 -04:00
gateway_ptr - > ob_failed_calls + + ;
2008-01-17 17:37:49 +00:00
goto error ;
}
}
}
if ( tech_pvt - > transport ! = gateway_ptr - > register_transport ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR ,
2008-05-27 04:54:52 +00:00
" You are trying to use a different transport type for this gateway (overriding the register-transport), this is unsupported! \n " ) ;
2008-01-17 17:37:49 +00:00
cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ;
goto error ;
}
2007-03-31 19:01:33 +00:00
profile = gateway_ptr - > profile ;
2007-12-04 13:48:20 +00:00
tech_pvt - > gateway_name = switch_core_session_strdup ( nsession , gateway_ptr - > name ) ;
switch_channel_set_variable ( nchannel , " sip_gateway_name " , gateway_ptr - > name ) ;
2008-01-17 17:37:49 +00:00
2009-02-09 17:56:38 +00:00
if ( ! sofia_test_flag ( gateway_ptr , REG_FLAG_CALLERID ) ) {
2007-04-18 20:21:53 +00:00
tech_pvt - > gateway_from_str = switch_core_session_strdup ( nsession , gateway_ptr - > register_from ) ;
}
2008-01-17 17:37:49 +00:00
2007-03-31 19:01:33 +00:00
if ( ! strchr ( dest , ' @ ' ) ) {
2009-07-27 02:30:15 +00:00
tech_pvt - > dest = switch_core_session_sprintf ( nsession , " sip:%s@%s " , dest , sofia_glue_strip_proto ( gateway_ptr - > register_proxy ) ) ;
2006-10-20 06:17:00 +00:00
} else {
2007-03-31 19:01:33 +00:00
tech_pvt - > dest = switch_core_session_sprintf ( nsession , " sip:%s " , dest ) ;
2006-10-20 06:17:00 +00:00
}
2008-01-17 17:37:49 +00:00
2009-10-07 02:49:23 +00:00
if ( ( host = switch_core_session_strdup ( nsession , tech_pvt - > dest ) ) ) {
2009-11-05 17:22:15 +00:00
char * pp = strchr ( host , ' @ ' ) ;
if ( pp ) {
2010-02-06 03:38:24 +00:00
host = pp + 1 ;
2009-10-06 15:30:30 +00:00
} else {
host = NULL ;
dest_to = NULL ;
}
}
2008-01-17 17:37:49 +00:00
if ( params ) {
tech_pvt - > invite_contact = switch_core_session_sprintf ( nsession , " %s;%s " , gateway_ptr - > register_contact , params ) ;
} else {
tech_pvt - > invite_contact = switch_core_session_strdup ( nsession , gateway_ptr - > register_contact ) ;
}
2010-02-06 03:38:24 +00:00
2009-01-23 20:33:30 +00:00
gateway_ptr - > ob_calls + + ;
2010-02-06 03:38:24 +00:00
2009-10-23 16:03:42 +00:00
if ( ! zstr ( gateway_ptr - > from_domain ) & & ! switch_channel_get_variable ( nchannel , " sip_invite_domain " ) ) {
2009-07-14 15:00:26 +00:00
switch_channel_set_variable ( nchannel , " sip_invite_domain " , gateway_ptr - > from_domain ) ;
}
2008-10-21 22:40:20 +00:00
2009-10-23 16:03:42 +00:00
if ( ! zstr ( gateway_ptr - > outbound_sticky_proxy ) & & ! switch_channel_get_variable ( nchannel , " sip_route_uri " ) ) {
2009-07-16 00:46:35 +00:00
switch_channel_set_variable ( nchannel , " sip_route_uri " , gateway_ptr - > outbound_sticky_proxy ) ;
}
2010-02-06 03:38:24 +00:00
2009-01-23 20:33:30 +00:00
if ( gateway_ptr - > ob_vars ) {
2008-10-21 22:40:20 +00:00
switch_event_header_t * hp ;
2010-02-06 03:38:24 +00:00
for ( hp = gateway_ptr - > ob_vars - > headers ; hp ; hp = hp - > next ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " %s setting variable [%s]=[%s] \n " ,
2008-10-21 22:40:20 +00:00
switch_channel_get_name ( nchannel ) , hp - > name , hp - > value ) ;
switch_channel_set_variable ( nchannel , hp - > name , hp - > value ) ;
}
}
2006-10-15 05:10:34 +00:00
} else {
2007-03-31 19:01:33 +00:00
if ( ! ( dest = strchr ( profile_name , ' / ' ) ) ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Invalid URL \n " ) ;
2007-03-31 19:01:33 +00:00
cause = SWITCH_CAUSE_INVALID_NUMBER_FORMAT ;
2007-12-21 04:29:41 +00:00
goto error ;
2007-03-31 19:01:33 +00:00
}
* dest + + = ' \0 ' ;
2006-10-15 05:10:34 +00:00
2007-03-31 19:01:33 +00:00
if ( ! ( profile = sofia_glue_find_profile ( profile_name ) ) ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Invalid Profile \n " ) ;
2007-03-31 19:01:33 +00:00
cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ;
2007-12-21 04:29:41 +00:00
goto error ;
2007-03-31 19:01:33 +00:00
}
2006-10-15 05:10:34 +00:00
2008-01-21 23:52:34 +00:00
if ( profile - > domain_name & & profile - > domain_name ! = profile - > name ) {
profile_name = profile - > domain_name ;
}
2008-09-11 23:40:57 +00:00
if ( ! strncasecmp ( dest , " sip: " , 4 ) | | ! strncasecmp ( dest , " sips: " , 5 ) ) {
2010-08-18 14:58:14 -05:00
char * c ;
2008-09-11 23:40:57 +00:00
tech_pvt - > dest = switch_core_session_strdup ( nsession , dest ) ;
2010-08-18 14:58:14 -05:00
if ( ( c = strchr ( tech_pvt - > dest , ' : ' ) ) ) {
c + + ;
tech_pvt - > e_dest = switch_core_session_strdup ( nsession , c ) ;
}
2008-09-11 23:40:57 +00:00
} else if ( ( host = strchr ( dest , ' % ' ) ) ) {
2009-06-16 16:06:37 +00:00
char buf [ 1024 ] ;
2007-03-31 19:01:33 +00:00
* host = ' @ ' ;
tech_pvt - > e_dest = switch_core_session_strdup ( nsession , dest ) ;
* host + + = ' \0 ' ;
if ( sofia_reg_find_reg_url ( profile , dest , host , buf , sizeof ( buf ) ) ) {
tech_pvt - > dest = switch_core_session_strdup ( nsession , buf ) ;
2007-11-30 21:02:41 +00:00
tech_pvt - > local_url = switch_core_session_sprintf ( nsession , " %s@%s " , dest , host ) ;
2007-03-31 19:01:33 +00:00
} else {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING , " Cannot locate registered user %s@%s \n " , dest , host ) ;
2008-08-11 16:12:55 +00:00
cause = SWITCH_CAUSE_USER_NOT_REGISTERED ;
2007-12-21 04:29:41 +00:00
goto error ;
2007-03-29 22:31:56 +00:00
}
2008-02-11 20:47:20 +00:00
} else if ( ! ( host = strchr ( dest , ' @ ' ) ) ) {
2009-06-16 16:06:37 +00:00
char buf [ 1024 ] ;
2007-03-31 19:01:33 +00:00
tech_pvt - > e_dest = switch_core_session_strdup ( nsession , dest ) ;
2008-01-21 23:52:34 +00:00
if ( sofia_reg_find_reg_url ( profile , dest , profile_name , buf , sizeof ( buf ) ) ) {
2007-03-31 19:01:33 +00:00
tech_pvt - > dest = switch_core_session_strdup ( nsession , buf ) ;
2008-01-21 23:52:34 +00:00
tech_pvt - > local_url = switch_core_session_sprintf ( nsession , " %s@%s " , dest , profile_name ) ;
2008-02-11 20:47:20 +00:00
host = profile_name ;
2007-03-31 19:01:33 +00:00
} else {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING , " Cannot locate registered user %s@%s \n " , dest , profile_name ) ;
2008-08-11 16:12:55 +00:00
cause = SWITCH_CAUSE_USER_NOT_REGISTERED ;
2007-12-21 04:29:41 +00:00
goto error ;
2007-03-29 22:31:56 +00:00
}
2007-03-31 19:01:33 +00:00
} else {
2010-03-25 13:48:26 +00:00
host + + ;
2007-03-31 19:01:33 +00:00
tech_pvt - > dest = switch_core_session_alloc ( nsession , strlen ( dest ) + 5 ) ;
2010-08-18 14:58:14 -05:00
tech_pvt - > e_dest = switch_core_session_strdup ( nsession , dest ) ;
2007-12-12 21:53:32 +00:00
switch_snprintf ( tech_pvt - > dest , strlen ( dest ) + 5 , " sip:%s " , dest ) ;
2007-03-29 22:31:56 +00:00
}
2006-10-12 00:59:09 +00:00
}
2010-03-23 03:59:49 +00:00
switch_channel_set_variable_printf ( nchannel , " sip_local_network_addr " , " %s " , profile - > extsipip ? profile - > extsipip : profile - > sipip ) ;
2009-11-23 19:57:14 +00:00
switch_channel_set_variable ( nchannel , " sip_profile_name " , profile_name ) ;
2010-06-02 01:09:54 +02:00
switch_split_user_domain ( switch_core_session_strdup ( nsession , tech_pvt - > dest ) , NULL , & tech_pvt - > remote_ip ) ;
2009-06-03 21:08:34 +00:00
2008-02-11 20:47:20 +00:00
if ( dest_to ) {
if ( strchr ( dest_to , ' @ ' ) ) {
tech_pvt - > dest_to = switch_core_session_sprintf ( nsession , " sip:%s " , dest_to ) ;
} else {
2009-11-03 18:26:09 +00:00
tech_pvt - > dest_to = switch_core_session_sprintf ( nsession , " sip:%s@%s " , dest_to , host ? host : profile - > sipip ) ;
2008-02-11 20:47:20 +00:00
}
}
2008-05-27 04:54:52 +00:00
2007-03-31 19:01:33 +00:00
if ( ! tech_pvt - > dest_to ) {
tech_pvt - > dest_to = tech_pvt - > dest ;
}
2006-10-12 00:59:09 +00:00
2008-10-23 04:48:03 +00:00
sofia_glue_attach_private ( nsession , profile , tech_pvt , dest ) ;
2007-11-30 21:02:41 +00:00
if ( tech_pvt - > local_url ) {
switch_channel_set_variable ( nchannel , " sip_local_url " , tech_pvt - > local_url ) ;
2008-09-18 00:01:03 +00:00
if ( profile - > pres_type ) {
2007-12-18 01:12:50 +00:00
switch_channel_set_variable ( nchannel , " presence_id " , tech_pvt - > local_url ) ;
}
2007-11-30 21:02:41 +00:00
}
switch_channel_set_variable ( nchannel , " sip_destination_url " , tech_pvt - > dest ) ;
2009-11-15 02:16:10 +00:00
#if 0
2009-10-07 22:35:21 +00:00
dest_num = switch_core_session_strdup ( nsession , dest ) ;
2009-11-04 16:46:17 +00:00
if ( ( p = strchr ( dest_num , ' @ ' ) ) ) {
* p = ' \0 ' ;
2010-02-06 03:38:24 +00:00
2009-11-04 16:46:17 +00:00
if ( ( p = strrchr ( dest_num , ' / ' ) ) ) {
dest_num = p + 1 ;
2010-02-06 03:38:24 +00:00
} else if ( ( p = ( char * ) switch_stristr ( " sip: " , dest_num ) ) ) {
2009-11-04 16:46:17 +00:00
dest_num = p + 4 ;
2010-02-06 03:38:24 +00:00
} else if ( ( p = ( char * ) switch_stristr ( " sips: " , dest_num ) ) ) {
2009-11-04 16:46:17 +00:00
dest_num = p + 5 ;
2009-10-07 22:35:21 +00:00
}
}
2009-11-15 02:16:10 +00:00
# endif
2009-10-07 22:35:21 +00:00
2010-06-18 13:39:55 -05:00
if ( profile - > pres_type ) {
char * sql ;
const char * presence_id = switch_channel_get_variable ( nchannel , " presence_id " ) ;
const char * presence_data = switch_channel_get_variable ( nchannel , " presence_data " ) ;
if ( zstr ( presence_id ) ) {
presence_id = switch_event_get_header ( var_event , " presence_id " ) ;
}
if ( zstr ( presence_data ) ) {
presence_data = switch_event_get_header ( var_event , " presence_data " ) ;
}
2010-02-06 03:38:24 +00:00
2010-06-18 13:39:55 -05:00
sql = switch_mprintf ( " insert into sip_dialogs (uuid,presence_id,presence_data,profile_name,hostname) "
2010-06-23 13:22:52 -05:00
" values ('%q', '%q', '%q', '%q', '%q') " , switch_core_session_get_uuid ( nsession ) ,
2010-06-18 13:39:55 -05:00
switch_str_nil ( presence_id ) , switch_str_nil ( presence_data ) , profile - > name , mod_sofia_globals . hostname ) ;
sofia_glue_actually_execute_sql ( profile , sql , profile - > ireg_mutex ) ;
switch_safe_free ( sql ) ;
}
2010-06-23 13:22:52 -05:00
2010-06-18 13:39:55 -05:00
caller_profile = switch_caller_profile_clone ( nsession , outbound_profile ) ;
2010-06-23 13:22:52 -05:00
2010-02-06 03:38:24 +00:00
2009-11-15 02:16:10 +00:00
caller_profile - > destination_number = switch_sanitize_number ( caller_profile - > destination_number ) ;
2010-02-06 03:38:24 +00:00
not_const = ( char * ) caller_profile - > caller_id_name ;
2009-11-17 00:12:54 +00:00
caller_profile - > caller_id_name = switch_sanitize_number ( not_const ) ;
2010-02-06 03:38:24 +00:00
not_const = ( char * ) caller_profile - > caller_id_number ;
2009-11-17 00:12:54 +00:00
caller_profile - > caller_id_number = switch_sanitize_number ( not_const ) ;
2010-02-06 03:38:24 +00:00
2009-11-15 02:16:10 +00:00
//caller_profile->destination_number = switch_core_strdup(caller_profile->pool, dest_num);
2007-03-31 19:01:33 +00:00
switch_channel_set_caller_profile ( nchannel , caller_profile ) ;
2009-02-09 17:56:38 +00:00
sofia_set_flag_locked ( tech_pvt , TFLAG_OUTBOUND ) ;
sofia_clear_flag_locked ( tech_pvt , TFLAG_LATE_NEGOTIATION ) ;
2008-01-26 01:53:42 +00:00
if ( switch_channel_get_state ( nchannel ) = = CS_NEW ) {
switch_channel_set_state ( nchannel , CS_INIT ) ;
}
2007-11-19 17:09:46 +00:00
tech_pvt - > caller_profile = caller_profile ;
2007-03-31 19:01:33 +00:00
* new_session = nsession ;
cause = SWITCH_CAUSE_SUCCESS ;
2007-12-18 01:12:50 +00:00
2010-01-21 00:12:24 +00:00
if ( ( hval = switch_event_get_header ( var_event , " sip_enable_soa " ) ) ) {
if ( switch_true ( hval ) ) {
sofia_set_flag ( tech_pvt , TFLAG_ENABLE_SOA ) ;
} else {
sofia_clear_flag ( tech_pvt , TFLAG_ENABLE_SOA ) ;
}
}
2008-12-31 01:08:51 +00:00
if ( ( hval = switch_event_get_header ( var_event , " sip_auto_answer " ) ) & & switch_true ( hval ) ) {
switch_channel_set_variable_printf ( nchannel , " sip_h_Call-Info " , " <sip:%s>;answer-after=0 " , profile - > sipip ) ;
switch_channel_set_variable ( nchannel , " sip_invite_params " , " intercom=true " ) ;
}
2010-02-06 03:38:24 +00:00
if ( ( ( hval = switch_event_get_header ( var_event , " effective_callee_id_name " ) ) | |
2009-11-06 22:08:59 +00:00
( hval = switch_event_get_header ( var_event , " sip_callee_id_name " ) ) ) & & ! zstr ( hval ) ) {
2009-10-19 19:58:23 +00:00
caller_profile - > callee_id_name = switch_core_strdup ( caller_profile - > pool , hval ) ;
}
2010-02-06 03:38:24 +00:00
if ( ( ( hval = switch_event_get_header ( var_event , " effective_callee_id_number " ) ) | |
2009-11-06 22:08:59 +00:00
( hval = switch_event_get_header ( var_event , " sip_callee_id_number " ) ) ) & & ! zstr ( hval ) ) {
2009-10-19 19:58:23 +00:00
caller_profile - > callee_id_number = switch_core_strdup ( caller_profile - > pool , hval ) ;
}
2007-03-31 19:01:33 +00:00
if ( session ) {
2008-05-23 19:41:23 +00:00
switch_channel_t * o_channel = switch_core_session_get_channel ( session ) ;
2009-01-05 16:22:09 +00:00
const char * vval = NULL ;
2008-05-23 19:41:23 +00:00
2009-01-05 16:22:09 +00:00
if ( ( vval = switch_channel_get_variable ( o_channel , " sip_auto_answer " ) ) & & switch_true ( vval ) ) {
switch_channel_set_variable_printf ( nchannel , " sip_h_Call-Info " , " <sip:%s>;answer-after=0 " , profile - > sipip ) ;
switch_channel_set_variable ( nchannel , " sip_invite_params " , " intercom=true " ) ;
}
2010-02-06 03:38:24 +00:00
2007-03-31 19:01:33 +00:00
switch_ivr_transfer_variable ( session , nsession , SOFIA_REPLACES_HEADER ) ;
2008-01-12 04:00:21 +00:00
switch_ivr_transfer_variable ( session , nsession , " sip_auto_answer " ) ;
2009-12-04 19:57:50 +00:00
if ( ! ( vval = switch_channel_get_variable ( o_channel , " sip_copy_custom_headers " ) ) | | switch_true ( vval ) ) {
2010-02-06 03:38:24 +00:00
switch_ivr_transfer_variable ( session , nsession , SOFIA_SIP_HEADER_PREFIX_T ) ;
2009-12-04 19:57:50 +00:00
}
2010-06-01 17:22:45 -05:00
if ( ! ( vval = switch_channel_get_variable ( o_channel , " sip_copy_multipart " ) ) | | switch_true ( vval ) ) {
switch_ivr_transfer_variable ( session , nsession , SOFIA_MULTIPART_PREFIX_T ) ;
}
2008-02-07 22:42:27 +00:00
switch_ivr_transfer_variable ( session , nsession , " sip_video_fmtp " ) ;
2008-05-13 23:22:21 +00:00
switch_ivr_transfer_variable ( session , nsession , " sip-force-contact " ) ;
switch_ivr_transfer_variable ( session , nsession , " sip_sticky_contact " ) ;
2010-06-04 19:37:04 -05:00
if ( ! cid_locked ) {
switch_ivr_transfer_variable ( session , nsession , " sip_cid_type " ) ;
}
2010-02-06 03:38:24 +00:00
2007-03-31 19:01:33 +00:00
if ( switch_core_session_compare ( session , nsession ) ) {
/* It's another sofia channel! so lets cache what they use as a pt for telephone event so
we can keep it the same
2010-06-30 10:35:03 -05:00
*/
2007-03-31 19:01:33 +00:00
private_object_t * ctech_pvt ;
ctech_pvt = switch_core_session_get_private ( session ) ;
2007-12-12 23:21:45 +00:00
switch_assert ( ctech_pvt ! = NULL ) ;
2007-03-31 19:01:33 +00:00
tech_pvt - > bte = ctech_pvt - > te ;
tech_pvt - > bcng_pt = ctech_pvt - > cng_pt ;
2010-06-04 19:37:04 -05:00
if ( ! cid_locked ) {
tech_pvt - > cid_type = ctech_pvt - > cid_type ;
}
2010-02-06 03:38:24 +00:00
2010-01-21 00:12:24 +00:00
if ( sofia_test_flag ( tech_pvt , TFLAG_ENABLE_SOA ) ) {
sofia_set_flag ( ctech_pvt , TFLAG_ENABLE_SOA ) ;
} else {
sofia_clear_flag ( ctech_pvt , TFLAG_ENABLE_SOA ) ;
}
2006-10-12 00:59:09 +00:00
}
2008-05-23 19:41:23 +00:00
if ( switch_channel_test_flag ( o_channel , CF_PROXY_MEDIA ) ) {
const char * r_sdp = switch_channel_get_variable ( o_channel , SWITCH_R_SDP_VARIABLE ) ;
if ( switch_stristr ( " m=video " , r_sdp ) ) {
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_channel_set_flag ( tech_pvt - > channel , CF_VIDEO ) ;
2009-02-09 17:56:38 +00:00
sofia_set_flag ( tech_pvt , TFLAG_VIDEO ) ;
2008-05-23 19:41:23 +00:00
}
}
2006-10-15 05:10:34 +00:00
}
2006-10-12 00:59:09 +00:00
2007-12-21 04:29:41 +00:00
goto done ;
2010-06-30 10:35:03 -05:00
error :
2007-12-21 04:29:41 +00:00
if ( nsession ) {
switch_core_session_destroy ( & nsession ) ;
}
2010-05-04 15:48:36 -05:00
if ( pool ) {
* pool = NULL ;
}
2010-06-30 10:35:03 -05:00
done :
2008-01-16 06:01:53 +00:00
2007-04-29 01:16:49 +00:00
if ( profile ) {
2009-04-21 17:47:22 +00:00
if ( cause = = SWITCH_CAUSE_SUCCESS ) {
profile - > ob_calls + + ;
} else {
profile - > ob_failed_calls + + ;
}
2007-05-03 01:55:25 +00:00
sofia_glue_release_profile ( profile ) ;
2007-04-29 01:16:49 +00:00
}
2007-03-31 19:01:33 +00:00
return cause ;
2006-10-12 00:59:09 +00:00
}
2008-09-26 14:37:50 +00:00
static int notify_callback ( void * pArg , int argc , char * * argv , char * * columnNames )
{
nua_handle_t * nh ;
sofia_profile_t * ext_profile = NULL , * profile = ( sofia_profile_t * ) pArg ;
char * user = argv [ 0 ] ;
char * host = argv [ 1 ] ;
char * contact_in = argv [ 2 ] ;
char * profile_name = argv [ 3 ] ;
char * ct = argv [ 4 ] ;
char * es = argv [ 5 ] ;
char * body = argv [ 6 ] ;
char * id = NULL ;
2010-02-06 03:38:24 +00:00
char * p , * contact ;
2008-09-26 14:37:50 +00:00
if ( profile_name & & strcasecmp ( profile_name , profile - > name ) ) {
2010-02-06 03:38:24 +00:00
if ( ( ext_profile = sofia_glue_find_profile ( profile_name ) ) ) {
profile = ext_profile ;
}
}
2008-09-26 14:37:50 +00:00
id = switch_mprintf ( " sip:%s@%s " , user , host ) ;
switch_assert ( id ) ;
contact = sofia_glue_get_url_from_contact ( contact_in , 1 ) ;
2010-02-06 03:38:24 +00:00
2008-09-26 14:37:50 +00:00
if ( ( p = strstr ( contact , " ;fs_ " ) ) ) {
* p = ' \0 ' ;
}
2010-02-06 03:38:24 +00:00
nh = nua_handle ( profile - > nua , NULL , NUTAG_URL ( contact ) , SIPTAG_FROM_STR ( id ) , SIPTAG_TO_STR ( id ) , SIPTAG_CONTACT_STR ( profile - > url ) , TAG_END ( ) ) ;
2009-03-22 05:15:17 +00:00
nua_handle_bind ( nh , & mod_sofia_globals . destroy_private ) ;
2010-02-06 03:38:24 +00:00
nua_notify ( nh , NUTAG_NEWSUB ( 1 ) , SIPTAG_EVENT_STR ( es ) , SIPTAG_CONTENT_TYPE_STR ( ct ) , TAG_IF ( ! zstr ( body ) , SIPTAG_PAYLOAD_STR ( body ) ) , TAG_END ( ) ) ;
2008-09-26 14:37:50 +00:00
free ( id ) ;
free ( contact ) ;
if ( ext_profile ) {
sofia_glue_release_profile ( ext_profile ) ;
2010-02-06 03:38:24 +00:00
}
2008-09-26 14:37:50 +00:00
return 0 ;
}
2008-07-22 22:23:50 +00:00
static void general_event_handler ( switch_event_t * event )
{
switch ( event - > event_id ) {
case SWITCH_EVENT_NOTIFY :
{
const char * profile_name = switch_event_get_header ( event , " profile " ) ;
const char * ct = switch_event_get_header ( event , " content-type " ) ;
const char * es = switch_event_get_header ( event , " event-string " ) ;
const char * user = switch_event_get_header ( event , " user " ) ;
const char * host = switch_event_get_header ( event , " host " ) ;
2008-09-26 17:00:30 +00:00
const char * call_id = switch_event_get_header ( event , " call-id " ) ;
2008-12-11 20:24:31 +00:00
const char * uuid = switch_event_get_header ( event , " uuid " ) ;
2008-07-22 22:23:50 +00:00
const char * body = switch_event_get_body ( event ) ;
2009-04-29 03:37:30 +00:00
const char * to_uri = switch_event_get_header ( event , " to-uri " ) ;
const char * from_uri = switch_event_get_header ( event , " from-uri " ) ;
2008-07-22 22:23:50 +00:00
sofia_profile_t * profile ;
2009-04-29 04:15:52 +00:00
if ( to_uri | | from_uri ) {
2010-02-06 03:38:24 +00:00
2009-04-29 04:15:52 +00:00
if ( ! to_uri ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Missing To-URI header \n " ) ;
return ;
}
2010-02-06 03:38:24 +00:00
2009-04-29 04:15:52 +00:00
if ( ! from_uri ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Missing From-URI header \n " ) ;
return ;
}
2010-02-06 03:38:24 +00:00
2009-04-29 04:15:52 +00:00
if ( ! es ) {
es = " message-summary " ;
}
2009-04-29 03:37:30 +00:00
2009-04-29 04:15:52 +00:00
if ( ! ct ) {
ct = " application/simple-message-summary " ;
}
2009-04-29 03:37:30 +00:00
2009-04-29 04:15:52 +00:00
if ( ! profile_name ) {
profile_name = " default " ;
}
2010-02-06 03:38:24 +00:00
2009-04-29 04:15:52 +00:00
if ( ! ( profile = sofia_glue_find_profile ( profile_name ) ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Can't find profile %s \n " , profile_name ) ;
return ;
}
2010-02-06 03:38:24 +00:00
2009-04-29 04:15:52 +00:00
if ( to_uri & & from_uri & & ct & & es & & profile_name & & ( profile = sofia_glue_find_profile ( profile_name ) ) ) {
2010-02-06 03:38:24 +00:00
nua_handle_t * nh = nua_handle ( profile - > nua ,
NULL ,
NUTAG_URL ( to_uri ) ,
SIPTAG_FROM_STR ( from_uri ) ,
SIPTAG_TO_STR ( to_uri ) ,
SIPTAG_CONTACT_STR ( profile - > url ) ,
2009-04-29 04:15:52 +00:00
TAG_END ( ) ) ;
2010-02-06 03:38:24 +00:00
2009-04-29 04:15:52 +00:00
nua_handle_bind ( nh , & mod_sofia_globals . destroy_private ) ;
2010-02-06 03:38:24 +00:00
2009-04-29 04:15:52 +00:00
nua_notify ( nh ,
NUTAG_NEWSUB ( 1 ) ,
NUTAG_WITH_THIS ( profile - > nua ) ,
2010-02-06 03:38:24 +00:00
SIPTAG_EVENT_STR ( es ) , TAG_IF ( ct , SIPTAG_CONTENT_TYPE_STR ( ct ) ) , TAG_IF ( ! zstr ( body ) , SIPTAG_PAYLOAD_STR ( body ) ) , TAG_END ( ) ) ;
2009-04-29 04:15:52 +00:00
sofia_glue_release_profile ( profile ) ;
}
return ;
2009-04-29 03:37:30 +00:00
}
2009-04-29 04:15:52 +00:00
2008-12-11 20:24:31 +00:00
if ( uuid & & ct & & es ) {
switch_core_session_t * session ;
private_object_t * tech_pvt ;
if ( ( session = switch_core_session_locate ( uuid ) ) ) {
if ( ( tech_pvt = switch_core_session_get_private ( session ) ) ) {
nua_notify ( tech_pvt - > nh ,
NUTAG_NEWSUB ( 1 ) ,
2010-02-06 03:38:24 +00:00
SIPTAG_EVENT_STR ( es ) , SIPTAG_CONTENT_TYPE_STR ( ct ) , TAG_IF ( ! zstr ( body ) , SIPTAG_PAYLOAD_STR ( body ) ) , TAG_END ( ) ) ;
2008-12-11 20:24:31 +00:00
}
switch_core_session_rwunlock ( session ) ;
}
} else if ( profile_name & & ct & & es & & user & & host & & ( profile = sofia_glue_find_profile ( profile_name ) ) ) {
2008-09-26 17:00:30 +00:00
char * sql ;
if ( call_id ) {
sql = switch_mprintf ( " select sip_user,sip_host,contact,profile_name,'%q','%q','%q' "
2010-02-06 03:38:24 +00:00
" from sip_registrations where call_id='%q' " , ct , es , switch_str_nil ( body ) , call_id ) ;
2008-09-26 17:00:30 +00:00
} else {
2009-09-25 20:07:40 +00:00
if ( ! strcasecmp ( es , " message-summary " ) ) {
sql = switch_mprintf ( " select sip_user,sip_host,contact,profile_name,'%q','%q','%q' "
2010-02-06 03:38:24 +00:00
" from sip_registrations where mwi_user='%s' and mwi_host='%q' " ,
ct , es , switch_str_nil ( body ) , switch_str_nil ( user ) , switch_str_nil ( host )
2010-06-30 10:35:03 -05:00
) ;
2009-09-25 20:07:40 +00:00
} else {
sql = switch_mprintf ( " select sip_user,sip_host,contact,profile_name,'%q','%q','%q' "
2010-02-06 03:38:24 +00:00
" from sip_registrations where sip_user='%s' and sip_host='%q' " ,
ct , es , switch_str_nil ( body ) , switch_str_nil ( user ) , switch_str_nil ( host )
2010-06-30 10:35:03 -05:00
) ;
2009-09-25 20:07:40 +00:00
}
2008-09-26 17:00:30 +00:00
}
2010-02-06 03:38:24 +00:00
2008-07-22 22:23:50 +00:00
2008-09-26 14:37:50 +00:00
switch_mutex_lock ( profile - > ireg_mutex ) ;
2009-11-12 03:52:07 +00:00
sofia_glue_execute_sql_callback ( profile , NULL , sql , notify_callback , profile ) ;
2008-09-26 14:37:50 +00:00
switch_mutex_unlock ( profile - > ireg_mutex ) ;
2008-07-22 22:23:50 +00:00
sofia_glue_release_profile ( profile ) ;
2008-09-26 17:00:30 +00:00
free ( sql ) ;
2008-07-22 22:23:50 +00:00
}
2010-02-06 03:38:24 +00:00
2008-07-22 22:23:50 +00:00
}
break ;
case SWITCH_EVENT_SEND_MESSAGE :
{
const char * profile_name = switch_event_get_header ( event , " profile " ) ;
const char * ct = switch_event_get_header ( event , " content-type " ) ;
const char * user = switch_event_get_header ( event , " user " ) ;
const char * host = switch_event_get_header ( event , " host " ) ;
2010-06-10 15:47:13 -05:00
const char * subject = switch_event_get_header ( event , " subject " ) ;
2008-07-22 22:23:50 +00:00
const char * body = switch_event_get_body ( event ) ;
sofia_profile_t * profile ;
nua_handle_t * nh ;
2010-08-18 14:58:14 -05:00
2008-09-18 20:43:13 +00:00
if ( profile_name & & ct & & user & & host ) {
2008-07-22 22:23:50 +00:00
char * id = NULL ;
2008-07-23 13:11:45 +00:00
char * contact , * p ;
2010-08-18 14:58:14 -05:00
switch_console_callback_match_t * list = NULL ;
switch_console_callback_match_node_t * m ;
2008-07-23 18:19:56 +00:00
if ( ! ( profile = sofia_glue_find_profile ( profile_name ) ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Can't find profile %s \n " , profile_name ) ;
return ;
}
2010-08-18 14:58:14 -05:00
if ( ! ( list = sofia_reg_find_reg_url_multi ( profile , user , host ) ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Can't find registered user %s@%s \n " , user , host ) ;
2008-07-22 22:23:50 +00:00
return ;
}
id = switch_mprintf ( " sip:%s@%s " , user , host ) ;
switch_assert ( id ) ;
2010-02-06 03:38:24 +00:00
2010-08-18 14:58:14 -05:00
for ( m = list - > head ; m ; m = m - > next ) {
contact = sofia_glue_get_url_from_contact ( m - > val , 0 ) ;
if ( ( p = strstr ( contact , " ;fs_ " ) ) ) {
* p = ' \0 ' ;
}
2010-02-06 03:38:24 +00:00
2010-08-18 14:58:14 -05:00
nh = nua_handle ( profile - > nua ,
NULL , NUTAG_URL ( contact ) , SIPTAG_FROM_STR ( id ) , SIPTAG_TO_STR ( id ) , SIPTAG_CONTACT_STR ( profile - > url ) , TAG_END ( ) ) ;
2010-02-06 03:38:24 +00:00
2010-08-18 14:58:14 -05:00
nua_message ( nh , NUTAG_NEWSUB ( 1 ) , SIPTAG_CONTENT_TYPE_STR ( ct ) ,
TAG_IF ( ! zstr ( body ) , SIPTAG_PAYLOAD_STR ( body ) ) , TAG_IF ( ! zstr ( subject ) , SIPTAG_SUBJECT_STR ( subject ) ) , TAG_END ( ) ) ;
2010-02-06 03:38:24 +00:00
2010-08-18 14:58:14 -05:00
free ( id ) ;
}
switch_console_free_matches ( & list ) ;
2008-07-22 22:23:50 +00:00
sofia_glue_release_profile ( profile ) ;
}
2009-04-20 17:07:54 +00:00
}
break ;
case SWITCH_EVENT_SEND_INFO :
{
const char * profile_name = switch_event_get_header ( event , " profile " ) ;
const char * ct = switch_event_get_header ( event , " content-type " ) ;
2009-11-17 16:46:34 +00:00
const char * cd = switch_event_get_header ( event , " content-disposition " ) ;
2009-04-20 17:07:54 +00:00
const char * to_uri = switch_event_get_header ( event , " to-uri " ) ;
2009-04-27 18:18:29 +00:00
const char * local_user_full = switch_event_get_header ( event , " local-user " ) ;
2009-04-20 17:07:54 +00:00
const char * from_uri = switch_event_get_header ( event , " from-uri " ) ;
2009-04-27 23:36:03 +00:00
const char * call_info = switch_event_get_header ( event , " call-info " ) ;
const char * alert_info = switch_event_get_header ( event , " alert-info " ) ;
2009-05-15 17:07:07 +00:00
const char * call_id = switch_event_get_header ( event , " call-id " ) ;
2009-04-20 17:07:54 +00:00
const char * body = switch_event_get_body ( event ) ;
2009-04-27 18:18:29 +00:00
sofia_profile_t * profile = NULL ;
2009-04-20 17:07:54 +00:00
nua_handle_t * nh ;
2009-04-27 18:18:29 +00:00
char * local_dup = NULL ;
char * local_user , * local_host ;
char buf [ 1024 ] = " " ;
char * p ;
2009-04-20 17:07:54 +00:00
if ( ! profile_name ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Missing Profile Name \n " ) ;
goto done ;
}
2009-04-20 17:07:54 +00:00
2010-02-06 03:38:24 +00:00
if ( ! call_id & & ! to_uri & & ! local_user_full ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Missing To-URI header \n " ) ;
goto done ;
}
2009-04-20 17:07:54 +00:00
2010-02-06 03:38:24 +00:00
if ( ! call_id & & ! from_uri ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Missing From-URI header \n " ) ;
goto done ;
}
2009-04-29 04:15:52 +00:00
2010-02-06 03:38:24 +00:00
if ( ! ( profile = sofia_glue_find_profile ( profile_name ) ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Can't find profile %s \n " , profile_name ) ;
goto done ;
}
2009-04-20 17:07:54 +00:00
2009-05-15 17:07:07 +00:00
if ( call_id ) {
nh = nua_handle_by_call_id ( profile - > nua , call_id ) ;
2009-04-27 18:18:29 +00:00
2009-05-15 17:07:07 +00:00
if ( ! nh ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Invalid Call-ID %s \n " , call_id ) ;
2009-04-27 18:18:29 +00:00
goto done ;
}
2009-11-17 16:46:34 +00:00
} else {
2009-05-15 17:07:07 +00:00
if ( local_user_full ) {
local_dup = strdup ( local_user_full ) ;
local_user = local_dup ;
if ( ( local_host = strchr ( local_user , ' @ ' ) ) ) {
* local_host + + = ' \0 ' ;
}
2010-02-06 03:38:24 +00:00
2009-05-15 17:07:07 +00:00
if ( ! local_user | | ! local_host | | ! sofia_reg_find_reg_url ( profile , local_user , local_host , buf , sizeof ( buf ) ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Can't find local user \n " ) ;
goto done ;
}
2010-02-06 03:38:24 +00:00
2009-05-15 17:07:07 +00:00
to_uri = sofia_glue_get_url_from_contact ( buf , 0 ) ;
2010-02-06 03:38:24 +00:00
2009-05-15 17:07:07 +00:00
if ( ( p = strstr ( to_uri , " ;fs_ " ) ) ) {
* p = ' \0 ' ;
}
2010-02-06 03:38:24 +00:00
2009-05-15 17:07:07 +00:00
}
2010-02-06 03:38:24 +00:00
nh = nua_handle ( profile - > nua ,
NULL , NUTAG_URL ( to_uri ) , SIPTAG_FROM_STR ( from_uri ) , SIPTAG_TO_STR ( to_uri ) , SIPTAG_CONTACT_STR ( profile - > url ) , TAG_END ( ) ) ;
2009-05-15 17:07:07 +00:00
nua_handle_bind ( nh , & mod_sofia_globals . destroy_private ) ;
}
2009-04-20 19:00:39 +00:00
2009-04-20 17:07:54 +00:00
nua_info ( nh ,
2009-04-20 19:00:39 +00:00
NUTAG_WITH_THIS ( profile - > nua ) ,
2009-04-27 23:36:03 +00:00
TAG_IF ( ct , SIPTAG_CONTENT_TYPE_STR ( ct ) ) ,
2009-11-17 16:46:34 +00:00
TAG_IF ( cd , SIPTAG_CONTENT_DISPOSITION_STR ( cd ) ) ,
2009-04-27 23:36:03 +00:00
TAG_IF ( alert_info , SIPTAG_ALERT_INFO_STR ( alert_info ) ) ,
2010-02-06 03:38:24 +00:00
TAG_IF ( call_info , SIPTAG_CALL_INFO_STR ( call_info ) ) , TAG_IF ( ! zstr ( body ) , SIPTAG_PAYLOAD_STR ( body ) ) , TAG_END ( ) ) ;
2009-04-20 17:07:54 +00:00
2009-05-15 17:07:07 +00:00
if ( call_id & & nh ) {
nua_handle_unref ( nh ) ;
}
2009-04-27 18:18:29 +00:00
if ( profile ) {
sofia_glue_release_profile ( profile ) ;
}
2010-02-06 03:38:24 +00:00
2010-06-30 10:35:03 -05:00
done :
2009-04-27 18:18:29 +00:00
switch_safe_free ( local_dup ) ;
2010-02-06 03:38:24 +00:00
2008-07-22 22:23:50 +00:00
}
break ;
case SWITCH_EVENT_TRAP :
{
const char * cond = switch_event_get_header ( event , " condition " ) ;
2009-06-30 18:59:05 +00:00
2008-12-11 20:16:32 +00:00
if ( cond & & ! strcmp ( cond , " network-address-change " ) & & mod_sofia_globals . auto_restart ) {
2009-01-22 23:07:31 +00:00
const char * old_ip4 = switch_event_get_header_nil ( event , " network-address-previous-v4 " ) ;
const char * new_ip4 = switch_event_get_header_nil ( event , " network-address-change-v4 " ) ;
const char * old_ip6 = switch_event_get_header_nil ( event , " network-address-previous-v6 " ) ;
const char * new_ip6 = switch_event_get_header_nil ( event , " network-address-change-v6 " ) ;
switch_hash_index_t * hi ;
const void * var ;
void * val ;
sofia_profile_t * profile ;
2009-11-12 20:59:04 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_INFO , " EVENT_TRAP: IP change detected \n " ) ;
2009-01-22 23:07:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_INFO , " IP change detected [%s]->[%s] [%s]->[%s] \n " , old_ip4 , new_ip4 , old_ip6 , new_ip6 ) ;
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 ) ) {
2010-09-29 15:47:58 -05:00
int rb = 0 ;
uint32_t x = 0 ;
2009-01-22 23:07:31 +00:00
switch_hash_this ( hi , & var , NULL , & val ) ;
if ( ( profile = ( sofia_profile_t * ) val ) & & profile - > auto_restart ) {
if ( ! strcmp ( profile - > sipip , old_ip4 ) ) {
profile - > sipip = switch_core_strdup ( profile - > pool , new_ip4 ) ;
rb + + ;
}
2010-06-23 13:22:52 -05:00
2010-06-10 17:08:29 -05:00
for ( x = 0 ; x < profile - > rtpip_index ; x + + ) {
if ( ! strcmp ( profile - > rtpip [ x ] , old_ip4 ) ) {
profile - > rtpip [ x ] = switch_core_strdup ( profile - > pool , new_ip4 ) ;
rb + + ;
}
if ( ! strcmp ( profile - > rtpip [ x ] , old_ip6 ) ) {
profile - > rtpip [ x ] = switch_core_strdup ( profile - > pool , new_ip6 ) ;
rb + + ;
}
2009-01-22 23:07:31 +00:00
}
2010-06-23 13:22:52 -05:00
2010-06-10 17:08:29 -05:00
2009-01-22 23:07:31 +00:00
if ( ! strcmp ( profile - > sipip , old_ip6 ) ) {
profile - > sipip = switch_core_strdup ( profile - > pool , new_ip6 ) ;
rb + + ;
}
2010-06-23 13:22:52 -05:00
2009-01-22 23:07:31 +00:00
if ( rb ) {
sofia_set_pflag_locked ( profile , PFLAG_RESPAWN ) ;
sofia_clear_pflag_locked ( profile , PFLAG_RUNNING ) ;
}
}
}
}
2009-03-12 02:24:24 +00:00
switch_mutex_unlock ( mod_sofia_globals . hash_mutex ) ;
2008-07-22 22:23:50 +00:00
sofia_glue_restart_all_profiles ( ) ;
}
2010-02-06 03:38:24 +00:00
2008-07-22 22:23:50 +00:00
}
break ;
default :
break ;
}
}
2009-12-14 20:10:06 +00:00
static switch_status_t list_profiles ( const char * line , const char * cursor , switch_console_callback_match_t * * matches )
{
sofia_profile_t * profile = NULL ;
switch_hash_index_t * hi ;
void * val ;
const void * vvar ;
switch_console_callback_match_t * my_matches = NULL ;
switch_status_t status = SWITCH_STATUS_FALSE ;
switch_mutex_lock ( mod_sofia_globals . hash_mutex ) ;
for ( hi = switch_hash_first ( NULL , mod_sofia_globals . profile_hash ) ; hi ; hi = switch_hash_next ( hi ) ) {
switch_hash_this ( hi , & vvar , NULL , & val ) ;
profile = ( sofia_profile_t * ) val ;
if ( sofia_test_pflag ( profile , PFLAG_RUNNING ) ) {
2010-02-06 03:38:24 +00:00
switch_console_push_match ( & my_matches , ( const char * ) vvar ) ;
2009-12-14 20:10:06 +00:00
}
}
switch_mutex_unlock ( mod_sofia_globals . hash_mutex ) ;
if ( my_matches ) {
* matches = my_matches ;
status = SWITCH_STATUS_SUCCESS ;
}
return status ;
}
static switch_status_t list_gateways ( const char * line , const char * cursor , switch_console_callback_match_t * * matches )
{
sofia_profile_t * profile = NULL ;
switch_hash_index_t * hi ;
void * val ;
const void * vvar ;
switch_console_callback_match_t * my_matches = NULL ;
switch_status_t status = SWITCH_STATUS_FALSE ;
switch_mutex_lock ( mod_sofia_globals . hash_mutex ) ;
for ( hi = switch_hash_first ( NULL , mod_sofia_globals . profile_hash ) ; hi ; hi = switch_hash_next ( hi ) ) {
switch_hash_this ( hi , & vvar , NULL , & val ) ;
profile = ( sofia_profile_t * ) val ;
if ( sofia_test_pflag ( profile , PFLAG_RUNNING ) ) {
sofia_gateway_t * gp ;
for ( gp = profile - > gateways ; gp ; gp = gp - > next ) {
switch_console_push_match ( & my_matches , gp - > name ) ;
}
}
}
switch_mutex_unlock ( mod_sofia_globals . hash_mutex ) ;
if ( my_matches ) {
* matches = my_matches ;
status = SWITCH_STATUS_SUCCESS ;
}
2010-02-06 03:38:24 +00:00
2009-12-14 20:10:06 +00:00
return status ;
}
static switch_status_t list_profile_gateway ( const char * line , const char * cursor , switch_console_callback_match_t * * matches )
{
sofia_profile_t * profile = NULL ;
switch_console_callback_match_t * my_matches = NULL ;
switch_status_t status = SWITCH_STATUS_FALSE ;
char * dup = NULL ;
int argc ;
char * argv [ 4 ] = { 0 } ;
if ( zstr ( line ) ) {
return SWITCH_STATUS_FALSE ;
}
dup = strdup ( line ) ;
argc = switch_split ( dup , ' ' , argv ) ;
2010-02-06 03:38:24 +00:00
2009-12-15 23:05:49 +00:00
if ( zstr ( argv [ 2 ] ) | | ! strcmp ( argv [ 2 ] , " " ) ) {
2009-12-14 20:10:06 +00:00
goto end ;
}
if ( ( profile = sofia_glue_find_profile ( argv [ 2 ] ) ) ) {
sofia_gateway_t * gp ;
for ( gp = profile - > gateways ; gp ; gp = gp - > next ) {
switch_console_push_match ( & my_matches , gp - > name ) ;
}
sofia_glue_release_profile ( profile ) ;
}
if ( my_matches ) {
* matches = my_matches ;
status = SWITCH_STATUS_SUCCESS ;
}
2010-02-06 03:38:24 +00:00
2010-06-30 10:35:03 -05:00
end :
2009-12-14 20:10:06 +00:00
switch_safe_free ( dup ) ;
return status ;
}
2010-02-24 00:01:39 +00:00
2007-06-13 14:35:55 +00:00
SWITCH_MODULE_LOAD_FUNCTION ( mod_sofia_load )
2006-08-25 23:55:59 +00:00
{
2007-06-20 07:15:53 +00:00
switch_chat_interface_t * chat_interface ;
switch_api_interface_t * api_interface ;
switch_management_interface_t * management_interface ;
2009-06-05 22:00:10 +00:00
struct in_addr in ;
2006-08-25 23:55:59 +00:00
2006-10-31 21:38:06 +00:00
silence_frame . data = silence_data ;
silence_frame . datalen = sizeof ( silence_data ) ;
silence_frame . buflen = sizeof ( silence_data ) ;
silence_frame . flags = SFF_CNG ;
2007-04-01 01:16:16 +00:00
memset ( & mod_sofia_globals , 0 , sizeof ( mod_sofia_globals ) ) ;
2008-05-06 22:56:55 +00:00
mod_sofia_globals . destroy_private . destroy_nh = 1 ;
2009-03-22 05:15:17 +00:00
mod_sofia_globals . destroy_private . is_static = 1 ;
mod_sofia_globals . keep_private . is_static = 1 ;
2008-03-14 03:46:54 +00:00
mod_sofia_globals . pool = pool ;
switch_mutex_init ( & mod_sofia_globals . mutex , SWITCH_MUTEX_NESTED , mod_sofia_globals . pool ) ;
2007-01-19 19:11:44 +00:00
2009-06-02 16:55:10 +00:00
switch_find_local_ip ( mod_sofia_globals . guess_ip , sizeof ( mod_sofia_globals . guess_ip ) , & mod_sofia_globals . guess_mask , AF_INET ) ;
2009-06-05 22:00:10 +00:00
in . s_addr = mod_sofia_globals . guess_mask ;
switch_set_string ( mod_sofia_globals . guess_mask_str , inet_ntoa ( in ) ) ;
2008-09-18 00:01:03 +00:00
gethostname ( mod_sofia_globals . hostname , sizeof ( mod_sofia_globals . hostname ) ) ;
2006-09-27 20:18:14 +00:00
2008-03-14 03:46:54 +00:00
switch_core_hash_init ( & mod_sofia_globals . profile_hash , mod_sofia_globals . pool ) ;
switch_core_hash_init ( & mod_sofia_globals . gateway_hash , mod_sofia_globals . pool ) ;
switch_mutex_init ( & mod_sofia_globals . hash_mutex , SWITCH_MUTEX_NESTED , mod_sofia_globals . pool ) ;
2008-05-27 04:54:52 +00:00
2007-04-13 23:19:51 +00:00
switch_mutex_lock ( mod_sofia_globals . mutex ) ;
mod_sofia_globals . running = 1 ;
switch_mutex_unlock ( mod_sofia_globals . mutex ) ;
2006-10-18 22:57:35 +00:00
2009-06-03 21:08:34 +00:00
mod_sofia_globals . auto_nat = ( switch_core_get_variable ( " nat_type " ) ? 1 : 0 ) ;
2008-08-24 01:52:27 +00:00
switch_queue_create ( & mod_sofia_globals . presence_queue , SOFIA_QUEUE_SIZE , mod_sofia_globals . pool ) ;
switch_queue_create ( & mod_sofia_globals . mwi_queue , SOFIA_QUEUE_SIZE , mod_sofia_globals . pool ) ;
2008-03-14 03:46:54 +00:00
2008-02-07 22:13:40 +00:00
if ( config_sofia ( 0 , NULL ) ! = SWITCH_STATUS_SUCCESS ) {
mod_sofia_globals . running = 0 ;
return SWITCH_STATUS_GENERR ;
}
2007-05-01 16:12:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Waiting for profiles to start \n " ) ;
switch_yield ( 1500000 ) ;
2008-07-22 22:23:50 +00:00
if ( switch_event_bind_removable ( modname , SWITCH_EVENT_CUSTOM , MULTICAST_EVENT , event_handler , NULL ,
& mod_sofia_globals . custom_node ) ! = SWITCH_STATUS_SUCCESS ) {
2007-05-01 16:12:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Couldn't bind! \n " ) ;
return SWITCH_STATUS_TERM ;
}
2008-07-22 22:23:50 +00:00
if ( switch_event_bind_removable ( modname , SWITCH_EVENT_PRESENCE_IN , SWITCH_EVENT_SUBCLASS_ANY , sofia_presence_event_handler , NULL ,
& mod_sofia_globals . in_node ) ! = SWITCH_STATUS_SUCCESS ) {
2006-10-12 00:59:09 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Couldn't bind! \n " ) ;
return SWITCH_STATUS_GENERR ;
}
2006-08-25 23:55:59 +00:00
2008-07-22 22:23:50 +00:00
if ( switch_event_bind_removable ( modname , SWITCH_EVENT_PRESENCE_OUT , SWITCH_EVENT_SUBCLASS_ANY , sofia_presence_event_handler , NULL ,
& mod_sofia_globals . out_node ) ! = SWITCH_STATUS_SUCCESS ) {
2006-10-12 00:59:09 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Couldn't bind! \n " ) ;
2006-12-19 17:48:50 +00:00
return SWITCH_STATUS_GENERR ;
}
2008-07-22 22:23:50 +00:00
if ( switch_event_bind_removable ( modname , SWITCH_EVENT_PRESENCE_PROBE , SWITCH_EVENT_SUBCLASS_ANY , sofia_presence_event_handler , NULL ,
& mod_sofia_globals . probe_node ) ! = SWITCH_STATUS_SUCCESS ) {
2006-12-19 17:48:50 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Couldn't bind! \n " ) ;
2006-10-12 00:59:09 +00:00
return SWITCH_STATUS_GENERR ;
}
2008-07-22 22:23:50 +00:00
if ( switch_event_bind_removable ( modname , SWITCH_EVENT_ROSTER , SWITCH_EVENT_SUBCLASS_ANY , sofia_presence_event_handler , NULL ,
& mod_sofia_globals . roster_node ) ! = SWITCH_STATUS_SUCCESS ) {
2007-04-02 19:54:25 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Couldn't bind! \n " ) ;
return SWITCH_STATUS_GENERR ;
}
2008-07-22 22:23:50 +00:00
if ( switch_event_bind_removable ( modname , SWITCH_EVENT_MESSAGE_WAITING , SWITCH_EVENT_SUBCLASS_ANY , sofia_presence_mwi_event_handler , NULL ,
& mod_sofia_globals . mwi_node ) ! = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Couldn't bind! \n " ) ;
return SWITCH_STATUS_GENERR ;
}
2010-06-30 10:35:03 -05:00
if ( switch_event_bind_removable ( modname , SWITCH_EVENT_CUSTOM , MY_EVENT_RECOVERY , sofia_glue_track_event_handler , NULL ,
& mod_sofia_globals . recovery_node ) ! = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Couldn't bind! \n " ) ;
return SWITCH_STATUS_GENERR ;
}
2008-07-22 22:23:50 +00:00
if ( switch_event_bind ( modname , SWITCH_EVENT_TRAP , SWITCH_EVENT_SUBCLASS_ANY , general_event_handler , NULL ) ! = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Couldn't bind! \n " ) ;
return SWITCH_STATUS_GENERR ;
}
if ( switch_event_bind ( modname , SWITCH_EVENT_NOTIFY , SWITCH_EVENT_SUBCLASS_ANY , general_event_handler , NULL ) ! = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Couldn't bind! \n " ) ;
return SWITCH_STATUS_GENERR ;
}
if ( switch_event_bind ( modname , SWITCH_EVENT_SEND_MESSAGE , SWITCH_EVENT_SUBCLASS_ANY , general_event_handler , NULL ) ! = SWITCH_STATUS_SUCCESS ) {
2006-10-12 00:59:09 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Couldn't bind! \n " ) ;
return SWITCH_STATUS_GENERR ;
}
2006-10-09 17:11:39 +00:00
2009-04-20 17:07:54 +00:00
if ( switch_event_bind ( modname , SWITCH_EVENT_SEND_INFO , SWITCH_EVENT_SUBCLASS_ANY , general_event_handler , NULL ) ! = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Couldn't bind! \n " ) ;
return SWITCH_STATUS_GENERR ;
}
2006-08-25 23:55:59 +00:00
/* connect my internal structure to the blank pointer passed to me */
2007-06-20 07:15:53 +00:00
* module_interface = switch_loadable_module_create_module_interface ( pool , modname ) ;
sofia_endpoint_interface = switch_loadable_module_create_interface ( * module_interface , SWITCH_ENDPOINT_INTERFACE ) ;
2007-06-20 18:45:35 +00:00
sofia_endpoint_interface - > interface_name = " sofia " ;
2007-06-20 07:15:53 +00:00
sofia_endpoint_interface - > io_routines = & sofia_io_routines ;
sofia_endpoint_interface - > state_handler = & sofia_event_handlers ;
management_interface = switch_loadable_module_create_interface ( * module_interface , SWITCH_MANAGEMENT_INTERFACE ) ;
management_interface - > relative_oid = " 1 " ;
management_interface - > management_function = sofia_manage ;
SWITCH_ADD_API ( api_interface , " sofia " , " Sofia Controls " , sofia_function , " <cmd> <args> " ) ;
2010-02-06 03:38:24 +00:00
SWITCH_ADD_API ( api_interface , " sofia_gateway_data " , " Get data from a sofia gateway " , sofia_gateway_data_function ,
" <gateway_name> [ivar|ovar|var] <name> " ) ;
2008-05-28 21:36:16 +00:00
switch_console_set_complete ( " add sofia help " ) ;
switch_console_set_complete ( " add sofia status " ) ;
2010-01-12 16:13:03 +00:00
switch_console_set_complete ( " add sofia xmlstatus " ) ;
2010-09-17 14:10:30 -05:00
switch_console_set_complete ( " add sofia loglevel ::[all:default:tport:iptsec:nea:nta:nth_client:nth_server:nua:soa:sresolv:stun ::[0:1:2:3:4:5:6:7:8:9 " ) ;
switch_console_set_complete ( " add sofia tracelevel ::[console:alert:crit:err:warning:notice:info:debug " ) ;
2010-09-20 16:55:09 -05:00
switch_console_set_complete ( " add sofia global siptrace ::[on:off " ) ;
2008-05-28 21:36:16 +00:00
switch_console_set_complete ( " add sofia profile " ) ;
2008-07-22 22:23:50 +00:00
switch_console_set_complete ( " add sofia profile restart all " ) ;
2008-05-28 21:36:16 +00:00
2010-09-16 18:17:52 -05:00
switch_console_set_complete ( " add sofia profile ::sofia::list_profiles start " ) ;
switch_console_set_complete ( " add sofia profile ::sofia::list_profiles stop " ) ;
switch_console_set_complete ( " add sofia profile ::sofia::list_profiles rescan " ) ;
switch_console_set_complete ( " add sofia profile ::sofia::list_profiles restart " ) ;
2009-12-14 20:10:06 +00:00
switch_console_set_complete ( " add sofia profile ::sofia::list_profiles flush_inbound_reg " ) ;
switch_console_set_complete ( " add sofia profile ::sofia::list_profiles register ::sofia::list_profile_gateway " ) ;
switch_console_set_complete ( " add sofia profile ::sofia::list_profiles unregister ::sofia::list_profile_gateway " ) ;
switch_console_set_complete ( " add sofia profile ::sofia::list_profiles killgw ::sofia::list_profile_gateway " ) ;
switch_console_set_complete ( " add sofia profile ::sofia::list_profiles siptrace on " ) ;
switch_console_set_complete ( " add sofia profile ::sofia::list_profiles siptrace off " ) ;
2010-09-17 14:11:57 -05:00
switch_console_set_complete ( " add sofia profile ::sofia::list_profiles gwlist up " ) ;
switch_console_set_complete ( " add sofia profile ::sofia::list_profiles gwlist down " ) ;
2009-12-14 20:10:06 +00:00
switch_console_set_complete ( " add sofia status profile ::sofia::list_profiles " ) ;
2010-01-13 17:01:36 +00:00
switch_console_set_complete ( " add sofia status profile ::sofia::list_profiles reg " ) ;
2009-12-14 20:10:06 +00:00
switch_console_set_complete ( " add sofia status gateway ::sofia::list_gateways " ) ;
2010-01-12 16:13:03 +00:00
switch_console_set_complete ( " add sofia xmlstatus profile ::sofia::list_profiles " ) ;
2010-01-13 19:19:06 +00:00
switch_console_set_complete ( " add sofia xmlstatus profile ::sofia::list_profiles reg " ) ;
2010-01-12 16:13:03 +00:00
switch_console_set_complete ( " add sofia xmlstatus gateway ::sofia::list_gateways " ) ;
2009-12-10 20:51:13 +00:00
2009-12-14 20:10:06 +00:00
switch_console_add_complete_func ( " ::sofia::list_profiles " , list_profiles ) ;
switch_console_add_complete_func ( " ::sofia::list_gateways " , list_gateways ) ;
switch_console_add_complete_func ( " ::sofia::list_profile_gateway " , list_profile_gateway ) ;
2009-12-10 20:51:13 +00:00
2007-10-18 01:02:01 +00:00
SWITCH_ADD_API ( api_interface , " sofia_contact " , " Sofia Contacts " , sofia_contact_function , " [profile/]<user>@<domain> " ) ;
2010-04-26 05:24:05 -04:00
SWITCH_ADD_API ( api_interface , " sofia_count_reg " , " Count Sofia registration " , sofia_count_reg_function , " [profile/]<user>@<domain> " ) ;
2010-02-24 00:01:39 +00:00
SWITCH_ADD_API ( api_interface , " sofia_dig " , " SIP DIG " , sip_dig_function , " <url> " ) ;
2007-06-20 07:15:53 +00:00
SWITCH_ADD_CHAT ( chat_interface , SOFIA_CHAT_PROTO , sofia_presence_chat_send ) ;
2006-08-25 23:55:59 +00:00
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS ;
}
2007-06-13 14:35:55 +00:00
SWITCH_MODULE_SHUTDOWN_FUNCTION ( mod_sofia_shutdown )
2006-08-25 23:55:59 +00:00
{
2007-04-13 23:19:51 +00:00
int sanity = 0 ;
2008-05-27 04:54:52 +00:00
2009-12-14 20:10:06 +00:00
switch_console_del_complete_func ( " ::sofia::list_profiles " ) ;
2009-12-10 20:51:13 +00:00
switch_console_set_complete ( " del sofia " ) ;
2007-04-01 01:16:16 +00:00
switch_mutex_lock ( mod_sofia_globals . mutex ) ;
if ( mod_sofia_globals . running = = 1 ) {
2007-04-13 23:19:51 +00:00
mod_sofia_globals . running = 0 ;
2006-09-27 03:44:14 +00:00
}
2007-04-01 01:16:16 +00:00
switch_mutex_unlock ( mod_sofia_globals . mutex ) ;
2006-09-27 03:44:14 +00:00
2008-07-03 23:54:35 +00:00
switch_event_unbind ( & mod_sofia_globals . in_node ) ;
switch_event_unbind ( & mod_sofia_globals . probe_node ) ;
switch_event_unbind ( & mod_sofia_globals . out_node ) ;
switch_event_unbind ( & mod_sofia_globals . roster_node ) ;
switch_event_unbind ( & mod_sofia_globals . custom_node ) ;
switch_event_unbind ( & mod_sofia_globals . mwi_node ) ;
2010-06-30 10:35:03 -05:00
switch_event_unbind ( & mod_sofia_globals . recovery_node ) ;
2008-07-22 22:23:50 +00:00
switch_event_unbind_callback ( general_event_handler ) ;
2010-02-06 03:38:24 +00:00
2007-04-13 23:19:51 +00:00
while ( mod_sofia_globals . threads ) {
2008-11-14 23:31:21 +00:00
switch_cond_next ( ) ;
2009-03-03 20:16:05 +00:00
if ( + + sanity > = 60000 ) {
2007-04-13 23:19:51 +00:00
break ;
}
2006-09-27 03:44:14 +00:00
}
2009-03-03 20:16:05 +00:00
//switch_yield(1000000);
2006-08-25 23:55:59 +00:00
su_deinit ( ) ;
2008-03-14 03:46:54 +00:00
switch_mutex_lock ( mod_sofia_globals . hash_mutex ) ;
2007-09-29 01:06:08 +00:00
switch_core_hash_destroy ( & mod_sofia_globals . profile_hash ) ;
switch_core_hash_destroy ( & mod_sofia_globals . gateway_hash ) ;
2008-03-14 03:46:54 +00:00
switch_mutex_unlock ( mod_sofia_globals . hash_mutex ) ;
2007-09-29 01:06:08 +00:00
2006-08-25 23:55:59 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2006-11-27 22:30:48 +00:00
/* For Emacs:
* Local Variables :
* mode : c
2008-02-03 22:14:57 +00:00
* indent - tabs - mode : t
2006-11-27 22:30:48 +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 :
2006-11-27 22:30:48 +00:00
*/