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_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 )
{
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " %s Standard INIT \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 )
{
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " %s Standard HANGUP, 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
}
2009-03-04 04:19:33 +00:00
static void switch_core_standard_on_reporting ( switch_core_session_t * session )
{
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " %s Standard REPORTING, cause: %s \n " ,
2009-03-04 04:19:33 +00:00
switch_channel_get_name ( session - > channel ) , switch_channel_cause2str ( switch_channel_get_cause ( session - > channel ) ) ) ;
}
2009-04-10 17:43:18 +00:00
static void switch_core_standard_on_destroy ( switch_core_session_t * session )
{
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " %s Standard DESTROY \n " ,
2009-04-10 17:43:18 +00:00
switch_channel_get_name ( session - > channel ) ) ;
}
2007-07-03 02:10:35 +00:00
static void switch_core_standard_on_reset ( switch_core_session_t * session )
{
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " %s Standard RESET \n " , switch_channel_get_name ( session - > channel ) ) ;
2007-07-03 02:10:35 +00:00
}
2008-05-05 15:30:55 +00:00
static void switch_core_standard_on_routing ( switch_core_session_t * session )
2007-03-29 22:34:40 +00:00
{
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
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " %s Standard ROUTING \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 ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Can't get profile! \n " ) ;
2007-03-29 22:34:40 +00:00
switch_channel_hangup ( session - > channel , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
return ;
} else {
char * dp [ 25 ] ;
int argc , x , count = 0 ;
2008-05-27 04:30:03 +00:00
2009-10-23 16:03:42 +00:00
if ( ! zstr ( caller_profile - > dialplan ) ) {
2007-03-29 22:34:40 +00:00
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-10-28 16:01:15 +00:00
2007-03-29 22:34:40 +00:00
if ( dpname ) {
if ( ( dparg = strchr ( dpname , ' : ' ) ) ) {
* dparg + + = ' \0 ' ;
}
2008-05-16 15:49:23 +00:00
} else {
continue ;
2007-03-29 22:34:40 +00:00
}
if ( ! ( dialplan_interface = switch_loadable_module_get_dialplan_interface ( dpname ) ) ) {
continue ;
}
2008-10-28 16:01:15 +00:00
2007-03-29 22:34:40 +00:00
count + + ;
2008-11-12 19:28:05 +00:00
extension = dialplan_interface - > hunt_function ( session , dparg , NULL ) ;
UNPROTECT_INTERFACE ( dialplan_interface ) ;
if ( extension ) {
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 ) ) {
2008-10-28 16:01:15 +00:00
if ( switch_channel_test_flag ( session - > channel , CF_ANSWERED ) ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " No Dialplan on answered channel, changing state to HANGUP \n " ) ;
2008-10-28 16:01:15 +00:00
switch_channel_hangup ( session - > channel , SWITCH_CAUSE_NO_ROUTE_DESTINATION ) ;
} else {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " No Dialplan, changing state to CONSUME_MEDIA \n " ) ;
2008-10-28 16:01:15 +00:00
switch_channel_set_state ( session - > channel , CS_CONSUME_MEDIA ) ;
}
2008-01-08 19:38:57 +00:00
goto end ;
2007-03-29 22:34:40 +00:00
}
}
}
if ( ! extension ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_INFO , " No Route, Aborting \n " ) ;
2007-03-29 22:34:40 +00:00
switch_channel_hangup ( session - > channel , SWITCH_CAUSE_NO_ROUTE_DESTINATION ) ;
}
2008-05-27 04:30:03 +00:00
end :
2008-01-08 19:38:57 +00:00
if ( expanded & & dpstr & & expanded ! = dpstr ) {
free ( expanded ) ;
}
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 ;
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " %s Standard EXECUTE \n " , switch_channel_get_name ( session - > channel ) ) ;
2007-03-29 22:34:40 +00:00
2008-05-27 04:30:03 +00:00
top :
2007-07-26 00:49:02 +00:00
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 ) {
2008-09-25 14:25:59 +00:00
switch_caller_application_t * current_application = extension - > current_application ;
extension - > current_application = extension - > current_application - > next ;
2008-05-27 04:30:03 +00:00
if ( switch_core_session_execute_application ( session ,
2008-09-25 14:25:59 +00:00
current_application - > application_name ,
current_application - > application_data ) ! = SWITCH_STATUS_SUCCESS ) {
2007-03-29 22:34:40 +00:00
return ;
}
2008-05-27 04:30:03 +00:00
2007-07-26 00:49:02 +00:00
if ( switch_channel_test_flag ( session - > channel , CF_RESET ) ) {
goto top ;
}
2008-09-25 14:25:59 +00:00
2007-03-29 22:34:40 +00:00
}
if ( switch_channel_get_state ( session - > channel ) = = CS_EXECUTE ) {
2008-11-21 00:09:11 +00:00
switch_channel_hangup ( session - > channel , SWITCH_CAUSE_NORMAL_CLEARING ) ;
2007-03-29 22:34:40 +00:00
}
}
2008-05-05 15:30:55 +00:00
static void switch_core_standard_on_exchange_media ( switch_core_session_t * session )
2007-03-29 22:34:40 +00:00
{
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " %s Standard EXCHANGE_MEDIA \n " , switch_channel_get_name ( session - > channel ) ) ;
2007-03-29 22:34:40 +00:00
}
2008-05-05 15:30:55 +00:00
static void switch_core_standard_on_soft_execute ( switch_core_session_t * session )
2007-03-29 22:34:40 +00:00
{
2007-12-11 19:23:57 +00:00
switch_assert ( session ! = NULL ) ;
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " %s Standard SOFT_EXECUTE \n " , switch_channel_get_name ( session - > channel ) ) ;
2007-03-29 22:34:40 +00:00
}
2007-12-13 22:17:20 +00:00
static void switch_core_standard_on_park ( switch_core_session_t * session )
{
switch_assert ( session ! = NULL ) ;
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " %s Standard PARK \n " , switch_channel_get_name ( session - > channel ) ) ;
2009-01-09 20:34:01 +00:00
switch_core_session_reset ( session , SWITCH_TRUE , SWITCH_TRUE ) ;
2007-12-13 22:17:20 +00:00
switch_ivr_park ( session , NULL ) ;
}
2008-05-05 15:30:55 +00:00
static void switch_core_standard_on_consume_media ( switch_core_session_t * session )
2007-03-29 22:34:40 +00:00
{
2007-12-11 19:23:57 +00:00
switch_assert ( session ! = NULL ) ;
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " %s Standard CONSUME_MEDIA \n " , switch_channel_get_name ( session - > channel ) ) ;
2007-03-29 22:34:40 +00:00
}
static void switch_core_standard_on_hibernate ( switch_core_session_t * session )
{
2007-12-11 19:23:57 +00:00
switch_assert ( session ! = NULL ) ;
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " %s Standard HIBERNATE \n " , switch_channel_get_name ( session - > channel ) ) ;
2007-03-29 22:34:40 +00:00
}
2007-03-30 02:20:13 +00:00
void switch_core_state_machine_init ( switch_memory_pool_t * pool )
{
2009-09-18 15:55:10 +00:00
return ;
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 ; \
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " (%s) State %s \n " , switch_channel_get_name ( session - > channel ) , __STATE_STR ) ; \
2008-03-11 14:08:33 +00:00
if ( ! driver_state_handler - > on_ # # __STATE | | ( driver_state_handler - > on_ # # __STATE ( session ) = = SWITCH_STATUS_SUCCESS \
2009-02-03 17:17:31 +00:00
) ) { \
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 \
2009-02-03 17:17:31 +00:00
) ) { \
2007-10-04 20:22:37 +00:00
proceed + + ; \
continue ; \
} else { \
proceed = 0 ; \
break ; \
} \
} \
index = 0 ; \
2009-02-03 17:17:31 +00:00
if ( ! proceed ) global_proceed = 0 ; \
proceed = 1 ; \
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 \
2009-02-03 17:17:31 +00:00
) ) { \
2007-10-04 20:22:37 +00:00
proceed + + ; \
continue ; \
} else { \
proceed = 0 ; \
break ; \
} \
} \
2009-02-03 17:17:31 +00:00
if ( ! proceed | | midstate ! = switch_channel_get_state ( session - > channel ) ) global_proceed = 0 ; \
if ( global_proceed ) { \
2007-10-04 20:22:37 +00:00
switch_core_standard_on_ # # __STATE ( session ) ; \
} \
} \
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " (%s) State %s going to sleep \n " , switch_channel_get_name ( session - > channel ) , __STATE_STR ) ; \
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 )
{
2009-04-10 17:43:18 +00:00
switch_channel_state_t state = CS_NEW , midstate = CS_DESTROY , 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 ;
2009-09-18 15:55:10 +00:00
int silly = 0 ;
2009-07-22 19:14:47 +00:00
uint32_t new_loops = 60000 ;
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 > )
2008-10-06 23:05:55 +00:00
The endpoint module gets the first crack at implementing the state
if it wants to , it can cancel the default behavior by returning SWITCH_STATUS_FALSE
2007-03-29 22:34:40 +00:00
Next comes the channel ' s event handler table that can be set by an application
2008-10-06 23:05:55 +00:00
which also can veto the next behavior in line by returning SWITCH_STATUS_FALSE
2007-03-29 22:34:40 +00:00
2008-10-06 23:05:55 +00:00
Finally the default state behavior is called .
2007-03-29 22:34:40 +00:00
*/
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 ) ;
2009-04-10 17:43:18 +00:00
while ( ( state = switch_channel_get_state ( session - > channel ) ) ! = CS_DESTROY ) {
2009-03-04 04:19:33 +00:00
switch_channel_wait_for_flag ( session - > channel , CF_BLOCK_STATE , SWITCH_FALSE , 0 , NULL ) ;
2007-10-05 16:09:47 +00:00
midstate = state ;
2009-03-04 04:19:33 +00:00
if ( state ! = switch_channel_get_running_state ( session - > channel ) | | state > = CS_HANGUP ) {
2007-03-29 22:34:40 +00:00
int index = 0 ;
int proceed = 1 ;
2009-02-03 17:17:31 +00:00
int global_proceed = 1 ;
2008-05-27 04:30:03 +00:00
int do_extra_handlers = 1 ;
2009-03-04 04:19:33 +00:00
2008-03-08 21:07:15 +00:00
switch_channel_set_running_state ( session - > channel , state ) ;
2008-11-21 00:09:11 +00:00
switch_channel_clear_flag ( session - > channel , CF_TRANSFER ) ;
2008-11-25 17:53:35 +00:00
switch_channel_clear_flag ( session - > channel , CF_REDIRECT ) ;
2007-03-29 22:34:40 +00:00
switch ( state ) {
2009-03-04 04:19:33 +00:00
case CS_NEW : /* Just created, Waiting for first instructions */
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " (%s) State NEW \n " , switch_channel_get_name ( session - > channel ) ) ;
2007-03-29 22:34:40 +00:00
break ;
2009-04-10 17:43:18 +00:00
case CS_DESTROY :
2007-03-29 22:34:40 +00:00
goto done ;
2009-03-04 04:19:33 +00:00
case CS_REPORTING : /* Call Detail */
2008-01-14 15:26:46 +00:00
{
2009-04-28 14:13:05 +00:00
switch_core_session_reporting_state ( session ) ;
2009-04-10 17:43:18 +00:00
switch_channel_set_state ( session - > channel , CS_DESTROY ) ;
2009-03-04 04:19:33 +00:00
}
goto done ;
case CS_HANGUP : /* Deactivate and end the thread */
{
2009-09-14 20:10:58 +00:00
switch_core_session_hangup_state ( session ) ;
2009-03-25 20:07:40 +00:00
switch_channel_set_state ( session - > channel , CS_REPORTING ) ;
2008-01-14 15:26:46 +00:00
}
2009-03-25 20:07:40 +00:00
2009-03-04 04:19:33 +00:00
break ;
2008-05-27 04:30:03 +00:00
case CS_INIT : /* Basic setup tasks */
2008-03-11 14:08:33 +00:00
STATE_MACRO ( init , " INIT " ) ;
2007-03-29 22:34:40 +00:00
break ;
2008-05-27 04:30:03 +00:00
case CS_ROUTING : /* Look for a dialplan and find something to do */
2008-05-05 15:30:55 +00:00
STATE_MACRO ( routing , " ROUTING " ) ;
2007-03-29 22:34:40 +00:00
break ;
2008-05-27 04:30:03 +00:00
case CS_RESET : /* Reset */
2007-10-04 20:22:37 +00:00
STATE_MACRO ( reset , " RESET " ) ;
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 */
2008-05-27 04:30:03 +00:00
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-05-27 04:30:03 +00:00
case CS_EXCHANGE_MEDIA : /* loop all data back to source */
2008-05-05 15:30:55 +00:00
STATE_MACRO ( exchange_media , " EXCHANGE_MEDIA " ) ;
2007-03-29 22:34:40 +00:00
break ;
2008-05-27 04:30:03 +00:00
case CS_SOFT_EXECUTE : /* send/recieve data to/from another channel */
2008-05-05 15:30:55 +00:00
STATE_MACRO ( soft_execute , " SOFT_EXECUTE " ) ;
2007-03-29 22:34:40 +00:00
break ;
2008-05-27 04:30:03 +00:00
case CS_PARK : /* wait in limbo */
2007-12-13 22:17:20 +00:00
STATE_MACRO ( park , " PARK " ) ;
break ;
2008-05-27 04:30:03 +00:00
case CS_CONSUME_MEDIA : /* wait in limbo */
2008-05-05 15:30:55 +00:00
STATE_MACRO ( consume_media , " CONSUME_MEDIA " ) ;
2007-03-29 22:34:40 +00:00
break ;
2008-05-27 04:30:03 +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
}
2008-05-27 04:30:03 +00:00
2009-04-10 17:43:18 +00:00
if ( midstate = = CS_DESTROY ) {
2007-03-29 22:34:40 +00:00
break ;
}
}
endstate = switch_channel_get_state ( session - > channel ) ;
2008-05-27 04:30:03 +00:00
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 ) {
2008-11-14 23:31:21 +00:00
switch_cond_next ( ) ;
2009-07-21 19:17:22 +00:00
if ( ! - - new_loops ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_CRIT , " %s Timeout waiting for next instruction in CS_NEW! \n " , session - > uuid_str ) ;
2009-07-21 19:17:22 +00:00
switch_channel_hangup ( session - > channel , SWITCH_CAUSE_INVALID_CALL_REFERENCE ) ;
}
2007-10-11 19:12:18 +00:00
} else {
2009-10-12 22:23:55 +00:00
switch_core_session_message_t * message ;
while ( switch_core_session_dequeue_message ( session , & message ) = = SWITCH_STATUS_SUCCESS ) {
switch_core_session_receive_message ( session , message ) ;
message = NULL ;
}
2009-10-20 17:03:03 +00:00
switch_channel_set_flag ( session - > channel , CF_THREAD_SLEEPING ) ;
2007-10-11 19:12:18 +00:00
switch_thread_cond_wait ( session - > cond , session - > mutex ) ;
2009-10-20 17:03:03 +00:00
switch_channel_clear_flag ( session - > channel , CF_THREAD_SLEEPING ) ;
2009-10-12 22:23:55 +00:00
while ( switch_core_session_dequeue_message ( session , & message ) = = SWITCH_STATUS_SUCCESS ) {
switch_core_session_receive_message ( session , message ) ;
message = NULL ;
}
2007-10-11 19:12:18 +00:00
}
2007-03-29 22:34:40 +00:00
}
}
done :
switch_mutex_unlock ( session - > mutex ) ;
session - > thread_running = 0 ;
}
2008-01-27 17:36:53 +00:00
2009-04-10 17:43:18 +00:00
SWITCH_DECLARE ( void ) switch_core_session_destroy_state ( switch_core_session_t * session )
{
switch_channel_state_t state = CS_DESTROY , midstate = CS_DESTROY ;
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 ;
int proceed = 1 ;
int global_proceed = 1 ;
int do_extra_handlers = 1 ;
int silly = 0 ;
int index = 0 ;
switch_assert ( session ! = NULL ) ;
2009-08-26 21:53:43 +00:00
switch_channel_set_running_state ( session - > channel , CS_DESTROY ) ;
2009-09-14 20:10:58 +00:00
switch_channel_clear_flag ( session - > channel , CF_TRANSFER ) ;
switch_channel_clear_flag ( session - > channel , CF_REDIRECT ) ;
2009-04-10 17:43:18 +00:00
session - > thread_running = 1 ;
endpoint_interface = session - > endpoint_interface ;
switch_assert ( endpoint_interface ! = NULL ) ;
driver_state_handler = endpoint_interface - > state_handler ;
switch_assert ( driver_state_handler ! = NULL ) ;
STATE_MACRO ( destroy , " DESTROY " ) ;
return ;
}
2009-04-28 14:13:05 +00:00
2009-09-14 20:10:58 +00:00
SWITCH_DECLARE ( void ) switch_core_session_hangup_state ( switch_core_session_t * session )
{
const char * hook_var ;
switch_core_session_t * use_session = NULL ;
switch_call_cause_t cause = switch_channel_get_cause ( session - > channel ) ;
switch_call_cause_t cause_q850 = switch_channel_get_cause_q850 ( session - > channel ) ;
switch_event_t * event ;
int proceed = 1 ;
int global_proceed = 1 ;
int do_extra_handlers = 1 ;
int silly = 0 ;
int index = 0 ;
switch_channel_state_t state = switch_channel_get_state ( session - > channel ) , midstate = state ;
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 ;
if ( switch_thread_self ( ) ! = session - > thread_id ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " thread mismatch skipping state handler. \n " ) ;
return ;
}
if ( switch_test_flag ( session , SSF_HANGUP ) ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " handler already called, skipping state handler. \n " ) ;
return ;
}
endpoint_interface = session - > endpoint_interface ;
switch_assert ( endpoint_interface ! = NULL ) ;
driver_state_handler = endpoint_interface - > state_handler ;
switch_assert ( driver_state_handler ! = NULL ) ;
switch_channel_set_hangup_time ( session - > channel ) ;
switch_core_media_bug_remove_all ( session ) ;
switch_channel_stop_broadcast ( session - > channel ) ;
switch_channel_set_variable ( session - > channel , " hangup_cause " , switch_channel_cause2str ( cause ) ) ;
switch_channel_set_variable_printf ( session - > channel , " hangup_cause_q850 " , " %d " , cause_q850 ) ;
switch_channel_presence ( session - > channel , " unknown " , switch_channel_cause2str ( cause ) , NULL ) ;
switch_channel_set_timestamps ( session - > channel ) ;
STATE_MACRO ( hangup , " HANGUP " ) ;
hook_var = switch_channel_get_variable ( session - > channel , SWITCH_API_HANGUP_HOOK_VARIABLE ) ;
if ( switch_true ( switch_channel_get_variable ( session - > channel , SWITCH_SESSION_IN_HANGUP_HOOK_VARIABLE ) ) ) {
use_session = session ;
}
2009-10-23 16:03:42 +00:00
if ( ! zstr ( hook_var ) ) {
2009-09-14 20:10:58 +00:00
switch_stream_handle_t stream = { 0 } ;
char * cmd = switch_core_session_strdup ( session , hook_var ) ;
char * arg = NULL ;
char * expanded = NULL ;
if ( ( arg = strchr ( cmd , ' : ' ) ) & & * ( arg + 1 ) = = ' : ' ) {
* arg + + = ' \0 ' ;
* arg + + = ' \0 ' ;
} else {
if ( ( arg = strchr ( cmd , ' ' ) ) ) {
* arg + + = ' \0 ' ;
}
}
SWITCH_STANDARD_STREAM ( stream ) ;
switch_channel_get_variables ( session - > channel , & stream . param_event ) ;
switch_channel_event_set_data ( session - > channel , stream . param_event ) ;
expanded = switch_channel_expand_variables ( session - > channel , arg ) ;
switch_api_execute ( cmd , expanded , use_session , & stream ) ;
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Hangup Command %s(%s): \n %s \n " , cmd , switch_str_nil ( expanded ) ,
switch_str_nil ( ( char * ) stream . data ) ) ;
if ( expanded ! = arg ) {
switch_safe_free ( expanded ) ;
}
switch_safe_free ( stream . data ) ;
}
if ( switch_event_create ( & event , SWITCH_EVENT_CHANNEL_HANGUP_COMPLETE ) = = SWITCH_STATUS_SUCCESS ) {
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Hangup-Cause " , switch_channel_cause2str ( cause ) ) ;
switch_channel_event_set_data ( session - > channel , event ) ;
switch_event_fire ( & event ) ;
}
switch_set_flag ( session , SSF_HANGUP ) ;
}
2009-04-28 14:13:05 +00:00
SWITCH_DECLARE ( void ) switch_core_session_reporting_state ( switch_core_session_t * session )
{
switch_channel_state_t state = switch_channel_get_state ( session - > channel ) , midstate = state ;
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 ;
int proceed = 1 ;
int global_proceed = 1 ;
int do_extra_handlers = 1 ;
int silly = 0 ;
int index = 0 ;
2009-04-28 15:11:38 +00:00
const char * var = switch_channel_get_variable ( session - > channel , SWITCH_PROCESS_CDR_VARIABLE ) ;
2009-04-28 14:13:05 +00:00
if ( switch_channel_test_flag ( session - > channel , CF_REPORTING ) ) {
return ;
}
switch_channel_set_flag ( session - > channel , CF_REPORTING ) ;
switch_assert ( session ! = NULL ) ;
session - > thread_running = 1 ;
endpoint_interface = session - > endpoint_interface ;
switch_assert ( endpoint_interface ! = NULL ) ;
driver_state_handler = endpoint_interface - > state_handler ;
switch_assert ( driver_state_handler ! = NULL ) ;
2009-10-23 16:03:42 +00:00
if ( ! zstr ( var ) ) {
2009-04-28 14:13:05 +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 ;
}
} else if ( ! switch_true ( var ) ) {
do_extra_handlers = 0 ;
}
}
STATE_MACRO ( reporting , " REPORTING " ) ;
return ;
}
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
*/