2007-03-29 22:34:40 +00:00
/*
* FreeSWITCH Modular Media Switching Software Library / Soft - Switch Application
2009-02-13 23:37:37 +00:00
* Copyright ( C ) 2005 - 2009 , Anthony Minessale II < anthm @ freeswitch . org >
2007-03-29 22:34:40 +00:00
*
* Version : MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 ( the " License " ) ; you may not use this file except in compliance with
* the License . You may obtain a copy of the License at
* http : //www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an " AS IS " basis ,
* WITHOUT WARRANTY OF ANY KIND , either express or implied . See the License
* for the specific language governing rights and limitations under the
* License .
*
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft - Switch Application
*
* The Initial Developer of the Original Code is
2009-02-04 21:20:54 +00:00
* Anthony Minessale II < anthm @ freeswitch . org >
2007-03-29 22:34:40 +00:00
* Portions created by the Initial Developer are Copyright ( C )
* the Initial Developer . All Rights Reserved .
*
* Contributor ( s ) :
*
2009-02-04 21:20:54 +00:00
* Anthony Minessale II < anthm @ freeswitch . org >
2007-03-29 22:34:40 +00:00
* Michael Jerris < mike @ jerris . com >
* Paul D . Tinsley < pdt at jackhammer . org >
*
*
* switch_core_session . c - - Main Core Library ( session routines )
*
*/
2008-01-27 17:36:53 +00:00
2007-12-30 21:42:15 +00:00
# include "switch.h"
# include "switch_core.h"
2007-05-14 17:10:46 +00:00
# include "private/switch_core_pvt.h"
2007-03-29 22:34:40 +00:00
static struct {
switch_memory_pool_t * memory_pool ;
switch_hash_t * session_table ;
uint32_t session_count ;
uint32_t session_limit ;
2007-04-22 01:25:02 +00:00
switch_size_t session_id ;
2007-05-10 16:56:29 +00:00
} session_manager ;
2007-03-29 22:34:40 +00:00
# ifdef SWITCH_DEBUG_RWLOCKS
2007-05-12 14:48:14 +00:00
SWITCH_DECLARE ( switch_core_session_t * ) switch_core_session_perform_locate ( const char * uuid_str , const char * file , const char * func , int line )
2007-03-29 22:34:40 +00:00
# else
2007-05-12 14:48:14 +00:00
SWITCH_DECLARE ( switch_core_session_t * ) switch_core_session_locate ( const char * uuid_str )
2007-03-29 22:34:40 +00:00
# endif
{
switch_core_session_t * session = NULL ;
if ( uuid_str ) {
2009-03-07 17:45:37 +00:00
switch_mutex_lock ( runtime . session_hash_mutex ) ;
2007-05-10 16:56:29 +00:00
if ( ( session = switch_core_hash_find ( session_manager . session_table , uuid_str ) ) ) {
2007-03-29 22:34:40 +00:00
/* Acquire a read lock on the session */
# ifdef SWITCH_DEBUG_RWLOCKS
2008-11-01 16:18:04 +00:00
if ( switch_core_session_perform_read_lock ( session , file , func , line ) ! = SWITCH_STATUS_SUCCESS ) {
2009-02-20 01:10:59 +00:00
# if EMACS_CC_MODE_IS_BUGGY
}
# endif
2007-03-29 22:34:40 +00:00
# else
2008-11-01 16:18:04 +00:00
if ( switch_core_session_read_lock ( session ) ! = SWITCH_STATUS_SUCCESS ) {
2007-03-29 22:34:40 +00:00
# endif
/* not available, forget it */
session = NULL ;
}
}
2009-03-07 17:45:37 +00:00
switch_mutex_unlock ( runtime . session_hash_mutex ) ;
2007-03-29 22:34:40 +00:00
}
/* if its not NULL, now it's up to you to rwunlock this */
return session ;
}
2009-04-28 14:13:05 +00:00
# ifdef SWITCH_DEBUG_RWLOCKS
SWITCH_DECLARE ( switch_core_session_t * ) switch_core_session_perform_force_locate ( const char * uuid_str , const char * file , const char * func , int line )
# else
SWITCH_DECLARE ( switch_core_session_t * ) switch_core_session_force_locate ( const char * uuid_str )
# endif
{
switch_core_session_t * session = NULL ;
switch_status_t status ;
if ( uuid_str ) {
switch_mutex_lock ( runtime . session_hash_mutex ) ;
if ( ( session = switch_core_hash_find ( session_manager . session_table , uuid_str ) ) ) {
/* Acquire a read lock on the session */
if ( switch_test_flag ( session , SSF_DESTROYED ) ) {
status = SWITCH_STATUS_FALSE ;
# ifdef SWITCH_DEBUG_RWLOCKS
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_ID_LOG , file , func , line , uuid_str , SWITCH_LOG_ERROR , " %s Read lock FAIL \n " ,
2009-04-28 14:13:05 +00:00
switch_channel_get_name ( session - > channel ) ) ;
# endif
} else {
status = ( switch_status_t ) switch_thread_rwlock_tryrdlock ( session - > rwlock ) ;
# ifdef SWITCH_DEBUG_RWLOCKS
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_ID_LOG , file , func , line , uuid_str , SWITCH_LOG_ERROR , " %s Read lock ACQUIRED \n " ,
2009-04-28 14:13:05 +00:00
switch_channel_get_name ( session - > channel ) ) ;
# endif
}
if ( status ! = SWITCH_STATUS_SUCCESS ) {
/* not available, forget it */
session = NULL ;
}
}
switch_mutex_unlock ( runtime . session_hash_mutex ) ;
}
/* if its not NULL, now it's up to you to rwunlock this */
return session ;
}
2009-04-27 17:45:04 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_session_get_partner ( switch_core_session_t * session , switch_core_session_t * * partner )
{
const char * uuid ;
if ( ( uuid = switch_channel_get_variable ( session - > channel , SWITCH_SIGNAL_BOND_VARIABLE ) ) ) {
2009-04-28 14:13:05 +00:00
if ( ( * partner = switch_core_session_locate ( uuid ) ) ) {
return SWITCH_STATUS_SUCCESS ;
}
2009-04-27 17:45:04 +00:00
}
* partner = NULL ;
return SWITCH_STATUS_FALSE ;
}
2008-07-01 23:41:09 +00:00
SWITCH_DECLARE ( void ) switch_core_session_hupall_matching_var ( const char * var_name , const char * var_val , switch_call_cause_t cause )
{
switch_hash_index_t * hi ;
void * val ;
switch_core_session_t * session ;
2009-03-09 22:51:31 +00:00
switch_memory_pool_t * pool ;
switch_queue_t * queue ;
void * pop ;
switch_core_new_memory_pool ( & pool ) ;
switch_queue_create ( & queue , 250000 , pool ) ;
2008-07-01 23:41:09 +00:00
2008-11-07 23:08:57 +00:00
if ( ! var_val ) return ;
2009-03-07 17:45:37 +00:00
switch_mutex_lock ( runtime . session_hash_mutex ) ;
2008-07-01 23:41:09 +00:00
for ( hi = switch_hash_first ( NULL , session_manager . session_table ) ; hi ; hi = switch_hash_next ( hi ) ) {
switch_hash_this ( hi , NULL , NULL , & val ) ;
if ( val ) {
const char * this_val ;
session = ( switch_core_session_t * ) val ;
2008-11-12 19:28:05 +00:00
if ( switch_core_session_read_lock ( session ) = = SWITCH_STATUS_SUCCESS ) {
2009-02-25 03:41:18 +00:00
if ( switch_channel_up ( session - > channel ) & &
2008-11-12 19:28:05 +00:00
( this_val = switch_channel_get_variable ( session - > channel , var_name ) ) & & ( ! strcmp ( this_val , var_val ) ) ) {
2009-03-09 22:51:31 +00:00
switch_queue_push ( queue , switch_core_strdup ( pool , session - > uuid_str ) ) ;
2008-11-12 19:28:05 +00:00
}
switch_core_session_rwunlock ( session ) ;
2008-07-01 23:41:09 +00:00
}
}
}
2009-03-07 17:45:37 +00:00
switch_mutex_unlock ( runtime . session_hash_mutex ) ;
2009-03-09 22:51:31 +00:00
while ( switch_queue_trypop ( queue , & pop ) = = SWITCH_STATUS_SUCCESS & & pop ) {
char * uuid = ( char * ) pop ;
if ( ( session = switch_core_session_locate ( uuid ) ) ) {
switch_channel_hangup ( session - > channel , cause ) ;
switch_core_session_rwunlock ( session ) ;
}
}
switch_core_destroy_memory_pool ( & pool ) ;
2008-07-01 23:41:09 +00:00
}
SWITCH_DECLARE ( void ) switch_core_session_hupall_endpoint ( const switch_endpoint_interface_t * endpoint_interface , switch_call_cause_t cause )
{
switch_hash_index_t * hi ;
void * val ;
switch_core_session_t * session ;
2009-03-09 22:51:31 +00:00
switch_memory_pool_t * pool ;
switch_queue_t * queue ;
void * pop ;
switch_core_new_memory_pool ( & pool ) ;
switch_queue_create ( & queue , 250000 , pool ) ;
2008-07-01 23:41:09 +00:00
2009-03-07 17:45:37 +00:00
switch_mutex_lock ( runtime . session_hash_mutex ) ;
2008-07-01 23:41:09 +00:00
for ( hi = switch_hash_first ( NULL , session_manager . session_table ) ; hi ; hi = switch_hash_next ( hi ) ) {
switch_hash_this ( hi , NULL , NULL , & val ) ;
if ( val ) {
session = ( switch_core_session_t * ) val ;
2009-01-09 20:34:01 +00:00
if ( switch_core_session_read_lock ( session ) = = SWITCH_STATUS_SUCCESS ) {
if ( session - > endpoint_interface = = endpoint_interface ) {
2009-03-09 22:51:31 +00:00
switch_queue_push ( queue , switch_core_strdup ( pool , session - > uuid_str ) ) ;
2009-01-09 20:34:01 +00:00
}
switch_core_session_rwunlock ( session ) ;
2008-07-01 23:41:09 +00:00
}
}
}
2009-03-07 17:45:37 +00:00
switch_mutex_unlock ( runtime . session_hash_mutex ) ;
2009-03-09 22:51:31 +00:00
while ( switch_queue_trypop ( queue , & pop ) = = SWITCH_STATUS_SUCCESS & & pop ) {
char * uuid = ( char * ) pop ;
if ( ( session = switch_core_session_locate ( uuid ) ) ) {
switch_channel_hangup ( session - > channel , cause ) ;
switch_core_session_rwunlock ( session ) ;
}
}
switch_core_destroy_memory_pool ( & pool ) ;
2008-07-01 23:41:09 +00:00
}
2007-03-29 22:34:40 +00:00
SWITCH_DECLARE ( void ) switch_core_session_hupall ( switch_call_cause_t cause )
{
switch_hash_index_t * hi ;
void * val ;
switch_core_session_t * session ;
2009-03-09 22:51:31 +00:00
switch_memory_pool_t * pool ;
switch_queue_t * queue ;
void * pop ;
2009-02-20 01:10:59 +00:00
2009-03-09 22:51:31 +00:00
switch_core_new_memory_pool ( & pool ) ;
switch_queue_create ( & queue , 250000 , pool ) ;
switch_mutex_lock ( runtime . session_hash_mutex ) ;
for ( hi = switch_hash_first ( NULL , session_manager . session_table ) ; hi ; hi = switch_hash_next ( hi ) ) {
switch_hash_this ( hi , NULL , NULL , & val ) ;
if ( val ) {
session = ( switch_core_session_t * ) val ;
if ( switch_core_session_read_lock ( session ) = = SWITCH_STATUS_SUCCESS ) {
switch_queue_push ( queue , switch_core_strdup ( pool , session - > uuid_str ) ) ;
switch_core_session_rwunlock ( session ) ;
2009-01-09 20:34:01 +00:00
}
2007-03-29 22:34:40 +00:00
}
2009-03-09 22:51:31 +00:00
}
switch_mutex_unlock ( runtime . session_hash_mutex ) ;
while ( switch_queue_trypop ( queue , & pop ) = = SWITCH_STATUS_SUCCESS & & pop ) {
char * uuid = ( char * ) pop ;
if ( ( session = switch_core_session_locate ( uuid ) ) ) {
switch_channel_hangup ( session - > channel , cause ) ;
switch_core_session_rwunlock ( session ) ;
2007-03-29 22:34:40 +00:00
}
}
2009-03-09 22:51:31 +00:00
switch_core_destroy_memory_pool ( & pool ) ;
2007-03-29 22:34:40 +00:00
}
2009-02-20 01:10:59 +00:00
2007-12-30 21:42:15 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_session_message_send ( const char * uuid_str , switch_core_session_message_t * message )
2007-03-29 22:34:40 +00:00
{
switch_core_session_t * session = NULL ;
switch_status_t status = SWITCH_STATUS_FALSE ;
2009-03-07 17:45:37 +00:00
switch_mutex_lock ( runtime . session_hash_mutex ) ;
2007-05-10 16:56:29 +00:00
if ( ( session = switch_core_hash_find ( session_manager . session_table , uuid_str ) ) ! = 0 ) {
2007-03-29 22:34:40 +00:00
/* Acquire a read lock on the session or forget it the channel is dead */
if ( switch_core_session_read_lock ( session ) = = SWITCH_STATUS_SUCCESS ) {
2009-02-25 03:41:18 +00:00
if ( switch_channel_up ( session - > channel ) ) {
2007-03-29 22:34:40 +00:00
status = switch_core_session_receive_message ( session , message ) ;
}
switch_core_session_rwunlock ( session ) ;
}
}
2009-03-07 17:45:37 +00:00
switch_mutex_unlock ( runtime . session_hash_mutex ) ;
2007-03-29 22:34:40 +00:00
return status ;
}
2007-12-30 21:42:15 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_session_event_send ( const char * uuid_str , switch_event_t * * event )
2007-03-29 22:34:40 +00:00
{
switch_core_session_t * session = NULL ;
switch_status_t status = SWITCH_STATUS_FALSE ;
2009-03-07 17:45:37 +00:00
switch_mutex_lock ( runtime . session_hash_mutex ) ;
2007-05-10 16:56:29 +00:00
if ( ( session = switch_core_hash_find ( session_manager . session_table , uuid_str ) ) ! = 0 ) {
2007-03-29 22:34:40 +00:00
/* Acquire a read lock on the session or forget it the channel is dead */
if ( switch_core_session_read_lock ( session ) = = SWITCH_STATUS_SUCCESS ) {
2009-02-25 03:41:18 +00:00
if ( switch_channel_up ( session - > channel ) ) {
2007-03-29 22:34:40 +00:00
status = switch_core_session_queue_event ( session , event ) ;
}
switch_core_session_rwunlock ( session ) ;
}
}
2009-03-07 17:45:37 +00:00
switch_mutex_unlock ( runtime . session_hash_mutex ) ;
2007-03-29 22:34:40 +00:00
return status ;
}
SWITCH_DECLARE ( void * ) switch_core_session_get_private ( switch_core_session_t * session )
{
2007-12-11 19:23:57 +00:00
switch_assert ( session ! = NULL ) ;
2007-03-29 22:34:40 +00:00
return session - > private_info ;
}
2009-02-10 19:09:06 +00:00
2007-03-29 22:34:40 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_session_set_private ( switch_core_session_t * session , void * private_info )
{
2007-12-11 19:23:57 +00:00
switch_assert ( session ! = NULL ) ;
2007-03-29 22:34:40 +00:00
session - > private_info = private_info ;
return SWITCH_STATUS_SUCCESS ;
}
SWITCH_DECLARE ( int ) switch_core_session_add_stream ( switch_core_session_t * session , void * private_info )
{
session - > streams [ session - > stream_count + + ] = private_info ;
return session - > stream_count - 1 ;
}
SWITCH_DECLARE ( void * ) switch_core_session_get_stream ( switch_core_session_t * session , int index )
{
return session - > streams [ index ] ;
}
SWITCH_DECLARE ( int ) switch_core_session_get_stream_count ( switch_core_session_t * session )
{
return session - > stream_count ;
}
2008-03-06 03:11:20 +00:00
SWITCH_DECLARE ( switch_call_cause_t ) switch_core_session_resurrect_channel ( const char * endpoint_name ,
2008-05-27 04:30:03 +00:00
switch_core_session_t * * new_session , switch_memory_pool_t * * pool , void * data )
2008-03-06 03:11:20 +00:00
{
const switch_endpoint_interface_t * endpoint_interface ;
if ( ( endpoint_interface = switch_loadable_module_get_endpoint_interface ( endpoint_name ) ) = = 0 ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Could not locate channel type %s \n " , endpoint_name ) ;
return SWITCH_CAUSE_CHAN_NOT_IMPLEMENTED ;
}
return endpoint_interface - > io_routines - > resurrect_session ( new_session , pool , data ) ;
}
2008-05-27 04:30:03 +00:00
SWITCH_DECLARE ( switch_call_cause_t ) switch_core_session_outgoing_channel ( switch_core_session_t * session , switch_event_t * var_event ,
const char * endpoint_name ,
switch_caller_profile_t * caller_profile ,
switch_core_session_t * * new_session ,
switch_memory_pool_t * * pool , switch_originate_flag_t flags )
2007-03-29 22:34:40 +00:00
{
switch_io_event_hook_outgoing_channel_t * ptr ;
switch_status_t status = SWITCH_STATUS_FALSE ;
2008-11-19 19:22:20 +00:00
switch_endpoint_interface_t * endpoint_interface ;
2007-03-29 22:34:40 +00:00
switch_channel_t * channel = NULL ;
switch_caller_profile_t * outgoing_profile = caller_profile ;
switch_call_cause_t cause = SWITCH_CAUSE_REQUESTED_CHAN_UNAVAIL ;
2007-12-24 19:23:36 +00:00
const char * forwardvar ;
int forwardval = 70 ;
2007-03-29 22:34:40 +00:00
if ( ( endpoint_interface = switch_loadable_module_get_endpoint_interface ( endpoint_name ) ) = = 0 ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Could not locate channel type %s \n " , endpoint_name ) ;
2007-03-29 22:34:40 +00:00
return SWITCH_CAUSE_CHAN_NOT_IMPLEMENTED ;
}
2007-12-24 19:23:36 +00:00
if ( ! endpoint_interface - > io_routines - > outgoing_channel ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Could not locate outgoing channel interface for %s \n " , endpoint_name ) ;
2007-12-24 19:23:36 +00:00
return SWITCH_CAUSE_CHAN_NOT_IMPLEMENTED ;
}
2007-03-29 22:34:40 +00:00
2007-12-24 19:23:36 +00:00
if ( session ) {
channel = switch_core_session_get_channel ( session ) ;
2007-12-24 23:32:01 +00:00
2008-05-16 15:29:44 +00:00
switch_assert ( channel ! = NULL ) ;
2008-05-27 04:30:03 +00:00
2007-12-24 23:32:01 +00:00
forwardvar = switch_channel_get_variable ( channel , SWITCH_MAX_FORWARDS_VARIABLE ) ;
2009-10-23 16:03:42 +00:00
if ( ! zstr ( forwardvar ) ) {
2008-05-27 04:30:03 +00:00
forwardval = atoi ( forwardvar ) - 1 ;
2007-12-24 23:32:01 +00:00
}
if ( forwardval < = 0 ) {
return SWITCH_CAUSE_EXCHANGE_ROUTING_ERROR ;
}
2007-12-24 19:23:36 +00:00
if ( caller_profile ) {
const char * ecaller_id_name = NULL , * ecaller_id_number = NULL ;
2008-08-11 21:27:20 +00:00
if ( ! ( flags & SOF_NO_EFFECTIVE_CID_NAME ) ) {
ecaller_id_name = switch_channel_get_variable ( channel , " effective_caller_id_name " ) ;
}
2007-08-28 21:43:18 +00:00
2008-08-11 21:27:20 +00:00
if ( ! ( flags & SOF_NO_EFFECTIVE_CID_NUM ) ) {
ecaller_id_number = switch_channel_get_variable ( channel , " effective_caller_id_number " ) ;
}
2007-12-24 19:23:36 +00:00
if ( ecaller_id_name | | ecaller_id_number ) {
outgoing_profile = switch_caller_profile_clone ( session , caller_profile ) ;
if ( ecaller_id_name ) {
outgoing_profile - > caller_id_name = ecaller_id_name ;
}
if ( ecaller_id_number ) {
outgoing_profile - > caller_id_number = ecaller_id_number ;
2007-03-29 22:34:40 +00:00
}
}
}
2007-12-24 19:23:36 +00:00
if ( ! outgoing_profile ) {
outgoing_profile = switch_channel_get_caller_profile ( channel ) ;
2007-04-16 20:51:19 +00:00
}
2007-12-24 19:23:36 +00:00
}
2007-04-16 20:51:19 +00:00
2008-05-27 04:30:03 +00:00
if ( ( cause =
endpoint_interface - > io_routines - > outgoing_channel ( session , var_event , outgoing_profile , new_session , pool , flags ) ) ! = SWITCH_CAUSE_SUCCESS ) {
2008-11-19 19:22:20 +00:00
UNPROTECT_INTERFACE ( endpoint_interface ) ;
2007-12-24 19:23:36 +00:00
return cause ;
}
if ( session ) {
for ( ptr = session - > event_hooks . outgoing_channel ; ptr ; ptr = ptr - > next ) {
2008-05-15 19:29:35 +00:00
if ( ( status = ptr - > outgoing_channel ( session , var_event , caller_profile , * new_session , flags ) ) ! = SWITCH_STATUS_SUCCESS ) {
2007-12-24 19:23:36 +00:00
break ;
2007-03-29 22:34:40 +00:00
}
}
}
2008-02-06 01:05:01 +00:00
if ( ! * new_session ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_CRIT , " Outgoing method for endpoint: [%s] returned: [%s] but there is no new session! \n " ,
2008-02-06 01:05:01 +00:00
endpoint_name , switch_channel_cause2str ( cause ) ) ;
2008-11-19 19:22:20 +00:00
UNPROTECT_INTERFACE ( endpoint_interface ) ;
2008-02-06 01:05:01 +00:00
return SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ;
} else {
2007-03-29 22:34:40 +00:00
switch_caller_profile_t * profile = NULL , * peer_profile = NULL , * cloned_profile = NULL ;
switch_event_t * event ;
switch_channel_t * peer_channel = switch_core_session_get_channel ( * new_session ) ;
2008-11-04 16:46:33 +00:00
const char * use_uuid ;
2008-05-27 04:30:03 +00:00
2008-05-16 15:29:44 +00:00
switch_assert ( peer_channel ) ;
2008-05-27 04:30:03 +00:00
2008-05-16 15:29:44 +00:00
peer_profile = switch_channel_get_caller_profile ( peer_channel ) ;
2008-11-04 16:46:33 +00:00
if ( ( use_uuid = switch_event_get_header ( var_event , " origination_uuid " ) ) ) {
2009-03-13 01:57:10 +00:00
use_uuid = switch_core_session_strdup ( * new_session , use_uuid ) ;
2008-11-04 16:46:33 +00:00
if ( switch_core_session_set_uuid ( * new_session , use_uuid ) = = SWITCH_STATUS_SUCCESS ) {
switch_event_del_header ( var_event , " origination_uuid " ) ;
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( * new_session ) , SWITCH_LOG_DEBUG , " %s set UUID=%s \n " , switch_channel_get_name ( peer_channel ) , use_uuid ) ;
2008-11-04 16:46:33 +00:00
} else {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( * new_session ) , SWITCH_LOG_CRIT , " %s set UUID=%s FAILED \n " , switch_channel_get_name ( peer_channel ) , use_uuid ) ;
2008-11-04 16:46:33 +00:00
}
}
2008-05-16 15:29:44 +00:00
if ( channel ) {
2007-11-01 11:28:26 +00:00
const char * export_vars , * val ;
2009-02-10 19:09:06 +00:00
switch_codec_t * vid_read_codec = NULL , * read_codec = switch_core_session_get_read_codec ( session ) ;
2007-12-24 19:23:36 +00:00
const char * max_forwards = switch_core_session_sprintf ( session , " %d " , forwardval ) ;
2008-05-16 15:29:44 +00:00
2007-12-24 19:23:36 +00:00
switch_channel_set_variable ( peer_channel , SWITCH_MAX_FORWARDS_VARIABLE , max_forwards ) ;
2007-03-29 22:34:40 +00:00
2008-05-16 15:29:44 +00:00
profile = switch_channel_get_caller_profile ( channel ) ;
2009-02-10 19:19:53 +00:00
vid_read_codec = switch_core_session_get_video_read_codec ( session ) ;
2009-04-09 17:17:12 +00:00
if ( read_codec & & read_codec - > implementation & & switch_core_codec_ready ( read_codec ) ) {
2009-02-10 19:19:53 +00:00
char rc [ 80 ] = " " , vrc [ 80 ] = " " , tmp [ 160 ] = " " ;
switch_codec2str ( read_codec , rc , sizeof ( rc ) ) ;
2009-04-09 17:17:12 +00:00
if ( vid_read_codec & & vid_read_codec - > implementation & & switch_core_codec_ready ( vid_read_codec ) ) {
2009-02-10 19:19:53 +00:00
vrc [ 0 ] = ' , ' ;
switch_codec2str ( read_codec , vrc + 1 , sizeof ( vrc ) - 1 ) ;
switch_channel_set_variable ( peer_channel , SWITCH_ORIGINATOR_VIDEO_CODEC_VARIABLE , vrc + 1 ) ;
}
switch_snprintf ( tmp , sizeof ( tmp ) , " %s%s " , rc , vrc ) ;
2007-03-29 22:34:40 +00:00
switch_channel_set_variable ( peer_channel , SWITCH_ORIGINATOR_CODEC_VARIABLE , tmp ) ;
}
2007-03-30 00:13:31 +00:00
switch_channel_set_variable ( peer_channel , SWITCH_ORIGINATOR_VARIABLE , switch_core_session_get_uuid ( session ) ) ;
switch_channel_set_variable ( peer_channel , SWITCH_SIGNAL_BOND_VARIABLE , switch_core_session_get_uuid ( session ) ) ;
switch_channel_set_variable ( channel , SWITCH_SIGNAL_BOND_VARIABLE , switch_core_session_get_uuid ( * new_session ) ) ;
2007-03-29 22:34:40 +00:00
/* A comma (,) separated list of variable names that should ne propagated from originator to originatee */
if ( ( export_vars = switch_channel_get_variable ( channel , SWITCH_EXPORT_VARS_VARIABLE ) ) ) {
char * cptmp = switch_core_session_strdup ( session , export_vars ) ;
int argc ;
char * argv [ 256 ] ;
if ( ( argc = switch_separate_string ( cptmp , ' , ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ) ) {
int x ;
for ( x = 0 ; x < argc ; x + + ) {
2007-12-11 21:31:57 +00:00
const char * vval ;
if ( ( vval = switch_channel_get_variable ( channel , argv [ x ] ) ) ) {
char * vvar = argv [ x ] ;
if ( ! strncasecmp ( vvar , " nolocal: " , 8 ) ) {
vvar + = 8 ;
2007-05-10 14:11:26 +00:00
}
2007-12-11 21:31:57 +00:00
switch_channel_set_variable ( peer_channel , vvar , vval ) ;
2007-03-29 22:34:40 +00:00
}
}
}
}
2008-01-14 16:10:56 +00:00
if ( ( val = switch_channel_get_variable ( channel , SWITCH_PROCESS_CDR_VARIABLE ) ) ) {
switch_channel_set_variable ( peer_channel , SWITCH_PROCESS_CDR_VARIABLE , val ) ;
}
2007-03-29 22:34:40 +00:00
if ( ( val = switch_channel_get_variable ( channel , SWITCH_R_SDP_VARIABLE ) ) ) {
switch_channel_set_variable ( peer_channel , SWITCH_B_SDP_VARIABLE , val ) ;
}
2008-02-21 17:48:41 +00:00
if ( switch_channel_test_flag ( channel , CF_PROXY_MODE ) ) {
2009-10-19 19:58:23 +00:00
if ( switch_channel_test_cap ( peer_channel , CC_BYPASS_MEDIA ) ) {
2009-10-20 17:03:03 +00:00
switch_channel_set_flag ( peer_channel , CF_PROXY_MODE ) ;
2009-10-19 19:58:23 +00:00
} else {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING ,
" %s does not support the proxy feature, disabling. \n " ,
switch_channel_get_name ( peer_channel ) ) ;
switch_channel_clear_flag ( channel , CF_PROXY_MODE ) ;
2009-10-20 17:03:03 +00:00
}
}
if ( switch_channel_test_flag ( channel , CF_PROXY_MEDIA ) ) {
if ( switch_channel_test_cap ( peer_channel , CC_PROXY_MEDIA ) ) {
switch_channel_set_flag ( peer_channel , CF_PROXY_MEDIA ) ;
if ( switch_channel_test_flag ( channel , CF_VIDEO ) ) {
switch_channel_set_flag ( peer_channel , CF_VIDEO ) ;
}
} else {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING ,
" %s does not support the proxy feature, disabling. \n " ,
switch_channel_get_name ( peer_channel ) ) ;
2009-10-19 19:58:23 +00:00
switch_channel_clear_flag ( channel , CF_PROXY_MEDIA ) ;
2008-05-23 19:41:23 +00:00
}
2007-03-29 22:34:40 +00:00
}
if ( profile ) {
if ( ( cloned_profile = switch_caller_profile_clone ( * new_session , profile ) ) ! = 0 ) {
switch_channel_set_originator_caller_profile ( peer_channel , cloned_profile ) ;
}
}
2008-05-27 04:30:03 +00:00
2009-03-12 16:47:47 +00:00
if ( peer_profile & & ! ( flags & SOF_FORKED_DIAL ) ) {
2008-05-16 15:29:44 +00:00
if ( ( cloned_profile = switch_caller_profile_clone ( session , peer_profile ) ) ! = 0 ) {
2007-03-29 22:34:40 +00:00
switch_channel_set_originatee_caller_profile ( channel , cloned_profile ) ;
}
}
2007-10-16 01:51:15 +00:00
}
2007-03-29 22:34:40 +00:00
2007-10-16 01:51:15 +00:00
if ( switch_event_create ( & event , SWITCH_EVENT_CHANNEL_OUTGOING ) = = SWITCH_STATUS_SUCCESS ) {
switch_channel_event_set_data ( peer_channel , event ) ;
switch_event_fire ( & event ) ;
2007-03-29 22:34:40 +00:00
}
}
2008-11-19 19:22:20 +00:00
UNPROTECT_INTERFACE ( endpoint_interface ) ;
2007-03-29 22:34:40 +00:00
return cause ;
}
2008-11-05 00:20:30 +00:00
static const char * message_names [ ] = {
2008-12-30 19:50:33 +00:00
" REDIRECT_AUDIO " ,
" TRANSMIT_TEXT " ,
" ANSWER " ,
" PROGRESS " ,
" BRIDGE " ,
" UNBRIDGE " ,
" TRANSFER " ,
" RINGING " ,
" MEDIA " ,
" NOMEDIA " ,
" HOLD " ,
" UNHOLD " ,
" REDIRECT " ,
" RESPOND " ,
" BROADCAST " ,
" MEDIA_REDIRECT " ,
" DEFLECT " ,
" VIDEO_REFRESH_REQ " ,
" DISPLAY " ,
" TRANSCODING_NECESSARY " ,
" AUDIO_SYNC " ,
" REQUEST_IMAGE_MEDIA " ,
" INVALID "
2008-11-05 00:20:30 +00:00
} ;
SWITCH_DECLARE ( switch_status_t ) switch_core_session_perform_receive_message ( switch_core_session_t * session ,
switch_core_session_message_t * message ,
const char * file , const char * func , int line )
2007-03-29 22:34:40 +00:00
{
2007-04-16 16:53:30 +00:00
switch_io_event_hook_receive_message_t * ptr ;
2007-03-29 22:34:40 +00:00
switch_status_t status = SWITCH_STATUS_SUCCESS ;
2007-12-11 19:23:57 +00:00
switch_assert ( session ! = NULL ) ;
2007-03-29 22:34:40 +00:00
2009-02-25 03:41:18 +00:00
if ( switch_channel_down ( session - > channel ) ) {
2008-02-26 20:31:53 +00:00
return SWITCH_STATUS_FALSE ;
}
2008-02-25 16:35:19 +00:00
if ( ( status = switch_core_session_read_lock ( session ) ) ! = SWITCH_STATUS_SUCCESS ) {
return status ;
}
2008-05-27 04:30:03 +00:00
2009-10-13 20:28:45 +00:00
if ( ! message - > _file ) {
message - > _file = file ;
}
if ( ! message - > _func ) {
message - > _func = func ;
}
if ( ! message - > _line ) {
message - > _line = line ;
}
2008-11-05 00:20:30 +00:00
if ( message - > message_id > SWITCH_MESSAGE_INVALID ) {
message - > message_id = SWITCH_MESSAGE_INVALID ;
}
2009-10-13 20:28:45 +00:00
switch_log_printf ( SWITCH_CHANNEL_ID_LOG , message - > _file , message - > _func , message - > _line ,
switch_core_session_get_uuid ( session ) , SWITCH_LOG_DEBUG , " %s receive message [%s] \n " ,
2008-11-05 00:20:30 +00:00
switch_channel_get_name ( session - > channel ) , message_names [ message - > message_id ] ) ;
2007-04-16 16:53:30 +00:00
if ( session - > endpoint_interface - > io_routines - > receive_message ) {
status = session - > endpoint_interface - > io_routines - > receive_message ( session , message ) ;
2007-03-29 22:34:40 +00:00
}
if ( status = = SWITCH_STATUS_SUCCESS ) {
2007-04-16 16:53:30 +00:00
for ( ptr = session - > event_hooks . receive_message ; ptr ; ptr = ptr - > next ) {
if ( ( status = ptr - > receive_message ( session , message ) ) ! = SWITCH_STATUS_SUCCESS ) {
2007-03-29 22:34:40 +00:00
break ;
}
}
}
2008-11-05 00:20:30 +00:00
message - > _file = NULL ;
message - > _func = NULL ;
message - > _line = 0 ;
2008-11-19 22:27:17 +00:00
switch ( message - > message_id ) {
case SWITCH_MESSAGE_REDIRECT_AUDIO :
case SWITCH_MESSAGE_INDICATE_ANSWER :
case SWITCH_MESSAGE_INDICATE_PROGRESS :
case SWITCH_MESSAGE_INDICATE_BRIDGE :
case SWITCH_MESSAGE_INDICATE_UNBRIDGE :
case SWITCH_MESSAGE_INDICATE_TRANSFER :
case SWITCH_MESSAGE_INDICATE_RINGING :
case SWITCH_MESSAGE_INDICATE_MEDIA :
case SWITCH_MESSAGE_INDICATE_NOMEDIA :
case SWITCH_MESSAGE_INDICATE_HOLD :
case SWITCH_MESSAGE_INDICATE_UNHOLD :
case SWITCH_MESSAGE_INDICATE_REDIRECT :
case SWITCH_MESSAGE_INDICATE_RESPOND :
case SWITCH_MESSAGE_INDICATE_BROADCAST :
case SWITCH_MESSAGE_INDICATE_MEDIA_REDIRECT :
case SWITCH_MESSAGE_INDICATE_DEFLECT :
switch_core_session_kill_channel ( session , SWITCH_SIG_BREAK ) ;
break ;
default :
break ;
}
2009-10-12 22:23:55 +00:00
switch_core_session_free_message ( & message ) ;
2008-02-25 16:35:19 +00:00
switch_core_session_rwunlock ( session ) ;
2007-03-29 22:34:40 +00:00
return status ;
}
2007-04-16 16:53:30 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_session_pass_indication ( switch_core_session_t * session , switch_core_session_message_types_t indication )
2007-03-29 22:34:40 +00:00
{
2008-05-27 04:30:03 +00:00
switch_core_session_message_t msg = { 0 } ;
2007-04-16 16:53:30 +00:00
switch_core_session_t * other_session ;
2007-11-01 11:28:26 +00:00
const char * uuid ;
2008-01-28 07:26:10 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
2007-03-29 22:34:40 +00:00
switch_status_t status = SWITCH_STATUS_SUCCESS ;
2007-04-16 16:53:30 +00:00
if ( ( uuid = switch_channel_get_variable ( channel , SWITCH_SIGNAL_BOND_VARIABLE ) ) & & ( other_session = switch_core_session_locate ( uuid ) ) ) {
msg . message_id = indication ;
msg . from = __FILE__ ;
status = switch_core_session_receive_message ( other_session , & msg ) ;
switch_core_session_rwunlock ( other_session ) ;
} else {
status = SWITCH_STATUS_FALSE ;
2007-03-29 22:34:40 +00:00
}
2008-05-27 04:30:03 +00:00
2007-03-29 22:34:40 +00:00
return status ;
}
2007-03-30 00:13:31 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_session_queue_indication ( switch_core_session_t * session , switch_core_session_message_types_t indication )
2007-03-29 22:34:40 +00:00
{
switch_core_session_message_t * msg ;
if ( ( msg = malloc ( sizeof ( * msg ) ) ) ) {
memset ( msg , 0 , sizeof ( * msg ) ) ;
msg - > message_id = indication ;
msg - > from = __FILE__ ;
switch_set_flag ( msg , SCSMF_DYNAMIC ) ;
2007-04-16 16:53:30 +00:00
switch_core_session_queue_message ( session , msg ) ;
2007-03-29 22:34:40 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2008-05-27 04:30:03 +00:00
2007-03-29 22:34:40 +00:00
return SWITCH_STATUS_FALSE ;
}
2007-03-30 00:13:31 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_session_queue_message ( switch_core_session_t * session , switch_core_session_message_t * message )
2007-03-29 22:34:40 +00:00
{
switch_status_t status = SWITCH_STATUS_FALSE ;
2007-12-11 19:23:57 +00:00
switch_assert ( session ! = NULL ) ;
2007-03-29 22:34:40 +00:00
if ( session - > message_queue ) {
if ( switch_queue_trypush ( session - > message_queue , message ) = = SWITCH_STATUS_SUCCESS ) {
status = SWITCH_STATUS_SUCCESS ;
}
2009-10-12 22:23:55 +00:00
2009-10-20 17:03:03 +00:00
switch_core_session_kill_channel ( session , SWITCH_SIG_BREAK ) ;
if ( switch_channel_test_flag ( session - > channel , CF_PROXY_MODE ) | | switch_channel_test_flag ( session - > channel , CF_THREAD_SLEEPING ) ) {
2009-10-12 22:23:55 +00:00
switch_core_session_wake_session_thread ( session ) ;
}
2007-03-29 22:34:40 +00:00
}
2008-05-27 04:30:03 +00:00
2007-03-29 22:34:40 +00:00
return status ;
}
2009-10-12 22:23:55 +00:00
SWITCH_DECLARE ( void ) switch_core_session_free_message ( switch_core_session_message_t * * message )
{
switch_core_session_message_t * to_free = * message ;
int i ;
char * s ;
* message = NULL ;
if ( switch_test_flag ( to_free , SCSMF_DYNAMIC ) ) {
s = ( char * ) to_free - > string_arg ;
switch_safe_free ( s ) ;
switch_safe_free ( to_free - > pointer_arg ) ;
for ( i = 0 ; i < MESSAGE_STRING_ARG_MAX ; i + + ) {
s = ( char * ) to_free - > string_array_arg [ i ] ;
switch_safe_free ( s ) ;
}
switch_safe_free ( to_free ) ;
}
}
2007-03-30 00:13:31 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_session_dequeue_message ( switch_core_session_t * session , switch_core_session_message_t * * message )
2007-03-29 22:34:40 +00:00
{
switch_status_t status = SWITCH_STATUS_FALSE ;
void * pop ;
2007-12-11 19:23:57 +00:00
switch_assert ( session ! = NULL ) ;
2007-03-29 22:34:40 +00:00
if ( session - > message_queue ) {
if ( ( status = ( switch_status_t ) switch_queue_trypop ( session - > message_queue , & pop ) ) = = SWITCH_STATUS_SUCCESS ) {
* message = ( switch_core_session_message_t * ) pop ;
2009-10-21 18:48:28 +00:00
if ( ( * message ) - > delivery_time & & ( * message ) - > delivery_time > switch_epoch_time_now ( NULL ) ) {
switch_core_session_queue_message ( session , * message ) ;
* message = NULL ;
status = SWITCH_STATUS_FALSE ;
}
2007-03-29 22:34:40 +00:00
}
}
return status ;
}
SWITCH_DECLARE ( switch_status_t ) switch_core_session_flush_message ( switch_core_session_t * session )
{
switch_core_session_message_t * message ;
2009-10-12 22:23:55 +00:00
while ( switch_core_session_dequeue_message ( session , & message ) = = SWITCH_STATUS_SUCCESS ) {
switch_core_session_free_message ( & message ) ;
2007-03-29 22:34:40 +00:00
}
return SWITCH_STATUS_SUCCESS ;
}
2007-03-30 00:13:31 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_session_receive_event ( switch_core_session_t * session , switch_event_t * * event )
2007-03-29 22:34:40 +00:00
{
switch_io_event_hook_receive_event_t * ptr ;
switch_status_t status = SWITCH_STATUS_FALSE ;
2007-12-11 19:23:57 +00:00
switch_assert ( session ! = NULL ) ;
2007-03-29 22:34:40 +00:00
/* Acquire a read lock on the session or forget it the channel is dead */
if ( switch_core_session_read_lock ( session ) = = SWITCH_STATUS_SUCCESS ) {
2009-02-25 03:41:18 +00:00
if ( switch_channel_up ( session - > channel ) ) {
2007-03-29 22:34:40 +00:00
if ( session - > endpoint_interface - > io_routines - > receive_event ) {
status = session - > endpoint_interface - > io_routines - > receive_event ( session , * event ) ;
}
if ( status = = SWITCH_STATUS_SUCCESS ) {
for ( ptr = session - > event_hooks . receive_event ; ptr ; ptr = ptr - > next ) {
if ( ( status = ptr - > receive_event ( session , * event ) ) ! = SWITCH_STATUS_SUCCESS ) {
break ;
}
}
}
if ( status = = SWITCH_STATUS_BREAK ) {
status = SWITCH_STATUS_SUCCESS ;
}
if ( status = = SWITCH_STATUS_SUCCESS ) {
switch_event_destroy ( event ) ;
}
}
switch_core_session_rwunlock ( session ) ;
}
switch_core_session_kill_channel ( session , SWITCH_SIG_BREAK ) ;
return status ;
}
SWITCH_DECLARE ( switch_status_t ) switch_core_session_queue_event ( switch_core_session_t * session , switch_event_t * * event )
{
switch_status_t status = SWITCH_STATUS_FALSE ;
2007-12-11 19:23:57 +00:00
switch_assert ( session ! = NULL ) ;
2007-03-29 22:34:40 +00:00
if ( session - > event_queue ) {
if ( switch_queue_trypush ( session - > event_queue , * event ) = = SWITCH_STATUS_SUCCESS ) {
* event = NULL ;
status = SWITCH_STATUS_SUCCESS ;
}
}
return status ;
}
2007-05-15 00:05:32 +00:00
SWITCH_DECLARE ( uint32_t ) switch_core_session_event_count ( switch_core_session_t * session )
2007-03-29 22:34:40 +00:00
{
if ( session - > event_queue ) {
2007-05-15 00:05:32 +00:00
return switch_queue_size ( session - > event_queue ) ;
2007-03-29 22:34:40 +00:00
}
2007-05-15 00:05:32 +00:00
return 0 ;
2007-03-29 22:34:40 +00:00
}
2009-02-21 23:19:58 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_session_dequeue_event ( switch_core_session_t * session , switch_event_t * * event , switch_bool_t force )
2007-03-29 22:34:40 +00:00
{
switch_status_t status = SWITCH_STATUS_FALSE ;
void * pop ;
2007-12-11 19:23:57 +00:00
switch_assert ( session ! = NULL ) ;
2007-03-29 22:34:40 +00:00
2009-02-21 23:19:58 +00:00
if ( session - > event_queue & & ( force | | ! switch_channel_test_flag ( session - > channel , CF_DIVERT_EVENTS ) ) ) {
2007-03-29 22:34:40 +00:00
if ( ( status = ( switch_status_t ) switch_queue_trypop ( session - > event_queue , & pop ) ) = = SWITCH_STATUS_SUCCESS ) {
* event = ( switch_event_t * ) pop ;
}
}
return status ;
}
2007-03-30 00:13:31 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_session_queue_private_event ( switch_core_session_t * session , switch_event_t * * event )
2007-03-29 22:34:40 +00:00
{
switch_status_t status = SWITCH_STATUS_FALSE ;
2007-12-11 19:23:57 +00:00
switch_assert ( session ! = NULL ) ;
2007-03-29 22:34:40 +00:00
if ( session - > private_event_queue ) {
( * event ) - > event_id = SWITCH_EVENT_PRIVATE_COMMAND ;
if ( switch_queue_trypush ( session - > private_event_queue , * event ) = = SWITCH_STATUS_SUCCESS ) {
* event = NULL ;
switch_core_session_kill_channel ( session , SWITCH_SIG_BREAK ) ;
status = SWITCH_STATUS_SUCCESS ;
}
}
return status ;
}
2007-05-15 00:05:32 +00:00
SWITCH_DECLARE ( uint32_t ) switch_core_session_private_event_count ( switch_core_session_t * session )
2007-03-29 22:34:40 +00:00
{
2008-05-16 13:16:27 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
if ( ! switch_channel_test_flag ( channel , CF_EVENT_LOCK ) & & session - > private_event_queue ) {
2007-05-15 00:05:32 +00:00
return switch_queue_size ( session - > private_event_queue ) ;
2007-03-29 22:34:40 +00:00
}
2008-05-27 04:30:03 +00:00
2007-05-15 00:05:32 +00:00
return 0 ;
2007-03-29 22:34:40 +00:00
}
2007-03-30 00:13:31 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_session_dequeue_private_event ( switch_core_session_t * session , switch_event_t * * event )
2007-03-29 22:34:40 +00:00
{
switch_status_t status = SWITCH_STATUS_FALSE ;
void * pop ;
2008-01-28 07:26:10 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
2007-03-29 22:34:40 +00:00
2007-06-25 21:25:33 +00:00
if ( switch_channel_test_flag ( channel , CF_EVENT_LOCK ) ) {
2007-03-29 22:34:40 +00:00
return status ;
}
if ( session - > private_event_queue ) {
2007-03-30 00:13:31 +00:00
if ( ( status = ( switch_status_t ) switch_queue_trypop ( session - > private_event_queue , & pop ) ) = = SWITCH_STATUS_SUCCESS ) {
2007-03-29 22:34:40 +00:00
* event = ( switch_event_t * ) pop ;
}
}
return status ;
}
2008-02-15 16:01:12 +00:00
SWITCH_DECLARE ( uint32_t ) switch_core_session_flush_private_events ( switch_core_session_t * session )
{
switch_status_t status = SWITCH_STATUS_FALSE ;
int x = 0 ;
void * pop ;
if ( session - > private_event_queue ) {
while ( ( status = ( switch_status_t ) switch_queue_trypop ( session - > private_event_queue , & pop ) ) = = SWITCH_STATUS_SUCCESS ) {
x + + ;
}
}
2008-05-27 04:30:03 +00:00
2008-02-15 16:01:12 +00:00
return x ;
}
2009-01-09 20:34:01 +00:00
SWITCH_DECLARE ( void ) switch_core_session_reset ( switch_core_session_t * session , switch_bool_t flush_dtmf , switch_bool_t reset_read_codec )
2007-03-29 22:34:40 +00:00
{
2008-01-28 07:26:10 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
2007-03-29 22:34:40 +00:00
switch_size_t has ;
2009-01-09 20:34:01 +00:00
if ( reset_read_codec ) {
switch_core_session_set_read_codec ( session , NULL ) ;
}
2008-10-29 00:04:20 +00:00
2008-05-27 04:30:03 +00:00
/* clear resamplers */
2008-07-14 22:15:24 +00:00
switch_mutex_lock ( session - > resample_mutex ) ;
2007-12-12 21:30:55 +00:00
switch_resample_destroy ( & session - > read_resampler ) ;
switch_resample_destroy ( & session - > write_resampler ) ;
2008-07-14 22:15:24 +00:00
switch_mutex_unlock ( session - > resample_mutex ) ;
2007-03-29 22:34:40 +00:00
/* clear indications */
switch_core_session_flush_message ( session ) ;
2009-05-01 21:31:16 +00:00
2008-10-06 23:05:55 +00:00
/* wipe these, they will be recreated if need be */
2009-05-01 21:31:16 +00:00
switch_mutex_lock ( session - > codec_write_mutex ) ;
2007-03-29 22:34:40 +00:00
switch_buffer_destroy ( & session - > raw_write_buffer ) ;
2009-05-01 21:31:16 +00:00
switch_mutex_unlock ( session - > codec_write_mutex ) ;
switch_mutex_lock ( session - > codec_read_mutex ) ;
switch_buffer_destroy ( & session - > raw_read_buffer ) ;
switch_mutex_unlock ( session - > codec_read_mutex ) ;
2008-05-27 04:30:03 +00:00
2008-01-13 18:39:51 +00:00
if ( flush_dtmf ) {
while ( ( has = switch_channel_has_dtmf ( channel ) ) ) {
switch_channel_flush_dtmf ( channel ) ;
}
2007-03-29 22:34:40 +00:00
}
2008-05-13 20:36:23 +00:00
switch_clear_flag ( session , SSF_WARN_TRANSCODE ) ;
2007-04-09 18:38:47 +00:00
switch_ivr_deactivate_unicast ( session ) ;
2007-03-30 22:13:19 +00:00
switch_channel_clear_flag ( channel , CF_BREAK ) ;
2007-03-29 22:34:40 +00:00
}
SWITCH_DECLARE ( switch_channel_t * ) switch_core_session_get_channel ( switch_core_session_t * session )
{
2008-01-28 07:26:10 +00:00
switch_assert ( session - > channel ) ;
2007-03-29 22:34:40 +00:00
return session - > channel ;
}
2009-10-12 22:23:55 +00:00
SWITCH_DECLARE ( void ) switch_core_session_wake_session_thread ( switch_core_session_t * session )
2007-03-29 22:34:40 +00:00
{
/* If trylock fails the signal is already awake so we needn't bother */
if ( switch_mutex_trylock ( session - > mutex ) = = SWITCH_STATUS_SUCCESS ) {
switch_thread_cond_signal ( session - > cond ) ;
switch_mutex_unlock ( session - > mutex ) ;
}
2009-10-12 22:23:55 +00:00
}
SWITCH_DECLARE ( void ) switch_core_session_signal_state_change ( switch_core_session_t * session )
{
switch_status_t status = SWITCH_STATUS_SUCCESS ;
switch_io_event_hook_state_change_t * ptr ;
switch_core_session_wake_session_thread ( session ) ;
2007-03-29 22:34:40 +00:00
if ( session - > endpoint_interface - > io_routines - > state_change ) {
status = session - > endpoint_interface - > io_routines - > state_change ( session ) ;
}
if ( status = = SWITCH_STATUS_SUCCESS ) {
for ( ptr = session - > event_hooks . state_change ; ptr ; ptr = ptr - > next ) {
if ( ( status = ptr - > state_change ( session ) ) ! = SWITCH_STATUS_SUCCESS ) {
break ;
}
}
}
2007-05-16 17:35:00 +00:00
switch_core_session_kill_channel ( session , SWITCH_SIG_BREAK ) ;
2007-03-29 22:34:40 +00:00
}
SWITCH_DECLARE ( unsigned int ) switch_core_session_running ( switch_core_session_t * session )
{
return session - > thread_running ;
}
2007-05-11 00:27:55 +00:00
SWITCH_DECLARE ( void ) switch_core_session_perform_destroy ( switch_core_session_t * * session , const char * file , const char * func , int line )
2007-03-29 22:34:40 +00:00
{
switch_memory_pool_t * pool ;
switch_event_t * event ;
2008-11-13 17:40:25 +00:00
switch_endpoint_interface_t * endpoint_interface = ( * session ) - > endpoint_interface ;
2008-07-01 23:41:09 +00:00
2007-03-29 22:34:40 +00:00
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_ID_LOG , file , func , line , switch_core_session_get_uuid ( * session ) , SWITCH_LOG_NOTICE , " Close Channel %s [%s] \n " ,
2008-05-27 04:30:03 +00:00
switch_channel_get_name ( ( * session ) - > channel ) , switch_channel_state_name ( switch_channel_get_state ( ( * session ) - > channel ) ) ) ;
2008-01-21 17:14:43 +00:00
2008-07-14 22:15:24 +00:00
2009-01-09 20:34:01 +00:00
switch_core_session_reset ( * session , TRUE , SWITCH_TRUE ) ;
2008-07-14 22:15:24 +00:00
2008-05-27 04:30:03 +00:00
switch_core_media_bug_remove_all ( * session ) ;
2007-04-09 18:38:47 +00:00
switch_ivr_deactivate_unicast ( * session ) ;
2008-05-27 04:30:03 +00:00
2007-03-29 22:34:40 +00:00
switch_scheduler_del_task_group ( ( * session ) - > uuid_str ) ;
2009-03-07 17:45:37 +00:00
switch_mutex_lock ( runtime . session_hash_mutex ) ;
2007-05-10 16:56:29 +00:00
switch_core_hash_delete ( session_manager . session_table , ( * session ) - > uuid_str ) ;
if ( session_manager . session_count ) {
session_manager . session_count - - ;
2007-03-29 22:34:40 +00:00
}
2009-03-07 17:45:37 +00:00
switch_mutex_unlock ( runtime . session_hash_mutex ) ;
2007-03-29 22:34:40 +00:00
if ( switch_event_create ( & event , SWITCH_EVENT_CHANNEL_DESTROY ) = = SWITCH_STATUS_SUCCESS ) {
switch_channel_event_set_data ( ( * session ) - > channel , event ) ;
switch_event_fire ( & event ) ;
}
2009-04-10 17:43:18 +00:00
switch_core_session_destroy_state ( * session ) ;
2008-01-21 17:14:43 +00:00
2007-03-29 22:34:40 +00:00
switch_buffer_destroy ( & ( * session ) - > raw_read_buffer ) ;
switch_buffer_destroy ( & ( * session ) - > raw_write_buffer ) ;
2007-10-15 16:25:08 +00:00
switch_ivr_clear_speech_cache ( * session ) ;
2007-03-29 22:34:40 +00:00
switch_channel_uninit ( ( * session ) - > channel ) ;
pool = ( * session ) - > pool ;
2007-09-29 01:06:08 +00:00
//#ifndef NDEBUG
//memset(*session, 0, sizeof(switch_core_session_t));
//#endif
2007-03-29 22:34:40 +00:00
* session = NULL ;
2007-09-29 01:06:08 +00:00
switch_core_destroy_memory_pool ( & pool ) ;
2008-05-27 04:30:03 +00:00
2008-11-12 19:28:05 +00:00
UNPROTECT_INTERFACE ( endpoint_interface ) ;
2007-03-29 22:34:40 +00:00
}
2009-04-10 17:43:18 +00:00
2008-10-21 16:22:38 +00:00
SWITCH_STANDARD_SCHED_FUNC ( sch_heartbeat_callback )
{
switch_event_t * event ;
switch_core_session_t * session ;
char * uuid = task - > cmd_arg ;
if ( ( session = switch_core_session_locate ( uuid ) ) ) {
switch_event_create ( & event , SWITCH_EVENT_SESSION_HEARTBEAT ) ;
switch_channel_event_set_data ( session - > channel , event ) ;
switch_event_fire ( & event ) ;
2008-10-22 03:03:43 +00:00
/* reschedule this task */
2009-01-25 21:23:07 +00:00
task - > runtime = switch_epoch_time_now ( NULL ) + session - > track_duration ;
2008-10-22 03:03:43 +00:00
2008-10-21 16:22:38 +00:00
switch_core_session_rwunlock ( session ) ;
}
}
SWITCH_DECLARE ( void ) switch_core_session_unsched_heartbeat ( switch_core_session_t * session )
{
if ( session - > track_id ) {
switch_scheduler_del_task_id ( session - > track_id ) ;
session - > track_id = 0 ;
}
}
SWITCH_DECLARE ( void ) switch_core_session_sched_heartbeat ( switch_core_session_t * session , uint32_t seconds )
{
switch_core_session_unsched_heartbeat ( session ) ;
2009-01-25 21:23:07 +00:00
session - > track_id = switch_scheduler_add_task ( switch_epoch_time_now ( NULL ) , sch_heartbeat_callback , ( char * ) __SWITCH_FUNC__ ,
2008-10-21 16:22:38 +00:00
switch_core_session_get_uuid ( session ) , 0 , strdup ( switch_core_session_get_uuid ( session ) ) , SSHF_FREE_ARG ) ;
}
2008-10-07 21:03:37 +00:00
SWITCH_DECLARE ( void ) switch_core_session_enable_heartbeat ( switch_core_session_t * session , uint32_t seconds )
{
switch_assert ( session ! = NULL ) ;
2008-10-07 21:42:31 +00:00
2008-12-08 15:30:08 +00:00
if ( ! seconds ) {
2008-10-07 21:42:31 +00:00
seconds = 60 ;
}
2009-08-01 06:11:22 +00:00
session - > track_duration = seconds ;
2008-10-21 16:22:38 +00:00
if ( switch_channel_test_flag ( session - > channel , CF_PROXY_MODE ) ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING , " %s using scheduler due to bypass_media mode \n " , switch_channel_get_name ( session - > channel ) ) ;
2008-10-21 16:22:38 +00:00
switch_core_session_sched_heartbeat ( session , seconds ) ;
return ;
}
switch_core_session_unsched_heartbeat ( session ) ;
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_INFO , " %s setting session heartbeat to %u second(s). \n " ,
2008-10-07 21:03:37 +00:00
switch_channel_get_name ( session - > channel ) , seconds ) ;
2009-08-01 06:11:22 +00:00
2008-10-07 21:42:31 +00:00
session - > read_frame_count = 0 ;
2008-10-21 16:22:38 +00:00
2008-10-07 21:03:37 +00:00
}
SWITCH_DECLARE ( void ) switch_core_session_disable_heartbeat ( switch_core_session_t * session )
{
2008-10-21 16:22:38 +00:00
switch_core_session_unsched_heartbeat ( session ) ;
2008-10-07 21:03:37 +00:00
switch_assert ( session ! = NULL ) ;
2008-10-07 21:42:31 +00:00
session - > read_frame_count = 0 ;
2008-10-07 21:03:37 +00:00
session - > track_duration = 0 ;
2008-10-21 16:22:38 +00:00
2008-10-07 21:03:37 +00:00
}
2008-05-27 04:30:03 +00:00
static void * SWITCH_THREAD_FUNC switch_core_session_thread ( switch_thread_t * thread , void * obj )
2007-03-29 22:34:40 +00:00
{
switch_core_session_t * session = obj ;
2008-02-21 21:38:49 +00:00
switch_event_t * event ;
char * event_str = NULL ;
const char * val ;
2007-03-29 22:34:40 +00:00
session - > thread = thread ;
2009-09-14 20:10:58 +00:00
session - > thread_id = switch_thread_self ( ) ;
2007-03-29 22:34:40 +00:00
switch_core_session_run ( session ) ;
2008-06-25 19:56:20 +00:00
switch_core_media_bug_remove_all ( session ) ;
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Session % " SWITCH_SIZE_T_FMT " (%s) Locked, Waiting on external entities \n " ,
2007-03-29 22:34:40 +00:00
session - > id , switch_channel_get_name ( session - > channel ) ) ;
switch_core_session_write_lock ( session ) ;
switch_set_flag ( session , SSF_DESTROYED ) ;
2008-02-21 21:38:49 +00:00
if ( ( val = switch_channel_get_variable ( session - > channel , " memory_debug " ) ) & & switch_true ( val ) ) {
2008-10-02 17:10:05 +00:00
if ( switch_event_create ( & event , SWITCH_EVENT_GENERAL ) = = SWITCH_STATUS_SUCCESS ) {
2008-02-21 21:38:49 +00:00
switch_channel_event_set_data ( session - > channel , event ) ;
switch_event_serialize ( event , & event_str , SWITCH_FALSE ) ;
switch_assert ( event_str ) ;
switch_core_memory_pool_tag ( switch_core_session_get_pool ( session ) , switch_core_session_strdup ( session , event_str ) ) ;
free ( event_str ) ;
2008-03-14 16:21:13 +00:00
switch_event_destroy ( & event ) ;
2008-02-21 21:38:49 +00:00
}
}
2007-03-29 22:34:40 +00:00
switch_core_session_rwunlock ( session ) ;
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_NOTICE , " Session % " SWITCH_SIZE_T_FMT " (%s) Ended \n " ,
2007-04-22 19:11:22 +00:00
session - > id , switch_channel_get_name ( session - > channel ) ) ;
2007-03-29 22:34:40 +00:00
switch_core_session_destroy ( & session ) ;
return NULL ;
}
2007-05-11 00:27:55 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_session_thread_launch ( switch_core_session_t * session )
2007-03-29 22:34:40 +00:00
{
2007-05-31 13:32:23 +00:00
switch_status_t status = SWITCH_STATUS_FALSE ;
2007-03-29 22:34:40 +00:00
switch_thread_t * thread ;
switch_threadattr_t * thd_attr ; ;
2007-05-31 13:32:23 +00:00
2007-03-29 22:34:40 +00:00
switch_threadattr_create ( & thd_attr , session - > pool ) ;
switch_threadattr_detach_set ( thd_attr , 1 ) ;
2007-05-29 20:57:17 +00:00
switch_mutex_lock ( session - > mutex ) ;
2008-05-27 04:30:03 +00:00
2007-03-29 22:34:40 +00:00
if ( ! session - > thread_running ) {
2007-05-29 20:57:17 +00:00
session - > thread_running = 1 ;
2007-03-29 22:34:40 +00:00
switch_threadattr_stacksize_set ( thd_attr , SWITCH_THREAD_STACKSIZE ) ;
2007-05-11 00:27:55 +00:00
if ( switch_thread_create ( & thread , thd_attr , switch_core_session_thread , session , session - > pool ) = = SWITCH_STATUS_SUCCESS ) {
2007-05-29 20:57:17 +00:00
status = SWITCH_STATUS_SUCCESS ;
2007-05-11 00:27:55 +00:00
} else {
2007-05-29 20:57:17 +00:00
session - > thread_running = 0 ;
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_CRIT , " Cannot create thread! \n " ) ;
2007-03-29 22:34:40 +00:00
}
2007-05-11 00:27:55 +00:00
} else {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_CRIT , " Cannot double-launch thread! \n " ) ;
2007-03-29 22:34:40 +00:00
}
2007-05-11 00:27:55 +00:00
2007-05-29 20:57:17 +00:00
switch_mutex_unlock ( session - > mutex ) ;
return status ;
2007-03-29 22:34:40 +00:00
}
2007-03-30 00:13:31 +00:00
SWITCH_DECLARE ( void ) switch_core_session_launch_thread ( switch_core_session_t * session , switch_thread_start_t func , void * obj )
2007-03-29 22:34:40 +00:00
{
switch_thread_t * thread ;
switch_threadattr_t * thd_attr = NULL ;
switch_threadattr_create ( & thd_attr , session - > pool ) ;
switch_threadattr_detach_set ( thd_attr , 1 ) ;
switch_threadattr_stacksize_set ( thd_attr , SWITCH_THREAD_STACKSIZE ) ;
switch_thread_create ( & thread , thd_attr , func , obj , session - > pool ) ;
}
2008-11-04 16:46:33 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_session_set_uuid ( switch_core_session_t * session , const char * use_uuid )
{
switch_event_t * event ;
2009-10-22 14:54:29 +00:00
switch_core_session_message_t msg = { 0 } ;
2008-11-04 16:46:33 +00:00
switch_assert ( use_uuid ) ;
2009-03-13 01:57:10 +00:00
switch_mutex_lock ( runtime . session_hash_mutex ) ;
2008-11-04 16:46:33 +00:00
if ( switch_core_hash_find ( session_manager . session_table , use_uuid ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Duplicate UUID! \n " ) ;
2009-03-13 01:57:10 +00:00
switch_mutex_unlock ( runtime . session_hash_mutex ) ;
2008-11-04 16:46:33 +00:00
return SWITCH_STATUS_FALSE ;
}
2009-10-22 14:54:29 +00:00
msg . message_id = SWITCH_MESSAGE_INDICATE_UUID_CHANGE ;
msg . from = switch_channel_get_name ( session - > channel ) ;
msg . string_array_arg [ 0 ] = session - > uuid_str ;
msg . string_array_arg [ 1 ] = use_uuid ;
switch_core_session_receive_message ( session , & msg ) ;
2008-11-04 16:46:33 +00:00
switch_event_create ( & event , SWITCH_EVENT_CHANNEL_UUID ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Old-Unique-ID " , session - > uuid_str ) ;
switch_core_hash_delete ( session_manager . session_table , session - > uuid_str ) ;
switch_set_string ( session - > uuid_str , use_uuid ) ;
switch_core_hash_insert ( session_manager . session_table , session - > uuid_str , session ) ;
2009-03-07 17:45:37 +00:00
switch_mutex_unlock ( runtime . session_hash_mutex ) ;
2008-11-04 16:46:33 +00:00
switch_channel_event_set_data ( session - > channel , event ) ;
switch_event_fire ( & event ) ;
return SWITCH_STATUS_SUCCESS ;
}
2008-11-13 17:40:25 +00:00
SWITCH_DECLARE ( switch_core_session_t * ) switch_core_session_request_uuid ( switch_endpoint_interface_t
2009-02-23 16:31:59 +00:00
* endpoint_interface ,
switch_call_direction_t direction ,
switch_memory_pool_t * * pool ,
const char * use_uuid )
2007-03-29 22:34:40 +00:00
{
switch_memory_pool_t * usepool ;
switch_core_session_t * session ;
switch_uuid_t uuid ;
uint32_t count = 0 ;
2007-10-03 16:44:11 +00:00
int32_t sps = 0 ;
2007-03-29 22:34:40 +00:00
2008-11-12 19:28:05 +00:00
2008-11-04 16:46:33 +00:00
if ( use_uuid & & switch_core_hash_find ( session_manager . session_table , use_uuid ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Duplicate UUID! \n " ) ;
return NULL ;
}
2007-07-06 16:29:25 +00:00
if ( ! switch_core_ready ( ) | | endpoint_interface = = NULL ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " The system cannot create any sessions at this time. \n " ) ;
return NULL ;
}
2007-03-29 22:34:40 +00:00
2008-11-12 19:28:05 +00:00
PROTECT_INTERFACE ( endpoint_interface ) ;
2007-10-03 16:44:11 +00:00
switch_mutex_lock ( runtime . throttle_mutex ) ;
2007-05-10 16:56:29 +00:00
count = session_manager . session_count ;
2007-10-03 16:44:11 +00:00
sps = - - runtime . sps ;
switch_mutex_unlock ( runtime . throttle_mutex ) ;
2008-05-27 04:30:03 +00:00
2007-10-03 16:44:11 +00:00
if ( sps < = 0 ) {
//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Throttle Error!\n");
2008-11-12 19:28:05 +00:00
UNPROTECT_INTERFACE ( endpoint_interface ) ;
2007-10-03 16:44:11 +00:00
return NULL ;
}
2007-03-29 22:34:40 +00:00
2007-05-10 16:56:29 +00:00
if ( ( count + 1 ) > session_manager . session_limit ) {
2007-10-03 16:44:11 +00:00
//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Over Session Limit!\n");
2008-11-12 19:28:05 +00:00
UNPROTECT_INTERFACE ( endpoint_interface ) ;
2007-03-29 22:34:40 +00:00
return NULL ;
}
if ( pool & & * pool ) {
usepool = * pool ;
* pool = NULL ;
2007-10-23 00:11:03 +00:00
} else {
switch_core_new_memory_pool ( & usepool ) ;
2007-03-29 22:34:40 +00:00
}
2007-10-23 00:11:03 +00:00
session = switch_core_alloc ( usepool , sizeof ( * session ) ) ;
session - > pool = usepool ;
2009-05-22 18:19:55 +00:00
switch_core_memory_pool_set_data ( session - > pool , " __session " , session ) ;
2008-11-04 16:46:33 +00:00
2009-02-23 16:31:59 +00:00
if ( switch_channel_alloc ( & session - > channel , direction , session - > pool ) ! = SWITCH_STATUS_SUCCESS ) {
2007-10-23 00:11:03 +00:00
abort ( ) ;
2007-03-29 22:34:40 +00:00
}
2009-02-24 00:05:19 +00:00
switch_channel_init ( session - > channel , session , CS_NEW , 0 ) ;
2009-02-23 16:31:59 +00:00
if ( direction = = SWITCH_CALL_DIRECTION_OUTBOUND ) {
switch_channel_set_flag ( session - > channel , CF_OUTBOUND ) ;
}
2009-02-24 00:05:19 +00:00
2007-03-29 22:34:40 +00:00
/* The session *IS* the pool you may not alter it because you have no idea how
its all private it will be passed to the thread run function */
2008-11-04 16:46:33 +00:00
if ( use_uuid ) {
switch_set_string ( session - > uuid_str , use_uuid ) ;
} else {
switch_uuid_get ( & uuid ) ;
switch_uuid_format ( session - > uuid_str , & uuid ) ;
}
2007-03-29 22:34:40 +00:00
session - > endpoint_interface = endpoint_interface ;
session - > raw_write_frame . data = session - > raw_write_buf ;
session - > raw_write_frame . buflen = sizeof ( session - > raw_write_buf ) ;
session - > raw_read_frame . data = session - > raw_read_buf ;
session - > raw_read_frame . buflen = sizeof ( session - > raw_read_buf ) ;
session - > enc_write_frame . data = session - > enc_write_buf ;
session - > enc_write_frame . buflen = sizeof ( session - > enc_write_buf ) ;
session - > enc_read_frame . data = session - > enc_read_buf ;
session - > enc_read_frame . buflen = sizeof ( session - > enc_read_buf ) ;
switch_mutex_init ( & session - > mutex , SWITCH_MUTEX_NESTED , session - > pool ) ;
2008-01-04 00:19:09 +00:00
switch_mutex_init ( & session - > resample_mutex , SWITCH_MUTEX_NESTED , session - > pool ) ;
2008-11-21 00:09:11 +00:00
switch_mutex_init ( & session - > codec_read_mutex , SWITCH_MUTEX_NESTED , session - > pool ) ;
switch_mutex_init ( & session - > codec_write_mutex , SWITCH_MUTEX_NESTED , session - > pool ) ;
2007-03-29 22:34:40 +00:00
switch_thread_rwlock_create ( & session - > bug_rwlock , session - > pool ) ;
switch_thread_cond_create ( & session - > cond , session - > pool ) ;
switch_thread_rwlock_create ( & session - > rwlock , session - > pool ) ;
2007-09-24 19:34:25 +00:00
switch_queue_create ( & session - > message_queue , SWITCH_MESSAGE_QUEUE_LEN , session - > pool ) ;
switch_queue_create ( & session - > event_queue , SWITCH_EVENT_QUEUE_LEN , session - > pool ) ;
switch_queue_create ( & session - > private_event_queue , SWITCH_EVENT_QUEUE_LEN , session - > pool ) ;
2009-03-07 17:45:37 +00:00
switch_mutex_lock ( runtime . session_hash_mutex ) ;
2007-05-10 16:56:29 +00:00
switch_core_hash_insert ( session_manager . session_table , session - > uuid_str , session ) ;
2009-03-07 17:45:37 +00:00
session - > id = session_manager . session_id + + ;
2007-05-10 16:56:29 +00:00
session_manager . session_count + + ;
2009-03-07 17:45:37 +00:00
switch_mutex_unlock ( runtime . session_hash_mutex ) ;
2007-03-29 22:34:40 +00:00
return session ;
}
SWITCH_DECLARE ( uint32_t ) switch_core_session_count ( void )
{
2007-05-10 16:56:29 +00:00
return session_manager . session_count ;
2007-03-29 22:34:40 +00:00
}
2008-10-17 00:10:49 +00:00
SWITCH_DECLARE ( switch_size_t ) switch_core_session_get_id ( switch_core_session_t * session )
2008-10-08 20:59:16 +00:00
{
return session - > id ;
}
2007-04-22 01:25:02 +00:00
SWITCH_DECLARE ( switch_size_t ) switch_core_session_id ( void )
{
2007-05-10 16:56:29 +00:00
return session_manager . session_id ;
2007-04-22 01:25:02 +00:00
}
2009-02-23 16:31:59 +00:00
SWITCH_DECLARE ( switch_core_session_t * ) switch_core_session_request_by_name ( const char * endpoint_name ,
switch_call_direction_t direction ,
switch_memory_pool_t * * pool )
2007-03-29 22:34:40 +00:00
{
2008-11-13 17:40:25 +00:00
switch_endpoint_interface_t * endpoint_interface ;
2008-11-19 19:22:20 +00:00
switch_core_session_t * session ;
2007-03-29 22:34:40 +00:00
if ( ( endpoint_interface = switch_loadable_module_get_endpoint_interface ( endpoint_name ) ) = = 0 ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Could not locate channel type %s \n " , endpoint_name ) ;
return NULL ;
}
2008-11-13 17:40:25 +00:00
2009-02-23 16:31:59 +00:00
session = switch_core_session_request ( endpoint_interface , direction , pool ) ;
2008-11-19 19:22:20 +00:00
UNPROTECT_INTERFACE ( endpoint_interface ) ;
2008-11-12 19:28:05 +00:00
2008-11-19 19:22:20 +00:00
return session ;
2007-03-29 22:34:40 +00:00
}
# ifndef SWITCH_PREFIX_DIR
# define SWITCH_PREFIX_DIR "."
# endif
SWITCH_DECLARE ( uint8_t ) switch_core_session_compare ( switch_core_session_t * a , switch_core_session_t * b )
{
2007-12-11 19:23:57 +00:00
switch_assert ( a ! = NULL ) ;
switch_assert ( b ! = NULL ) ;
2007-03-29 22:34:40 +00:00
return ( uint8_t ) ( a - > endpoint_interface = = b - > endpoint_interface ) ;
}
2008-07-30 15:04:56 +00:00
SWITCH_DECLARE ( uint8_t ) switch_core_session_check_interface ( switch_core_session_t * session , const switch_endpoint_interface_t * endpoint_interface )
{
switch_assert ( session ! = NULL ) ;
switch_assert ( endpoint_interface ! = NULL ) ;
return ( uint8_t ) ( session - > endpoint_interface = = endpoint_interface ) ;
}
2007-03-29 22:34:40 +00:00
SWITCH_DECLARE ( char * ) switch_core_session_get_uuid ( switch_core_session_t * session )
{
return session - > uuid_str ;
}
SWITCH_DECLARE ( uint32_t ) switch_core_session_limit ( uint32_t new_limit )
{
if ( new_limit ) {
2007-05-10 16:56:29 +00:00
session_manager . session_limit = new_limit ;
2007-03-29 22:34:40 +00:00
}
2007-05-10 16:56:29 +00:00
return session_manager . session_limit ;
2007-03-29 22:34:40 +00:00
}
2007-10-03 16:44:11 +00:00
SWITCH_DECLARE ( uint32_t ) switch_core_sessions_per_second ( uint32_t new_limit )
{
if ( new_limit ) {
runtime . sps_total = new_limit ;
}
return runtime . sps_total ;
}
2007-03-30 02:20:13 +00:00
void switch_core_session_init ( switch_memory_pool_t * pool )
2007-03-29 22:34:40 +00:00
{
2007-05-10 16:56:29 +00:00
memset ( & session_manager , 0 , sizeof ( session_manager ) ) ;
session_manager . session_limit = 1000 ;
session_manager . session_id = 1 ;
session_manager . memory_pool = pool ;
switch_core_hash_init ( & session_manager . session_table , session_manager . memory_pool ) ;
2007-03-29 22:34:40 +00:00
}
2007-04-20 23:45:14 +00:00
2007-09-29 01:06:08 +00:00
void switch_core_session_uninit ( void )
{
switch_core_hash_destroy ( & session_manager . session_table ) ;
}
2007-04-20 23:45:14 +00:00
2007-04-21 01:03:58 +00:00
SWITCH_DECLARE ( switch_app_log_t * ) switch_core_session_get_app_log ( switch_core_session_t * session )
{
return session - > app_log ;
}
2008-04-02 15:11:07 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_session_execute_application ( switch_core_session_t * session , const char * app , const char * arg )
{
2008-11-13 17:40:25 +00:00
switch_application_interface_t * application_interface ;
2009-04-23 05:26:21 +00:00
switch_status_t status = SWITCH_STATUS_SUCCESS ;
2009-02-25 03:41:18 +00:00
if ( switch_channel_down ( session - > channel ) ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Channel is hungup, aborting execution of application: %s \n " , app ) ;
2009-02-20 15:30:01 +00:00
return SWITCH_STATUS_FALSE ;
}
2008-04-02 15:11:07 +00:00
if ( ( application_interface = switch_loadable_module_get_application_interface ( app ) ) = = 0 ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Invalid Application %s \n " , app ) ;
2008-04-02 15:11:07 +00:00
switch_channel_hangup ( session - > channel , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
return SWITCH_STATUS_FALSE ;
}
2008-05-27 04:30:03 +00:00
2008-04-02 15:11:07 +00:00
if ( ! application_interface - > application_function ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " No Function for %s \n " , app ) ;
2008-04-02 15:11:07 +00:00
switch_channel_hangup ( session - > channel , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
2009-04-23 05:26:21 +00:00
switch_goto_status ( SWITCH_STATUS_FALSE , done ) ;
2008-04-02 15:11:07 +00:00
}
2008-05-27 04:30:03 +00:00
2008-04-02 15:11:07 +00:00
if ( switch_channel_test_flag ( session - > channel , CF_PROXY_MODE ) & & ! switch_test_flag ( application_interface , SAF_SUPPORT_NOMEDIA ) ) {
switch_ivr_media ( session - > uuid_str , SMF_NONE ) ;
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Application %s Requires media on channel %s! \n " ,
2008-04-02 15:11:07 +00:00
app , switch_channel_get_name ( session - > channel ) ) ;
} else if ( ! switch_test_flag ( application_interface , SAF_SUPPORT_NOMEDIA ) & & ! switch_channel_media_ready ( session - > channel ) ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Application %s Requires media! pre_answering channel %s \n " ,
2008-04-02 15:11:07 +00:00
app , switch_channel_get_name ( session - > channel ) ) ;
if ( switch_channel_pre_answer ( session - > channel ) ! = SWITCH_STATUS_SUCCESS ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Well, that didn't work very well did it? ... \n " ) ;
2009-04-23 05:26:21 +00:00
switch_goto_status ( SWITCH_STATUS_FALSE , done ) ;
2008-04-02 15:11:07 +00:00
}
}
2009-01-30 23:46:00 +00:00
switch_core_session_exec ( session , application_interface , arg ) ;
2009-01-30 23:08:55 +00:00
2009-04-23 05:26:21 +00:00
done :
2009-01-30 23:08:55 +00:00
UNPROTECT_INTERFACE ( application_interface ) ;
2009-04-23 05:26:21 +00:00
return status ;
2009-01-30 23:08:55 +00:00
}
SWITCH_DECLARE ( switch_status_t ) switch_core_session_exec ( switch_core_session_t * session ,
const switch_application_interface_t * application_interface , const char * arg )
{
switch_app_log_t * log , * lp ;
switch_event_t * event ;
const char * var ;
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
char * expanded = NULL ;
const char * app ;
switch_assert ( application_interface ) ;
app = application_interface - > interface_name ;
2009-03-06 03:54:38 +00:00
if ( arg ) {
expanded = switch_channel_expand_variables ( session - > channel , arg ) ;
2008-04-02 15:11:07 +00:00
}
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG_CLEAN ( session ) , SWITCH_LOG_DEBUG , " EXECUTE %s %s(%s) \n " ,
2009-03-06 03:54:38 +00:00
switch_channel_get_name ( session - > channel ) , app , switch_str_nil ( expanded ) ) ;
2008-08-25 16:30:28 +00:00
if ( ( var = switch_channel_get_variable ( session - > channel , " verbose_presence " ) ) & & switch_true ( var ) ) {
2008-04-04 21:36:04 +00:00
char * myarg = NULL ;
if ( expanded ) {
2008-07-28 15:38:52 +00:00
myarg = switch_mprintf ( " %s(%s) " , app , expanded ) ;
2009-10-23 16:03:42 +00:00
} else if ( ! zstr ( arg ) ) {
2008-07-28 15:38:52 +00:00
myarg = switch_mprintf ( " %s(%s) " , app , arg ) ;
} else {
myarg = switch_mprintf ( " %s " , app ) ;
2008-04-04 21:36:04 +00:00
}
if ( myarg ) {
2008-08-25 16:30:28 +00:00
switch_channel_presence ( session - > channel , " unknown " , myarg , NULL ) ;
2008-04-04 21:36:04 +00:00
switch_safe_free ( myarg ) ;
2008-04-02 15:11:07 +00:00
}
}
2008-05-22 01:08:30 +00:00
if ( ! ( var = switch_channel_get_variable ( session - > channel , SWITCH_DISABLE_APP_LOG_VARIABLE ) ) | | ( ! ( switch_true ( var ) ) ) ) {
log = switch_core_session_alloc ( session , sizeof ( * log ) ) ;
2007-04-21 01:03:58 +00:00
2008-05-22 01:08:30 +00:00
log - > app = switch_core_session_strdup ( session , application_interface - > interface_name ) ;
2009-02-02 17:04:56 +00:00
if ( expanded ) {
log - > arg = switch_core_session_strdup ( session , expanded ) ;
}
2007-04-21 01:03:58 +00:00
2008-05-27 04:30:03 +00:00
for ( lp = session - > app_log ; lp & & lp - > next ; lp = lp - > next ) ;
2007-04-21 01:03:58 +00:00
2008-05-22 01:08:30 +00:00
if ( lp ) {
lp - > next = log ;
} else {
session - > app_log = log ;
}
2007-04-21 01:03:58 +00:00
}
2008-11-06 03:36:15 +00:00
2008-12-08 15:42:37 +00:00
switch_channel_set_variable ( channel , SWITCH_CURRENT_APPLICATION_VARIABLE , application_interface - > interface_name ) ;
2009-03-27 15:07:49 +00:00
switch_channel_set_variable_var_check ( channel , SWITCH_CURRENT_APPLICATION_DATA_VARIABLE , expanded , SWITCH_FALSE ) ;
2008-12-08 15:42:37 +00:00
switch_channel_set_variable ( channel , SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE , NULL ) ;
2007-06-23 05:41:07 +00:00
if ( switch_event_create ( & event , SWITCH_EVENT_CHANNEL_EXECUTE ) = = SWITCH_STATUS_SUCCESS ) {
switch_channel_event_set_data ( session - > channel , event ) ;
2008-08-16 02:17:09 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Application " , application_interface - > interface_name ) ;
2009-01-31 00:16:27 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Application-Data " , expanded ) ;
2007-06-23 05:41:07 +00:00
switch_event_fire ( & event ) ;
}
2008-01-28 07:26:10 +00:00
switch_channel_clear_flag ( session - > channel , CF_BREAK ) ;
2008-01-11 16:50:05 +00:00
switch_assert ( application_interface - > application_function ) ;
2008-07-01 23:41:09 +00:00
switch_channel_set_variable ( session - > channel , SWITCH_CURRENT_APPLICATION_VARIABLE , application_interface - > interface_name ) ;
2008-05-27 04:30:03 +00:00
2009-01-30 23:08:55 +00:00
application_interface - > application_function ( session , expanded ) ;
2008-07-01 23:41:09 +00:00
2007-06-23 05:41:07 +00:00
if ( switch_event_create ( & event , SWITCH_EVENT_CHANNEL_EXECUTE_COMPLETE ) = = SWITCH_STATUS_SUCCESS ) {
2008-12-08 15:42:37 +00:00
const char * resp = switch_channel_get_variable ( session - > channel , SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE ) ;
2007-06-23 05:41:07 +00:00
switch_channel_event_set_data ( session - > channel , event ) ;
2008-08-16 02:17:09 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Application " , application_interface - > interface_name ) ;
2009-01-31 00:16:27 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Application-Data " , expanded ) ;
2008-12-08 15:42:37 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Application-Response " , resp ? resp : " _none_ " ) ;
2007-06-23 05:41:07 +00:00
switch_event_fire ( & event ) ;
}
2007-04-21 01:03:58 +00:00
2009-01-30 23:08:55 +00:00
if ( expanded ! = arg ) {
switch_safe_free ( expanded ) ;
}
2007-04-21 01:03:58 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2008-05-27 04:30:03 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_session_execute_exten ( switch_core_session_t * session , const char * exten , const char * dialplan ,
const char * context )
2007-04-20 23:45:14 +00:00
{
char * dp [ 25 ] ;
char * dpstr ;
int argc , x , count = 0 ;
2008-03-10 18:38:01 +00:00
switch_caller_profile_t * profile , * new_profile , * pp = NULL ;
2008-01-28 07:26:10 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
2007-04-20 23:45:14 +00:00
switch_dialplan_interface_t * dialplan_interface = NULL ;
switch_caller_extension_t * extension = NULL ;
2007-04-29 03:42:38 +00:00
switch_status_t status = SWITCH_STATUS_SUCCESS ;
2007-04-20 23:45:14 +00:00
if ( ! ( profile = switch_channel_get_caller_profile ( channel ) ) ) {
2007-04-29 03:42:38 +00:00
return SWITCH_STATUS_FALSE ;
}
2008-05-27 04:30:03 +00:00
2007-04-29 03:42:38 +00:00
if ( session - > stack_count > SWITCH_MAX_STACKS ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Error %s too many stacked extensions \n " , switch_channel_get_name ( session - > channel ) ) ;
2007-04-29 03:42:38 +00:00
return SWITCH_STATUS_FALSE ;
2007-04-20 23:45:14 +00:00
}
2007-04-29 03:42:38 +00:00
session - > stack_count + + ;
2008-05-27 04:30:03 +00:00
2007-04-20 23:45:14 +00:00
new_profile = switch_caller_profile_clone ( session , profile ) ;
2009-04-10 21:37:17 +00:00
new_profile - > destination_number = switch_core_strdup ( new_profile - > pool , exten ) ;
2008-05-27 04:30:03 +00:00
2009-10-23 16:03:42 +00:00
if ( ! zstr ( dialplan ) ) {
2009-04-10 21:37:17 +00:00
new_profile - > dialplan = switch_core_strdup ( new_profile - > pool , dialplan ) ;
2007-04-20 23:45:14 +00:00
}
2008-05-27 04:30:03 +00:00
2009-10-23 16:03:42 +00:00
if ( ! zstr ( context ) ) {
2009-04-10 21:37:17 +00:00
new_profile - > context = switch_core_strdup ( new_profile - > pool , context ) ;
2007-04-20 23:45:14 +00:00
}
2009-06-05 01:17:59 +00:00
dpstr = switch_core_session_strdup ( session , new_profile - > dialplan ) ;
2007-04-20 23:45:14 +00:00
2009-06-05 01:05:11 +00:00
switch_channel_set_hunt_caller_profile ( channel , new_profile ) ;
2007-04-20 23:45:14 +00:00
argc = switch_separate_string ( dpstr , ' , ' , dp , ( sizeof ( dp ) / sizeof ( dp [ 0 ] ) ) ) ;
for ( x = 0 ; x < argc ; x + + ) {
char * dpname = dp [ x ] ;
char * dparg = NULL ;
2008-05-27 04:30:03 +00:00
2007-04-20 23:45:14 +00:00
if ( dpname ) {
if ( ( dparg = strchr ( dpname , ' : ' ) ) ) {
* dparg + + = ' \0 ' ;
}
2008-05-16 14:59:28 +00:00
} else {
continue ;
2007-04-20 23:45:14 +00:00
}
2008-05-16 14:59:28 +00:00
2007-04-20 23:45:14 +00:00
if ( ! ( dialplan_interface = switch_loadable_module_get_dialplan_interface ( dpname ) ) ) {
continue ;
}
2008-05-27 04:30:03 +00:00
2007-04-20 23:45:14 +00:00
count + + ;
2008-05-27 04:30:03 +00:00
2009-07-28 18:33:18 +00:00
extension = dialplan_interface - > hunt_function ( session , dparg , new_profile ) ;
UNPROTECT_INTERFACE ( dialplan_interface ) ;
if ( extension ) {
2007-04-20 23:45:14 +00:00
break ;
}
}
2008-05-27 04:30:03 +00:00
2007-04-20 23:45:14 +00:00
if ( ! extension ) {
2007-04-29 03:42:38 +00:00
status = SWITCH_STATUS_FALSE ;
goto done ;
2007-04-20 23:45:14 +00:00
}
2007-04-21 01:03:58 +00:00
new_profile - > caller_extension = extension ;
2008-03-10 18:38:01 +00:00
if ( profile - > caller_extension ) {
2008-05-27 04:30:03 +00:00
for ( pp = profile - > caller_extension - > children ; pp & & pp - > next ; pp = pp - > next ) ;
2008-03-10 18:38:01 +00:00
if ( pp ) {
pp - > next = new_profile ;
} else {
profile - > caller_extension - > children = new_profile ;
}
2007-04-21 01:03:58 +00:00
}
2007-04-20 23:45:14 +00:00
while ( switch_channel_ready ( channel ) & & extension - > current_application ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_NOTICE , " Execute %s(%s) \n " ,
2007-04-20 23:45:14 +00:00
extension - > current_application - > application_name , switch_str_nil ( extension - > current_application - > application_data ) ) ;
2008-05-27 04:30:03 +00:00
2008-04-02 15:11:07 +00:00
if ( switch_core_session_execute_application ( session ,
extension - > current_application - > application_name ,
extension - > current_application - > application_data ) ! = SWITCH_STATUS_SUCCESS ) {
2007-04-29 03:42:38 +00:00
goto done ;
2007-04-20 23:45:14 +00:00
}
2008-05-27 04:30:03 +00:00
extension - > current_application = extension - > current_application - > next ;
2007-04-20 23:45:14 +00:00
}
2008-05-27 04:30:03 +00:00
done :
2009-06-05 01:05:11 +00:00
switch_channel_set_hunt_caller_profile ( channel , NULL ) ;
2007-04-29 03:42:38 +00:00
session - > stack_count - - ;
2008-05-27 04:30:03 +00:00
return status ;
2007-04-20 23:45:14 +00:00
}
2008-01-27 17:36:53 +00:00
/* For Emacs:
* Local Variables :
* mode : c
2008-02-03 22:14:57 +00:00
* indent - tabs - mode : t
2008-01-27 17:36:53 +00:00
* tab - width : 4
* c - basic - offset : 4
* End :
* For VIM :
2008-07-03 19:12:26 +00:00
* vim : set softtabstop = 4 shiftwidth = 4 tabstop = 4 :
2008-01-27 17:36:53 +00:00
*/