2006-11-28 02:23:26 +00:00
/*
* FreeSWITCH Modular Media Switching Software Library / Soft - Switch Application
2012-04-18 11:51:48 -05:00
* Copyright ( C ) 2005 - 2012 , Anthony Minessale II < anthm @ freeswitch . org >
2006-11-28 02:23:26 +00:00
*
* Version : MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 ( the " License " ) ; you may not use this file except in compliance with
* the License . You may obtain a copy of the License at
* http : //www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an " AS IS " basis ,
* WITHOUT WARRANTY OF ANY KIND , either express or implied . See the License
* for the specific language governing rights and limitations under the
* License .
*
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft - Switch Application
*
* The Initial Developer of the Original Code is
2009-02-04 21:20:54 +00:00
* Anthony Minessale II < anthm @ freeswitch . org >
2006-11-28 02:23:26 +00:00
* Portions created by the Initial Developer are Copyright ( C )
* the Initial Developer . All Rights Reserved .
*
* Contributor ( s ) :
*
2009-02-04 21:20:54 +00:00
* Anthony Minessale II < anthm @ freeswitch . org >
2012-04-18 11:04:16 -05:00
* Ken Rice < krice @ freeswitch . org >
2006-11-28 02:23:26 +00:00
* Michael Murdock < mike at mmurdock dot org >
2006-12-04 05:50:41 +00:00
* Neal Horman < neal at wanlink dot com >
2007-06-04 22:10:42 +00:00
* Bret McDanel < trixter AT 0xdecafbad dot com >
2010-08-22 18:12:18 -05:00
* Luke Dashjr < luke @ openmethods . com > ( OpenMethods , LLC )
2011-03-29 20:35:34 -05:00
* Cesar Cepeda < cesar @ auronix . com >
2012-06-11 13:05:29 +00:00
* Christopher M . Rienzo < chris @ rienzo . com >
2006-11-28 02:23:26 +00:00
*
* mod_dptools . c - - Raw Audio File Streaming Application Module
*
*/
# include <switch.h>
2007-06-13 16:00:14 +00:00
SWITCH_MODULE_LOAD_FUNCTION ( mod_dptools_load ) ;
2012-05-04 18:59:25 -05:00
SWITCH_MODULE_SHUTDOWN_FUNCTION ( mod_dptools_shutdown ) ;
SWITCH_MODULE_DEFINITION ( mod_dptools , mod_dptools_load , mod_dptools_shutdown , NULL ) ;
2006-11-28 02:23:26 +00:00
2008-04-22 15:18:35 +00:00
SWITCH_STANDARD_DIALPLAN ( inline_dialplan_hunt )
{
switch_caller_extension_t * extension = NULL ;
2009-04-29 01:00:47 +00:00
char * argv [ 128 ] = { 0 } ;
int argc ;
2008-04-22 15:18:35 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
int x = 0 ;
char * lbuf ;
2008-04-26 15:59:42 +00:00
char * target = arg ;
2010-01-27 22:27:26 +00:00
char delim = ' , ' ;
2008-04-22 15:18:35 +00:00
if ( ! caller_profile ) {
caller_profile = switch_channel_get_caller_profile ( channel ) ;
2008-05-27 04:54:52 +00:00
}
2008-04-22 15:18:35 +00:00
if ( ( extension = switch_caller_extension_new ( session , " inline " , " inline " ) ) = = 0 ) {
abort ( ) ;
}
2008-04-26 15:59:42 +00:00
2009-10-23 16:03:42 +00:00
if ( zstr ( target ) ) {
2008-04-26 15:59:42 +00:00
target = caller_profile - > destination_number ;
}
2008-05-27 04:54:52 +00:00
2010-01-27 22:27:26 +00:00
if ( zstr ( target ) ) {
2008-04-22 15:18:35 +00:00
return NULL ;
2010-01-27 22:27:26 +00:00
} else {
lbuf = switch_core_session_strdup ( session , target ) ;
}
if ( * lbuf = = ' m ' & & * ( lbuf + 1 ) = = ' : ' & & * ( lbuf + 3 ) = = ' : ' ) {
delim = * ( lbuf + 2 ) ;
lbuf + = 4 ;
2008-04-22 15:18:35 +00:00
}
2010-01-27 22:27:26 +00:00
argc = switch_separate_string ( lbuf , delim , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ;
2008-05-27 04:54:52 +00:00
for ( x = 0 ; x < argc ; x + + ) {
2008-04-22 15:18:35 +00:00
char * app = argv [ x ] ;
char * data = strchr ( app , ' : ' ) ;
if ( data ) {
* data + + = ' \0 ' ;
}
2008-05-27 04:54:52 +00:00
while ( * app = = ' ' ) {
2008-04-22 15:18:35 +00:00
app + + ;
}
2008-05-27 04:54:52 +00:00
2008-04-22 15:18:35 +00:00
switch_caller_extension_add_application ( session , extension , app , data ) ;
}
2010-02-06 03:38:24 +00:00
caller_profile - > destination_number = ( char * ) caller_profile - > rdnis ;
2009-11-05 02:10:10 +00:00
caller_profile - > rdnis = SWITCH_BLANK_STRING ;
2008-04-22 15:18:35 +00:00
return extension ;
}
2010-10-07 18:30:07 -05:00
struct action_binding {
2010-10-08 13:50:15 -05:00
char * realm ;
2010-10-07 18:30:07 -05:00
char * input ;
char * string ;
char * value ;
2011-09-02 09:34:40 -05:00
switch_digit_action_target_t target ;
2010-10-07 18:30:07 -05:00
switch_core_session_t * session ;
} ;
2010-10-08 13:50:15 -05:00
static switch_status_t digit_nomatch_action_callback ( switch_ivr_dmachine_match_t * match )
{
switch_core_session_t * session = ( switch_core_session_t * ) match - > user_data ;
2011-09-01 10:11:16 -05:00
switch_channel_t * channel ;
2010-10-08 17:45:40 -05:00
switch_event_t * event ;
switch_status_t status ;
2011-09-01 10:11:16 -05:00
switch_core_session_t * use_session = session ;
if ( switch_ivr_dmachine_get_target ( match - > dmachine ) = = DIGIT_TARGET_PEER ) {
if ( switch_core_session_get_partner ( session , & use_session ) ! = SWITCH_STATUS_SUCCESS ) {
use_session = session ;
}
}
channel = switch_core_session_get_channel ( use_session ) ;
2010-10-08 13:50:15 -05:00
2010-10-15 12:55:59 -05:00
switch_channel_set_variable ( channel , " last_non_matching_digits " , match - > match_digits ) ;
2011-09-01 10:11:16 -05:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( use_session ) , SWITCH_LOG_DEBUG , " %s Digit NOT match binding [%s] \n " ,
2010-10-08 13:50:15 -05:00
switch_channel_get_name ( channel ) , match - > match_digits ) ;
2010-10-08 17:45:40 -05:00
if ( switch_event_create_plain ( & event , SWITCH_EVENT_CHANNEL_DATA ) = = SWITCH_STATUS_SUCCESS ) {
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " digits " , match - > match_digits ) ;
2011-09-01 10:11:16 -05:00
if ( ( status = switch_core_session_queue_event ( use_session , & event ) ) ! = SWITCH_STATUS_SUCCESS ) {
2010-10-08 17:45:40 -05:00
switch_event_destroy ( & event ) ;
2011-09-01 10:11:16 -05:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( use_session ) , SWITCH_LOG_WARNING , " %s event queue failure. \n " ,
switch_core_session_get_name ( use_session ) ) ;
2010-10-08 17:45:40 -05:00
}
}
2011-09-13 16:19:00 -05:00
/* send it back around and skip the dmachine */
switch_channel_queue_dtmf_string ( channel , match - > match_digits ) ;
2010-10-08 13:50:15 -05:00
2011-09-01 10:11:16 -05:00
if ( use_session ! = session ) {
switch_core_session_rwunlock ( use_session ) ;
}
2010-10-08 13:50:15 -05:00
return SWITCH_STATUS_SUCCESS ;
}
2010-10-07 18:30:07 -05:00
static switch_status_t digit_action_callback ( switch_ivr_dmachine_match_t * match )
{
struct action_binding * act = ( struct action_binding * ) match - > user_data ;
switch_event_t * event ;
switch_status_t status ;
int exec = 0 ;
2011-12-16 13:46:14 -05:00
int api = 0 ;
2010-10-07 18:30:07 -05:00
char * string = act - > string ;
2011-09-01 10:11:16 -05:00
switch_channel_t * channel ;
switch_core_session_t * use_session = act - > session ;
2011-09-02 09:34:40 -05:00
int x = 0 ;
2011-11-11 20:17:21 -06:00
char * flags = " " ;
2011-09-02 09:34:40 -05:00
if ( switch_ivr_dmachine_get_target ( match - > dmachine ) = = DIGIT_TARGET_PEER | | act - > target = = DIGIT_TARGET_PEER | | act - > target = = DIGIT_TARGET_BOTH ) {
2011-09-01 10:11:16 -05:00
if ( switch_core_session_get_partner ( act - > session , & use_session ) ! = SWITCH_STATUS_SUCCESS ) {
use_session = act - > session ;
}
}
2011-09-02 09:34:40 -05:00
top :
x + + ;
2011-11-11 20:17:21 -06:00
string = switch_core_session_strdup ( use_session , act - > string ) ;
2011-09-02 09:34:40 -05:00
exec = 0 ;
2011-12-16 13:46:14 -05:00
api = 0 ;
2011-09-02 09:34:40 -05:00
2011-09-01 10:11:16 -05:00
channel = switch_core_session_get_channel ( use_session ) ;
2010-10-07 18:30:07 -05:00
2010-10-15 12:55:59 -05:00
switch_channel_set_variable ( channel , " last_matching_digits " , match - > match_digits ) ;
2011-09-01 10:11:16 -05:00
2010-10-15 12:55:59 -05:00
2010-10-07 18:30:07 -05:00
if ( switch_event_create_plain ( & event , SWITCH_EVENT_CHANNEL_DATA ) = = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( act - > session ) , SWITCH_LOG_DEBUG , " %s Digit match binding [%s][%s] \n " ,
switch_channel_get_name ( channel ) , act - > string , act - > value ) ;
2011-11-11 20:17:21 -06:00
if ( ! strncasecmp ( string , " exec " , 4 ) ) {
char * e ;
string + = 4 ;
if ( * string = = ' : ' ) {
string + + ;
exec = 1 ;
} else if ( * string = = ' [ ' ) {
flags = string ;
if ( ( e = switch_find_end_paren ( flags , ' [ ' , ' ] ' ) ) ) {
if ( e & & * + + e = = ' : ' ) {
flags + + ;
* e + + = ' \0 ' ;
string = e ;
exec = strchr ( flags , ' i ' ) ? 2 : 1 ;
}
}
}
2011-12-16 13:46:14 -05:00
} else if ( ! strncasecmp ( string , " api: " , 4 ) ) {
string + = 4 ;
api = 1 ;
2010-10-07 18:30:07 -05:00
}
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , string , act - > value ) ;
2010-10-08 17:45:40 -05:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " digits " , match - > match_digits ) ;
2010-10-07 18:30:07 -05:00
if ( exec ) {
2011-11-11 20:17:21 -06:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " execute " , exec = = 1 ? " non-blocking " : " blocking " ) ;
2011-12-16 13:46:14 -05:00
}
2010-10-07 18:30:07 -05:00
2011-09-01 10:11:16 -05:00
if ( ( status = switch_core_session_queue_event ( use_session , & event ) ) ! = SWITCH_STATUS_SUCCESS ) {
2010-10-07 18:30:07 -05:00
switch_event_destroy ( & event ) ;
2011-12-16 13:46:14 -05:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( use_session ) , SWITCH_LOG_WARNING , " %s event queue failure. \n " ,
2011-09-01 10:11:16 -05:00
switch_core_session_get_name ( use_session ) ) ;
2010-10-07 18:30:07 -05:00
}
}
if ( exec ) {
2011-11-11 20:17:21 -06:00
if ( exec = = 2 ) {
switch_core_session_execute_application ( use_session , string , act - > value ) ;
} else {
char * cmd = switch_core_session_sprintf ( use_session , " %s::%s " , string , act - > value ) ;
switch_media_flag_enum_t exec_flags = SMF_ECHO_ALEG ;
if ( act - > target ! = DIGIT_TARGET_BOTH & & ! strchr ( flags , ' H ' ) ) {
2011-11-14 08:24:08 -06:00
exec_flags | = SMF_HOLD_BLEG ;
2011-11-11 20:17:21 -06:00
}
switch_ivr_broadcast_in_thread ( use_session , cmd , exec_flags ) ;
}
2011-12-16 13:46:14 -05:00
} else if ( api ) {
switch_stream_handle_t stream = { 0 } ;
SWITCH_STANDARD_STREAM ( stream ) ;
switch_api_execute ( string , act - > value , NULL , & stream ) ;
if ( stream . data ) {
switch_channel_set_variable ( channel , " bind_digit_action_api_result " , ( char * ) stream . data ) ;
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( act - > session ) , SWITCH_LOG_DEBUG , " %s Digit match binding [%s][%s] api executed, %s \n " ,
switch_core_session_get_name ( use_session ) , act - > string , act - > value , ( char * ) stream . data ) ;
} else {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( act - > session ) , SWITCH_LOG_DEBUG , " %s Digit match binding [%s][%s] api executed \n " ,
switch_core_session_get_name ( use_session ) , act - > string , act - > value ) ;
}
switch_safe_free ( stream . data ) ;
2010-10-07 18:30:07 -05:00
}
2011-09-01 10:11:16 -05:00
if ( use_session ! = act - > session ) {
switch_core_session_rwunlock ( use_session ) ;
2011-09-02 09:34:40 -05:00
if ( act - > target = = DIGIT_TARGET_BOTH ) {
use_session = act - > session ;
goto top ;
}
}
2011-09-01 10:11:16 -05:00
2010-10-07 18:30:07 -05:00
return SWITCH_STATUS_SUCCESS ;
}
2011-09-02 09:34:40 -05:00
static switch_digit_action_target_t str2target ( const char * target_str )
{
if ( ! strcasecmp ( target_str , " peer " ) ) {
return DIGIT_TARGET_PEER ;
}
if ( ! strcasecmp ( target_str , " both " ) ) {
return DIGIT_TARGET_BOTH ;
}
return DIGIT_TARGET_SELF ;
}
# define CLEAR_DIGIT_ACTION_USAGE "<realm>|all[,target]"
2010-10-07 18:30:07 -05:00
SWITCH_STANDARD_APP ( clear_digit_action_function )
{
//switch_channel_t *channel = switch_core_session_get_channel(session);
switch_ivr_dmachine_t * dmachine ;
2011-09-02 09:34:40 -05:00
char * realm = switch_core_session_strdup ( session , data ) ;
char * target_str ;
switch_digit_action_target_t target = DIGIT_TARGET_SELF ;
2010-10-08 13:50:15 -05:00
2011-09-02 09:50:24 -05:00
if ( ( target_str = strchr ( realm , ' , ' ) ) ) {
2011-09-02 09:34:40 -05:00
* target_str + + = ' \0 ' ;
target = str2target ( target_str ) ;
}
if ( ( dmachine = switch_core_session_get_dmachine ( session , target ) ) ) {
2010-10-08 13:50:15 -05:00
if ( zstr ( realm ) | | ! strcasecmp ( realm , " all " ) ) {
2011-10-06 10:12:36 -05:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_INFO , " Digit parser %s: Clearing all realms \n " , switch_ivr_dmachine_get_name ( dmachine ) ) ;
2011-09-02 09:34:40 -05:00
switch_core_session_set_dmachine ( session , NULL , target ) ;
2010-10-08 13:50:15 -05:00
switch_ivr_dmachine_destroy ( & dmachine ) ;
} else {
switch_ivr_dmachine_clear_realm ( dmachine , realm ) ;
}
}
}
2011-09-02 09:34:40 -05:00
# define DIGIT_ACTION_SET_REALM_USAGE "<realm>[,<target>]"
2010-10-08 13:50:15 -05:00
SWITCH_STANDARD_APP ( digit_action_set_realm_function )
{
switch_ivr_dmachine_t * dmachine ;
2011-09-02 09:34:40 -05:00
char * realm = switch_core_session_strdup ( session , data ) ;
char * target_str ;
switch_digit_action_target_t target = DIGIT_TARGET_SELF ;
2011-09-02 09:50:24 -05:00
if ( ( target_str = strchr ( realm , ' , ' ) ) ) {
2011-09-02 09:34:40 -05:00
* target_str + + = ' \0 ' ;
target = str2target ( target_str ) ;
}
2010-10-08 13:50:15 -05:00
if ( zstr ( data ) ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING , " Syntax Error, USAGE %s \n " , DIGIT_ACTION_SET_REALM_USAGE ) ;
return ;
}
2011-09-02 09:50:24 -05:00
2010-10-07 18:30:07 -05:00
2011-09-02 09:34:40 -05:00
if ( ( dmachine = switch_core_session_get_dmachine ( session , target ) ) ) {
2010-10-08 13:50:15 -05:00
switch_ivr_dmachine_set_realm ( dmachine , realm ) ;
2010-10-07 18:30:07 -05:00
}
2010-10-08 13:50:15 -05:00
2010-10-07 18:30:07 -05:00
}
2011-09-01 10:11:16 -05:00
2011-09-02 09:34:40 -05:00
static void bind_to_session ( switch_core_session_t * session ,
const char * arg0 , const char * arg1 , const char * arg2 , const char * arg3 ,
switch_digit_action_target_t target , switch_digit_action_target_t bind_target )
2011-09-01 10:11:16 -05:00
{
2011-09-02 09:34:40 -05:00
struct action_binding * act ;
2011-09-01 10:11:16 -05:00
switch_ivr_dmachine_t * dmachine ;
2011-09-02 09:34:40 -05:00
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
2011-09-01 10:11:16 -05:00
2011-09-02 09:34:40 -05:00
if ( ! ( dmachine = switch_core_session_get_dmachine ( session , target ) ) ) {
uint32_t digit_timeout = 1500 ;
uint32_t input_timeout = 0 ;
const char * var ;
2011-09-01 10:11:16 -05:00
2011-09-02 09:34:40 -05:00
if ( ( var = switch_channel_get_variable ( channel , " bind_digit_digit_timeout " ) ) ) {
2012-01-08 14:19:16 -06:00
digit_timeout = switch_atoul ( var ) ;
2011-09-01 10:11:16 -05:00
}
2011-09-02 09:34:40 -05:00
if ( ( var = switch_channel_get_variable ( channel , " bind_digit_input_timeout " ) ) ) {
2012-01-08 14:19:16 -06:00
input_timeout = switch_atoul ( var ) ;
2011-09-02 09:34:40 -05:00
}
switch_ivr_dmachine_create ( & dmachine , " DPTOOLS " , NULL , digit_timeout , input_timeout , NULL , digit_nomatch_action_callback , session ) ;
switch_core_session_set_dmachine ( session , dmachine , target ) ;
2011-09-01 10:11:16 -05:00
}
2011-09-02 09:34:40 -05:00
act = switch_core_session_alloc ( session , sizeof ( * act ) ) ;
act - > realm = switch_core_session_strdup ( session , arg0 ) ;
act - > input = switch_core_session_strdup ( session , arg1 ) ;
act - > string = switch_core_session_strdup ( session , arg2 ) ;
act - > value = switch_core_session_strdup ( session , arg3 ) ;
act - > target = bind_target ;
act - > session = session ;
switch_ivr_dmachine_bind ( dmachine , act - > realm , act - > input , 0 , digit_action_callback , act ) ;
2011-09-01 10:11:16 -05:00
}
2011-12-16 13:46:14 -05:00
# define BIND_DIGIT_ACTION_USAGE "<realm>,<digits|~regex>,<string>[,<value>][,<dtmf target leg>][,<event target leg>]"
2010-10-07 18:30:07 -05:00
SWITCH_STANDARD_APP ( bind_digit_action_function )
{
2011-09-02 09:34:40 -05:00
2010-10-07 18:30:07 -05:00
char * mydata ;
int argc = 0 ;
2011-09-02 09:34:40 -05:00
char * argv [ 6 ] = { 0 } ;
switch_digit_action_target_t target , bind_target ;
char * target_str = " self " , * bind_target_str = " self " ;
2011-12-16 13:46:14 -05:00
char * value = " " ;
2010-10-07 18:30:07 -05:00
if ( zstr ( data ) ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING , " Syntax Error, USAGE %s \n " , BIND_DIGIT_ACTION_USAGE ) ;
return ;
}
2010-10-08 13:50:15 -05:00
mydata = switch_core_session_strdup ( session , data ) ;
argc = switch_separate_string ( mydata , ' , ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ;
2011-12-16 13:46:14 -05:00
if ( argc < 3 | | zstr ( argv [ 0 ] ) | | zstr ( argv [ 1 ] ) | | zstr ( argv [ 2 ] ) ) {
2010-10-08 13:50:15 -05:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING , " Syntax Error, USAGE %s \n " , BIND_DIGIT_ACTION_USAGE ) ;
return ;
}
2011-12-16 13:46:14 -05:00
if ( argv [ 3 ] ) {
value = argv [ 3 ] ;
}
2011-09-02 09:34:40 -05:00
if ( argv [ 4 ] ) {
target_str = argv [ 4 ] ;
}
2010-10-07 18:30:07 -05:00
2011-09-02 09:34:40 -05:00
if ( argv [ 5 ] ) {
bind_target_str = argv [ 5 ] ;
2010-10-07 18:30:07 -05:00
}
2011-09-02 09:34:40 -05:00
target = str2target ( target_str ) ;
bind_target = str2target ( bind_target_str ) ;
2011-09-01 10:11:16 -05:00
2010-10-07 18:30:07 -05:00
2011-09-02 09:34:40 -05:00
switch ( target ) {
case DIGIT_TARGET_PEER :
2011-12-16 13:46:14 -05:00
bind_to_session ( session , argv [ 0 ] , argv [ 1 ] , argv [ 2 ] , value , DIGIT_TARGET_PEER , bind_target ) ;
2011-09-02 09:34:40 -05:00
break ;
case DIGIT_TARGET_BOTH :
2011-12-16 13:46:14 -05:00
bind_to_session ( session , argv [ 0 ] , argv [ 1 ] , argv [ 2 ] , value , DIGIT_TARGET_PEER , bind_target ) ;
bind_to_session ( session , argv [ 0 ] , argv [ 1 ] , argv [ 2 ] , value , DIGIT_TARGET_SELF , bind_target ) ;
2011-09-02 09:34:40 -05:00
break ;
default :
2011-12-16 13:46:14 -05:00
bind_to_session ( session , argv [ 0 ] , argv [ 1 ] , argv [ 2 ] , value , DIGIT_TARGET_SELF , bind_target ) ;
2011-09-02 09:34:40 -05:00
break ;
}
}
2010-10-07 18:30:07 -05:00
2010-08-22 20:24:53 -05:00
# define DETECT_SPEECH_SYNTAX "<mod_name> <gram_name> <gram_path> [<addr>] OR grammar <gram_name> [<path>] OR nogrammar <gram_name> OR grammaron / grammaroff <gram_name> OR grammarsalloff OR pause OR resume OR start_input_timers OR stop OR param <name> <value>"
2007-06-20 05:39:50 +00:00
SWITCH_STANDARD_APP ( detect_speech_function )
2006-11-28 02:23:26 +00:00
{
2009-10-04 00:00:30 +00:00
char * argv [ 4 ] ;
int argc ;
2006-11-28 02:23:26 +00:00
char * lbuf = NULL ;
2009-10-23 16:03:42 +00:00
if ( ! zstr ( data ) & & ( lbuf = switch_core_session_strdup ( session , data ) )
2009-10-04 00:00:30 +00:00
& & ( argc = switch_separate_string ( lbuf , ' ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ) ) {
2006-11-28 02:23:26 +00:00
if ( ! strcasecmp ( argv [ 0 ] , " grammar " ) & & argc > = 1 ) {
switch_ivr_detect_speech_load_grammar ( session , argv [ 1 ] , argv [ 2 ] ) ;
} else if ( ! strcasecmp ( argv [ 0 ] , " nogrammar " ) ) {
switch_ivr_detect_speech_unload_grammar ( session , argv [ 1 ] ) ;
2010-08-22 18:12:18 -05:00
} else if ( ! strcasecmp ( argv [ 0 ] , " grammaron " ) ) {
switch_ivr_detect_speech_enable_grammar ( session , argv [ 1 ] ) ;
} else if ( ! strcasecmp ( argv [ 0 ] , " grammaroff " ) ) {
switch_ivr_detect_speech_disable_grammar ( session , argv [ 1 ] ) ;
} else if ( ! strcasecmp ( argv [ 0 ] , " grammarsalloff " ) ) {
switch_ivr_detect_speech_disable_all_grammars ( session ) ;
2006-11-28 02:23:26 +00:00
} else if ( ! strcasecmp ( argv [ 0 ] , " pause " ) ) {
switch_ivr_pause_detect_speech ( session ) ;
} else if ( ! strcasecmp ( argv [ 0 ] , " resume " ) ) {
switch_ivr_resume_detect_speech ( session ) ;
} else if ( ! strcasecmp ( argv [ 0 ] , " stop " ) ) {
switch_ivr_stop_detect_speech ( session ) ;
2010-02-10 15:38:32 +00:00
} else if ( ! strcasecmp ( argv [ 0 ] , " param " ) ) {
switch_ivr_set_param_detect_speech ( session , argv [ 1 ] , argv [ 2 ] ) ;
2010-08-22 18:07:24 -05:00
} else if ( ! strcasecmp ( argv [ 0 ] , " start_input_timers " ) ) {
switch_ivr_detect_speech_start_input_timers ( session ) ;
2006-11-28 02:23:26 +00:00
} else if ( argc > = 3 ) {
switch_ivr_detect_speech ( session , argv [ 0 ] , argv [ 1 ] , argv [ 2 ] , argv [ 3 ] , NULL ) ;
}
} else {
2007-06-20 05:15:07 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Usage: %s \n " , DETECT_SPEECH_SYNTAX ) ;
2006-11-28 02:23:26 +00:00
}
}
2011-11-15 11:28:05 -06:00
# define PLAY_AND_DETECT_SPEECH_SYNTAX "<file> detect:<engine> {param1=val1,param2=val2}<grammar>"
SWITCH_STANDARD_APP ( play_and_detect_speech_function )
{
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
char * argv [ 2 ] ;
char * lbuf = NULL ;
const char * response = " DONE " ;
char * detect = NULL ;
2012-04-25 17:58:41 +00:00
char * s ;
2011-11-15 11:28:05 -06:00
switch_channel_set_variable ( channel , " detect_speech_result " , " " ) ;
if ( zstr ( data ) | | ! ( lbuf = switch_core_session_strdup ( session , data ) ) | | ! ( detect = strstr ( lbuf , " detect: " ) ) ) {
/* bad input */
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Usage: %s \n " , PLAY_AND_DETECT_SPEECH_SYNTAX ) ;
response = " USAGE ERROR " ;
goto done ;
}
2012-04-25 17:58:41 +00:00
/* trim any trailing space */
s = detect ;
while ( - - s > = lbuf & & switch_isspace ( * s ) ) {
* s = ' \0 ' ;
}
2011-11-15 11:28:05 -06:00
/* split input at "detect:" */
detect [ 0 ] = ' \0 ' ;
detect + = 7 ;
if ( zstr ( detect ) ) {
/* bad input */
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Usage: %s \n " , PLAY_AND_DETECT_SPEECH_SYNTAX ) ;
response = " USAGE ERROR " ;
goto done ;
}
/* need to have at 2 parameters for detect */
if ( switch_separate_string ( detect , ' ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) = = 2 ) {
char * file = lbuf ;
char * engine = argv [ 0 ] ;
char * grammar = argv [ 1 ] ;
char * result = NULL ;
2012-01-05 10:38:08 -06:00
switch_ivr_play_and_detect_speech ( session , file , engine , grammar , & result , 0 , NULL ) ;
2011-11-15 11:28:05 -06:00
switch_channel_set_variable ( channel , " detect_speech_result " , result ) ;
} else {
/* bad input */
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Usage: %s \n " , PLAY_AND_DETECT_SPEECH_SYNTAX ) ;
response = " USAGE ERROR " ;
}
done :
switch_channel_set_variable ( channel , SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE , response ) ;
}
2009-03-06 20:16:48 +00:00
# define SCHED_HEARTBEAT_SYNTAX "[0|<seconds>]"
SWITCH_STANDARD_APP ( sched_heartbeat_function )
{
int seconds = 0 ;
if ( data ) {
seconds = atoi ( data ) ;
if ( seconds > = 0 ) {
switch_core_session_sched_heartbeat ( session , seconds ) ;
return ;
}
}
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Usage: %s \n " , SCHED_HEARTBEAT_SYNTAX ) ;
2009-03-06 20:16:48 +00:00
}
# define HEARTBEAT_SYNTAX "[0|<seconds>]"
SWITCH_STANDARD_APP ( heartbeat_function )
{
int seconds = 0 ;
if ( data ) {
seconds = atoi ( data ) ;
if ( seconds > = 0 ) {
switch_core_session_enable_heartbeat ( session , seconds ) ;
return ;
}
}
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Usage: %s \n " , HEARTBEAT_SYNTAX ) ;
2009-03-06 20:16:48 +00:00
}
2007-06-20 05:15:07 +00:00
# define EXE_SYNTAX "<extension> <dialplan> <context>"
2007-06-20 05:39:50 +00:00
SWITCH_STANDARD_APP ( exe_function )
2007-04-20 23:45:14 +00:00
{
2008-01-06 22:14:10 +00:00
char * argv [ 4 ] = { 0 } ;
2007-04-20 23:45:14 +00:00
int argc ;
char * lbuf = NULL ;
2008-05-27 04:54:52 +00:00
2009-10-23 16:03:42 +00:00
if ( ! zstr ( data ) & & ( lbuf = switch_core_session_strdup ( session , data ) )
2007-04-20 23:45:14 +00:00
& & ( argc = switch_separate_string ( lbuf , ' ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ) ) {
2008-01-06 22:14:10 +00:00
switch_core_session_execute_exten ( session , argv [ 0 ] , argv [ 1 ] , argv [ 2 ] ) ;
2007-04-20 23:45:14 +00:00
} else {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Usage: %s \n " , EXE_SYNTAX ) ;
2007-04-20 23:45:14 +00:00
}
}
2008-12-11 23:06:51 +00:00
# define MKDIR_SYNTAX "<path>"
SWITCH_STANDARD_APP ( mkdir_function )
{
switch_dir_make_recursive ( data , SWITCH_DEFAULT_DIR_PERMS , switch_core_session_get_pool ( session ) ) ;
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " %s MKDIR: %s \n " ,
switch_channel_get_name ( switch_core_session_get_channel ( session ) ) , data ) ;
2008-12-11 23:06:51 +00:00
}
2008-04-09 18:15:15 +00:00
# define SOFT_HOLD_SYNTAX "<unhold key> [<moh_a>] [<moh_b>]"
SWITCH_STANDARD_APP ( soft_hold_function )
{
char * argv [ 3 ] = { 0 } ;
int argc ;
char * lbuf = NULL ;
2008-05-27 04:54:52 +00:00
2009-10-23 16:03:42 +00:00
if ( ! zstr ( data ) & & ( lbuf = switch_core_session_strdup ( session , data ) )
2008-04-09 18:15:15 +00:00
& & ( argc = switch_separate_string ( lbuf , ' ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ) > = 1 ) {
switch_ivr_soft_hold ( session , argv [ 0 ] , argv [ 1 ] , argv [ 2 ] ) ;
} else {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Usage: %s \n " , SOFT_HOLD_SYNTAX ) ;
2008-04-09 18:15:15 +00:00
}
}
2010-06-07 21:14:47 -04:00
SWITCH_STANDARD_APP ( dtmf_unblock_function )
{
switch_ivr_unblock_dtmf_session ( session ) ;
}
SWITCH_STANDARD_APP ( dtmf_block_function )
{
switch_ivr_block_dtmf_session ( session ) ;
}
2008-12-31 01:08:51 +00:00
# define UNBIND_SYNTAX "[<key>]"
SWITCH_STANDARD_APP ( dtmf_unbind_function )
{
char * key = ( char * ) data ;
int kval = 0 ;
if ( key ) {
2011-01-05 17:53:27 -06:00
kval = switch_dtmftoi ( key ) ;
2008-12-31 01:08:51 +00:00
}
switch_ivr_unbind_dtmf_meta_session ( session , kval ) ;
}
2009-09-24 22:21:44 +00:00
# define BIND_SYNTAX "<key> [a|b|ab] [a|b|o|s|i|1] <app>"
2008-03-11 21:32:56 +00:00
SWITCH_STANDARD_APP ( dtmf_bind_function )
{
2008-03-11 22:19:17 +00:00
char * argv [ 4 ] = { 0 } ;
2008-03-11 21:32:56 +00:00
int argc ;
char * lbuf = NULL ;
2008-05-27 04:54:52 +00:00
2009-10-23 16:03:42 +00:00
if ( ! zstr ( data ) & & ( lbuf = switch_core_session_strdup ( session , data ) )
2008-03-11 22:19:17 +00:00
& & ( argc = switch_separate_string ( lbuf , ' ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ) = = 4 ) {
2011-01-05 17:53:27 -06:00
int kval = switch_dtmftoi ( argv [ 0 ] ) ;
2008-05-19 21:02:26 +00:00
switch_bind_flag_t bind_flags = 0 ;
if ( strchr ( argv [ 1 ] , ' a ' ) ) {
bind_flags | = SBF_DIAL_ALEG ;
}
2008-07-03 17:11:15 +00:00
2008-05-19 21:02:26 +00:00
if ( strchr ( argv [ 1 ] , ' b ' ) ) {
bind_flags | = SBF_DIAL_BLEG ;
}
2008-07-03 17:11:15 +00:00
2008-05-19 21:02:26 +00:00
if ( strchr ( argv [ 2 ] , ' a ' ) ) {
if ( ( bind_flags & SBF_EXEC_BLEG ) ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Cannot bind execute to multiple legs \n " ) ;
2008-05-19 21:02:26 +00:00
} else {
bind_flags | = SBF_EXEC_ALEG ;
}
}
2008-07-03 17:11:15 +00:00
2008-05-19 21:02:26 +00:00
if ( strchr ( argv [ 2 ] , ' b ' ) ) {
if ( ( bind_flags & SBF_EXEC_ALEG ) ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Cannot bind execute to multiple legs \n " ) ;
2008-05-19 21:02:26 +00:00
} else {
bind_flags | = SBF_EXEC_BLEG ;
}
}
2008-07-03 17:11:15 +00:00
if ( strchr ( argv [ 2 ] , ' a ' ) ) {
if ( ( bind_flags & SBF_EXEC_BLEG ) ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Cannot bind execute to multiple legs \n " ) ;
2008-07-03 17:11:15 +00:00
} else {
bind_flags | = SBF_EXEC_ALEG ;
}
}
2009-09-24 22:21:44 +00:00
if ( strchr ( argv [ 2 ] , ' i ' ) ) {
bind_flags | = SBF_EXEC_INLINE ;
}
2008-05-19 21:02:26 +00:00
if ( strchr ( argv [ 2 ] , ' o ' ) ) {
if ( ( bind_flags & SBF_EXEC_BLEG ) | | ( bind_flags & SBF_EXEC_ALEG ) | | ( bind_flags & SBF_EXEC_SAME ) ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Cannot bind execute to multiple legs \n " ) ;
2008-05-19 21:02:26 +00:00
} else {
bind_flags | = SBF_EXEC_OPPOSITE ;
}
}
if ( strchr ( argv [ 2 ] , ' s ' ) ) {
if ( ( bind_flags & SBF_EXEC_BLEG ) | | ( bind_flags & SBF_EXEC_ALEG ) | | ( bind_flags & SBF_EXEC_SAME ) ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Cannot bind execute to multiple legs \n " ) ;
2008-05-19 21:02:26 +00:00
} else {
bind_flags | = SBF_EXEC_SAME ;
}
}
2008-12-31 01:08:51 +00:00
if ( strchr ( argv [ 2 ] , ' 1 ' ) ) {
bind_flags | = SBF_ONCE ;
}
2010-02-06 03:38:24 +00:00
2008-05-19 21:02:26 +00:00
if ( switch_ivr_bind_dtmf_meta_session ( session , kval , bind_flags , argv [ 3 ] ) ! = SWITCH_STATUS_SUCCESS ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Bind Error! \n " ) ;
2008-03-11 21:32:56 +00:00
}
} else {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Usage: %s \n " , BIND_SYNTAX ) ;
2008-03-11 21:32:56 +00:00
}
}
2008-05-24 17:28:04 +00:00
# define INTERCEPT_SYNTAX "[-bleg] <uuid>"
2007-12-08 00:14:21 +00:00
SWITCH_STANDARD_APP ( intercept_function )
{
2008-05-24 17:28:04 +00:00
int argc ;
char * argv [ 4 ] = { 0 } ;
char * mydata ;
char * uuid ;
switch_bool_t bleg = SWITCH_FALSE ;
2009-10-23 16:03:42 +00:00
if ( ! zstr ( data ) & & ( mydata = switch_core_session_strdup ( session , data ) ) ) {
2008-05-24 17:28:04 +00:00
if ( ( argc = switch_separate_string ( mydata , ' ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ) > = 1 ) {
if ( ! strcasecmp ( argv [ 0 ] , " -bleg " ) ) {
if ( argv [ 1 ] ) {
uuid = argv [ 1 ] ;
bleg = SWITCH_TRUE ;
} else {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Usage: %s \n " , INTERCEPT_SYNTAX ) ;
2008-05-24 17:28:04 +00:00
return ;
}
} else {
uuid = argv [ 0 ] ;
}
2008-05-27 04:54:52 +00:00
2008-05-24 17:28:04 +00:00
switch_ivr_intercept_session ( session , uuid , bleg ) ;
}
return ;
}
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Usage: %s \n " , INTERCEPT_SYNTAX ) ;
2007-12-08 00:14:21 +00:00
}
2007-11-30 22:56:01 +00:00
2008-04-11 22:35:30 +00:00
# define MAX_SPY 3000
struct e_data {
char * uuid_list [ MAX_SPY ] ;
int total ;
} ;
static int e_callback ( void * pArg , int argc , char * * argv , char * * columnNames )
{
char * uuid = argv [ 0 ] ;
struct e_data * e_data = ( struct e_data * ) pArg ;
if ( uuid & & e_data ) {
e_data - > uuid_list [ e_data - > total + + ] = strdup ( uuid ) ;
return 0 ;
}
return 1 ;
}
2008-04-11 23:26:47 +00:00
# define eavesdrop_SYNTAX "[all | <uuid>]"
2007-11-30 22:56:01 +00:00
SWITCH_STANDARD_APP ( eavesdrop_function )
{
2009-10-23 16:03:42 +00:00
if ( zstr ( data ) ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Usage: %s \n " , eavesdrop_SYNTAX ) ;
2008-01-06 22:14:10 +00:00
} else {
2010-05-25 10:30:40 -05:00
switch_eavesdrop_flag_t flags = ED_DTMF ;
2008-04-12 16:17:09 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
const char * require_group = switch_channel_get_variable ( channel , " eavesdrop_require_group " ) ;
2010-05-25 10:30:40 -05:00
const char * enable_dtmf = switch_channel_get_variable ( channel , " eavesdrop_enable_dtmf " ) ;
if ( enable_dtmf ) {
flags = switch_true ( enable_dtmf ) ? ED_DTMF : ED_NONE ;
}
2008-05-27 04:54:52 +00:00
if ( ! strcasecmp ( ( char * ) data , " all " ) ) {
2009-11-17 00:12:54 +00:00
switch_cache_db_handle_t * db = NULL ;
2008-04-11 22:35:30 +00:00
char * errmsg = NULL ;
2008-05-27 04:54:52 +00:00
struct e_data e_data = { { 0 } } ;
2008-04-11 22:35:30 +00:00
char * sql = switch_mprintf ( " select uuid from channels where uuid != '%q' " , switch_core_session_get_uuid ( session ) ) ;
const char * file = NULL ;
int x = 0 ;
char buf [ 2 ] = " " ;
switch_size_t buflen = sizeof ( buf ) ;
char terminator ;
2008-04-12 16:17:09 +00:00
switch_status_t status ;
2008-05-27 04:54:52 +00:00
while ( switch_channel_ready ( channel ) ) {
for ( x = 0 ; x < MAX_SPY ; x + + ) {
2008-04-11 22:35:30 +00:00
switch_safe_free ( e_data . uuid_list [ x ] ) ;
}
e_data . total = 0 ;
2010-04-17 00:34:01 -05:00
if ( switch_core_db_handle ( & db ) ! = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Database Error! \n " ) ;
break ;
}
2009-11-17 00:12:54 +00:00
switch_cache_db_execute_sql_callback ( db , sql , e_callback , & e_data , & errmsg ) ;
2010-04-17 00:34:01 -05:00
switch_cache_db_release_db_handle ( & db ) ;
2008-04-11 22:35:30 +00:00
if ( errmsg ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Error: %s \n " , errmsg ) ;
2010-06-07 16:47:35 -05:00
free ( errmsg ) ;
2008-04-11 22:35:30 +00:00
if ( ( file = switch_channel_get_variable ( channel , " eavesdrop_indicate_failed " ) ) ) {
switch_ivr_play_file ( session , NULL , file , NULL ) ;
}
switch_ivr_collect_digits_count ( session , buf , buflen , 1 , " * " , & terminator , 5000 , 0 , 0 ) ;
continue ;
}
if ( e_data . total ) {
for ( x = 0 ; x < e_data . total & & switch_channel_ready ( channel ) ; x + + ) {
2010-06-18 17:00:29 -05:00
if ( ! switch_ivr_uuid_exists ( e_data . uuid_list [ x ] ) ) continue ;
2008-07-01 17:41:54 +00:00
/* If we have a group and 1000 concurrent calls, we will flood the logs. This check avoids this */
2010-02-06 03:38:24 +00:00
if ( ! require_group )
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Spy: %s \n " , e_data . uuid_list [ x ] ) ;
2008-04-11 22:35:30 +00:00
if ( ( file = switch_channel_get_variable ( channel , " eavesdrop_indicate_new " ) ) ) {
switch_ivr_play_file ( session , NULL , file , NULL ) ;
}
2010-05-25 10:30:40 -05:00
if ( ( status = switch_ivr_eavesdrop_session ( session , e_data . uuid_list [ x ] , require_group , flags ) ) ! = SWITCH_STATUS_SUCCESS ) {
2008-04-12 16:17:09 +00:00
if ( status ! = SWITCH_STATUS_BREAK ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Spy: %s Failed \n " , e_data . uuid_list [ x ] ) ;
2008-04-12 16:17:09 +00:00
if ( ( file = switch_channel_get_variable ( channel , " eavesdrop_indicate_failed " ) ) ) {
switch_ivr_play_file ( session , NULL , file , NULL ) ;
}
switch_ivr_collect_digits_count ( session , buf , buflen , 1 , " * " , & terminator , 5000 , 0 , 0 ) ;
2008-04-11 22:35:30 +00:00
}
}
}
} else {
if ( ( file = switch_channel_get_variable ( channel , " eavesdrop_indicate_idle " ) ) ) {
switch_ivr_play_file ( session , NULL , file , NULL ) ;
}
switch_ivr_collect_digits_count ( session , buf , buflen , 1 , " * " , & terminator , 2000 , 0 , 0 ) ;
}
}
2008-05-27 04:54:52 +00:00
for ( x = 0 ; x < MAX_SPY ; x + + ) {
2008-04-11 22:35:30 +00:00
switch_safe_free ( e_data . uuid_list [ x ] ) ;
}
2009-04-01 20:11:36 +00:00
free ( sql ) ;
2008-05-27 04:54:52 +00:00
2008-04-11 22:35:30 +00:00
} else {
2010-05-25 10:30:40 -05:00
switch_ivr_eavesdrop_session ( session , data , require_group , flags ) ;
2008-04-11 22:35:30 +00:00
}
2007-11-30 22:56:01 +00:00
}
}
2008-04-12 04:59:15 +00:00
# define threeway_SYNTAX "<uuid>"
2008-01-10 00:45:28 +00:00
SWITCH_STANDARD_APP ( three_way_function )
{
2009-10-23 16:03:42 +00:00
if ( zstr ( data ) ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Usage: %s \n " , threeway_SYNTAX ) ;
2008-01-10 00:45:28 +00:00
} else {
2008-04-12 16:17:09 +00:00
switch_ivr_eavesdrop_session ( session , data , NULL , ED_MUX_READ | ED_MUX_WRITE ) ;
2008-01-10 00:45:28 +00:00
}
}
2009-09-08 19:05:32 +00:00
# define SET_USER_SYNTAX "<user>@<domain> [prefix]"
2007-11-13 19:58:44 +00:00
SWITCH_STANDARD_APP ( set_user_function )
{
2008-07-16 17:44:54 +00:00
switch_ivr_set_user ( session , data ) ;
2007-11-13 19:58:44 +00:00
}
2009-12-17 23:08:38 +00:00
# define SET_AUDIO_LEVEL_SYNTAX "[read|write] <vol>"
SWITCH_STANDARD_APP ( set_audio_level_function )
{
char * argv [ 2 ] = { 0 } ;
int argc = 0 ;
char * mydata ;
int level = 0 ;
mydata = switch_core_session_strdup ( session , data ) ;
argc = switch_split ( mydata , ' ' , argv ) ;
2010-02-06 03:38:24 +00:00
2009-12-17 23:08:38 +00:00
if ( argc ! = 2 ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " %s Error. USAGE: %s \n " ,
2009-12-17 23:08:38 +00:00
switch_core_session_get_name ( session ) , SET_AUDIO_LEVEL_SYNTAX ) ;
return ;
}
level = atoi ( argv [ 1 ] ) ;
switch_ivr_session_audio ( session , " level " , argv [ 0 ] , level ) ;
2010-02-06 03:38:24 +00:00
2009-12-17 23:08:38 +00:00
}
2009-12-18 15:52:56 +00:00
# define SET_MUTE_SYNTAX "[read|write] [[true|cn level]|false]"
2009-12-17 23:08:38 +00:00
SWITCH_STANDARD_APP ( set_mute_function )
{
char * argv [ 2 ] = { 0 } ;
int argc = 0 ;
char * mydata ;
int level = 0 ;
mydata = switch_core_session_strdup ( session , data ) ;
argc = switch_split ( mydata , ' ' , argv ) ;
2010-02-06 03:38:24 +00:00
2009-12-17 23:08:38 +00:00
if ( argc ! = 2 ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " %s Error. USAGE: %s \n " ,
2009-12-17 23:08:38 +00:00
switch_core_session_get_name ( session ) , SET_MUTE_SYNTAX ) ;
return ;
}
2010-02-06 03:38:24 +00:00
2009-12-18 15:52:56 +00:00
if ( ( level = atoi ( argv [ 1 ] ) ) < = 0 ) {
level = switch_true ( argv [ 1 ] ) ;
}
2010-02-06 03:38:24 +00:00
2009-12-17 23:08:38 +00:00
switch_ivr_session_audio ( session , " mute " , argv [ 0 ] , level ) ;
2010-02-06 03:38:24 +00:00
2009-12-17 23:08:38 +00:00
}
2007-06-20 05:39:50 +00:00
SWITCH_STANDARD_APP ( ring_ready_function )
2006-11-28 02:23:26 +00:00
{
2010-06-15 16:14:39 -05:00
if ( ! zstr ( data ) ) {
if ( ! strcasecmp ( data , " queued " ) ) {
switch_channel_ring_ready_value ( switch_core_session_get_channel ( session ) , SWITCH_RING_READY_QUEUED ) ;
return ;
}
}
2008-01-28 07:26:10 +00:00
switch_channel_ring_ready ( switch_core_session_get_channel ( session ) ) ;
2006-11-28 02:23:26 +00:00
}
2008-07-29 15:19:58 +00:00
SWITCH_STANDARD_APP ( remove_bugs_function )
{
switch_core_media_bug_remove_all ( session ) ;
}
2007-06-25 21:25:33 +00:00
SWITCH_STANDARD_APP ( break_function )
{
2009-01-29 21:52:20 +00:00
switch_channel_t * channel ;
channel = switch_core_session_get_channel ( session ) ;
if ( data & & strcasecmp ( data , " all " ) ) {
switch_core_session_flush_private_events ( session ) ;
}
if ( switch_channel_test_flag ( channel , CF_BROADCAST ) ) {
switch_channel_stop_broadcast ( channel ) ;
} else {
switch_channel_set_flag ( channel , CF_BREAK ) ;
}
2007-06-25 21:25:33 +00:00
}
2007-06-20 05:39:50 +00:00
SWITCH_STANDARD_APP ( queue_dtmf_function )
2007-01-29 20:06:23 +00:00
{
2008-01-28 07:26:10 +00:00
switch_channel_queue_dtmf_string ( switch_core_session_get_channel ( session ) , ( const char * ) data ) ;
2008-01-12 20:30:48 +00:00
}
2007-12-22 00:32:20 +00:00
2008-01-12 20:30:48 +00:00
SWITCH_STANDARD_APP ( send_dtmf_function )
{
switch_core_session_send_dtmf_string ( session , ( const char * ) data ) ;
2007-01-29 20:06:23 +00:00
}
2008-03-26 22:14:09 +00:00
SWITCH_STANDARD_APP ( check_acl_function )
{
int argc ;
2008-05-27 04:54:52 +00:00
char * argv [ 3 ] = { 0 } ;
2008-03-26 22:14:09 +00:00
char * mydata ;
switch_call_cause_t cause = SWITCH_CAUSE_CALL_REJECTED ;
2009-10-23 16:03:42 +00:00
if ( ! zstr ( data ) & & ( mydata = switch_core_session_strdup ( session , data ) ) ) {
2008-03-26 22:14:09 +00:00
if ( ( argc = switch_separate_string ( mydata , ' ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ) > 1 ) {
if ( ! switch_check_network_list_ip ( argv [ 0 ] , argv [ 1 ] ) ) {
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
if ( argc > 2 ) {
cause = switch_channel_str2cause ( argv [ 2 ] ) ;
}
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Call failed acl check for ip %s on list %s \n " , argv [ 0 ] , argv [ 1 ] ) ;
2008-03-26 22:14:09 +00:00
switch_channel_hangup ( channel , cause ) ;
}
}
}
2008-05-27 04:54:52 +00:00
2008-03-26 22:14:09 +00:00
}
2008-11-05 17:25:54 +00:00
SWITCH_STANDARD_APP ( flush_dtmf_function )
{
switch_channel_flush_dtmf ( switch_core_session_get_channel ( session ) ) ;
}
2007-06-20 05:39:50 +00:00
SWITCH_STANDARD_APP ( transfer_function )
2006-11-28 02:23:26 +00:00
{
int argc ;
2007-03-29 22:31:56 +00:00
char * argv [ 4 ] = { 0 } ;
2006-11-28 02:23:26 +00:00
char * mydata ;
2008-03-12 00:30:52 +00:00
int bleg = 0 , both = 0 ;
2006-11-28 02:23:26 +00:00
2008-05-27 04:54:52 +00:00
2009-10-23 16:03:42 +00:00
if ( ! zstr ( data ) & & ( mydata = switch_core_session_strdup ( session , data ) ) ) {
2006-11-28 02:23:26 +00:00
if ( ( argc = switch_separate_string ( mydata , ' ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ) > = 1 ) {
2008-03-12 00:30:52 +00:00
bleg = ! strcasecmp ( argv [ 0 ] , " -bleg " ) ;
both = ! strcasecmp ( argv [ 0 ] , " -both " ) ;
if ( bleg | | both ) {
2008-03-11 22:19:17 +00:00
const char * uuid ;
2008-05-27 04:54:52 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
2012-05-29 13:10:15 -05:00
if ( ( uuid = switch_channel_get_partner_uuid ( channel ) ) ) {
2008-03-11 22:19:17 +00:00
switch_core_session_t * b_session ;
if ( ( b_session = switch_core_session_locate ( uuid ) ) ) {
switch_ivr_session_transfer ( b_session , argv [ 1 ] , argv [ 2 ] , argv [ 3 ] ) ;
switch_core_session_rwunlock ( b_session ) ;
}
2008-03-13 01:08:42 +00:00
} else {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING , " No B-leg present. \n " ) ;
2008-03-11 22:19:17 +00:00
}
2008-03-12 00:30:52 +00:00
if ( both ) {
switch_ivr_session_transfer ( session , argv [ 1 ] , argv [ 2 ] , argv [ 3 ] ) ;
}
2008-03-11 22:19:17 +00:00
} else {
switch_ivr_session_transfer ( session , argv [ 0 ] , argv [ 1 ] , argv [ 2 ] ) ;
}
2006-11-28 02:23:26 +00:00
} else {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " No extension specified. \n " ) ;
2006-11-28 02:23:26 +00:00
}
}
}
2007-06-20 05:39:50 +00:00
SWITCH_STANDARD_APP ( sched_transfer_function )
2007-03-28 23:37:12 +00:00
{
int argc ;
2007-03-29 22:31:56 +00:00
char * argv [ 4 ] = { 0 } ;
2007-03-28 23:37:12 +00:00
char * mydata ;
2007-03-29 22:31:56 +00:00
2009-10-23 16:03:42 +00:00
if ( ! zstr ( data ) & & ( mydata = switch_core_session_strdup ( session , data ) ) ) {
2007-03-28 23:37:12 +00:00
if ( ( argc = switch_separate_string ( mydata , ' ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ) > = 2 ) {
time_t when ;
if ( * argv [ 0 ] = = ' + ' ) {
2009-01-25 21:23:07 +00:00
when = switch_epoch_time_now ( NULL ) + atol ( argv [ 0 ] + 1 ) ;
2007-03-28 23:37:12 +00:00
} else {
when = atol ( argv [ 0 ] ) ;
}
switch_ivr_schedule_transfer ( when , switch_core_session_get_uuid ( session ) , argv [ 1 ] , argv [ 2 ] , argv [ 3 ] ) ;
} else {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Invalid Args \n " ) ;
2007-03-28 23:37:12 +00:00
}
}
}
2007-06-20 05:39:50 +00:00
SWITCH_STANDARD_APP ( sched_hangup_function )
2007-03-28 23:37:12 +00:00
{
int argc ;
2007-03-29 22:31:56 +00:00
char * argv [ 5 ] = { 0 } ;
2007-03-28 23:37:12 +00:00
char * mydata ;
2009-10-23 16:03:42 +00:00
if ( ! zstr ( data ) & & ( mydata = switch_core_session_strdup ( session , data ) ) ) {
2007-03-28 23:37:12 +00:00
if ( ( argc = switch_separate_string ( mydata , ' ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ) > = 1 ) {
time_t when ;
switch_call_cause_t cause = SWITCH_CAUSE_ALLOTTED_TIMEOUT ;
switch_bool_t bleg = SWITCH_FALSE ;
2012-05-04 19:48:31 -05:00
int sec = atol ( argv [ 0 ] + 1 ) ;
2007-03-28 23:37:12 +00:00
if ( * argv [ 0 ] = = ' + ' ) {
2012-05-04 19:48:31 -05:00
when = switch_epoch_time_now ( NULL ) + sec ;
2007-03-28 23:37:12 +00:00
} else {
when = atol ( argv [ 0 ] ) ;
}
2007-03-29 22:31:56 +00:00
2007-03-28 23:37:12 +00:00
if ( argv [ 1 ] ) {
cause = switch_channel_str2cause ( argv [ 1 ] ) ;
}
if ( argv [ 2 ] & & ! strcasecmp ( argv [ 2 ] , " bleg " ) ) {
bleg = SWITCH_TRUE ;
}
2012-05-04 19:48:31 -05:00
if ( sec = = 0 ) {
switch_channel_hangup ( switch_core_session_get_channel ( session ) , cause ) ;
} else {
switch_ivr_schedule_hangup ( when , switch_core_session_get_uuid ( session ) , cause , bleg ) ;
}
2007-03-28 23:37:12 +00:00
} else {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " No time specified. \n " ) ;
2007-03-28 23:37:12 +00:00
}
}
}
2007-06-20 05:39:50 +00:00
SWITCH_STANDARD_APP ( sched_broadcast_function )
2007-03-28 23:37:12 +00:00
{
int argc ;
2007-03-29 22:31:56 +00:00
char * argv [ 6 ] = { 0 } ;
2007-03-28 23:37:12 +00:00
char * mydata ;
2009-10-23 16:03:42 +00:00
if ( ! zstr ( data ) & & ( mydata = switch_core_session_strdup ( session , data ) ) ) {
2007-03-28 23:37:12 +00:00
if ( ( argc = switch_separate_string ( mydata , ' ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ) > = 2 ) {
time_t when ;
switch_media_flag_t flags = SMF_NONE ;
2007-03-29 22:31:56 +00:00
2007-03-28 23:37:12 +00:00
if ( * argv [ 0 ] = = ' + ' ) {
2009-01-25 21:23:07 +00:00
when = switch_epoch_time_now ( NULL ) + atol ( argv [ 0 ] + 1 ) ;
2007-03-28 23:37:12 +00:00
} else {
when = atol ( argv [ 0 ] ) ;
}
2007-03-29 22:31:56 +00:00
2007-03-28 23:37:12 +00:00
if ( argv [ 2 ] ) {
if ( ! strcmp ( argv [ 2 ] , " both " ) ) {
flags | = ( SMF_ECHO_ALEG | SMF_ECHO_BLEG ) ;
} else if ( ! strcmp ( argv [ 2 ] , " aleg " ) ) {
flags | = SMF_ECHO_ALEG ;
} else if ( ! strcmp ( argv [ 2 ] , " bleg " ) ) {
flags | = SMF_ECHO_BLEG ;
}
} else {
flags | = SMF_ECHO_ALEG ;
}
switch_ivr_schedule_broadcast ( when , switch_core_session_get_uuid ( session ) , argv [ 1 ] , flags ) ;
} else {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Invalid Args \n " ) ;
2007-03-28 23:37:12 +00:00
}
}
}
2007-10-04 15:09:44 +00:00
SWITCH_STANDARD_APP ( delay_function )
{
uint32_t len = 0 ;
2009-10-23 16:03:42 +00:00
if ( zstr ( data ) ) {
2007-10-04 15:09:44 +00:00
len = 1000 ;
} else {
len = atoi ( data ) ;
}
2008-05-27 04:54:52 +00:00
2007-10-04 15:09:44 +00:00
switch_ivr_delay_echo ( session , len ) ;
}
2007-06-20 05:39:50 +00:00
SWITCH_STANDARD_APP ( eval_function )
2006-11-28 02:23:26 +00:00
{
return ;
}
2011-09-13 17:12:37 -05:00
SWITCH_STANDARD_APP ( zombie_function )
{
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
if ( switch_channel_up ( channel ) ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " %s MMM Brains.... \n " , switch_channel_get_name ( channel ) ) ;
switch_channel_set_flag ( channel , CF_ZOMBIE_EXEC ) ;
}
return ;
}
2006-12-20 21:25:14 +00:00
2007-06-20 05:39:50 +00:00
SWITCH_STANDARD_APP ( hangup_function )
2007-01-02 18:56:39 +00:00
{
2007-03-29 22:31:56 +00:00
switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING ;
2007-01-02 18:56:39 +00:00
2009-10-23 16:03:42 +00:00
if ( ! zstr ( data ) ) {
2008-01-06 22:14:10 +00:00
cause = switch_channel_str2cause ( data ) ;
2007-03-29 22:31:56 +00:00
}
2007-01-02 18:56:39 +00:00
2008-01-28 07:26:10 +00:00
switch_channel_hangup ( switch_core_session_get_channel ( session ) , cause ) ;
2007-01-02 18:56:39 +00:00
}
2008-02-26 23:29:58 +00:00
SWITCH_STANDARD_APP ( set_name_function )
{
2009-10-23 16:03:42 +00:00
if ( ! zstr ( data ) ) {
2008-02-26 23:29:58 +00:00
switch_channel_set_name ( switch_core_session_get_channel ( session ) , ( char * ) data ) ;
}
}
2007-06-20 05:39:50 +00:00
SWITCH_STANDARD_APP ( answer_function )
2006-11-28 02:23:26 +00:00
{
2008-10-09 23:11:35 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
switch_channel_answer ( channel ) ;
2006-11-28 02:23:26 +00:00
}
2008-08-25 16:30:28 +00:00
SWITCH_STANDARD_APP ( presence_function )
{
char * argv [ 6 ] = { 0 } ;
2009-01-13 23:48:55 +00:00
int argc ;
char * mydata = NULL ;
2008-08-25 16:30:28 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
2009-10-23 16:03:42 +00:00
if ( zstr ( data ) | | ! ( mydata = switch_core_session_strdup ( session , data ) ) ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " INVALID ARGS! \n " ) ;
2009-01-13 23:48:55 +00:00
return ;
}
2008-08-25 16:30:28 +00:00
if ( ( argc = switch_separate_string ( mydata , ' ' , argv , sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) < 2 ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " INVALID ARGS! \n " ) ;
2008-08-25 16:30:28 +00:00
return ;
}
2010-02-06 03:38:24 +00:00
switch_channel_presence ( channel , argv [ 0 ] , argv [ 1 ] , argv [ 2 ] ) ;
2008-08-25 16:30:28 +00:00
}
2007-06-20 05:39:50 +00:00
SWITCH_STANDARD_APP ( pre_answer_function )
2007-02-10 19:34:03 +00:00
{
2008-10-09 23:11:35 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
switch_channel_pre_answer ( channel ) ;
2007-02-10 19:34:03 +00:00
}
2007-06-20 05:39:50 +00:00
SWITCH_STANDARD_APP ( redirect_function )
2007-01-10 21:26:10 +00:00
{
2007-03-29 22:31:56 +00:00
switch_core_session_message_t msg = { 0 } ;
2007-01-10 21:26:10 +00:00
2007-03-29 22:31:56 +00:00
/* Tell the channel to redirect */
2007-01-10 21:26:10 +00:00
msg . from = __FILE__ ;
msg . string_arg = data ;
2007-03-29 22:31:56 +00:00
msg . message_id = SWITCH_MESSAGE_INDICATE_REDIRECT ;
2007-01-10 21:26:10 +00:00
switch_core_session_receive_message ( session , & msg ) ;
}
2012-05-09 09:06:21 -05:00
SWITCH_STANDARD_APP ( video_refresh_function )
{
switch_core_session_message_t msg = { 0 } ;
/* Tell the channel to refresh video */
msg . from = __FILE__ ;
msg . string_arg = data ;
msg . message_id = SWITCH_MESSAGE_INDICATE_VIDEO_REFRESH_REQ ;
switch_core_session_receive_message ( session , & msg ) ;
}
2011-11-23 15:38:54 -06:00
SWITCH_STANDARD_APP ( send_info_function )
{
switch_core_session_message_t msg = { 0 } ;
/* Tell the channel to send info */
msg . from = __FILE__ ;
msg . string_arg = data ;
msg . message_id = SWITCH_MESSAGE_INDICATE_INFO ;
msg . string_array_arg [ 2 ] = data ;
switch_core_session_receive_message ( session , & msg ) ;
}
2010-12-10 17:47:24 -06:00
SWITCH_STANDARD_APP ( jitterbuffer_function )
{
switch_core_session_message_t msg = { 0 } ;
/* Tell the channel to change the jitter buffer */
msg . from = __FILE__ ;
msg . string_arg = data ;
msg . message_id = SWITCH_MESSAGE_INDICATE_JITTER_BUFFER ;
switch_core_session_receive_message ( session , & msg ) ;
}
2008-03-11 03:45:16 +00:00
SWITCH_STANDARD_APP ( display_function )
{
switch_core_session_message_t msg = { 0 } ;
2010-06-17 15:04:09 -05:00
/* Tell the channel to change display */
2008-03-11 03:45:16 +00:00
msg . from = __FILE__ ;
msg . string_arg = data ;
msg . message_id = SWITCH_MESSAGE_INDICATE_DISPLAY ;
switch_core_session_receive_message ( session , & msg ) ;
}
2008-01-03 00:50:53 +00:00
SWITCH_STANDARD_APP ( respond_function )
2007-04-21 15:04:01 +00:00
{
switch_core_session_message_t msg = { 0 } ;
2008-01-03 00:50:53 +00:00
/* Tell the channel to respond the call */
2007-04-21 15:04:01 +00:00
msg . from = __FILE__ ;
msg . string_arg = data ;
2008-01-03 00:50:53 +00:00
msg . message_id = SWITCH_MESSAGE_INDICATE_RESPOND ;
2007-04-21 15:04:01 +00:00
switch_core_session_receive_message ( session , & msg ) ;
}
2008-01-03 23:42:15 +00:00
SWITCH_STANDARD_APP ( deflect_function )
{
switch_core_session_message_t msg = { 0 } ;
2008-01-06 22:14:10 +00:00
/* Tell the channel to deflect the call */
2008-01-03 23:42:15 +00:00
msg . from = __FILE__ ;
msg . string_arg = data ;
msg . message_id = SWITCH_MESSAGE_INDICATE_DEFLECT ;
switch_core_session_receive_message ( session , & msg ) ;
}
2010-12-29 13:15:14 -06:00
SWITCH_STANDARD_APP ( recovery_refresh_function )
{
switch_core_session_message_t msg = { 0 } ;
/* Tell the channel to recovery_refresh the call */
msg . from = __FILE__ ;
msg . string_arg = data ;
msg . message_id = SWITCH_MESSAGE_INDICATE_RECOVERY_REFRESH ;
switch_core_session_receive_message ( session , & msg ) ;
}
2010-07-02 14:06:53 -05:00
SWITCH_STANDARD_APP ( sched_cancel_function )
{
const char * group = data ;
if ( zstr ( group ) ) {
group = switch_core_session_get_uuid ( session ) ;
}
switch_scheduler_del_task_group ( group ) ;
}
2011-05-25 15:42:36 -05:00
static void base_set ( switch_core_session_t * session , const char * data , switch_stack_t stack )
2006-11-28 02:23:26 +00:00
{
char * var , * val = NULL ;
2010-02-06 03:38:24 +00:00
2009-10-23 16:03:42 +00:00
if ( zstr ( data ) ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " No variable name specified. \n " ) ;
2006-11-28 02:23:26 +00:00
} else {
2008-07-09 00:53:10 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
char * expanded = NULL ;
2006-11-28 02:23:26 +00:00
var = switch_core_session_strdup ( session , data ) ;
2011-05-25 15:42:36 -05:00
if ( ! ( val = strchr ( var , ' = ' ) ) ) {
val = strchr ( var , ' , ' ) ;
}
2006-11-28 02:23:26 +00:00
if ( val ) {
* val + + = ' \0 ' ;
2009-10-23 16:03:42 +00:00
if ( zstr ( val ) ) {
2007-03-29 22:31:56 +00:00
val = NULL ;
}
2006-11-28 02:23:26 +00:00
}
2007-03-29 22:31:56 +00:00
2008-07-09 00:53:10 +00:00
if ( val ) {
expanded = switch_channel_expand_variables ( channel , val ) ;
}
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " %s SET [%s]=[%s] \n " , switch_channel_get_name ( channel ) , var ,
expanded ? expanded : " UNDEF " ) ;
2011-05-25 15:42:36 -05:00
switch_channel_add_variable_var_check ( channel , var , expanded , SWITCH_FALSE , stack ) ;
2008-07-09 00:53:10 +00:00
if ( expanded & & expanded ! = val ) {
switch_safe_free ( expanded ) ;
}
2006-11-28 02:23:26 +00:00
}
}
2011-05-25 15:42:36 -05:00
SWITCH_STANDARD_APP ( set_function )
{
base_set ( session , data , SWITCH_STACK_BOTTOM ) ;
}
SWITCH_STANDARD_APP ( push_function )
{
base_set ( session , data , SWITCH_STACK_PUSH ) ;
}
SWITCH_STANDARD_APP ( unshift_function )
{
base_set ( session , data , SWITCH_STACK_UNSHIFT ) ;
}
2007-11-09 15:55:40 +00:00
SWITCH_STANDARD_APP ( set_global_function )
{
char * var , * val = NULL ;
2009-10-23 16:03:42 +00:00
if ( zstr ( data ) ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " No variable name specified. \n " ) ;
2007-11-09 15:55:40 +00:00
} else {
var = strdup ( data ) ;
2007-12-12 03:21:14 +00:00
switch_assert ( var ) ;
2007-11-09 15:55:40 +00:00
val = strchr ( var , ' = ' ) ;
if ( val ) {
* val + + = ' \0 ' ;
2009-10-23 16:03:42 +00:00
if ( zstr ( val ) ) {
2007-11-09 15:55:40 +00:00
val = NULL ;
}
}
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " SET GLOBAL [%s]=[%s] \n " , var , val ? val : " UNDEF " ) ;
2007-11-09 15:55:40 +00:00
switch_core_set_variable ( var , val ) ;
free ( var ) ;
}
}
2007-08-22 00:22:22 +00:00
SWITCH_STANDARD_APP ( set_profile_var_function )
{
char * name , * val = NULL ;
2009-10-23 16:03:42 +00:00
if ( zstr ( data ) ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " No variable name specified. \n " ) ;
2007-08-22 00:22:22 +00:00
} else {
2009-10-19 19:58:23 +00:00
name = switch_core_session_strdup ( session , data ) ;
2007-08-22 00:22:22 +00:00
val = strchr ( name , ' = ' ) ;
if ( val ) {
* val + + = ' \0 ' ;
2009-10-23 16:03:42 +00:00
if ( zstr ( val ) ) {
2007-08-22 00:22:22 +00:00
val = NULL ;
}
}
2010-02-06 03:38:24 +00:00
2009-10-19 19:58:23 +00:00
switch_channel_set_profile_var ( switch_core_session_get_channel ( session ) , name , val ) ;
2007-08-22 00:22:22 +00:00
}
}
2007-06-20 05:39:50 +00:00
SWITCH_STANDARD_APP ( export_function )
2007-02-16 20:07:35 +00:00
{
2008-01-28 07:26:10 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
2010-10-01 17:26:03 -05:00
char * var , * val = NULL ;
2007-02-16 20:07:35 +00:00
2009-10-23 16:03:42 +00:00
if ( zstr ( data ) ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " No variable name specified. \n " ) ;
2007-02-16 20:07:35 +00:00
} else {
var = switch_core_session_strdup ( session , data ) ;
2010-10-01 17:26:03 -05:00
if ( ( val = strchr ( var , ' = ' ) ) ) {
2007-02-16 20:07:35 +00:00
* val + + = ' \0 ' ;
2009-10-23 16:03:42 +00:00
if ( zstr ( val ) ) {
2007-03-29 22:31:56 +00:00
val = NULL ;
}
2007-02-16 20:07:35 +00:00
}
2007-03-29 22:31:56 +00:00
2010-10-01 17:26:03 -05:00
switch_channel_export_variable ( channel , var , val , SWITCH_EXPORT_VARS_VARIABLE ) ;
}
}
2007-02-16 20:07:35 +00:00
2010-10-01 17:26:03 -05:00
SWITCH_STANDARD_APP ( bridge_export_function )
{
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
char * var , * val = NULL ;
2007-05-10 14:11:26 +00:00
2010-10-01 17:26:03 -05:00
if ( zstr ( data ) ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " No variable name specified. \n " ) ;
} else {
var = switch_core_session_strdup ( session , data ) ;
2007-05-10 14:11:26 +00:00
2010-10-01 17:26:03 -05:00
if ( ( val = strchr ( var , ' = ' ) ) ) {
* val + + = ' \0 ' ;
if ( zstr ( val ) ) {
val = NULL ;
}
2007-02-16 20:07:35 +00:00
}
2010-10-01 17:26:03 -05:00
switch_channel_export_variable ( channel , var , val , SWITCH_BRIDGE_EXPORT_VARS_VARIABLE ) ;
2007-02-16 20:07:35 +00:00
}
}
2007-02-05 19:35:31 +00:00
2007-06-20 05:39:50 +00:00
SWITCH_STANDARD_APP ( unset_function )
2007-02-05 19:35:31 +00:00
{
2009-10-23 16:03:42 +00:00
if ( zstr ( data ) ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " No variable name specified. \n " ) ;
2007-02-05 19:35:31 +00:00
} else {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " UNSET [%s] \n " , ( char * ) data ) ;
2008-01-28 07:26:10 +00:00
switch_channel_set_variable ( switch_core_session_get_channel ( session ) , data , NULL ) ;
2007-02-05 19:35:31 +00:00
}
}
2007-06-20 05:39:50 +00:00
SWITCH_STANDARD_APP ( log_function )
2006-11-28 02:23:26 +00:00
{
2007-03-29 22:31:56 +00:00
char * level , * log_str ;
2006-11-28 02:23:26 +00:00
2007-03-29 22:31:56 +00:00
if ( data & & ( level = strdup ( data ) ) ) {
2007-05-04 02:14:40 +00:00
switch_log_level_t ltype = SWITCH_LOG_DEBUG ;
2007-03-29 22:31:56 +00:00
if ( ( log_str = strchr ( level , ' ' ) ) ) {
* log_str + + = ' \0 ' ;
2007-05-04 02:14:40 +00:00
ltype = switch_log_str2level ( level ) ;
2007-03-29 22:31:56 +00:00
} else {
log_str = level ;
}
2007-12-10 19:16:50 +00:00
if ( ltype = = SWITCH_LOG_INVALID ) {
ltype = SWITCH_LOG_DEBUG ;
}
2007-03-29 22:31:56 +00:00
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , ltype , " %s \n " , log_str ) ;
2007-03-29 22:31:56 +00:00
switch_safe_free ( level ) ;
}
2006-11-28 02:23:26 +00:00
}
2007-06-20 05:39:50 +00:00
SWITCH_STANDARD_APP ( info_function )
2006-11-28 02:23:26 +00:00
{
2007-03-29 22:31:56 +00:00
switch_event_t * event ;
char * buf ;
2009-08-26 16:29:47 +00:00
int level = SWITCH_LOG_INFO ;
2009-10-23 16:03:42 +00:00
if ( ! zstr ( data ) ) {
2009-08-26 16:29:47 +00:00
level = switch_log_str2level ( data ) ;
}
2006-11-28 02:23:26 +00:00
2009-03-24 23:44:03 +00:00
if ( switch_event_create_plain ( & event , SWITCH_EVENT_CHANNEL_DATA ) = = SWITCH_STATUS_SUCCESS ) {
2008-01-28 07:26:10 +00:00
switch_channel_event_set_data ( switch_core_session_get_channel ( session ) , event ) ;
2007-12-11 22:19:49 +00:00
switch_event_serialize ( event , & buf , SWITCH_FALSE ) ;
switch_assert ( buf ) ;
2009-08-26 16:29:47 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , level , " CHANNEL_DATA: \n %s \n " , buf ) ;
2007-03-29 22:31:56 +00:00
switch_event_destroy ( & event ) ;
2007-12-11 22:19:49 +00:00
free ( buf ) ;
2007-03-29 22:31:56 +00:00
}
2006-11-28 02:23:26 +00:00
}
2009-02-05 19:53:13 +00:00
SWITCH_STANDARD_APP ( sound_test_function )
{
switch_ivr_sound_test ( session ) ;
}
2007-06-23 05:41:07 +00:00
SWITCH_STANDARD_APP ( event_function )
{
switch_event_t * event ;
2008-01-06 22:14:10 +00:00
char * argv [ 25 ] = { 0 } ;
2007-06-23 05:41:07 +00:00
int argc = 0 ;
char * lbuf ;
if ( switch_event_create ( & event , SWITCH_EVENT_CHANNEL_APPLICATION ) = = SWITCH_STATUS_SUCCESS ) {
2009-10-23 16:03:42 +00:00
if ( ! zstr ( data ) & & ( lbuf = switch_core_session_strdup ( session , data ) )
2007-06-23 05:41:07 +00:00
& & ( argc = switch_separate_string ( lbuf , ' , ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ) ) {
int x = 0 ;
for ( x = 0 ; x < argc ; x + + ) {
char * p , * this = argv [ x ] ;
if ( this ) {
2008-05-19 22:26:59 +00:00
char * var , * val ;
p = this ;
2008-05-27 04:54:52 +00:00
while ( * p = = ' ' )
* p + + = ' \0 ' ;
2008-05-19 22:26:59 +00:00
this = p ;
2008-05-27 04:54:52 +00:00
2008-05-19 22:26:59 +00:00
var = this ;
val = NULL ;
2007-06-23 05:41:07 +00:00
if ( ( val = strchr ( var , ' = ' ) ) ) {
p = val - 1 ;
* val + + = ' \0 ' ;
2008-05-27 04:54:52 +00:00
while ( * p = = ' ' )
* p - - = ' \0 ' ;
2007-06-23 05:41:07 +00:00
p = val ;
2008-05-27 04:54:52 +00:00
while ( * p = = ' ' )
* p + + = ' \0 ' ;
2007-06-23 05:41:07 +00:00
val = p ;
2010-02-06 03:38:24 +00:00
if ( ! strcasecmp ( var , " Event-Name " ) ) {
2009-04-02 19:40:26 +00:00
switch_name_event ( val , & event - > event_id ) ;
switch_event_del_header ( event , var ) ;
2009-04-21 01:02:45 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , var , val ) ;
2010-02-06 03:38:24 +00:00
} else if ( ! strcasecmp ( var , " Event-Subclass " ) ) {
2009-04-02 19:40:26 +00:00
size_t len = strlen ( val ) + 1 ;
void * new = malloc ( len ) ;
switch_assert ( new ) ;
memcpy ( new , val , len ) ;
event - > subclass_name = new ;
2011-09-08 22:35:20 -05:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , var , val ) ;
2009-04-02 19:40:26 +00:00
} else {
2009-04-21 01:02:45 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , var , val ) ;
2009-04-02 19:40:26 +00:00
}
2007-06-23 05:41:07 +00:00
}
}
}
}
2009-04-02 19:40:26 +00:00
switch_channel_event_set_data ( switch_core_session_get_channel ( session ) , event ) ;
2007-06-23 05:41:07 +00:00
switch_event_fire ( & event ) ;
}
}
2007-06-20 05:39:50 +00:00
SWITCH_STANDARD_APP ( privacy_function )
2006-11-28 02:23:26 +00:00
{
2008-01-28 07:26:10 +00:00
switch_caller_profile_t * caller_profile = switch_channel_get_caller_profile ( switch_core_session_get_channel ( session ) ) ;
2006-11-28 02:23:26 +00:00
2009-10-23 16:03:42 +00:00
if ( zstr ( data ) ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " No privacy mode specified. \n " ) ;
2006-11-28 02:23:26 +00:00
} else {
switch_set_flag ( caller_profile , SWITCH_CPF_SCREEN ) ;
2009-03-04 21:22:41 +00:00
if ( ! strcasecmp ( data , " full " ) ) {
2006-11-28 02:23:26 +00:00
switch_set_flag ( caller_profile , SWITCH_CPF_HIDE_NAME | SWITCH_CPF_HIDE_NUMBER ) ;
2008-01-06 22:14:10 +00:00
} else if ( ! strcasecmp ( data , " name " ) ) {
2006-11-28 02:23:26 +00:00
switch_set_flag ( caller_profile , SWITCH_CPF_HIDE_NAME ) ;
2008-01-06 22:14:10 +00:00
} else if ( ! strcasecmp ( data , " number " ) ) {
2006-11-28 02:23:26 +00:00
switch_set_flag ( caller_profile , SWITCH_CPF_HIDE_NUMBER ) ;
2009-03-04 21:22:41 +00:00
} else if ( switch_true ( data ) ) {
switch_set_flag ( caller_profile , SWITCH_CPF_HIDE_NAME | SWITCH_CPF_HIDE_NUMBER ) ;
} else if ( switch_false ( data ) ) {
switch_clear_flag ( caller_profile , SWITCH_CPF_HIDE_NAME ) ;
switch_clear_flag ( caller_profile , SWITCH_CPF_HIDE_NUMBER ) ;
2006-11-28 02:23:26 +00:00
} else {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR ,
" INVALID privacy mode specified. Use a valid mode [no|yes|name|full|number]. \n " ) ;
2006-11-28 02:23:26 +00:00
}
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Set Privacy to %s [%d] \n " , data , caller_profile - > flags ) ;
2006-11-28 02:23:26 +00:00
}
}
2007-06-20 05:39:50 +00:00
SWITCH_STANDARD_APP ( strftime_function )
2006-11-28 02:23:26 +00:00
{
2008-01-06 22:14:10 +00:00
char * argv [ 2 ] = { 0 } ;
2006-11-28 02:23:26 +00:00
int argc ;
char * lbuf ;
2009-10-23 16:03:42 +00:00
if ( ! zstr ( data ) & & ( lbuf = switch_core_session_strdup ( session , data ) )
2007-03-29 22:31:56 +00:00
& & ( argc = switch_separate_string ( lbuf , ' = ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ) > 1 ) {
2006-11-28 02:23:26 +00:00
switch_size_t retsize ;
switch_time_exp_t tm ;
char date [ 80 ] = " " ;
2009-01-25 21:23:07 +00:00
switch_time_exp_lt ( & tm , switch_micro_time_now ( ) ) ;
2006-11-28 02:23:26 +00:00
switch_strftime ( date , & retsize , sizeof ( date ) , argv [ 1 ] , & tm ) ;
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " SET [%s]=[%s] \n " , argv [ 0 ] , date ) ;
2008-01-28 07:26:10 +00:00
switch_channel_set_variable ( switch_core_session_get_channel ( session ) , argv [ 0 ] , date ) ;
2006-11-28 02:23:26 +00:00
}
}
2007-05-12 21:36:15 +00:00
SWITCH_STANDARD_API ( strepoch_api_function )
2007-01-03 00:21:17 +00:00
{
2007-03-29 22:31:56 +00:00
switch_time_t out ;
2009-10-23 16:03:42 +00:00
if ( zstr ( cmd ) ) {
2009-01-25 21:23:07 +00:00
out = switch_micro_time_now ( ) ;
2007-03-29 22:31:56 +00:00
} else {
2007-05-12 21:36:15 +00:00
out = switch_str_time ( cmd ) ;
2007-03-29 22:31:56 +00:00
}
2007-01-03 00:21:17 +00:00
2007-03-29 22:31:56 +00:00
stream - > write_function ( stream , " %d " , ( uint32_t ) ( ( out ) / ( int64_t ) ( 1000000 ) ) ) ;
2007-01-05 16:49:36 +00:00
return SWITCH_STATUS_SUCCESS ;
2007-01-03 00:21:17 +00:00
}
2012-01-27 17:27:20 -06:00
SWITCH_STANDARD_API ( strmicroepoch_api_function )
{
switch_time_t out ;
if ( zstr ( cmd ) ) {
out = switch_micro_time_now ( ) ;
} else {
out = switch_str_time ( cmd ) ;
}
stream - > write_function ( stream , " % " SWITCH_TIME_T_FMT , out ) ;
return SWITCH_STATUS_SUCCESS ;
}
2007-05-12 21:36:15 +00:00
SWITCH_STANDARD_API ( strftime_api_function )
2006-11-28 02:23:26 +00:00
{
switch_size_t retsize ;
switch_time_exp_t tm ;
char date [ 80 ] = " " ;
2007-10-12 03:28:59 +00:00
switch_time_t thetime ;
2011-07-13 08:43:35 -05:00
char * p , * q = NULL ;
2010-12-10 17:47:24 -06:00
char * mycmd = NULL ;
if ( ! zstr ( cmd ) ) {
mycmd = strdup ( cmd ) ;
2011-07-13 08:43:35 -05:00
q = mycmd ;
2010-12-10 17:47:24 -06:00
}
2011-07-13 08:43:35 -05:00
if ( ! zstr ( q ) & & ( p = strchr ( q , ' | ' ) ) ) {
2010-12-10 17:47:24 -06:00
* p + + = ' \0 ' ;
2011-07-13 08:43:35 -05:00
thetime = switch_time_make ( atol ( q ) , 0 ) ;
q = p + 1 ;
2007-10-12 03:28:59 +00:00
} else {
2009-01-25 21:23:07 +00:00
thetime = switch_micro_time_now ( ) ;
2007-10-12 03:28:59 +00:00
}
switch_time_exp_lt ( & tm , thetime ) ;
2010-12-10 17:47:24 -06:00
2011-07-13 08:43:35 -05:00
if ( zstr ( q ) ) {
2008-10-12 21:51:51 +00:00
switch_strftime_nocheck ( date , & retsize , sizeof ( date ) , " %Y-%m-%d %T " , & tm ) ;
} else {
2011-07-13 08:43:35 -05:00
switch_strftime ( date , & retsize , sizeof ( date ) , q , & tm ) ;
2008-10-12 21:51:51 +00:00
}
2007-01-03 00:21:17 +00:00
stream - > write_function ( stream , " %s " , date ) ;
2011-07-08 22:11:15 -05:00
switch_safe_free ( mycmd ) ;
2006-11-28 02:23:26 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2009-04-27 15:52:34 +00:00
# define PRESENCE_USAGE "[in|out] <user> <rpid> <message>"
2007-05-12 21:36:15 +00:00
SWITCH_STANDARD_API ( presence_api_function )
2006-11-28 02:23:26 +00:00
{
switch_event_t * event ;
2010-02-06 03:38:24 +00:00
char * lbuf = NULL , * argv [ 4 ] ;
2006-11-28 02:23:26 +00:00
int argc = 0 ;
switch_event_types_t type = SWITCH_EVENT_PRESENCE_IN ;
2009-04-27 15:52:34 +00:00
int need = 4 ;
2006-11-28 02:23:26 +00:00
2009-10-23 16:03:42 +00:00
if ( ! zstr ( cmd ) & & ( lbuf = strdup ( cmd ) )
2009-04-27 15:52:34 +00:00
& & ( argc = switch_separate_string ( lbuf , ' ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ) > 0 ) {
2006-11-28 02:23:26 +00:00
if ( ! strcasecmp ( argv [ 0 ] , " out " ) ) {
type = SWITCH_EVENT_PRESENCE_OUT ;
2009-04-27 15:52:34 +00:00
need = 2 ;
} else if ( strcasecmp ( argv [ 0 ] , " in " ) ) {
goto error ;
}
2009-04-27 17:31:34 +00:00
if ( argc < need ) {
2009-04-27 15:52:34 +00:00
goto error ;
2006-11-28 02:23:26 +00:00
}
2007-03-29 22:31:56 +00:00
2006-11-28 02:23:26 +00:00
if ( switch_event_create ( & event , type ) = = SWITCH_STATUS_SUCCESS ) {
2008-08-16 02:19:43 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " proto " , " dp " ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " login " , __FILE__ ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " from " , argv [ 1 ] ) ;
2009-04-27 17:31:34 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " rpid " , argv [ 2 ] ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " status " , argv [ 3 ] ) ;
2006-11-28 02:23:26 +00:00
if ( type = = SWITCH_EVENT_PRESENCE_IN ) {
2009-04-27 17:31:34 +00:00
if ( ! strncasecmp ( argv [ 3 ] , " cs_ " , 3 ) | | switch_stristr ( " hangup " , argv [ 3 ] ) ) {
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " channel-state " , " CS_HANGUP " ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " status " , " CS_HANGUP " ) ;
}
} else {
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " status " , " CS_HANGUP " ) ;
2006-11-28 02:23:26 +00:00
}
2008-08-16 02:19:43 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " event_type " , " presence " ) ;
2009-04-27 15:52:34 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " alt_event_type " , " dialog " ) ;
2009-04-27 17:31:34 +00:00
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " event_count " , " %d " , 0 ) ;
2006-11-28 02:23:26 +00:00
switch_event_fire ( & event ) ;
}
stream - > write_function ( stream , " Event Sent " ) ;
} else {
2009-04-27 15:52:34 +00:00
goto error ;
2006-11-28 02:23:26 +00:00
}
2009-04-27 15:52:34 +00:00
2009-05-27 01:57:16 +00:00
switch_safe_free ( lbuf ) ;
2006-11-28 02:23:26 +00:00
return SWITCH_STATUS_SUCCESS ;
2009-04-27 15:52:34 +00:00
2010-02-06 03:38:24 +00:00
error :
2009-04-27 15:52:34 +00:00
2009-05-27 01:57:16 +00:00
switch_safe_free ( lbuf ) ;
2009-04-27 15:52:34 +00:00
stream - > write_function ( stream , " Invalid: presence %s " , PRESENCE_USAGE ) ;
return SWITCH_STATUS_SUCCESS ;
2006-11-28 02:23:26 +00:00
}
2007-05-12 21:36:15 +00:00
SWITCH_STANDARD_API ( chat_api_function )
2006-11-28 02:23:26 +00:00
{
2009-05-27 01:58:19 +00:00
char * lbuf = NULL , * argv [ 5 ] ;
2006-11-28 02:23:26 +00:00
int argc = 0 ;
2009-10-23 16:03:42 +00:00
if ( ! zstr ( cmd ) & & ( lbuf = strdup ( cmd ) )
2009-01-20 21:24:37 +00:00
& & ( argc = switch_separate_string ( lbuf , ' | ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ) > = 4 ) {
2011-10-07 08:23:40 -05:00
if ( switch_core_chat_send_args ( argv [ 0 ] , " global " , argv [ 1 ] , argv [ 2 ] , " " , argv [ 3 ] , ! zstr ( argv [ 4 ] ) ? argv [ 4 ] : NULL , " " ) = = SWITCH_STATUS_SUCCESS ) {
2009-01-20 20:49:47 +00:00
stream - > write_function ( stream , " Sent " ) ;
2006-11-28 02:23:26 +00:00
} else {
2009-01-20 20:49:47 +00:00
stream - > write_function ( stream , " Error! Message Not Sent " ) ;
2006-11-28 02:23:26 +00:00
}
} else {
stream - > write_function ( stream , " Invalid " ) ;
}
2007-03-29 22:31:56 +00:00
2009-05-27 01:58:19 +00:00
switch_safe_free ( lbuf ) ;
2006-11-28 02:23:26 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2006-12-04 05:50:41 +00:00
static char * ivr_cf_name = " ivr.conf " ;
# ifdef _TEST_CALLBACK_
2008-05-27 04:54:52 +00:00
static switch_ivr_action_t menu_handler ( switch_ivr_menu_t * menu , char * param , char * buf , size_t buflen , void * obj )
2006-12-04 05:50:41 +00:00
{
switch_ivr_action_t action = SWITCH_IVR_ACTION_NOOP ;
if ( param ! = NULL ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " menu_handler '%s' \n " , param ) ;
2006-12-04 05:50:41 +00:00
}
return action ;
}
# endif
2007-06-20 05:39:50 +00:00
SWITCH_STANDARD_APP ( ivr_application_function )
2006-12-04 05:50:41 +00:00
{
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
2008-01-23 20:59:25 +00:00
switch_event_t * params ;
2010-02-06 03:38:24 +00:00
const char * name = ( const char * ) data ;
2008-05-27 04:54:52 +00:00
2008-01-23 20:59:25 +00:00
if ( channel ) {
2006-12-04 05:50:41 +00:00
switch_xml_t cxml = NULL , cfg = NULL , xml_menus = NULL , xml_menu = NULL ;
2008-09-02 10:17:44 +00:00
/* Open the config from the xml registry */
2008-10-02 17:10:05 +00:00
switch_event_create ( & params , SWITCH_EVENT_REQUEST_PARAMS ) ;
2008-01-23 20:59:25 +00:00
switch_assert ( params ) ;
2009-03-19 04:15:14 +00:00
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " Menu-Name " , name ) ;
2008-01-23 20:59:25 +00:00
switch_channel_event_set_data ( channel , params ) ;
if ( ( cxml = switch_xml_open_cfg ( ivr_cf_name , & cfg , params ) ) ! = NULL ) {
2006-12-04 05:50:41 +00:00
if ( ( xml_menus = switch_xml_child ( cfg , " menus " ) ) ) {
2009-03-19 04:11:51 +00:00
xml_menu = switch_xml_find_child ( xml_menus , " menu " , " name " , name ) ;
2006-12-04 05:50:41 +00:00
2008-09-02 10:17:44 +00:00
/* if the menu was found */
2006-12-04 05:50:41 +00:00
if ( xml_menu ! = NULL ) {
switch_ivr_menu_xml_ctx_t * xml_ctx = NULL ;
switch_ivr_menu_t * menu_stack = NULL ;
2008-09-02 10:17:44 +00:00
/* build a menu tree and execute it */
2007-03-29 22:31:56 +00:00
if ( switch_ivr_menu_stack_xml_init ( & xml_ctx , NULL ) = = SWITCH_STATUS_SUCCESS
2006-12-04 05:50:41 +00:00
# ifdef _TEST_CALLBACK_
2007-03-30 00:13:31 +00:00
& & switch_ivr_menu_stack_xml_add_custom ( xml_ctx , " custom " , & menu_handler ) = = SWITCH_STATUS_SUCCESS
2006-12-04 05:50:41 +00:00
# endif
2007-03-30 00:13:31 +00:00
& & switch_ivr_menu_stack_xml_build ( xml_ctx , & menu_stack , xml_menus , xml_menu ) = = SWITCH_STATUS_SUCCESS ) {
2007-02-14 17:28:42 +00:00
switch_xml_free ( cxml ) ;
2007-02-14 17:34:16 +00:00
cxml = NULL ;
2010-02-06 03:38:24 +00:00
switch_ivr_menu_execute ( session , menu_stack , ( char * ) name , NULL ) ;
2006-12-04 05:50:41 +00:00
switch_ivr_menu_stack_free ( menu_stack ) ;
} else {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Unable to create menu \n " ) ;
2006-12-04 05:50:41 +00:00
}
} else {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Unable to find menu \n " ) ;
2006-12-04 05:50:41 +00:00
}
2011-01-09 14:42:42 -05:00
} else {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " No menus configured \n " ) ;
2006-12-04 05:50:41 +00:00
}
2007-02-14 17:34:16 +00:00
switch_xml_free ( cxml ) ;
2006-12-04 05:50:41 +00:00
} else {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Open of %s failed \n " , ivr_cf_name ) ;
2006-12-04 05:50:41 +00:00
}
2008-01-23 20:59:25 +00:00
switch_event_destroy ( & params ) ;
2006-12-04 05:50:41 +00:00
}
}
2006-11-28 02:23:26 +00:00
2007-06-20 05:39:50 +00:00
SWITCH_STANDARD_APP ( dtmf_session_function )
2007-06-04 17:12:43 +00:00
{
switch_ivr_inband_dtmf_session ( session ) ;
}
2007-06-20 05:39:50 +00:00
SWITCH_STANDARD_APP ( stop_dtmf_session_function )
2007-06-04 17:12:43 +00:00
{
2007-06-04 22:10:42 +00:00
switch_ivr_stop_inband_dtmf_session ( session ) ;
}
2007-06-04 17:12:43 +00:00
2007-10-31 16:44:02 +00:00
SWITCH_STANDARD_APP ( dtmf_session_generate_function )
{
switch_bool_t do_read = SWITCH_TRUE ;
2008-05-27 04:54:52 +00:00
2009-10-23 16:03:42 +00:00
if ( ! zstr ( data ) ) {
2007-10-31 16:44:02 +00:00
if ( ! strcasecmp ( data , " write " ) ) {
do_read = SWITCH_FALSE ;
}
2008-05-27 04:54:52 +00:00
}
2007-10-31 16:44:02 +00:00
switch_ivr_inband_dtmf_generate_session ( session , do_read ) ;
}
SWITCH_STANDARD_APP ( stop_dtmf_session_generate_function )
{
switch_ivr_stop_inband_dtmf_generate_session ( session ) ;
}
2007-06-20 05:39:50 +00:00
SWITCH_STANDARD_APP ( fax_detect_session_function )
2007-06-04 22:10:42 +00:00
{
2009-01-19 16:10:54 +00:00
switch_ivr_tone_detect_session ( session , " fax " , " 1100.0 " , " r " , 0 , 1 , NULL , NULL , NULL ) ;
2007-06-04 22:10:42 +00:00
}
2007-06-04 17:12:43 +00:00
2007-06-20 05:39:50 +00:00
SWITCH_STANDARD_APP ( system_session_function )
2007-06-20 02:19:29 +00:00
{
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_NOTICE , " Executing command: %s \n " , data ) ;
2008-09-26 15:50:12 +00:00
if ( switch_system ( data , SWITCH_TRUE ) < 0 ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_NOTICE , " Failed to execute command: %s \n " , data ) ;
2007-08-03 21:29:01 +00:00
}
2007-06-20 02:19:29 +00:00
}
2007-06-20 05:39:50 +00:00
SWITCH_STANDARD_APP ( tone_detect_session_function )
2007-06-15 17:39:18 +00:00
{
2008-11-18 02:05:11 +00:00
char * argv [ 7 ] = { 0 } ;
2007-06-16 02:25:40 +00:00
int argc ;
char * mydata = NULL ;
time_t to = 0 ;
2011-04-04 18:50:46 -05:00
int hits = 0 ;
const char * hp = NULL ;
2007-06-16 02:25:40 +00:00
2009-10-23 16:03:42 +00:00
if ( zstr ( data ) | | ! ( mydata = switch_core_session_strdup ( session , data ) ) ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " INVALID ARGS! \n " ) ;
2008-01-06 22:14:10 +00:00
return ;
}
2007-06-16 02:25:40 +00:00
if ( ( argc = switch_separate_string ( mydata , ' ' , argv , sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) < 2 ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " INVALID ARGS! \n " ) ;
2008-01-06 22:14:10 +00:00
return ;
2007-06-16 02:25:40 +00:00
}
2008-01-06 22:14:10 +00:00
2007-06-16 02:25:40 +00:00
if ( argv [ 3 ] ) {
uint32_t mto ;
2007-06-16 03:43:13 +00:00
if ( * argv [ 3 ] = = ' + ' ) {
2008-05-27 04:54:52 +00:00
if ( ( mto = atol ( argv [ 3 ] + 1 ) ) > 0 ) {
2009-01-25 21:23:07 +00:00
to = switch_epoch_time_now ( NULL ) + mto ;
2007-06-16 02:25:40 +00:00
} else {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " INVALID Timeout! \n " ) ;
2007-06-16 02:25:40 +00:00
}
} else {
2009-01-25 21:23:07 +00:00
if ( ( to = atol ( argv [ 3 ] ) ) < switch_epoch_time_now ( NULL ) ) {
2008-07-22 14:53:54 +00:00
if ( to > = 1 ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " INVALID Timeout! \n " ) ;
2008-07-22 14:53:54 +00:00
}
2007-06-16 02:25:40 +00:00
to = 0 ;
}
}
}
2011-04-04 18:50:46 -05:00
if ( argv [ 4 ] & & argv [ 5 ] ) {
hp = argv [ 6 ] ;
} else if ( argv [ 4 ] & & ! argv [ 6 ] ) {
hp = argv [ 4 ] ;
}
if ( hp ) {
hits = atoi ( hp ) ;
2008-11-18 02:05:11 +00:00
if ( hits < 0 ) {
2011-04-04 18:50:46 -05:00
hits = 0 ;
2008-11-18 02:05:11 +00:00
}
}
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_NOTICE , " Enabling tone detection '%s' '%s' \n " , argv [ 0 ] , argv [ 1 ] ) ;
2008-05-27 04:54:52 +00:00
2009-01-19 16:10:54 +00:00
switch_ivr_tone_detect_session ( session , argv [ 0 ] , argv [ 1 ] , argv [ 2 ] , to , hits , argv [ 4 ] , argv [ 5 ] , NULL ) ;
2007-06-15 17:39:18 +00:00
}
2007-06-20 05:39:50 +00:00
SWITCH_STANDARD_APP ( stop_fax_detect_session_function )
2007-06-04 22:10:42 +00:00
{
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_NOTICE , " Disabling tone detection \n " ) ;
2007-06-16 02:25:40 +00:00
switch_ivr_stop_tone_detect_session ( session ) ;
2007-06-04 17:12:43 +00:00
}
2007-06-20 05:39:50 +00:00
SWITCH_STANDARD_APP ( echo_function )
2007-06-13 16:00:14 +00:00
{
2008-09-25 19:53:43 +00:00
switch_ivr_session_echo ( session , NULL ) ;
2007-06-13 16:00:14 +00:00
}
2007-06-20 05:39:50 +00:00
SWITCH_STANDARD_APP ( park_function )
2007-06-13 16:00:14 +00:00
{
switch_ivr_park ( session , NULL ) ;
}
2007-12-13 22:17:20 +00:00
SWITCH_STANDARD_APP ( park_state_function )
{
switch_ivr_park_session ( session ) ;
}
2007-06-13 16:00:14 +00:00
/********************************************************************************/
/* Playback/Record Functions */
/********************************************************************************/
/*
dtmf handler function you can hook up to be executed when a digit is dialed during playback
if you return anything but SWITCH_STATUS_SUCCESS the playback will stop .
*/
2008-05-23 20:12:44 +00:00
static switch_status_t bridge_on_dtmf ( switch_core_session_t * session , void * input , switch_input_type_t itype , void * buf , unsigned int buflen )
{
char * str = ( char * ) buf ;
2008-05-27 04:54:52 +00:00
2008-05-23 20:12:44 +00:00
if ( str & & input & & itype = = SWITCH_INPUT_TYPE_DTMF ) {
switch_dtmf_t * dtmf = ( switch_dtmf_t * ) input ;
if ( strchr ( str , dtmf - > digit ) ) {
return SWITCH_STATUS_BREAK ;
}
}
return SWITCH_STATUS_SUCCESS ;
}
2007-06-13 16:00:14 +00:00
static switch_status_t on_dtmf ( switch_core_session_t * session , void * input , switch_input_type_t itype , void * buf , unsigned int buflen )
{
2008-09-26 16:04:16 +00:00
char sbuf [ 3 ] ;
2007-06-13 16:00:14 +00:00
switch ( itype ) {
2007-10-16 14:36:39 +00:00
case SWITCH_INPUT_TYPE_DTMF :
{
2007-12-22 00:32:20 +00:00
switch_dtmf_t * dtmf = ( switch_dtmf_t * ) input ;
2007-11-01 11:28:26 +00:00
const char * terminators ;
2007-10-16 14:36:39 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
2007-11-01 11:28:26 +00:00
const char * p ;
2007-10-16 14:36:39 +00:00
if ( ! ( terminators = switch_channel_get_variable ( channel , SWITCH_PLAYBACK_TERMINATORS_VARIABLE ) ) ) {
terminators = " * " ;
}
if ( ! strcasecmp ( terminators , " none " ) ) {
terminators = NULL ;
}
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Digit %c \n " , dtmf - > digit ) ;
2008-05-27 04:54:52 +00:00
2007-10-16 14:36:39 +00:00
for ( p = terminators ; p & & * p ; p + + ) {
2007-12-22 00:32:20 +00:00
if ( * p = = dtmf - > digit ) {
2008-09-26 16:04:16 +00:00
switch_snprintf ( sbuf , sizeof ( sbuf ) , " %c " , * p ) ;
2010-02-06 03:38:24 +00:00
switch_channel_set_variable ( channel , SWITCH_PLAYBACK_TERMINATOR_USED , sbuf ) ;
2007-12-22 00:32:20 +00:00
return SWITCH_STATUS_BREAK ;
2007-10-16 14:36:39 +00:00
}
2007-06-13 16:00:14 +00:00
}
}
break ;
default :
break ;
}
return SWITCH_STATUS_SUCCESS ;
}
2008-07-08 17:27:02 +00:00
SWITCH_STANDARD_APP ( sleep_function )
2008-09-26 18:03:17 +00:00
{
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
2009-10-23 16:03:42 +00:00
if ( zstr ( data ) ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " No timeout specified. \n " ) ;
2008-07-08 17:27:02 +00:00
} else {
uint32_t ms = atoi ( data ) ;
char buf [ 10 ] ;
switch_input_args_t args = { 0 } ;
2009-07-02 00:18:56 +00:00
if ( switch_true ( switch_channel_get_variable ( channel , " sleep_eat_digits " ) ) ) {
args . input_callback = on_dtmf ;
args . buf = buf ;
args . buflen = sizeof ( buf ) ;
2010-02-06 03:38:24 +00:00
switch_channel_set_variable ( channel , SWITCH_PLAYBACK_TERMINATOR_USED , " " ) ;
2009-07-02 00:18:56 +00:00
}
2008-09-26 16:04:16 +00:00
2008-12-10 00:48:24 +00:00
switch_ivr_sleep ( session , ms , SWITCH_TRUE , & args ) ;
2008-07-08 17:27:02 +00:00
}
}
2007-10-15 16:25:08 +00:00
SWITCH_STANDARD_APP ( clear_speech_cache_function )
{
switch_ivr_clear_speech_cache ( session ) ;
}
2007-06-13 16:00:14 +00:00
2007-06-20 05:39:50 +00:00
SWITCH_STANDARD_APP ( speak_function )
2007-06-13 16:00:14 +00:00
{
2008-01-06 22:14:10 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
2007-06-13 16:00:14 +00:00
char buf [ 10 ] ;
2012-04-18 08:53:38 -05:00
char * argv [ 3 ] = { 0 } ;
2007-06-13 16:00:14 +00:00
int argc ;
2007-11-01 11:28:26 +00:00
const char * engine = NULL ;
const char * voice = NULL ;
2007-06-13 16:00:14 +00:00
char * text = NULL ;
char * mydata = NULL ;
switch_input_args_t args = { 0 } ;
2009-10-23 16:03:42 +00:00
if ( zstr ( data ) | | ! ( mydata = switch_core_session_strdup ( session , data ) ) ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Invalid Params! \n " ) ;
2008-01-06 22:14:10 +00:00
return ;
}
2007-06-13 16:00:14 +00:00
argc = switch_separate_string ( mydata , ' | ' , argv , sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ;
2008-05-27 04:54:52 +00:00
2008-01-06 22:14:10 +00:00
if ( argc = = 0 ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Invalid Params! \n " ) ;
2008-01-06 22:14:10 +00:00
return ;
} else if ( argc = = 1 ) {
2012-04-18 08:53:38 -05:00
text = switch_core_session_strdup ( session , data ) ; /* unstripped text */
2007-10-15 16:25:08 +00:00
} else if ( argc = = 2 ) {
voice = argv [ 0 ] ;
2012-04-18 08:53:38 -05:00
text = switch_core_session_strdup ( session , data + ( argv [ 1 ] - argv [ 0 ] ) ) ; /* unstripped text */
2007-10-15 16:25:08 +00:00
} else {
engine = argv [ 0 ] ;
voice = argv [ 1 ] ;
2012-04-18 08:53:38 -05:00
text = switch_core_session_strdup ( session , data + ( argv [ 2 ] - argv [ 0 ] ) ) ; /* unstripped text */
2007-10-15 16:25:08 +00:00
}
if ( ! engine ) {
engine = switch_channel_get_variable ( channel , " tts_engine " ) ;
}
2007-06-13 16:00:14 +00:00
2007-10-15 16:25:08 +00:00
if ( ! voice ) {
voice = switch_channel_get_variable ( channel , " tts_voice " ) ;
}
2007-06-13 16:00:14 +00:00
if ( ! ( engine & & voice & & text ) ) {
if ( ! engine ) {
engine = " NULL " ;
}
if ( ! voice ) {
voice = " NULL " ;
}
if ( ! text ) {
text = " NULL " ;
}
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Invalid Params! [%s][%s][%s] \n " , engine , voice , text ) ;
2007-06-13 16:00:14 +00:00
switch_channel_hangup ( channel , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
}
args . input_callback = on_dtmf ;
args . buf = buf ;
args . buflen = sizeof ( buf ) ;
2008-09-26 16:04:16 +00:00
2010-02-06 03:38:24 +00:00
switch_channel_set_variable ( channel , SWITCH_PLAYBACK_TERMINATOR_USED , " " ) ;
2008-09-26 16:04:16 +00:00
2007-08-28 17:06:20 +00:00
switch_ivr_speak_text ( session , engine , voice , text , & args ) ;
2007-06-13 16:00:14 +00:00
}
2008-03-13 01:08:42 +00:00
static switch_status_t xfer_on_dtmf ( switch_core_session_t * session , void * input , switch_input_type_t itype , void * buf , unsigned int buflen )
{
switch_core_session_t * peer_session = ( switch_core_session_t * ) buf ;
if ( ! buf | | ! peer_session ) {
return SWITCH_STATUS_SUCCESS ;
}
switch ( itype ) {
case SWITCH_INPUT_TYPE_DTMF :
2008-05-27 04:54:52 +00:00
{
2008-03-13 01:08:42 +00:00
switch_dtmf_t * dtmf = ( switch_dtmf_t * ) input ;
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
switch_channel_t * peer_channel = switch_core_session_get_channel ( peer_session ) ;
2008-05-27 04:54:52 +00:00
2009-09-29 19:05:10 +00:00
if ( dtmf - > digit = = ' * ' ) {
switch_channel_hangup ( channel , SWITCH_CAUSE_NORMAL_CLEARING ) ;
return SWITCH_STATUS_FALSE ;
}
2008-03-13 01:08:42 +00:00
if ( dtmf - > digit = = ' # ' ) {
2009-07-31 19:09:50 +00:00
switch_channel_hangup ( peer_channel , SWITCH_CAUSE_NORMAL_CLEARING ) ;
2008-03-13 01:08:42 +00:00
return SWITCH_STATUS_FALSE ;
}
if ( dtmf - > digit = = ' 0 ' ) {
switch_caller_extension_t * extension = NULL ;
const char * app = " three_way " ;
const char * app_arg = switch_core_session_get_uuid ( session ) ;
2009-10-07 04:30:19 +00:00
const char * holding = switch_channel_get_variable ( channel , SWITCH_SOFT_HOLDING_UUID_VARIABLE ) ;
2008-03-13 01:08:42 +00:00
switch_core_session_t * b_session ;
if ( holding & & ( b_session = switch_core_session_locate ( holding ) ) ) {
switch_channel_t * b_channel = switch_core_session_get_channel ( b_session ) ;
if ( ! switch_channel_ready ( b_channel ) ) {
app = " intercept " ;
}
switch_core_session_rwunlock ( b_session ) ;
}
2008-05-27 04:54:52 +00:00
2008-03-13 01:08:42 +00:00
if ( ( extension = switch_caller_extension_new ( peer_session , app , app_arg ) ) = = 0 ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_CRIT , " Memory Error! \n " ) ;
2008-03-13 01:08:42 +00:00
abort ( ) ;
}
2008-05-27 04:54:52 +00:00
2008-03-13 01:08:42 +00:00
switch_caller_extension_add_application ( peer_session , extension , app , app_arg ) ;
switch_channel_set_caller_extension ( peer_channel , extension ) ;
2011-06-20 11:15:24 -05:00
switch_channel_set_state ( peer_channel , CS_RESET ) ;
switch_channel_wait_for_state ( peer_channel , channel , CS_RESET ) ;
2008-03-13 01:08:42 +00:00
switch_channel_set_state ( peer_channel , CS_EXECUTE ) ;
2008-05-15 15:42:13 +00:00
switch_channel_set_variable ( channel , SWITCH_HANGUP_AFTER_BRIDGE_VARIABLE , NULL ) ;
2008-03-13 01:08:42 +00:00
return SWITCH_STATUS_FALSE ;
}
2008-05-27 04:54:52 +00:00
2008-03-13 01:08:42 +00:00
}
break ;
default :
break ;
}
return SWITCH_STATUS_SUCCESS ;
}
static switch_status_t hanguphook ( switch_core_session_t * session )
{
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
switch_channel_state_t state = switch_channel_get_state ( channel ) ;
const char * id = NULL ;
2008-05-05 15:30:55 +00:00
if ( state = = CS_HANGUP | | state = = CS_ROUTING ) {
2008-03-13 01:08:42 +00:00
if ( ( id = switch_channel_get_variable ( channel , " xfer_uuids " ) ) ) {
switch_stream_handle_t stream = { 0 } ;
SWITCH_STANDARD_STREAM ( stream ) ;
switch_api_execute ( " uuid_bridge " , id , NULL , & stream ) ;
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " \n Hangup Command uuid_bridge(%s): \n %s \n " , id ,
switch_str_nil ( ( char * ) stream . data ) ) ;
2008-03-13 01:08:42 +00:00
switch_safe_free ( stream . data ) ;
}
2008-05-27 04:54:52 +00:00
2008-03-13 01:08:42 +00:00
switch_core_event_hook_remove_state_change ( session , hanguphook ) ;
}
return SWITCH_STATUS_SUCCESS ;
}
2012-05-07 11:41:47 -05:00
static void att_xfer_set_result ( switch_channel_t * channel , switch_status_t status )
{
switch_channel_set_variable ( channel , SWITCH_ATT_XFER_RESULT_VARIABLE , status = = SWITCH_STATUS_SUCCESS ? " success " : " failure " ) ;
}
2008-03-13 01:08:42 +00:00
SWITCH_STANDARD_APP ( att_xfer_function )
{
switch_core_session_t * peer_session = NULL ;
switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING ;
switch_channel_t * channel , * peer_channel = NULL ;
const char * bond = NULL ;
2008-05-19 21:02:26 +00:00
switch_core_session_t * b_session = NULL ;
2008-03-13 01:08:42 +00:00
channel = switch_core_session_get_channel ( session ) ;
2012-05-29 13:10:15 -05:00
if ( ( bond = switch_channel_get_partner_uuid ( channel ) ) ) {
2008-03-13 01:08:42 +00:00
bond = switch_core_session_strdup ( session , bond ) ;
}
2009-10-07 04:30:19 +00:00
switch_channel_set_variable ( channel , SWITCH_SOFT_HOLDING_UUID_VARIABLE , bond ) ;
2008-05-27 04:54:52 +00:00
2010-02-06 03:38:24 +00:00
if ( switch_ivr_originate ( session , & peer_session , & cause , data , 0 , NULL , NULL , NULL , NULL , NULL , SOF_NONE , NULL )
2008-12-05 14:59:24 +00:00
! = SWITCH_STATUS_SUCCESS | | ! peer_session ) {
2011-02-08 11:23:59 -06:00
switch_channel_set_variable ( channel , SWITCH_SIGNAL_BOND_VARIABLE , bond ) ;
2008-05-19 21:02:26 +00:00
goto end ;
2008-03-13 01:08:42 +00:00
}
peer_channel = switch_core_session_get_channel ( peer_session ) ;
switch_channel_set_flag ( peer_channel , CF_INNER_BRIDGE ) ;
switch_channel_set_flag ( channel , CF_INNER_BRIDGE ) ;
2008-05-27 04:54:52 +00:00
2008-03-13 01:08:42 +00:00
switch_ivr_multi_threaded_bridge ( session , peer_session , xfer_on_dtmf , peer_session , NULL ) ;
2008-05-27 04:54:52 +00:00
2008-05-15 21:36:32 +00:00
switch_channel_clear_flag ( peer_channel , CF_INNER_BRIDGE ) ;
switch_channel_clear_flag ( channel , CF_INNER_BRIDGE ) ;
2009-12-11 21:51:10 +00:00
if ( zstr ( bond ) & & switch_channel_down ( peer_channel ) ) {
2008-05-19 21:02:26 +00:00
switch_core_session_rwunlock ( peer_session ) ;
2011-02-08 11:23:59 -06:00
switch_channel_set_variable ( channel , SWITCH_SIGNAL_BOND_VARIABLE , bond ) ;
2008-05-19 21:02:26 +00:00
goto end ;
}
2008-03-13 01:08:42 +00:00
if ( bond ) {
char buf [ 128 ] = " " ;
2009-12-11 21:51:10 +00:00
int br = 0 ;
2008-03-13 01:08:42 +00:00
2009-12-11 21:51:10 +00:00
switch_channel_set_variable ( channel , SWITCH_SIGNAL_BOND_VARIABLE , bond ) ;
2008-03-13 01:08:42 +00:00
2009-12-11 21:51:10 +00:00
if ( ! switch_channel_down ( peer_channel ) ) {
if ( ! switch_channel_ready ( channel ) ) {
2012-05-07 11:41:47 -05:00
switch_status_t status = switch_ivr_uuid_bridge ( switch_core_session_get_uuid ( peer_session ) , bond ) ;
att_xfer_set_result ( peer_channel , status ) ;
2009-12-11 21:51:10 +00:00
br + + ;
} else if ( ( b_session = switch_core_session_locate ( bond ) ) ) {
switch_channel_t * b_channel = switch_core_session_get_channel ( b_session ) ;
switch_snprintf ( buf , sizeof ( buf ) , " %s %s " , switch_core_session_get_uuid ( peer_session ) , switch_core_session_get_uuid ( session ) ) ;
switch_channel_set_variable ( b_channel , " xfer_uuids " , buf ) ;
2010-02-06 03:38:24 +00:00
2009-12-11 21:51:10 +00:00
switch_snprintf ( buf , sizeof ( buf ) , " %s %s " , switch_core_session_get_uuid ( peer_session ) , bond ) ;
switch_channel_set_variable ( channel , " xfer_uuids " , buf ) ;
2010-02-06 03:38:24 +00:00
2009-12-11 21:51:10 +00:00
switch_core_event_hook_add_state_change ( session , hanguphook ) ;
switch_core_event_hook_add_state_change ( b_session , hanguphook ) ;
2010-02-06 03:38:24 +00:00
2009-12-11 21:51:10 +00:00
switch_core_session_rwunlock ( b_session ) ;
}
2008-03-13 01:08:42 +00:00
}
2008-05-27 04:54:52 +00:00
2009-12-11 21:51:10 +00:00
if ( ! br ) {
2012-05-07 11:41:47 -05:00
switch_status_t status = switch_ivr_uuid_bridge ( switch_core_session_get_uuid ( session ) , bond ) ;
att_xfer_set_result ( channel , status ) ;
2009-12-11 21:51:10 +00:00
}
2010-02-06 03:38:24 +00:00
2008-03-13 01:08:42 +00:00
}
2008-05-27 04:54:52 +00:00
2008-05-19 22:34:30 +00:00
switch_core_session_rwunlock ( peer_session ) ;
2008-05-27 04:54:52 +00:00
end :
2009-10-07 04:30:19 +00:00
switch_channel_set_variable ( channel , SWITCH_SOFT_HOLDING_UUID_VARIABLE , NULL ) ;
switch_channel_clear_flag ( channel , CF_XFER_ZOMBIE ) ;
2008-03-13 01:08:42 +00:00
}
2008-03-04 18:55:16 +00:00
SWITCH_STANDARD_APP ( read_function )
{
char * mydata ;
2010-09-23 18:37:45 -05:00
char * argv [ 7 ] = { 0 } ;
2008-03-04 18:55:16 +00:00
int argc ;
int32_t min_digits = 0 ;
int32_t max_digits = 0 ;
2010-09-23 18:37:45 -05:00
uint32_t digit_timeout = 0 ;
2008-03-04 18:55:16 +00:00
int timeout = 1000 ;
char digit_buffer [ 128 ] = " " ;
const char * prompt_audio_file = NULL ;
const char * var_name = NULL ;
const char * valid_terminators = NULL ;
2009-10-23 16:03:42 +00:00
if ( ! zstr ( data ) & & ( mydata = switch_core_session_strdup ( session , data ) ) ) {
2008-03-04 18:55:16 +00:00
argc = switch_separate_string ( mydata , ' ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ;
} else {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " No arguments specified. \n " ) ;
2008-03-04 18:55:16 +00:00
return ;
}
min_digits = atoi ( argv [ 0 ] ) ;
2008-05-27 04:54:52 +00:00
2008-03-04 18:55:16 +00:00
if ( argc > 1 ) {
max_digits = atoi ( argv [ 1 ] ) ;
}
if ( argc > 2 ) {
prompt_audio_file = argv [ 2 ] ;
}
2008-05-27 04:54:52 +00:00
2008-03-04 18:55:16 +00:00
if ( argc > 3 ) {
var_name = argv [ 3 ] ;
}
2008-05-27 04:54:52 +00:00
2008-03-04 18:55:16 +00:00
if ( argc > 4 ) {
timeout = atoi ( argv [ 4 ] ) ;
}
2008-05-27 04:54:52 +00:00
2008-03-04 18:55:16 +00:00
if ( argc > 5 ) {
valid_terminators = argv [ 5 ] ;
}
2008-05-27 04:54:52 +00:00
2010-09-23 18:37:45 -05:00
if ( argc > 6 ) {
2012-01-08 14:19:16 -06:00
digit_timeout = switch_atoui ( argv [ 6 ] ) ;
2010-09-23 18:37:45 -05:00
}
2008-03-04 18:55:16 +00:00
if ( min_digits < = 1 ) {
min_digits = 1 ;
}
if ( max_digits < min_digits ) {
max_digits = min_digits ;
}
2008-05-27 04:54:52 +00:00
2008-03-04 18:55:16 +00:00
if ( timeout < = 1000 ) {
timeout = 1000 ;
}
2009-10-23 16:03:42 +00:00
if ( zstr ( valid_terminators ) ) {
2008-03-04 18:55:16 +00:00
valid_terminators = " # " ;
}
2010-09-23 18:37:45 -05:00
switch_ivr_read ( session , min_digits , max_digits , prompt_audio_file , var_name , digit_buffer , sizeof ( digit_buffer ) , timeout , valid_terminators ,
digit_timeout ) ;
2008-03-04 18:55:16 +00:00
}
2009-01-14 20:29:16 +00:00
SWITCH_STANDARD_APP ( play_and_get_digits_function )
{
char * mydata ;
2011-08-18 20:29:52 -07:00
char * argv [ 11 ] = { 0 } ;
2009-01-14 20:29:16 +00:00
int argc ;
int32_t min_digits = 0 ;
int32_t max_digits = 0 ;
int32_t max_tries = 0 ;
2010-09-23 18:37:45 -05:00
uint32_t digit_timeout = 0 ;
2009-01-14 20:29:16 +00:00
int timeout = 1000 ;
char digit_buffer [ 128 ] = " " ;
const char * prompt_audio_file = NULL ;
const char * bad_input_audio_file = NULL ;
2009-01-15 03:42:45 +00:00
const char * var_name = NULL ;
2009-01-14 20:29:16 +00:00
const char * valid_terminators = NULL ;
const char * digits_regex = NULL ;
2011-08-18 20:29:52 -07:00
const char * transfer_on_failure = NULL ;
2009-01-14 20:29:16 +00:00
2009-10-23 16:03:42 +00:00
if ( ! zstr ( data ) & & ( mydata = switch_core_session_strdup ( session , data ) ) ) {
2009-01-14 20:29:16 +00:00
argc = switch_separate_string ( mydata , ' ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ;
} else {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " No arguments specified. \n " ) ;
2009-01-14 20:29:16 +00:00
return ;
}
min_digits = atoi ( argv [ 0 ] ) ;
if ( argc > 1 ) {
max_digits = atoi ( argv [ 1 ] ) ;
}
2008-11-21 13:56:32 +00:00
2009-01-14 20:29:16 +00:00
if ( argc > 2 ) {
max_tries = atoi ( argv [ 2 ] ) ;
}
if ( argc > 3 ) {
timeout = atoi ( argv [ 3 ] ) ;
}
if ( argc > 4 ) {
valid_terminators = argv [ 4 ] ;
}
if ( argc > 5 ) {
prompt_audio_file = argv [ 5 ] ;
}
if ( argc > 6 ) {
bad_input_audio_file = argv [ 6 ] ;
}
if ( argc > 7 ) {
2009-01-15 03:42:45 +00:00
var_name = argv [ 7 ] ;
}
if ( argc > 8 ) {
digits_regex = argv [ 8 ] ;
}
2010-09-23 18:37:45 -05:00
if ( argc > 9 ) {
2012-01-08 14:19:16 -06:00
digit_timeout = switch_atoui ( argv [ 9 ] ) ;
2010-09-23 18:37:45 -05:00
}
2011-08-18 20:29:52 -07:00
if ( argc > 10 ) {
transfer_on_failure = argv [ 10 ] ;
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Transfer on failure = [%s]. \n " , transfer_on_failure ) ;
}
2010-09-23 18:37:45 -05:00
2009-01-15 03:42:45 +00:00
if ( min_digits < = 1 ) {
min_digits = 1 ;
}
if ( max_digits < min_digits ) {
max_digits = min_digits ;
}
if ( timeout < = 1000 ) {
timeout = 1000 ;
2009-01-14 20:29:16 +00:00
}
2009-10-23 16:03:42 +00:00
if ( zstr ( valid_terminators ) ) {
2009-01-14 20:29:16 +00:00
valid_terminators = " # " ;
}
switch_play_and_get_digits ( session , min_digits , max_digits , max_tries , timeout , valid_terminators ,
2011-08-18 20:29:52 -07:00
prompt_audio_file , bad_input_audio_file , var_name , digit_buffer , sizeof ( digit_buffer ) ,
digits_regex , digit_timeout , transfer_on_failure ) ;
2009-01-14 20:29:16 +00:00
}
2008-11-21 13:56:32 +00:00
2011-04-01 10:35:20 -05:00
# define SAY_SYNTAX "<module_name>[:<lang>] <say_type> <say_method> [<say_gender>] <text>"
2008-11-21 13:56:32 +00:00
SWITCH_STANDARD_APP ( say_function )
2007-06-13 16:00:14 +00:00
{
2010-03-07 19:34:05 +00:00
char * argv [ 5 ] = { 0 } ;
2008-11-21 13:56:32 +00:00
int argc ;
char * lbuf = NULL ;
2007-06-13 16:00:14 +00:00
switch_input_args_t args = { 0 } ;
2008-09-26 18:03:17 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
2007-06-13 16:00:14 +00:00
2009-10-23 16:03:42 +00:00
if ( ! zstr ( data ) & & ( lbuf = switch_core_session_strdup ( session , data ) )
2010-03-07 19:34:05 +00:00
& & ( argc = switch_separate_string ( lbuf , ' ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ) & & ( argc = = 4 | | argc = = 5 ) ) {
2010-02-06 03:38:24 +00:00
2008-11-21 13:56:32 +00:00
args . input_callback = on_dtmf ;
2010-02-06 03:38:24 +00:00
switch_channel_set_variable ( channel , SWITCH_PLAYBACK_TERMINATOR_USED , " " ) ;
2011-04-01 10:35:20 -05:00
/* Set default langauge according to the <module_name> */
if ( ! strchr ( argv [ 0 ] , ' : ' ) ) {
argv [ 0 ] = switch_core_session_sprintf ( session , " %s:%s " , argv [ 0 ] , argv [ 0 ] ) ;
}
2010-03-07 19:34:05 +00:00
switch_ivr_say ( session , ( argc = = 4 ) ? argv [ 3 ] : argv [ 4 ] , argv [ 0 ] , argv [ 1 ] , argv [ 2 ] , ( argc = = 5 ) ? argv [ 3 ] : NULL , & args ) ;
2008-11-21 13:56:32 +00:00
} else {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Usage: %s \n " , SAY_SYNTAX ) ;
2008-11-21 13:56:32 +00:00
}
}
SWITCH_STANDARD_APP ( phrase_function )
{
char * mydata = NULL ;
switch_input_args_t args = { 0 } ;
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
2009-05-14 01:41:54 +00:00
switch_status_t status ;
2008-11-21 13:56:32 +00:00
2009-10-23 16:03:42 +00:00
if ( ! zstr ( data ) & & ( mydata = switch_core_session_strdup ( session , data ) ) ) {
2008-11-21 13:56:32 +00:00
const char * lang ;
char * macro = mydata ;
char * mdata = NULL ;
if ( ( mdata = strchr ( macro , ' , ' ) ) ) {
* mdata + + = ' \0 ' ;
}
2010-02-06 03:38:24 +00:00
2008-11-22 04:37:36 +00:00
lang = switch_channel_get_variable ( channel , " language " ) ;
2008-11-21 13:56:32 +00:00
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Execute %s(%s) lang %s \n " , macro , switch_str_nil ( mdata ) ,
switch_str_nil ( lang ) ) ;
2008-11-21 13:56:32 +00:00
args . input_callback = on_dtmf ;
2010-02-06 03:38:24 +00:00
switch_channel_set_variable ( channel , SWITCH_PLAYBACK_TERMINATOR_USED , " " ) ;
2008-11-21 13:56:32 +00:00
2009-05-14 01:41:54 +00:00
status = switch_ivr_phrase_macro ( session , macro , mdata , lang , & args ) ;
} else {
status = SWITCH_STATUS_NOOP ;
}
switch ( status ) {
case SWITCH_STATUS_SUCCESS :
case SWITCH_STATUS_BREAK :
switch_channel_set_variable ( channel , SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE , " PHRASE PLAYED " ) ;
break ;
case SWITCH_STATUS_NOOP :
switch_channel_set_variable ( channel , SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE , " NOTHING " ) ;
break ;
default :
switch_channel_set_variable ( channel , SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE , " UNKNOWN ERROR " ) ;
break ;
2008-11-21 13:56:32 +00:00
}
}
SWITCH_STANDARD_APP ( playback_function )
{
switch_input_args_t args = { 0 } ;
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
2009-04-28 23:46:18 +00:00
switch_status_t status = SWITCH_STATUS_SUCCESS ;
2009-09-02 20:43:49 +00:00
switch_file_handle_t fh = { 0 } ;
char * p ;
const char * file = NULL ;
2010-02-06 03:38:24 +00:00
2009-09-02 20:43:49 +00:00
if ( data ) {
file = switch_core_session_strdup ( session , data ) ;
2010-02-06 03:38:24 +00:00
if ( ( p = strchr ( file , ' @ ' ) ) & & * ( p + 1 ) = = ' @ ' ) {
2009-09-02 20:43:49 +00:00
* p = ' \0 ' ;
p + = 2 ;
if ( p & & * p ) {
fh . samples = atoi ( p ) ;
}
}
} else {
file = data ;
}
2007-06-13 16:00:14 +00:00
args . input_callback = on_dtmf ;
2008-09-26 16:04:16 +00:00
2010-02-06 03:38:24 +00:00
switch_channel_set_variable ( channel , SWITCH_PLAYBACK_TERMINATOR_USED , " " ) ;
2008-09-26 16:04:16 +00:00
2009-09-02 20:43:49 +00:00
status = switch_ivr_play_file ( session , & fh , file , & args ) ;
2008-12-08 15:42:37 +00:00
switch ( status ) {
case SWITCH_STATUS_SUCCESS :
case SWITCH_STATUS_BREAK :
switch_channel_set_variable ( channel , SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE , " FILE PLAYED " ) ;
break ;
case SWITCH_STATUS_NOTFOUND :
switch_channel_set_variable ( channel , SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE , " FILE NOT FOUND " ) ;
break ;
default :
switch_channel_set_variable ( channel , SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE , " PLAYBACK ERROR " ) ;
break ;
}
2007-06-13 16:00:14 +00:00
}
2009-10-07 04:30:19 +00:00
SWITCH_STANDARD_APP ( endless_playback_function )
{
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
switch_status_t status = SWITCH_STATUS_SUCCESS ;
const char * file = data ;
2010-02-06 03:38:24 +00:00
while ( switch_channel_ready ( channel ) ) {
2009-10-08 16:14:45 +00:00
status = switch_ivr_play_file ( session , NULL , file , NULL ) ;
if ( status ! = SWITCH_STATUS_SUCCESS & & status ! = SWITCH_STATUS_BREAK ) {
2009-10-07 04:30:19 +00:00
break ;
}
}
switch ( status ) {
case SWITCH_STATUS_SUCCESS :
case SWITCH_STATUS_BREAK :
switch_channel_set_variable ( channel , SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE , " FILE PLAYED " ) ;
break ;
case SWITCH_STATUS_NOTFOUND :
switch_channel_set_variable ( channel , SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE , " FILE NOT FOUND " ) ;
break ;
default :
switch_channel_set_variable ( channel , SWITCH_CURRENT_APPLICATION_RESPONSE_VARIABLE , " PLAYBACK ERROR " ) ;
break ;
}
}
2007-06-20 05:39:50 +00:00
SWITCH_STANDARD_APP ( gentones_function )
2007-06-17 01:16:39 +00:00
{
char * tone_script = NULL ;
switch_input_args_t args = { 0 } ;
char * l ;
int32_t loops = 0 ;
2008-09-26 18:03:17 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
2007-06-17 01:16:39 +00:00
2009-10-23 16:03:42 +00:00
if ( zstr ( data ) | | ! ( tone_script = switch_core_session_strdup ( session , data ) ) ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Invalid Params! \n " ) ;
2008-01-06 22:14:10 +00:00
return ;
}
2007-06-17 01:16:39 +00:00
if ( ( l = strchr ( tone_script , ' | ' ) ) ) {
* l + + = ' \0 ' ;
loops = atoi ( l ) ;
if ( loops < 0 ) {
loops = - 1 ;
}
}
args . input_callback = on_dtmf ;
2008-09-26 16:04:16 +00:00
2010-02-06 03:38:24 +00:00
switch_channel_set_variable ( channel , SWITCH_PLAYBACK_TERMINATOR_USED , " " ) ;
2008-09-26 16:04:16 +00:00
2007-06-17 01:16:39 +00:00
switch_ivr_gentones ( session , tone_script , loops , & args ) ;
}
2007-06-20 05:39:50 +00:00
SWITCH_STANDARD_APP ( displace_session_function )
2007-06-15 01:47:48 +00:00
{
char * path = NULL ;
uint32_t limit = 0 ;
2008-01-06 22:14:10 +00:00
char * argv [ 6 ] = { 0 } ;
2007-06-15 01:47:48 +00:00
int x , argc ;
char * lbuf = NULL ;
char * flags = NULL ;
2009-10-23 16:03:42 +00:00
if ( ! zstr ( data ) & & ( lbuf = switch_core_session_strdup ( session , data ) )
2007-06-15 01:47:48 +00:00
& & ( argc = switch_separate_string ( lbuf , ' ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ) ) {
path = argv [ 0 ] ;
2008-05-27 04:54:52 +00:00
for ( x = 1 ; x < argc ; x + + ) {
2007-06-15 01:47:48 +00:00
if ( strchr ( argv [ x ] , ' + ' ) ) {
limit = atoi ( argv [ x ] ) ;
2009-10-23 16:03:42 +00:00
} else if ( ! zstr ( argv [ x ] ) ) {
2007-06-15 01:47:48 +00:00
flags = argv [ x ] ;
}
}
switch_ivr_displace_session ( session , path , limit , flags ) ;
}
}
2007-06-20 05:39:50 +00:00
SWITCH_STANDARD_APP ( stop_displace_session_function )
2007-06-15 01:47:48 +00:00
{
switch_ivr_stop_displace_session ( session , data ) ;
}
2011-05-25 16:12:42 -05:00
SWITCH_STANDARD_APP ( capture_function )
{
char * argv [ 3 ] = { 0 } ;
int argc ;
switch_regex_t * re = NULL ;
int ovector [ 30 ] = { 0 } ;
char * lbuf ;
int proceed ;
if ( ! zstr ( data ) & & ( lbuf = switch_core_session_strdup ( session , data ) )
& & ( argc = switch_separate_string ( lbuf , ' | ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ) = = 3 ) {
if ( ( proceed = switch_regex_perform ( argv [ 1 ] , argv [ 2 ] , & re , ovector , sizeof ( ovector ) / sizeof ( ovector [ 0 ] ) ) ) ) {
2011-05-26 08:39:28 -05:00
switch_capture_regex ( re , proceed , argv [ 1 ] , ovector , argv [ 0 ] , switch_regex_set_var_callback , session ) ;
2011-05-25 16:12:42 -05:00
}
switch_regex_safe_free ( re ) ;
} else {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " No data specified. \n " ) ;
}
}
2007-06-20 05:39:50 +00:00
SWITCH_STANDARD_APP ( record_function )
2007-06-13 16:00:14 +00:00
{
2008-01-06 22:14:10 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
2007-06-13 16:00:14 +00:00
switch_status_t status ;
uint32_t limit = 0 ;
char * path ;
switch_input_args_t args = { 0 } ;
2007-07-24 21:42:54 +00:00
switch_file_handle_t fh = { 0 } ;
2011-04-22 16:43:29 -05:00
//int argc;
2008-05-27 04:54:52 +00:00
char * mydata , * argv [ 4 ] = { 0 } ;
2007-07-24 21:42:54 +00:00
char * l = NULL ;
2007-12-12 21:30:55 +00:00
const char * tmp ;
int rate ;
2009-10-23 16:03:42 +00:00
if ( ! zstr ( data ) & & ( mydata = switch_core_session_strdup ( session , data ) ) ) {
2011-04-22 16:43:29 -05:00
switch_separate_string ( mydata , ' ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ;
2007-07-24 21:42:54 +00:00
} else {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " No file specified. \n " ) ;
2007-07-24 21:42:54 +00:00
return ;
}
2008-05-27 04:54:52 +00:00
2007-07-24 21:42:54 +00:00
path = argv [ 0 ] ;
l = argv [ 1 ] ;
if ( l ) {
if ( * l = = ' + ' ) {
l + + ;
2008-01-05 22:17:26 +00:00
}
if ( l ) {
2012-01-08 14:19:16 -06:00
limit = switch_atoui ( l ) ;
2007-07-24 21:42:54 +00:00
}
}
2007-06-13 16:00:14 +00:00
2007-07-24 21:42:54 +00:00
if ( argv [ 2 ] ) {
2012-01-08 14:19:16 -06:00
fh . thresh = switch_atoui ( argv [ 2 ] ) ;
2007-07-24 21:42:54 +00:00
}
if ( argv [ 3 ] ) {
2012-01-08 14:19:16 -06:00
fh . silence_hits = switch_atoui ( argv [ 3 ] ) ;
2007-06-13 16:00:14 +00:00
}
2007-12-12 21:30:55 +00:00
if ( ( tmp = switch_channel_get_variable ( channel , " record_rate " ) ) ) {
rate = atoi ( tmp ) ;
if ( rate > 0 ) {
fh . samplerate = rate ;
}
}
2007-06-13 16:00:14 +00:00
args . input_callback = on_dtmf ;
2008-09-26 16:04:16 +00:00
2010-02-06 03:38:24 +00:00
switch_channel_set_variable ( channel , SWITCH_PLAYBACK_TERMINATOR_USED , " " ) ;
2008-09-26 16:04:16 +00:00
2007-07-24 21:42:54 +00:00
status = switch_ivr_record_file ( session , & fh , path , & args , limit ) ;
2007-06-13 16:00:14 +00:00
if ( ! switch_channel_ready ( channel ) | | ( status ! = SWITCH_STATUS_SUCCESS & & ! SWITCH_STATUS_IS_BREAK ( status ) ) ) {
switch_channel_hangup ( channel , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
}
}
2009-09-23 22:39:00 +00:00
SWITCH_STANDARD_APP ( preprocess_session_function )
{
2010-02-06 03:38:24 +00:00
switch_ivr_preprocess_session ( session , ( char * ) data ) ;
2009-09-23 22:39:00 +00:00
}
2007-06-20 05:39:50 +00:00
SWITCH_STANDARD_APP ( record_session_function )
2007-06-13 16:00:14 +00:00
{
2008-09-26 18:03:17 +00:00
char * path = NULL ;
char * path_end ;
2007-06-13 16:00:14 +00:00
uint32_t limit = 0 ;
2009-10-23 16:03:42 +00:00
if ( zstr ( data ) ) {
2008-01-06 22:36:41 +00:00
return ;
}
2007-06-13 16:00:14 +00:00
path = switch_core_session_strdup ( session , data ) ;
2008-05-19 22:36:25 +00:00
2008-09-26 18:03:17 +00:00
/* Search for a space then a plus followed by only numbers at the end of the path,
if found trim any spaces to the left / right of the plus use the left side as the
path and right side as a time limit on the recording
2010-02-06 03:38:24 +00:00
*/
2008-09-26 18:03:17 +00:00
2008-09-26 18:17:11 +00:00
/* if we find a + and the character before it is a space */
2008-09-26 18:03:17 +00:00
if ( ( path_end = strrchr ( path , ' + ' ) ) & & path_end > path & & * ( path_end - 1 ) = = ' ' ) {
char * limit_start = path_end + 1 ;
/* not at the end and the rest is numbers lets parse out the limit and fix up the path */
if ( * limit_start ! = ' \0 ' & & switch_is_number ( limit_start ) = = SWITCH_TRUE ) {
limit = atoi ( limit_start ) ;
2008-10-06 23:05:55 +00:00
/* back it off by one character to the char before the + */
2008-09-26 18:03:17 +00:00
path_end - - ;
/* trim spaces to the left of the plus */
2010-02-06 03:38:24 +00:00
while ( path_end > path & & * path_end = = ' ' ) {
2008-09-26 18:03:17 +00:00
path_end - - ;
}
2008-05-19 22:36:25 +00:00
2008-09-26 18:03:17 +00:00
* ( path_end + 1 ) = ' \0 ' ;
2007-06-13 16:00:14 +00:00
}
}
switch_ivr_record_session ( session , path , limit , NULL ) ;
}
2007-06-20 05:39:50 +00:00
SWITCH_STANDARD_APP ( stop_record_session_function )
2007-06-13 16:00:14 +00:00
{
switch_ivr_stop_record_session ( session , data ) ;
}
/********************************************************************************/
/* Bridge Functions */
/********************************************************************************/
2009-10-23 22:37:49 +00:00
static switch_status_t camp_fire ( switch_core_session_t * session , void * input , switch_input_type_t itype , void * buf , unsigned int buflen )
{
switch ( itype ) {
case SWITCH_INPUT_TYPE_DTMF :
{
switch_dtmf_t * dtmf = ( switch_dtmf_t * ) input ;
char * key = ( char * ) buf ;
if ( dtmf - > digit = = * key ) {
return SWITCH_STATUS_BREAK ;
}
}
default :
break ;
}
return SWITCH_STATUS_SUCCESS ;
}
2009-10-22 22:11:28 +00:00
struct camping_stake {
switch_core_session_t * session ;
int running ;
2009-10-23 22:37:49 +00:00
int do_xfer ;
2009-10-22 22:11:28 +00:00
const char * moh ;
} ;
static void * SWITCH_THREAD_FUNC camp_music_thread ( switch_thread_t * thread , void * obj )
{
struct camping_stake * stake = ( struct camping_stake * ) obj ;
switch_core_session_t * session = stake - > session ;
switch_channel_t * channel = switch_core_session_get_channel ( stake - > session ) ;
2009-10-23 22:37:49 +00:00
const char * moh = stake - > moh , * greet = NULL ;
switch_input_args_t args = { 0 } ;
char dbuf [ 2 ] = " " ;
switch_status_t status = SWITCH_STATUS_FALSE ;
const char * stop ;
if ( ( stop = switch_channel_get_variable ( channel , " campon_stop_key " ) ) ) {
* dbuf = * stop ;
}
2009-10-22 22:11:28 +00:00
2009-10-23 22:37:49 +00:00
args . input_callback = camp_fire ;
args . buf = dbuf ;
args . buflen = sizeof ( dbuf ) ;
2010-02-06 03:38:24 +00:00
2009-10-22 22:11:28 +00:00
switch_core_session_read_lock ( session ) ;
2009-10-23 22:37:49 +00:00
/* don't set this to a local_stream:// or you will not be happy */
if ( ( greet = switch_channel_get_variable ( channel , " campon_announce_sound " ) ) ) {
status = switch_ivr_play_file ( session , NULL , greet , & args ) ;
}
2010-02-06 03:38:24 +00:00
while ( stake - > running & & switch_channel_ready ( channel ) ) {
2009-10-23 22:37:49 +00:00
if ( status ! = SWITCH_STATUS_BREAK ) {
if ( ! strcasecmp ( moh , " silence " ) ) {
status = switch_ivr_collect_digits_callback ( session , & args , 0 , 0 ) ;
} else {
status = switch_ivr_play_file ( session , NULL , stake - > moh , & args ) ;
}
}
if ( status = = SWITCH_STATUS_BREAK ) {
switch_channel_set_flag ( channel , CF_NOT_READY ) ;
stake - > do_xfer = 1 ;
2009-10-22 22:11:28 +00:00
}
}
switch_core_session_rwunlock ( session ) ;
2009-10-23 22:37:49 +00:00
stake - > running = 0 ;
2011-07-06 16:45:25 -05:00
2009-10-22 22:11:28 +00:00
return NULL ;
}
2007-06-20 05:39:50 +00:00
SWITCH_STANDARD_APP ( audio_bridge_function )
2007-06-13 16:00:14 +00:00
{
2008-01-06 22:14:10 +00:00
switch_channel_t * caller_channel = switch_core_session_get_channel ( session ) ;
2007-06-13 16:00:14 +00:00
switch_core_session_t * peer_session = NULL ;
2011-03-29 12:52:06 -05:00
const char * transfer_on_fail = NULL ;
char * tof_data = NULL ;
char * tof_array [ 4 ] = { 0 } ;
2011-04-22 16:43:29 -05:00
//int tof_arrayc = 0;
2011-05-27 09:49:02 -05:00
const char * v_campon = NULL , * v_campon_retries , * v_campon_sleep , * v_campon_timeout , * v_campon_fallback_exten = NULL ;
2007-06-13 16:00:14 +00:00
switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING ;
2009-10-23 22:37:49 +00:00
int campon_retries = 100 , campon_timeout = 10 , campon_sleep = 10 , tmp , camping = 0 , fail = 0 , thread_started = 0 ;
2009-10-22 22:11:28 +00:00
struct camping_stake stake = { 0 } ;
const char * moh = NULL ;
switch_thread_t * thread = NULL ;
switch_threadattr_t * thd_attr = NULL ;
char * camp_data = NULL ;
2012-04-18 08:53:38 -05:00
switch_status_t status = SWITCH_STATUS_FALSE ;
2011-07-06 16:45:25 -05:00
int camp_loops = 0 ;
2010-02-06 03:38:24 +00:00
2009-10-23 16:03:42 +00:00
if ( zstr ( data ) ) {
2007-06-13 16:00:14 +00:00
return ;
}
2011-03-29 12:52:06 -05:00
transfer_on_fail = switch_channel_get_variable ( caller_channel , " transfer_on_fail " ) ;
tof_data = switch_core_session_strdup ( session , transfer_on_fail ) ;
2011-04-22 16:43:29 -05:00
switch_split ( tof_data , ' ' , tof_array ) ;
2011-03-29 12:52:06 -05:00
transfer_on_fail = tof_array [ 0 ] ;
2009-10-22 22:11:28 +00:00
if ( ( v_campon = switch_channel_get_variable ( caller_channel , " campon " ) ) & & switch_true ( v_campon ) ) {
const char * cid_name = NULL ;
const char * cid_number = NULL ;
2010-02-06 03:38:24 +00:00
2009-10-22 22:11:28 +00:00
if ( ! ( cid_name = switch_channel_get_variable ( caller_channel , " effective_caller_id_name " ) ) ) {
cid_name = switch_channel_get_variable ( caller_channel , " caller_id_name " ) ;
}
if ( ! ( cid_number = switch_channel_get_variable ( caller_channel , " effective_caller_id_number " ) ) ) {
cid_number = switch_channel_get_variable ( caller_channel , " caller_id_number " ) ;
}
if ( cid_name & & ! cid_number ) {
cid_number = cid_name ;
}
if ( cid_number & & ! cid_name ) {
cid_name = cid_number ;
}
v_campon_retries = switch_channel_get_variable ( caller_channel , " campon_retries " ) ;
v_campon_timeout = switch_channel_get_variable ( caller_channel , " campon_timeout " ) ;
v_campon_sleep = switch_channel_get_variable ( caller_channel , " campon_sleep " ) ;
v_campon_fallback_exten = switch_channel_get_variable ( caller_channel , " campon_fallback_exten " ) ;
2010-02-06 03:38:24 +00:00
2009-10-22 22:11:28 +00:00
if ( v_campon_retries ) {
if ( ( tmp = atoi ( v_campon_retries ) ) > 0 ) {
campon_retries = tmp ;
}
}
if ( v_campon_timeout ) {
if ( ( tmp = atoi ( v_campon_timeout ) ) > 0 ) {
campon_timeout = tmp ;
}
}
if ( v_campon_sleep ) {
if ( ( tmp = atoi ( v_campon_sleep ) ) > 0 ) {
campon_sleep = tmp ;
}
}
switch_channel_answer ( caller_channel ) ;
camping = 1 ;
if ( cid_name & & cid_number ) {
2010-02-06 03:38:24 +00:00
camp_data = switch_core_session_sprintf ( session , " {origination_caller_id_name='%s',origination_caller_id_number='%s'}%s " ,
2009-10-22 22:11:28 +00:00
cid_name , cid_number , data ) ;
} else {
2010-02-06 03:38:24 +00:00
camp_data = ( char * ) data ;
2009-10-22 22:11:28 +00:00
}
2011-01-05 18:58:56 -06:00
if ( ! ( moh = switch_channel_get_hold_music ( caller_channel ) ) ) {
2009-10-22 22:11:28 +00:00
moh = switch_channel_get_variable ( caller_channel , " campon_hold_music " ) ;
}
do {
fail = 0 ;
2010-02-06 03:38:24 +00:00
2009-10-22 22:11:28 +00:00
if ( ! switch_channel_ready ( caller_channel ) ) {
fail = 1 ;
break ;
}
2010-02-06 03:38:24 +00:00
2009-10-22 22:11:28 +00:00
if ( status = = SWITCH_STATUS_SUCCESS ) {
camping = 0 ;
break ;
} else {
fail = 1 ;
}
2010-02-06 03:38:24 +00:00
2009-10-22 22:11:28 +00:00
if ( camping ) {
2010-02-06 03:38:24 +00:00
if ( ! thread_started & & fail & & moh & & ! switch_channel_test_flag ( caller_channel , CF_PROXY_MODE ) & &
2009-10-22 22:11:28 +00:00
! switch_channel_test_flag ( caller_channel , CF_PROXY_MEDIA ) & &
! switch_true ( switch_channel_get_variable ( caller_channel , " bypass_media " ) ) ) {
switch_threadattr_create ( & thd_attr , switch_core_session_get_pool ( session ) ) ;
switch_threadattr_stacksize_set ( thd_attr , SWITCH_THREAD_STACKSIZE ) ;
stake . running = 1 ;
stake . moh = moh ;
stake . session = session ;
switch_thread_create ( & thread , thd_attr , camp_music_thread , & stake , switch_core_session_get_pool ( session ) ) ;
thread_started = 1 ;
}
2011-07-06 16:45:25 -05:00
if ( camp_loops + + ) {
if ( - - campon_retries < = 0 | | stake . do_xfer ) {
camping = 0 ;
stake . do_xfer = 1 ;
break ;
}
2009-10-22 22:11:28 +00:00
2011-07-06 16:45:25 -05:00
if ( fail ) {
int64_t wait = campon_sleep * 1000000 ;
while ( stake . running & & wait > 0 & & switch_channel_ready ( caller_channel ) ) {
switch_yield ( 100000 ) ;
wait - = 100000 ;
}
2009-10-22 22:11:28 +00:00
}
}
}
2011-07-06 16:45:25 -05:00
status = switch_ivr_originate ( NULL , & peer_session ,
& cause , camp_data , campon_timeout , NULL , NULL , NULL , NULL , NULL , SOF_NONE ,
switch_channel_get_cause_ptr ( caller_channel ) ) ;
2009-10-23 22:37:49 +00:00
} while ( camping & & switch_channel_ready ( caller_channel ) ) ;
2010-02-06 03:38:24 +00:00
2009-10-22 22:11:28 +00:00
if ( thread ) {
stake . running = 0 ;
switch_channel_set_flag ( caller_channel , CF_NOT_READY ) ;
switch_thread_join ( & status , thread ) ;
}
2009-10-23 22:37:49 +00:00
switch_channel_clear_flag ( caller_channel , CF_NOT_READY ) ;
2010-02-06 03:38:24 +00:00
2009-10-23 22:37:49 +00:00
if ( stake . do_xfer & & ! zstr ( v_campon_fallback_exten ) ) {
2010-02-06 03:38:24 +00:00
switch_ivr_session_transfer ( session ,
v_campon_fallback_exten ,
2009-10-22 22:11:28 +00:00
switch_channel_get_variable ( caller_channel , " campon_fallback_dialplan " ) ,
switch_channel_get_variable ( caller_channel , " campon_fallback_context " ) ) ;
2012-02-22 21:48:03 -06:00
if ( peer_session ) {
switch_channel_hangup ( switch_core_session_get_channel ( peer_session ) , SWITCH_CAUSE_ORIGINATOR_CANCEL ) ;
switch_core_session_rwunlock ( peer_session ) ;
}
2009-10-22 22:11:28 +00:00
return ;
}
} else {
2010-02-06 03:38:24 +00:00
if ( ( status =
switch_ivr_originate ( session , & peer_session , & cause , data , 0 , NULL , NULL , NULL , NULL , NULL , SOF_NONE , NULL ) ) ! = SWITCH_STATUS_SUCCESS ) {
2009-10-22 22:11:28 +00:00
fail = 1 ;
}
}
if ( fail ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_INFO , " Originate Failed. Cause: %s \n " , switch_channel_cause2str ( cause ) ) ;
2007-10-15 14:00:48 +00:00
/*
if the variable continue_on_fail is set it can be :
' true ' to continue on all failures .
' false ' to not continue .
2007-11-15 16:22:18 +00:00
A list of codes either names or numbers eg " user_busy,normal_temporary_failure,603 "
2010-02-06 03:38:24 +00:00
failure_causes acts as the opposite version
2009-11-05 06:56:16 +00:00
EXCEPTION . . . ATTENDED_TRANSFER never is a reason to continue . . . . . . .
2008-05-27 04:54:52 +00:00
*/
2009-11-05 06:56:16 +00:00
if ( cause ! = SWITCH_CAUSE_ATTENDED_TRANSFER ) {
2011-05-27 09:49:02 -05:00
const char * continue_on_fail = NULL , * failure_causes = NULL ;
continue_on_fail = switch_channel_get_variable ( caller_channel , " continue_on_fail " ) ;
failure_causes = switch_channel_get_variable ( caller_channel , " failure_causes " ) ;
2009-11-05 06:56:16 +00:00
if ( continue_on_fail | | failure_causes ) {
const char * cause_str ;
char cause_num [ 35 ] = " " ;
2010-02-06 03:38:24 +00:00
2009-11-05 06:56:16 +00:00
cause_str = switch_channel_cause2str ( cause ) ;
switch_snprintf ( cause_num , sizeof ( cause_num ) , " %u " , cause ) ;
2010-02-06 03:38:24 +00:00
2009-11-05 06:56:16 +00:00
if ( failure_causes ) {
char * lbuf = switch_core_session_strdup ( session , failure_causes ) ;
char * argv [ 256 ] = { 0 } ;
int argc = switch_separate_string ( lbuf , ' , ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ;
int i , x = 0 ;
2010-02-06 03:38:24 +00:00
2009-11-05 06:56:16 +00:00
for ( i = 0 ; i < argc ; i + + ) {
if ( ! strcasecmp ( argv [ i ] , cause_str ) | | ! strcasecmp ( argv [ i ] , cause_num ) ) {
x + + ;
break ;
}
2010-01-24 08:49:18 +00:00
}
if ( ! x ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG ,
2010-01-24 08:55:48 +00:00
" Failure causes [%s]: Cause: %s \n " , failure_causes , cause_str ) ;
2010-01-24 08:49:18 +00:00
return ;
2009-11-05 06:56:16 +00:00
}
}
2009-03-29 18:11:30 +00:00
2009-11-05 06:56:16 +00:00
if ( continue_on_fail ) {
2009-11-05 18:39:43 +00:00
if ( switch_true ( continue_on_fail ) ) {
return ;
} else {
char * lbuf = switch_core_session_strdup ( session , continue_on_fail ) ;
char * argv [ 256 ] = { 0 } ;
int argc = switch_separate_string ( lbuf , ' , ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ;
int i ;
2010-02-06 03:38:24 +00:00
2009-11-05 18:39:43 +00:00
for ( i = 0 ; i < argc ; i + + ) {
if ( ! strcasecmp ( argv [ i ] , cause_str ) | | ! strcasecmp ( argv [ i ] , cause_num ) ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG ,
2009-11-05 18:39:43 +00:00
" Continue on fail [%s]: Cause: %s \n " , continue_on_fail , cause_str ) ;
return ;
}
2009-11-05 06:56:16 +00:00
}
}
}
} else {
/* no answer is *always* a reason to continue */
if ( cause = = SWITCH_CAUSE_NO_ANSWER | | cause = = SWITCH_CAUSE_NO_USER_RESPONSE | | cause = = SWITCH_CAUSE_ORIGINATOR_CANCEL ) {
return ;
}
2009-09-24 22:41:37 +00:00
}
2011-03-29 12:52:06 -05:00
if ( transfer_on_fail | | failure_causes ) {
const char * cause_str ;
char cause_num [ 35 ] = " " ;
cause_str = switch_channel_cause2str ( cause ) ;
switch_snprintf ( cause_num , sizeof ( cause_num ) , " %u " , cause ) ;
if ( ( tof_array [ 1 ] = = NULL ) | | ( ! strcasecmp ( tof_array [ 1 ] , " auto_cause " ) ) ) {
tof_array [ 1 ] = ( char * ) cause_str ;
}
if ( failure_causes ) {
char * lbuf = switch_core_session_strdup ( session , failure_causes ) ;
char * argv [ 256 ] = { 0 } ;
int argc = switch_separate_string ( lbuf , ' , ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ;
int i , x = 0 ;
for ( i = 0 ; i < argc ; i + + ) {
if ( ! strcasecmp ( argv [ i ] , cause_str ) | | ! strcasecmp ( argv [ i ] , cause_num ) ) {
x + + ;
break ;
}
}
if ( ! x ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG ,
" Failure causes [%s]: Cause: %s \n " , failure_causes , cause_str ) ;
switch_ivr_session_transfer ( session , tof_array [ 1 ] , tof_array [ 2 ] , tof_array [ 3 ] ) ;
}
}
if ( transfer_on_fail ) {
if ( switch_true ( transfer_on_fail ) ) {
return ;
} else {
char * lbuf = switch_core_session_strdup ( session , transfer_on_fail ) ;
char * argv [ 256 ] = { 0 } ;
int argc = switch_separate_string ( lbuf , ' , ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ;
int i ;
for ( i = 0 ; i < argc ; i + + ) {
if ( ! strcasecmp ( argv [ i ] , cause_str ) | | ! strcasecmp ( argv [ i ] , cause_num ) ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG ,
" Transfer on fail [%s]: Cause: %s \n " , transfer_on_fail , cause_str ) ;
switch_ivr_session_transfer ( session , tof_array [ 1 ] , tof_array [ 2 ] , tof_array [ 3 ] ) ;
}
}
}
}
}
2007-10-15 14:00:48 +00:00
}
2012-05-09 08:39:23 -05:00
if ( ! switch_channel_test_flag ( caller_channel , CF_TRANSFER ) & & ! switch_channel_test_flag ( caller_channel , CF_CONFIRM_BLIND_TRANSFER ) & &
switch_channel_get_state ( caller_channel ) ! = CS_ROUTING ) {
2008-01-03 23:42:15 +00:00
switch_channel_hangup ( caller_channel , cause ) ;
}
2007-06-13 16:00:14 +00:00
return ;
} else {
2010-02-06 03:38:24 +00:00
2009-03-06 03:54:38 +00:00
if ( switch_channel_test_flag ( caller_channel , CF_PROXY_MODE ) ) {
2012-02-21 10:08:58 -06:00
switch_channel_t * peer_channel = switch_core_session_get_channel ( peer_session ) ;
if ( switch_true ( switch_channel_get_variable ( caller_channel , SWITCH_BYPASS_MEDIA_AFTER_BRIDGE_VARIABLE ) ) | |
switch_true ( switch_channel_get_variable ( peer_channel , SWITCH_BYPASS_MEDIA_AFTER_BRIDGE_VARIABLE ) ) ) {
switch_channel_set_flag ( caller_channel , CF_BYPASS_MEDIA_AFTER_BRIDGE ) ;
}
2007-06-13 16:00:14 +00:00
switch_ivr_signal_bridge ( session , peer_session ) ;
} else {
2009-03-06 03:54:38 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
switch_channel_t * peer_channel = switch_core_session_get_channel ( peer_session ) ;
char * a_key = ( char * ) switch_channel_get_variable ( channel , " bridge_terminate_key " ) ;
char * b_key = ( char * ) switch_channel_get_variable ( peer_channel , " bridge_terminate_key " ) ;
int ok = 0 ;
switch_input_callback_function_t func = NULL ;
if ( a_key ) {
a_key = switch_core_session_strdup ( session , a_key ) ;
ok + + ;
}
if ( b_key ) {
b_key = switch_core_session_strdup ( session , b_key ) ;
ok + + ;
}
if ( ok ) {
func = bridge_on_dtmf ;
2007-06-13 16:00:14 +00:00
} else {
2009-03-06 03:54:38 +00:00
a_key = NULL ;
b_key = NULL ;
2007-06-13 16:00:14 +00:00
}
2009-03-06 03:54:38 +00:00
2010-02-09 15:20:16 +00:00
if ( switch_true ( switch_channel_get_variable ( caller_channel , SWITCH_BYPASS_MEDIA_AFTER_BRIDGE_VARIABLE ) ) | |
switch_true ( switch_channel_get_variable ( peer_channel , SWITCH_BYPASS_MEDIA_AFTER_BRIDGE_VARIABLE ) ) ) {
2009-11-09 23:49:35 +00:00
switch_channel_set_flag ( caller_channel , CF_BYPASS_MEDIA_AFTER_BRIDGE ) ;
}
2010-02-06 03:38:24 +00:00
2010-01-28 17:10:23 +00:00
switch_ivr_multi_threaded_bridge ( session , peer_session , func , a_key , b_key ) ;
2007-06-13 16:00:14 +00:00
}
2010-02-06 03:38:24 +00:00
2007-06-13 16:00:14 +00:00
if ( peer_session ) {
switch_core_session_rwunlock ( peer_session ) ;
}
}
}
2007-06-04 22:10:42 +00:00
2012-05-04 18:59:25 -05:00
static struct {
switch_memory_pool_t * pool ;
switch_hash_t * pickup_hash ;
switch_mutex_t * pickup_mutex ;
} globals ;
/* pickup channel */
typedef struct pickup_node_s {
char * key ;
char * uuid ;
struct pickup_node_s * next ;
} pickup_node_t ;
# define PICKUP_PROTO "pickup"
static int EC = 0 ;
static int pickup_count ( const char * key_name )
{
int count = 0 ;
pickup_node_t * head , * np ;
switch_mutex_lock ( globals . pickup_mutex ) ;
if ( ( head = switch_core_hash_find ( globals . pickup_hash , key_name ) ) ) {
for ( np = head ; np ; np = np - > next ) count + + ;
}
switch_mutex_unlock ( globals . pickup_mutex ) ;
return count ;
}
static void pickup_send_presence ( const char * key_name )
{
char * domain_name , * dup_key_name = NULL , * dup_domain_name = NULL , * dup_id = NULL ;
switch_event_t * event ;
int count ;
dup_key_name = strdup ( key_name ) ;
key_name = dup_key_name ;
if ( ( domain_name = strchr ( dup_key_name , ' @ ' ) ) ) {
* domain_name + + = ' \0 ' ;
}
if ( zstr ( domain_name ) ) {
dup_domain_name = switch_core_get_variable_dup ( " domain " ) ;
domain_name = dup_domain_name ;
}
if ( zstr ( domain_name ) ) {
domain_name = " cluecon.com " ;
}
dup_id = switch_mprintf ( " %s@%s " , key_name , domain_name ) ;
count = pickup_count ( dup_id ) ;
if ( count > 0 ) {
if ( switch_event_create ( & event , SWITCH_EVENT_PRESENCE_IN ) = = SWITCH_STATUS_SUCCESS ) {
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " proto " , PICKUP_PROTO ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " login " , dup_id ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " from " , dup_id ) ;
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " force-status " , " Active (%d call%s) " , count , count = = 1 ? " " : " s " ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " rpid " , " active " ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " event_type " , " presence " ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " alt_event_type " , " dialog " ) ;
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " event_count " , " %d " , EC + + ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " unique-id " , key_name ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " channel-state " , " CS_ROUTING " ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " answer-state " , " confirmed " ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " call-direction " , " inbound " ) ;
switch_event_fire ( & event ) ;
}
} else {
if ( switch_event_create ( & event , SWITCH_EVENT_PRESENCE_IN ) = = SWITCH_STATUS_SUCCESS ) {
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " proto " , PICKUP_PROTO ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " login " , dup_id ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " from " , dup_id ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " force-status " , " Idle " ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " rpid " , " unknown " ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " event_type " , " presence " ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " alt_event_type " , " dialog " ) ;
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " event_count " , " %d " , EC + + ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " unique-id " , dup_id ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " channel-state " , " CS_HANGUP " ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " answer-state " , " terminated " ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " call-direction " , " inbound " ) ;
switch_event_fire ( & event ) ;
}
}
switch_safe_free ( dup_domain_name ) ;
switch_safe_free ( dup_key_name ) ;
switch_safe_free ( dup_id ) ;
}
static void pickup_pres_event_handler ( switch_event_t * event )
{
char * to = switch_event_get_header ( event , " to " ) ;
char * dup_to = NULL , * key_name , * dup_key_name = NULL , * domain_name , * dup_domain_name = NULL ;
int count = 0 ;
if ( ! to | | strncasecmp ( to , " pickup+ " , 7 ) | | ! strchr ( to , ' @ ' ) ) {
return ;
}
if ( ! ( dup_to = strdup ( to ) ) ) {
return ;
}
key_name = dup_to + 7 ;
if ( ( domain_name = strchr ( key_name , ' @ ' ) ) ) {
* domain_name + + = ' \0 ' ;
} else {
dup_domain_name = switch_core_get_variable_dup ( " domain " ) ;
domain_name = dup_domain_name ;
}
if ( zstr ( domain_name ) ) {
switch_safe_free ( dup_to ) ;
return ;
}
dup_key_name = switch_mprintf ( " %q@%q " , key_name , domain_name ) ;
count = pickup_count ( dup_key_name ) ;
switch_event_create ( & event , SWITCH_EVENT_PRESENCE_IN ) ;
if ( count ) {
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " proto " , PICKUP_PROTO ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " login " , key_name ) ;
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " from " , " %s@%s " , key_name , domain_name ) ;
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " force-status " , " Active (%d call%s) " , count , count = = 1 ? " " : " s " ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " rpid " , " active " ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " event_type " , " presence " ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " alt_event_type " , " dialog " ) ;
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " event_count " , " %d " , EC + + ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " unique-id " , key_name ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " channel-state " , " CS_ROUTING " ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " answer-state " , " confirmed " ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " call-direction " , " inbound " ) ;
} else {
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " proto " , PICKUP_PROTO ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " login " , key_name ) ;
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " from " , " %s@%s " , key_name , domain_name ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " force-status " , " Idle " ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " rpid " , " unknown " ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " event_type " , " presence " ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " alt_event_type " , " dialog " ) ;
switch_event_add_header ( event , SWITCH_STACK_BOTTOM , " event_count " , " %d " , EC + + ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " unique-id " , key_name ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " channel-state " , " CS_HANGUP " ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " answer-state " , " terminated " ) ;
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " call-direction " , " inbound " ) ;
}
switch_event_fire ( & event ) ;
switch_safe_free ( dup_to ) ;
switch_safe_free ( dup_key_name ) ;
switch_safe_free ( dup_domain_name ) ;
}
static void pickup_add_session ( switch_core_session_t * session , const char * key )
{
pickup_node_t * head , * node , * np ;
char * dup_key = NULL ;
if ( ! strchr ( key , ' @ ' ) ) {
dup_key = switch_mprintf ( " %s@%s " , key , switch_core_get_variable ( " domain " ) ) ;
key = dup_key ;
}
node = malloc ( sizeof ( * node ) ) ;
node - > key = strdup ( key ) ;
node - > uuid = strdup ( switch_core_session_get_uuid ( session ) ) ;
node - > next = NULL ;
switch_mutex_lock ( globals . pickup_mutex ) ;
head = switch_core_hash_find ( globals . pickup_hash , key ) ;
if ( head ) {
for ( np = head ; np & & np - > next ; np = np - > next ) ;
np - > next = node ;
} else {
head = node ;
switch_core_hash_insert ( globals . pickup_hash , key , head ) ;
}
switch_mutex_unlock ( globals . pickup_mutex ) ;
pickup_send_presence ( key ) ;
switch_safe_free ( dup_key ) ;
}
static char * pickup_pop_uuid ( const char * key , const char * uuid )
{
pickup_node_t * node = NULL , * head ;
char * r = NULL ;
char * dup_key = NULL ;
if ( ! strchr ( key , ' @ ' ) ) {
dup_key = switch_mprintf ( " %s@%s " , key , switch_core_get_variable ( " domain " ) ) ;
key = dup_key ;
}
switch_mutex_lock ( globals . pickup_mutex ) ;
if ( ( head = switch_core_hash_find ( globals . pickup_hash , key ) ) ) {
switch_core_hash_delete ( globals . pickup_hash , key ) ;
if ( uuid ) {
pickup_node_t * np , * lp = NULL ;
for ( np = head ; np ; np = np - > next ) {
if ( ! strcmp ( np - > uuid , uuid ) ) {
if ( lp ) {
lp - > next = np - > next ;
} else {
head = np - > next ;
}
node = np ;
break ;
}
lp = np ;
}
} else {
node = head ;
head = head - > next ;
}
if ( head ) {
switch_core_hash_insert ( globals . pickup_hash , key , head ) ;
}
}
if ( node ) {
r = node - > uuid ;
free ( node - > key ) ;
free ( node ) ;
}
switch_mutex_unlock ( globals . pickup_mutex ) ;
if ( r ) pickup_send_presence ( key ) ;
switch_safe_free ( dup_key ) ;
return r ;
}
typedef struct pickup_pvt_s {
char * key ;
switch_event_t * vars ;
} pickup_pvt_t ;
switch_endpoint_interface_t * pickup_endpoint_interface ;
static switch_call_cause_t pickup_outgoing_channel ( switch_core_session_t * session ,
switch_event_t * var_event ,
switch_caller_profile_t * outbound_profile ,
switch_core_session_t * * new_session , switch_memory_pool_t * * pool , switch_originate_flag_t flags ,
switch_call_cause_t * cancel_cause ) ;
switch_io_routines_t pickup_io_routines = {
/*.outgoing_channel */ pickup_outgoing_channel
} ;
static switch_status_t pickup_event_handler ( switch_core_session_t * session )
{
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
switch_channel_state_t state = switch_channel_get_running_state ( channel ) ;
pickup_pvt_t * tech_pvt = switch_core_session_get_private ( session ) ;
switch ( state ) {
case CS_DESTROY :
if ( tech_pvt - > vars ) {
switch_event_destroy ( & tech_pvt - > vars ) ;
}
break ;
case CS_REPORTING :
return SWITCH_STATUS_FALSE ;
case CS_HANGUP :
{
if ( switch_channel_test_flag ( channel , CF_CHANNEL_SWAP ) ) {
const char * key = switch_channel_get_variable ( channel , " channel_swap_uuid " ) ;
switch_core_session_t * swap_session ;
if ( ( swap_session = switch_core_session_locate ( key ) ) ) {
switch_channel_t * swap_channel = switch_core_session_get_channel ( swap_session ) ;
switch_channel_hangup ( swap_channel , SWITCH_CAUSE_PICKED_OFF ) ;
switch_core_session_rwunlock ( swap_session ) ;
}
switch_channel_clear_flag ( channel , CF_CHANNEL_SWAP ) ;
}
pickup_pop_uuid ( tech_pvt - > key , switch_core_session_get_uuid ( session ) ) ;
}
break ;
default :
break ;
}
return SWITCH_STATUS_SUCCESS ;
}
switch_state_handler_table_t pickup_event_handlers = {
/*.on_init */ pickup_event_handler ,
/*.on_routing */ pickup_event_handler ,
/*.on_execute */ pickup_event_handler ,
/*.on_hangup */ pickup_event_handler ,
/*.on_exchange_media */ pickup_event_handler ,
/*.on_soft_execute */ pickup_event_handler ,
/*.on_consume_media */ pickup_event_handler ,
/*.on_hibernate */ pickup_event_handler ,
/*.on_reset */ pickup_event_handler ,
/*.on_park */ pickup_event_handler ,
/*.on_reporting */ pickup_event_handler ,
/*.on_destroy */ pickup_event_handler
} ;
static switch_call_cause_t pickup_outgoing_channel ( switch_core_session_t * session ,
switch_event_t * var_event ,
switch_caller_profile_t * outbound_profile ,
switch_core_session_t * * new_session , switch_memory_pool_t * * pool , switch_originate_flag_t flags ,
switch_call_cause_t * cancel_cause )
{
char * pickup ;
switch_call_cause_t cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ;
switch_core_session_t * nsession ;
switch_channel_t * nchannel ;
char * name ;
pickup_pvt_t * tech_pvt ;
switch_caller_profile_t * caller_profile ;
if ( zstr ( outbound_profile - > destination_number ) ) {
goto done ;
}
pickup = outbound_profile - > destination_number ;
if ( ! ( nsession = switch_core_session_request ( pickup_endpoint_interface , SWITCH_CALL_DIRECTION_OUTBOUND , flags , pool ) ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " Error Creating Session \n " ) ;
goto error ;
}
tech_pvt = switch_core_session_alloc ( nsession , sizeof ( * tech_pvt ) ) ;
tech_pvt - > key = switch_core_session_strdup ( nsession , pickup ) ;
switch_event_dup ( & tech_pvt - > vars , var_event ) ;
switch_core_session_set_private ( nsession , tech_pvt ) ;
nchannel = switch_core_session_get_channel ( nsession ) ;
caller_profile = switch_caller_profile_clone ( nsession , outbound_profile ) ;
switch_channel_set_caller_profile ( nchannel , caller_profile ) ;
switch_channel_set_state ( nchannel , CS_ROUTING ) ;
* new_session = nsession ;
cause = SWITCH_CAUSE_SUCCESS ;
name = switch_core_session_sprintf ( nsession , " pickup/%s " , pickup ) ;
switch_channel_set_name ( nchannel , name ) ;
switch_channel_set_variable ( nchannel , " process_cdr " , " false " ) ;
pickup_add_session ( nsession , pickup ) ;
2012-05-07 08:17:41 -05:00
switch_channel_set_flag ( nchannel , CF_PICKUP ) ;
2012-05-04 18:59:25 -05:00
goto done ;
error :
if ( nsession ) {
switch_core_session_destroy ( & nsession ) ;
}
if ( pool ) {
* pool = NULL ;
}
done :
return cause ;
}
# define PICKUP_SYNTAX "[<key>]"
SWITCH_STANDARD_APP ( pickup_function )
{
char * uuid = NULL ;
switch_core_session_t * pickup_session ;
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
if ( zstr ( data ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Missing data. Usage: pickup %s \n " , PICKUP_SYNTAX ) ;
return ;
}
if ( ( uuid = pickup_pop_uuid ( ( char * ) data , NULL ) ) ) {
if ( ( pickup_session = switch_core_session_locate ( uuid ) ) ) {
switch_channel_t * pickup_channel = switch_core_session_get_channel ( pickup_session ) ;
switch_caller_profile_t * pickup_caller_profile = switch_channel_get_caller_profile ( pickup_channel ) ,
* caller_profile = switch_channel_get_caller_profile ( channel ) ;
const char * name , * num ;
switch_event_t * event ;
switch_event_header_t * hp ;
pickup_pvt_t * tech_pvt = switch_core_session_get_private ( pickup_session ) ;
for ( hp = tech_pvt - > vars - > headers ; hp ; hp = hp - > next ) {
switch_channel_set_variable ( channel , hp - > name , hp - > value ) ;
}
switch_channel_set_flag ( pickup_channel , CF_CHANNEL_SWAP ) ;
switch_channel_set_variable ( pickup_channel , " channel_swap_uuid " , switch_core_session_get_uuid ( session ) ) ;
name = caller_profile - > caller_id_name ;
num = caller_profile - > caller_id_number ;
caller_profile - > caller_id_name = switch_core_strdup ( caller_profile - > pool , pickup_caller_profile - > caller_id_name ) ;
caller_profile - > caller_id_number = switch_core_strdup ( caller_profile - > pool , pickup_caller_profile - > caller_id_number ) ;
caller_profile - > callee_id_name = name ;
caller_profile - > callee_id_number = num ;
if ( switch_event_create ( & event , SWITCH_EVENT_CALL_UPDATE ) = = SWITCH_STATUS_SUCCESS ) {
2012-05-29 13:10:15 -05:00
const char * uuid = switch_channel_get_partner_uuid ( channel ) ;
2012-05-04 18:59:25 -05:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Direction " , " RECV " ) ;
if ( uuid ) {
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Bridged-To " , uuid ) ;
}
switch_channel_event_set_data ( channel , event ) ;
switch_event_fire ( & event ) ;
}
switch_channel_set_state ( channel , CS_HIBERNATE ) ;
switch_channel_mark_answered ( pickup_channel ) ;
switch_core_session_rwunlock ( pickup_session ) ;
}
free ( uuid ) ;
}
}
2008-08-12 18:00:56 +00:00
/* fake chan_error */
switch_endpoint_interface_t * error_endpoint_interface ;
static switch_call_cause_t error_outgoing_channel ( switch_core_session_t * session ,
2010-02-06 03:38:24 +00:00
switch_event_t * var_event ,
switch_caller_profile_t * outbound_profile ,
switch_core_session_t * * new_session , switch_memory_pool_t * * pool , switch_originate_flag_t flags ,
switch_call_cause_t * cancel_cause ) ;
2008-08-12 18:00:56 +00:00
switch_io_routines_t error_io_routines = {
/*.outgoing_channel */ error_outgoing_channel
} ;
static switch_call_cause_t error_outgoing_channel ( switch_core_session_t * session ,
2010-02-06 03:38:24 +00:00
switch_event_t * var_event ,
switch_caller_profile_t * outbound_profile ,
switch_core_session_t * * new_session , switch_memory_pool_t * * pool , switch_originate_flag_t flags ,
switch_call_cause_t * cancel_cause )
2008-08-12 18:00:56 +00:00
{
switch_call_cause_t cause = switch_channel_str2cause ( outbound_profile - > destination_number ) ;
if ( cause = = SWITCH_CAUSE_NONE ) {
cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ;
}
return cause ;
}
2008-12-23 17:36:50 +00:00
/* fake chan_group */
switch_endpoint_interface_t * group_endpoint_interface ;
static switch_call_cause_t group_outgoing_channel ( switch_core_session_t * session ,
2010-02-06 03:38:24 +00:00
switch_event_t * var_event ,
switch_caller_profile_t * outbound_profile ,
switch_core_session_t * * new_session , switch_memory_pool_t * * pool , switch_originate_flag_t flags ,
switch_call_cause_t * cancel_cause ) ;
2008-12-23 17:36:50 +00:00
switch_io_routines_t group_io_routines = {
/*.outgoing_channel */ group_outgoing_channel
} ;
static switch_call_cause_t group_outgoing_channel ( switch_core_session_t * session ,
2010-02-06 03:38:24 +00:00
switch_event_t * var_event ,
switch_caller_profile_t * outbound_profile ,
switch_core_session_t * * new_session , switch_memory_pool_t * * pool , switch_originate_flag_t flags ,
switch_call_cause_t * cancel_cause )
2008-12-23 17:36:50 +00:00
{
2009-05-27 02:07:20 +00:00
char * group = NULL ;
2009-01-01 19:11:49 +00:00
switch_call_cause_t cause = SWITCH_CAUSE_NONE ;
2008-12-23 17:36:50 +00:00
char * template = NULL , * dest = NULL ;
switch_originate_flag_t myflags = SOF_NONE ;
char * cid_name_override = NULL ;
char * cid_num_override = NULL ;
2011-02-04 08:56:30 -06:00
char * domain = NULL , * dup_domain = NULL ;
2008-12-23 17:36:50 +00:00
switch_channel_t * new_channel = NULL ;
2009-10-08 17:43:51 +00:00
unsigned int timelimit = 60 ;
const char * skip , * var ;
2008-12-23 17:36:50 +00:00
group = strdup ( outbound_profile - > destination_number ) ;
2010-02-06 03:38:24 +00:00
if ( ! group )
goto done ;
2008-12-23 17:36:50 +00:00
if ( ( domain = strchr ( group , ' @ ' ) ) ) {
* domain + + = ' \0 ' ;
} else {
2011-03-31 09:38:48 -05:00
domain = switch_core_get_variable_dup ( " domain " ) ;
2011-02-04 08:56:30 -06:00
dup_domain = domain ;
2008-12-23 17:36:50 +00:00
}
2010-02-06 03:38:24 +00:00
2008-12-23 17:36:50 +00:00
if ( ! domain ) {
goto done ;
}
2010-02-06 03:38:24 +00:00
if ( var_event & & ( skip = switch_event_get_header ( var_event , " group_recurse_variables " ) ) & & switch_false ( skip ) ) {
if ( ( var = switch_event_get_header ( var_event , SWITCH_CALL_TIMEOUT_VARIABLE ) ) | | ( var = switch_event_get_header ( var_event , " leg_timeout " ) ) ) {
2009-05-06 15:13:51 +00:00
timelimit = atoi ( var ) ;
}
var_event = NULL ;
}
2008-12-23 17:36:50 +00:00
template = switch_mprintf ( " ${group_call(%s@%s)} " , group , domain ) ;
2010-02-06 03:38:24 +00:00
2008-12-23 17:36:50 +00:00
if ( session ) {
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
dest = switch_channel_expand_variables ( channel , template ) ;
2010-02-06 03:38:24 +00:00
if ( ( var = switch_channel_get_variable ( channel , SWITCH_CALL_TIMEOUT_VARIABLE ) ) | | ( var = switch_event_get_header ( var_event , " leg_timeout " ) ) ) {
2008-12-23 17:36:50 +00:00
timelimit = atoi ( var ) ;
}
} else if ( var_event ) {
dest = switch_event_expand_headers ( var_event , template ) ;
2009-05-06 15:13:51 +00:00
} else {
switch_event_t * event = NULL ;
switch_event_create ( & event , SWITCH_EVENT_REQUEST_PARAMS ) ;
dest = switch_event_expand_headers ( event , template ) ;
switch_event_destroy ( & event ) ;
2008-12-23 17:36:50 +00:00
}
2009-05-06 15:13:51 +00:00
2008-12-23 17:36:50 +00:00
if ( ! dest ) {
goto done ;
}
2010-02-06 03:38:24 +00:00
2008-12-23 17:36:50 +00:00
if ( var_event ) {
cid_name_override = switch_event_get_header ( var_event , " origination_caller_id_name " ) ;
cid_num_override = switch_event_get_header ( var_event , " origination_caller_id_number " ) ;
2010-02-06 03:38:24 +00:00
if ( ( var = switch_event_get_header ( var_event , SWITCH_CALL_TIMEOUT_VARIABLE ) ) | | ( var = switch_event_get_header ( var_event , " leg_timeout " ) ) ) {
2008-12-23 17:36:50 +00:00
timelimit = atoi ( var ) ;
}
}
2010-02-06 03:38:24 +00:00
2008-12-23 17:36:50 +00:00
if ( ( flags & SOF_FORKED_DIAL ) ) {
myflags | = SOF_NOBLOCK ;
}
2010-02-06 03:38:24 +00:00
if ( switch_ivr_originate ( session , new_session , & cause , dest , timelimit , NULL ,
2009-11-20 02:17:08 +00:00
cid_name_override , cid_num_override , NULL , var_event , myflags , cancel_cause ) = = SWITCH_STATUS_SUCCESS ) {
2008-12-23 17:36:50 +00:00
const char * context ;
switch_caller_profile_t * cp ;
2010-02-06 03:38:24 +00:00
2008-12-23 17:36:50 +00:00
new_channel = switch_core_session_get_channel ( * new_session ) ;
2010-02-06 03:38:24 +00:00
2008-12-23 17:36:50 +00:00
if ( ( context = switch_channel_get_variable ( new_channel , " group_context " ) ) ) {
if ( ( cp = switch_channel_get_caller_profile ( new_channel ) ) ) {
cp - > context = switch_core_strdup ( cp - > pool , context ) ;
}
}
switch_core_session_rwunlock ( * new_session ) ;
}
2009-01-13 23:48:55 +00:00
done :
2008-12-23 17:36:50 +00:00
if ( dest & & dest ! = template ) {
switch_safe_free ( dest ) ;
}
2010-02-06 03:38:24 +00:00
switch_safe_free ( template ) ;
switch_safe_free ( group ) ;
2011-02-04 08:56:30 -06:00
switch_safe_free ( dup_domain ) ;
2008-12-23 17:36:50 +00:00
if ( cause = = SWITCH_CAUSE_NONE ) {
cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ;
}
return cause ;
}
2007-12-04 19:39:14 +00:00
/* fake chan_user */
switch_endpoint_interface_t * user_endpoint_interface ;
static switch_call_cause_t user_outgoing_channel ( switch_core_session_t * session ,
2008-05-15 19:29:35 +00:00
switch_event_t * var_event ,
2007-12-04 19:39:14 +00:00
switch_caller_profile_t * outbound_profile ,
2010-02-06 03:38:24 +00:00
switch_core_session_t * * new_session , switch_memory_pool_t * * pool , switch_originate_flag_t flags ,
switch_call_cause_t * cancel_cause ) ;
2007-12-04 19:39:14 +00:00
switch_io_routines_t user_io_routines = {
/*.outgoing_channel */ user_outgoing_channel
} ;
static switch_call_cause_t user_outgoing_channel ( switch_core_session_t * session ,
2008-05-15 19:29:35 +00:00
switch_event_t * var_event ,
2007-12-04 19:39:14 +00:00
switch_caller_profile_t * outbound_profile ,
2010-02-06 03:38:24 +00:00
switch_core_session_t * * new_session , switch_memory_pool_t * * pool , switch_originate_flag_t flags ,
switch_call_cause_t * cancel_cause )
2007-12-04 19:39:14 +00:00
{
2011-11-15 07:55:31 -06:00
switch_xml_t x_user = NULL , x_param , x_params ;
2012-02-24 14:15:32 -06:00
char * user = NULL , * domain = NULL , * dup_domain = NULL , * dialed_user = NULL ;
2007-12-04 19:39:14 +00:00
const char * dest = NULL ;
2011-02-22 20:25:16 -05:00
switch_call_cause_t cause = SWITCH_CAUSE_NONE ;
2007-12-04 19:39:14 +00:00
unsigned int timelimit = 60 ;
2007-12-11 15:14:33 +00:00
switch_channel_t * new_channel = NULL ;
2009-05-07 02:05:16 +00:00
switch_event_t * params = NULL , * var_event_orig = var_event ;
2009-03-03 20:55:39 +00:00
char stupid [ 128 ] = " " ;
2009-05-06 15:13:51 +00:00
const char * skip = NULL , * var = NULL ;
2009-03-03 20:55:39 +00:00
2009-10-23 16:03:42 +00:00
if ( zstr ( outbound_profile - > destination_number ) ) {
2008-01-06 22:14:10 +00:00
goto done ;
}
2008-01-14 21:58:36 +00:00
user = strdup ( outbound_profile - > destination_number ) ;
2007-12-04 19:39:14 +00:00
2010-02-06 03:38:24 +00:00
if ( ! user )
goto done ;
2008-05-19 22:39:48 +00:00
2008-12-23 17:36:50 +00:00
if ( ( domain = strchr ( user , ' @ ' ) ) ) {
* domain + + = ' \0 ' ;
} else {
2011-02-04 08:44:11 -06:00
domain = switch_core_get_variable_dup ( " domain " ) ;
dup_domain = domain ;
2008-12-23 17:36:50 +00:00
}
2010-02-06 03:38:24 +00:00
2008-12-23 17:36:50 +00:00
if ( ! domain ) {
2007-12-04 19:39:14 +00:00
goto done ;
}
2007-12-20 21:42:00 +00:00
2010-02-06 03:38:24 +00:00
2010-07-15 01:00:08 -05:00
switch_event_create ( & params , SWITCH_EVENT_REQUEST_PARAMS ) ;
switch_assert ( params ) ;
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " as_channel " , " true " ) ;
switch_event_add_header_string ( params , SWITCH_STACK_BOTTOM , " action " , " user_call " ) ;
if ( var_event ) {
switch_event_merge ( params , var_event ) ;
}
2010-02-06 03:38:24 +00:00
if ( var_event & & ( skip = switch_event_get_header ( var_event , " user_recurse_variables " ) ) & & switch_false ( skip ) ) {
if ( ( var = switch_event_get_header ( var_event , SWITCH_CALL_TIMEOUT_VARIABLE ) ) | | ( var = switch_event_get_header ( var_event , " leg_timeout " ) ) ) {
2009-05-06 15:13:51 +00:00
timelimit = atoi ( var ) ;
}
var_event = NULL ;
}
2010-07-15 01:00:08 -05:00
2011-03-31 13:44:15 -05:00
if ( switch_xml_locate_user_merged ( " id " , user , domain , NULL , & x_user , params ) ! = SWITCH_STATUS_SUCCESS ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING , " Can't find user [%s@%s] \n " , user , domain ) ;
2008-02-06 01:05:01 +00:00
cause = SWITCH_CAUSE_SUBSCRIBER_ABSENT ;
2007-12-04 19:39:14 +00:00
goto done ;
}
if ( ( x_params = switch_xml_child ( x_user , " params " ) ) ) {
for ( x_param = switch_xml_child ( x_params , " param " ) ; x_param ; x_param = x_param - > next ) {
2009-05-11 22:28:02 +00:00
const char * pvar = switch_xml_attr ( x_param , " name " ) ;
2007-12-04 19:39:14 +00:00
const char * val = switch_xml_attr ( x_param , " value " ) ;
2008-05-27 04:54:52 +00:00
2009-05-11 22:28:02 +00:00
if ( ! strcasecmp ( pvar , " dial-string " ) ) {
2007-12-04 19:39:14 +00:00
dest = val ;
2009-05-11 22:28:02 +00:00
} else if ( ! strncasecmp ( pvar , " dial-var- " , 9 ) ) {
2009-05-07 02:05:16 +00:00
if ( ! var_event ) {
switch_event_create ( & var_event , SWITCH_EVENT_GENERAL ) ;
} else {
2009-05-11 22:28:02 +00:00
switch_event_del_header ( var_event , pvar + 9 ) ;
2009-05-07 02:05:16 +00:00
}
2009-05-11 22:28:02 +00:00
switch_event_add_header_string ( var_event , SWITCH_STACK_BOTTOM , pvar + 9 , val ) ;
2007-12-04 19:39:14 +00:00
}
}
}
2011-03-31 13:44:15 -05:00
2012-02-24 14:15:32 -06:00
dialed_user = ( char * ) switch_xml_attr ( x_user , " id " ) ;
2011-08-09 08:33:03 -05:00
if ( var_event ) {
2012-02-24 14:15:32 -06:00
switch_event_add_header_string ( var_event , SWITCH_STACK_BOTTOM , " dialed_user " , dialed_user ) ;
2011-08-09 08:33:03 -05:00
switch_event_add_header_string ( var_event , SWITCH_STACK_BOTTOM , " dialed_domain " , domain ) ;
2012-03-01 10:00:24 -06:00
if ( ! zstr ( dest ) & & ! strstr ( dest , " presence_id= " ) ) {
2012-02-24 14:15:32 -06:00
switch_event_add_header ( var_event , SWITCH_STACK_BOTTOM , " presence_id " , " %s@%s " , dialed_user , domain ) ;
2012-02-15 15:22:28 -06:00
}
2011-08-09 08:33:03 -05:00
}
2007-12-04 19:39:14 +00:00
2008-07-30 13:14:39 +00:00
if ( ! dest ) {
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " No dial-string available, please check your user directory. \n " ) ;
2008-07-30 13:14:39 +00:00
cause = SWITCH_CAUSE_MANDATORY_IE_MISSING ;
} else {
2009-05-11 22:28:02 +00:00
const char * varval ;
2007-12-05 18:54:49 +00:00
char * d_dest = NULL ;
2007-12-04 19:39:14 +00:00
switch_channel_t * channel ;
2007-12-20 21:42:00 +00:00
switch_originate_flag_t myflags = SOF_NONE ;
2008-06-23 19:04:17 +00:00
char * cid_name_override = NULL ;
char * cid_num_override = NULL ;
2008-12-11 22:32:02 +00:00
2008-06-23 19:04:17 +00:00
if ( var_event ) {
cid_name_override = switch_event_get_header ( var_event , " origination_caller_id_name " ) ;
cid_num_override = switch_event_get_header ( var_event , " origination_caller_id_number " ) ;
}
2007-12-20 21:42:00 +00:00
2008-01-14 21:58:36 +00:00
if ( session ) {
channel = switch_core_session_get_channel ( session ) ;
2009-05-11 22:28:02 +00:00
if ( ( varval = switch_channel_get_variable ( channel , SWITCH_CALL_TIMEOUT_VARIABLE ) )
2010-07-06 10:25:58 -05:00
| | ( var_event & & ( varval = switch_event_get_header ( var_event , " leg_timeout " ) ) ) ) {
2009-05-11 22:28:02 +00:00
timelimit = atoi ( varval ) ;
2008-01-14 21:58:36 +00:00
}
2008-05-27 04:54:52 +00:00
2012-02-24 14:15:32 -06:00
switch_channel_set_variable ( channel , " dialed_user " , dialed_user ) ;
2008-01-14 21:58:36 +00:00
switch_channel_set_variable ( channel , " dialed_domain " , domain ) ;
2008-05-27 04:54:52 +00:00
2008-01-14 21:58:36 +00:00
d_dest = switch_channel_expand_variables ( channel , dest ) ;
2007-12-11 22:56:20 +00:00
2008-01-14 21:58:36 +00:00
} else {
2008-12-11 22:32:02 +00:00
switch_event_t * event = NULL ;
if ( var_event ) {
switch_event_dup ( & event , var_event ) ;
2009-05-06 15:13:51 +00:00
switch_event_del_header ( event , " dialed_user " ) ;
switch_event_del_header ( event , " dialed_domain " ) ;
2010-02-06 03:38:24 +00:00
if ( ( varval = switch_event_get_header ( var_event , SWITCH_CALL_TIMEOUT_VARIABLE ) ) | |
2009-05-11 22:28:02 +00:00
( varval = switch_event_get_header ( var_event , " leg_timeout " ) ) ) {
timelimit = atoi ( varval ) ;
2008-12-23 17:36:50 +00:00
}
2008-12-11 22:32:02 +00:00
} else {
2008-10-02 17:10:05 +00:00
switch_event_create ( & event , SWITCH_EVENT_REQUEST_PARAMS ) ;
2008-05-15 19:29:35 +00:00
switch_assert ( event ) ;
2009-05-06 22:52:09 +00:00
}
2012-02-24 14:15:32 -06:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " dialed_user " , dialed_user ) ;
2009-05-06 22:52:09 +00:00
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " dialed_domain " , domain ) ;
d_dest = switch_event_expand_headers ( event , dest ) ;
switch_event_destroy ( & event ) ;
2008-01-14 21:58:36 +00:00
}
2008-05-27 04:54:52 +00:00
2010-08-26 12:19:49 -05:00
if ( ( flags & SOF_NO_LIMITS ) ) {
myflags | = SOF_NO_LIMITS ;
}
2007-12-20 21:42:00 +00:00
if ( ( flags & SOF_FORKED_DIAL ) ) {
myflags | = SOF_NOBLOCK ;
}
2010-07-23 09:40:57 -05:00
2012-02-24 14:15:32 -06:00
switch_snprintf ( stupid , sizeof ( stupid ) , " user/%s " , dialed_user ) ;
2009-03-03 20:55:39 +00:00
if ( switch_stristr ( stupid , d_dest ) ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING , " Waddya Daft? You almost called '%s' in an infinate loop! \n " ,
stupid ) ;
2009-03-03 20:55:39 +00:00
cause = SWITCH_CAUSE_INVALID_IE_CONTENTS ;
2010-02-06 03:38:24 +00:00
} else if ( switch_ivr_originate ( session , new_session , & cause , d_dest , timelimit , NULL ,
cid_name_override , cid_num_override , outbound_profile , var_event , myflags ,
cancel_cause ) = = SWITCH_STATUS_SUCCESS ) {
2007-12-11 01:05:52 +00:00
const char * context ;
switch_caller_profile_t * cp ;
2007-12-11 15:14:33 +00:00
2010-07-23 09:40:57 -05:00
if ( var_event ) {
switch_event_del_header ( var_event , " origination_uuid " ) ;
}
2007-12-11 15:14:33 +00:00
new_channel = switch_core_session_get_channel ( * new_session ) ;
2008-05-27 04:54:52 +00:00
2007-12-11 15:38:07 +00:00
if ( ( context = switch_channel_get_variable ( new_channel , " user_context " ) ) ) {
2007-12-11 01:05:52 +00:00
if ( ( cp = switch_channel_get_caller_profile ( new_channel ) ) ) {
cp - > context = switch_core_strdup ( cp - > pool , context ) ;
}
}
2007-12-04 19:39:14 +00:00
switch_core_session_rwunlock ( * new_session ) ;
}
2007-12-05 18:54:49 +00:00
if ( d_dest ! = dest ) {
switch_safe_free ( d_dest ) ;
}
2007-12-04 19:39:14 +00:00
}
2011-11-15 07:55:31 -06:00
if ( new_channel & & x_user ) {
2007-12-11 15:14:33 +00:00
if ( ( x_params = switch_xml_child ( x_user , " variables " ) ) ) {
for ( x_param = switch_xml_child ( x_params , " variable " ) ; x_param ; x_param = x_param - > next ) {
2009-05-11 22:28:02 +00:00
const char * pvar = switch_xml_attr ( x_param , " name " ) ;
2007-12-11 15:14:33 +00:00
const char * val = switch_xml_attr ( x_param , " value " ) ;
2009-05-11 22:28:02 +00:00
switch_channel_set_variable ( new_channel , pvar , val ) ;
2007-12-11 15:14:33 +00:00
}
}
}
2008-05-27 04:54:52 +00:00
done :
2008-01-27 22:05:01 +00:00
2011-11-15 07:50:45 -06:00
if ( x_user ) {
switch_xml_free ( x_user ) ;
}
2008-02-25 19:45:07 +00:00
if ( params ) {
switch_event_destroy ( & params ) ;
}
2010-02-06 03:38:24 +00:00
2009-05-07 02:05:16 +00:00
if ( var_event & & var_event_orig ! = var_event ) {
switch_event_destroy ( & var_event ) ;
}
2008-01-27 22:05:01 +00:00
2008-01-14 21:58:36 +00:00
switch_safe_free ( user ) ;
2011-02-04 08:44:11 -06:00
switch_safe_free ( dup_domain ) ;
2007-12-04 19:39:14 +00:00
return cause ;
}
2008-04-21 20:15:50 +00:00
# define HOLD_SYNTAX "[<display message>]"
SWITCH_STANDARD_APP ( hold_function )
{
2008-05-01 16:41:46 +00:00
switch_ivr_hold_uuid ( switch_core_session_get_uuid ( session ) , data , 1 ) ;
2008-04-21 20:15:50 +00:00
}
# define UNHOLD_SYNTAX ""
SWITCH_STANDARD_APP ( unhold_function )
{
switch_ivr_unhold_uuid ( switch_core_session_get_uuid ( session ) ) ;
}
2008-10-02 15:38:45 +00:00
SWITCH_STANDARD_APP ( verbose_events_function )
{
switch_channel_set_flag ( switch_core_session_get_channel ( session ) , CF_VERBOSE_EVENTS ) ;
}
2010-12-22 20:38:57 -06:00
SWITCH_STANDARD_APP ( cng_plc_function )
{
switch_channel_set_flag ( switch_core_session_get_channel ( session ) , CF_CNG_PLC ) ;
}
2009-12-11 00:28:54 +00:00
SWITCH_STANDARD_APP ( early_hangup_function )
{
switch_channel_set_flag ( switch_core_session_get_channel ( session ) , CF_EARLY_HANGUP ) ;
}
2008-07-10 19:59:57 +00:00
# define WAIT_FOR_SILENCE_SYNTAX "<silence_thresh> <silence_hits> <listen_hits> <timeout_ms> [<file>]"
2008-07-10 15:57:41 +00:00
SWITCH_STANDARD_APP ( wait_for_silence_function )
{
2008-07-10 19:59:57 +00:00
char * argv [ 5 ] = { 0 } ;
uint32_t thresh , silence_hits , listen_hits , timeout_ms = 0 ;
2008-07-10 15:57:41 +00:00
int argc ;
char * lbuf = NULL ;
2010-02-06 03:38:24 +00:00
2009-10-23 16:03:42 +00:00
if ( ! zstr ( data ) & & ( lbuf = switch_core_session_strdup ( session , data ) )
2008-07-10 15:57:41 +00:00
& & ( argc = switch_separate_string ( lbuf , ' ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ) > = 3 ) {
thresh = atoi ( argv [ 0 ] ) ;
silence_hits = atoi ( argv [ 1 ] ) ;
listen_hits = atoi ( argv [ 2 ] ) ;
2008-07-10 19:59:57 +00:00
if ( argv [ 3 ] ) {
2012-01-08 14:19:16 -06:00
timeout_ms = switch_atoui ( argv [ 3 ] ) ;
2008-07-10 19:59:57 +00:00
}
2008-07-10 15:57:41 +00:00
if ( thresh > 0 & & silence_hits > 0 & & listen_hits > 0 ) {
2008-07-10 19:59:57 +00:00
switch_ivr_wait_for_silence ( session , thresh , silence_hits , listen_hits , timeout_ms , argv [ 4 ] ) ;
2008-07-10 15:57:41 +00:00
return ;
}
2010-02-06 03:38:24 +00:00
}
2009-08-13 21:24:51 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Usage: %s \n " , WAIT_FOR_SILENCE_SYNTAX ) ;
2008-07-10 15:57:41 +00:00
}
2011-09-13 16:51:30 -05:00
static switch_status_t event_chat_send ( switch_event_t * message_event )
2008-07-23 18:19:56 +00:00
{
switch_event_t * event ;
2011-09-13 16:51:30 -05:00
const char * to ;
2008-07-23 18:19:56 +00:00
2011-09-13 16:51:30 -05:00
switch_event_dup ( & event , message_event ) ;
event - > event_id = SWITCH_EVENT_RECV_MESSAGE ;
2008-07-23 18:19:56 +00:00
2011-09-13 16:51:30 -05:00
if ( ( to = switch_event_get_header ( event , " to " ) ) ) {
char * v ;
if ( ( v = switch_core_get_variable_dup ( to ) ) ) {
switch_event_add_header_string ( event , SWITCH_STACK_BOTTOM , " Command " , v ) ;
free ( v ) ;
2008-07-23 18:19:56 +00:00
}
2011-09-13 16:51:30 -05:00
}
2008-07-23 18:19:56 +00:00
2011-09-13 16:51:30 -05:00
if ( switch_event_fire ( & event ) = = SWITCH_STATUS_SUCCESS ) {
return SWITCH_STATUS_SUCCESS ;
2008-07-23 18:19:56 +00:00
}
2011-09-13 16:51:30 -05:00
switch_event_destroy ( & event ) ;
2010-02-06 03:38:24 +00:00
2008-07-23 18:19:56 +00:00
return SWITCH_STATUS_MEMERR ;
}
2011-09-13 16:51:30 -05:00
static switch_status_t api_chat_send ( switch_event_t * message_event )
2008-07-23 18:19:56 +00:00
{
2011-09-13 16:51:30 -05:00
const char * proto ;
const char * from ;
const char * to ;
//const char *subject;
//const char *body;
const char * type ;
const char * hint ;
proto = switch_event_get_header ( message_event , " proto " ) ;
from = switch_event_get_header ( message_event , " from " ) ;
to = switch_event_get_header ( message_event , " to " ) ;
//subject = switch_event_get_header(message_event, "subject");
//body = switch_event_get_body(message_event);
type = switch_event_get_header ( message_event , " type " ) ;
hint = switch_event_get_header ( message_event , " hint " ) ;
2010-02-06 03:38:24 +00:00
if ( to ) {
2011-02-02 15:43:26 -06:00
char * v = NULL ;
2008-07-23 18:19:56 +00:00
switch_stream_handle_t stream = { 0 } ;
2009-05-27 02:07:20 +00:00
char * cmd = NULL , * arg ;
2010-02-06 03:38:24 +00:00
2011-02-02 15:43:26 -06:00
if ( ! ( v = switch_core_get_variable_dup ( to ) ) ) {
v = strdup ( to ) ;
2008-07-23 18:19:56 +00:00
}
2011-02-02 15:43:26 -06:00
cmd = v ;
2008-07-23 18:19:56 +00:00
switch_assert ( cmd ) ;
switch_url_decode ( cmd ) ;
if ( ( arg = strchr ( cmd , ' ' ) ) ) {
* arg + + = ' \0 ' ;
}
SWITCH_STANDARD_STREAM ( stream ) ;
switch_api_execute ( cmd , arg , NULL , & stream ) ;
2009-01-20 20:49:47 +00:00
if ( proto ) {
2011-09-13 16:51:30 -05:00
switch_core_chat_send_args ( proto , " api " , to , hint & & strchr ( hint , ' / ' ) ? hint : from , ! zstr ( type ) ? type : NULL , ( char * ) stream . data , NULL , NULL ) ;
2008-07-23 18:19:56 +00:00
}
switch_safe_free ( stream . data ) ;
2010-02-06 03:38:24 +00:00
2008-07-23 18:19:56 +00:00
free ( cmd ) ;
}
2010-02-06 03:38:24 +00:00
2008-07-23 18:19:56 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2010-01-20 19:19:48 +00:00
# define SESSION_LOGLEVEL_SYNTAX "<level>"
SWITCH_STANDARD_APP ( session_loglevel_function )
{
if ( ! zstr ( data ) ) {
switch_log_level_t level = switch_log_str2level ( data ) ;
if ( level = = SWITCH_LOG_INVALID ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Invalid log level: %s \n " , data ) ;
} else {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Setting log level \" %s \" on session \n " , switch_log_level2str ( level ) ) ;
switch_core_session_set_loglevel ( session , level ) ;
}
} else {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " No log level specified \n " ) ;
}
}
2010-04-01 21:31:14 -05:00
/* LIMIT STUFF */
# define LIMIT_USAGE "<backend> <realm> <id> [<max>[ / interval]] [number [dialplan [context]]]"
# define LIMIT_DESC "limit access to a resource and transfer to an extension if the limit is exceeded"
SWITCH_STANDARD_APP ( limit_function )
{
int argc = 0 ;
char * argv [ 7 ] = { 0 } ;
char * mydata = NULL ;
char * backend = NULL ;
char * realm = NULL ;
char * id = NULL ;
char * xfer_exten = NULL ;
int max = - 1 ;
int interval = 0 ;
2010-06-20 04:12:50 -05:00
switch_limit_interface_t * limit = NULL ;
2010-04-01 21:31:14 -05:00
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
/* Parse application data */
if ( ! zstr ( data ) ) {
mydata = switch_core_session_strdup ( session , data ) ;
argc = switch_separate_string ( mydata , ' ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ;
}
2010-06-20 04:12:50 -05:00
2010-06-20 19:02:50 -05:00
backend = argv [ 0 ] ;
/* must have at least one item */
if ( argc < 1 ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " USAGE: limit %s \n " , LIMIT_USAGE ) ;
2010-04-01 21:31:14 -05:00
return ;
}
2010-06-20 04:12:50 -05:00
/* if this is an invalid backend, fallback to db backend */
/* TODO: remove this when we can! */
2010-06-20 19:02:50 -05:00
if ( switch_true ( switch_channel_get_variable ( channel , " switch_limit_backwards_compat_flag " ) ) & &
! ( limit = switch_loadable_module_get_limit_interface ( backend ) ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Unknown backend '%s'. To maintain backwards compatability, falling back on db backend and shifting argumens. Either update your diaplan to include the backend, fix the typo, or load the appropriate limit implementation module. \n " , backend ) ;
2010-06-20 04:12:50 -05:00
mydata = switch_core_session_sprintf ( session , " db %s " , data ) ;
argc = switch_separate_string ( mydata , ' ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ;
backend = argv [ 0 ] ;
}
2010-06-20 19:02:50 -05:00
if ( argc < 3 ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " USAGE: limit %s \n " , LIMIT_USAGE ) ;
return ;
}
2010-04-01 21:31:14 -05:00
realm = argv [ 1 ] ;
id = argv [ 2 ] ;
/* If max is omitted or negative, only act as a counter and skip maximum checks */
if ( argc > 3 ) {
if ( argv [ 3 ] [ 0 ] = = ' - ' ) {
max = - 1 ;
} else {
char * szinterval = NULL ;
if ( ( szinterval = strchr ( argv [ 3 ] , ' / ' ) ) ) {
* szinterval + + = ' \0 ' ;
interval = atoi ( szinterval ) ;
}
max = atoi ( argv [ 3 ] ) ;
if ( max < 0 ) {
max = 0 ;
}
}
}
if ( argc > 4 ) {
xfer_exten = argv [ 4 ] ;
} else {
xfer_exten = LIMIT_DEF_XFER_EXTEN ;
}
if ( switch_limit_incr ( backend , session , realm , id , max , interval ) ! = SWITCH_STATUS_SUCCESS ) {
/* Limit exceeded */
if ( * xfer_exten = = ' ! ' ) {
switch_channel_hangup ( channel , switch_channel_str2cause ( xfer_exten + 1 ) ) ;
} else {
switch_ivr_session_transfer ( session , xfer_exten , argv [ 5 ] , argv [ 6 ] ) ;
}
}
}
2010-06-20 04:12:50 -05:00
# define LIMIT_HASH_USAGE "<realm> <id> [<max>[ / interval]] [number [dialplan [context]]]"
# define LIMIT_HASH_DESC "DEPRECATED: limit access to a resource and transfer to an extension if the limit is exceeded"
SWITCH_STANDARD_APP ( limit_hash_function )
{
char * mydata = NULL ;
2010-06-20 19:02:50 -05:00
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
if ( switch_true ( switch_channel_get_variable ( channel , " switch_limit_backwards_compat_flag " ) ) ) {
mydata = switch_core_session_sprintf ( session , " hash %s " , data ) ;
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Using deprecated 'limit_hash' api: Please use 'limit hash'. \n " ) ;
limit_function ( session , mydata ) ;
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " 'limit_hash' (deprecated) is only available after loading mod_limit. \n " ) ;
}
2010-06-20 04:12:50 -05:00
}
2010-04-01 21:31:14 -05:00
2010-06-20 04:12:50 -05:00
# define LIMITEXECUTE_USAGE "<backend> <realm> <id> <max>[ / interval] <application> [application arguments]"
2010-04-01 21:31:14 -05:00
# define LIMITEXECUTE_DESC "limit access to a resource. the specified application will only be executed if the resource is available"
SWITCH_STANDARD_APP ( limit_execute_function )
{
int argc = 0 ;
char * argv [ 6 ] = { 0 } ;
char * mydata = NULL ;
char * backend = NULL ;
char * realm = NULL ;
char * id = NULL ;
char * app = NULL ;
char * app_arg = NULL ;
int max = - 1 ;
int interval = 0 ;
2010-06-20 19:02:50 -05:00
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
2010-04-01 21:31:14 -05:00
/* Parse application data */
if ( ! zstr ( data ) ) {
mydata = switch_core_session_strdup ( session , data ) ;
argc = switch_separate_string ( mydata , ' ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ;
}
2010-06-20 04:12:50 -05:00
/* backwards compat version, if we have 5, just prepend with db and reparse */
2010-06-20 19:02:50 -05:00
if ( switch_true ( switch_channel_get_variable ( channel , " switch_limit_backwards_compat_flag " ) ) & &
argc = = 5 ) {
2010-06-20 04:12:50 -05:00
mydata = switch_core_session_sprintf ( session , " db %s " , data ) ;
argc = switch_separate_string ( mydata , ' ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ;
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Using deprecated limit api: Please specify backend. Defaulting to 'db' backend. \n " ) ;
}
2010-04-01 21:31:14 -05:00
if ( argc < 6 ) {
2010-06-20 19:02:50 -05:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " USAGE: limit_execute %s \n " , LIMITEXECUTE_USAGE ) ;
2010-04-01 21:31:14 -05:00
return ;
}
backend = argv [ 0 ] ;
realm = argv [ 1 ] ;
id = argv [ 2 ] ;
/* Accept '-' as unlimited (act as counter) */
if ( argv [ 3 ] [ 0 ] = = ' - ' ) {
max = - 1 ;
} else {
char * szinterval = NULL ;
if ( ( szinterval = strchr ( argv [ 3 ] , ' / ' ) ) ) {
* szinterval + + = ' \0 ' ;
interval = atoi ( szinterval ) ;
}
max = atoi ( argv [ 3 ] ) ;
if ( max < 0 ) {
max = 0 ;
}
}
app = argv [ 4 ] ;
app_arg = argv [ 5 ] ;
if ( zstr ( app ) ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Missing application \n " ) ;
return ;
}
if ( switch_limit_incr ( backend , session , realm , id , max , interval ) = = SWITCH_STATUS_SUCCESS ) {
switch_core_session_execute_application ( session , app , app_arg ) ;
/* Only release the resource if we are still in CS_EXECUTE */
if ( switch_channel_get_state ( switch_core_session_get_channel ( session ) ) = = CS_EXECUTE ) {
2010-06-19 20:07:39 -05:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_INFO , " immediately releasing \n " ) ;
2010-04-01 21:31:14 -05:00
switch_limit_release ( backend , session , realm , id ) ;
}
}
}
2010-06-20 04:12:50 -05:00
# define LIMITHASHEXECUTE_USAGE "<realm> <id> <max>[ / interval] <application> [application arguments]"
# define LIMITHASHEXECUTE_DESC "DEPRECATED: limit access to a resource. the specified application will only be executed if the resource is available"
SWITCH_STANDARD_APP ( limit_hash_execute_function )
{
char * mydata = NULL ;
2010-06-20 19:02:50 -05:00
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
if ( switch_true ( switch_channel_get_variable ( channel , " switch_limit_backwards_compat_flag " ) ) ) {
mydata = switch_core_session_sprintf ( session , " hash %s " , data ) ;
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Using deprecated 'limit_hash_execute' api: Please use 'limit_execute hash'. \n " ) ;
limit_execute_function ( session , mydata ) ;
} else {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " 'limit_hash_execute' (deprecated) is only available after loading mod_limit. \n " ) ;
}
2010-06-20 04:12:50 -05:00
}
2011-03-29 20:35:34 -05:00
/* FILE STRING INTERFACE */
/* for apr_pstrcat */
# define DEFAULT_PREBUFFER_SIZE 1024 * 64
struct file_string_source ;
struct file_string_context {
char * argv [ 128 ] ;
int argc ;
int index ;
int samples ;
switch_file_handle_t fh ;
} ;
typedef struct file_string_context file_string_context_t ;
static int next_file ( switch_file_handle_t * handle )
{
file_string_context_t * context = handle - > private_info ;
char * file ;
const char * prefix = handle - > prefix ;
top :
context - > index + + ;
if ( switch_test_flag ( ( & context - > fh ) , SWITCH_FILE_OPEN ) ) {
switch_core_file_close ( & context - > fh ) ;
}
if ( context - > index > = context - > argc ) {
return 0 ;
}
if ( ! prefix ) {
if ( ! ( prefix = switch_core_get_variable_pdup ( " sound_prefix " , handle - > memory_pool ) ) ) {
prefix = SWITCH_GLOBAL_dirs . sounds_dir ;
}
}
if ( ! prefix | | switch_is_file_path ( context - > argv [ context - > index ] ) ) {
file = context - > argv [ context - > index ] ;
} else {
file = switch_core_sprintf ( handle - > memory_pool , " %s%s%s " , prefix , SWITCH_PATH_SEPARATOR , context - > argv [ context - > index ] ) ;
}
if ( switch_core_file_open ( & context - > fh ,
file , handle - > channels , handle - > samplerate , SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT , NULL ) ! = SWITCH_STATUS_SUCCESS ) {
goto top ;
}
handle - > samples = context - > fh . samples ;
2011-10-07 10:40:30 -05:00
//handle->samplerate = context->fh.samplerate;
//handle->channels = context->fh.channels;
2011-03-29 20:35:34 -05:00
handle - > format = context - > fh . format ;
handle - > sections = context - > fh . sections ;
handle - > seekable = context - > fh . seekable ;
handle - > speed = context - > fh . speed ;
handle - > interval = context - > fh . interval ;
2011-03-31 15:01:58 -05:00
if ( switch_test_flag ( ( & context - > fh ) , SWITCH_FILE_NATIVE ) ) {
switch_set_flag ( handle , SWITCH_FILE_NATIVE ) ;
} else {
switch_clear_flag ( handle , SWITCH_FILE_NATIVE ) ;
}
if ( ! switch_test_flag ( handle , SWITCH_FILE_NATIVE ) ) {
if ( context - > index = = 0 ) {
context - > samples = ( handle - > samplerate / 1000 ) * 250 ;
}
2011-03-29 20:35:34 -05:00
}
return 1 ;
}
static switch_status_t file_string_file_seek ( switch_file_handle_t * handle , unsigned int * cur_sample , int64_t samples , int whence )
{
file_string_context_t * context = handle - > private_info ;
if ( samples = = 0 & & whence = = SEEK_SET ) {
context - > index = - 1 ;
return SWITCH_STATUS_SUCCESS ;
}
if ( ! handle - > seekable ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " File is not seekable \n " ) ;
return SWITCH_STATUS_NOTIMPL ;
}
return switch_core_file_seek ( & context - > fh , cur_sample , samples , whence ) ;
}
static switch_status_t file_string_file_open ( switch_file_handle_t * handle , const char * path )
{
file_string_context_t * context ;
char * file_dup ;
if ( switch_test_flag ( handle , SWITCH_FILE_FLAG_WRITE ) ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " This format does not support writing! \n " ) ;
return SWITCH_STATUS_FALSE ;
}
context = switch_core_alloc ( handle - > memory_pool , sizeof ( * context ) ) ;
file_dup = switch_core_strdup ( handle - > memory_pool , path ) ;
context - > argc = switch_separate_string ( file_dup , ' ! ' , context - > argv , ( sizeof ( context - > argv ) / sizeof ( context - > argv [ 0 ] ) ) ) ;
context - > index = - 1 ;
handle - > private_info = context ;
return next_file ( handle ) ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE ;
}
static switch_status_t file_string_file_close ( switch_file_handle_t * handle )
{
file_string_context_t * context = handle - > private_info ;
2011-08-17 18:10:44 -05:00
if ( switch_test_flag ( ( & context - > fh ) , SWITCH_FILE_OPEN ) ) {
switch_core_file_close ( & context - > fh ) ;
}
2011-03-29 20:35:34 -05:00
return SWITCH_STATUS_SUCCESS ;
}
static switch_status_t file_string_file_read ( switch_file_handle_t * handle , void * data , size_t * len )
{
file_string_context_t * context = handle - > private_info ;
switch_status_t status ;
size_t llen = * len ;
if ( context - > samples > 0 ) {
if ( * len > ( size_t ) context - > samples ) {
* len = context - > samples ;
}
2012-04-18 08:53:38 -05:00
context - > samples - = ( int ) * len ;
2011-04-03 17:53:06 -05:00
memset ( data , 255 , * len * 2 ) ;
2011-03-29 20:35:34 -05:00
status = SWITCH_STATUS_SUCCESS ;
} else {
status = switch_core_file_read ( & context - > fh , data , len ) ;
}
if ( status ! = SWITCH_STATUS_SUCCESS ) {
if ( ! next_file ( handle ) ) {
return SWITCH_STATUS_FALSE ;
}
* len = llen ;
status = switch_core_file_read ( & context - > fh , data , len ) ;
}
return SWITCH_STATUS_SUCCESS ;
}
/* Registration */
static char * file_string_supported_formats [ SWITCH_MAX_CODECS ] = { 0 } ;
/* /FILE STRING INTERFACE */
2012-05-08 08:50:33 -05:00
SWITCH_STANDARD_APP ( blind_transfer_ack_function )
{
switch_bool_t val = 0 ;
if ( data ) {
val = switch_true ( ( char * ) val ) ;
}
2012-05-08 19:33:53 -05:00
switch_ivr_blind_transfer_ack ( session , val ) ;
2012-05-08 08:50:33 -05:00
}
2011-03-29 20:35:34 -05:00
2007-06-20 05:15:07 +00:00
# define SPEAK_DESC "Speak text to a channel via the tts interface"
# define DISPLACE_DESC "Displace audio from a file to the channels input"
# define SESS_REC_DESC "Starts a background recording of the entire session"
# define STOP_SESS_REC_DESC "Stops a background recording of the entire session"
# define SCHED_TRANSF_DESCR "Schedule a transfer in the future"
# define SCHED_BROADCAST_DESCR "Schedule a broadcast in the future"
# define SCHED_HANGUP_DESCR "Schedule a hangup in the future"
2007-11-09 17:46:20 +00:00
# define UNSET_LONG_DESC "Unset a channel variable for the channel calling the application."
# define SET_LONG_DESC "Set a channel variable for the channel calling the application."
# define SET_GLOBAL_LONG_DESC "Set a global variable."
# define SET_PROFILE_VAR_LONG_DESC "Set a caller profile variable for the channel calling the application."
# define EXPORT_LONG_DESC "Set and export a channel variable for the channel calling the application."
# define LOG_LONG_DESC "Logs a channel variable for the channel calling the application."
2008-10-06 23:05:55 +00:00
# define TRANSFER_LONG_DESC "Immediately transfer the calling channel to a new extension"
2007-06-20 05:15:07 +00:00
# define SLEEP_LONG_DESC "Pause the channel for a given number of milliseconds, consuming the audio for that period of time."
2012-05-04 18:59:25 -05:00
SWITCH_MODULE_SHUTDOWN_FUNCTION ( mod_dptools_shutdown )
{
switch_event_unbind_callback ( pickup_pres_event_handler ) ;
return SWITCH_STATUS_SUCCESS ;
}
2007-06-13 16:00:14 +00:00
SWITCH_MODULE_LOAD_FUNCTION ( mod_dptools_load )
2006-11-28 02:23:26 +00:00
{
2007-06-20 05:15:07 +00:00
switch_api_interface_t * api_interface ;
switch_application_interface_t * app_interface ;
2008-04-22 15:18:35 +00:00
switch_dialplan_interface_t * dp_interface ;
2008-07-23 18:19:56 +00:00
switch_chat_interface_t * chat_interface ;
2011-03-29 20:35:34 -05:00
switch_file_interface_t * file_interface ;
2006-11-28 02:23:26 +00:00
2012-05-04 18:59:25 -05:00
globals . pool = pool ;
switch_core_hash_init ( & globals . pickup_hash , NULL ) ;
switch_mutex_init ( & globals . pickup_mutex , SWITCH_MUTEX_NESTED , globals . pool ) ;
2006-11-28 02:23:26 +00:00
/* connect my internal structure to the blank pointer passed to me */
2007-06-20 05:15:07 +00:00
* module_interface = switch_loadable_module_create_module_interface ( pool , modname ) ;
2012-05-04 18:59:25 -05:00
switch_event_bind ( modname , SWITCH_EVENT_PRESENCE_PROBE , SWITCH_EVENT_SUBCLASS_ANY , pickup_pres_event_handler , NULL ) ;
2011-03-29 20:35:34 -05:00
file_string_supported_formats [ 0 ] = " file_string " ;
2012-04-18 08:53:38 -05:00
file_interface = ( switch_file_interface_t * ) switch_loadable_module_create_interface ( * module_interface , SWITCH_FILE_INTERFACE ) ;
2011-03-29 20:35:34 -05:00
file_interface - > interface_name = modname ;
file_interface - > extens = file_string_supported_formats ;
file_interface - > file_open = file_string_file_open ;
file_interface - > file_close = file_string_file_close ;
file_interface - > file_read = file_string_file_read ;
file_interface - > file_seek = file_string_file_seek ;
2012-04-18 08:53:38 -05:00
error_endpoint_interface = ( switch_endpoint_interface_t * ) switch_loadable_module_create_interface ( * module_interface , SWITCH_ENDPOINT_INTERFACE ) ;
2008-11-05 00:01:37 +00:00
error_endpoint_interface - > interface_name = " error " ;
2008-08-12 18:00:56 +00:00
error_endpoint_interface - > io_routines = & error_io_routines ;
2012-04-18 08:53:38 -05:00
group_endpoint_interface = ( switch_endpoint_interface_t * ) switch_loadable_module_create_interface ( * module_interface , SWITCH_ENDPOINT_INTERFACE ) ;
2008-12-23 17:36:50 +00:00
group_endpoint_interface - > interface_name = " group " ;
group_endpoint_interface - > io_routines = & group_io_routines ;
2012-04-18 08:53:38 -05:00
user_endpoint_interface = ( switch_endpoint_interface_t * ) switch_loadable_module_create_interface ( * module_interface , SWITCH_ENDPOINT_INTERFACE ) ;
2008-11-05 00:01:37 +00:00
user_endpoint_interface - > interface_name = " user " ;
2008-05-27 04:54:52 +00:00
user_endpoint_interface - > io_routines = & user_io_routines ;
2007-12-04 19:39:14 +00:00
2012-05-04 18:59:25 -05:00
pickup_endpoint_interface = ( switch_endpoint_interface_t * ) switch_loadable_module_create_interface ( * module_interface , SWITCH_ENDPOINT_INTERFACE ) ;
pickup_endpoint_interface - > interface_name = " pickup " ;
pickup_endpoint_interface - > io_routines = & pickup_io_routines ;
pickup_endpoint_interface - > state_handler = & pickup_event_handlers ;
2008-07-23 18:19:56 +00:00
SWITCH_ADD_CHAT ( chat_interface , " event " , event_chat_send ) ;
SWITCH_ADD_CHAT ( chat_interface , " api " , api_chat_send ) ;
2010-02-06 03:38:24 +00:00
2008-01-06 22:14:10 +00:00
SWITCH_ADD_API ( api_interface , " strepoch " , " Convert a date string into epoch time " , strepoch_api_function , " <string> " ) ;
2012-01-27 17:27:20 -06:00
SWITCH_ADD_API ( api_interface , " strmicroepoch " , " Convert a date string into micoepoch time " , strmicroepoch_api_function , " <string> " ) ;
2009-01-20 21:24:37 +00:00
SWITCH_ADD_API ( api_interface , " chat " , " chat " , chat_api_function , " <proto>|<from>|<to>|<message>|[<content-type>] " ) ;
2007-06-20 05:15:07 +00:00
SWITCH_ADD_API ( api_interface , " strftime " , " strftime " , strftime_api_function , " <format_string> " ) ;
2009-04-27 15:52:34 +00:00
SWITCH_ADD_API ( api_interface , " presence " , " presence " , presence_api_function , PRESENCE_USAGE ) ;
2010-10-07 18:30:07 -05:00
2012-05-08 08:50:33 -05:00
SWITCH_ADD_APP ( app_interface , " blind_transfer_ack " , " " , " " , blind_transfer_ack_function , " [true|false] " , SAF_NONE ) ;
2010-10-07 18:30:07 -05:00
SWITCH_ADD_APP ( app_interface , " bind_digit_action " , " bind a key sequence or regex to an action " ,
" bind a key sequence or regex to an action " , bind_digit_action_function , BIND_DIGIT_ACTION_USAGE , SAF_SUPPORT_NOMEDIA ) ;
2011-05-25 16:12:42 -05:00
SWITCH_ADD_APP ( app_interface , " capture " , " capture data into a var " , " capture data into a var " ,
capture_function , " <varname>|<data>|<regex> " , SAF_SUPPORT_NOMEDIA ) ;
2010-10-07 18:30:07 -05:00
SWITCH_ADD_APP ( app_interface , " clear_digit_action " , " clear all digit bindings " , " " ,
clear_digit_action_function , CLEAR_DIGIT_ACTION_USAGE , SAF_SUPPORT_NOMEDIA ) ;
2010-10-08 13:50:15 -05:00
SWITCH_ADD_APP ( app_interface , " digit_action_set_realm " , " change binding realm " , " " ,
digit_action_set_realm_function , DIGIT_ACTION_SET_REALM_USAGE , SAF_SUPPORT_NOMEDIA ) ;
2011-09-01 10:11:16 -05:00
2008-05-27 04:54:52 +00:00
SWITCH_ADD_APP ( app_interface , " privacy " , " Set privacy on calls " , " Set caller privacy on calls. " , privacy_function , " off|on|name|full|number " ,
SAF_SUPPORT_NOMEDIA ) ;
2008-04-21 20:15:50 +00:00
2009-12-17 23:08:38 +00:00
SWITCH_ADD_APP ( app_interface , " set_audio_level " , " set volume " , " set volume " , set_audio_level_function , " " , SAF_NONE ) ;
SWITCH_ADD_APP ( app_interface , " set_mute " , " set mute " , " set mute " , set_mute_function , " " , SAF_NONE ) ;
2008-11-05 17:25:54 +00:00
SWITCH_ADD_APP ( app_interface , " flush_dtmf " , " flush any queued dtmf " , " flush any queued dtmf " , flush_dtmf_function , " " , SAF_SUPPORT_NOMEDIA ) ;
2008-04-21 20:15:50 +00:00
SWITCH_ADD_APP ( app_interface , " hold " , " Send a hold message " , " Send a hold message " , hold_function , HOLD_SYNTAX , SAF_SUPPORT_NOMEDIA ) ;
SWITCH_ADD_APP ( app_interface , " unhold " , " Send a un-hold message " , " Send a un-hold message " , unhold_function , UNHOLD_SYNTAX , SAF_SUPPORT_NOMEDIA ) ;
2008-05-27 04:54:52 +00:00
SWITCH_ADD_APP ( app_interface , " transfer " , " Transfer a channel " , TRANSFER_LONG_DESC , transfer_function , " <exten> [<dialplan> <context>] " ,
SAF_SUPPORT_NOMEDIA ) ;
SWITCH_ADD_APP ( app_interface , " check_acl " , " Check an ip against an ACL list " , " Check an ip against an ACL list " , check_acl_function ,
2009-09-17 19:05:58 +00:00
" <ip> <acl | cidr> [<hangup_cause>] " , SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC ) ;
2010-02-06 03:38:24 +00:00
SWITCH_ADD_APP ( app_interface , " verbose_events " , " Make ALL Events verbose. " , " Make ALL Events verbose. " , verbose_events_function , " " ,
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC ) ;
2010-12-22 20:38:57 -06:00
SWITCH_ADD_APP ( app_interface , " cng_plc " , " Do PLC on CNG frames " , " " , cng_plc_function , " " ,
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC ) ;
2009-12-11 00:28:54 +00:00
SWITCH_ADD_APP ( app_interface , " early_hangup " , " Enable early hangup " , " " , early_hangup_function , " " , SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC ) ;
2008-03-18 18:48:32 +00:00
SWITCH_ADD_APP ( app_interface , " sleep " , " Pause a channel " , SLEEP_LONG_DESC , sleep_function , " <pausemilliseconds> " , SAF_SUPPORT_NOMEDIA ) ;
2007-10-04 15:09:44 +00:00
SWITCH_ADD_APP ( app_interface , " delay_echo " , " echo audio at a specified delay " , " Delay n ms " , delay_function , " <delay ms> " , SAF_NONE ) ;
2008-07-21 13:39:27 +00:00
SWITCH_ADD_APP ( app_interface , " strftime " , " strftime " , " strftime " , strftime_function , " [<epoch>|]<format string> " , SAF_SUPPORT_NOMEDIA ) ;
2007-06-20 05:15:07 +00:00
SWITCH_ADD_APP ( app_interface , " phrase " , " Say a Phrase " , " Say a Phrase " , phrase_function , " <macro_name>,<data> " , SAF_NONE ) ;
2011-09-13 09:35:41 -05:00
SWITCH_ADD_APP ( app_interface , " eval " , " Do Nothing " , " Do Nothing " , eval_function , " " , SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC ) ;
2011-09-13 17:12:37 -05:00
SWITCH_ADD_APP ( app_interface , " stop " , " Do Nothing " , " Do Nothing " , eval_function , " " , SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC ) ;
SWITCH_ADD_APP ( app_interface , " set_zombie_exec " , " Enable Zombie Execution " , " Enable Zombie Execution " ,
zombie_function , " " , SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC ) ;
2008-03-08 01:34:08 +00:00
SWITCH_ADD_APP ( app_interface , " pre_answer " , " Pre-Answer the call " , " Pre-Answer the call for a channel. " , pre_answer_function , " " , SAF_SUPPORT_NOMEDIA ) ;
SWITCH_ADD_APP ( app_interface , " answer " , " Answer the call " , " Answer the call for a channel. " , answer_function , " " , SAF_SUPPORT_NOMEDIA ) ;
2007-06-20 05:15:07 +00:00
SWITCH_ADD_APP ( app_interface , " hangup " , " Hangup the call " , " Hangup the call for a channel. " , hangup_function , " [<cause>] " , SAF_SUPPORT_NOMEDIA ) ;
2008-02-26 23:29:58 +00:00
SWITCH_ADD_APP ( app_interface , " set_name " , " Name the channel " , " Name the channel " , set_name_function , " <name> " , SAF_SUPPORT_NOMEDIA ) ;
2010-02-06 03:38:24 +00:00
SWITCH_ADD_APP ( app_interface , " presence " , " Send Presence " , " Send Presence. " , presence_function , " <rpid> <status> [<id>] " ,
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC ) ;
SWITCH_ADD_APP ( app_interface , " log " , " Logs to the logger " , LOG_LONG_DESC , log_function , " <log_level> <log_string> " ,
2011-09-13 16:53:12 -05:00
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC ) ;
2011-09-13 09:35:41 -05:00
SWITCH_ADD_APP ( app_interface , " info " , " Display Call Info " , " Display Call Info " , info_function , " " , SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC ) ;
SWITCH_ADD_APP ( app_interface , " event " , " Fire an event " , " Fire an event " , event_function , " " , SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC ) ;
2009-02-05 19:53:13 +00:00
SWITCH_ADD_APP ( app_interface , " sound_test " , " Analyze Audio " , " Analyze Audio " , sound_test_function , " " , SAF_NONE ) ;
2008-05-27 04:54:52 +00:00
SWITCH_ADD_APP ( app_interface , " export " , " Export a channel variable across a bridge " , EXPORT_LONG_DESC , export_function , " <varname>=<value> " ,
2011-09-13 09:35:41 -05:00
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC ) ;
2010-10-01 17:26:03 -05:00
SWITCH_ADD_APP ( app_interface , " bridge_export " , " Export a channel variable across a bridge " , EXPORT_LONG_DESC , bridge_export_function , " <varname>=<value> " ,
2011-09-13 09:35:41 -05:00
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC ) ;
2010-02-06 03:38:24 +00:00
SWITCH_ADD_APP ( app_interface , " set " , " Set a channel variable " , SET_LONG_DESC , set_function , " <varname>=<value> " ,
2011-09-13 09:35:41 -05:00
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC ) ;
2011-05-25 15:42:36 -05:00
SWITCH_ADD_APP ( app_interface , " push " , " Set a channel variable " , SET_LONG_DESC , push_function , " <varname>=<value> " ,
2011-09-13 09:35:41 -05:00
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC ) ;
2011-05-25 15:42:36 -05:00
SWITCH_ADD_APP ( app_interface , " unshift " , " Set a channel variable " , SET_LONG_DESC , unshift_function , " <varname>=<value> " ,
2011-09-13 09:35:41 -05:00
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC ) ;
2011-05-25 15:42:36 -05:00
2008-05-27 04:54:52 +00:00
SWITCH_ADD_APP ( app_interface , " set_global " , " Set a global variable " , SET_GLOBAL_LONG_DESC , set_global_function , " <varname>=<value> " ,
2011-09-13 09:35:41 -05:00
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC ) ;
2008-05-27 04:54:52 +00:00
SWITCH_ADD_APP ( app_interface , " set_profile_var " , " Set a caller profile variable " , SET_PROFILE_VAR_LONG_DESC , set_profile_var_function ,
2011-09-13 09:35:41 -05:00
" <varname>=<value> " , SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC ) ;
2010-02-06 03:38:24 +00:00
SWITCH_ADD_APP ( app_interface , " unset " , " Unset a channel variable " , UNSET_LONG_DESC , unset_function , " <varname> " ,
2011-09-13 09:35:41 -05:00
SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC | SAF_ZOMBIE_EXEC ) ;
2007-06-20 05:15:07 +00:00
SWITCH_ADD_APP ( app_interface , " ring_ready " , " Indicate Ring_Ready " , " Indicate Ring_Ready on a channel. " , ring_ready_function , " " , SAF_SUPPORT_NOMEDIA ) ;
2008-07-29 15:19:58 +00:00
SWITCH_ADD_APP ( app_interface , " remove_bugs " , " Remove media bugs " , " Remove all media bugs from a channel. " , remove_bugs_function , " " , SAF_NONE ) ;
2007-06-25 21:25:33 +00:00
SWITCH_ADD_APP ( app_interface , " break " , " Break " , " Set the break flag. " , break_function , " " , SAF_SUPPORT_NOMEDIA ) ;
2007-06-20 05:15:07 +00:00
SWITCH_ADD_APP ( app_interface , " detect_speech " , " Detect speech " , " Detect speech on a channel. " , detect_speech_function , DETECT_SPEECH_SYNTAX , SAF_NONE ) ;
2011-11-15 11:28:05 -06:00
SWITCH_ADD_APP ( app_interface , " play_and_detect_speech " , " Play and do speech recognition " , " Play and do speech recognition " , play_and_detect_speech_function , PLAY_AND_DETECT_SPEECH_SYNTAX , SAF_NONE ) ;
2007-06-20 05:15:07 +00:00
SWITCH_ADD_APP ( app_interface , " ivr " , " Run an ivr menu " , " Run an ivr menu. " , ivr_application_function , " <menu_name> " , SAF_NONE ) ;
2008-05-27 04:54:52 +00:00
SWITCH_ADD_APP ( app_interface , " redirect " , " Send session redirect " , " Send a redirect message to a session. " , redirect_function , " <redirect_data> " ,
SAF_SUPPORT_NOMEDIA ) ;
2012-05-09 09:06:21 -05:00
SWITCH_ADD_APP ( app_interface , " video_refresh " , " Send video refresh. " , " Send video refresh. " , video_refresh_function , " " ,
SAF_SUPPORT_NOMEDIA ) ;
2011-11-23 15:38:54 -06:00
SWITCH_ADD_APP ( app_interface , " send_info " , " Send info " , " Send info " , send_info_function , " <info> " , SAF_SUPPORT_NOMEDIA ) ;
2010-12-10 17:47:24 -06:00
SWITCH_ADD_APP ( app_interface , " jitterbuffer " , " Send session jitterbuffer " , " Send a jitterbuffer message to a session. " ,
jitterbuffer_function , " <jitterbuffer_data> " , SAF_SUPPORT_NOMEDIA ) ;
2008-05-27 04:54:52 +00:00
SWITCH_ADD_APP ( app_interface , " send_display " , " Send session a new display " , " Send session a new display. " , display_function , " <text> " ,
SAF_SUPPORT_NOMEDIA ) ;
SWITCH_ADD_APP ( app_interface , " respond " , " Send session respond " , " Send a respond message to a session. " , respond_function , " <respond_data> " ,
SAF_SUPPORT_NOMEDIA ) ;
2008-01-03 23:42:15 +00:00
SWITCH_ADD_APP ( app_interface , " deflect " , " Send call deflect " , " Send a call deflect. " , deflect_function , " <deflect_data> " , SAF_SUPPORT_NOMEDIA ) ;
2010-12-29 13:15:14 -06:00
SWITCH_ADD_APP ( app_interface , " recovery_refresh " , " Send call recovery_refresh " , " Send a call recovery_refresh. " , recovery_refresh_function , " " , SAF_SUPPORT_NOMEDIA ) ;
2008-05-27 04:54:52 +00:00
SWITCH_ADD_APP ( app_interface , " queue_dtmf " , " Queue dtmf to be sent " , " Queue dtmf to be sent from a session " , queue_dtmf_function , " <dtmf_data> " ,
SAF_SUPPORT_NOMEDIA ) ;
SWITCH_ADD_APP ( app_interface , " send_dtmf " , " Send dtmf to be sent " , " Send dtmf to be sent from a session " , send_dtmf_function , " <dtmf_data> " ,
SAF_SUPPORT_NOMEDIA ) ;
2011-10-07 09:06:49 -05:00
SWITCH_ADD_APP ( app_interface , " sched_cancel " , " cancel scheduled tasks " , " cancel scheduled tasks " , sched_cancel_function , " [group] " ,
2010-07-02 14:06:53 -05:00
SAF_SUPPORT_NOMEDIA ) ;
2008-05-27 04:54:52 +00:00
SWITCH_ADD_APP ( app_interface , " sched_hangup " , SCHED_HANGUP_DESCR , SCHED_HANGUP_DESCR , sched_hangup_function , " [+]<time> [<cause>] " ,
SAF_SUPPORT_NOMEDIA ) ;
SWITCH_ADD_APP ( app_interface , " sched_broadcast " , SCHED_BROADCAST_DESCR , SCHED_BROADCAST_DESCR , sched_broadcast_function ,
" [+]<time> <path> [aleg|bleg|both] " , SAF_SUPPORT_NOMEDIA ) ;
SWITCH_ADD_APP ( app_interface , " sched_transfer " , SCHED_TRANSF_DESCR , SCHED_TRANSF_DESCR , sched_transfer_function ,
" [+]<time> <extension> <dialplan> <context> " , SAF_SUPPORT_NOMEDIA ) ;
2007-06-20 05:15:07 +00:00
SWITCH_ADD_APP ( app_interface , " execute_extension " , " Execute an extension " , " Execute an extension " , exe_function , EXE_SYNTAX , SAF_SUPPORT_NOMEDIA ) ;
2010-02-06 03:38:24 +00:00
SWITCH_ADD_APP ( app_interface , " sched_heartbeat " , " Enable Scheduled Heartbeat " , " Enable Scheduled Heartbeat " ,
2009-03-06 20:16:48 +00:00
sched_heartbeat_function , SCHED_HEARTBEAT_SYNTAX , SAF_SUPPORT_NOMEDIA ) ;
2010-02-06 03:38:24 +00:00
SWITCH_ADD_APP ( app_interface , " enable_heartbeat " , " Enable Media Heartbeat " , " Enable Media Heartbeat " ,
2009-03-06 20:16:48 +00:00
heartbeat_function , HEARTBEAT_SYNTAX , SAF_SUPPORT_NOMEDIA ) ;
2008-12-11 23:06:51 +00:00
SWITCH_ADD_APP ( app_interface , " mkdir " , " Create a directory " , " Create a directory " , mkdir_function , MKDIR_SYNTAX , SAF_SUPPORT_NOMEDIA ) ;
2008-05-27 04:54:52 +00:00
SWITCH_ADD_APP ( app_interface , " soft_hold " , " Put a bridged channel on hold " , " Put a bridged channel on hold " , soft_hold_function , SOFT_HOLD_SYNTAX ,
SAF_NONE ) ;
SWITCH_ADD_APP ( app_interface , " bind_meta_app " , " Bind a key to an application " , " Bind a key to an application " , dtmf_bind_function , BIND_SYNTAX ,
SAF_SUPPORT_NOMEDIA ) ;
2010-02-06 03:38:24 +00:00
SWITCH_ADD_APP ( app_interface , " unbind_meta_app " , " Unbind a key from an application " , " Unbind a key from an application " , dtmf_unbind_function ,
2008-12-31 01:08:51 +00:00
UNBIND_SYNTAX , SAF_SUPPORT_NOMEDIA ) ;
2010-06-07 21:14:47 -04:00
SWITCH_ADD_APP ( app_interface , " block_dfmf " , " Block DTMF " , " Block DTMF " , dtmf_block_function , " " , SAF_SUPPORT_NOMEDIA ) ;
SWITCH_ADD_APP ( app_interface , " unblock_dtmf " , " Stop blocking DTMF " , " Stop blocking DTMF " , dtmf_unblock_function , " " , SAF_SUPPORT_NOMEDIA ) ;
2007-12-08 00:14:21 +00:00
SWITCH_ADD_APP ( app_interface , " intercept " , " intercept " , " intercept " , intercept_function , INTERCEPT_SYNTAX , SAF_NONE ) ;
2009-12-02 18:13:11 +00:00
SWITCH_ADD_APP ( app_interface , " eavesdrop " , " eavesdrop on a uuid " , " eavesdrop on a uuid " , eavesdrop_function , eavesdrop_SYNTAX , SAF_MEDIA_TAP ) ;
2010-02-06 03:38:24 +00:00
SWITCH_ADD_APP ( app_interface , " three_way " , " three way call with a uuid " , " three way call with a uuid " , three_way_function , threeway_SYNTAX ,
SAF_MEDIA_TAP ) ;
SWITCH_ADD_APP ( app_interface , " set_user " , " Set a User " , " Set a User " , set_user_function , SET_USER_SYNTAX , SAF_SUPPORT_NOMEDIA | SAF_ROUTING_EXEC ) ;
2007-06-20 05:15:07 +00:00
SWITCH_ADD_APP ( app_interface , " stop_dtmf " , " stop inband dtmf " , " Stop detecting inband dtmf. " , stop_dtmf_session_function , " " , SAF_NONE ) ;
2009-12-02 18:13:11 +00:00
SWITCH_ADD_APP ( app_interface , " start_dtmf " , " Detect dtmf " , " Detect inband dtmf on the session " , dtmf_session_function , " " , SAF_MEDIA_TAP ) ;
2008-05-27 04:54:52 +00:00
SWITCH_ADD_APP ( app_interface , " stop_dtmf_generate " , " stop inband dtmf generation " , " Stop generating inband dtmf. " ,
2007-10-31 16:44:02 +00:00
stop_dtmf_session_generate_function , " [write] " , SAF_NONE ) ;
2008-05-27 04:54:52 +00:00
SWITCH_ADD_APP ( app_interface , " start_dtmf_generate " , " Generate dtmf " , " Generate inband dtmf on the session " , dtmf_session_generate_function , " " ,
SAF_NONE ) ;
2007-06-20 05:15:07 +00:00
SWITCH_ADD_APP ( app_interface , " stop_tone_detect " , " stop detecting tones " , " Stop detecting tones " , stop_fax_detect_session_function , " " , SAF_NONE ) ;
2009-12-02 18:13:11 +00:00
SWITCH_ADD_APP ( app_interface , " fax_detect " , " Detect faxes " , " Detect fax send tone " , fax_detect_session_function , " " , SAF_MEDIA_TAP ) ;
SWITCH_ADD_APP ( app_interface , " tone_detect " , " Detect tones " , " Detect tones " , tone_detect_session_function , " " , SAF_MEDIA_TAP ) ;
2007-06-20 05:15:07 +00:00
SWITCH_ADD_APP ( app_interface , " echo " , " Echo " , " Perform an echo test against the calling channel " , echo_function , " " , SAF_NONE ) ;
2010-06-07 09:34:44 -05:00
SWITCH_ADD_APP ( app_interface , " park " , " Park " , " Park " , park_function , " " , SAF_SUPPORT_NOMEDIA ) ;
2007-12-13 22:17:20 +00:00
SWITCH_ADD_APP ( app_interface , " park_state " , " Park State " , " Park State " , park_state_function , " " , SAF_NONE ) ;
2007-06-20 05:15:07 +00:00
SWITCH_ADD_APP ( app_interface , " gentones " , " Generate Tones " , " Generate tones to the channel " , gentones_function , " <tgml_script>[|<loops>] " , SAF_NONE ) ;
SWITCH_ADD_APP ( app_interface , " playback " , " Playback File " , " Playback a file to the channel " , playback_function , " <path> " , SAF_NONE ) ;
2010-02-06 03:38:24 +00:00
SWITCH_ADD_APP ( app_interface , " endless_playback " , " Playback File Endlessly " , " Endlessly Playback a file to the channel " ,
2009-10-07 04:30:19 +00:00
endless_playback_function , " <path> " , SAF_NONE ) ;
2008-03-13 01:35:48 +00:00
SWITCH_ADD_APP ( app_interface , " att_xfer " , " Attended Transfer " , " Attended Transfer " , att_xfer_function , " <channel_url> " , SAF_NONE ) ;
2010-09-23 18:37:45 -05:00
SWITCH_ADD_APP ( app_interface , " read " , " Read Digits " , " Read Digits " , read_function ,
" <min> <max> <file> <var_name> <timeout> <terminators> <digit_timeout> " , SAF_NONE ) ;
2010-02-06 03:38:24 +00:00
SWITCH_ADD_APP ( app_interface , " play_and_get_digits " , " Play and get Digits " , " Play and get Digits " ,
2010-09-23 18:37:45 -05:00
play_and_get_digits_function ,
2011-08-18 20:29:52 -07:00
" \n \t <min> <max> <tries> <timeout> <terminators> <file> <invalid_file> <var_name> <regexp> [<digit_timeout>] ['<failure_ext> [failure_dp [failure_context]]'] " , SAF_NONE ) ;
2007-06-20 05:15:07 +00:00
SWITCH_ADD_APP ( app_interface , " stop_record_session " , " Stop Record Session " , STOP_SESS_REC_DESC , stop_record_session_function , " <path> " , SAF_NONE ) ;
2009-12-02 18:13:11 +00:00
SWITCH_ADD_APP ( app_interface , " record_session " , " Record Session " , SESS_REC_DESC , record_session_function , " <path> [+<timeout>] " , SAF_MEDIA_TAP ) ;
2008-05-27 04:54:52 +00:00
SWITCH_ADD_APP ( app_interface , " record " , " Record File " , " Record a file from the channels input " , record_function ,
" <path> [<time_limit_secs>] [<silence_thresh>] [<silence_hits>] " , SAF_NONE ) ;
2009-09-23 22:39:00 +00:00
SWITCH_ADD_APP ( app_interface , " preprocess " , " pre-process " , " pre-process " , preprocess_session_function , " " , SAF_NONE ) ;
2008-05-27 04:54:52 +00:00
SWITCH_ADD_APP ( app_interface , " stop_displace_session " , " Stop Displace File " , " Stop Displacing to a file " , stop_displace_session_function , " <path> " ,
SAF_NONE ) ;
2008-07-14 20:57:35 +00:00
SWITCH_ADD_APP ( app_interface , " displace_session " , " Displace File " , DISPLACE_DESC , displace_session_function , " <path> [<flags>] [+time_limit_ms] " ,
2009-12-02 18:13:11 +00:00
SAF_MEDIA_TAP ) ;
2007-06-20 05:15:07 +00:00
SWITCH_ADD_APP ( app_interface , " speak " , " Speak text " , SPEAK_DESC , speak_function , " <engine>|<voice>|<text> " , SAF_NONE ) ;
2008-05-27 04:54:52 +00:00
SWITCH_ADD_APP ( app_interface , " clear_speech_cache " , " Clear Speech Handle Cache " , " Clear Speech Handle Cache " , clear_speech_cache_function , " " ,
SAF_NONE ) ;
SWITCH_ADD_APP ( app_interface , " bridge " , " Bridge Audio " , " Bridge the audio between two sessions " , audio_bridge_function , " <channel_url> " ,
SAF_SUPPORT_NOMEDIA ) ;
SWITCH_ADD_APP ( app_interface , " system " , " Execute a system command " , " Execute a system command " , system_session_function , " <command> " ,
2011-11-28 16:45:59 -06:00
SAF_SUPPORT_NOMEDIA | SAF_ZOMBIE_EXEC ) ;
2008-05-09 22:16:08 +00:00
SWITCH_ADD_APP ( app_interface , " say " , " say " , " say " , say_function , SAY_SYNTAX , SAF_NONE ) ;
2006-11-28 02:23:26 +00:00
2010-02-06 03:38:24 +00:00
SWITCH_ADD_APP ( app_interface , " wait_for_silence " , " wait_for_silence " , " wait_for_silence " , wait_for_silence_function , WAIT_FOR_SILENCE_SYNTAX ,
SAF_NONE ) ;
SWITCH_ADD_APP ( app_interface , " session_loglevel " , " session_loglevel " , " session_loglevel " , session_loglevel_function , SESSION_LOGLEVEL_SYNTAX ,
SAF_SUPPORT_NOMEDIA ) ;
2010-04-01 21:31:14 -05:00
SWITCH_ADD_APP ( app_interface , " limit " , " Limit " , LIMIT_DESC , limit_function , LIMIT_USAGE , SAF_SUPPORT_NOMEDIA ) ;
2010-06-20 04:12:50 -05:00
SWITCH_ADD_APP ( app_interface , " limit_hash " , " Limit " , LIMIT_HASH_DESC , limit_hash_function , LIMIT_HASH_USAGE , SAF_SUPPORT_NOMEDIA ) ;
SWITCH_ADD_APP ( app_interface , " limit_execute " , " Limit " , LIMITEXECUTE_DESC , limit_execute_function , LIMITEXECUTE_USAGE , SAF_SUPPORT_NOMEDIA ) ;
SWITCH_ADD_APP ( app_interface , " limit_hash_execute " , " Limit " , LIMITHASHEXECUTE_DESC , limit_hash_execute_function , LIMITHASHEXECUTE_USAGE , SAF_SUPPORT_NOMEDIA ) ;
2008-07-10 15:57:41 +00:00
2012-05-04 18:59:25 -05:00
SWITCH_ADD_APP ( app_interface , " pickup " , " Pickup " , " Pickup a call " , pickup_function , PICKUP_SYNTAX , SAF_SUPPORT_NOMEDIA ) ;
2008-04-22 15:18:35 +00:00
SWITCH_ADD_DIALPLAN ( dp_interface , " inline " , inline_dialplan_hunt ) ;
2006-11-28 02:23:26 +00:00
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS ;
}
2006-11-27 22:30:48 +00:00
/* For Emacs:
* Local Variables :
* mode : c
2008-02-03 22:14:57 +00:00
* indent - tabs - mode : t
2006-11-27 22:30:48 +00:00
* tab - width : 4
* c - basic - offset : 4
* End :
* For VIM :
2008-07-03 19:12:26 +00:00
* vim : set softtabstop = 4 shiftwidth = 4 tabstop = 4 :
2006-11-27 22:30:48 +00:00
*/