2005-11-19 20:07:43 +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 >
*
*
* switch_core . c - - Main Core Library
*
*/
2006-04-12 15:25:26 +00:00
2005-11-19 20:07:43 +00:00
# include <switch.h>
2006-04-29 06:05:03 +00:00
# include <stdio.h>
2006-03-29 19:15:44 +00:00
//#define DEBUG_ALLOC
2005-11-19 20:07:43 +00:00
2006-04-14 16:43:49 +00:00
# define SWITCH_EVENT_QUEUE_LEN 256
2006-04-26 17:18:33 +00:00
# define SWITCH_SQL_QUEUE_LEN 2000
2006-04-14 16:43:49 +00:00
2005-11-19 20:07:43 +00:00
struct switch_core_session {
2006-03-30 23:02:50 +00:00
uint32_t id ;
2005-11-19 20:07:43 +00:00
char name [ 80 ] ;
2006-03-01 22:55:28 +00:00
int thread_running ;
2006-04-29 01:00:52 +00:00
switch_memory_pool_t * pool ;
2006-04-29 06:05:03 +00:00
switch_channel_t * channel ;
2006-04-29 01:00:52 +00:00
switch_thread_t * thread ;
2006-04-29 23:43:28 +00:00
const switch_endpoint_interface_t * endpoint_interface ;
switch_io_event_hooks_t event_hooks ;
2006-04-29 06:05:03 +00:00
switch_codec_t * read_codec ;
switch_codec_t * write_codec ;
2006-01-14 16:44:52 +00:00
2006-04-29 06:05:03 +00:00
switch_buffer_t * raw_write_buffer ;
switch_frame_t raw_write_frame ;
switch_frame_t enc_write_frame ;
2006-03-27 17:42:59 +00:00
uint8_t raw_write_buf [ SWITCH_RECCOMMENDED_BUFFER_SIZE ] ;
uint8_t enc_write_buf [ SWITCH_RECCOMMENDED_BUFFER_SIZE ] ;
2005-11-19 20:07:43 +00:00
2006-04-29 06:05:03 +00:00
switch_buffer_t * raw_read_buffer ;
switch_frame_t raw_read_frame ;
switch_frame_t enc_read_frame ;
2006-03-27 17:42:59 +00:00
uint8_t raw_read_buf [ SWITCH_RECCOMMENDED_BUFFER_SIZE ] ;
uint8_t enc_read_buf [ SWITCH_RECCOMMENDED_BUFFER_SIZE ] ;
2005-11-19 20:07:43 +00:00
2006-01-02 17:28:59 +00:00
2006-04-29 01:00:52 +00:00
switch_audio_resampler_t * read_resampler ;
switch_audio_resampler_t * write_resampler ;
2006-01-02 17:28:59 +00:00
2005-11-19 20:07:43 +00:00
switch_mutex_t * mutex ;
switch_thread_cond_t * cond ;
2006-04-28 19:46:57 +00:00
switch_thread_rwlock_t * rwlock ;
2006-01-09 18:40:56 +00:00
void * streams [ SWITCH_MAX_STREAMS ] ;
int stream_count ;
2006-01-20 15:05:05 +00:00
char uuid_str [ SWITCH_UUID_FORMATTED_LENGTH + 1 ] ;
2006-02-26 04:52:34 +00:00
void * private_info ;
2006-04-14 16:43:49 +00:00
switch_queue_t * event_queue ;
2005-11-19 20:07:43 +00:00
} ;
2006-03-01 06:25:56 +00:00
SWITCH_DECLARE_DATA switch_directories SWITCH_GLOBAL_dirs ;
2006-02-28 21:21:48 +00:00
2005-11-19 20:07:43 +00:00
struct switch_core_runtime {
2006-05-10 03:23:05 +00:00
switch_time_t initiated ;
2006-03-30 23:02:50 +00:00
uint32_t session_id ;
2005-11-19 20:07:43 +00:00
apr_pool_t * memory_pool ;
2006-04-29 01:00:52 +00:00
switch_hash_t * session_table ;
2006-07-07 18:59:14 +00:00
switch_mutex_t * session_table_mutex ;
2006-05-05 13:35:33 +00:00
# ifdef CRASH_PROT
2006-04-29 01:00:52 +00:00
switch_hash_t * stack_table ;
2006-05-05 13:35:33 +00:00
# endif
2006-04-30 17:54:05 +00:00
switch_core_db_t * db ;
switch_core_db_t * event_db ;
2006-04-29 06:05:03 +00:00
const switch_state_handler_table_t * state_handlers [ SWITCH_MAX_STATE_HANDLERS ] ;
2006-02-07 20:47:15 +00:00
int state_handler_index ;
2005-11-19 20:07:43 +00:00
FILE * console ;
2006-07-07 18:59:14 +00:00
uint32_t session_count ;
uint32_t session_limit ;
2006-04-26 17:18:33 +00:00
switch_queue_t * sql_queue ;
2005-11-19 20:07:43 +00:00
} ;
/* Prototypes */
2006-04-29 01:00:52 +00:00
static void * SWITCH_THREAD_FUNC switch_core_session_thread ( switch_thread_t * thread , void * obj ) ;
2006-04-29 06:05:03 +00:00
static void switch_core_standard_on_init ( switch_core_session_t * session ) ;
static void switch_core_standard_on_hangup ( switch_core_session_t * session ) ;
static void switch_core_standard_on_ring ( switch_core_session_t * session ) ;
static void switch_core_standard_on_execute ( switch_core_session_t * session ) ;
static void switch_core_standard_on_loopback ( switch_core_session_t * session ) ;
static void switch_core_standard_on_transmit ( switch_core_session_t * session ) ;
static void switch_core_standard_on_hold ( switch_core_session_t * session ) ;
2005-11-19 20:07:43 +00:00
2005-12-21 22:25:22 +00:00
2005-11-19 20:07:43 +00:00
/* The main runtime obj we keep this hidden for ourselves */
static struct switch_core_runtime runtime ;
2006-03-30 23:02:50 +00:00
static void db_pick_path ( char * dbname , char * buf , switch_size_t size )
2005-12-21 22:25:22 +00:00
{
memset ( buf , 0 , size ) ;
if ( strchr ( dbname , ' / ' ) ) {
strncpy ( buf , dbname , size ) ;
} else {
2006-06-05 18:12:33 +00:00
snprintf ( buf , size , " %s%s%s.db " , SWITCH_DB_DIR , SWITCH_PATH_SEPARATOR , dbname ) ;
2005-12-21 22:25:22 +00:00
}
}
2006-04-30 17:54:05 +00:00
SWITCH_DECLARE ( switch_core_db_t * ) switch_core_db_open_file ( char * filename )
2005-12-21 22:25:22 +00:00
{
2006-04-30 17:54:05 +00:00
switch_core_db_t * db ;
2005-12-21 22:25:22 +00:00
char path [ 1024 ] ;
2006-01-03 01:17:59 +00:00
2005-12-21 22:25:22 +00:00
db_pick_path ( filename , path , sizeof ( path ) ) ;
if ( switch_core_db_open ( path , & db ) ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " SQL ERR [%s] \n " , switch_core_db_errmsg ( db ) ) ;
2005-12-21 22:25:22 +00:00
switch_core_db_close ( db ) ;
2006-01-20 15:05:05 +00:00
db = NULL ;
2005-12-21 22:25:22 +00:00
}
return db ;
}
2006-05-11 21:11:20 +00:00
SWITCH_DECLARE ( void ) switch_core_db_test_reactive ( switch_core_db_t * db , char * test_sql , char * reactive_sql )
{
2006-04-04 21:26:21 +00:00
char * errmsg ;
if ( db ) {
if ( test_sql ) {
switch_core_db_exec (
db ,
test_sql ,
NULL ,
NULL ,
& errmsg
) ;
if ( errmsg ) {
2006-04-11 21:13:44 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " SQL ERR [%s] \n [%s] \n Auto Generating Table! \n " , errmsg , test_sql ) ;
2006-04-04 21:26:21 +00:00
switch_core_db_free ( errmsg ) ;
errmsg = NULL ;
switch_core_db_exec (
db ,
2006-05-11 21:11:20 +00:00
reactive_sql ,
2006-04-04 21:26:21 +00:00
NULL ,
NULL ,
& errmsg
) ;
if ( errmsg ) {
2006-05-11 21:11:20 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " SQL ERR [%s] \n [%s] \n " , errmsg , reactive_sql ) ;
2006-04-04 21:26:21 +00:00
switch_core_db_free ( errmsg ) ;
errmsg = NULL ;
}
}
}
}
}
2006-05-11 21:11:20 +00:00
2006-04-04 21:26:21 +00:00
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_set_console ( char * console )
2006-02-24 19:11:49 +00:00
{
2006-02-28 21:21:48 +00:00
if ( ( runtime . console = fopen ( console , " a " ) ) = = 0 ) {
fprintf ( stderr , " Cannot open output file %s. \n " , console ) ;
return SWITCH_STATUS_FALSE ;
}
return SWITCH_STATUS_SUCCESS ;
}
SWITCH_DECLARE ( FILE * ) switch_core_get_console ( void )
{
return runtime . console ;
2006-02-24 19:11:49 +00:00
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( FILE * ) switch_core_data_channel ( switch_text_channel_t channel )
2005-11-19 20:07:43 +00:00
{
FILE * handle = stdout ;
switch ( channel ) {
2006-04-11 21:13:44 +00:00
case SWITCH_CHANNEL_ID_LOG :
case SWITCH_CHANNEL_ID_LOG_CLEAN :
2006-01-06 01:34:10 +00:00
handle = runtime . console ;
break ;
default :
2006-02-24 19:11:49 +00:00
handle = runtime . console ;
2006-01-06 01:34:10 +00:00
break ;
2005-11-19 20:07:43 +00:00
}
return handle ;
}
2006-04-29 06:05:03 +00:00
SWITCH_DECLARE ( int ) switch_core_add_state_handler ( const switch_state_handler_table_t * state_handler )
2006-02-07 20:47:15 +00:00
{
int index = runtime . state_handler_index + + ;
if ( runtime . state_handler_index > = SWITCH_MAX_STATE_HANDLERS ) {
return - 1 ;
}
runtime . state_handlers [ index ] = state_handler ;
return index ;
}
2006-04-29 06:05:03 +00:00
SWITCH_DECLARE ( const switch_state_handler_table_t * ) switch_core_get_state_handler ( int index )
2006-02-07 20:47:15 +00:00
{
if ( index > SWITCH_MAX_STATE_HANDLERS | | index > runtime . state_handler_index ) {
return NULL ;
}
return runtime . state_handlers [ index ] ;
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_session_read_lock ( switch_core_session_t * session )
2006-04-28 19:46:57 +00:00
{
2006-04-29 23:43:28 +00:00
return ( switch_status_t ) switch_thread_rwlock_tryrdlock ( session - > rwlock ) ;
2006-04-28 19:46:57 +00:00
}
2006-04-29 06:05:03 +00:00
SWITCH_DECLARE ( void ) switch_core_session_write_lock ( switch_core_session_t * session )
2006-04-28 19:46:57 +00:00
{
switch_thread_rwlock_wrlock ( session - > rwlock ) ;
}
2006-04-29 06:05:03 +00:00
SWITCH_DECLARE ( void ) switch_core_session_rwunlock ( switch_core_session_t * session )
2006-04-28 19:46:57 +00:00
{
switch_thread_rwlock_unlock ( session - > rwlock ) ;
}
2006-04-29 06:05:03 +00:00
SWITCH_DECLARE ( switch_core_session_t * ) switch_core_session_locate ( char * uuid_str )
2006-03-03 16:57:21 +00:00
{
2006-04-29 06:05:03 +00:00
switch_core_session_t * session ;
2006-07-07 18:59:14 +00:00
switch_mutex_lock ( runtime . session_table_mutex ) ;
2006-04-28 19:46:57 +00:00
if ( ( session = switch_core_hash_find ( runtime . session_table , uuid_str ) ) ) {
/* Acquire a read lock on the session */
if ( switch_thread_rwlock_tryrdlock ( session - > rwlock ) ! = SWITCH_STATUS_SUCCESS ) {
/* not available, forget it */
session = NULL ;
}
}
2006-07-07 18:59:14 +00:00
switch_mutex_unlock ( runtime . session_table_mutex ) ;
2006-04-28 19:46:57 +00:00
/* if its not NULL, now it's up to you to rwunlock this */
2006-03-03 16:57:21 +00:00
return session ;
}
2006-07-07 18:59:14 +00:00
SWITCH_DECLARE ( void ) switch_core_session_hupall ( void )
{
switch_hash_index_t * hi ;
void * val ;
switch_core_session_t * session ;
switch_channel_t * channel ;
switch_mutex_lock ( runtime . session_table_mutex ) ;
for ( hi = switch_hash_first ( runtime . memory_pool , runtime . session_table ) ; hi ; hi = switch_hash_next ( hi ) ) {
switch_hash_this ( hi , NULL , NULL , & val ) ;
if ( val ) {
session = ( switch_core_session_t * ) val ;
channel = switch_core_session_get_channel ( session ) ;
switch_channel_hangup ( channel , SWITCH_CAUSE_SYSTEM_SHUTDOWN ) ;
}
}
switch_mutex_unlock ( runtime . session_table_mutex ) ;
while ( runtime . session_count ) {
switch_yield ( 1000 ) ;
}
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_session_message_send ( char * uuid_str , switch_core_session_message_t * message )
2006-01-09 19:48:20 +00:00
{
2006-04-29 06:05:03 +00:00
switch_core_session_t * session = NULL ;
2006-04-29 23:43:28 +00:00
switch_status_t status = SWITCH_STATUS_FALSE ;
2006-01-09 19:48:20 +00:00
2006-07-07 18:59:14 +00:00
switch_mutex_lock ( runtime . session_table_mutex ) ;
2006-02-20 00:23:25 +00:00
if ( ( session = switch_core_hash_find ( runtime . session_table , uuid_str ) ) ! = 0 ) {
2006-04-28 19:46:57 +00:00
/* Acquire a read lock on the session or forget it the channel is dead */
if ( switch_thread_rwlock_tryrdlock ( session - > rwlock ) = = SWITCH_STATUS_SUCCESS ) {
if ( switch_channel_get_state ( session - > channel ) < CS_HANGUP ) {
status = switch_core_session_receive_message ( session , message ) ;
}
switch_thread_rwlock_unlock ( session - > rwlock ) ;
2006-01-09 19:48:20 +00:00
}
}
2006-07-07 18:59:14 +00:00
switch_mutex_unlock ( runtime . session_table_mutex ) ;
2006-01-09 19:48:20 +00:00
2006-04-28 19:46:57 +00:00
return status ;
2006-01-09 19:48:20 +00:00
}
2005-11-19 20:07:43 +00:00
2006-07-12 18:39:19 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_session_event_send ( char * uuid_str , switch_event_t * * event )
2006-04-14 16:43:49 +00:00
{
2006-04-29 06:05:03 +00:00
switch_core_session_t * session = NULL ;
2006-04-29 23:43:28 +00:00
switch_status_t status = SWITCH_STATUS_FALSE ;
2006-04-14 16:43:49 +00:00
2006-07-07 18:59:14 +00:00
switch_mutex_lock ( runtime . session_table_mutex ) ;
2006-04-14 16:43:49 +00:00
if ( ( session = switch_core_hash_find ( runtime . session_table , uuid_str ) ) ! = 0 ) {
2006-04-28 19:46:57 +00:00
/* Acquire a read lock on the session or forget it the channel is dead */
if ( switch_thread_rwlock_tryrdlock ( session - > rwlock ) = = SWITCH_STATUS_SUCCESS ) {
if ( switch_channel_get_state ( session - > channel ) < CS_HANGUP ) {
status = switch_core_session_queue_event ( session , event ) ;
}
switch_thread_rwlock_unlock ( session - > rwlock ) ;
2006-04-14 16:43:49 +00:00
}
}
2006-07-07 18:59:14 +00:00
switch_mutex_unlock ( runtime . session_table_mutex ) ;
2006-04-14 16:43:49 +00:00
2006-04-28 19:46:57 +00:00
return status ;
2006-04-14 16:43:49 +00:00
}
2006-04-29 06:05:03 +00:00
SWITCH_DECLARE ( char * ) switch_core_session_get_uuid ( switch_core_session_t * session )
2005-12-22 01:57:32 +00:00
{
return session - > uuid_str ;
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_session_set_read_codec ( switch_core_session_t * session , switch_codec_t * codec )
2005-11-19 20:07:43 +00:00
{
assert ( session ! = NULL ) ;
session - > read_codec = codec ;
return SWITCH_STATUS_SUCCESS ;
}
2006-04-29 06:05:03 +00:00
SWITCH_DECLARE ( switch_codec_t * ) switch_core_session_get_read_codec ( switch_core_session_t * session )
2006-01-27 01:46:14 +00:00
{
return session - > read_codec ;
}
2005-11-19 20:07:43 +00:00
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_session_set_write_codec ( switch_core_session_t * session , switch_codec_t * codec )
2005-11-19 20:07:43 +00:00
{
assert ( session ! = NULL ) ;
session - > write_codec = codec ;
return SWITCH_STATUS_SUCCESS ;
}
2006-04-29 06:05:03 +00:00
SWITCH_DECLARE ( switch_codec_t * ) switch_core_session_get_write_codec ( switch_core_session_t * session )
2006-01-27 01:46:14 +00:00
{
return session - > write_codec ;
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_codec_init ( switch_codec_t * codec , char * codec_name , uint32_t rate , int ms ,
2006-03-30 23:02:50 +00:00
int channels , uint32_t flags ,
2006-04-29 06:05:03 +00:00
const switch_codec_settings_t * codec_settings ,
2006-04-29 01:00:52 +00:00
switch_memory_pool_t * pool )
2005-11-19 20:07:43 +00:00
{
2006-04-29 23:43:28 +00:00
const switch_codec_interface_t * codec_interface ;
2006-04-29 06:05:03 +00:00
const switch_codec_implementation_t * iptr , * implementation = NULL ;
2005-11-19 20:07:43 +00:00
assert ( codec ! = NULL ) ;
assert ( codec_name ! = NULL ) ;
memset ( codec , 0 , sizeof ( * codec ) ) ;
2006-02-20 00:23:25 +00:00
if ( ( codec_interface = switch_loadable_module_get_codec_interface ( codec_name ) ) = = 0 ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " invalid codec %s! \n " , codec_name ) ;
2005-11-19 20:07:43 +00:00
return SWITCH_STATUS_GENERR ;
}
2006-01-20 15:05:05 +00:00
for ( iptr = codec_interface - > implementations ; iptr ; iptr = iptr - > next ) {
if ( ( ! rate | | rate = = iptr - > samples_per_second ) & &
( ! ms | | ms = = ( iptr - > microseconds_per_frame / 1000 ) ) & &
2005-12-28 20:06:03 +00:00
( ! channels | | channels = = iptr - > number_of_channels ) ) {
2006-01-06 01:34:10 +00:00
implementation = iptr ;
break ;
2005-11-19 20:07:43 +00:00
}
}
if ( implementation ) {
2006-04-29 23:43:28 +00:00
switch_status_t status ;
2005-11-19 20:07:43 +00:00
codec - > codec_interface = codec_interface ;
codec - > implementation = implementation ;
codec - > flags = flags ;
2005-12-26 21:01:22 +00:00
if ( pool ) {
codec - > memory_pool = pool ;
} else {
if ( ( status = switch_core_new_memory_pool ( & codec - > memory_pool ) ) ! = SWITCH_STATUS_SUCCESS ) {
return status ;
}
switch_set_flag ( codec , SWITCH_CODEC_FLAG_FREE_POOL ) ;
2005-12-10 01:14:49 +00:00
}
2005-11-19 20:07:43 +00:00
implementation - > init ( codec , flags , codec_settings ) ;
return SWITCH_STATUS_SUCCESS ;
2005-12-30 17:26:38 +00:00
} else {
2006-07-03 19:46:32 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Codec %s Exists but not at the desired implementation. \n " ,
2006-01-20 15:05:05 +00:00
codec_name ) ;
2005-11-19 20:07:43 +00:00
}
return SWITCH_STATUS_NOTIMPL ;
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_codec_encode ( switch_codec_t * codec ,
2006-04-29 06:05:03 +00:00
switch_codec_t * other_codec ,
2006-01-03 01:17:59 +00:00
void * decoded_data ,
2006-04-09 00:10:13 +00:00
uint32_t decoded_data_len ,
uint32_t decoded_rate ,
2006-01-03 01:17:59 +00:00
void * encoded_data ,
2006-04-09 00:10:13 +00:00
uint32_t * encoded_data_len , uint32_t * encoded_rate , unsigned int * flag )
2005-11-19 20:07:43 +00:00
{
assert ( codec ! = NULL ) ;
assert ( encoded_data ! = NULL ) ;
assert ( decoded_data ! = NULL ) ;
if ( ! codec - > implementation ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Codec is not initilized! \n " ) ;
2005-11-19 20:07:43 +00:00
return SWITCH_STATUS_GENERR ;
}
if ( ! switch_test_flag ( codec , SWITCH_CODEC_FLAG_ENCODE ) ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Codec's encoder is not initilized! \n " ) ;
2005-11-19 20:07:43 +00:00
return SWITCH_STATUS_GENERR ;
}
2006-02-09 17:01:32 +00:00
2006-01-06 01:34:10 +00:00
return codec - > implementation - > encode ( codec ,
other_codec ,
decoded_data ,
decoded_data_len ,
2006-01-20 15:05:05 +00:00
decoded_rate , encoded_data , encoded_data_len , encoded_rate , flag ) ;
2006-01-06 01:34:10 +00:00
2005-11-19 20:07:43 +00:00
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_codec_decode ( switch_codec_t * codec ,
2006-04-29 06:05:03 +00:00
switch_codec_t * other_codec ,
2006-01-03 01:17:59 +00:00
void * encoded_data ,
2006-04-09 00:10:13 +00:00
uint32_t encoded_data_len ,
uint32_t encoded_rate ,
2006-01-03 01:17:59 +00:00
void * decoded_data ,
2006-04-21 22:31:08 +00:00
uint32_t * decoded_data_len ,
uint32_t * decoded_rate ,
unsigned int * flag )
2005-11-19 20:07:43 +00:00
{
2006-01-12 21:22:20 +00:00
2005-11-19 20:07:43 +00:00
assert ( codec ! = NULL ) ;
assert ( encoded_data ! = NULL ) ;
assert ( decoded_data ! = NULL ) ;
2006-02-09 17:01:32 +00:00
2005-11-19 20:07:43 +00:00
if ( ! codec - > implementation ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Codec is not initilized! \n " ) ;
2005-11-19 20:07:43 +00:00
return SWITCH_STATUS_GENERR ;
}
if ( ! switch_test_flag ( codec , SWITCH_CODEC_FLAG_DECODE ) ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Codec's decoder is not initilized! \n " ) ;
2005-11-19 20:07:43 +00:00
return SWITCH_STATUS_GENERR ;
}
2006-02-09 17:01:32 +00:00
2006-01-06 01:34:10 +00:00
return codec - > implementation - > decode ( codec ,
other_codec ,
encoded_data ,
encoded_data_len ,
2006-01-20 15:05:05 +00:00
encoded_rate , decoded_data , decoded_data_len , decoded_rate , flag ) ;
2006-01-06 01:34:10 +00:00
2005-11-19 20:07:43 +00:00
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_codec_destroy ( switch_codec_t * codec )
2005-11-19 20:07:43 +00:00
{
assert ( codec ! = NULL ) ;
if ( ! codec - > implementation ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Codec is not initilized! \n " ) ;
2005-11-19 20:07:43 +00:00
return SWITCH_STATUS_GENERR ;
}
codec - > implementation - > destroy ( codec ) ;
2005-12-26 21:01:22 +00:00
if ( switch_test_flag ( codec , SWITCH_CODEC_FLAG_FREE_POOL ) ) {
switch_core_destroy_memory_pool ( & codec - > memory_pool ) ;
}
2005-11-19 20:07:43 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_file_open ( switch_file_handle_t * fh , char * file_path , unsigned int flags ,
2006-04-29 01:00:52 +00:00
switch_memory_pool_t * pool )
2005-12-27 18:46:12 +00:00
{
char * ext ;
2006-04-29 23:43:28 +00:00
switch_status_t status ;
2005-12-27 18:46:12 +00:00
2006-02-20 00:23:25 +00:00
if ( ( ext = strrchr ( file_path , ' . ' ) ) = = 0 ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Invalid Format \n " ) ;
2005-12-27 18:46:12 +00:00
return SWITCH_STATUS_FALSE ;
}
ext + + ;
2006-02-20 00:23:25 +00:00
if ( ( fh - > file_interface = switch_loadable_module_get_file_interface ( ext ) ) = = 0 ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " invalid file format [%s]! \n " , ext ) ;
2005-12-27 18:46:12 +00:00
return SWITCH_STATUS_GENERR ;
}
2006-01-03 01:17:59 +00:00
2005-12-27 18:46:12 +00:00
fh - > flags = flags ;
if ( pool ) {
fh - > memory_pool = pool ;
} else {
if ( ( status = switch_core_new_memory_pool ( & fh - > memory_pool ) ) ! = SWITCH_STATUS_SUCCESS ) {
2006-01-03 01:17:59 +00:00
return status ;
}
2006-01-27 16:43:57 +00:00
switch_set_flag ( fh , SWITCH_FILE_FLAG_FREE_POOL ) ;
2005-12-27 18:46:12 +00:00
}
return fh - > file_interface - > file_open ( fh , file_path ) ;
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_file_read ( switch_file_handle_t * fh , void * data , switch_size_t * len )
2005-12-27 18:46:12 +00:00
{
assert ( fh ! = NULL ) ;
2006-01-03 01:17:59 +00:00
2006-02-20 06:13:56 +00:00
return fh - > file_interface - > file_read ( fh , data , len ) ;
2005-12-27 18:46:12 +00:00
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_file_write ( switch_file_handle_t * fh , void * data , switch_size_t * len )
2005-12-27 18:46:12 +00:00
{
assert ( fh ! = NULL ) ;
2006-01-03 01:17:59 +00:00
2006-02-20 06:13:56 +00:00
return fh - > file_interface - > file_write ( fh , data , len ) ;
2005-12-27 18:46:12 +00:00
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_file_seek ( switch_file_handle_t * fh , unsigned int * cur_pos , int64_t samples ,
2006-01-20 15:05:05 +00:00
int whence )
2005-12-27 18:46:12 +00:00
{
return fh - > file_interface - > file_seek ( fh , cur_pos , samples , whence ) ;
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_file_close ( switch_file_handle_t * fh )
2005-12-27 18:46:12 +00:00
{
return fh - > file_interface - > file_close ( fh ) ;
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_directory_open ( switch_directory_handle_t * dh ,
2006-02-09 16:28:49 +00:00
char * module_name ,
char * source ,
char * dsn ,
char * passwd ,
2006-04-29 01:00:52 +00:00
switch_memory_pool_t * pool )
2006-02-09 16:28:49 +00:00
{
2006-04-29 23:43:28 +00:00
switch_status_t status ;
2006-02-09 16:28:49 +00:00
2006-02-20 00:23:25 +00:00
if ( ( dh - > directory_interface = switch_loadable_module_get_directory_interface ( module_name ) ) = = 0 ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " invalid directory module [%s]! \n " , module_name ) ;
2006-02-09 16:28:49 +00:00
return SWITCH_STATUS_GENERR ;
}
if ( pool ) {
dh - > memory_pool = pool ;
} else {
if ( ( status = switch_core_new_memory_pool ( & dh - > memory_pool ) ) ! = SWITCH_STATUS_SUCCESS ) {
return status ;
}
switch_set_flag ( dh , SWITCH_DIRECTORY_FLAG_FREE_POOL ) ;
}
return dh - > directory_interface - > directory_open ( dh , source , dsn , passwd ) ;
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_directory_query ( switch_directory_handle_t * dh , char * base , char * query )
2006-02-09 16:28:49 +00:00
{
2006-02-09 22:37:44 +00:00
return dh - > directory_interface - > directory_query ( dh , base , query ) ;
2006-02-09 16:28:49 +00:00
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_directory_next ( switch_directory_handle_t * dh )
2006-02-09 16:28:49 +00:00
{
return dh - > directory_interface - > directory_next ( dh ) ;
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_directory_next_pair ( switch_directory_handle_t * dh , char * * var , char * * val )
2006-02-09 16:28:49 +00:00
{
return dh - > directory_interface - > directory_next_pair ( dh , var , val ) ;
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_directory_close ( switch_directory_handle_t * dh )
2006-02-09 16:28:49 +00:00
{
return dh - > directory_interface - > directory_close ( dh ) ;
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_speech_open ( switch_speech_handle_t * sh ,
2006-06-08 01:58:37 +00:00
char * module_name ,
char * voice_name ,
unsigned int rate ,
switch_speech_flag_t * flags ,
switch_memory_pool_t * pool )
2006-01-27 16:43:57 +00:00
{
2006-04-29 23:43:28 +00:00
switch_status_t status ;
2006-01-27 16:43:57 +00:00
2006-02-20 00:23:25 +00:00
if ( ( sh - > speech_interface = switch_loadable_module_get_speech_interface ( module_name ) ) = = 0 ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " invalid speech module [%s]! \n " , module_name ) ;
2006-01-27 16:43:57 +00:00
return SWITCH_STATUS_GENERR ;
}
2006-06-08 19:22:54 +00:00
switch_copy_string ( sh - > engine , module_name , sizeof ( sh - > engine ) ) ;
2006-03-02 21:05:07 +00:00
sh - > flags = * flags ;
2006-01-27 16:43:57 +00:00
if ( pool ) {
sh - > memory_pool = pool ;
} else {
if ( ( status = switch_core_new_memory_pool ( & sh - > memory_pool ) ) ! = SWITCH_STATUS_SUCCESS ) {
return status ;
}
switch_set_flag ( sh , SWITCH_SPEECH_FLAG_FREE_POOL ) ;
}
2006-06-08 01:58:37 +00:00
sh - > rate = rate ;
sh - > name = switch_core_strdup ( pool , module_name ) ;
2006-02-26 20:23:23 +00:00
return sh - > speech_interface - > speech_open ( sh , voice_name , rate , flags ) ;
2006-01-27 16:43:57 +00:00
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_speech_feed_asr ( switch_speech_handle_t * sh , void * data , unsigned int * len , int rate , switch_speech_flag_t * flags )
2006-01-27 16:43:57 +00:00
{
assert ( sh ! = NULL ) ;
return sh - > speech_interface - > speech_feed_asr ( sh , data , len , rate , flags ) ;
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_speech_interpret_asr ( switch_speech_handle_t * sh , char * buf , unsigned int buflen , switch_speech_flag_t * flags )
2006-01-27 16:43:57 +00:00
{
assert ( sh ! = NULL ) ;
2006-03-02 21:05:07 +00:00
2006-01-27 16:43:57 +00:00
return sh - > speech_interface - > speech_interpret_asr ( sh , buf , buflen , flags ) ;
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_speech_feed_tts ( switch_speech_handle_t * sh , char * text , switch_speech_flag_t * flags )
2006-01-27 16:43:57 +00:00
{
assert ( sh ! = NULL ) ;
return sh - > speech_interface - > speech_feed_tts ( sh , text , flags ) ;
}
2006-06-08 01:58:37 +00:00
SWITCH_DECLARE ( void ) switch_core_speech_flush_tts ( switch_speech_handle_t * sh )
{
assert ( sh ! = NULL ) ;
if ( sh - > speech_interface - > speech_flush_tts ) {
sh - > speech_interface - > speech_flush_tts ( sh ) ;
}
}
SWITCH_DECLARE ( void ) switch_core_speech_text_param_tts ( switch_speech_handle_t * sh , char * param , char * val )
{
assert ( sh ! = NULL ) ;
if ( sh - > speech_interface - > speech_text_param_tts ) {
sh - > speech_interface - > speech_text_param_tts ( sh , param , val ) ;
}
}
SWITCH_DECLARE ( void ) switch_core_speech_numeric_param_tts ( switch_speech_handle_t * sh , char * param , int val )
{
assert ( sh ! = NULL ) ;
if ( sh - > speech_interface - > speech_numeric_param_tts ) {
sh - > speech_interface - > speech_numeric_param_tts ( sh , param , val ) ;
}
}
2006-06-08 19:22:54 +00:00
SWITCH_DECLARE ( void ) switch_core_speech_float_param_tts ( switch_speech_handle_t * sh , char * param , double val )
{
assert ( sh ! = NULL ) ;
if ( sh - > speech_interface - > speech_float_param_tts ) {
sh - > speech_interface - > speech_float_param_tts ( sh , param , val ) ;
}
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_speech_read_tts ( switch_speech_handle_t * sh ,
2006-01-27 16:43:57 +00:00
void * data ,
2006-03-30 23:02:50 +00:00
switch_size_t * datalen ,
2006-04-09 00:10:13 +00:00
uint32_t * rate ,
2006-04-29 23:43:28 +00:00
switch_speech_flag_t * flags )
2006-01-27 16:43:57 +00:00
{
assert ( sh ! = NULL ) ;
return sh - > speech_interface - > speech_read_tts ( sh , data , datalen , rate , flags ) ;
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_speech_close ( switch_speech_handle_t * sh , switch_speech_flag_t * flags )
2006-01-27 16:43:57 +00:00
{
2006-02-21 15:05:18 +00:00
return sh - > speech_interface - > speech_close ( sh , flags ) ;
2006-01-27 16:43:57 +00:00
}
2005-12-27 18:46:12 +00:00
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_timer_init ( switch_timer_t * timer , char * timer_name , int interval , int samples ,
2006-04-29 01:00:52 +00:00
switch_memory_pool_t * pool )
2005-11-19 20:07:43 +00:00
{
2006-04-29 23:43:28 +00:00
switch_timer_interface_t * timer_interface ;
switch_status_t status ;
2005-11-19 20:07:43 +00:00
memset ( timer , 0 , sizeof ( * timer ) ) ;
2006-02-20 00:23:25 +00:00
if ( ( timer_interface = switch_loadable_module_get_timer_interface ( timer_name ) ) = = 0 ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " invalid timer %s! \n " , timer_name ) ;
2005-11-19 20:07:43 +00:00
return SWITCH_STATUS_GENERR ;
}
timer - > interval = interval ;
timer - > samples = samples ;
timer - > samplecount = 0 ;
timer - > timer_interface = timer_interface ;
2005-12-26 21:01:22 +00:00
if ( pool ) {
timer - > memory_pool = pool ;
} else {
if ( ( status = switch_core_new_memory_pool ( & timer - > memory_pool ) ) ! = SWITCH_STATUS_SUCCESS ) {
return status ;
}
switch_set_flag ( timer , SWITCH_TIMER_FLAG_FREE_POOL ) ;
2005-12-10 01:14:49 +00:00
}
2005-11-19 20:07:43 +00:00
timer - > timer_interface - > timer_init ( timer ) ;
return SWITCH_STATUS_SUCCESS ;
}
2006-04-29 06:05:03 +00:00
SWITCH_DECLARE ( int ) switch_core_timer_next ( switch_timer_t * timer )
2005-11-19 20:07:43 +00:00
{
if ( ! timer - > timer_interface ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Timer is not initilized! \n " ) ;
2005-11-19 20:07:43 +00:00
return SWITCH_STATUS_GENERR ;
}
if ( timer - > timer_interface - > timer_next ( timer ) = = SWITCH_STATUS_SUCCESS ) {
return timer - > samplecount ;
} else {
return - 1 ;
}
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_timer_destroy ( switch_timer_t * timer )
2005-11-19 20:07:43 +00:00
{
if ( ! timer - > timer_interface ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Timer is not initilized! \n " ) ;
2005-11-19 20:07:43 +00:00
return SWITCH_STATUS_GENERR ;
}
timer - > timer_interface - > timer_destroy ( timer ) ;
2005-12-26 21:01:22 +00:00
if ( switch_test_flag ( timer , SWITCH_TIMER_FLAG_FREE_POOL ) ) {
switch_core_destroy_memory_pool ( & timer - > memory_pool ) ;
}
2005-11-19 20:07:43 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2006-04-29 01:00:52 +00:00
static void * switch_core_service_thread ( switch_thread_t * thread , void * obj )
2005-11-19 20:07:43 +00:00
{
2006-04-29 06:05:03 +00:00
switch_core_thread_session_t * data = obj ;
switch_core_session_t * session = data - > objs [ 0 ] ;
2006-01-09 19:48:20 +00:00
int * stream_id_p = data - > objs [ 1 ] ;
2006-04-29 06:05:03 +00:00
switch_channel_t * channel ;
switch_frame_t * read_frame ;
2006-01-09 19:48:20 +00:00
int stream_id = * stream_id_p ;
2005-11-19 20:07:43 +00:00
2006-03-30 23:02:50 +00:00
assert ( thread ! = NULL ) ;
2005-11-19 20:07:43 +00:00
assert ( session ! = NULL ) ;
channel = switch_core_session_get_channel ( session ) ;
assert ( channel ! = NULL ) ;
2006-06-09 22:59:13 +00:00
switch_channel_set_flag ( channel , CF_SERVICE ) ;
2006-01-20 15:05:05 +00:00
while ( data - > running > 0 ) {
switch ( switch_core_session_read_frame ( session , & read_frame , - 1 , stream_id ) ) {
2006-01-06 01:34:10 +00:00
case SWITCH_STATUS_SUCCESS :
case SWITCH_STATUS_TIMEOUT :
2006-06-08 19:22:54 +00:00
case SWITCH_STATUS_BREAK :
2006-01-06 01:34:10 +00:00
break ;
default :
data - > running = - 1 ;
continue ;
2005-11-19 20:07:43 +00:00
}
}
2006-06-09 22:59:13 +00:00
switch_channel_clear_flag ( channel , CF_SERVICE ) ;
2005-11-19 20:07:43 +00:00
data - > running = 0 ;
return NULL ;
}
2006-02-22 22:36:52 +00:00
2005-11-19 20:07:43 +00:00
/* Either add a timeout here or make damn sure the thread cannot get hung somehow (my preference) */
2006-04-29 06:05:03 +00:00
SWITCH_DECLARE ( void ) switch_core_thread_session_end ( switch_core_thread_session_t * thread_session )
2005-11-19 20:07:43 +00:00
{
if ( thread_session - > running > 0 ) {
thread_session - > running = - 1 ;
2006-01-20 15:05:05 +00:00
while ( thread_session - > running ) {
2005-11-19 20:07:43 +00:00
switch_yield ( 1000 ) ;
}
}
}
2006-04-29 06:05:03 +00:00
SWITCH_DECLARE ( void ) switch_core_service_session ( switch_core_session_t * session ,
switch_core_thread_session_t * thread_session , int stream_id )
2005-11-19 20:07:43 +00:00
{
thread_session - > running = 1 ;
thread_session - > objs [ 0 ] = session ;
2006-01-09 18:40:56 +00:00
thread_session - > objs [ 1 ] = & stream_id ;
2005-11-19 20:07:43 +00:00
switch_core_session_launch_thread ( session , switch_core_service_thread , thread_session ) ;
}
2006-04-29 06:05:03 +00:00
SWITCH_DECLARE ( switch_memory_pool_t * ) switch_core_session_get_pool ( switch_core_session_t * session )
2005-11-19 20:07:43 +00:00
{
return session - > pool ;
}
/* **ONLY** alloc things with this function that **WILL NOT** outlive
2006-01-06 01:34:10 +00:00
the session itself or expect an earth shattering KABOOM ! */
2006-04-29 06:05:03 +00:00
SWITCH_DECLARE ( void * ) switch_core_session_alloc ( switch_core_session_t * session , switch_size_t memory )
2005-11-19 20:07:43 +00:00
{
void * ptr = NULL ;
assert ( session ! = NULL ) ;
assert ( session - > pool ! = NULL ) ;
2006-03-27 17:42:59 +00:00
# ifdef DEBUG_ALLOC
2006-04-11 21:13:44 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Allocate %d \n " , memory ) ;
2006-03-27 17:42:59 +00:00
# endif
2006-02-20 00:23:25 +00:00
if ( ( ptr = apr_palloc ( session - > pool , memory ) ) ! = 0 ) {
2005-11-19 20:07:43 +00:00
memset ( ptr , 0 , memory ) ;
}
return ptr ;
}
/* **ONLY** alloc things with these functions that **WILL NOT** need
2006-01-06 01:34:10 +00:00
to be freed * EVER * ie this is for * PERMENANT * memory allocation */
2005-11-19 20:07:43 +00:00
2006-03-30 23:02:50 +00:00
SWITCH_DECLARE ( void * ) switch_core_permenant_alloc ( switch_size_t memory )
2005-11-19 20:07:43 +00:00
{
void * ptr = NULL ;
assert ( runtime . memory_pool ! = NULL ) ;
2006-03-27 17:42:59 +00:00
# ifdef DEBUG_ALLOC
2006-04-11 21:13:44 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Perm Allocate %d \n " , memory ) ;
2006-03-27 17:42:59 +00:00
# endif
2006-02-20 00:23:25 +00:00
if ( ( ptr = apr_palloc ( runtime . memory_pool , memory ) ) ! = 0 ) {
2005-11-19 20:07:43 +00:00
memset ( ptr , 0 , memory ) ;
}
return ptr ;
}
SWITCH_DECLARE ( char * ) switch_core_permenant_strdup ( char * todup )
{
char * duped = NULL ;
2006-03-30 23:02:50 +00:00
switch_size_t len ;
2005-11-19 20:07:43 +00:00
assert ( runtime . memory_pool ! = NULL ) ;
2006-01-20 15:05:05 +00:00
if ( ! todup )
return NULL ;
2005-12-28 17:11:47 +00:00
2005-12-28 05:17:21 +00:00
len = strlen ( todup ) + 1 ;
2006-03-27 17:42:59 +00:00
# ifdef DEBUG_ALLOC
2006-04-11 21:13:44 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Perm Allocate %d \n " , len ) ;
2006-03-27 17:42:59 +00:00
# endif
2006-02-20 00:23:25 +00:00
if ( todup & & ( duped = apr_palloc ( runtime . memory_pool , len ) ) ! = 0 ) {
2005-12-28 05:17:21 +00:00
strncpy ( duped , todup , len ) ;
2005-11-19 20:07:43 +00:00
}
return duped ;
}
2006-04-29 06:05:03 +00:00
SWITCH_DECLARE ( char * ) switch_core_session_strdup ( switch_core_session_t * session , char * todup )
2005-11-19 20:07:43 +00:00
{
char * duped = NULL ;
2006-03-30 23:02:50 +00:00
switch_size_t len ;
2005-11-19 20:07:43 +00:00
assert ( session ! = NULL ) ;
assert ( session - > pool ! = NULL ) ;
2006-03-01 22:55:28 +00:00
if ( ! todup ) {
2006-01-20 15:05:05 +00:00
return NULL ;
2006-03-01 22:55:28 +00:00
}
2005-12-28 05:17:21 +00:00
len = strlen ( todup ) + 1 ;
2006-03-27 17:42:59 +00:00
# ifdef DEBUG_ALLOC
2006-04-11 21:13:44 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Allocate %d \n " , len ) ;
2006-03-27 17:42:59 +00:00
# endif
2006-02-20 00:23:25 +00:00
if ( todup & & ( duped = apr_palloc ( session - > pool , len ) ) ! = 0 ) {
2005-12-28 05:17:21 +00:00
strncpy ( duped , todup , len ) ;
2005-11-19 20:07:43 +00:00
}
return duped ;
}
2005-12-13 19:53:29 +00:00
2006-04-29 01:00:52 +00:00
SWITCH_DECLARE ( char * ) switch_core_strdup ( switch_memory_pool_t * pool , char * todup )
2005-12-13 19:53:29 +00:00
{
char * duped = NULL ;
2006-03-30 23:02:50 +00:00
switch_size_t len ;
2005-12-13 19:53:29 +00:00
assert ( pool ! = NULL ) ;
2006-03-01 22:55:28 +00:00
if ( ! todup ) {
2006-01-20 15:05:05 +00:00
return NULL ;
2006-03-01 22:55:28 +00:00
}
2005-12-28 05:17:21 +00:00
len = strlen ( todup ) + 1 ;
2006-03-27 17:42:59 +00:00
# ifdef DEBUG_ALLOC
2006-04-11 21:13:44 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Allocate %d \n " , len ) ;
2006-03-27 17:42:59 +00:00
# endif
2006-02-20 00:23:25 +00:00
if ( todup & & ( duped = apr_palloc ( pool , len ) ) ! = 0 ) {
2005-12-28 05:17:21 +00:00
strncpy ( duped , todup , len ) ;
2005-12-13 19:53:29 +00:00
}
return duped ;
}
2006-04-29 06:05:03 +00:00
SWITCH_DECLARE ( void * ) switch_core_session_get_private ( switch_core_session_t * session )
2005-11-19 20:07:43 +00:00
{
assert ( session ! = NULL ) ;
2006-02-26 04:52:34 +00:00
return session - > private_info ;
2005-11-19 20:07:43 +00:00
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_session_set_private ( switch_core_session_t * session , void * private_info )
2005-11-19 20:07:43 +00:00
{
assert ( session ! = NULL ) ;
2006-02-26 04:52:34 +00:00
session - > private_info = private_info ;
2005-11-19 20:07:43 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2006-04-29 06:05:03 +00:00
SWITCH_DECLARE ( int ) switch_core_session_add_stream ( switch_core_session_t * session , void * private_info )
2006-01-09 18:40:56 +00:00
{
2006-02-26 04:52:34 +00:00
session - > streams [ session - > stream_count + + ] = private_info ;
2006-01-09 18:40:56 +00:00
return session - > stream_count - 1 ;
}
2006-04-29 06:05:03 +00:00
SWITCH_DECLARE ( void * ) switch_core_session_get_stream ( switch_core_session_t * session , int index )
2006-01-09 18:40:56 +00:00
{
return session - > streams [ index ] ;
}
2006-04-29 06:05:03 +00:00
SWITCH_DECLARE ( int ) switch_core_session_get_stream_count ( switch_core_session_t * session )
2006-01-09 18:40:56 +00:00
{
return session - > stream_count ;
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_session_outgoing_channel ( switch_core_session_t * session ,
2006-01-03 01:17:59 +00:00
char * endpoint_name ,
2006-04-29 06:05:03 +00:00
switch_caller_profile_t * caller_profile ,
switch_core_session_t * * new_session ,
2006-04-29 01:00:52 +00:00
switch_memory_pool_t * pool )
2005-11-19 20:07:43 +00:00
{
2006-04-29 23:43:28 +00:00
switch_io_event_hook_outgoing_channel_t * ptr ;
switch_status_t status = SWITCH_STATUS_FALSE ;
const switch_endpoint_interface_t * endpoint_interface ;
2006-07-13 17:58:28 +00:00
switch_channel_t * channel = NULL ;
switch_caller_profile_t * outgoing_profile = caller_profile ;
2005-11-19 20:07:43 +00:00
2006-02-20 00:23:25 +00:00
if ( ( endpoint_interface = switch_loadable_module_get_endpoint_interface ( endpoint_name ) ) = = 0 ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Could not locate channel type %s \n " , endpoint_name ) ;
2005-11-19 20:07:43 +00:00
return SWITCH_STATUS_FALSE ;
}
if ( endpoint_interface - > io_routines - > outgoing_channel ) {
2006-07-13 17:58:28 +00:00
if ( session ) {
char * ecaller_id_name = NULL , * ecaller_id_number = NULL ;
channel = switch_core_session_get_channel ( session ) ;
ecaller_id_name = switch_channel_get_variable ( channel , " effective_caller_id_name " ) ;
ecaller_id_number = switch_channel_get_variable ( channel , " effective_caller_id_number " ) ;
if ( ecaller_id_name | | ecaller_id_number ) {
if ( caller_profile ) {
outgoing_profile = switch_caller_profile_new ( switch_core_session_get_pool ( session ) ,
caller_profile - > username ,
caller_profile - > dialplan ,
ecaller_id_name ? ecaller_id_name : caller_profile - > caller_id_name ,
ecaller_id_number ? ecaller_id_number : caller_profile - > caller_id_number ,
caller_profile - > network_addr ,
caller_profile - > ani ,
caller_profile - > ani2 ,
caller_profile - > rdnis ,
caller_profile - > source ,
caller_profile - > context ,
caller_profile - > destination_number ) ;
}
}
}
if ( ( status = endpoint_interface - > io_routines - > outgoing_channel ( session ,
outgoing_profile ,
new_session ,
pool ) ) = = SWITCH_STATUS_SUCCESS ) {
2006-03-01 22:55:28 +00:00
if ( session ) {
for ( ptr = session - > event_hooks . outgoing_channel ; ptr ; ptr = ptr - > next ) {
if ( ( status = ptr - > outgoing_channel ( session , caller_profile , * new_session ) ) ! = SWITCH_STATUS_SUCCESS ) {
break ;
}
2005-11-19 20:07:43 +00:00
}
}
2006-02-24 16:47:22 +00:00
} else {
return status ;
2005-11-19 20:07:43 +00:00
}
2006-07-13 17:58:28 +00:00
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Could not locate outgoing channel interface for %s \n " , endpoint_name ) ;
return SWITCH_STATUS_FALSE ;
2005-11-19 20:07:43 +00:00
}
2005-12-26 19:09:59 +00:00
if ( * new_session ) {
2006-04-29 06:05:03 +00:00
switch_caller_profile_t * profile = NULL , * peer_profile = NULL , * cloned_profile = NULL ;
2006-07-13 17:58:28 +00:00
switch_channel_t * peer_channel = NULL ;
2005-12-26 19:09:59 +00:00
2006-07-13 17:58:28 +00:00
if ( session & & channel ) {
2005-12-26 19:09:59 +00:00
profile = switch_channel_get_caller_profile ( channel ) ;
}
2006-02-20 00:23:25 +00:00
if ( ( peer_channel = switch_core_session_get_channel ( * new_session ) ) ! = 0 ) {
2005-12-26 19:09:59 +00:00
peer_profile = switch_channel_get_caller_profile ( peer_channel ) ;
}
if ( channel & & peer_channel ) {
if ( profile ) {
2006-02-20 00:23:25 +00:00
if ( ( cloned_profile = switch_caller_profile_clone ( * new_session , profile ) ) ! = 0 ) {
2005-12-26 19:09:59 +00:00
switch_channel_set_originator_caller_profile ( peer_channel , cloned_profile ) ;
}
}
if ( peer_profile ) {
2006-03-01 22:55:28 +00:00
if ( session & & ( cloned_profile = switch_caller_profile_clone ( session , peer_profile ) ) ! = 0 ) {
2005-12-26 19:09:59 +00:00
switch_channel_set_originatee_caller_profile ( channel , cloned_profile ) ;
}
}
}
}
2005-11-19 20:07:43 +00:00
return status ;
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_session_answer_channel ( switch_core_session_t * session )
2005-11-19 20:07:43 +00:00
{
2006-04-29 23:43:28 +00:00
switch_io_event_hook_answer_channel_t * ptr ;
switch_status_t status = SWITCH_STATUS_FALSE ;
2005-11-19 20:07:43 +00:00
assert ( session ! = NULL ) ;
if ( session - > endpoint_interface - > io_routines - > answer_channel ) {
if ( ( status = session - > endpoint_interface - > io_routines - > answer_channel ( session ) ) = = SWITCH_STATUS_SUCCESS ) {
2006-01-20 15:05:05 +00:00
for ( ptr = session - > event_hooks . answer_channel ; ptr ; ptr = ptr - > next ) {
2005-11-19 20:07:43 +00:00
if ( ( status = ptr - > answer_channel ( session ) ) ! = SWITCH_STATUS_SUCCESS ) {
break ;
}
}
}
} else {
status = SWITCH_STATUS_SUCCESS ;
}
return status ;
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_session_receive_message ( switch_core_session_t * session ,
2006-04-29 06:05:03 +00:00
switch_core_session_message_t * message )
2006-01-09 19:48:20 +00:00
{
2006-04-29 23:43:28 +00:00
switch_io_event_hook_receive_message_t * ptr ;
switch_status_t status = SWITCH_STATUS_FALSE ;
2006-01-09 19:48:20 +00:00
assert ( session ! = NULL ) ;
if ( session - > endpoint_interface - > io_routines - > receive_message ) {
2006-01-20 15:05:05 +00:00
if ( ( status =
session - > endpoint_interface - > io_routines - > receive_message ( session , message ) ) = = SWITCH_STATUS_SUCCESS ) {
for ( ptr = session - > event_hooks . receive_message ; ptr ; ptr = ptr - > next ) {
2006-01-09 19:48:20 +00:00
if ( ( status = ptr - > receive_message ( session , message ) ) ! = SWITCH_STATUS_SUCCESS ) {
break ;
}
}
}
2006-03-03 17:49:22 +00:00
}
2006-01-09 19:48:20 +00:00
return status ;
}
2006-07-12 18:39:19 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_session_receive_event ( switch_core_session_t * session , switch_event_t * * event )
2006-04-14 16:43:49 +00:00
{
2006-07-12 18:39:19 +00:00
switch_io_event_hook_receive_event_t * ptr ;
switch_status_t status = SWITCH_STATUS_FALSE ;
2006-04-14 16:43:49 +00:00
assert ( session ! = NULL ) ;
2006-07-12 18:39:19 +00:00
/* Acquire a read lock on the session or forget it the channel is dead */
if ( switch_thread_rwlock_tryrdlock ( session - > rwlock ) = = SWITCH_STATUS_SUCCESS ) {
if ( switch_channel_get_state ( session - > channel ) < CS_HANGUP ) {
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 ;
}
2006-04-14 16:43:49 +00:00
}
}
2006-07-12 18:39:19 +00:00
if ( status = = SWITCH_STATUS_BREAK ) {
status = SWITCH_STATUS_SUCCESS ;
2006-04-14 16:43:49 +00:00
}
2006-07-12 18:39:19 +00:00
if ( status = = SWITCH_STATUS_SUCCESS ) {
switch_event_destroy ( event ) ;
}
}
switch_thread_rwlock_unlock ( session - > rwlock ) ;
}
return status ;
}
SWITCH_DECLARE ( switch_status_t ) switch_core_session_queue_event ( switch_core_session_t * session , switch_event_t * * event )
{
2006-07-17 14:12:07 +00:00
switch_status_t status = SWITCH_STATUS_FALSE ;
2006-07-12 18:39:19 +00:00
assert ( session ! = NULL ) ;
if ( ! session - > event_queue ) {
switch_queue_create ( & session - > event_queue , SWITCH_EVENT_QUEUE_LEN , session - > pool ) ;
}
2006-07-17 14:12:07 +00:00
if ( session - > event_queue ) {
if ( switch_queue_trypush ( session - > event_queue , * event ) = = SWITCH_STATUS_SUCCESS ) {
* event = NULL ;
status = SWITCH_STATUS_SUCCESS ;
}
}
2006-07-12 18:39:19 +00:00
return status ;
}
SWITCH_DECLARE ( switch_status_t ) switch_core_session_dequeue_event ( switch_core_session_t * session , switch_event_t * * event )
{
switch_status_t status = SWITCH_STATUS_FALSE ;
void * pop ;
assert ( session ! = NULL ) ;
if ( session - > event_queue ) {
if ( ( status = ( switch_status_t ) switch_queue_trypop ( session - > event_queue , & pop ) ) = = SWITCH_STATUS_SUCCESS ) {
* event = ( switch_event_t * ) pop ;
2006-04-14 16:43:49 +00:00
}
}
return status ;
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_session_read_frame ( switch_core_session_t * session , switch_frame_t * * frame ,
2006-01-20 15:05:05 +00:00
int timeout , int stream_id )
2005-11-19 20:07:43 +00:00
{
2006-04-29 23:43:28 +00:00
switch_io_event_hook_read_frame_t * ptr ;
2006-06-28 19:12:56 +00:00
switch_status_t status ;
int need_codec , perfect ;
top :
status = SWITCH_STATUS_FALSE ;
need_codec = perfect = 0 ;
2006-03-29 19:11:20 +00:00
assert ( session ! = NULL ) ;
* frame = NULL ;
2005-11-19 20:07:43 +00:00
2006-04-28 19:46:57 +00:00
while ( switch_channel_test_flag ( session - > channel , CF_HOLD ) ) {
return SWITCH_STATUS_BREAK ;
}
2005-11-19 20:07:43 +00:00
if ( session - > endpoint_interface - > io_routines - > read_frame ) {
2006-01-09 18:40:56 +00:00
if ( ( status = session - > endpoint_interface - > io_routines - > read_frame ( session ,
frame ,
timeout ,
SWITCH_IO_FLAG_NOOP ,
stream_id ) ) = = SWITCH_STATUS_SUCCESS ) {
2006-01-20 15:05:05 +00:00
for ( ptr = session - > event_hooks . read_frame ; ptr ; ptr = ptr - > next ) {
if ( ( status =
ptr - > read_frame ( session , frame , timeout , SWITCH_IO_FLAG_NOOP ,
stream_id ) ) ! = SWITCH_STATUS_SUCCESS ) {
2005-11-19 20:07:43 +00:00
break ;
}
}
}
}
if ( status ! = SWITCH_STATUS_SUCCESS | | ! ( * frame ) ) {
return status ;
}
2006-03-29 19:11:20 +00:00
assert ( session ! = NULL ) ;
assert ( * frame ! = NULL ) ;
2006-04-06 19:50:53 +00:00
if ( switch_test_flag ( * frame , SFF_CNG ) ) {
return SWITCH_STATUS_SUCCESS ;
}
if ( ( session - > read_codec & & ( * frame ) - > codec & & session - > read_codec - > implementation ! = ( * frame ) - > codec - > implementation ) ) {
2005-11-19 20:07:43 +00:00
need_codec = TRUE ;
}
if ( session - > read_codec & & ! ( * frame ) - > codec ) {
need_codec = TRUE ;
}
if ( ! session - > read_codec & & ( * frame ) - > codec ) {
need_codec = TRUE ;
}
if ( status = = SWITCH_STATUS_SUCCESS & & need_codec ) {
2006-04-29 06:05:03 +00:00
switch_frame_t * enc_frame , * read_frame = * frame ;
2005-11-19 20:07:43 +00:00
2006-01-02 17:28:59 +00:00
if ( read_frame - > codec ) {
2005-12-13 21:04:03 +00:00
unsigned int flag = 0 ;
2005-12-12 17:50:07 +00:00
session - > raw_read_frame . datalen = session - > raw_read_frame . buflen ;
2005-11-19 20:07:43 +00:00
status = switch_core_codec_decode ( read_frame - > codec ,
2006-01-06 01:34:10 +00:00
session - > read_codec ,
read_frame - > data ,
read_frame - > datalen ,
session - > read_codec - > implementation - > samples_per_second ,
session - > raw_read_frame . data ,
2006-04-09 00:10:13 +00:00
& session - > raw_read_frame . datalen ,
& session - > raw_read_frame . rate ,
& flag ) ;
2005-11-19 20:07:43 +00:00
switch ( status ) {
2006-01-06 01:34:10 +00:00
case SWITCH_STATUS_RESAMPLE :
if ( ! session - > read_resampler ) {
switch_resample_create ( & session - > read_resampler ,
read_frame - > codec - > implementation - > samples_per_second ,
2006-01-12 18:27:20 +00:00
read_frame - > codec - > implementation - > bytes_per_frame * 20 ,
2006-01-06 01:34:10 +00:00
session - > read_codec - > implementation - > samples_per_second ,
2006-01-20 15:05:05 +00:00
session - > read_codec - > implementation - > bytes_per_frame * 20 , session - > pool ) ;
2006-01-06 01:34:10 +00:00
}
case SWITCH_STATUS_SUCCESS :
read_frame = & session - > raw_read_frame ;
break ;
case SWITCH_STATUS_NOOP :
status = SWITCH_STATUS_SUCCESS ;
break ;
default :
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Codec %s decoder error! \n " ,
2006-05-05 13:35:33 +00:00
session - > read_codec - > codec_interface - > interface_name ) ;
2006-01-06 01:34:10 +00:00
return status ;
2005-11-19 20:07:43 +00:00
}
}
2006-01-02 17:28:59 +00:00
if ( session - > read_resampler ) {
short * data = read_frame - > data ;
2006-01-20 15:05:05 +00:00
session - > read_resampler - > from_len =
switch_short_to_float ( data , session - > read_resampler - > from , ( int ) read_frame - > datalen / 2 ) ;
session - > read_resampler - > to_len =
switch_resample_process ( session - > read_resampler , session - > read_resampler - > from ,
session - > read_resampler - > from_len , session - > read_resampler - > to ,
2006-04-09 00:10:13 +00:00
session - > read_resampler - > to_size , 0 ) ;
2006-01-02 17:28:59 +00:00
switch_float_to_short ( session - > read_resampler - > to , data , read_frame - > datalen ) ;
read_frame - > samples = session - > read_resampler - > to_len ;
read_frame - > datalen = session - > read_resampler - > to_len * 2 ;
read_frame - > rate = session - > read_resampler - > to_rate ;
}
2005-11-19 20:07:43 +00:00
if ( session - > read_codec ) {
if ( ( * frame ) - > datalen = = session - > read_codec - > implementation - > bytes_per_frame ) {
perfect = TRUE ;
} else {
2006-01-20 15:05:05 +00:00
if ( ! session - > raw_read_buffer ) {
2006-03-30 23:02:50 +00:00
switch_size_t bytes = session - > read_codec - > implementation - > bytes_per_frame * 10 ;
2006-04-11 21:13:44 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Engaging Read Buffer at %u bytes \n " , bytes ) ;
2005-11-19 20:07:43 +00:00
switch_buffer_create ( session - > pool , & session - > raw_read_buffer , bytes ) ;
}
if ( ! switch_buffer_write ( session - > raw_read_buffer , read_frame - > data , read_frame - > datalen ) ) {
return SWITCH_STATUS_MEMERR ;
}
}
2006-03-28 21:22:05 +00:00
if ( perfect | | switch_buffer_inuse ( session - > raw_read_buffer ) > = session - > read_codec - > implementation - > bytes_per_frame ) {
2005-11-19 20:07:43 +00:00
unsigned int flag = 0 ;
if ( perfect ) {
enc_frame = * frame ;
2006-01-06 01:34:10 +00:00
session - > raw_read_frame . rate = ( * frame ) - > rate ;
2005-11-19 20:07:43 +00:00
} else {
2006-04-09 00:10:13 +00:00
session - > raw_read_frame . datalen = ( uint32_t ) switch_buffer_read ( session - > raw_read_buffer ,
2006-06-28 19:12:56 +00:00
session - > raw_read_frame . data ,
session - > read_codec - > implementation - > bytes_per_frame ) ;
2005-12-30 00:00:21 +00:00
session - > raw_read_frame . rate = session - > read_codec - > implementation - > samples_per_second ;
2005-11-19 20:07:43 +00:00
enc_frame = & session - > raw_read_frame ;
}
2005-12-12 17:50:07 +00:00
session - > enc_read_frame . datalen = session - > enc_read_frame . buflen ;
2006-06-28 19:12:56 +00:00
assert ( session - > read_codec ! = NULL ) ;
assert ( enc_frame ! = NULL ) ;
assert ( enc_frame - > data ! = NULL ) ;
2005-11-19 20:07:43 +00:00
status = switch_core_codec_encode ( session - > read_codec ,
2006-03-30 23:02:50 +00:00
enc_frame - > codec ,
enc_frame - > data ,
enc_frame - > datalen ,
2006-06-28 19:12:56 +00:00
session - > read_codec - > implementation - > samples_per_second ,
2006-01-06 01:34:10 +00:00
session - > enc_read_frame . data ,
& session - > enc_read_frame . datalen ,
2006-03-30 23:02:50 +00:00
& session - > enc_read_frame . rate ,
& flag ) ;
2005-11-19 20:07:43 +00:00
switch ( status ) {
2006-01-06 01:34:10 +00:00
case SWITCH_STATUS_RESAMPLE :
2006-04-11 21:13:44 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " fixme 1 \n " ) ;
2006-01-06 01:34:10 +00:00
case SWITCH_STATUS_SUCCESS :
* frame = & session - > enc_read_frame ;
break ;
case SWITCH_STATUS_NOOP :
* frame = & session - > raw_read_frame ;
status = SWITCH_STATUS_SUCCESS ;
break ;
default :
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Codec %s encoder error! \n " ,
2006-01-20 15:05:05 +00:00
session - > read_codec - > codec_interface - > interface_name ) ;
2006-01-06 01:34:10 +00:00
* frame = NULL ;
status = SWITCH_STATUS_GENERR ;
break ;
2005-11-19 20:07:43 +00:00
}
2006-06-28 19:12:56 +00:00
} else {
goto top ;
2005-11-19 20:07:43 +00:00
}
}
}
return status ;
}
2006-04-29 23:43:28 +00:00
static switch_status_t perform_write ( switch_core_session_t * session , switch_frame_t * frame , int timeout , switch_io_flag_t flags , int stream_id )
2006-01-20 15:05:05 +00:00
{
2006-04-29 23:43:28 +00:00
switch_io_event_hook_write_frame_t * ptr ;
switch_status_t status = SWITCH_STATUS_FALSE ;
2005-11-19 20:07:43 +00:00
if ( session - > endpoint_interface - > io_routines - > write_frame ) {
2006-01-20 15:05:05 +00:00
if ( ( status =
session - > endpoint_interface - > io_routines - > write_frame ( session , frame , timeout , flags ,
stream_id ) ) = = SWITCH_STATUS_SUCCESS ) {
for ( ptr = session - > event_hooks . write_frame ; ptr ; ptr = ptr - > next ) {
2006-01-09 18:40:56 +00:00
if ( ( status = ptr - > write_frame ( session , frame , timeout , flags , stream_id ) ) ! = SWITCH_STATUS_SUCCESS ) {
2005-11-19 20:07:43 +00:00
break ;
}
}
}
}
return status ;
}
2006-05-30 17:19:01 +00:00
SWITCH_DECLARE ( void ) switch_core_session_reset ( switch_core_session_t * session )
{
/* sweep theese under the rug, they wont be leaked they will be reclaimed
when the session ends .
*/
session - > raw_write_buffer = NULL ;
session - > raw_read_buffer = NULL ;
session - > read_resampler = NULL ;
session - > write_resampler = NULL ;
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_session_write_frame ( switch_core_session_t * session , switch_frame_t * frame ,
2006-01-20 15:05:05 +00:00
int timeout , int stream_id )
2005-11-19 20:07:43 +00:00
{
2006-04-29 23:43:28 +00:00
switch_status_t status = SWITCH_STATUS_FALSE ;
2006-04-29 06:05:03 +00:00
switch_frame_t * enc_frame = NULL , * write_frame = frame ;
2005-12-13 21:04:03 +00:00
unsigned int flag = 0 , need_codec = 0 , perfect = 0 ;
2006-04-29 23:43:28 +00:00
switch_io_flag_t io_flag = SWITCH_IO_FLAG_NOOP ;
2005-11-19 20:07:43 +00:00
2006-03-29 19:11:20 +00:00
assert ( session ! = NULL ) ;
assert ( frame ! = NULL ) ;
2006-03-18 04:04:59 +00:00
assert ( frame - > codec ! = NULL ) ;
2006-04-28 19:46:57 +00:00
if ( switch_channel_test_flag ( session - > channel , CF_HOLD ) ) {
return SWITCH_STATUS_SUCCESS ;
}
2006-04-06 19:50:53 +00:00
if ( switch_test_flag ( frame , SFF_CNG ) ) {
if ( switch_channel_test_flag ( session - > channel , CF_ACCEPT_CNG ) ) {
return perform_write ( session , frame , timeout , flag , stream_id ) ;
}
return SWITCH_STATUS_SUCCESS ;
}
2005-11-19 20:07:43 +00:00
if ( ( session - > write_codec & & frame - > codec & & session - > write_codec - > implementation ! = frame - > codec - > implementation ) ) {
need_codec = TRUE ;
}
if ( session - > write_codec & & ! frame - > codec ) {
need_codec = TRUE ;
}
if ( ! session - > write_codec & & frame - > codec ) {
need_codec = TRUE ;
}
if ( need_codec ) {
2006-01-02 17:28:59 +00:00
if ( frame - > codec ) {
2005-12-12 17:50:07 +00:00
session - > raw_write_frame . datalen = session - > raw_write_frame . buflen ;
2005-11-19 20:07:43 +00:00
status = switch_core_codec_decode ( frame - > codec ,
2006-01-06 01:34:10 +00:00
session - > write_codec ,
frame - > data ,
frame - > datalen ,
session - > write_codec - > implementation - > samples_per_second ,
session - > raw_write_frame . data ,
2006-01-20 15:05:05 +00:00
& session - > raw_write_frame . datalen , & session - > raw_write_frame . rate , & flag ) ;
2006-03-18 04:04:59 +00:00
2005-11-19 20:07:43 +00:00
switch ( status ) {
2006-01-06 01:34:10 +00:00
case SWITCH_STATUS_RESAMPLE :
write_frame = & session - > raw_write_frame ;
if ( ! session - > write_resampler ) {
status = switch_resample_create ( & session - > write_resampler ,
frame - > codec - > implementation - > samples_per_second ,
2006-01-12 18:27:20 +00:00
frame - > codec - > implementation - > bytes_per_frame * 20 ,
2006-01-06 01:34:10 +00:00
session - > write_codec - > implementation - > samples_per_second ,
2006-01-12 18:27:20 +00:00
session - > write_codec - > implementation - > bytes_per_frame * 20 ,
2006-01-06 01:34:10 +00:00
session - > pool ) ;
}
break ;
case SWITCH_STATUS_SUCCESS :
write_frame = & session - > raw_write_frame ;
break ;
2006-03-17 19:27:26 +00:00
case SWITCH_STATUS_BREAK :
return SWITCH_STATUS_SUCCESS ;
2006-01-06 01:34:10 +00:00
case SWITCH_STATUS_NOOP :
write_frame = frame ;
status = SWITCH_STATUS_SUCCESS ;
break ;
default :
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Codec %s decoder error! \n " ,
2006-01-20 15:05:05 +00:00
frame - > codec - > codec_interface - > interface_name ) ;
2006-01-06 01:34:10 +00:00
return status ;
2005-11-19 20:07:43 +00:00
}
2006-01-20 15:05:05 +00:00
}
2006-01-02 17:28:59 +00:00
if ( session - > write_resampler ) {
short * data = write_frame - > data ;
2006-05-30 17:19:01 +00:00
session - > write_resampler - > from_len = write_frame - > datalen / 2 ;
switch_short_to_float ( data , session - > write_resampler - > from , session - > write_resampler - > from_len ) ;
2006-04-09 00:10:13 +00:00
session - > write_resampler - > to_len = ( uint32_t )
2006-01-20 15:05:05 +00:00
switch_resample_process ( session - > write_resampler , session - > write_resampler - > from ,
session - > write_resampler - > from_len , session - > write_resampler - > to ,
2006-04-09 00:10:13 +00:00
session - > write_resampler - > to_size , 0 ) ;
2006-05-30 17:19:01 +00:00
switch_float_to_short ( session - > write_resampler - > to , data , session - > write_resampler - > to_len ) ;
2006-01-02 17:28:59 +00:00
write_frame - > samples = session - > write_resampler - > to_len ;
2006-05-30 17:19:01 +00:00
write_frame - > datalen = write_frame - > samples * 2 ;
2006-01-02 17:28:59 +00:00
write_frame - > rate = session - > write_resampler - > to_rate ;
}
2006-03-18 04:04:59 +00:00
2005-11-19 20:07:43 +00:00
if ( session - > write_codec ) {
if ( write_frame - > datalen = = session - > write_codec - > implementation - > bytes_per_frame ) {
perfect = TRUE ;
} else {
if ( ! session - > raw_write_buffer ) {
2006-03-30 23:02:50 +00:00
switch_size_t bytes = session - > write_codec - > implementation - > bytes_per_frame * 10 ;
2006-04-11 21:13:44 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG ,
2006-03-30 23:02:50 +00:00
" Engaging Write Buffer at %u bytes to accomodate %u->%u \n " ,
2006-01-06 01:34:10 +00:00
bytes ,
2006-01-20 15:05:05 +00:00
write_frame - > datalen , session - > write_codec - > implementation - > bytes_per_frame ) ;
if ( ( status =
2006-05-30 17:19:01 +00:00
switch_buffer_create ( session - > pool , & session - > raw_write_buffer , bytes ) ) ! = SWITCH_STATUS_SUCCESS ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Write Buffer Failed! \n " ) ;
2005-11-19 20:07:43 +00:00
return status ;
}
}
2006-05-30 17:19:01 +00:00
2005-11-19 20:07:43 +00:00
if ( ! ( switch_buffer_write ( session - > raw_write_buffer , write_frame - > data , write_frame - > datalen ) ) ) {
2006-04-19 19:04:30 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Write Buffer %u bytes Failed! \n " , write_frame - > datalen ) ;
2005-11-19 20:07:43 +00:00
return SWITCH_STATUS_MEMERR ;
}
}
2006-05-30 17:19:01 +00:00
2005-11-19 20:07:43 +00:00
if ( perfect ) {
enc_frame = write_frame ;
2005-12-12 17:50:07 +00:00
session - > enc_write_frame . datalen = session - > enc_write_frame . buflen ;
2005-12-30 00:00:21 +00:00
2005-11-19 20:07:43 +00:00
status = switch_core_codec_encode ( session - > write_codec ,
2006-01-06 01:34:10 +00:00
frame - > codec ,
enc_frame - > data ,
enc_frame - > datalen ,
session - > write_codec - > implementation - > samples_per_second ,
session - > enc_write_frame . data ,
& session - > enc_write_frame . datalen ,
2006-01-20 15:05:05 +00:00
& session - > enc_write_frame . rate , & flag ) ;
2006-05-30 17:19:01 +00:00
2005-11-19 20:07:43 +00:00
switch ( status ) {
2006-01-06 01:34:10 +00:00
case SWITCH_STATUS_RESAMPLE :
2006-04-11 21:13:44 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " fixme 2 \n " ) ;
2006-01-06 01:34:10 +00:00
case SWITCH_STATUS_SUCCESS :
write_frame = & session - > enc_write_frame ;
break ;
case SWITCH_STATUS_NOOP :
write_frame = enc_frame ;
status = SWITCH_STATUS_SUCCESS ;
break ;
default :
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Codec %s encoder error! \n " ,
2006-01-20 15:05:05 +00:00
session - > read_codec - > codec_interface - > interface_name ) ;
2006-01-06 01:34:10 +00:00
write_frame = NULL ;
return status ;
2005-11-19 20:07:43 +00:00
}
2006-01-09 18:40:56 +00:00
status = perform_write ( session , write_frame , timeout , io_flag , stream_id ) ;
2005-11-19 20:07:43 +00:00
return status ;
} else {
2006-03-30 23:02:50 +00:00
switch_size_t used = switch_buffer_inuse ( session - > raw_write_buffer ) ;
2006-04-09 00:10:13 +00:00
uint32_t bytes = session - > write_codec - > implementation - > bytes_per_frame ;
2006-03-30 23:02:50 +00:00
switch_size_t frames = ( used / bytes ) ;
2006-05-30 17:19:01 +00:00
2006-04-09 00:10:13 +00:00
status = SWITCH_STATUS_SUCCESS ;
2006-05-30 17:19:01 +00:00
if ( ! frames ) {
return status ;
} else {
2006-03-30 23:02:50 +00:00
switch_size_t x ;
2005-11-19 20:07:43 +00:00
for ( x = 0 ; x < frames ; x + + ) {
2006-04-09 00:10:13 +00:00
if ( ( session - > raw_write_frame . datalen = ( uint32_t )
2006-02-20 00:23:25 +00:00
switch_buffer_read ( session - > raw_write_buffer , session - > raw_write_frame . data , bytes ) ) ! = 0 ) {
2006-01-06 01:34:10 +00:00
enc_frame = & session - > raw_write_frame ;
session - > raw_write_frame . rate = session - > write_codec - > implementation - > samples_per_second ;
session - > enc_write_frame . datalen = session - > enc_write_frame . buflen ;
2006-03-18 04:04:59 +00:00
2006-01-06 01:34:10 +00:00
status = switch_core_codec_encode ( session - > write_codec ,
frame - > codec ,
enc_frame - > data ,
enc_frame - > datalen ,
frame - > codec - > implementation - > samples_per_second ,
session - > enc_write_frame . data ,
& session - > enc_write_frame . datalen ,
2006-01-20 15:05:05 +00:00
& session - > enc_write_frame . rate , & flag ) ;
2006-01-06 01:34:10 +00:00
2006-03-18 04:04:59 +00:00
2006-01-06 01:34:10 +00:00
switch ( status ) {
case SWITCH_STATUS_RESAMPLE :
write_frame = & session - > enc_write_frame ;
if ( ! session - > read_resampler ) {
status = switch_resample_create ( & session - > read_resampler ,
frame - > codec - > implementation - > samples_per_second ,
2006-01-12 18:27:20 +00:00
frame - > codec - > implementation - > bytes_per_frame * 20 ,
2006-01-20 15:05:05 +00:00
session - > write_codec - > implementation - >
samples_per_second ,
session - > write_codec - > implementation - >
bytes_per_frame * 20 , session - > pool ) ;
2006-01-03 01:17:59 +00:00
}
2006-01-06 01:34:10 +00:00
break ;
case SWITCH_STATUS_SUCCESS :
write_frame = & session - > enc_write_frame ;
break ;
case SWITCH_STATUS_NOOP :
write_frame = enc_frame ;
status = SWITCH_STATUS_SUCCESS ;
break ;
default :
2006-04-22 01:49:27 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Codec %s encoder error %d! \n " ,
session - > read_codec - > codec_interface - > interface_name , status ) ;
2006-01-06 01:34:10 +00:00
write_frame = NULL ;
return status ;
}
if ( session - > read_resampler ) {
short * data = write_frame - > data ;
2006-01-20 15:05:05 +00:00
2006-01-06 01:34:10 +00:00
session - > read_resampler - > from_len = switch_short_to_float ( data ,
session - > read_resampler - > from ,
2006-01-20 15:05:05 +00:00
( int ) write_frame - > datalen /
2 ) ;
2006-04-09 00:10:13 +00:00
session - > read_resampler - > to_len = ( uint32_t )
2006-01-20 15:05:05 +00:00
switch_resample_process ( session - > read_resampler , session - > read_resampler - > from ,
session - > read_resampler - > from_len ,
session - > read_resampler - > to ,
2006-04-09 00:10:13 +00:00
session - > read_resampler - > to_size , 0 ) ;
2006-01-06 01:34:10 +00:00
switch_float_to_short ( session - > read_resampler - > to , data , write_frame - > datalen * 2 ) ;
write_frame - > samples = session - > read_resampler - > to_len ;
write_frame - > datalen = session - > read_resampler - > to_len * 2 ;
write_frame - > rate = session - > read_resampler - > to_rate ;
}
2006-04-19 19:04:30 +00:00
if ( ( status = perform_write ( session , write_frame , timeout , io_flag , stream_id ) ) ! = SWITCH_STATUS_SUCCESS ) {
break ;
}
2005-11-19 20:07:43 +00:00
}
}
2006-04-19 19:04:30 +00:00
return status ;
2005-11-19 20:07:43 +00:00
}
}
}
} else {
2006-03-18 04:04:59 +00:00
return perform_write ( session , frame , timeout , io_flag , stream_id ) ;
2005-11-19 20:07:43 +00:00
}
2006-03-18 04:04:59 +00:00
2005-11-19 20:07:43 +00:00
return status ;
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_session_perform_kill_channel ( switch_core_session_t * session ,
2006-04-27 15:02:35 +00:00
const char * file ,
const char * func ,
int line ,
2006-04-29 23:43:28 +00:00
switch_signal_t sig )
2005-11-19 20:07:43 +00:00
{
2006-04-29 23:43:28 +00:00
switch_io_event_hook_kill_channel_t * ptr ;
switch_status_t status = SWITCH_STATUS_FALSE ;
2006-04-27 15:02:35 +00:00
2006-05-27 18:39:20 +00:00
switch_log_printf ( SWITCH_CHANNEL_ID_LOG , ( char * ) file , func , line , SWITCH_LOG_INFO , " Kill %s [%d] \n " , switch_channel_get_name ( session - > channel ) , sig ) ;
2005-11-19 20:07:43 +00:00
if ( session - > endpoint_interface - > io_routines - > kill_channel ) {
if ( ( status = session - > endpoint_interface - > io_routines - > kill_channel ( session , sig ) ) = = SWITCH_STATUS_SUCCESS ) {
2006-01-20 15:05:05 +00:00
for ( ptr = session - > event_hooks . kill_channel ; ptr ; ptr = ptr - > next ) {
2005-11-19 20:07:43 +00:00
if ( ( status = ptr - > kill_channel ( session , sig ) ) ! = SWITCH_STATUS_SUCCESS ) {
break ;
}
}
}
}
return status ;
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_session_waitfor_read ( switch_core_session_t * session , int timeout , int stream_id )
2005-11-19 20:07:43 +00:00
{
2006-04-29 23:43:28 +00:00
switch_io_event_hook_waitfor_read_t * ptr ;
switch_status_t status = SWITCH_STATUS_FALSE ;
2005-11-19 20:07:43 +00:00
if ( session - > endpoint_interface - > io_routines - > waitfor_read ) {
2006-01-20 15:05:05 +00:00
if ( ( status =
session - > endpoint_interface - > io_routines - > waitfor_read ( session , timeout ,
stream_id ) ) = = SWITCH_STATUS_SUCCESS ) {
for ( ptr = session - > event_hooks . waitfor_read ; ptr ; ptr = ptr - > next ) {
2006-01-09 18:40:56 +00:00
if ( ( status = ptr - > waitfor_read ( session , timeout , stream_id ) ) ! = SWITCH_STATUS_SUCCESS ) {
2005-11-19 20:07:43 +00:00
break ;
}
}
}
}
return status ;
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_session_waitfor_write ( switch_core_session_t * session , int timeout ,
2006-01-20 15:05:05 +00:00
int stream_id )
2005-11-19 20:07:43 +00:00
{
2006-04-29 23:43:28 +00:00
switch_io_event_hook_waitfor_write_t * ptr ;
switch_status_t status = SWITCH_STATUS_FALSE ;
2005-11-19 20:07:43 +00:00
if ( session - > endpoint_interface - > io_routines - > waitfor_write ) {
2006-01-20 15:05:05 +00:00
if ( ( status =
session - > endpoint_interface - > io_routines - > waitfor_write ( session , timeout ,
stream_id ) ) = = SWITCH_STATUS_SUCCESS ) {
for ( ptr = session - > event_hooks . waitfor_write ; ptr ; ptr = ptr - > next ) {
2006-01-09 18:40:56 +00:00
if ( ( status = ptr - > waitfor_write ( session , timeout , stream_id ) ) ! = SWITCH_STATUS_SUCCESS ) {
2005-11-19 20:07:43 +00:00
break ;
}
}
}
}
return status ;
}
2005-12-06 21:25:56 +00:00
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_session_send_dtmf ( switch_core_session_t * session , char * dtmf )
2005-12-06 21:25:56 +00:00
{
2006-04-29 23:43:28 +00:00
switch_io_event_hook_send_dtmf_t * ptr ;
switch_status_t status = SWITCH_STATUS_FALSE ;
2005-12-06 21:25:56 +00:00
if ( session - > endpoint_interface - > io_routines - > send_dtmf ) {
if ( ( status = session - > endpoint_interface - > io_routines - > send_dtmf ( session , dtmf ) ) = = SWITCH_STATUS_SUCCESS ) {
2006-01-20 15:05:05 +00:00
for ( ptr = session - > event_hooks . send_dtmf ; ptr ; ptr = ptr - > next ) {
2005-12-06 21:25:56 +00:00
if ( ( status = ptr - > send_dtmf ( session , dtmf ) ) ! = SWITCH_STATUS_SUCCESS ) {
break ;
}
}
}
}
return status ;
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_session_add_event_hook_outgoing ( switch_core_session_t * session ,
switch_outgoing_channel_hook_t outgoing_channel )
2005-11-19 20:07:43 +00:00
{
2006-04-29 23:43:28 +00:00
switch_io_event_hook_outgoing_channel_t * hook , * ptr ;
2005-11-19 20:07:43 +00:00
assert ( outgoing_channel ! = NULL ) ;
2006-02-20 00:23:25 +00:00
if ( ( hook = switch_core_session_alloc ( session , sizeof ( * hook ) ) ) ! = 0 ) {
2005-11-19 20:07:43 +00:00
hook - > outgoing_channel = outgoing_channel ;
if ( ! session - > event_hooks . outgoing_channel ) {
session - > event_hooks . outgoing_channel = hook ;
} else {
2006-01-20 15:05:05 +00:00
for ( ptr = session - > event_hooks . outgoing_channel ; ptr & & ptr - > next ; ptr = ptr - > next ) ;
2005-11-19 20:07:43 +00:00
ptr - > next = hook ;
}
return SWITCH_STATUS_SUCCESS ;
}
return SWITCH_STATUS_MEMERR ;
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_session_add_event_hook_answer_channel ( switch_core_session_t * session ,
switch_answer_channel_hook_t
2006-01-20 15:05:05 +00:00
answer_channel )
2005-11-19 20:07:43 +00:00
{
2006-04-29 23:43:28 +00:00
switch_io_event_hook_answer_channel_t * hook , * ptr ;
2005-11-19 20:07:43 +00:00
assert ( answer_channel ! = NULL ) ;
2006-02-20 00:23:25 +00:00
if ( ( hook = switch_core_session_alloc ( session , sizeof ( * hook ) ) ) ! = 0 ) {
2005-11-19 20:07:43 +00:00
hook - > answer_channel = answer_channel ;
if ( ! session - > event_hooks . answer_channel ) {
session - > event_hooks . answer_channel = hook ;
} else {
2006-01-20 15:05:05 +00:00
for ( ptr = session - > event_hooks . answer_channel ; ptr & & ptr - > next ; ptr = ptr - > next ) ;
2005-11-19 20:07:43 +00:00
ptr - > next = hook ;
}
return SWITCH_STATUS_SUCCESS ;
}
return SWITCH_STATUS_MEMERR ;
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_session_add_event_hook_read_frame ( switch_core_session_t * session ,
switch_read_frame_hook_t read_frame )
2005-11-19 20:07:43 +00:00
{
2006-04-29 23:43:28 +00:00
switch_io_event_hook_read_frame_t * hook , * ptr ;
2005-11-19 20:07:43 +00:00
assert ( read_frame ! = NULL ) ;
2006-02-20 00:23:25 +00:00
if ( ( hook = switch_core_session_alloc ( session , sizeof ( * hook ) ) ) ! = 0 ) {
2005-11-19 20:07:43 +00:00
hook - > read_frame = read_frame ;
if ( ! session - > event_hooks . read_frame ) {
session - > event_hooks . read_frame = hook ;
} else {
2006-01-20 15:05:05 +00:00
for ( ptr = session - > event_hooks . read_frame ; ptr & & ptr - > next ; ptr = ptr - > next ) ;
2005-11-19 20:07:43 +00:00
ptr - > next = hook ;
}
return SWITCH_STATUS_SUCCESS ;
}
return SWITCH_STATUS_MEMERR ;
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_session_add_event_hook_write_frame ( switch_core_session_t * session ,
switch_write_frame_hook_t write_frame )
2005-11-19 20:07:43 +00:00
{
2006-04-29 23:43:28 +00:00
switch_io_event_hook_write_frame_t * hook , * ptr ;
2005-11-19 20:07:43 +00:00
assert ( write_frame ! = NULL ) ;
2006-02-20 00:23:25 +00:00
if ( ( hook = switch_core_session_alloc ( session , sizeof ( * hook ) ) ) ! = 0 ) {
2005-11-19 20:07:43 +00:00
hook - > write_frame = write_frame ;
if ( ! session - > event_hooks . write_frame ) {
session - > event_hooks . write_frame = hook ;
} else {
2006-01-20 15:05:05 +00:00
for ( ptr = session - > event_hooks . write_frame ; ptr & & ptr - > next ; ptr = ptr - > next ) ;
2005-11-19 20:07:43 +00:00
ptr - > next = hook ;
}
return SWITCH_STATUS_SUCCESS ;
}
return SWITCH_STATUS_MEMERR ;
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_session_add_event_hook_kill_channel ( switch_core_session_t * session ,
switch_kill_channel_hook_t kill_channel )
2005-11-19 20:07:43 +00:00
{
2006-04-29 23:43:28 +00:00
switch_io_event_hook_kill_channel_t * hook , * ptr ;
2005-11-19 20:07:43 +00:00
assert ( kill_channel ! = NULL ) ;
2006-02-20 00:23:25 +00:00
if ( ( hook = switch_core_session_alloc ( session , sizeof ( * hook ) ) ) ! = 0 ) {
2005-11-19 20:07:43 +00:00
hook - > kill_channel = kill_channel ;
if ( ! session - > event_hooks . kill_channel ) {
session - > event_hooks . kill_channel = hook ;
} else {
2006-01-20 15:05:05 +00:00
for ( ptr = session - > event_hooks . kill_channel ; ptr & & ptr - > next ; ptr = ptr - > next ) ;
2005-11-19 20:07:43 +00:00
ptr - > next = hook ;
}
return SWITCH_STATUS_SUCCESS ;
}
return SWITCH_STATUS_MEMERR ;
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_session_add_event_hook_waitfor_read ( switch_core_session_t * session ,
switch_waitfor_read_hook_t waitfor_read )
2005-11-19 20:07:43 +00:00
{
2006-04-29 23:43:28 +00:00
switch_io_event_hook_waitfor_read_t * hook , * ptr ;
2005-11-19 20:07:43 +00:00
assert ( waitfor_read ! = NULL ) ;
2006-02-20 00:23:25 +00:00
if ( ( hook = switch_core_session_alloc ( session , sizeof ( * hook ) ) ) ! = 0 ) {
2005-11-19 20:07:43 +00:00
hook - > waitfor_read = waitfor_read ;
if ( ! session - > event_hooks . waitfor_read ) {
session - > event_hooks . waitfor_read = hook ;
} else {
2006-01-20 15:05:05 +00:00
for ( ptr = session - > event_hooks . waitfor_read ; ptr & & ptr - > next ; ptr = ptr - > next ) ;
2005-11-19 20:07:43 +00:00
ptr - > next = hook ;
}
return SWITCH_STATUS_SUCCESS ;
}
return SWITCH_STATUS_MEMERR ;
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_session_add_event_hook_waitfor_write ( switch_core_session_t * session ,
switch_waitfor_write_hook_t waitfor_write )
2005-11-19 20:07:43 +00:00
{
2006-04-29 23:43:28 +00:00
switch_io_event_hook_waitfor_write_t * hook , * ptr ;
2005-11-19 20:07:43 +00:00
assert ( waitfor_write ! = NULL ) ;
2006-02-20 00:23:25 +00:00
if ( ( hook = switch_core_session_alloc ( session , sizeof ( * hook ) ) ) ! = 0 ) {
2005-11-19 20:07:43 +00:00
hook - > waitfor_write = waitfor_write ;
if ( ! session - > event_hooks . waitfor_write ) {
session - > event_hooks . waitfor_write = hook ;
} else {
2006-01-20 15:05:05 +00:00
for ( ptr = session - > event_hooks . waitfor_write ; ptr & & ptr - > next ; ptr = ptr - > next ) ;
2005-11-19 20:07:43 +00:00
ptr - > next = hook ;
}
return SWITCH_STATUS_SUCCESS ;
}
return SWITCH_STATUS_MEMERR ;
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_session_add_event_hook_send_dtmf ( switch_core_session_t * session ,
switch_send_dtmf_hook_t send_dtmf )
2005-12-06 21:25:56 +00:00
{
2006-04-29 23:43:28 +00:00
switch_io_event_hook_send_dtmf_t * hook , * ptr ;
2005-12-06 21:25:56 +00:00
assert ( send_dtmf ! = NULL ) ;
2006-02-20 00:23:25 +00:00
if ( ( hook = switch_core_session_alloc ( session , sizeof ( * hook ) ) ) ! = 0 ) {
2005-12-06 21:25:56 +00:00
hook - > send_dtmf = send_dtmf ;
if ( ! session - > event_hooks . send_dtmf ) {
session - > event_hooks . send_dtmf = hook ;
} else {
2006-01-20 15:05:05 +00:00
for ( ptr = session - > event_hooks . send_dtmf ; ptr & & ptr - > next ; ptr = ptr - > next ) ;
2005-12-06 21:25:56 +00:00
ptr - > next = hook ;
}
return SWITCH_STATUS_SUCCESS ;
}
return SWITCH_STATUS_MEMERR ;
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_new_memory_pool ( switch_memory_pool_t * * pool )
2005-11-19 20:07:43 +00:00
{
2005-12-28 05:17:21 +00:00
2006-03-29 19:11:20 +00:00
assert ( runtime . memory_pool ! = NULL ) ;
2005-11-19 20:07:43 +00:00
2006-05-27 18:39:20 +00:00
if ( ( apr_pool_create ( pool , NULL ) ) ! = SWITCH_STATUS_SUCCESS ) {
2005-11-19 20:07:43 +00:00
* pool = NULL ;
return SWITCH_STATUS_MEMERR ;
}
return SWITCH_STATUS_SUCCESS ;
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_destroy_memory_pool ( switch_memory_pool_t * * pool )
2005-11-19 20:07:43 +00:00
{
apr_pool_destroy ( * pool ) ;
return SWITCH_STATUS_SUCCESS ;
}
2006-04-29 06:05:03 +00:00
SWITCH_DECLARE ( switch_channel_t * ) switch_core_session_get_channel ( switch_core_session_t * session )
2005-11-19 20:07:43 +00:00
{
return session - > channel ;
}
2006-04-29 06:05:03 +00:00
static void switch_core_standard_on_init ( switch_core_session_t * session )
2005-11-19 20:07:43 +00:00
{
2006-04-11 21:13:44 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Standard INIT %s \n " , switch_channel_get_name ( session - > channel ) ) ;
2005-11-19 20:07:43 +00:00
}
2006-04-29 06:05:03 +00:00
static void switch_core_standard_on_hangup ( switch_core_session_t * session )
2005-11-19 20:07:43 +00:00
{
2006-01-03 01:17:59 +00:00
2006-04-11 21:13:44 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Standard HANGUP %s \n " , switch_channel_get_name ( session - > channel ) ) ;
2005-12-15 00:45:38 +00:00
2005-11-19 20:07:43 +00:00
}
2006-04-29 06:05:03 +00:00
static void switch_core_standard_on_ring ( switch_core_session_t * session )
2005-11-19 20:07:43 +00:00
{
2006-04-29 23:43:28 +00:00
switch_dialplan_interface_t * dialplan_interface = NULL ;
2006-04-29 06:05:03 +00:00
switch_caller_profile_t * caller_profile ;
switch_caller_extension_t * extension ;
2005-11-19 20:07:43 +00:00
2006-04-11 21:13:44 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Standard RING %s \n " , switch_channel_get_name ( session - > channel ) ) ;
2005-12-15 00:45:38 +00:00
2006-02-20 00:23:25 +00:00
if ( ( caller_profile = switch_channel_get_caller_profile ( session - > channel ) ) = = 0 ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Can't get profile! \n " ) ;
2006-04-26 20:15:16 +00:00
switch_channel_hangup ( session - > channel , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
2005-11-19 20:07:43 +00:00
} else {
2006-03-02 00:32:45 +00:00
if ( ! switch_strlen_zero ( caller_profile - > dialplan ) ) {
dialplan_interface = switch_loadable_module_get_dialplan_interface ( caller_profile - > dialplan ) ;
}
if ( ! dialplan_interface ) {
if ( switch_channel_test_flag ( session - > channel , CF_OUTBOUND ) ) {
2006-05-10 03:23:05 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_INFO , " No Dialplan, changing state to HOLD \n " ) ;
switch_channel_set_state ( session - > channel , CS_HOLD ) ;
2006-03-02 00:32:45 +00:00
return ;
2006-05-10 03:23:05 +00:00
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_INFO , " No Dialplan, Aborting \n " ) ;
switch_channel_hangup ( session - > channel , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
2006-03-02 00:32:45 +00:00
}
2005-11-19 20:07:43 +00:00
} else {
2006-02-20 00:23:25 +00:00
if ( ( extension = dialplan_interface - > hunt_function ( session ) ) ! = 0 ) {
2005-11-19 20:07:43 +00:00
switch_channel_set_caller_extension ( session - > channel , extension ) ;
}
}
}
2006-01-03 01:17:59 +00:00
}
2005-11-19 20:07:43 +00:00
2006-04-29 06:05:03 +00:00
static void switch_core_standard_on_execute ( switch_core_session_t * session )
2005-11-19 20:07:43 +00:00
{
2006-04-29 06:05:03 +00:00
switch_caller_extension_t * extension ;
2006-04-29 01:00:52 +00:00
switch_event_t * event ;
2006-04-29 23:43:28 +00:00
const switch_application_interface_t * application_interface ;
2005-11-19 20:07:43 +00:00
2006-04-11 21:13:44 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Standard EXECUTE \n " ) ;
2006-02-20 00:23:25 +00:00
if ( ( extension = switch_channel_get_caller_extension ( session - > channel ) ) = = 0 ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " No Extension! \n " ) ;
2006-04-26 20:15:16 +00:00
switch_channel_hangup ( session - > channel , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
2005-11-19 20:07:43 +00:00
return ;
}
while ( switch_channel_get_state ( session - > channel ) = = CS_EXECUTE & & extension - > current_application ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_NOTICE , " Execute %s(%s) \n " ,
2006-01-20 15:05:05 +00:00
extension - > current_application - > application_name ,
2006-01-06 01:34:10 +00:00
extension - > current_application - > application_data ) ;
2006-02-20 00:23:25 +00:00
if (
2006-01-20 15:05:05 +00:00
( application_interface =
2006-02-20 00:23:25 +00:00
switch_loadable_module_get_application_interface ( extension - > current_application - > application_name ) ) = = 0 ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Invalid Application %s \n " ,
2006-01-20 15:05:05 +00:00
extension - > current_application - > application_name ) ;
2006-04-26 20:15:16 +00:00
switch_channel_hangup ( session - > channel , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
2005-11-19 20:07:43 +00:00
return ;
}
if ( ! application_interface - > application_function ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " No Function for %s \n " ,
2006-01-20 15:05:05 +00:00
extension - > current_application - > application_name ) ;
2006-04-26 20:15:16 +00:00
switch_channel_hangup ( session - > channel , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
2005-11-19 20:07:43 +00:00
return ;
}
2006-04-04 21:26:21 +00:00
2006-04-11 14:55:14 +00:00
if ( switch_event_create ( & event , SWITCH_EVENT_CHANNEL_EXECUTE ) = = SWITCH_STATUS_SUCCESS ) {
2006-04-04 21:26:21 +00:00
switch_channel_event_set_data ( session - > channel , event ) ;
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " Application " , extension - > current_application - > application_name ) ;
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " Application-Data " , extension - > current_application - > application_data ) ;
switch_event_fire ( & event ) ;
}
2005-11-19 20:07:43 +00:00
application_interface - > application_function ( session , extension - > current_application - > application_data ) ;
extension - > current_application = extension - > current_application - > next ;
}
2006-04-26 20:15:16 +00:00
2006-03-06 23:10:22 +00:00
if ( switch_channel_get_state ( session - > channel ) = = CS_EXECUTE ) {
2006-04-26 20:15:16 +00:00
switch_channel_hangup ( session - > channel , SWITCH_CAUSE_NORMAL_CLEARING ) ;
2006-03-06 23:10:22 +00:00
}
2005-11-19 20:07:43 +00:00
}
2006-04-29 06:05:03 +00:00
static void switch_core_standard_on_loopback ( switch_core_session_t * session )
2005-11-19 20:07:43 +00:00
{
2006-04-29 06:05:03 +00:00
switch_frame_t * frame ;
2006-01-09 18:40:56 +00:00
int stream_id ;
2005-11-19 20:07:43 +00:00
2006-04-11 21:13:44 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Standard LOOPBACK \n " ) ;
2005-11-19 20:07:43 +00:00
2006-03-30 23:02:50 +00:00
while ( switch_channel_get_state ( session - > channel ) = = CS_LOOPBACK ) {
2006-01-20 15:05:05 +00:00
for ( stream_id = 0 ; stream_id < session - > stream_count ; stream_id + + ) {
2006-01-09 18:40:56 +00:00
if ( switch_core_session_read_frame ( session , & frame , - 1 , stream_id ) = = SWITCH_STATUS_SUCCESS ) {
switch_core_session_write_frame ( session , frame , - 1 , stream_id ) ;
}
2005-11-19 20:07:43 +00:00
}
}
}
2006-04-29 06:05:03 +00:00
static void switch_core_standard_on_transmit ( switch_core_session_t * session )
2005-11-19 20:07:43 +00:00
{
2006-03-30 23:02:50 +00:00
assert ( session ! = NULL ) ;
2006-04-11 21:13:44 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Standard TRANSMIT \n " ) ;
2005-11-19 20:07:43 +00:00
}
2006-04-29 06:05:03 +00:00
static void switch_core_standard_on_hold ( switch_core_session_t * session )
2006-04-28 19:46:57 +00:00
{
assert ( session ! = NULL ) ;
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Standard HOLD \n " ) ;
}
2006-04-29 06:05:03 +00:00
SWITCH_DECLARE ( void ) switch_core_session_signal_state_change ( switch_core_session_t * session )
2005-11-19 20:07:43 +00:00
{
switch_thread_cond_signal ( session - > cond ) ;
}
2006-04-29 06:05:03 +00:00
SWITCH_DECLARE ( unsigned int ) switch_core_session_runing ( switch_core_session_t * session )
2006-03-01 22:55:28 +00:00
{
return session - > thread_running ;
}
2006-05-05 13:35:33 +00:00
# ifdef CRASH_PROT
2006-05-03 15:44:58 +00:00
# if defined (__GNUC__) && defined (LINUX)
2006-04-27 21:56:09 +00:00
# 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
2006-04-27 21:09:58 +00:00
static int handle_fatality ( int sig )
{
2006-04-29 01:00:52 +00:00
switch_thread_id_t thread_id ;
2006-04-27 21:09:58 +00:00
jmp_buf * env ;
if ( sig & & ( thread_id = switch_thread_self ( ) ) & & ( env = ( jmp_buf * ) apr_hash_get ( runtime . stack_table , & thread_id , sizeof ( thread_id ) ) ) ) {
2006-04-27 21:56:09 +00:00
print_trace ( ) ;
2006-04-27 21:09:58 +00:00
longjmp ( * env , sig ) ;
} else {
2006-04-28 19:46:57 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Caught signal %d for unmapped thread! " , sig ) ;
2006-04-27 21:09:58 +00:00
abort ( ) ;
}
return 0 ;
}
2006-05-05 13:35:33 +00:00
# endif
2006-04-27 21:09:58 +00:00
2006-04-29 06:05:03 +00:00
SWITCH_DECLARE ( void ) switch_core_session_run ( switch_core_session_t * session )
2005-11-19 20:07:43 +00:00
{
2006-04-29 23:43:28 +00:00
switch_channel_state_t state = CS_NEW , laststate = CS_HANGUP , midstate = CS_DONE ;
const switch_endpoint_interface_t * endpoint_interface ;
2006-04-29 06:05:03 +00:00
const switch_state_handler_table_t * driver_state_handler = NULL ;
const switch_state_handler_table_t * application_state_handler = NULL ;
2006-05-05 13:35:33 +00:00
# ifdef CRASH_PROT
2006-04-29 01:00:52 +00:00
switch_thread_id_t thread_id = switch_thread_self ( ) ;
2006-04-27 21:09:58 +00:00
jmp_buf env ;
int sig ;
signal ( SIGSEGV , ( void * ) handle_fatality ) ;
signal ( SIGFPE , ( void * ) handle_fatality ) ;
# ifndef WIN32
signal ( SIGBUS , ( void * ) handle_fatality ) ;
# endif
if ( ( sig = setjmp ( env ) ) ! = 0 ) {
2006-04-29 01:00:52 +00:00
switch_event_t * event ;
2006-04-27 21:09:58 +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 {
apr_hash_set ( runtime . stack_table , & thread_id , sizeof ( thread_id ) , & env ) ;
}
2006-05-05 13:35:33 +00:00
# endif
2005-11-19 20:07:43 +00:00
/*
2006-01-20 15:05:05 +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 > )
2005-11-19 20:07:43 +00:00
2006-01-20 15:05:05 +00:00
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
2005-11-19 20:07:43 +00:00
2006-01-20 15:05:05 +00:00
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
2005-11-19 20:07:43 +00:00
2006-01-20 15:05:05 +00:00
Finally the default state behaviour is called .
2005-11-19 20:07:43 +00:00
2006-01-20 15:05:05 +00:00
*/
2005-11-19 20:07:43 +00:00
assert ( session ! = NULL ) ;
2006-03-01 22:55:28 +00:00
session - > thread_running = 1 ;
2005-11-19 20:07:43 +00:00
endpoint_interface = session - > endpoint_interface ;
assert ( endpoint_interface ! = NULL ) ;
2006-02-07 20:47:15 +00:00
driver_state_handler = endpoint_interface - > state_handler ;
assert ( driver_state_handler ! = NULL ) ;
2005-11-19 20:07:43 +00:00
switch_mutex_lock ( session - > mutex ) ;
while ( ( state = switch_channel_get_state ( session - > channel ) ) ! = CS_DONE ) {
2005-12-21 22:25:22 +00:00
if ( state ! = laststate ) {
2006-02-07 20:47:15 +00:00
int index = 0 ;
int proceed = 1 ;
2005-11-19 20:07:43 +00:00
midstate = state ;
2006-01-20 15:05:05 +00:00
switch ( state ) {
case CS_NEW : /* Just created, Waiting for first instructions */
2006-04-26 23:09:48 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " (%s) State NEW \n " , switch_channel_get_name ( session - > channel ) ) ;
2006-01-06 01:34:10 +00:00
break ;
case CS_DONE :
continue ;
2006-01-20 15:05:05 +00:00
case CS_HANGUP : /* Deactivate and end the thread */
2006-04-26 23:09:48 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " (%s) State HANGUP \n " , switch_channel_get_name ( session - > channel ) ) ;
2006-02-07 20:47:15 +00:00
if ( ! driver_state_handler - > on_hangup | |
( driver_state_handler - > on_hangup & &
driver_state_handler - > on_hangup ( session ) = = SWITCH_STATUS_SUCCESS & &
2006-01-06 01:34:10 +00:00
midstate = = switch_channel_get_state ( session - > channel ) ) ) {
2006-02-20 00:23:25 +00:00
while ( ( application_state_handler = switch_channel_get_state_handler ( session - > channel , index + + ) ) ! = 0 ) {
2006-02-07 20:47:15 +00:00
if ( ! application_state_handler | | ! application_state_handler - > on_hangup | |
( application_state_handler - > on_hangup & &
application_state_handler - > on_hangup ( session ) = = SWITCH_STATUS_SUCCESS & &
midstate = = switch_channel_get_state ( session - > channel ) ) ) {
proceed + + ;
continue ;
} else {
proceed = 0 ;
break ;
}
}
index = 0 ;
2006-02-20 00:23:25 +00:00
while ( proceed & & ( application_state_handler = switch_core_get_state_handler ( index + + ) ) ! = 0 ) {
2006-02-07 20:47:15 +00:00
if ( ! application_state_handler | | ! application_state_handler - > on_hangup | |
( application_state_handler - > on_hangup & &
application_state_handler - > on_hangup ( session ) = = SWITCH_STATUS_SUCCESS & &
midstate = = switch_channel_get_state ( session - > channel ) ) ) {
proceed + + ;
continue ;
} else {
proceed = 0 ;
break ;
}
}
if ( proceed ) {
2006-01-06 01:34:10 +00:00
switch_core_standard_on_hangup ( session ) ;
}
}
switch_channel_set_state ( session - > channel , CS_DONE ) ;
2006-02-13 17:43:49 +00:00
midstate = switch_channel_get_state ( session - > channel ) ;
2006-01-06 01:34:10 +00:00
break ;
2006-01-20 15:05:05 +00:00
case CS_INIT : /* Basic setup tasks */
2006-04-26 23:09:48 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " (%s) State INIT \n " , switch_channel_get_name ( session - > channel ) ) ;
2006-02-07 20:47:15 +00:00
if ( ! driver_state_handler - > on_init | |
( driver_state_handler - > on_init & &
driver_state_handler - > on_init ( session ) = = SWITCH_STATUS_SUCCESS & &
2006-01-06 01:34:10 +00:00
midstate = = switch_channel_get_state ( session - > channel ) ) ) {
2006-02-20 00:23:25 +00:00
while ( ( application_state_handler = switch_channel_get_state_handler ( session - > channel , index + + ) ) ! = 0 ) {
2006-02-07 20:47:15 +00:00
if ( ! application_state_handler | | ! application_state_handler - > on_init | |
( application_state_handler - > on_init & &
application_state_handler - > on_init ( session ) = = SWITCH_STATUS_SUCCESS & &
midstate = = switch_channel_get_state ( session - > channel ) ) ) {
proceed + + ;
continue ;
} else {
proceed = 0 ;
break ;
}
}
index = 0 ;
2006-02-20 00:23:25 +00:00
while ( proceed & & ( application_state_handler = switch_core_get_state_handler ( index + + ) ) ! = 0 ) {
2006-02-07 20:47:15 +00:00
if ( ! application_state_handler | | ! application_state_handler - > on_init | |
( application_state_handler - > on_init & &
application_state_handler - > on_init ( session ) = = SWITCH_STATUS_SUCCESS & &
midstate = = switch_channel_get_state ( session - > channel ) ) ) {
proceed + + ;
continue ;
} else {
proceed = 0 ;
break ;
}
}
if ( proceed ) {
2006-01-06 01:34:10 +00:00
switch_core_standard_on_init ( session ) ;
}
}
break ;
2006-01-20 15:05:05 +00:00
case CS_RING : /* Look for a dialplan and find something to do */
2006-04-26 23:09:48 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " (%s) State RING \n " , switch_channel_get_name ( session - > channel ) ) ;
2006-02-07 20:47:15 +00:00
if ( ! driver_state_handler - > on_ring | |
( driver_state_handler - > on_ring & &
driver_state_handler - > on_ring ( session ) = = SWITCH_STATUS_SUCCESS & &
2006-01-06 01:34:10 +00:00
midstate = = switch_channel_get_state ( session - > channel ) ) ) {
2006-02-20 00:23:25 +00:00
while ( ( application_state_handler = switch_channel_get_state_handler ( session - > channel , index + + ) ) ! = 0 ) {
2006-02-07 20:47:15 +00:00
if ( ! application_state_handler | | ! application_state_handler - > on_ring | |
( application_state_handler - > on_ring & &
application_state_handler - > on_ring ( session ) = = SWITCH_STATUS_SUCCESS & &
midstate = = switch_channel_get_state ( session - > channel ) ) ) {
proceed + + ;
continue ;
} else {
proceed = 0 ;
break ;
}
}
index = 0 ;
2006-02-20 00:23:25 +00:00
while ( proceed & & ( application_state_handler = switch_core_get_state_handler ( index + + ) ) ! = 0 ) {
2006-02-07 20:47:15 +00:00
if ( ! application_state_handler | | ! application_state_handler - > on_ring | |
( application_state_handler - > on_ring & &
application_state_handler - > on_ring ( session ) = = SWITCH_STATUS_SUCCESS & &
midstate = = switch_channel_get_state ( session - > channel ) ) ) {
proceed + + ;
continue ;
} else {
proceed = 0 ;
break ;
}
}
if ( proceed ) {
2006-01-06 01:34:10 +00:00
switch_core_standard_on_ring ( session ) ;
}
}
break ;
2006-01-20 15:05:05 +00:00
case CS_EXECUTE : /* Execute an Operation */
2006-04-26 23:09:48 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " (%s) State EXECUTE \n " , switch_channel_get_name ( session - > channel ) ) ;
2006-02-07 20:47:15 +00:00
if ( ! driver_state_handler - > on_execute | |
( driver_state_handler - > on_execute & &
driver_state_handler - > on_execute ( session ) = = SWITCH_STATUS_SUCCESS & &
2006-01-06 01:34:10 +00:00
midstate = = switch_channel_get_state ( session - > channel ) ) ) {
2006-02-20 00:23:25 +00:00
while ( ( application_state_handler = switch_channel_get_state_handler ( session - > channel , index + + ) ) ! = 0 ) {
2006-02-07 20:47:15 +00:00
if ( ! application_state_handler | | ! application_state_handler - > on_execute | |
( application_state_handler - > on_execute & &
application_state_handler - > on_execute ( session ) = = SWITCH_STATUS_SUCCESS & &
midstate = = switch_channel_get_state ( session - > channel ) ) ) {
proceed + + ;
continue ;
} else {
proceed = 0 ;
break ;
}
}
index = 0 ;
2006-02-20 00:23:25 +00:00
while ( proceed & & ( application_state_handler = switch_core_get_state_handler ( index + + ) ) ! = 0 ) {
2006-02-07 20:47:15 +00:00
if ( ! application_state_handler | | ! application_state_handler - > on_execute | |
( application_state_handler - > on_execute & &
application_state_handler - > on_execute ( session ) = = SWITCH_STATUS_SUCCESS & &
midstate = = switch_channel_get_state ( session - > channel ) ) ) {
proceed + + ;
continue ;
} else {
proceed = 0 ;
break ;
}
}
if ( proceed ) {
2006-01-06 01:34:10 +00:00
switch_core_standard_on_execute ( session ) ;
}
}
break ;
2006-01-20 15:05:05 +00:00
case CS_LOOPBACK : /* loop all data back to source */
2006-04-26 23:09:48 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " (%s) State LOOPBACK \n " , switch_channel_get_name ( session - > channel ) ) ;
2006-02-07 20:47:15 +00:00
if ( ! driver_state_handler - > on_loopback | |
( driver_state_handler - > on_loopback & &
driver_state_handler - > on_loopback ( session ) = = SWITCH_STATUS_SUCCESS & &
2006-01-06 01:34:10 +00:00
midstate = = switch_channel_get_state ( session - > channel ) ) ) {
2006-02-20 00:23:25 +00:00
while ( ( application_state_handler = switch_channel_get_state_handler ( session - > channel , index + + ) ) ! = 0 ) {
2006-02-07 20:47:15 +00:00
if ( ! application_state_handler | | ! application_state_handler - > on_loopback | |
( application_state_handler - > on_loopback & &
application_state_handler - > on_loopback ( session ) = = SWITCH_STATUS_SUCCESS & &
midstate = = switch_channel_get_state ( session - > channel ) ) ) {
proceed + + ;
continue ;
} else {
proceed = 0 ;
break ;
}
}
index = 0 ;
2006-02-20 00:23:25 +00:00
while ( proceed & & ( application_state_handler = switch_core_get_state_handler ( index + + ) ) ! = 0 ) {
2006-02-07 20:47:15 +00:00
if ( ! application_state_handler | | ! application_state_handler - > on_loopback | |
( application_state_handler - > on_loopback & &
application_state_handler - > on_loopback ( session ) = = SWITCH_STATUS_SUCCESS & &
midstate = = switch_channel_get_state ( session - > channel ) ) ) {
proceed + + ;
continue ;
} else {
proceed = 0 ;
break ;
}
}
if ( proceed ) {
2006-01-06 01:34:10 +00:00
switch_core_standard_on_loopback ( session ) ;
}
}
break ;
2006-01-20 15:05:05 +00:00
case CS_TRANSMIT : /* send/recieve data to/from another channel */
2006-04-26 23:09:48 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " (%s) State TRANSMIT \n " , switch_channel_get_name ( session - > channel ) ) ;
2006-02-07 20:47:15 +00:00
if ( ! driver_state_handler - > on_transmit | |
( driver_state_handler - > on_transmit & &
driver_state_handler - > on_transmit ( session ) = = SWITCH_STATUS_SUCCESS & &
2006-01-06 01:34:10 +00:00
midstate = = switch_channel_get_state ( session - > channel ) ) ) {
2006-02-07 20:47:15 +00:00
2006-02-20 00:23:25 +00:00
while ( ( application_state_handler = switch_channel_get_state_handler ( session - > channel , index + + ) ) ! = 0 ) {
2006-02-07 20:47:15 +00:00
if ( ! application_state_handler | | ! application_state_handler - > on_transmit | |
( application_state_handler - > on_transmit & &
application_state_handler - > on_transmit ( session ) = = SWITCH_STATUS_SUCCESS & &
midstate = = switch_channel_get_state ( session - > channel ) ) ) {
proceed + + ;
continue ;
} else {
proceed = 0 ;
break ;
}
}
index = 0 ;
2006-02-20 00:23:25 +00:00
while ( proceed & & ( application_state_handler = switch_core_get_state_handler ( index + + ) ) ! = 0 ) {
2006-02-07 20:47:15 +00:00
if ( ! application_state_handler | | ! application_state_handler - > on_transmit | |
( application_state_handler - > on_transmit & &
application_state_handler - > on_transmit ( session ) = = SWITCH_STATUS_SUCCESS & &
midstate = = switch_channel_get_state ( session - > channel ) ) ) {
proceed + + ;
continue ;
} else {
proceed = 0 ;
break ;
}
}
if ( proceed ) {
2006-01-06 01:34:10 +00:00
switch_core_standard_on_transmit ( session ) ;
}
}
break ;
2006-04-28 19:46:57 +00:00
case CS_HOLD : /* wait in limbo */
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " (%s) State HOLD \n " , switch_channel_get_name ( session - > channel ) ) ;
if ( ! driver_state_handler - > on_hold | |
( driver_state_handler - > on_hold & &
driver_state_handler - > on_hold ( session ) = = SWITCH_STATUS_SUCCESS & &
midstate = = switch_channel_get_state ( session - > channel ) ) ) {
while ( ( application_state_handler = switch_channel_get_state_handler ( session - > channel , index + + ) ) ! = 0 ) {
if ( ! application_state_handler | | ! application_state_handler - > on_hold | |
( application_state_handler - > on_hold & &
application_state_handler - > on_hold ( session ) = = SWITCH_STATUS_SUCCESS & &
midstate = = switch_channel_get_state ( session - > channel ) ) ) {
proceed + + ;
continue ;
} else {
proceed = 0 ;
break ;
}
}
index = 0 ;
while ( proceed & & ( application_state_handler = switch_core_get_state_handler ( index + + ) ) ! = 0 ) {
if ( ! application_state_handler | | ! application_state_handler - > on_hold | |
( application_state_handler - > on_hold & &
application_state_handler - > on_hold ( session ) = = SWITCH_STATUS_SUCCESS & &
midstate = = switch_channel_get_state ( session - > channel ) ) ) {
proceed + + ;
continue ;
} else {
proceed = 0 ;
break ;
}
}
if ( proceed ) {
switch_core_standard_on_hold ( session ) ;
}
}
break ;
2005-11-19 20:07:43 +00:00
}
2006-02-13 17:37:10 +00:00
if ( midstate = = CS_DONE ) {
break ;
}
2005-11-19 20:07:43 +00:00
laststate = midstate ;
}
2006-02-13 17:37:10 +00:00
2005-11-19 20:07:43 +00:00
if ( state < CS_DONE & & midstate = = switch_channel_get_state ( session - > channel ) ) {
switch_thread_cond_wait ( session - > cond , session - > mutex ) ;
2006-02-13 17:37:10 +00:00
}
2005-11-19 20:07:43 +00:00
}
2006-05-05 13:35:33 +00:00
# ifdef CRASH_PROT
2006-04-27 21:09:58 +00:00
apr_hash_set ( runtime . stack_table , & thread_id , sizeof ( thread_id ) , NULL ) ;
2006-05-05 13:35:33 +00:00
# endif
2006-03-01 22:55:28 +00:00
session - > thread_running = 0 ;
2005-11-19 20:07:43 +00:00
}
2006-04-29 06:05:03 +00:00
SWITCH_DECLARE ( void ) switch_core_session_destroy ( switch_core_session_t * * session )
2005-11-19 20:07:43 +00:00
{
2006-04-29 01:00:52 +00:00
switch_memory_pool_t * pool ;
switch_event_t * event ;
2006-04-25 23:11:56 +00:00
2006-04-26 23:09:48 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_NOTICE , " Close Channel %s \n " , switch_channel_get_name ( ( * session ) - > channel ) ) ;
2006-04-25 23:11:56 +00:00
if ( switch_event_create ( & event , SWITCH_EVENT_CHANNEL_DESTROY ) = = SWITCH_STATUS_SUCCESS ) {
2006-04-26 17:18:33 +00:00
switch_channel_event_set_data ( ( * session ) - > channel , event ) ;
2006-04-25 23:11:56 +00:00
switch_event_fire ( & event ) ;
}
2005-11-19 20:07:43 +00:00
pool = ( * session ) - > pool ;
* session = NULL ;
apr_pool_destroy ( pool ) ;
pool = NULL ;
2006-07-07 18:59:14 +00:00
switch_mutex_lock ( runtime . session_table_mutex ) ;
runtime . session_count - - ;
switch_mutex_unlock ( runtime . session_table_mutex ) ;
2005-11-19 20:07:43 +00:00
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_hash_init ( switch_hash_t * * hash , switch_memory_pool_t * pool )
2005-11-19 20:07:43 +00:00
{
2006-03-29 19:11:20 +00:00
assert ( pool ! = NULL ) ;
2006-02-20 00:23:25 +00:00
if ( ( * hash = apr_hash_make ( pool ) ) ! = 0 ) {
2005-11-19 20:07:43 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2006-03-29 19:11:20 +00:00
2005-11-19 20:07:43 +00:00
return SWITCH_STATUS_GENERR ;
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_hash_destroy ( switch_hash_t * hash )
2005-11-19 20:07:43 +00:00
{
2006-03-30 23:02:50 +00:00
assert ( hash ! = NULL ) ;
2005-11-19 20:07:43 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_hash_insert_dup ( switch_hash_t * hash , char * key , void * data )
2005-12-14 22:46:09 +00:00
{
apr_hash_set ( hash , switch_core_strdup ( apr_hash_pool_get ( hash ) , key ) , APR_HASH_KEY_STRING , data ) ;
return SWITCH_STATUS_SUCCESS ;
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_hash_insert ( switch_hash_t * hash , char * key , void * data )
2005-11-19 20:07:43 +00:00
{
apr_hash_set ( hash , key , APR_HASH_KEY_STRING , data ) ;
return SWITCH_STATUS_SUCCESS ;
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_hash_delete ( switch_hash_t * hash , char * key )
2005-11-19 20:07:43 +00:00
{
apr_hash_set ( hash , key , APR_HASH_KEY_STRING , NULL ) ;
return SWITCH_STATUS_SUCCESS ;
}
2006-04-29 01:00:52 +00:00
SWITCH_DECLARE ( void * ) switch_core_hash_find ( switch_hash_t * hash , char * key )
2005-11-19 20:07:43 +00:00
{
return apr_hash_get ( hash , key , APR_HASH_KEY_STRING ) ;
}
/* This function abstracts the thread creation for modules by allowing you to pass a function ptr and
2006-01-06 01:34:10 +00:00
a void object and trust that that the function will be run in a thread with arg This lets
you request and activate a thread without giving up any knowledge about what is in the thread
neither the core nor the calling module know anything about each other .
2005-11-19 20:07:43 +00:00
2006-01-06 01:34:10 +00:00
This thread is expected to never exit until the application exits so the func is responsible
to make sure that is the case .
2005-11-19 20:07:43 +00:00
2006-01-06 01:34:10 +00:00
The typical use for this is so switch_loadable_module . c can start up a thread for each module
passing the table of module methods as a session obj into the core without actually allowing
the core to have any clue and keeping switch_loadable_module . c from needing any thread code .
2005-11-19 20:07:43 +00:00
*/
2006-04-29 01:00:52 +00:00
SWITCH_DECLARE ( void ) switch_core_launch_thread ( switch_thread_start_t func , void * obj , switch_memory_pool_t * pool )
2005-11-19 20:07:43 +00:00
{
2006-04-29 01:00:52 +00:00
switch_thread_t * thread ;
2006-01-04 01:04:33 +00:00
switch_threadattr_t * thd_attr = NULL ;
2006-04-29 06:05:03 +00:00
switch_core_thread_session_t * ts ;
2006-01-04 01:04:33 +00:00
int mypool ;
2005-11-19 20:07:43 +00:00
2006-01-04 01:04:33 +00:00
mypool = pool ? 0 : 1 ;
2005-12-22 22:17:25 +00:00
2006-01-04 01:04:33 +00:00
if ( ! pool & & switch_core_new_memory_pool ( & pool ) ! = SWITCH_STATUS_SUCCESS ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Could not allocate memory pool \n " ) ;
2006-01-03 01:17:59 +00:00
return ;
}
2006-01-04 01:04:33 +00:00
switch_threadattr_create ( & thd_attr , pool ) ;
switch_threadattr_detach_set ( thd_attr , 1 ) ;
2006-02-20 00:23:25 +00:00
if ( ( ts = switch_core_alloc ( pool , sizeof ( * ts ) ) ) = = 0 ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Could not allocate memory \n " ) ;
2005-12-22 18:53:33 +00:00
} else {
2006-01-04 01:04:33 +00:00
if ( mypool ) {
ts - > pool = pool ;
}
2005-12-22 18:53:33 +00:00
ts - > objs [ 0 ] = obj ;
2006-03-29 21:27:35 +00:00
switch_threadattr_stacksize_set ( thd_attr , SWITCH_THREAD_STACKSIZE ) ;
2006-01-20 15:05:05 +00:00
switch_thread_create ( & thread , thd_attr , func , ts , pool ) ;
2005-12-22 18:53:33 +00:00
}
2005-11-19 20:07:43 +00:00
}
2006-04-29 01:00:52 +00:00
static void * SWITCH_THREAD_FUNC switch_core_session_thread ( switch_thread_t * thread , void * obj )
2005-11-19 20:07:43 +00:00
{
2006-04-29 06:05:03 +00:00
switch_core_session_t * session = obj ;
2005-11-19 20:07:43 +00:00
session - > thread = thread ;
2006-03-30 23:02:50 +00:00
snprintf ( session - > name , sizeof ( session - > name ) , " %u " , session - > id ) ;
2006-07-07 18:59:14 +00:00
switch_mutex_lock ( runtime . session_table_mutex ) ;
session - > id = runtime . session_id + + ;
2006-01-09 19:48:20 +00:00
switch_core_hash_insert ( runtime . session_table , session - > uuid_str , session ) ;
2006-07-07 18:59:14 +00:00
switch_mutex_unlock ( runtime . session_table_mutex ) ;
2005-11-19 20:07:43 +00:00
switch_core_session_run ( session ) ;
2006-04-28 19:46:57 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Session %u (%s) Locked, Waiting on external entities \n " , session - > id , switch_channel_get_name ( session - > channel ) ) ;
switch_core_session_write_lock ( session ) ;
switch_core_session_rwunlock ( session ) ;
2006-04-25 18:02:12 +00:00
2006-07-07 18:59:14 +00:00
switch_mutex_lock ( runtime . session_table_mutex ) ;
2006-01-09 19:48:20 +00:00
switch_core_hash_delete ( runtime . session_table , session - > uuid_str ) ;
2006-07-07 18:59:14 +00:00
switch_mutex_unlock ( runtime . session_table_mutex ) ;
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_INFO , " Session %u (%s) Ended \n " , session - > id , switch_channel_get_name ( session - > channel ) ) ;
2005-11-19 20:07:43 +00:00
switch_core_session_destroy ( & session ) ;
return NULL ;
}
2006-04-29 06:05:03 +00:00
SWITCH_DECLARE ( void ) switch_core_session_thread_launch ( switch_core_session_t * session )
2005-11-19 20:07:43 +00:00
{
2006-04-29 01:00:52 +00:00
switch_thread_t * thread ;
2005-12-14 20:22:19 +00:00
switch_threadattr_t * thd_attr ; ;
switch_threadattr_create ( & thd_attr , session - > pool ) ;
switch_threadattr_detach_set ( thd_attr , 1 ) ;
2005-11-19 20:07:43 +00:00
2006-03-01 22:55:28 +00:00
if ( ! session - > thread_running ) {
2006-03-29 21:27:35 +00:00
switch_threadattr_stacksize_set ( thd_attr , SWITCH_THREAD_STACKSIZE ) ;
2006-03-01 22:55:28 +00:00
if ( switch_thread_create ( & thread , thd_attr , switch_core_session_thread , session , session - > pool ) ! = SWITCH_STATUS_SUCCESS ) {
switch_core_session_destroy ( & session ) ;
}
2005-11-19 20:07:43 +00:00
}
}
2006-04-29 06:05:03 +00:00
SWITCH_DECLARE ( void ) switch_core_session_launch_thread ( switch_core_session_t * session , switch_thread_start_t func ,
2006-01-20 15:05:05 +00:00
void * obj )
2005-11-19 20:07:43 +00:00
{
2006-04-29 01:00:52 +00:00
switch_thread_t * thread ;
2006-01-13 02:05:39 +00:00
switch_threadattr_t * thd_attr = NULL ;
2005-12-14 20:22:19 +00:00
switch_threadattr_create ( & thd_attr , session - > pool ) ;
switch_threadattr_detach_set ( thd_attr , 1 ) ;
2005-11-19 20:07:43 +00:00
2006-03-29 21:27:35 +00:00
switch_threadattr_stacksize_set ( thd_attr , SWITCH_THREAD_STACKSIZE ) ;
2006-01-20 15:05:05 +00:00
switch_thread_create ( & thread , thd_attr , func , obj , session - > pool ) ;
2005-11-19 20:07:43 +00:00
}
2006-04-29 01:00:52 +00:00
SWITCH_DECLARE ( void * ) switch_core_alloc ( switch_memory_pool_t * pool , switch_size_t memory )
2005-11-19 20:07:43 +00:00
{
void * ptr = NULL ;
assert ( pool ! = NULL ) ;
2006-03-27 17:42:59 +00:00
# ifdef DEBUG_ALLOC
2006-04-11 21:13:44 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Allocate %d \n " , memory ) ;
2006-03-29 19:11:20 +00:00
//assert(memory < 600000);
2006-03-27 17:42:59 +00:00
# endif
2005-11-19 20:07:43 +00:00
2006-02-20 00:23:25 +00:00
if ( ( ptr = apr_palloc ( pool , memory ) ) ! = 0 ) {
2005-11-19 20:07:43 +00:00
memset ( ptr , 0 , memory ) ;
}
return ptr ;
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_core_session_t * ) switch_core_session_request ( const switch_endpoint_interface_t * endpoint_interface ,
2006-04-29 01:00:52 +00:00
switch_memory_pool_t * pool )
2005-11-19 20:07:43 +00:00
{
2006-04-29 01:00:52 +00:00
switch_memory_pool_t * usepool ;
2006-04-29 06:05:03 +00:00
switch_core_session_t * session ;
2005-12-22 01:57:32 +00:00
switch_uuid_t uuid ;
2006-07-07 18:59:14 +00:00
uint32_t count = 0 ;
2005-11-19 20:07:43 +00:00
assert ( endpoint_interface ! = NULL ) ;
2006-07-07 18:59:14 +00:00
switch_mutex_lock ( runtime . session_table_mutex ) ;
count = runtime . session_count ;
switch_mutex_unlock ( runtime . session_table_mutex ) ;
if ( ( count + 1 ) > runtime . session_limit ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Over Session Limit! \n " ) ;
return NULL ;
}
2005-11-19 20:07:43 +00:00
if ( pool ) {
usepool = pool ;
} else if ( switch_core_new_memory_pool ( & usepool ) ! = SWITCH_STATUS_SUCCESS ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Could not allocate memory pool \n " ) ;
2005-11-19 20:07:43 +00:00
return NULL ;
}
2006-04-29 06:05:03 +00:00
if ( ( session = switch_core_alloc ( usepool , sizeof ( switch_core_session_t ) ) ) = = 0 ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Could not allocate session \n " ) ;
2005-11-19 20:07:43 +00:00
apr_pool_destroy ( usepool ) ;
return NULL ;
}
if ( switch_channel_alloc ( & session - > channel , usepool ) ! = SWITCH_STATUS_SUCCESS ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Could not allocate channel structure \n " ) ;
2005-11-19 20:07:43 +00:00
apr_pool_destroy ( usepool ) ;
return NULL ;
}
2006-04-06 19:50:53 +00:00
switch_channel_init ( session - > channel , session , CS_NEW , 0 ) ;
2005-11-19 20:07:43 +00:00
/* The session *IS* the pool you may not alter it because you have no idea how
2006-01-06 01:34:10 +00:00
its all private it will be passed to the thread run function */
2005-11-19 20:07:43 +00:00
2005-12-22 01:57:32 +00:00
switch_uuid_get ( & uuid ) ;
switch_uuid_format ( session - > uuid_str , & uuid ) ;
2005-11-19 20:07:43 +00:00
session - > pool = usepool ;
session - > endpoint_interface = endpoint_interface ;
session - > raw_write_frame . data = session - > raw_write_buf ;
2005-12-12 17:50:07 +00:00
session - > raw_write_frame . buflen = sizeof ( session - > raw_write_buf ) ;
2005-11-19 20:07:43 +00:00
session - > raw_read_frame . data = session - > raw_read_buf ;
2005-12-12 17:50:07 +00:00
session - > raw_read_frame . buflen = sizeof ( session - > raw_read_buf ) ;
2006-01-03 01:17:59 +00:00
2005-11-19 20:07:43 +00:00
session - > enc_write_frame . data = session - > enc_write_buf ;
2005-12-12 17:50:07 +00:00
session - > enc_write_frame . buflen = sizeof ( session - > enc_write_buf ) ;
2005-11-19 20:07:43 +00:00
session - > enc_read_frame . data = session - > enc_read_buf ;
2005-12-12 17:50:07 +00:00
session - > enc_read_frame . buflen = sizeof ( session - > enc_read_buf ) ;
2005-11-19 20:07:43 +00:00
2006-01-20 15:05:05 +00:00
switch_mutex_init ( & session - > mutex , SWITCH_MUTEX_NESTED , session - > pool ) ;
2005-11-19 20:07:43 +00:00
switch_thread_cond_create ( & session - > cond , session - > pool ) ;
2006-04-28 19:46:57 +00:00
switch_thread_rwlock_create ( & session - > rwlock , session - > pool ) ;
2006-01-03 01:17:59 +00:00
2006-07-07 18:59:14 +00:00
switch_mutex_lock ( runtime . session_table_mutex ) ;
runtime . session_count + + ;
switch_mutex_unlock ( runtime . session_table_mutex ) ;
2005-11-19 20:07:43 +00:00
return session ;
}
2006-04-29 06:05:03 +00:00
SWITCH_DECLARE ( switch_core_session_t * ) switch_core_session_request_by_name ( char * endpoint_name , switch_memory_pool_t * pool )
2005-11-19 20:07:43 +00:00
{
2006-04-29 23:43:28 +00:00
const switch_endpoint_interface_t * endpoint_interface ;
2005-11-19 20:07:43 +00:00
2006-02-20 00:23:25 +00:00
if ( ( endpoint_interface = switch_loadable_module_get_endpoint_interface ( endpoint_name ) ) = = 0 ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Could not locate channel type %s \n " , endpoint_name ) ;
2005-11-19 20:07:43 +00:00
return NULL ;
}
return switch_core_session_request ( endpoint_interface , pool ) ;
}
2006-05-11 21:11:20 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_db_persistant_execute ( switch_core_db_t * db , char * sql , uint32_t retries )
2005-12-21 22:25:22 +00:00
{
2006-04-04 21:26:21 +00:00
char * errmsg ;
2006-04-29 23:43:28 +00:00
switch_status_t status = SWITCH_STATUS_FALSE ;
2006-04-26 17:18:33 +00:00
while ( retries > 0 ) {
switch_core_db_exec (
db ,
sql ,
NULL ,
NULL ,
& errmsg
) ;
if ( errmsg ) {
2006-05-11 21:11:20 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " SQL ERR \n [%s] \n [%s] \n " , sql , errmsg ) ;
2006-04-26 17:18:33 +00:00
switch_core_db_free ( errmsg ) ;
switch_yield ( 100000 ) ;
retries - - ;
} else {
status = SWITCH_STATUS_SUCCESS ;
break ;
}
}
return status ;
}
2006-04-04 21:26:21 +00:00
2006-04-29 01:00:52 +00:00
static void * SWITCH_THREAD_FUNC switch_core_sql_thread ( switch_thread_t * thread , void * obj )
2006-04-26 17:18:33 +00:00
{
void * pop ;
uint32_t itterations = 0 ;
uint8_t trans = 0 ;
switch_time_t last_commit = switch_time_now ( ) ;
2006-07-19 01:19:46 +00:00
uint32_t freq = 1000 , target = 1000 , diff = 0 ;
2006-04-26 17:18:33 +00:00
2006-05-12 15:33:49 +00:00
if ( ! runtime . event_db ) {
runtime . event_db = switch_core_db_handle ( ) ;
}
2006-04-26 19:11:49 +00:00
switch_queue_create ( & runtime . sql_queue , SWITCH_SQL_QUEUE_LEN , runtime . memory_pool ) ;
2006-04-26 17:18:33 +00:00
for ( ; ; ) {
2006-04-26 19:29:56 +00:00
uint32_t work = 0 ;
2006-04-26 17:18:33 +00:00
if ( switch_queue_trypop ( runtime . sql_queue , & pop ) = = SWITCH_STATUS_SUCCESS ) {
char * sql = ( char * ) pop ;
if ( sql ) {
work + + ;
if ( itterations = = 0 ) {
char * isql = " begin transaction CORE1; " ;
2006-05-11 21:11:20 +00:00
if ( switch_core_db_persistant_execute ( runtime . event_db , isql , 25 ) ! = SWITCH_STATUS_SUCCESS ) {
2006-04-26 17:18:33 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " SQL exec error! [%s] \n " , isql ) ;
} else {
trans = 1 ;
}
}
itterations + + ;
2006-05-11 21:11:20 +00:00
if ( switch_core_db_persistant_execute ( runtime . event_db , sql , 25 ) ! = SWITCH_STATUS_SUCCESS ) {
2006-04-26 17:18:33 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " SQL exec error! [%s] \n " , sql ) ;
}
2006-07-13 01:06:06 +00:00
switch_core_db_free ( sql ) ;
2006-04-26 17:18:33 +00:00
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_NOTICE , " SQL thread ending \n " ) ;
break ;
}
}
if ( diff < freq ) {
2006-04-26 18:37:03 +00:00
diff = ( uint32_t ) ( ( switch_time_now ( ) - last_commit ) / 1000 ) ;
2006-04-26 17:18:33 +00:00
}
if ( trans & & ( itterations = = target | | diff > = freq ) ) {
char * sql = " end transaction CORE1 " ;
work + + ;
2006-05-11 21:11:20 +00:00
if ( switch_core_db_persistant_execute ( runtime . event_db , sql , 25 ) ! = SWITCH_STATUS_SUCCESS ) {
2006-04-26 17:18:33 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " SQL exec error! [%s] \n " , sql ) ;
}
last_commit = switch_time_now ( ) ;
itterations = 0 ;
trans = 0 ;
diff = 0 ;
}
if ( ! work ) {
switch_yield ( 1000 ) ;
}
}
return NULL ;
}
static void switch_core_sql_thread_launch ( void )
{
2006-04-29 01:00:52 +00:00
switch_thread_t * thread ;
2006-04-26 17:18:33 +00:00
switch_threadattr_t * thd_attr ; ;
assert ( runtime . memory_pool ! = NULL ) ;
switch_threadattr_create ( & thd_attr , runtime . memory_pool ) ;
switch_threadattr_detach_set ( thd_attr , 1 ) ;
switch_threadattr_stacksize_set ( thd_attr , SWITCH_THREAD_STACKSIZE ) ;
switch_thread_create ( & thread , thd_attr , switch_core_sql_thread , NULL , runtime . memory_pool ) ;
}
2006-04-29 01:00:52 +00:00
static void core_event_handler ( switch_event_t * event )
2006-04-26 17:18:33 +00:00
{
char * sql = NULL ;
2006-01-20 15:05:05 +00:00
switch ( event - > event_id ) {
2006-04-25 23:11:56 +00:00
case SWITCH_EVENT_CHANNEL_DESTROY :
2006-07-19 01:19:46 +00:00
sql = switch_core_db_mprintf ( " delete from channels where uuid='%s' " , switch_event_get_header ( event , " unique-id " ) ) ;
2006-04-25 23:11:56 +00:00
break ;
2006-04-04 21:26:21 +00:00
case SWITCH_EVENT_CHANNEL_CREATE :
2006-07-13 01:06:06 +00:00
sql = switch_core_db_mprintf ( " insert into channels (uuid,created,name,state) values('%q','%q','%q','%q') " ,
switch_event_get_header ( event , " unique-id " ) ,
switch_event_get_header ( event , " event-date-local " ) ,
switch_event_get_header ( event , " channel-name " ) ,
switch_event_get_header ( event , " channel-state " )
) ;
2006-04-04 21:26:21 +00:00
break ;
2006-04-11 14:55:14 +00:00
case SWITCH_EVENT_CHANNEL_EXECUTE :
2006-07-20 03:55:07 +00:00
sql = switch_core_db_mprintf ( " update channels set application='%q',application_data='%q', read_codec='%q',read_rate='%q',write_codec='%q',write_rate='%q' where uuid='%q' " ,
2006-07-13 01:06:06 +00:00
switch_event_get_header ( event , " application " ) ,
switch_event_get_header ( event , " application-data " ) ,
2006-07-20 03:55:07 +00:00
switch_event_get_header ( event , " channel-read-codec-name " ) ,
switch_event_get_header ( event , " channel-read-codec-rate " ) ,
switch_event_get_header ( event , " channel-write-codec-name " ) ,
switch_event_get_header ( event , " channel-write-codec-rate " ) ,
2006-07-13 01:06:06 +00:00
switch_event_get_header ( event , " unique-id " )
) ;
2006-04-04 21:26:21 +00:00
break ;
case SWITCH_EVENT_CHANNEL_STATE :
if ( event ) {
char * state = switch_event_get_header ( event , " channel-state-number " ) ;
2006-04-29 23:43:28 +00:00
switch_channel_state_t state_i = atoi ( state ) ;
2006-04-04 21:26:21 +00:00
switch ( state_i ) {
case CS_HANGUP :
2006-04-25 23:11:56 +00:00
case CS_DONE :
2006-04-04 21:26:21 +00:00
break ;
case CS_RING :
2006-07-13 01:06:06 +00:00
sql = switch_core_db_mprintf ( " update channels set state='%s',cid_name='%q',cid_num='%q',ip_addr='%s',dest='%q' "
" where uuid='%s' " ,
switch_event_get_header ( event , " channel-state " ) ,
switch_event_get_header ( event , " caller-caller-id-name " ) ,
switch_event_get_header ( event , " caller-caller-id-number " ) ,
switch_event_get_header ( event , " caller-network-addr " ) ,
switch_event_get_header ( event , " caller-destination-number " ) ,
switch_event_get_header ( event , " unique-id " )
) ;
2006-04-04 21:26:21 +00:00
break ;
default :
2006-07-13 01:06:06 +00:00
sql = switch_core_db_mprintf ( " update channels set state='%s' where uuid='%s' " ,
switch_event_get_header ( event , " channel-state " ) ,
switch_event_get_header ( event , " unique-id " )
) ;
2006-04-04 21:26:21 +00:00
break ;
}
}
break ;
2006-04-11 14:55:14 +00:00
case SWITCH_EVENT_CHANNEL_BRIDGE :
2006-07-13 01:06:06 +00:00
sql = switch_core_db_mprintf ( " insert into calls values ('%s','%q','%q','%q','%q','%s','%q','%q','%q','%q','%s') " ,
switch_event_get_header ( event , " event-calling-function " ) ,
switch_event_get_header ( event , " caller-caller-id-name " ) ,
switch_event_get_header ( event , " caller-caller-id-number " ) ,
switch_event_get_header ( event , " caller-destination-number " ) ,
switch_event_get_header ( event , " caller-channel-name " ) ,
switch_event_get_header ( event , " caller-unique-id " ) ,
switch_event_get_header ( event , " originatee-caller-id-name " ) ,
switch_event_get_header ( event , " originatee-caller-id-number " ) ,
switch_event_get_header ( event , " originatee-destination-number " ) ,
switch_event_get_header ( event , " originatee-channel-name " ) ,
switch_event_get_header ( event , " originatee-unique-id " )
) ;
2006-04-11 14:55:14 +00:00
break ;
case SWITCH_EVENT_CHANNEL_UNBRIDGE :
2006-07-13 01:06:06 +00:00
sql = switch_core_db_mprintf ( " delete from calls where caller_uuid='%s' " , switch_event_get_header ( event , " caller-unique-id " ) ) ;
2006-04-11 14:55:14 +00:00
break ;
2006-04-04 21:26:21 +00:00
case SWITCH_EVENT_SHUTDOWN :
2006-07-13 01:06:06 +00:00
sql = switch_core_db_mprintf ( " delete from channels;delete from interfaces;delete from calls " ) ;
2006-04-04 21:26:21 +00:00
break ;
2006-01-06 01:34:10 +00:00
case SWITCH_EVENT_LOG :
return ;
2006-05-01 19:44:21 +00:00
case SWITCH_EVENT_MODULE_LOAD :
2006-07-13 01:06:06 +00:00
sql = switch_core_db_mprintf ( " insert into interfaces (type,name) values('%q','%q') " ,
switch_event_get_header ( event , " type " ) ,
switch_event_get_header ( event , " name " )
) ;
2006-05-01 19:44:21 +00:00
break ;
2006-01-06 01:34:10 +00:00
default :
2006-03-30 23:02:50 +00:00
//buf[0] = '\0';
2006-01-06 01:34:10 +00:00
//switch_event_serialize(event, buf, sizeof(buf), NULL);
2006-04-26 17:18:33 +00:00
//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "\nCORE EVENT\n--------------------------------\n%s\n", buf);
2006-01-06 01:34:10 +00:00
break ;
2005-12-21 22:25:22 +00:00
}
2006-04-04 21:26:21 +00:00
if ( sql ) {
2006-07-13 01:06:06 +00:00
switch_queue_push ( runtime . sql_queue , sql ) ;
sql = NULL ;
2006-04-04 21:26:21 +00:00
}
2005-12-21 22:25:22 +00:00
}
2006-03-01 17:06:10 +00:00
SWITCH_DECLARE ( void ) switch_core_set_globals ( void )
2005-11-19 20:07:43 +00:00
{
2006-03-01 06:25:56 +00:00
# ifdef WIN32
# define BUFSIZE 50
char lpPathBuffer [ BUFSIZE ] ;
DWORD dwBufSize = BUFSIZE ;
# endif
2006-02-28 21:21:48 +00:00
SWITCH_GLOBAL_dirs . base_dir = SWITCH_PREFIX_DIR ;
SWITCH_GLOBAL_dirs . mod_dir = SWITCH_MOD_DIR ;
SWITCH_GLOBAL_dirs . conf_dir = SWITCH_CONF_DIR ;
SWITCH_GLOBAL_dirs . log_dir = SWITCH_LOG_DIR ;
SWITCH_GLOBAL_dirs . db_dir = SWITCH_DB_DIR ;
SWITCH_GLOBAL_dirs . script_dir = SWITCH_SCRIPT_DIR ;
2006-05-10 03:23:05 +00:00
SWITCH_GLOBAL_dirs . htdocs_dir = SWITCH_HTDOCS_DIR ;
2006-03-01 06:25:56 +00:00
# ifdef SWITCH_TEMP_DIR
SWITCH_GLOBAL_dirs . temp_dir = SWITCH_TEMP_DIR ;
# else
# ifdef WIN32
GetTempPath ( dwBufSize , lpPathBuffer ) ;
SWITCH_GLOBAL_dirs . temp_dir = lpPathBuffer ;
# else
SWITCH_GLOBAL_dirs . temp_dir = " /tmp/ " ;
# endif
# endif
2006-03-01 17:06:10 +00:00
}
2006-07-07 18:59:14 +00:00
2006-07-19 18:34:28 +00:00
SWITCH_DECLARE ( uint32_t ) switch_core_session_limit ( uint32_t new_limit )
2006-07-07 18:59:14 +00:00
{
2006-07-19 18:34:28 +00:00
if ( new_limit ) {
runtime . session_limit = new_limit ;
2006-07-07 18:59:14 +00:00
}
return runtime . session_limit ;
}
2006-06-05 18:36:02 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_init ( char * console , const char * * err )
2006-03-01 17:06:10 +00:00
{
2006-07-11 20:59:07 +00:00
switch_xml_t xml = NULL , cfg = NULL ;
2006-03-01 17:06:10 +00:00
memset ( & runtime , 0 , sizeof ( runtime ) ) ;
2006-07-07 18:59:14 +00:00
runtime . session_limit = 1000 ;
2006-03-01 17:06:10 +00:00
switch_core_set_globals ( ) ;
2006-04-11 21:13:44 +00:00
/* INIT APR and Create the pool context */
if ( apr_initialize ( ) ! = SWITCH_STATUS_SUCCESS ) {
apr_terminate ( ) ;
2006-06-05 18:36:02 +00:00
* err = " FATAL ERROR! Could not initilize APR \n " ;
2006-04-11 21:13:44 +00:00
return SWITCH_STATUS_MEMERR ;
}
if ( apr_pool_create ( & runtime . memory_pool , NULL ) ! = SWITCH_STATUS_SUCCESS ) {
2006-05-15 18:16:43 +00:00
apr_terminate ( ) ;
2006-06-05 18:36:02 +00:00
* err = " FATAL ERROR! Could not allocate memory pool \n " ;
2006-04-11 21:13:44 +00:00
return SWITCH_STATUS_MEMERR ;
}
2006-06-05 18:36:02 +00:00
if ( switch_xml_init ( runtime . memory_pool , err ) ! = SWITCH_STATUS_SUCCESS ) {
2006-05-15 18:16:43 +00:00
apr_terminate ( ) ;
2006-05-10 03:23:05 +00:00
return SWITCH_STATUS_MEMERR ;
}
2006-07-07 18:59:14 +00:00
if ( ( xml = switch_xml_open_cfg ( " switch.conf " , & cfg , NULL ) ) ) {
switch_xml_t settings , param ;
if ( ( settings = switch_xml_child ( cfg , " settings " ) ) ) {
for ( param = switch_xml_child ( settings , " param " ) ; param ; param = param - > next ) {
char * var = ( char * ) switch_xml_attr_soft ( param , " name " ) ;
char * val = ( char * ) switch_xml_attr_soft ( param , " value " ) ;
if ( ! strcasecmp ( var , " max-sessions " ) ) {
runtime . session_limit = atoi ( val ) ;
}
}
}
switch_xml_free ( xml ) ;
}
2006-06-05 18:36:02 +00:00
* err = NULL ;
2006-02-26 03:13:01 +00:00
if ( console ) {
2006-03-01 17:06:10 +00:00
if ( * console ! = ' / ' ) {
char path [ 265 ] ;
snprintf ( path , sizeof ( path ) , " %s%s%s " , SWITCH_GLOBAL_dirs . log_dir , SWITCH_PATH_SEPARATOR , console ) ;
console = path ;
}
2006-06-05 18:36:02 +00:00
if ( switch_core_set_console ( console ) ! = SWITCH_STATUS_SUCCESS ) {
* err = " FATAL ERROR! Could not open console \n " ;
apr_terminate ( ) ;
return SWITCH_STATUS_GENERR ;
}
2006-02-26 03:13:01 +00:00
} else {
runtime . console = stdout ;
}
2005-11-19 20:07:43 +00:00
2006-04-26 19:11:49 +00:00
assert ( runtime . memory_pool ! = NULL ) ;
switch_log_init ( runtime . memory_pool ) ;
switch_core_sql_thread_launch ( ) ;
2006-04-11 21:13:44 +00:00
2006-04-29 06:05:03 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Allocated memory pool. Sessions are %u bytes \n " , sizeof ( switch_core_session_t ) ) ;
2005-12-13 19:53:29 +00:00
switch_event_init ( runtime . memory_pool ) ;
2006-04-05 20:17:22 +00:00
switch_rtp_init ( runtime . memory_pool ) ;
2005-12-28 05:17:21 +00:00
2005-12-21 22:25:22 +00:00
/* Activate SQL database */
2006-02-20 00:23:25 +00:00
if ( ( runtime . db = switch_core_db_handle ( ) ) = = 0 ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Error Opening DB! \n " ) ;
2005-12-21 22:25:22 +00:00
} else {
2006-04-11 14:55:14 +00:00
char create_channels_sql [ ] =
" CREATE TABLE channels ( \n "
2006-04-04 21:26:21 +00:00
" uuid VARCHAR(255), \n "
" created VARCHAR(255), \n "
" name VARCHAR(255), \n "
" state VARCHAR(255), \n "
" cid_name VARCHAR(255), \n "
" cid_num VARCHAR(255), \n "
" ip_addr VARCHAR(255), \n "
" dest VARCHAR(255), \n "
" application VARCHAR(255), \n "
2006-07-20 03:55:07 +00:00
" application_data VARCHAR(255), \n "
" read_codec VARCHAR(255), \n "
" read_rate VARCHAR(255), \n "
" write_codec VARCHAR(255), \n "
" write_rate VARCHAR(255) \n "
2006-04-04 21:26:21 +00:00
" ); \n " ;
2006-04-11 14:55:14 +00:00
char create_calls_sql [ ] =
" CREATE TABLE calls ( \n "
" function VARCHAR(255), \n "
" caller_cid_name VARCHAR(255), \n "
" caller_cid_num VARCHAR(255), \n "
" caller_dest_num VARCHAR(255), \n "
" caller_chan_name VARCHAR(255), \n "
" caller_uuid VARCHAR(255), \n "
" callee_cid_name VARCHAR(255), \n "
" callee_cid_num VARCHAR(255), \n "
" callee_dest_num VARCHAR(255), \n "
" callee_chan_name VARCHAR(255), \n "
" callee_uuid VARCHAR(255) \n "
" ); \n " ;
2006-05-01 19:44:21 +00:00
char create_interfaces_sql [ ] =
" CREATE TABLE interfaces ( \n "
" type VARCHAR(255), \n "
" name VARCHAR(255) \n "
" ); \n " ;
2006-04-04 21:26:21 +00:00
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_INFO , " Opening DB \n " ) ;
2006-04-11 14:55:14 +00:00
switch_core_db_exec ( runtime . db , " drop table channels " , NULL , NULL , NULL ) ;
2006-04-04 21:26:21 +00:00
switch_core_db_exec ( runtime . db , " drop table calls " , NULL , NULL , NULL ) ;
2006-05-01 19:44:21 +00:00
switch_core_db_exec ( runtime . db , " drop table interfaces " , NULL , NULL , NULL ) ;
2006-04-11 14:55:14 +00:00
switch_core_db_exec ( runtime . db , create_channels_sql , NULL , NULL , NULL ) ;
2006-04-04 21:26:21 +00:00
switch_core_db_exec ( runtime . db , create_calls_sql , NULL , NULL , NULL ) ;
2006-05-01 19:44:21 +00:00
switch_core_db_exec ( runtime . db , create_interfaces_sql , NULL , NULL , NULL ) ;
2006-04-04 21:26:21 +00:00
2006-01-20 15:05:05 +00:00
if ( switch_event_bind ( " core_db " , SWITCH_EVENT_ALL , SWITCH_EVENT_SUBCLASS_ANY , core_event_handler , NULL ) ! =
SWITCH_STATUS_SUCCESS ) {
2006-04-16 06:05:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Couldn't bind event handler! \n " ) ;
2005-12-21 22:25:22 +00:00
}
}
2005-11-19 20:07:43 +00:00
runtime . session_id = 1 ;
switch_core_hash_init ( & runtime . session_table , runtime . memory_pool ) ;
2006-07-07 18:59:14 +00:00
switch_mutex_init ( & runtime . session_table_mutex , SWITCH_MUTEX_NESTED , runtime . memory_pool ) ;
2006-05-05 13:35:33 +00:00
# ifdef CRASH_PROT
2006-04-27 21:09:58 +00:00
switch_core_hash_init ( & runtime . stack_table , runtime . memory_pool ) ;
2006-05-05 13:35:33 +00:00
# endif
2006-05-10 03:23:05 +00:00
runtime . initiated = switch_time_now ( ) ;
2005-11-19 20:07:43 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2006-05-10 03:23:05 +00:00
SWITCH_DECLARE ( void ) switch_core_measure_time ( switch_time_t total_ms , switch_core_time_duration_t * duration )
{
2006-05-10 04:05:07 +00:00
switch_time_t temp = total_ms / 1000 ;
memset ( duration , 0 , sizeof ( * duration ) ) ;
duration - > mms = ( uint32_t ) ( total_ms % 1000 ) ;
duration - > ms = ( uint32_t ) ( temp % 1000 ) ;
2006-05-10 04:42:31 +00:00
temp = temp / 1000 ;
duration - > sec = ( uint32_t ) ( temp % 60 ) ;
temp = temp / 60 ;
duration - > min = ( uint32_t ) ( temp % 60 ) ;
temp = temp / 60 ;
duration - > hr = ( uint32_t ) ( temp % 24 ) ;
temp = temp / 24 ;
duration - > day = ( uint32_t ) ( temp % 365 ) ;
duration - > yr = ( uint32_t ) ( temp / 365 ) ;
2006-05-10 03:23:05 +00:00
}
SWITCH_DECLARE ( switch_time_t ) switch_core_uptime ( void )
{
return switch_time_now ( ) - runtime . initiated ;
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_core_destroy ( void )
2005-11-19 20:07:43 +00:00
{
2005-12-14 20:22:19 +00:00
2006-04-11 21:13:44 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CONSOLE , " Closing Event Engine. \n " ) ;
2005-12-14 21:29:46 +00:00
switch_event_shutdown ( ) ;
2006-04-11 21:13:44 +00:00
switch_log_shutdown ( ) ;
2005-12-21 22:25:22 +00:00
2006-04-26 17:18:33 +00:00
switch_queue_push ( runtime . sql_queue , NULL ) ;
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CONSOLE , " Waiting for unfinished SQL transactions \n " ) ;
while ( switch_queue_size ( runtime . sql_queue ) > 0 ) {
switch_yield ( 1000 ) ;
}
2005-12-21 22:25:22 +00:00
switch_core_db_close ( runtime . db ) ;
2006-05-12 15:33:49 +00:00
switch_core_db_close ( runtime . event_db ) ;
2006-05-10 03:23:05 +00:00
switch_xml_destroy ( ) ;
2005-12-21 22:25:22 +00:00
2005-12-14 21:29:46 +00:00
if ( runtime . memory_pool ) {
2006-04-11 21:13:44 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CONSOLE , " Unallocating memory pool. \n " ) ;
2005-12-14 21:29:46 +00:00
apr_pool_destroy ( runtime . memory_pool ) ;
apr_terminate ( ) ;
}
2006-02-26 03:13:01 +00:00
if ( runtime . console ! = stdout & & runtime . console ! = stderr ) {
fclose ( runtime . console ) ;
runtime . console = NULL ;
}
2005-12-14 21:29:46 +00:00
2005-11-19 20:07:43 +00:00
return SWITCH_STATUS_SUCCESS ;
}