2007-03-29 22:34:40 +00:00
/*
* FreeSWITCH Modular Media Switching Software Library / Soft - Switch Application
* Copyright ( C ) 2005 / 2006 , Anthony Minessale II < anthmct @ yahoo . com >
*
* 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
* Anthony Minessale II < anthmct @ yahoo . com >
* Portions created by the Initial Developer are Copyright ( C )
* the Initial Developer . All Rights Reserved .
*
* Contributor ( s ) :
*
* Anthony Minessale II < anthmct @ yahoo . com >
* Michael Jerris < mike @ jerris . com >
* Paul D . Tinsley < pdt at jackhammer . org >
*
*
* switch_core_state_maching . c - - Main Core Library ( state machine )
*
*/
2008-01-27 17:36:53 +00:00
2007-03-29 22:34:40 +00:00
# include <switch.h>
2007-05-14 17:10:46 +00:00
# include "private/switch_core_pvt.h"
2007-03-29 22:34:40 +00:00
static void switch_core_standard_on_init ( switch_core_session_t * session )
{
2007-03-30 00:13:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Standard INIT %s \n " , switch_channel_get_name ( session - > channel ) ) ;
2007-03-29 22:34:40 +00:00
}
static void switch_core_standard_on_hangup ( switch_core_session_t * session )
{
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Standard HANGUP %s, cause: %s \n " ,
2007-03-30 00:13:31 +00:00
switch_channel_get_name ( session - > channel ) , switch_channel_cause2str ( switch_channel_get_cause ( session - > channel ) ) ) ;
2007-03-29 22:34:40 +00:00
}
2007-07-03 02:10:35 +00:00
static void switch_core_standard_on_reset ( switch_core_session_t * session )
{
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Standard RESET %s \n " ,
2008-01-27 17:36:53 +00:00
switch_channel_get_name ( session - > channel ) ) ;
2007-07-03 02:10:35 +00:00
}
2007-03-29 22:34:40 +00:00
static void switch_core_standard_on_ring ( switch_core_session_t * session )
{
switch_dialplan_interface_t * dialplan_interface = NULL ;
switch_caller_profile_t * caller_profile ;
switch_caller_extension_t * extension = NULL ;
2008-01-08 19:38:57 +00:00
char * expanded = NULL ;
char * dpstr = NULL ;
2007-03-29 22:34:40 +00:00
2007-03-30 00:13:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Standard RING %s \n " , switch_channel_get_name ( session - > channel ) ) ;
2007-03-29 22:34:40 +00:00
if ( ( caller_profile = switch_channel_get_caller_profile ( session - > channel ) ) = = 0 ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Can't get profile! \n " ) ;
switch_channel_hangup ( session - > channel , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
return ;
} else {
char * dp [ 25 ] ;
int argc , x , count = 0 ;
2008-01-08 19:38:57 +00:00
2007-03-29 22:34:40 +00:00
if ( ! switch_strlen_zero ( caller_profile - > dialplan ) ) {
if ( ( dpstr = switch_core_session_strdup ( session , caller_profile - > dialplan ) ) ) {
2008-01-08 19:38:57 +00:00
expanded = switch_channel_expand_variables ( session - > channel , dpstr ) ;
argc = switch_separate_string ( expanded , ' , ' , dp , ( sizeof ( dp ) / sizeof ( dp [ 0 ] ) ) ) ;
2007-03-29 22:34:40 +00:00
for ( x = 0 ; x < argc ; x + + ) {
char * dpname = dp [ x ] ;
char * dparg = NULL ;
2008-01-08 19:38:57 +00:00
2007-03-29 22:34:40 +00:00
if ( dpname ) {
if ( ( dparg = strchr ( dpname , ' : ' ) ) ) {
* dparg + + = ' \0 ' ;
}
}
if ( ! ( dialplan_interface = switch_loadable_module_get_dialplan_interface ( dpname ) ) ) {
continue ;
}
2008-01-08 19:38:57 +00:00
2007-03-29 22:34:40 +00:00
count + + ;
2007-04-20 23:45:14 +00:00
if ( ( extension = dialplan_interface - > hunt_function ( session , dparg , NULL ) ) ! = 0 ) {
2007-03-29 22:34:40 +00:00
switch_channel_set_caller_extension ( session - > channel , extension ) ;
2008-03-11 03:45:16 +00:00
switch_channel_set_state ( session - > channel , CS_EXECUTE ) ;
2008-01-08 19:38:57 +00:00
goto end ;
2007-03-29 22:34:40 +00:00
}
}
}
}
if ( ! count ) {
if ( switch_channel_test_flag ( session - > channel , CF_OUTBOUND ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_INFO , " No Dialplan, changing state to HOLD \n " ) ;
switch_channel_set_state ( session - > channel , CS_HOLD ) ;
2008-01-08 19:38:57 +00:00
goto end ;
2007-03-29 22:34:40 +00:00
}
}
}
if ( ! extension ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_INFO , " No Route, Aborting \n " ) ;
switch_channel_hangup ( session - > channel , SWITCH_CAUSE_NO_ROUTE_DESTINATION ) ;
}
2008-03-11 03:45:16 +00:00
2008-01-08 19:38:57 +00:00
end :
if ( expanded & & dpstr & & expanded ! = dpstr ) {
free ( expanded ) ;
}
2008-03-11 03:45:16 +00:00
2007-03-29 22:34:40 +00:00
}
static void switch_core_standard_on_execute ( switch_core_session_t * session )
{
switch_caller_extension_t * extension ;
const switch_application_interface_t * application_interface ;
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Standard EXECUTE \n " ) ;
2007-07-26 00:49:02 +00:00
top :
switch_channel_clear_flag ( session - > channel , CF_RESET ) ;
2007-03-29 22:34:40 +00:00
if ( ( extension = switch_channel_get_caller_extension ( session - > channel ) ) = = 0 ) {
switch_channel_hangup ( session - > channel , SWITCH_CAUSE_NORMAL_CLEARING ) ;
return ;
}
while ( switch_channel_get_state ( session - > channel ) = = CS_EXECUTE & & extension - > current_application ) {
char * expanded = NULL ;
2008-03-04 00:52:54 +00:00
2008-01-05 01:03:08 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " %s Execute %s(%s) \n " , switch_channel_get_name ( session - > channel ) ,
2007-03-30 00:13:31 +00:00
extension - > current_application - > application_name , switch_str_nil ( extension - > current_application - > application_data ) ) ;
if ( ( application_interface = switch_loadable_module_get_application_interface ( extension - > current_application - > application_name ) ) = = 0 ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Invalid Application %s \n " , extension - > current_application - > application_name ) ;
2007-03-29 22:34:40 +00:00
switch_channel_hangup ( session - > channel , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
return ;
}
2007-11-30 22:56:01 +00:00
2007-03-29 22:34:40 +00:00
if ( ! application_interface - > application_function ) {
2007-03-30 00:13:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " No Function for %s \n " , extension - > current_application - > application_name ) ;
2007-03-29 22:34:40 +00:00
switch_channel_hangup ( session - > channel , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
return ;
}
2007-11-30 22:56:01 +00:00
2008-02-21 17:48:41 +00:00
if ( switch_channel_test_flag ( session - > channel , CF_PROXY_MODE ) & & ! switch_test_flag ( application_interface , SAF_SUPPORT_NOMEDIA ) ) {
2007-11-30 22:56:01 +00:00
switch_ivr_media ( session - > uuid_str , SMF_NONE ) ;
2008-02-05 17:08:58 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Application %s Requires media on channel %s! \n " ,
2008-02-05 16:46:39 +00:00
extension - > current_application - > application_name , switch_channel_get_name ( session - > channel ) ) ;
2008-02-05 17:08:58 +00:00
} else if ( ! switch_test_flag ( application_interface , SAF_SUPPORT_NOMEDIA ) & & ! switch_channel_media_ready ( session - > channel ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Application %s Requires media! pre_answering channel %s \n " ,
2008-02-05 16:46:39 +00:00
extension - > current_application - > application_name , switch_channel_get_name ( session - > channel ) ) ;
switch_channel_pre_answer ( session - > channel ) ;
2007-11-30 22:56:01 +00:00
}
2007-03-29 22:34:40 +00:00
if ( ( expanded =
switch_channel_expand_variables ( session - > channel ,
2007-03-30 00:13:31 +00:00
extension - > current_application - > application_data ) ) ! = extension - > current_application - > application_data ) {
2008-01-05 01:03:08 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " %s Expanded String %s(%s) \n " , switch_channel_get_name ( session - > channel ) ,
2008-01-27 17:36:53 +00:00
extension - > current_application - > application_name , expanded ) ;
2007-03-29 22:34:40 +00:00
}
if ( switch_channel_get_variable ( session - > channel , " presence_id " ) ) {
char * arg = switch_mprintf ( " %s(%s) " , extension - > current_application - > application_name , expanded ) ;
if ( arg ) {
switch_channel_presence ( session - > channel , " unknown " , arg ) ;
switch_safe_free ( arg ) ;
}
}
2007-04-21 01:03:58 +00:00
switch_core_session_exec ( session , application_interface , expanded ) ;
//application_interface->application_function(session, expanded);
2007-03-29 22:34:40 +00:00
if ( expanded ! = extension - > current_application - > application_data ) {
switch_safe_free ( expanded ) ;
}
2007-07-26 00:49:02 +00:00
if ( switch_channel_test_flag ( session - > channel , CF_RESET ) ) {
goto top ;
}
2007-03-29 22:34:40 +00:00
extension - > current_application = extension - > current_application - > next ;
}
if ( switch_channel_get_state ( session - > channel ) = = CS_EXECUTE ) {
switch_channel_hangup ( session - > channel , SWITCH_CAUSE_NORMAL_CLEARING ) ;
}
}
static void switch_core_standard_on_loopback ( switch_core_session_t * session )
{
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Standard LOOPBACK \n " ) ;
2007-04-19 21:40:50 +00:00
switch_ivr_session_echo ( session ) ;
2007-03-29 22:34:40 +00:00
}
static void switch_core_standard_on_transmit ( 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
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Standard TRANSMIT \n " ) ;
}
2007-12-13 22:17:20 +00:00
static void switch_core_standard_on_park ( switch_core_session_t * session )
{
switch_assert ( session ! = NULL ) ;
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Standard PARK \n " ) ;
switch_channel_clear_flag ( session - > channel , CF_TRANSFER ) ;
2008-01-13 18:39:51 +00:00
switch_core_session_reset ( session , SWITCH_TRUE ) ;
2007-12-13 22:17:20 +00:00
switch_ivr_park ( session , NULL ) ;
}
2007-03-29 22:34:40 +00:00
static void switch_core_standard_on_hold ( 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
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Standard HOLD \n " ) ;
}
static void switch_core_standard_on_hibernate ( 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
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Standard HIBERNATE \n " ) ;
}
2007-09-29 01:06:08 +00:00
# include <sqlite3.h>
# include "../../../libs/sqlite/src/hash.h"
//static switch_hash_t *stack_table = NULL;
static Hash stack_table ;
2007-03-30 02:20:13 +00:00
# if defined (__GNUC__) && defined (LINUX)
# include <execinfo.h>
# include <stdio.h>
# include <stdlib.h>
# define STACK_LEN 10
/* Obtain a backtrace and print it to stdout. */
static void print_trace ( void )
{
void * array [ STACK_LEN ] ;
size_t size ;
char * * strings ;
size_t i ;
size = backtrace ( array , STACK_LEN ) ;
strings = backtrace_symbols ( array , size ) ;
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Obtained %zd stack frames. \n " , size ) ;
for ( i = 0 ; i < size ; i + + ) {
switch_log_printf ( SWITCH_CHANNEL_LOG_CLEAN , SWITCH_LOG_CRIT , " %s \n " , strings [ i ] ) ;
}
free ( strings ) ;
}
# else
static void print_trace ( void )
{
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Trace not avaliable =( \n " ) ;
}
# endif
static void handle_fatality ( int sig )
{
switch_thread_id_t thread_id ;
jmp_buf * env ;
if ( sig & & ( thread_id = switch_thread_self ( ) )
2007-09-29 01:06:08 +00:00
& & ( env = ( jmp_buf * ) sqlite3HashFind ( & stack_table , & thread_id , sizeof ( thread_id ) ) ) ) {
//&& (env = (jmp_buf *) switch_core_hash_find(stack_table, (char *)&thread_id, sizeof(thread_id)))) {
2007-03-30 02:20:13 +00:00
print_trace ( ) ;
longjmp ( * env , sig ) ;
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Caught signal %d for unmapped thread! " , sig ) ;
abort ( ) ;
}
}
2007-05-10 16:56:29 +00:00
2007-03-30 02:20:13 +00:00
void switch_core_state_machine_init ( switch_memory_pool_t * pool )
{
2007-09-29 01:06:08 +00:00
if ( switch_test_flag ( ( & runtime ) , SCF_CRASH_PROT ) ) {
sqlite3HashInit ( & stack_table , SQLITE_HASH_BINARY , 0 ) ;
2007-05-10 16:56:29 +00:00
}
2007-03-30 02:20:13 +00:00
}
2007-10-04 20:22:37 +00:00
# define STATE_MACRO(__STATE, __STATE_STR) do { \
midstate = state ; \
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " (%s) State %s \n " , switch_channel_get_name ( session - > channel ) , __STATE_STR ) ; \
2008-03-11 03:45:16 +00:00
if ( ! driver_state_handler - > on_ # # __STATE | | ( driver_state_handler - > on_ # # __STATE ( session ) = = SWITCH_STATUS_SUCCESS \
2007-10-04 20:22:37 +00:00
& & midstate = = switch_channel_get_state ( session - > channel ) ) ) { \
2008-01-14 15:26:46 +00:00
while ( do_extra_handlers & & ( application_state_handler = switch_channel_get_state_handler ( session - > channel , index + + ) ) ! = 0 ) { \
2007-10-04 20:22:37 +00:00
if ( ! application_state_handler | | ! application_state_handler - > on_ # # __STATE \
| | ( application_state_handler - > on_ # # __STATE \
& & application_state_handler - > on_ # # __STATE ( session ) = = SWITCH_STATUS_SUCCESS \
& & midstate = = switch_channel_get_state ( session - > channel ) ) ) { \
proceed + + ; \
continue ; \
} else { \
proceed = 0 ; \
break ; \
} \
} \
index = 0 ; \
2008-01-14 15:26:46 +00:00
while ( do_extra_handlers & & proceed & & ( application_state_handler = switch_core_get_state_handler ( index + + ) ) ! = 0 ) { \
2007-10-04 20:22:37 +00:00
if ( ! application_state_handler | | ! application_state_handler - > on_ # # __STATE | | \
( application_state_handler - > on_ # # __STATE & & \
application_state_handler - > on_ # # __STATE ( session ) = = SWITCH_STATUS_SUCCESS \
& & midstate = = switch_channel_get_state ( session - > channel ) ) ) { \
proceed + + ; \
continue ; \
} else { \
proceed = 0 ; \
break ; \
} \
} \
if ( proceed ) { \
switch_core_standard_on_ # # __STATE ( session ) ; \
} \
} \
2008-03-11 03:45:16 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " (%s) State end %s %s %s \n " , switch_channel_get_name ( session - > channel ) , __STATE_STR , switch_channel_state_name ( midstate ) , switch_channel_state_name ( switch_channel_get_state ( session - > channel ) ) ) ; \
2007-10-04 21:01:52 +00:00
} while ( silly )
2007-10-04 20:22:37 +00:00
2007-03-29 22:34:40 +00:00
SWITCH_DECLARE ( void ) switch_core_session_run ( switch_core_session_t * session )
{
2007-12-19 23:24:55 +00:00
switch_channel_state_t state = CS_NEW , midstate = CS_DONE , endstate ;
2007-03-29 22:34:40 +00:00
const switch_endpoint_interface_t * endpoint_interface ;
const switch_state_handler_table_t * driver_state_handler = NULL ;
const switch_state_handler_table_t * application_state_handler = NULL ;
2007-05-10 16:56:29 +00:00
switch_thread_id_t thread_id ;
2007-03-29 22:34:40 +00:00
jmp_buf env ;
2007-10-04 21:01:52 +00:00
int sig , silly = 0 ;
2007-03-29 22:34:40 +00:00
2007-09-29 01:06:08 +00:00
if ( switch_test_flag ( ( & runtime ) , SCF_CRASH_PROT ) ) {
2007-05-10 16:56:29 +00:00
thread_id = switch_thread_self ( ) ;
signal ( SIGSEGV , handle_fatality ) ;
signal ( SIGFPE , handle_fatality ) ;
2007-03-29 22:34:40 +00:00
# ifndef WIN32
2007-05-10 16:56:29 +00:00
signal ( SIGBUS , handle_fatality ) ;
2007-03-29 22:34:40 +00:00
# endif
2007-05-10 16:56:29 +00:00
if ( ( sig = setjmp ( env ) ) ! = 0 ) {
switch_event_t * event ;
2007-03-29 22:34:40 +00:00
2007-05-10 16:56:29 +00:00
if ( switch_event_create ( & event , SWITCH_EVENT_SESSION_CRASH ) = = SWITCH_STATUS_SUCCESS ) {
switch_channel_event_set_data ( session - > channel , event ) ;
switch_event_fire ( & event ) ;
}
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Thread has crashed for channel %s \n " , switch_channel_get_name ( session - > channel ) ) ;
switch_channel_hangup ( session - > channel , SWITCH_CAUSE_CRASH ) ;
} else {
2007-09-29 01:06:08 +00:00
sqlite3HashInsert ( & stack_table , & thread_id , sizeof ( thread_id ) , ( void * ) & env ) ;
//apr_hash_set(stack_table, &thread_id, sizeof(thread_id), &env);
2007-03-29 22:34:40 +00:00
}
}
2007-05-10 16:56:29 +00:00
2007-03-29 22:34:40 +00:00
/*
Life of the channel . you have channel and pool in your session
everywhere you go you use the session to malloc with
switch_core_session_alloc ( session , < size > )
The enpoint module gets the first crack at implementing the state
if it wants to , it can cancel the default behaviour by returning SWITCH_STATUS_FALSE
Next comes the channel ' s event handler table that can be set by an application
which also can veto the next behaviour in line by returning SWITCH_STATUS_FALSE
Finally the default state behaviour is called .
*/
2007-12-11 19:23:57 +00:00
switch_assert ( session ! = NULL ) ;
2007-03-29 22:34:40 +00:00
session - > thread_running = 1 ;
endpoint_interface = session - > endpoint_interface ;
2007-12-11 19:23:57 +00:00
switch_assert ( endpoint_interface ! = NULL ) ;
2007-03-29 22:34:40 +00:00
driver_state_handler = endpoint_interface - > state_handler ;
2007-12-11 19:23:57 +00:00
switch_assert ( driver_state_handler ! = NULL ) ;
2007-03-29 22:34:40 +00:00
switch_mutex_lock ( session - > mutex ) ;
while ( ( state = switch_channel_get_state ( session - > channel ) ) ! = CS_DONE ) {
uint8_t exception = 0 ;
2007-10-05 16:09:47 +00:00
midstate = state ;
2007-03-29 22:34:40 +00:00
if ( switch_channel_test_flag ( session - > channel , CF_REPEAT_STATE ) ) {
switch_channel_clear_flag ( session - > channel , CF_REPEAT_STATE ) ;
exception = 1 ;
}
2007-12-19 23:24:55 +00:00
if ( state ! = switch_channel_get_running_state ( session - > channel ) | | state = = CS_HANGUP | | exception ) {
2007-03-29 22:34:40 +00:00
int index = 0 ;
int proceed = 1 ;
2008-01-14 15:26:46 +00:00
int do_extra_handlers = 1 ;
2008-03-08 21:07:15 +00:00
switch_channel_set_running_state ( session - > channel , state ) ;
2007-03-29 22:34:40 +00:00
switch ( state ) {
case CS_NEW : /* Just created, Waiting for first instructions */
2007-03-30 00:13:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " (%s) State NEW \n " , switch_channel_get_name ( session - > channel ) ) ;
2007-03-29 22:34:40 +00:00
break ;
case CS_DONE :
goto done ;
2008-02-26 20:31:53 +00:00
/* HANGUP INIT RING and RESET are all short term so we signal lock during their callbacks */
2007-10-04 20:22:37 +00:00
case CS_HANGUP : /* Deactivate and end the thread */
2008-01-14 15:26:46 +00:00
{
2008-01-14 15:37:00 +00:00
const char * var = switch_channel_get_variable ( session - > channel , SWITCH_PROCESS_CDR_VARIABLE ) ;
if ( ! switch_strlen_zero ( var ) ) {
2008-01-14 16:10:56 +00:00
if ( ! strcasecmp ( var , " a_only " ) ) {
if ( switch_channel_get_originator_caller_profile ( session - > channel ) ) {
do_extra_handlers = 0 ;
}
} else if ( ! strcasecmp ( var , " b_only " ) ) {
if ( switch_channel_get_originatee_caller_profile ( session - > channel ) ) {
do_extra_handlers = 0 ;
}
2008-01-14 15:37:00 +00:00
} else if ( ! switch_true ( var ) ) {
do_extra_handlers = 0 ;
}
2008-01-14 15:26:46 +00:00
}
2008-02-26 20:31:53 +00:00
switch_core_session_signal_lock ( session ) ;
2008-01-14 15:26:46 +00:00
STATE_MACRO ( hangup , " HANGUP " ) ;
2008-02-26 20:31:53 +00:00
switch_core_session_signal_unlock ( session ) ;
2008-01-14 15:26:46 +00:00
}
2007-03-29 22:34:40 +00:00
goto done ;
2008-02-26 20:31:53 +00:00
case CS_INIT : /* Basic setup tasks */
2008-03-11 03:45:16 +00:00
assert ( driver_state_handler - > on_init ) ;
//switch_core_session_signal_lock(session);
if ( 0 ) STATE_MACRO ( init , " INIT " ) ;
//switch_core_session_signal_unlock(session);
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " (%s) State INIT \n " , switch_channel_get_name ( session - > channel ) ) ;
driver_state_handler - > on_init ( session ) ;
assert ( switch_channel_get_state ( session - > channel ) ! = CS_INIT ) ;
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " (%s) State INIT-END \n " , switch_channel_get_name ( session - > channel ) ) ;
2007-03-29 22:34:40 +00:00
break ;
2008-02-26 20:31:53 +00:00
case CS_RING : /* Look for a dialplan and find something to do */
switch_core_session_signal_lock ( session ) ;
2007-10-04 20:22:37 +00:00
STATE_MACRO ( ring , " RING " ) ;
2008-02-26 20:31:53 +00:00
switch_core_session_signal_unlock ( session ) ;
2007-03-29 22:34:40 +00:00
break ;
2008-02-26 20:31:53 +00:00
case CS_RESET : /* Reset */
switch_core_session_signal_lock ( session ) ;
2007-10-04 20:22:37 +00:00
STATE_MACRO ( reset , " RESET " ) ;
2008-02-26 20:31:53 +00:00
switch_core_session_signal_unlock ( session ) ;
2007-07-03 02:10:35 +00:00
break ;
2008-02-26 20:31:53 +00:00
/* These other states are intended for prolonged durations so we do not signal lock for them */
case CS_EXECUTE : /* Execute an Operation */
2007-10-04 20:22:37 +00:00
STATE_MACRO ( execute , " EXECUTE " ) ;
2007-03-29 22:34:40 +00:00
break ;
2008-02-26 20:31:53 +00:00
case CS_LOOPBACK : /* loop all data back to source */
2007-10-04 20:22:37 +00:00
STATE_MACRO ( loopback , " LOOPBACK " ) ;
2007-03-29 22:34:40 +00:00
break ;
2008-02-26 20:31:53 +00:00
case CS_TRANSMIT : /* send/recieve data to/from another channel */
2007-10-04 20:22:37 +00:00
STATE_MACRO ( transmit , " TRANSMIT " ) ;
2007-03-29 22:34:40 +00:00
break ;
2008-02-26 20:31:53 +00:00
case CS_PARK : /* wait in limbo */
2007-12-13 22:17:20 +00:00
STATE_MACRO ( park , " PARK " ) ;
break ;
2008-02-26 20:31:53 +00:00
case CS_HOLD : /* wait in limbo */
2007-10-04 20:22:37 +00:00
STATE_MACRO ( hold , " HOLD " ) ;
2007-03-29 22:34:40 +00:00
break ;
2008-02-26 20:31:53 +00:00
case CS_HIBERNATE : /* sleep */
2007-10-04 20:22:37 +00:00
STATE_MACRO ( hibernate , " HIBERNATE " ) ;
2007-03-29 22:34:40 +00:00
break ;
2007-12-19 23:24:55 +00:00
case CS_NONE :
abort ( ) ;
break ;
2007-03-29 22:34:40 +00:00
}
2007-10-04 20:22:37 +00:00
2007-03-29 22:34:40 +00:00
if ( midstate = = CS_DONE ) {
break ;
}
}
endstate = switch_channel_get_state ( session - > channel ) ;
2007-12-19 23:24:55 +00:00
if ( endstate = = switch_channel_get_running_state ( session - > channel ) ) {
2007-10-11 19:12:18 +00:00
if ( endstate = = CS_NEW ) {
switch_yield ( 1000 ) ;
} else {
2008-03-11 03:45:16 +00:00
assert ( switch_channel_get_state ( session - > channel ) ! = CS_INIT ) ;
assert ( switch_channel_get_running_state ( session - > channel ) ! = CS_INIT ) ;
2007-10-11 19:12:18 +00:00
switch_thread_cond_wait ( session - > cond , session - > mutex ) ;
}
2007-03-29 22:34:40 +00:00
}
}
done :
switch_mutex_unlock ( session - > mutex ) ;
2007-09-29 01:06:08 +00:00
if ( switch_test_flag ( ( & runtime ) , SCF_CRASH_PROT ) ) {
sqlite3HashInsert ( & stack_table , & thread_id , sizeof ( thread_id ) , NULL ) ;
//apr_hash_set(stack_table, &thread_id, sizeof(thread_id), NULL);
2007-05-10 16:56:29 +00:00
}
2007-03-29 22:34:40 +00:00
session - > thread_running = 0 ;
}
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 :
* vim : set softtabstop = 4 shiftwidth = 4 tabstop = 4 expandtab :
*/