2017-01-06 07:10:15 +00:00
/*
2007-03-29 22:34:40 +00:00
* FreeSWITCH Modular Media Switching Software Library / Soft - Switch Application
2021-03-18 23:28:40 +00:00
* Copyright ( C ) 2005 - 2021 , Anthony Minessale II < anthm @ freeswitch . org >
2007-03-29 22:34:40 +00:00
*
* Version : MPL 1.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 ( the " License " ) ; you may not use this file except in compliance with
* the License . You may obtain a copy of the License at
* http : //www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an " AS IS " basis ,
* WITHOUT WARRANTY OF ANY KIND , either express or implied . See the License
* for the specific language governing rights and limitations under the
* License .
*
* The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft - Switch Application
*
* The Initial Developer of the Original Code is
2009-02-04 21:20:54 +00:00
* Anthony Minessale II < anthm @ freeswitch . org >
2007-03-29 22:34:40 +00:00
* Portions created by the Initial Developer are Copyright ( C )
* the Initial Developer . All Rights Reserved .
*
* Contributor ( s ) :
2017-01-06 07:10:15 +00:00
*
2009-02-04 21:20:54 +00:00
* Anthony Minessale II < anthm @ freeswitch . org >
2007-03-29 22:34:40 +00:00
* Michael Jerris < mike @ jerris . com >
2008-10-22 17:51:34 +00:00
* Travis Cross < tc @ traviscross . com >
2007-03-29 22:34:40 +00:00
*
* switch_ivr_originate . c - - IVR Library ( originate )
*
*/
2008-01-27 17:36:53 +00:00
2007-03-29 22:34:40 +00:00
# include <switch.h>
2010-07-16 02:09:48 +00:00
# define QUOTED_ESC_COMMA 1
# define UNQUOTED_ESC_COMMA 2
2007-03-29 22:34:40 +00:00
static const switch_state_handler_table_t originate_state_handlers ;
2008-05-05 15:30:55 +00:00
static switch_status_t originate_on_consume_media_transmit ( switch_core_session_t * session )
2008-03-03 18:05:07 +00:00
{
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
2008-05-27 04:30:03 +00:00
2010-06-02 22:31:08 +00:00
if ( ! switch_channel_test_flag ( channel , CF_PROXY_MODE ) & & switch_channel_test_flag ( channel , CF_CONSUME_ON_ORIGINATE ) ) {
while ( switch_channel_test_flag ( channel , CF_ORIGINATING ) & &
switch_channel_get_state ( channel ) = = CS_CONSUME_MEDIA & & ! switch_channel_test_flag ( channel , CF_TAGGED ) ) {
2009-01-06 23:26:49 +00:00
if ( ! switch_channel_media_ready ( channel ) ) {
switch_yield ( 10000 ) ;
} else {
switch_ivr_sleep ( session , 10 , SWITCH_FALSE , NULL ) ;
}
2012-04-18 19:49:00 +00:00
switch_ivr_parse_all_messages ( session ) ;
2008-12-26 17:09:09 +00:00
}
}
2008-03-03 18:05:07 +00:00
switch_channel_clear_state_handler ( channel , & originate_state_handlers ) ;
return SWITCH_STATUS_FALSE ;
}
2008-05-05 15:30:55 +00:00
static switch_status_t originate_on_routing ( switch_core_session_t * session )
2007-03-29 22:34:40 +00:00
{
2008-01-28 07:26:10 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
2007-03-29 22:34:40 +00:00
2009-02-03 17:17:31 +00:00
if ( switch_channel_get_state ( channel ) = = CS_ROUTING ) {
/* put the channel in a passive state until it is answered */
switch_channel_set_state ( channel , CS_CONSUME_MEDIA ) ;
}
2008-03-03 18:05:07 +00:00
2007-03-29 22:34:40 +00:00
return SWITCH_STATUS_FALSE ;
}
static const switch_state_handler_table_t originate_state_handlers = {
/*.on_init */ NULL ,
2008-05-05 15:30:55 +00:00
/*.on_routing */ originate_on_routing ,
2007-03-29 22:34:40 +00:00
/*.on_execute */ NULL ,
/*.on_hangup */ NULL ,
2008-05-05 15:30:55 +00:00
/*.on_exchange_media */ NULL ,
/*.on_soft_execute */ originate_on_consume_media_transmit ,
/*.on_consume_media */ originate_on_consume_media_transmit
2007-03-29 22:34:40 +00:00
} ;
FS-11346: [core] add api to pass pre-parsed values instead of dial strings to switch_ivr_originate
SWITCH_DECLARE(switch_status_t) switch_dial_handle_create(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_destroy(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_add_leg_list(switch_dial_handle_t *handle, switch_dial_leg_list_t **leg_listP);
SWITCH_DECLARE(void) switch_dial_leg_list_add_leg(switch_dial_leg_list_t *parent, const char *dial_string, switch_dial_leg_t **legP);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var(switch_dial_handle_t *handle, const char *var, const char *val);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var_printf(switch_dial_handle_t *handle, const char *var, const char *fmt, ...);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var(switch_dial_leg_t *leg, const char *var, const char *val);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var_printf(switch_dial_leg_t *leg, const char *var, const char *fmt, ...);
SWITCH_DECLARE(int) switch_dial_handle_get_peers(switch_dial_handle_t *handle, int idx, char **array, int max);
SWITCH_DECLARE(int) switch_dial_handle_get_vars(switch_dial_handle_t *handle, int idx, switch_event_t **array, int max);
SWITCH_DECLARE(switch_event_t *) switch_dial_handle_get_global_vars(switch_dial_handle_t *handle);
SWITCH_DECLARE(switch_event_t *) switch_dial_leg_get_vars(switch_dial_leg_t *leg);
SWITCH_DECLARE(int) switch_dial_handle_get_total(switch_dial_handle_t *handle);
SWITCH_DECLARE(void) switch_ivr_orig_and_bridge(switch_core_session_t *session, const char *data, switch_dial_handle_t *dh);
add switch_dial_handle_t *dh to end of args for switch_ivr_originate
2018-08-16 00:40:30 +00:00
# define MAX_PEERS 128
struct switch_dial_handle_s ;
struct switch_dial_leg_list_s {
int leg_idx ;
switch_dial_leg_t * legs [ MAX_PEERS ] ;
struct switch_dial_handle_s * handle ;
} ;
struct switch_dial_leg_s {
char * dial_string ;
switch_event_t * leg_vars ;
struct switch_dial_handle_s * handle ;
struct switch_dial_leg_s * next ;
} ;
struct switch_dial_handle_s {
int is_sub ;
int leg_list_idx ;
switch_dial_leg_list_t * leg_lists [ MAX_PEERS ] ;
switch_event_t * global_vars ;
switch_memory_pool_t * pool ;
} ;
2021-03-18 23:28:40 +00:00
struct switch_dial_handle_list_s {
int handle_idx ;
switch_dial_handle_t * handles [ MAX_PEERS ] ;
switch_event_t * global_vars ;
switch_memory_pool_t * pool ;
} ;
static switch_status_t switch_dial_handle_dup ( switch_dial_handle_t * * handle , switch_dial_handle_t * todup ) ;
2009-01-19 17:54:54 +00:00
typedef struct {
2015-06-19 06:34:31 +00:00
switch_core_session_t * down_session ;
2009-01-19 17:54:54 +00:00
switch_core_session_t * peer_session ;
switch_channel_t * peer_channel ;
switch_caller_profile_t * caller_profile ;
uint8_t ring_ready ;
uint8_t early_media ;
uint8_t answered ;
2010-01-16 00:41:10 +00:00
uint8_t tagged ;
2021-07-09 11:52:00 +00:00
uint8_t array_pos ;
2009-01-20 00:21:58 +00:00
uint32_t per_channel_timelimit_sec ;
uint32_t per_channel_progress_timelimit_sec ;
2009-03-04 04:19:33 +00:00
uint32_t per_channel_delay_start ;
2009-01-19 17:54:54 +00:00
} originate_status_t ;
typedef struct {
switch_core_session_t * session ;
int32_t idx ;
uint32_t hups ;
2011-08-25 13:27:23 +00:00
char * file ;
char * error_file ;
2010-03-12 23:49:51 +00:00
int confirm_timeout ;
2020-01-06 12:25:44 +00:00
int confirm_read_timeout ;
2009-01-19 17:54:54 +00:00
char key [ 80 ] ;
uint8_t early_ok ;
uint8_t ring_ready ;
2009-02-11 00:22:41 +00:00
uint8_t instant_ringback ;
2009-01-19 17:54:54 +00:00
uint8_t sent_ring ;
uint8_t progress ;
uint8_t return_ring_ready ;
2009-01-19 23:15:59 +00:00
uint8_t monitor_early_media_ring ;
uint8_t monitor_early_media_fail ;
2009-01-20 15:39:32 +00:00
uint8_t gen_ringback ;
uint8_t ignore_early_media ;
uint8_t ignore_ring_ready ;
2009-02-11 14:56:22 +00:00
int monitor_early_media_ring_count ;
int monitor_early_media_ring_total ;
2016-02-04 22:14:43 +00:00
switch_bool_t cancel_timeout ;
2009-10-08 17:43:51 +00:00
int continue_on_timeout ;
2009-10-29 05:47:17 +00:00
int ringback_ok ;
int sending_ringback ;
2010-01-14 21:02:11 +00:00
int bridge_early_media ;
2010-01-15 21:10:31 +00:00
switch_thread_t * ethread ;
2010-05-03 17:13:37 +00:00
switch_caller_profile_t * caller_profile_override ;
2012-04-11 20:30:37 +00:00
switch_bool_t check_vars ;
2010-05-03 17:13:37 +00:00
switch_memory_pool_t * pool ;
2020-05-07 17:04:54 +00:00
originate_status_t originate_status [ MAX_PEERS ] ; // = { {0} };
2009-01-19 17:54:54 +00:00
} originate_global_t ;
2007-03-29 22:34:40 +00:00
typedef enum {
2013-12-04 23:46:02 +00:00
IDX_XFER = - 5 ,
2009-10-07 04:30:19 +00:00
IDX_KEY_CANCEL = - 4 ,
2008-04-16 21:29:57 +00:00
IDX_TIMEOUT = - 3 ,
2007-03-29 22:34:40 +00:00
IDX_CANCEL = - 2 ,
IDX_NADA = - 1
} abort_t ;
struct key_collect {
char * key ;
char * file ;
2010-03-12 23:49:51 +00:00
char * error_file ;
2020-01-06 12:25:44 +00:00
int confirm_read_timeout ;
2007-03-29 22:34:40 +00:00
switch_core_session_t * session ;
} ;
2008-05-27 04:30:03 +00:00
static void * SWITCH_THREAD_FUNC collect_thread_run ( switch_thread_t * thread , void * obj )
2007-03-29 22:34:40 +00:00
{
struct key_collect * collect = ( struct key_collect * ) obj ;
switch_channel_t * channel = switch_core_session_get_channel ( collect - > session ) ;
2007-09-29 01:06:08 +00:00
char buf [ 10 ] = SWITCH_BLANK_STRING ;
2010-01-21 02:34:06 +00:00
switch_application_interface_t * application_interface = NULL ;
2007-03-29 22:34:40 +00:00
2008-10-14 18:03:14 +00:00
if ( collect - > session ) {
if ( switch_core_session_read_lock ( collect - > session ) ! = SWITCH_STATUS_SUCCESS ) {
return NULL ;
}
} else {
return NULL ;
}
2010-02-06 03:38:24 +00:00
2008-12-10 00:48:24 +00:00
switch_ivr_sleep ( collect - > session , 0 , SWITCH_TRUE , NULL ) ;
2010-02-06 03:38:24 +00:00
2007-03-29 22:34:40 +00:00
if ( ! strcasecmp ( collect - > key , " exec " ) ) {
char * data ;
char * app_name , * app_data ;
2017-01-06 07:10:15 +00:00
2007-03-29 22:34:40 +00:00
if ( ! ( data = collect - > file ) ) {
goto wbreak ;
}
app_name = data ;
if ( ( app_data = strchr ( app_name , ' ' ) ) ) {
* app_data + + = ' \0 ' ;
}
if ( ( application_interface = switch_loadable_module_get_application_interface ( app_name ) ) = = 0 ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( collect - > session ) , SWITCH_LOG_ERROR , " Invalid Application %s \n " , app_name ) ;
2007-03-29 22:34:40 +00:00
switch_channel_hangup ( channel , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
goto wbreak ;
}
if ( ! application_interface - > application_function ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( collect - > session ) , SWITCH_LOG_ERROR , " No Function for %s \n " , app_name ) ;
2007-03-29 22:34:40 +00:00
switch_channel_hangup ( channel , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
goto wbreak ;
}
2007-04-21 01:03:58 +00:00
switch_core_session_exec ( collect - > session , application_interface , app_data ) ;
2008-05-27 04:30:03 +00:00
2011-11-18 19:17:56 +00:00
if ( switch_channel_up_nosig ( channel ) ) {
2007-03-29 22:34:40 +00:00
switch_channel_set_flag ( channel , CF_WINNER ) ;
2012-09-04 16:24:13 +00:00
switch_channel_set_variable ( channel , " group_dial_status " , " winner " ) ;
2007-03-29 22:34:40 +00:00
}
goto wbreak ;
}
2011-11-18 19:17:56 +00:00
if ( ! switch_channel_up_nosig ( channel ) ) {
2007-03-29 22:34:40 +00:00
switch_channel_hangup ( channel , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
goto wbreak ;
}
while ( switch_channel_ready ( channel ) ) {
2010-03-12 23:49:51 +00:00
switch_size_t len = strlen ( collect - > key ) ;
const char * file = collect - > file ;
switch_status_t status ;
2007-03-29 22:34:40 +00:00
memset ( buf , 0 , sizeof ( buf ) ) ;
2010-03-12 23:49:51 +00:00
if ( zstr ( file ) ) {
file = " silence " ;
}
2017-01-06 07:10:15 +00:00
2010-03-12 23:49:51 +00:00
status = switch_ivr_read ( collect - > session ,
2014-01-22 21:28:53 +00:00
( uint32_t ) len ,
( uint32_t ) len ,
2020-01-06 12:25:44 +00:00
file , NULL , buf , sizeof ( buf ) , collect - > confirm_read_timeout , NULL , 0 ) ;
2017-01-06 07:10:15 +00:00
2010-03-12 23:49:51 +00:00
if ( status ! = SWITCH_STATUS_SUCCESS & & status ! = SWITCH_STATUS_BREAK & & status ! = SWITCH_STATUS_TOO_SMALL ) {
2011-08-25 13:27:23 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( collect - > session ) , SWITCH_LOG_ERROR , " %s Error Playing File! \n " ,
2010-03-12 23:49:51 +00:00
switch_channel_get_name ( channel ) ) ;
switch_channel_hangup ( channel , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
2007-03-29 22:34:40 +00:00
}
2017-01-06 07:10:15 +00:00
2010-03-12 23:49:51 +00:00
if ( ! strcmp ( collect - > key , buf ) ) {
switch_channel_set_flag ( channel , CF_WINNER ) ;
2012-09-04 16:24:13 +00:00
switch_channel_set_variable ( channel , " group_dial_status " , " winner " ) ;
2010-03-12 23:49:51 +00:00
goto wbreak ;
} else if ( collect - > error_file ) {
switch_ivr_play_file ( collect - > session , NULL , collect - > error_file , NULL ) ;
2007-03-29 22:34:40 +00:00
}
}
2010-02-06 03:38:24 +00:00
wbreak :
2008-10-14 18:03:14 +00:00
switch_core_session_rwunlock ( collect - > session ) ;
2011-10-24 13:47:08 +00:00
2010-02-06 03:38:24 +00:00
UNPROTECT_INTERFACE ( application_interface ) ;
2011-10-24 13:47:08 +00:00
2007-03-29 22:34:40 +00:00
return NULL ;
}
static void launch_collect_thread ( struct key_collect * collect )
{
switch_thread_t * thread ;
switch_threadattr_t * thd_attr = NULL ;
switch_threadattr_create ( & thd_attr , switch_core_session_get_pool ( collect - > session ) ) ;
switch_threadattr_detach_set ( thd_attr , 1 ) ;
switch_threadattr_stacksize_set ( thd_attr , SWITCH_THREAD_STACKSIZE ) ;
2007-03-30 00:13:31 +00:00
switch_thread_create ( & thread , thd_attr , collect_thread_run , collect , switch_core_session_get_pool ( collect - > session ) ) ;
2007-03-29 22:34:40 +00:00
}
2009-02-03 20:33:24 +00:00
static int check_per_channel_timeouts ( originate_global_t * oglobals ,
2020-05-07 17:04:54 +00:00
int max , time_t start , switch_call_cause_t * force_reason )
2008-10-09 00:38:59 +00:00
{
2010-02-06 03:38:24 +00:00
int x = 0 , i , delayed_channels = 0 , active_channels = 0 ;
uint32_t early_exit_time = 0 , delayed_min = 0 ;
2009-09-30 23:28:49 +00:00
2009-01-25 21:23:07 +00:00
time_t elapsed = switch_epoch_time_now ( NULL ) - start ;
2008-10-09 00:38:59 +00:00
2009-09-30 23:28:49 +00:00
for ( i = 0 ; i < max ; i + + ) {
2020-05-07 17:04:54 +00:00
if ( oglobals - > originate_status [ i ] . peer_channel & & switch_channel_get_state ( oglobals - > originate_status [ i ] . peer_channel ) ! = CS_DESTROY & &
switch_channel_get_state ( oglobals - > originate_status [ i ] . peer_channel ) ! = CS_REPORTING ) {
if ( oglobals - > originate_status [ i ] . per_channel_delay_start ) {
2009-09-30 23:28:49 +00:00
delayed_channels + + ;
} else {
active_channels + + ;
}
}
}
2009-07-14 17:19:14 +00:00
2009-09-30 23:28:49 +00:00
if ( active_channels = = 0 & & delayed_channels ) {
for ( i = 0 ; i < max ; i + + ) {
2020-05-07 17:04:54 +00:00
if ( oglobals - > originate_status [ i ] . peer_channel & & oglobals - > originate_status [ i ] . per_channel_delay_start & &
( ! delayed_min | | delayed_min > oglobals - > originate_status [ i ] . per_channel_delay_start ) ) {
delayed_min = oglobals - > originate_status [ i ] . per_channel_delay_start ;
2009-09-30 23:28:49 +00:00
}
}
2009-10-01 18:56:47 +00:00
early_exit_time = delayed_min - ( uint32_t ) elapsed ;
2009-09-30 23:28:49 +00:00
}
2008-10-09 00:38:59 +00:00
for ( i = 0 ; i < max ; i + + ) {
2020-05-07 17:04:54 +00:00
if ( oglobals - > originate_status [ i ] . peer_channel & & oglobals - > originate_status [ i ] . per_channel_delay_start & &
( elapsed > oglobals - > originate_status [ i ] . per_channel_delay_start | | active_channels = = 0 ) ) {
2009-09-30 23:28:49 +00:00
if ( active_channels = = 0 ) {
2020-05-07 17:04:54 +00:00
if ( oglobals - > originate_status [ i ] . per_channel_timelimit_sec ) {
if ( oglobals - > originate_status [ i ] . per_channel_timelimit_sec > early_exit_time ) {
2009-10-29 05:47:17 +00:00
/* IN theory this check is not needed ( should just be if !0 then -= with no else), if its not 0 it should always be greater.... */
2020-05-07 17:04:54 +00:00
oglobals - > originate_status [ i ] . per_channel_timelimit_sec - = early_exit_time ;
2009-10-29 05:47:17 +00:00
} else {
2020-05-07 17:04:54 +00:00
oglobals - > originate_status [ i ] . per_channel_timelimit_sec = 1 ;
2009-10-29 05:47:17 +00:00
}
2009-09-30 23:28:49 +00:00
}
2020-05-07 17:04:54 +00:00
if ( oglobals - > originate_status [ i ] . per_channel_progress_timelimit_sec ) {
if ( oglobals - > originate_status [ i ] . per_channel_progress_timelimit_sec > early_exit_time ) {
2009-10-29 05:47:17 +00:00
/* IN theory this check is not needed ( should just be if !0 then -= with no else), if its not 0 it should always be greater.... */
2020-05-07 17:04:54 +00:00
oglobals - > originate_status [ i ] . per_channel_progress_timelimit_sec - = early_exit_time ;
2009-10-29 05:47:17 +00:00
} else {
2020-05-07 17:04:54 +00:00
oglobals - > originate_status [ i ] . per_channel_progress_timelimit_sec = 1 ;
2009-10-29 05:47:17 +00:00
}
2009-09-30 23:28:49 +00:00
}
2020-05-07 17:04:54 +00:00
oglobals - > originate_status [ i ] . per_channel_delay_start - = delayed_min ;
2009-09-30 23:28:49 +00:00
} else {
2020-05-07 17:04:54 +00:00
oglobals - > originate_status [ i ] . per_channel_delay_start = 0 ;
2009-09-30 23:28:49 +00:00
}
2020-05-07 17:04:54 +00:00
if ( ! oglobals - > originate_status [ i ] . per_channel_delay_start ) {
switch_channel_clear_flag ( oglobals - > originate_status [ i ] . peer_channel , CF_BLOCK_STATE ) ;
2009-09-30 23:28:49 +00:00
}
2009-03-04 04:19:33 +00:00
}
2020-05-07 17:04:54 +00:00
if ( oglobals - > originate_status [ i ] . peer_channel & & switch_channel_up_nosig ( oglobals - > originate_status [ i ] . peer_channel ) ) {
if ( oglobals - > originate_status [ i ] . per_channel_progress_timelimit_sec & & elapsed > oglobals - > originate_status [ i ] . per_channel_progress_timelimit_sec & &
! ( switch_channel_test_flag ( oglobals - > originate_status [ i ] . peer_channel , CF_RING_READY ) | |
switch_channel_test_flag ( oglobals - > originate_status [ i ] . peer_channel , CF_ANSWERED ) | |
( ! oglobals - > monitor_early_media_ring & & switch_channel_test_flag ( oglobals - > originate_status [ i ] . peer_channel , CF_EARLY_MEDIA ) )
2010-02-06 03:38:24 +00:00
)
2008-10-09 00:38:59 +00:00
) {
2020-05-07 17:04:54 +00:00
switch_channel_hangup ( oglobals - > originate_status [ i ] . peer_channel , SWITCH_CAUSE_PROGRESS_TIMEOUT ) ;
2010-01-14 21:31:40 +00:00
* force_reason = SWITCH_CAUSE_PROGRESS_TIMEOUT ;
2008-10-09 00:38:59 +00:00
x + + ;
}
2020-05-07 17:04:54 +00:00
if ( oglobals - > originate_status [ i ] . per_channel_timelimit_sec & & elapsed > oglobals - > originate_status [ i ] . per_channel_timelimit_sec ) {
switch_channel_hangup ( oglobals - > originate_status [ i ] . peer_channel , SWITCH_CAUSE_ALLOTTED_TIMEOUT ) ;
2008-10-09 00:38:59 +00:00
x + + ;
}
}
}
return x ;
}
2020-05-07 17:04:54 +00:00
2009-01-19 23:15:59 +00:00
static switch_bool_t monitor_callback ( switch_core_session_t * session , const char * app , const char * data )
{
if ( app ) {
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
if ( ! strcmp ( app , " fail " ) ) {
2009-01-22 23:50:01 +00:00
const char * bd = switch_channel_get_variable ( channel , " monitor_fail_dispo " ) ;
if ( ! bd ) {
bd = " monitor_early_media_fail " ;
}
2011-08-10 13:38:55 +00:00
switch_channel_set_variable ( channel , " DIALSTATUS " , " BUSY " ) ;
2009-01-22 23:50:01 +00:00
switch_channel_set_variable ( channel , " originate_disposition " , bd ) ;
2009-01-19 23:15:59 +00:00
switch_channel_hangup ( channel , data ? switch_channel_str2cause ( data ) : SWITCH_CAUSE_USER_BUSY ) ;
} else if ( ! strcmp ( app , " ring " ) ) {
originate_global_t * oglobals = ( originate_global_t * ) switch_channel_get_private ( channel , " _oglobals_ " ) ;
2009-01-22 23:50:01 +00:00
const char * bd = switch_channel_get_variable ( channel , " monitor_ring_dispo " ) ;
if ( ! bd ) {
bd = " monitor_early_media_ring " ;
}
switch_channel_set_variable ( channel , " originate_disposition " , bd ) ;
2011-08-10 13:38:55 +00:00
switch_channel_set_variable ( channel , " DIALSTATUS " , " EARLY " ) ;
2010-02-06 03:38:24 +00:00
2009-01-19 23:15:59 +00:00
if ( oglobals ) {
2009-02-11 00:16:36 +00:00
if ( oglobals - > monitor_early_media_ring_total & & + + oglobals - > monitor_early_media_ring_count < oglobals - > monitor_early_media_ring_total ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Ring %d/%d \n " ,
2009-02-11 00:16:36 +00:00
oglobals - > monitor_early_media_ring_count , oglobals - > monitor_early_media_ring_total ) ;
return SWITCH_TRUE ;
}
2010-02-06 03:38:24 +00:00
2009-01-19 23:15:59 +00:00
switch_channel_set_private ( channel , " _oglobals_ " , NULL ) ;
2010-02-06 03:38:24 +00:00
2009-01-19 23:30:41 +00:00
if ( ! oglobals - > progress ) {
oglobals - > progress = 1 ;
}
2010-02-06 03:38:24 +00:00
2009-01-20 15:39:32 +00:00
if ( ! oglobals - > ring_ready & & ! oglobals - > ignore_ring_ready ) {
2009-01-19 23:30:41 +00:00
oglobals - > ring_ready = 1 ;
}
2010-02-06 03:38:24 +00:00
2009-01-20 15:39:32 +00:00
if ( ! oglobals - > ignore_early_media & & ! oglobals - > early_ok ) {
oglobals - > early_ok = 1 ;
}
2009-01-19 23:15:59 +00:00
}
}
}
return SWITCH_FALSE ;
}
2010-04-23 21:09:27 +00:00
static void inherit_codec ( switch_channel_t * caller_channel , switch_core_session_t * session )
{
const char * var = switch_channel_get_variable ( caller_channel , " inherit_codec " ) ;
switch_channel_t * channel = switch_core_session_get_channel ( session ) ;
2012-06-01 15:06:28 +00:00
if ( ! zstr ( var ) & & ! strcasecmp ( var , " passthru " ) ) {
switch_channel_set_variable ( caller_channel , " absolute_codec_string " , switch_channel_get_variable ( channel , " ep_codec_string " ) ) ;
} else if ( switch_true ( var ) ) {
2010-04-23 21:09:27 +00:00
switch_codec_implementation_t impl = { 0 } ;
switch_codec_implementation_t video_impl = { 0 } ;
char tmp [ 128 ] = " " ;
if ( switch_core_session_get_read_impl ( session , & impl ) = = SWITCH_STATUS_SUCCESS ) {
2010-12-31 17:59:33 +00:00
const char * ep = switch_channel_get_variable ( caller_channel , " ep_codec_string " ) ;
2010-06-01 17:10:50 +00:00
if ( switch_core_session_get_video_read_impl ( session , & video_impl ) = = SWITCH_STATUS_SUCCESS ) {
2010-04-23 21:09:27 +00:00
switch_snprintf ( tmp , sizeof ( tmp ) , " %s@%uh@%ui,%s " ,
2012-12-29 20:57:15 +00:00
impl . iananame , impl . samples_per_second , ( uint32_t ) impl . microseconds_per_packet / 1000 ,
2010-04-23 21:09:27 +00:00
video_impl . iananame ) ;
} else {
switch_snprintf ( tmp , sizeof ( tmp ) , " %s@%uh@%ui " ,
2012-12-29 20:57:15 +00:00
impl . iananame , impl . samples_per_second , ( uint32_t ) impl . microseconds_per_packet / 1000 ) ;
2010-04-23 21:09:27 +00:00
}
2017-01-06 07:10:15 +00:00
2010-12-31 17:59:33 +00:00
if ( ep & & switch_stristr ( impl . iananame , ep ) ) {
switch_channel_set_variable ( caller_channel , " absolute_codec_string " , tmp ) ;
switch_log_printf ( SWITCH_CHANNEL_CHANNEL_LOG ( caller_channel ) , SWITCH_LOG_DEBUG , " Setting codec string on %s to %s \n " ,
switch_channel_get_name ( caller_channel ) , tmp ) ;
} else {
switch_log_printf ( SWITCH_CHANNEL_CHANNEL_LOG ( caller_channel ) , SWITCH_LOG_DEBUG , " Codec string %s not supported on %s, skipping inheritance \n " ,
tmp , switch_channel_get_name ( caller_channel ) ) ;
}
2010-04-23 21:09:27 +00:00
} else {
switch_log_printf ( SWITCH_CHANNEL_CHANNEL_LOG ( caller_channel ) , SWITCH_LOG_WARNING ,
" Error inheriting codec. Channel %s has no read codec yet. \n " ,
switch_channel_get_name ( channel ) ) ;
}
}
}
2020-01-06 12:25:44 +00:00
static uint8_t check_channel_status ( originate_global_t * oglobals , uint32_t len , switch_call_cause_t * force_reason , time_t start )
2007-03-29 22:34:40 +00:00
{
uint32_t i ;
2009-01-19 21:11:01 +00:00
uint8_t rval = 0 ;
2009-01-16 16:22:29 +00:00
switch_channel_t * caller_channel = NULL ;
int pindex = - 1 ;
2009-02-11 14:56:22 +00:00
char bug_key [ 256 ] = " " ;
2009-10-29 05:47:17 +00:00
int send_ringback = 0 ;
2010-06-17 17:52:20 +00:00
uint8_t ring_ready_val = 0 ;
2016-11-03 20:39:43 +00:00
int pickups_without_timelimit = 0 ;
2009-02-11 14:56:22 +00:00
2009-01-19 21:11:01 +00:00
oglobals - > hups = 0 ;
oglobals - > idx = IDX_NADA ;
2009-02-11 14:56:22 +00:00
2009-01-16 16:22:29 +00:00
2009-01-19 17:54:54 +00:00
if ( oglobals - > session ) {
caller_channel = switch_core_session_get_channel ( oglobals - > session ) ;
2009-10-09 00:52:25 +00:00
if ( switch_channel_test_flag ( caller_channel , CF_XFER_ZOMBIE ) ) {
caller_channel = NULL ;
}
2009-01-16 16:22:29 +00:00
}
2010-02-06 03:38:24 +00:00
2008-05-27 04:30:03 +00:00
2012-05-07 15:05:51 +00:00
for ( i = 0 ; i < len ; i + + ) {
2020-05-07 17:04:54 +00:00
if ( oglobals - > originate_status [ i ] . peer_channel & & switch_channel_test_flag ( oglobals - > originate_status [ i ] . peer_channel , CF_CHANNEL_SWAP ) ) {
const char * key = switch_channel_get_variable ( oglobals - > originate_status [ i ] . peer_channel , " channel_swap_uuid " ) ;
2012-05-07 15:05:51 +00:00
switch_core_session_t * swap_session , * old_session ;
2020-05-07 17:04:54 +00:00
2012-05-07 15:05:51 +00:00
if ( ( swap_session = switch_core_session_locate ( key ) ) ) {
2020-05-07 17:04:54 +00:00
switch_channel_clear_flag ( oglobals - > originate_status [ i ] . peer_channel , CF_CHANNEL_SWAP ) ;
switch_channel_hangup ( oglobals - > originate_status [ i ] . peer_channel , SWITCH_CAUSE_PICKED_OFF ) ;
2012-05-07 15:05:51 +00:00
2020-05-07 17:04:54 +00:00
switch_log_printf ( SWITCH_CHANNEL_CHANNEL_LOG ( oglobals - > originate_status [ i ] . peer_channel ) , SWITCH_LOG_DEBUG , " Swapping %s for %s \n " ,
switch_core_session_get_name ( swap_session ) , switch_channel_get_name ( oglobals - > originate_status [ i ] . peer_channel ) ) ;
2017-01-06 07:10:15 +00:00
2020-05-07 17:04:54 +00:00
old_session = oglobals - > originate_status [ i ] . peer_session ;
oglobals - > originate_status [ i ] . peer_session = swap_session ;
oglobals - > originate_status [ i ] . peer_channel = switch_core_session_get_channel ( oglobals - > originate_status [ i ] . peer_session ) ;
oglobals - > originate_status [ i ] . caller_profile = switch_channel_get_caller_profile ( oglobals - > originate_status [ i ] . peer_channel ) ;
switch_channel_set_flag ( oglobals - > originate_status [ i ] . peer_channel , CF_ORIGINATING ) ;
2017-01-06 07:10:15 +00:00
2020-05-07 17:04:54 +00:00
switch_channel_answer ( oglobals - > originate_status [ i ] . peer_channel ) ;
2013-04-30 16:41:29 +00:00
2020-05-07 17:04:54 +00:00
switch_channel_set_variable ( oglobals - > originate_status [ i ] . peer_channel , " picked_up_uuid " , switch_core_session_get_uuid ( old_session ) ) ;
switch_channel_execute_on ( oglobals - > originate_status [ i ] . peer_channel , " execute_on_pickup " ) ;
switch_channel_api_on ( oglobals - > originate_status [ i ] . peer_channel , " api_on_pickup " ) ;
2013-04-30 16:41:29 +00:00
2012-05-07 15:05:51 +00:00
switch_core_session_rwunlock ( old_session ) ;
break ;
}
}
}
2007-03-29 22:34:40 +00:00
for ( i = 0 ; i < len ; i + + ) {
2008-01-05 01:03:08 +00:00
switch_channel_state_t state ;
2010-01-16 00:41:10 +00:00
2020-05-07 17:04:54 +00:00
if ( oglobals - > originate_status [ i ] . tagged & & oglobals - > originate_status [ i ] . peer_session ) {
switch_channel_t * channel = switch_core_session_get_channel ( oglobals - > originate_status [ i ] . peer_session ) ;
2010-01-17 17:29:26 +00:00
uint32_t j ;
2010-02-06 03:38:24 +00:00
2011-11-18 19:17:56 +00:00
if ( switch_channel_down_nosig ( channel ) ) {
2010-01-16 00:41:10 +00:00
switch_call_cause_t cause = switch_channel_get_cause ( channel ) ;
2010-02-06 03:38:24 +00:00
2010-01-16 00:41:10 +00:00
for ( j = 0 ; j < len ; j + + ) {
2020-05-07 17:04:54 +00:00
channel = switch_core_session_get_channel ( oglobals - > originate_status [ j ] . peer_session ) ;
2010-01-16 00:41:10 +00:00
switch_channel_hangup ( channel , cause ) ;
}
oglobals - > hups = len ;
rval = 0 ;
goto end ;
}
}
2010-02-06 03:38:24 +00:00
2012-05-07 13:17:41 +00:00
2020-05-07 17:04:54 +00:00
if ( oglobals - > originate_status [ i ] . peer_channel & & switch_channel_test_flag ( oglobals - > originate_status [ i ] . peer_channel , CF_PICKUP ) ) {
if ( oglobals - > originate_status [ i ] . per_channel_timelimit_sec = = 0 ) {
2016-11-03 20:39:43 +00:00
pickups_without_timelimit + + ;
}
2012-05-07 13:17:41 +00:00
}
2020-05-07 17:04:54 +00:00
if ( ! ( oglobals - > originate_status [ i ] . peer_channel & & oglobals - > originate_status [ i ] . peer_session ) ) {
2009-09-14 18:03:25 +00:00
oglobals - > hups + + ;
2007-03-29 22:34:40 +00:00
continue ;
}
2009-01-19 17:54:54 +00:00
2020-05-07 17:04:54 +00:00
if ( ( ring_ready_val = ( uint8_t ) switch_channel_test_flag ( oglobals - > originate_status [ i ] . peer_channel , CF_RING_READY ) ) ) {
if ( ! oglobals - > originate_status [ i ] . ring_ready ) {
oglobals - > originate_status [ i ] . ring_ready = ring_ready_val ;
2009-01-19 17:54:54 +00:00
}
2009-10-29 05:47:17 +00:00
if ( oglobals - > sending_ringback = = 1 ) {
send_ringback + + ;
pindex = ( uint32_t ) i ;
} else {
if ( ! oglobals - > ring_ready ) {
2010-06-15 20:48:12 +00:00
oglobals - > ring_ready = ring_ready_val ;
2009-10-29 05:47:17 +00:00
if ( caller_channel & & ! oglobals - > ignore_ring_ready ) {
if ( len = = 1 ) {
2020-05-07 17:04:54 +00:00
switch_channel_pass_callee_id ( oglobals - > originate_status [ 0 ] . peer_channel , caller_channel ) ;
2009-10-29 05:47:17 +00:00
}
2010-06-15 20:48:12 +00:00
switch_channel_ring_ready_value ( caller_channel , ring_ready_val ) ;
oglobals - > sent_ring = ring_ready_val ;
2009-10-21 18:48:28 +00:00
}
2009-10-12 22:23:55 +00:00
}
2009-01-19 17:54:54 +00:00
}
2007-03-29 22:34:40 +00:00
}
2009-09-14 18:03:25 +00:00
2020-05-07 17:04:54 +00:00
if ( switch_channel_test_flag ( oglobals - > originate_status [ i ] . peer_channel , CF_EARLY_MEDIA ) ) {
2009-10-29 05:47:17 +00:00
2010-01-14 21:02:11 +00:00
if ( oglobals - > ignore_early_media = = 3 & & oglobals - > bridge_early_media = = - 1 ) {
oglobals - > bridge_early_media = i ;
oglobals - > ringback_ok = 1 ;
}
2009-10-29 05:47:17 +00:00
if ( oglobals - > sending_ringback = = 1 ) {
send_ringback + + ;
pindex = ( uint32_t ) i ;
} else if ( ! oglobals - > sent_ring & & oglobals - > ignore_early_media = = 2 & & len = = 1 & & caller_channel & & ! oglobals - > ignore_ring_ready ) {
2020-05-07 17:04:54 +00:00
switch_channel_pass_callee_id ( oglobals - > originate_status [ 0 ] . peer_channel , caller_channel ) ;
2010-12-22 21:53:11 +00:00
switch_channel_ring_ready ( caller_channel ) ;
2009-10-22 22:11:28 +00:00
oglobals - > sent_ring = 1 ;
}
2020-05-07 17:04:54 +00:00
if ( ! oglobals - > originate_status [ i ] . early_media ) {
oglobals - > originate_status [ i ] . early_media = 1 ;
2009-01-19 17:54:54 +00:00
if ( oglobals - > early_ok ) {
pindex = i ;
}
2010-02-06 03:38:24 +00:00
2009-01-19 23:15:59 +00:00
if ( oglobals - > monitor_early_media_fail ) {
2020-05-07 17:04:54 +00:00
const char * var = switch_channel_get_variable ( oglobals - > originate_status [ i ] . peer_channel , " monitor_early_media_fail " ) ;
2009-10-23 16:03:42 +00:00
if ( ! zstr ( var ) ) {
2010-02-06 03:38:24 +00:00
char * fail_array [ 128 ] = { 0 } ;
2009-01-19 23:15:59 +00:00
int fail_count = 0 ;
char * fail_data = strdup ( var ) ;
int fx ;
2009-02-11 00:16:36 +00:00
int y = 0 ;
2009-01-19 23:15:59 +00:00
switch_assert ( fail_data ) ;
fail_count = switch_separate_string ( fail_data , ' ! ' , fail_array , ( sizeof ( fail_array ) / sizeof ( fail_array [ 0 ] ) ) ) ;
2010-02-06 03:38:24 +00:00
for ( fx = 0 ; fx < fail_count ; fx + + ) {
2009-01-19 23:15:59 +00:00
char * cause = fail_array [ fx ] ;
int hits = 2 ;
char * p , * q ;
2010-02-06 03:38:24 +00:00
2009-01-19 23:15:59 +00:00
if ( ! ( p = strchr ( cause , ' : ' ) ) ) {
2020-05-07 17:04:54 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( oglobals - > originate_status [ i ] . peer_session ) , SWITCH_LOG_ERROR , " Parse Error \n " ) ;
2009-01-19 23:15:59 +00:00
continue ;
}
* p + + = ' \0 ' ;
2010-02-06 03:38:24 +00:00
2009-01-19 23:15:59 +00:00
if ( ! p ) {
2020-05-07 17:04:54 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( oglobals - > originate_status [ i ] . peer_session ) , SWITCH_LOG_ERROR , " Parse Error \n " ) ;
2009-01-19 23:15:59 +00:00
continue ;
}
2010-02-06 03:38:24 +00:00
2009-01-19 23:15:59 +00:00
if ( ! ( hits = atoi ( p ) ) ) {
hits = 2 ;
}
2010-02-06 03:38:24 +00:00
2009-01-19 23:15:59 +00:00
if ( ! ( p = strchr ( p , ' : ' ) ) ) {
2020-05-07 17:04:54 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( oglobals - > originate_status [ i ] . peer_session ) , SWITCH_LOG_ERROR , " Parse Error \n " ) ;
2009-01-19 23:15:59 +00:00
continue ;
}
* p + + = ' \0 ' ;
2010-02-06 03:38:24 +00:00
2009-01-19 23:15:59 +00:00
if ( ! p ) {
2020-05-07 17:04:54 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( oglobals - > originate_status [ i ] . peer_session ) , SWITCH_LOG_ERROR , " Parse Error \n " ) ;
2009-01-19 23:15:59 +00:00
continue ;
}
2010-02-06 03:38:24 +00:00
for ( q = p ; q & & * q ; q + + ) {
2009-01-19 23:15:59 +00:00
if ( * q = = ' + ' ) {
* q = ' , ' ;
}
}
2009-02-11 00:16:36 +00:00
switch_snprintf ( bug_key , sizeof ( bug_key ) , " monitor_early_media_fail_%d " , + + y ) ;
2020-05-07 17:04:54 +00:00
switch_ivr_tone_detect_session ( oglobals - > originate_status [ i ] . peer_session , bug_key , p , " r " , 0 , hits , " fail " , cause , monitor_callback ) ;
2010-02-06 03:38:24 +00:00
2009-01-19 23:15:59 +00:00
}
2010-02-06 03:38:24 +00:00
2009-01-19 23:15:59 +00:00
switch_safe_free ( fail_data ) ;
2010-02-06 03:38:24 +00:00
2009-01-19 23:15:59 +00:00
}
}
2010-02-06 03:38:24 +00:00
2009-01-19 23:15:59 +00:00
if ( oglobals - > monitor_early_media_ring ) {
2020-05-07 17:04:54 +00:00
const char * var = switch_channel_get_variable ( oglobals - > originate_status [ i ] . peer_channel , " monitor_early_media_ring " ) ;
const char * var_total = switch_channel_get_variable ( oglobals - > originate_status [ i ] . peer_channel , " monitor_early_media_ring_total " ) ;
2009-10-23 16:03:42 +00:00
if ( ! zstr ( var ) ) {
2010-02-06 03:38:24 +00:00
char * ring_array [ 128 ] = { 0 } ;
2009-01-19 23:15:59 +00:00
int ring_count = 0 ;
char * ring_data = strdup ( var ) ;
int fx ;
2009-02-11 00:16:36 +00:00
int y = 0 ;
2009-01-19 23:15:59 +00:00
switch_assert ( ring_data ) ;
ring_count = switch_separate_string ( ring_data , ' ! ' , ring_array , ( sizeof ( ring_array ) / sizeof ( ring_array [ 0 ] ) ) ) ;
2010-02-06 03:38:24 +00:00
for ( fx = 0 ; fx < ring_count ; fx + + ) {
2009-01-19 23:15:59 +00:00
int hits = 2 ;
char * p = ring_array [ fx ] , * q ;
2010-02-06 03:38:24 +00:00
2009-01-21 02:18:03 +00:00
if ( ! p ) {
2020-05-07 17:04:54 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( oglobals - > originate_status [ i ] . peer_session ) , SWITCH_LOG_ERROR , " Parse Error \n " ) ;
2009-01-21 02:18:03 +00:00
continue ;
}
2009-01-19 23:15:59 +00:00
if ( ! ( hits = atoi ( p ) ) ) {
hits = 2 ;
}
2010-02-06 03:38:24 +00:00
2009-01-19 23:15:59 +00:00
if ( ! ( p = strchr ( p , ' : ' ) ) ) {
2020-05-07 17:04:54 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( oglobals - > originate_status [ i ] . peer_session ) , SWITCH_LOG_ERROR , " Parse Error \n " ) ;
2009-01-19 23:15:59 +00:00
continue ;
}
* p + + = ' \0 ' ;
2010-02-06 03:38:24 +00:00
2009-01-19 23:15:59 +00:00
if ( ! p ) {
2020-05-07 17:04:54 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( oglobals - > originate_status [ i ] . peer_session ) , SWITCH_LOG_ERROR , " Parse Error \n " ) ;
2009-01-19 23:15:59 +00:00
continue ;
}
2010-02-06 03:38:24 +00:00
for ( q = p ; q & & * q ; q + + ) {
2009-01-19 23:15:59 +00:00
if ( * q = = ' + ' ) {
* q = ' , ' ;
}
}
2010-02-06 03:38:24 +00:00
2020-05-07 17:04:54 +00:00
switch_channel_set_private ( oglobals - > originate_status [ i ] . peer_channel , " _oglobals_ " , oglobals ) ;
2009-02-11 00:16:36 +00:00
switch_snprintf ( bug_key , sizeof ( bug_key ) , " monitor_early_media_ring_%d " , + + y ) ;
2020-05-07 17:04:54 +00:00
switch_ivr_tone_detect_session ( oglobals - > originate_status [ i ] . peer_session , bug_key , p , " r " , 0 , hits , " ring " , NULL , monitor_callback ) ;
2010-02-06 03:38:24 +00:00
2009-01-19 23:15:59 +00:00
}
2010-02-06 03:38:24 +00:00
2009-02-11 00:16:36 +00:00
if ( var_total ) {
int tmp = atoi ( var_total ) ;
if ( tmp > 0 & & tmp < 100 ) {
2020-05-07 17:04:54 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( oglobals - > originate_status [ i ] . peer_session ) , SWITCH_LOG_DEBUG ,
" %s setting ring total to %d \n " , switch_channel_get_name ( oglobals - > originate_status [ i ] . peer_channel ) , tmp ) ;
2009-02-11 00:16:36 +00:00
oglobals - > monitor_early_media_ring_total = tmp ;
}
}
2010-02-06 03:38:24 +00:00
2009-01-19 23:15:59 +00:00
switch_safe_free ( ring_data ) ;
2010-02-06 03:38:24 +00:00
2009-01-19 23:15:59 +00:00
}
}
2009-01-19 17:54:54 +00:00
}
2010-02-06 03:38:24 +00:00
2009-01-19 23:30:41 +00:00
if ( ! oglobals - > monitor_early_media_ring ) {
if ( ! oglobals - > progress ) {
oglobals - > progress = 1 ;
}
2010-02-06 03:38:24 +00:00
2009-01-20 15:39:32 +00:00
if ( ! oglobals - > ring_ready & & ! oglobals - > ignore_ring_ready ) {
2009-01-19 23:30:41 +00:00
oglobals - > ring_ready = 1 ;
2010-02-06 03:38:24 +00:00
2009-01-19 23:30:41 +00:00
}
2009-01-19 17:54:54 +00:00
}
2008-06-23 22:07:22 +00:00
}
2017-01-06 07:10:15 +00:00
2020-05-07 17:04:54 +00:00
if ( ! switch_channel_test_flag ( oglobals - > originate_status [ i ] . peer_channel , CF_PARK ) & &
! switch_channel_test_flag ( oglobals - > originate_status [ i ] . peer_channel , CF_CONSUME_ON_ORIGINATE ) ) {
if ( switch_core_session_messages_waiting ( oglobals - > originate_status [ i ] . peer_session ) ) {
if ( switch_channel_test_flag ( oglobals - > originate_status [ i ] . peer_channel , CF_THREAD_SLEEPING ) ) {
switch_core_session_wake_session_thread ( oglobals - > originate_status [ i ] . peer_session ) ;
2010-11-30 15:49:12 +00:00
} else {
2020-05-07 17:04:54 +00:00
switch_ivr_parse_all_events ( oglobals - > originate_status [ i ] . peer_session ) ;
2010-11-30 15:49:12 +00:00
}
2010-11-29 21:34:27 +00:00
}
}
2008-12-08 17:08:26 +00:00
2020-05-07 17:04:54 +00:00
if ( switch_channel_test_flag ( oglobals - > originate_status [ i ] . peer_channel , CF_EARLY_OK ) ) {
2012-08-30 22:17:15 +00:00
if ( ! oglobals - > early_ok ) {
oglobals - > early_ok = 1 ;
}
2020-05-07 17:04:54 +00:00
switch_channel_clear_flag ( oglobals - > originate_status [ i ] . peer_channel , CF_EARLY_OK ) ;
2012-08-30 21:51:06 +00:00
}
2012-09-04 17:38:29 +00:00
if ( caller_channel & & switch_channel_test_flag ( caller_channel , CF_EARLY_OK ) ) {
if ( ! oglobals - > early_ok ) {
oglobals - > early_ok = 1 ;
}
switch_channel_clear_flag ( caller_channel , CF_EARLY_OK ) ;
}
2020-05-07 17:04:54 +00:00
state = switch_channel_get_state ( oglobals - > originate_status [ i ] . peer_channel ) ;
if ( state > = CS_HANGUP | | state = = CS_RESET | | switch_channel_test_flag ( oglobals - > originate_status [ i ] . peer_channel , CF_TRANSFER ) | |
switch_channel_test_flag ( oglobals - > originate_status [ i ] . peer_channel , CF_REDIRECT ) | |
switch_channel_test_flag ( oglobals - > originate_status [ i ] . peer_channel , CF_BRIDGED ) | |
! switch_channel_test_flag ( oglobals - > originate_status [ i ] . peer_channel , CF_ORIGINATING )
2008-05-27 04:30:03 +00:00
) {
2009-01-19 17:54:54 +00:00
( oglobals - > hups ) + + ;
2020-05-07 17:04:54 +00:00
if ( switch_channel_test_flag ( oglobals - > originate_status [ i ] . peer_channel , CF_PICKUP ) ) {
if ( oglobals - > originate_status [ i ] . per_channel_timelimit_sec = = 0 ) {
2016-11-03 20:39:43 +00:00
pickups_without_timelimit - - ;
}
2012-07-19 21:12:06 +00:00
}
2020-05-07 17:04:54 +00:00
} else if ( ( switch_channel_test_flag ( oglobals - > originate_status [ i ] . peer_channel , CF_ANSWERED ) | |
( oglobals - > early_ok & & switch_channel_test_flag ( oglobals - > originate_status [ i ] . peer_channel , CF_EARLY_MEDIA ) ) | |
2010-02-06 03:38:24 +00:00
( oglobals - > ring_ready & & oglobals - > return_ring_ready & & len = = 1 & &
2020-05-07 17:04:54 +00:00
switch_channel_test_flag ( oglobals - > originate_status [ i ] . peer_channel , CF_RING_READY ) )
2010-02-06 03:38:24 +00:00
)
2020-05-07 17:04:54 +00:00
& & ! switch_channel_test_flag ( oglobals - > originate_status [ i ] . peer_channel , CF_TAGGED )
2010-02-06 03:38:24 +00:00
) {
2019-11-06 14:10:54 +00:00
const char * group_confirm_key = switch_channel_get_variable ( oglobals - > originate_status [ i ] . peer_channel , " group_confirm_key " ) ;
const char * group_confirm_file = switch_channel_get_variable ( oglobals - > originate_status [ i ] . peer_channel , " group_confirm_file " ) ;
if ( ! zstr ( oglobals - > key ) | | ! zstr ( group_confirm_key ) ) {
2007-03-29 22:34:40 +00:00
struct key_collect * collect ;
2020-01-06 12:25:44 +00:00
const char * group_confirm_timeout = switch_channel_get_variable ( oglobals - > originate_status [ i ] . peer_channel , " group_confirm_timeout " ) ;
int extend_timeout = 0 ;
int cancel_timeout = 0 ;
if ( group_confirm_timeout & & switch_is_number ( group_confirm_timeout ) ) {
// leg var overrides global group_confirm_timeout
extend_timeout = atoi ( group_confirm_timeout ) ;
if ( extend_timeout = = 0 ) {
cancel_timeout = 1 ;
}
} else {
extend_timeout = oglobals - > confirm_timeout ;
}
2007-03-29 22:34:40 +00:00
2020-01-06 12:25:44 +00:00
if ( extend_timeout > 0 ) {
/* extend timeout for this leg only */
time_t elapsed = switch_epoch_time_now ( NULL ) - start ;
oglobals - > originate_status [ i ] . per_channel_progress_timelimit_sec = elapsed + extend_timeout ;
oglobals - > originate_status [ i ] . per_channel_timelimit_sec = elapsed + extend_timeout ;
2020-01-17 17:18:31 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " elapsed % " TIME_T_FMT " , timelimit extended to %u \n " , elapsed , oglobals - > originate_status [ i ] . per_channel_timelimit_sec ) ;
2020-01-06 12:25:44 +00:00
} else if ( oglobals - > cancel_timeout | | cancel_timeout ) {
2016-02-04 22:14:43 +00:00
/* cancel timeout for this leg only */
2020-05-07 17:04:54 +00:00
oglobals - > originate_status [ i ] . per_channel_progress_timelimit_sec = 0 ;
oglobals - > originate_status [ i ] . per_channel_timelimit_sec = 0 ;
2009-07-14 17:19:14 +00:00
}
2020-05-07 17:04:54 +00:00
if ( ( collect = switch_core_session_alloc ( oglobals - > originate_status [ i ] . peer_session , sizeof ( * collect ) ) ) ) {
switch_channel_set_flag ( oglobals - > originate_status [ i ] . peer_channel , CF_TAGGED ) ;
2019-11-06 14:10:54 +00:00
if ( ! zstr ( group_confirm_key ) ) {
collect - > key = switch_core_session_strdup ( oglobals - > originate_status [ i ] . peer_session , group_confirm_key ) ;
} else {
2020-05-07 17:04:54 +00:00
collect - > key = switch_core_session_strdup ( oglobals - > originate_status [ i ] . peer_session , oglobals - > key ) ;
2009-01-19 17:54:54 +00:00
}
2019-11-06 14:10:54 +00:00
if ( ! zstr ( group_confirm_file ) ) {
collect - > file = switch_core_session_strdup ( oglobals - > originate_status [ i ] . peer_session , group_confirm_file ) ;
} else if ( ! zstr ( oglobals - > file ) ) {
2020-05-07 17:04:54 +00:00
collect - > file = switch_core_session_strdup ( oglobals - > originate_status [ i ] . peer_session , oglobals - > file ) ;
2007-03-29 22:34:40 +00:00
}
2010-03-12 23:49:51 +00:00
if ( ! zstr ( oglobals - > error_file ) ) {
2020-05-07 17:04:54 +00:00
collect - > error_file = switch_core_session_strdup ( oglobals - > originate_status [ i ] . peer_session , oglobals - > error_file ) ;
2010-03-12 23:49:51 +00:00
}
2020-01-06 12:25:44 +00:00
if ( oglobals - > confirm_read_timeout ) {
collect - > confirm_read_timeout = oglobals - > confirm_read_timeout ;
2010-03-12 23:49:51 +00:00
} else {
2020-01-06 12:25:44 +00:00
collect - > confirm_read_timeout = 5000 ;
2010-03-12 23:49:51 +00:00
}
2020-05-07 17:04:54 +00:00
switch_channel_audio_sync ( oglobals - > originate_status [ i ] . peer_channel ) ;
collect - > session = oglobals - > originate_status [ i ] . peer_session ;
2007-03-29 22:34:40 +00:00
launch_collect_thread ( collect ) ;
}
} else {
2009-01-19 17:54:54 +00:00
oglobals - > idx = i ;
2009-01-16 16:22:29 +00:00
pindex = ( uint32_t ) i ;
rval = 0 ;
goto end ;
2007-03-29 22:34:40 +00:00
}
2020-05-07 17:04:54 +00:00
} else if ( switch_channel_test_flag ( oglobals - > originate_status [ i ] . peer_channel , CF_WINNER ) ) {
2020-04-24 22:10:41 +00:00
/* unset group_confirm variables */
switch_channel_set_variable ( oglobals - > originate_status [ i ] . peer_channel , " group_confirm_key " , NULL ) ;
switch_channel_set_variable ( oglobals - > originate_status [ i ] . peer_channel , " group_confirm_file " , NULL ) ;
switch_channel_set_variable ( oglobals - > originate_status [ i ] . peer_channel , " group_confirm_error_file " , NULL ) ;
switch_channel_set_variable ( oglobals - > originate_status [ i ] . peer_channel , " group_confirm_cancel_timeout " , NULL ) ;
switch_channel_set_variable ( oglobals - > originate_status [ i ] . peer_channel , " group_confirm_read_timeout " , NULL ) ;
2009-01-19 17:54:54 +00:00
oglobals - > idx = i ;
2009-01-16 16:22:29 +00:00
rval = 0 ;
pindex = ( uint32_t ) i ;
goto end ;
2007-03-29 22:34:40 +00:00
}
}
2016-11-03 20:39:43 +00:00
if ( oglobals - > hups > 0 & & oglobals - > hups + pickups_without_timelimit = = len ) {
/* only pickup channels with no timelimit remain */
2009-01-16 16:22:29 +00:00
rval = 0 ;
2007-03-29 22:34:40 +00:00
} else {
2009-01-16 16:22:29 +00:00
rval = 1 ;
}
2010-02-06 03:38:24 +00:00
end :
2009-01-16 16:22:29 +00:00
2016-11-03 20:39:43 +00:00
if ( rval = = 0 & & pickups_without_timelimit ) {
2012-09-10 16:14:19 +00:00
for ( i = 0 ; i < len ; i + + ) {
2020-05-07 17:04:54 +00:00
if ( oglobals - > originate_status [ i ] . peer_channel & & switch_channel_test_flag ( oglobals - > originate_status [ i ] . peer_channel , CF_PICKUP ) & &
switch_channel_up ( oglobals - > originate_status [ i ] . peer_channel ) ) {
switch_channel_hangup ( oglobals - > originate_status [ i ] . peer_channel , SWITCH_CAUSE_NO_PICKUP ) ;
2012-09-10 16:14:19 +00:00
}
}
}
2017-01-06 07:10:15 +00:00
if ( pindex > - 1 & & caller_channel & & switch_channel_ready ( caller_channel ) & & ! switch_channel_media_ready ( caller_channel ) & &
2020-05-07 17:04:54 +00:00
switch_channel_media_ready ( oglobals - > originate_status [ pindex ] . peer_channel ) ) {
inherit_codec ( caller_channel , oglobals - > originate_status [ pindex ] . peer_session ) ;
2007-03-29 22:34:40 +00:00
}
2009-10-29 05:47:17 +00:00
if ( send_ringback ) {
2010-02-06 03:38:24 +00:00
oglobals - > sending_ringback + + ;
2009-10-29 05:47:17 +00:00
}
2009-01-16 16:22:29 +00:00
return rval ;
2007-03-29 22:34:40 +00:00
}
struct ringback {
switch_buffer_t * audio_buffer ;
teletone_generation_session_t ts ;
switch_file_handle_t fhb ;
switch_file_handle_t * fh ;
2008-12-09 00:32:51 +00:00
int silence ;
2007-03-29 22:34:40 +00:00
uint8_t asis ;
2015-10-12 22:00:13 +00:00
int channels ;
void * mux_buf ;
int mux_buflen ;
2007-03-29 22:34:40 +00:00
} ;
typedef struct ringback ringback_t ;
2008-05-27 04:30:03 +00:00
static int teletone_handler ( teletone_generation_session_t * ts , teletone_tone_map_t * map )
2007-03-29 22:34:40 +00:00
{
ringback_t * tto = ts - > user_data ;
int wrote ;
2015-10-12 22:00:13 +00:00
void * buf ;
int buflen ;
2007-03-29 22:34:40 +00:00
if ( ! tto ) {
return - 1 ;
}
wrote = teletone_mux_tones ( ts , map ) ;
2017-01-06 07:10:15 +00:00
2015-10-12 22:00:13 +00:00
if ( tto - > channels ! = 1 ) {
if ( tto - > mux_buflen < wrote * 2 * tto - > channels ) {
tto - > mux_buflen = wrote * 2 * tto - > channels ;
tto - > mux_buf = realloc ( tto - > mux_buf , tto - > mux_buflen ) ;
}
memcpy ( tto - > mux_buf , ts - > buffer , wrote * 2 ) ;
switch_mux_channels ( ( int16_t * ) tto - > mux_buf , wrote , 1 , tto - > channels ) ;
buf = tto - > mux_buf ;
buflen = wrote * 2 * tto - > channels ;
} else {
buf = ts - > buffer ;
buflen = wrote * 2 ;
}
switch_buffer_write ( tto - > audio_buffer , buf , buflen ) ;
2007-03-29 22:34:40 +00:00
return 0 ;
}
2008-01-05 01:03:08 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_ivr_wait_for_answer ( switch_core_session_t * session , switch_core_session_t * peer_session )
{
2008-07-18 19:29:29 +00:00
switch_channel_t * caller_channel = NULL ;
2008-01-28 07:26:10 +00:00
switch_channel_t * peer_channel = switch_core_session_get_channel ( peer_session ) ;
2008-05-27 04:30:03 +00:00
const char * ringback_data = NULL ;
2008-01-05 01:03:08 +00:00
switch_frame_t write_frame = { 0 } ;
switch_codec_t write_codec = { 0 } ;
2008-01-28 07:26:10 +00:00
switch_codec_t * read_codec = switch_core_session_get_read_codec ( session ) ;
2008-01-05 01:03:08 +00:00
uint8_t pass = 0 ;
ringback_t ringback = { 0 } ;
switch_frame_t * read_frame = NULL ;
switch_status_t status = SWITCH_STATUS_SUCCESS ;
2017-08-24 03:01:22 +00:00
int timelimit = SWITCH_DEFAULT_TIMEOUT ;
2008-07-21 14:55:49 +00:00
const char * var ;
2008-01-05 01:03:08 +00:00
switch_time_t start = 0 ;
2009-08-26 19:49:35 +00:00
const char * cancel_key = NULL ;
2009-10-07 04:30:19 +00:00
switch_channel_state_t wait_state = 0 ;
2008-05-27 04:30:03 +00:00
2008-07-21 14:55:49 +00:00
switch_assert ( peer_channel ) ;
2010-02-06 03:38:24 +00:00
2009-10-07 04:30:19 +00:00
if ( switch_channel_get_state ( peer_channel ) = = CS_RESET ) {
switch_channel_set_state ( peer_channel , CS_SOFT_EXECUTE ) ;
}
2008-07-18 19:29:29 +00:00
if ( session ) {
caller_channel = switch_core_session_get_channel ( session ) ;
}
2008-05-19 19:24:20 +00:00
if ( ( switch_channel_test_flag ( peer_channel , CF_ANSWERED ) | | switch_channel_test_flag ( peer_channel , CF_EARLY_MEDIA ) ) ) {
2009-01-03 03:10:11 +00:00
goto end ;
2008-05-19 19:24:20 +00:00
}
2008-02-18 21:34:06 +00:00
switch_zmalloc ( write_frame . data , SWITCH_RECOMMENDED_BUFFER_SIZE ) ;
2008-02-18 21:32:35 +00:00
write_frame . buflen = SWITCH_RECOMMENDED_BUFFER_SIZE ;
2008-01-05 01:03:08 +00:00
2009-05-21 17:55:56 +00:00
if ( caller_channel & & ( var = switch_channel_get_variable ( caller_channel , SWITCH_CALL_TIMEOUT_VARIABLE ) ) ) {
2008-01-05 01:03:08 +00:00
timelimit = atoi ( var ) ;
if ( timelimit < 0 ) {
2017-08-24 03:01:22 +00:00
timelimit = SWITCH_DEFAULT_TIMEOUT ;
2008-01-05 01:03:08 +00:00
}
}
timelimit * = 1000000 ;
2009-01-25 21:23:07 +00:00
start = switch_micro_time_now ( ) ;
2008-01-05 01:03:08 +00:00
2008-07-18 19:29:29 +00:00
if ( caller_channel ) {
2009-08-26 19:49:35 +00:00
cancel_key = switch_channel_get_variable ( caller_channel , " origination_cancel_key " ) ;
2008-07-18 19:29:29 +00:00
if ( switch_channel_test_flag ( caller_channel , CF_ANSWERED ) ) {
ringback_data = switch_channel_get_variable ( caller_channel , " transfer_ringback " ) ;
}
2010-02-06 03:38:24 +00:00
2008-07-18 19:29:29 +00:00
if ( ! ringback_data ) {
ringback_data = switch_channel_get_variable ( caller_channel , " ringback " ) ;
}
if ( switch_channel_test_flag ( caller_channel , CF_PROXY_MODE ) | | switch_channel_test_flag ( caller_channel , CF_PROXY_MEDIA ) ) {
ringback_data = NULL ;
2009-10-23 16:03:42 +00:00
} else if ( zstr ( ringback_data ) ) {
2008-12-09 00:32:51 +00:00
if ( ( var = switch_channel_get_variable ( caller_channel , SWITCH_SEND_SILENCE_WHEN_IDLE_VARIABLE ) ) ) {
int sval = atoi ( var ) ;
if ( sval ) {
2008-12-09 18:52:16 +00:00
ringback_data = switch_core_session_sprintf ( session , " silence:%d " , sval ) ;
2008-12-09 00:32:51 +00:00
}
}
2008-07-18 19:29:29 +00:00
}
2008-01-05 01:03:08 +00:00
}
2008-05-27 04:30:03 +00:00
2008-07-18 19:29:29 +00:00
if ( read_codec & & ringback_data ) {
2009-09-25 18:26:47 +00:00
if ( switch_is_file_path ( ringback_data ) ) {
if ( ! ( strrchr ( ringback_data , ' . ' ) | | strstr ( ringback_data , SWITCH_URL_SEPARATOR ) ) ) {
ringback . asis + + ;
}
}
2010-02-06 03:38:24 +00:00
2009-09-25 18:26:47 +00:00
if ( ! ringback . asis ) {
2009-09-30 17:53:09 +00:00
if ( ( pass = ( uint8_t ) switch_test_flag ( read_codec , SWITCH_CODEC_FLAG_PASSTHROUGH ) ) ) {
2009-09-25 18:26:47 +00:00
goto no_ringback ;
}
2008-01-05 01:03:08 +00:00
if ( switch_core_codec_init ( & write_codec ,
" L16 " ,
NULL ,
2015-03-19 19:26:47 +00:00
NULL ,
2008-01-05 01:03:08 +00:00
read_codec - > implementation - > actual_samples_per_second ,
2008-10-20 17:48:42 +00:00
read_codec - > implementation - > microseconds_per_packet / 1000 ,
2015-10-12 22:00:13 +00:00
read_codec - > implementation - > number_of_channels , SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE , NULL ,
2009-09-25 18:26:47 +00:00
switch_core_session_get_pool ( session ) ) ! = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Codec Error! \n " ) ;
if ( caller_channel ) {
2013-09-23 23:31:16 +00:00
switch_channel_hangup ( caller_channel , SWITCH_CAUSE_BEARERCAPABILITY_NOTIMPL ) ;
2009-09-25 18:26:47 +00:00
}
read_codec = NULL ;
goto done ;
} else {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG ,
2008-01-05 01:03:08 +00:00
" Raw Codec Activation Success L16@%uhz 1 channel %dms \n " ,
2008-10-20 17:48:42 +00:00
read_codec - > implementation - > actual_samples_per_second , read_codec - > implementation - > microseconds_per_packet / 1000 ) ;
2010-02-06 03:38:24 +00:00
2008-01-05 01:03:08 +00:00
write_frame . codec = & write_codec ;
2008-10-20 17:48:42 +00:00
write_frame . datalen = read_codec - > implementation - > decoded_bytes_per_packet ;
2008-01-05 01:03:08 +00:00
write_frame . samples = write_frame . datalen / 2 ;
memset ( write_frame . data , 255 , write_frame . datalen ) ;
2009-09-25 18:26:47 +00:00
switch_core_session_set_read_codec ( session , & write_codec ) ;
}
}
2010-02-06 03:38:24 +00:00
2009-10-22 22:11:28 +00:00
if ( switch_channel_test_flag ( caller_channel , CF_DISABLE_RINGBACK ) ) {
ringback_data = NULL ;
}
2009-09-25 18:26:47 +00:00
if ( ringback_data ) {
char * tmp_data = NULL ;
2008-01-05 01:03:08 +00:00
2009-09-25 18:26:47 +00:00
if ( switch_is_file_path ( ringback_data ) ) {
char * ext ;
2008-05-27 04:30:03 +00:00
2009-09-25 18:26:47 +00:00
if ( ringback . asis ) {
write_frame . codec = read_codec ;
ext = read_codec - > implementation - > iananame ;
tmp_data = switch_mprintf ( " %s.%s " , ringback_data , ext ) ;
ringback_data = tmp_data ;
}
2008-01-05 01:03:08 +00:00
2009-09-25 18:26:47 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Play Ringback File [%s] \n " , ringback_data ) ;
2008-01-05 01:03:08 +00:00
2009-09-25 18:26:47 +00:00
ringback . fhb . channels = read_codec - > implementation - > number_of_channels ;
ringback . fhb . samplerate = read_codec - > implementation - > actual_samples_per_second ;
if ( switch_core_file_open ( & ringback . fhb ,
ringback_data ,
read_codec - > implementation - > number_of_channels ,
read_codec - > implementation - > actual_samples_per_second ,
SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT , NULL ) ! = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Error Playing File \n " ) ;
2008-01-05 01:03:08 +00:00
switch_safe_free ( tmp_data ) ;
2009-09-25 18:26:47 +00:00
goto done ;
2008-01-05 01:03:08 +00:00
}
2009-09-25 18:26:47 +00:00
ringback . fh = & ringback . fhb ;
2008-01-05 01:03:08 +00:00
} else {
2009-09-25 18:26:47 +00:00
if ( ! strncasecmp ( ringback_data , " silence " , 7 ) ) {
const char * p = ringback_data + 7 ;
if ( * p = = ' : ' ) {
p + + ;
if ( p ) {
ringback . silence = atoi ( p ) ;
}
}
2011-05-26 03:16:24 +00:00
SWITCH_IVR_VERIFY_SILENCE_DIVISOR ( ringback . silence ) ;
2009-09-25 18:26:47 +00:00
} else {
switch_buffer_create_dynamic ( & ringback . audio_buffer , 512 , 1024 , 0 ) ;
switch_buffer_set_loops ( ringback . audio_buffer , - 1 ) ;
2010-02-06 03:38:24 +00:00
2009-09-25 18:26:47 +00:00
teletone_init_session ( & ringback . ts , 0 , teletone_handler , & ringback ) ;
ringback . ts . rate = read_codec - > implementation - > actual_samples_per_second ;
2015-10-12 22:00:13 +00:00
ringback . channels = read_codec - > implementation - > number_of_channels ;
2009-09-25 18:26:47 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Play Ringback Tone [%s] \n " , ringback_data ) ;
if ( teletone_run ( & ringback . ts , ringback_data ) ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Error Playing Tone \n " ) ;
teletone_destroy_session ( & ringback . ts ) ;
switch_buffer_destroy ( & ringback . audio_buffer ) ;
ringback_data = NULL ;
}
2008-07-18 19:29:29 +00:00
}
2008-01-05 01:03:08 +00:00
}
2009-09-25 18:26:47 +00:00
switch_safe_free ( tmp_data ) ;
2008-01-05 01:03:08 +00:00
}
}
2010-02-06 03:38:24 +00:00
no_ringback :
2009-09-25 18:26:47 +00:00
2009-10-07 04:30:19 +00:00
if ( caller_channel ) {
wait_state = switch_channel_get_state ( caller_channel ) ;
}
while ( switch_channel_ready ( peer_channel ) & & ! switch_channel_media_ready ( peer_channel ) ) {
2009-01-25 21:23:07 +00:00
int diff = ( int ) ( switch_micro_time_now ( ) - start ) ;
2008-05-27 04:30:03 +00:00
2012-04-18 19:49:00 +00:00
switch_ivr_parse_all_messages ( session ) ;
2009-08-26 19:49:35 +00:00
if ( caller_channel & & cancel_key ) {
if ( switch_channel_has_dtmf ( caller_channel ) ) {
switch_dtmf_t dtmf = { 0 , 0 } ;
if ( switch_channel_dequeue_dtmf ( caller_channel , & dtmf ) = = SWITCH_STATUS_SUCCESS ) {
if ( dtmf . digit = = * cancel_key ) {
status = SWITCH_STATUS_FALSE ;
goto done ;
}
}
}
}
2009-10-07 04:30:19 +00:00
if ( caller_channel & & switch_channel_get_state ( caller_channel ) ! = wait_state ) {
goto done ;
}
2008-01-05 01:03:08 +00:00
if ( diff > timelimit ) {
status = SWITCH_STATUS_TIMEOUT ;
goto done ;
}
2008-09-04 18:29:43 +00:00
if ( switch_channel_media_ready ( caller_channel ) ) {
status = switch_core_session_read_frame ( session , & read_frame , SWITCH_IO_FLAG_NONE , 0 ) ;
if ( ! SWITCH_READ_ACCEPTABLE ( status ) ) {
break ;
}
} else {
read_frame = NULL ;
}
2010-02-06 03:38:24 +00:00
2008-01-05 01:03:08 +00:00
if ( read_frame & & ! pass ) {
2009-01-19 19:32:44 +00:00
2021-04-01 20:53:57 +00:00
if ( ! write_frame . codec ) {
status = SWITCH_STATUS_FALSE ;
break ;
}
2008-01-05 01:03:08 +00:00
if ( ringback . fh ) {
switch_size_t mlen , olen ;
unsigned int pos = 0 ;
2010-02-06 03:38:24 +00:00
2008-01-05 01:03:08 +00:00
if ( ringback . asis ) {
2008-10-20 17:48:42 +00:00
mlen = write_frame . codec - > implementation - > encoded_bytes_per_packet ;
2008-01-05 01:03:08 +00:00
} else {
2008-10-20 17:48:42 +00:00
mlen = write_frame . codec - > implementation - > samples_per_packet ;
2008-01-05 01:03:08 +00:00
}
olen = mlen ;
2009-01-09 20:34:01 +00:00
//if (ringback.fh->resampler && ringback.fh->resampler->rfactor > 1) {
//olen = (switch_size_t) (olen * ringback.fh->resampler->rfactor);
//}
2008-02-18 21:32:35 +00:00
switch_core_file_read ( ringback . fh , write_frame . data , & olen ) ;
2008-01-05 01:03:08 +00:00
if ( olen = = 0 ) {
olen = mlen ;
ringback . fh - > speed = 0 ;
switch_core_file_seek ( ringback . fh , & pos , 0 , SEEK_SET ) ;
2008-02-18 21:32:35 +00:00
switch_core_file_read ( ringback . fh , write_frame . data , & olen ) ;
2008-01-05 01:03:08 +00:00
if ( olen = = 0 ) {
2017-01-06 07:10:15 +00:00
switch_log_printf ( SWITCH_CHANNEL_CHANNEL_LOG ( caller_channel ) , SWITCH_LOG_ERROR ,
2012-04-10 15:15:15 +00:00
" Failure to read or re-read after seeking to beginning on file [%s] \n " , ringback . fh - > file_path ) ;
2008-01-05 01:03:08 +00:00
break ;
}
}
2014-06-13 00:28:14 +00:00
write_frame . datalen = ( uint32_t ) ( ringback . asis ? olen : olen * 2 * ringback . fh - > channels ) ;
2008-01-05 01:03:08 +00:00
} else if ( ringback . audio_buffer ) {
if ( ( write_frame . datalen = ( uint32_t ) switch_buffer_read_loop ( ringback . audio_buffer ,
write_frame . data ,
2008-10-20 17:48:42 +00:00
write_frame . codec - > implementation - > decoded_bytes_per_packet ) ) < = 0 ) {
2008-01-05 01:03:08 +00:00
break ;
}
2008-12-09 00:32:51 +00:00
} else if ( ringback . silence ) {
write_frame . datalen = write_frame . codec - > implementation - > decoded_bytes_per_packet ;
2017-01-06 07:10:15 +00:00
switch_generate_sln_silence ( ( int16_t * ) write_frame . data , write_frame . datalen / 2 ,
2014-06-12 23:49:37 +00:00
write_frame . codec - > implementation - > number_of_channels , ringback . silence ) ;
2008-01-05 01:03:08 +00:00
}
2008-12-09 00:32:51 +00:00
if ( ( ringback . fh | | ringback . silence | | ringback . audio_buffer ) & & write_frame . codec & & write_frame . datalen ) {
2008-09-04 18:29:43 +00:00
if ( switch_core_session_write_frame ( session , & write_frame , SWITCH_IO_FLAG_NONE , 0 ) ! = SWITCH_STATUS_SUCCESS ) {
break ;
}
2008-01-05 01:03:08 +00:00
}
} else {
2008-11-14 23:31:21 +00:00
switch_cond_next ( ) ;
2008-01-05 01:03:08 +00:00
}
}
2010-02-06 03:38:24 +00:00
done :
2008-05-27 04:30:03 +00:00
2008-01-05 01:03:08 +00:00
if ( ringback . fh ) {
switch_core_file_close ( ringback . fh ) ;
ringback . fh = NULL ;
} else if ( ringback . audio_buffer ) {
teletone_destroy_session ( & ringback . ts ) ;
2015-10-12 22:00:13 +00:00
switch_safe_free ( ringback . mux_buf ) ;
2008-01-05 01:03:08 +00:00
switch_buffer_destroy ( & ringback . audio_buffer ) ;
}
2017-01-06 07:10:15 +00:00
2011-08-19 21:25:26 +00:00
switch_ivr_parse_all_events ( session ) ;
2017-01-06 07:10:15 +00:00
2009-01-09 20:34:01 +00:00
switch_core_session_reset ( session , SWITCH_TRUE , SWITCH_TRUE ) ;
2008-07-15 17:39:16 +00:00
2009-04-09 17:17:12 +00:00
if ( switch_core_codec_ready ( & write_codec ) ) {
2008-01-05 01:03:08 +00:00
switch_core_codec_destroy ( & write_codec ) ;
}
2008-02-18 21:32:35 +00:00
switch_safe_free ( write_frame . data ) ;
2008-01-05 01:03:08 +00:00
2010-02-06 03:38:24 +00:00
end :
2009-01-03 03:10:11 +00:00
2009-10-07 04:30:19 +00:00
if ( ! switch_channel_media_ready ( peer_channel ) ) {
2011-11-18 19:17:56 +00:00
if ( switch_channel_up_nosig ( peer_channel ) ) {
2009-10-07 04:30:19 +00:00
switch_channel_hangup ( peer_channel , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
}
status = SWITCH_STATUS_FALSE ;
}
2010-02-06 03:38:24 +00:00
2011-09-15 16:42:55 +00:00
if ( switch_channel_test_flag ( caller_channel , CF_XFER_ZOMBIE ) ) {
switch_channel_state_t peer_state = switch_channel_get_state ( peer_channel ) ;
while ( switch_channel_ready ( peer_channel ) & & switch_channel_get_state ( peer_channel ) = = peer_state ) {
2012-04-18 19:49:00 +00:00
switch_ivr_parse_all_messages ( session ) ;
2011-09-15 16:42:55 +00:00
switch_channel_ready ( caller_channel ) ;
switch_yield ( 20000 ) ;
}
}
2011-11-18 19:17:56 +00:00
if ( caller_channel & & ! switch_channel_up_nosig ( caller_channel ) ) {
2009-10-07 04:30:19 +00:00
status = SWITCH_STATUS_FALSE ;
}
return status ;
2008-01-05 01:03:08 +00:00
}
2010-11-05 23:20:09 +00:00
SWITCH_DECLARE ( void ) switch_process_import ( switch_core_session_t * session , switch_channel_t * peer_channel , const char * varname , const char * prefix )
2008-06-04 23:33:29 +00:00
{
const char * import , * val ;
switch_channel_t * caller_channel ;
switch_assert ( session & & peer_channel ) ;
caller_channel = switch_core_session_get_channel ( session ) ;
2010-02-06 03:38:24 +00:00
2009-03-23 16:06:32 +00:00
if ( ( import = switch_channel_get_variable ( caller_channel , varname ) ) ) {
2008-06-04 23:33:29 +00:00
char * mydata = switch_core_session_strdup ( session , import ) ;
int i , argc ;
char * argv [ 64 ] = { 0 } ;
if ( ( argc = switch_separate_string ( mydata , ' , ' , argv , ( sizeof ( argv ) / sizeof ( argv [ 0 ] ) ) ) ) ) {
2010-02-06 03:38:24 +00:00
for ( i = 0 ; i < argc ; i + + ) {
2008-06-04 23:33:29 +00:00
if ( ( val = switch_channel_get_variable ( peer_channel , argv [ i ] ) ) ) {
2010-11-05 23:20:09 +00:00
if ( prefix ) {
char * var = switch_mprintf ( " %s%s " , prefix , argv [ i ] ) ;
switch_channel_set_variable ( caller_channel , var , val ) ;
free ( var ) ;
} else {
switch_channel_set_variable ( caller_channel , argv [ i ] , val ) ;
}
2008-06-04 23:33:29 +00:00
}
}
}
}
}
2009-01-19 17:54:54 +00:00
2010-04-23 21:09:27 +00:00
static switch_status_t setup_ringback ( originate_global_t * oglobals , originate_status_t * originate_status , int len ,
2010-02-06 03:38:24 +00:00
const char * ringback_data , ringback_t * ringback , switch_frame_t * write_frame , switch_codec_t * write_codec )
2009-10-29 05:47:17 +00:00
{
switch_status_t status = SWITCH_STATUS_SUCCESS ;
switch_channel_t * caller_channel = switch_core_session_get_channel ( oglobals - > session ) ;
switch_codec_t * read_codec = NULL ;
char * tmp_data = NULL ;
if ( ! switch_channel_test_flag ( caller_channel , CF_ANSWERED )
& & ! switch_channel_test_flag ( caller_channel , CF_EARLY_MEDIA ) ) {
2017-01-06 07:10:15 +00:00
if ( oglobals - > bridge_early_media > - 1 & & len = = 1 & & originate_status [ 0 ] . peer_session & &
switch_channel_media_ready ( originate_status [ 0 ] . peer_channel ) ) {
2010-04-23 21:09:27 +00:00
inherit_codec ( caller_channel , originate_status [ 0 ] . peer_session ) ;
}
2009-10-29 05:47:17 +00:00
if ( ( status = switch_channel_pre_answer ( caller_channel ) ) ! = SWITCH_STATUS_SUCCESS ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_CHANNEL_LOG ( caller_channel ) , SWITCH_LOG_DEBUG , " %s Media Establishment Failed. \n " ,
2009-10-29 05:47:17 +00:00
switch_channel_get_name ( caller_channel ) ) ;
switch_goto_status ( SWITCH_STATUS_BREAK , end ) ;
}
}
if ( oglobals - > session & & ( read_codec = switch_core_session_get_read_codec ( oglobals - > session ) ) ) {
2010-01-14 21:02:11 +00:00
if ( ringback_data & & switch_is_file_path ( ringback_data ) ) {
2009-10-29 05:47:17 +00:00
if ( ! ( strrchr ( ringback_data , ' . ' ) | | strstr ( ringback_data , SWITCH_URL_SEPARATOR ) ) ) {
ringback - > asis + + ;
}
2010-04-23 21:09:27 +00:00
} else if ( oglobals - > bridge_early_media > - 1 & & zstr ( ringback_data ) & & len = = 1 & & originate_status [ 0 ] . peer_session ) {
switch_codec_implementation_t read_impl = { 0 } , write_impl = { 0 } ;
2017-01-06 07:10:15 +00:00
2010-04-23 21:09:27 +00:00
if ( switch_channel_ready ( originate_status [ 0 ] . peer_channel )
& & switch_core_session_get_read_impl ( originate_status [ 0 ] . peer_session , & read_impl ) = = SWITCH_STATUS_SUCCESS
& & switch_core_session_get_write_impl ( oglobals - > session , & write_impl ) = = SWITCH_STATUS_SUCCESS ) {
2017-01-06 07:10:15 +00:00
if ( read_impl . impl_id = = write_impl . impl_id & &
2010-04-23 21:09:27 +00:00
read_impl . microseconds_per_packet = = write_impl . microseconds_per_packet & &
read_impl . actual_samples_per_second = = write_impl . actual_samples_per_second ) {
ringback - > asis + + ;
write_frame - > codec = switch_core_session_get_write_codec ( originate_status [ 0 ] . peer_session ) ;
write_frame - > datalen = write_frame - > codec - > implementation - > decoded_bytes_per_packet ;
switch_log_printf ( SWITCH_CHANNEL_CHANNEL_LOG ( caller_channel ) , SWITCH_LOG_DEBUG , " bridge_early_media: passthrough enabled \n " ) ;
} else {
switch_log_printf ( SWITCH_CHANNEL_CHANNEL_LOG ( caller_channel ) , SWITCH_LOG_DEBUG , " bridge_early_media: codecs don't match (%s@%uh@%di / %s@%uh@%di) \n " ,
2017-01-06 07:10:15 +00:00
read_impl . iananame , read_impl . actual_samples_per_second , read_impl . microseconds_per_packet / 1000 ,
2010-04-23 21:09:27 +00:00
write_impl . iananame , write_impl . actual_samples_per_second , write_impl . microseconds_per_packet / 1000 ) ;
}
}
2009-10-29 05:47:17 +00:00
}
2010-02-06 03:38:24 +00:00
2009-10-29 05:47:17 +00:00
if ( ! ringback - > asis ) {
2012-09-21 15:15:45 +00:00
switch_codec_implementation_t peer_read_impl = { 0 } ;
2009-10-29 05:47:17 +00:00
if ( switch_test_flag ( read_codec , SWITCH_CODEC_FLAG_PASSTHROUGH ) ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_CHANNEL_LOG ( caller_channel ) , SWITCH_LOG_WARNING , " %s Ringback not supported in passthrough codec mode. \n " ,
2009-10-29 05:47:17 +00:00
switch_channel_get_name ( caller_channel ) ) ;
switch_goto_status ( SWITCH_STATUS_GENERR , end ) ;
}
2012-09-26 16:25:42 +00:00
if ( oglobals - > bridge_early_media > - 1 & & zstr ( ringback_data ) & & len = = 1 & & originate_status [ 0 ] . peer_session ) {
switch_core_session_get_read_impl ( originate_status [ 0 ] . peer_session , & peer_read_impl ) ;
} else {
switch_core_session_get_read_impl ( oglobals - > session , & peer_read_impl ) ;
}
2015-10-12 22:00:13 +00:00
2009-10-29 05:47:17 +00:00
if ( switch_core_codec_init ( write_codec ,
" L16 " ,
NULL ,
2015-03-19 19:26:47 +00:00
NULL ,
2012-09-21 15:15:45 +00:00
peer_read_impl . actual_samples_per_second ,
peer_read_impl . microseconds_per_packet / 1000 ,
2015-10-12 22:00:13 +00:00
peer_read_impl . number_of_channels , SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE , NULL ,
2009-10-29 05:47:17 +00:00
switch_core_session_get_pool ( oglobals - > session ) ) = = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( oglobals - > session ) , SWITCH_LOG_DEBUG ,
2015-10-12 22:00:13 +00:00
" Raw Codec Activation Success L16@%uhz %d channel %dms \n " ,
peer_read_impl . actual_samples_per_second , peer_read_impl . number_of_channels , peer_read_impl . microseconds_per_packet / 1000 ) ;
2009-10-29 05:47:17 +00:00
write_frame - > codec = write_codec ;
2015-10-12 22:00:13 +00:00
write_frame - > datalen = peer_read_impl . decoded_bytes_per_packet ;
2009-10-29 05:47:17 +00:00
write_frame - > samples = write_frame - > datalen / 2 ;
memset ( write_frame - > data , 255 , write_frame - > datalen ) ;
switch_core_session_set_read_codec ( oglobals - > session , write_codec ) ;
} else {
switch_log_printf ( SWITCH_CHANNEL_CHANNEL_LOG ( caller_channel ) , SWITCH_LOG_ERROR , " Codec Error! \n " ) ;
2013-09-23 23:31:16 +00:00
switch_channel_hangup ( caller_channel , SWITCH_CAUSE_BEARERCAPABILITY_NOTIMPL ) ;
2009-10-29 05:47:17 +00:00
read_codec = NULL ;
switch_goto_status ( SWITCH_STATUS_BREAK , end ) ;
}
2010-02-06 03:38:24 +00:00
}
2009-10-29 05:47:17 +00:00
oglobals - > gen_ringback = 1 ;
2010-02-06 03:38:24 +00:00
2010-01-14 21:02:11 +00:00
if ( zstr ( ringback_data ) ) {
switch_goto_status ( SWITCH_STATUS_SUCCESS , end ) ;
}
2009-10-29 05:47:17 +00:00
if ( switch_is_file_path ( ringback_data ) ) {
char * ext ;
if ( ringback - > asis ) {
write_frame - > codec = read_codec ;
ext = read_codec - > implementation - > iananame ;
tmp_data = switch_mprintf ( " %s.%s " , ringback_data , ext ) ;
ringback_data = tmp_data ;
}
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( oglobals - > session ) , SWITCH_LOG_DEBUG , " Play Ringback File [%s] \n " , ringback_data ) ;
2010-02-06 03:38:24 +00:00
2013-02-28 20:52:26 +00:00
if ( switch_test_flag ( ( & ringback - > fhb ) , SWITCH_FILE_OPEN ) ) {
switch_core_file_close ( & ringback - > fhb ) ;
}
2009-10-29 05:47:17 +00:00
ringback - > fhb . channels = read_codec - > implementation - > number_of_channels ;
ringback - > fhb . samplerate = read_codec - > implementation - > actual_samples_per_second ;
if ( switch_core_file_open ( & ringback - > fhb ,
ringback_data ,
read_codec - > implementation - > number_of_channels ,
read_codec - > implementation - > actual_samples_per_second ,
SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT , NULL ) ! = SWITCH_STATUS_SUCCESS ) {
2012-04-10 21:17:16 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( oglobals - > session ) , SWITCH_LOG_ERROR , " Error Playing File \n " ) ;
2009-10-29 05:47:17 +00:00
switch_safe_free ( tmp_data ) ;
switch_goto_status ( SWITCH_STATUS_GENERR , end ) ;
//switch_goto_status(SWITCH_STATUS_FALSE, end);
}
ringback - > fh = & ringback - > fhb ;
} else if ( ! strncasecmp ( ringback_data , " silence " , 7 ) ) {
const char * c = ringback_data + 7 ;
if ( * c = = ' : ' ) {
c + + ;
if ( c ) {
ringback - > silence = atoi ( c ) ;
}
}
2011-05-26 06:23:34 +00:00
SWITCH_IVR_VERIFY_SILENCE_DIVISOR ( ringback - > silence ) ;
2009-10-29 05:47:17 +00:00
} else {
2019-04-18 15:04:30 +00:00
if ( ringback - > audio_buffer ) {
switch_buffer_destroy ( & ringback - > audio_buffer ) ;
teletone_destroy_session ( & ringback - > ts ) ;
}
2009-10-29 05:47:17 +00:00
switch_buffer_create_dynamic ( & ringback - > audio_buffer , 512 , 1024 , 0 ) ;
switch_buffer_set_loops ( ringback - > audio_buffer , - 1 ) ;
teletone_init_session ( & ringback - > ts , 0 , teletone_handler , ringback ) ;
ringback - > ts . rate = read_codec - > implementation - > actual_samples_per_second ;
2015-10-12 22:00:13 +00:00
ringback - > channels = read_codec - > implementation - > number_of_channels ;
2012-04-10 21:17:16 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( oglobals - > session ) , SWITCH_LOG_DEBUG , " Play Ringback Tone [%s] \n " , ringback_data ) ;
2009-10-29 05:47:17 +00:00
/* ringback->ts.debug = 1;
ringback - > ts . debug_stream = switch_core_get_console ( ) ; */
2010-02-06 03:38:24 +00:00
2009-10-29 05:47:17 +00:00
if ( teletone_run ( & ringback - > ts , ringback_data ) ) {
2012-04-10 21:17:16 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( oglobals - > session ) , SWITCH_LOG_ERROR , " Error Playing Tone \n " ) ;
2009-10-29 05:47:17 +00:00
teletone_destroy_session ( & ringback - > ts ) ;
switch_buffer_destroy ( & ringback - > audio_buffer ) ;
switch_goto_status ( SWITCH_STATUS_GENERR , end ) ;
}
}
}
2010-02-06 03:38:24 +00:00
end :
2009-10-29 05:47:17 +00:00
switch_safe_free ( tmp_data ) ;
return status ;
2010-02-06 03:38:24 +00:00
2009-10-29 05:47:17 +00:00
}
2009-11-18 20:25:49 +00:00
FS-11346: [core] add api to pass pre-parsed values instead of dial strings to switch_ivr_originate
SWITCH_DECLARE(switch_status_t) switch_dial_handle_create(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_destroy(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_add_leg_list(switch_dial_handle_t *handle, switch_dial_leg_list_t **leg_listP);
SWITCH_DECLARE(void) switch_dial_leg_list_add_leg(switch_dial_leg_list_t *parent, const char *dial_string, switch_dial_leg_t **legP);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var(switch_dial_handle_t *handle, const char *var, const char *val);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var_printf(switch_dial_handle_t *handle, const char *var, const char *fmt, ...);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var(switch_dial_leg_t *leg, const char *var, const char *val);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var_printf(switch_dial_leg_t *leg, const char *var, const char *fmt, ...);
SWITCH_DECLARE(int) switch_dial_handle_get_peers(switch_dial_handle_t *handle, int idx, char **array, int max);
SWITCH_DECLARE(int) switch_dial_handle_get_vars(switch_dial_handle_t *handle, int idx, switch_event_t **array, int max);
SWITCH_DECLARE(switch_event_t *) switch_dial_handle_get_global_vars(switch_dial_handle_t *handle);
SWITCH_DECLARE(switch_event_t *) switch_dial_leg_get_vars(switch_dial_leg_t *leg);
SWITCH_DECLARE(int) switch_dial_handle_get_total(switch_dial_handle_t *handle);
SWITCH_DECLARE(void) switch_ivr_orig_and_bridge(switch_core_session_t *session, const char *data, switch_dial_handle_t *dh);
add switch_dial_handle_t *dh to end of args for switch_ivr_originate
2018-08-16 00:40:30 +00:00
2009-11-12 22:21:30 +00:00
typedef struct {
switch_core_session_t * session ;
switch_core_session_t * bleg ;
switch_call_cause_t cause ;
2009-11-20 02:17:08 +00:00
switch_call_cause_t cancel_cause ;
2009-11-12 22:21:30 +00:00
const char * bridgeto ;
uint32_t timelimit_sec ;
const switch_state_handler_table_t * table ;
const char * cid_name_override ;
const char * cid_num_override ;
2010-02-06 03:38:24 +00:00
switch_caller_profile_t * caller_profile_override ;
2009-11-12 22:21:30 +00:00
switch_event_t * ovars ;
switch_originate_flag_t flags ;
switch_status_t status ;
int done ;
switch_thread_t * thread ;
2009-11-20 02:17:08 +00:00
switch_mutex_t * mutex ;
2022-11-30 20:18:55 +00:00
switch_mutex_t * fence_mutex ;
2021-03-18 23:28:40 +00:00
switch_dial_handle_t * dh ;
2009-11-12 22:21:30 +00:00
} enterprise_originate_handle_t ;
2009-11-13 16:37:42 +00:00
struct ent_originate_ringback {
switch_core_session_t * session ;
int running ;
const char * ringback_data ;
switch_thread_t * thread ;
} ;
2009-11-12 22:21:30 +00:00
static void * SWITCH_THREAD_FUNC enterprise_originate_thread ( switch_thread_t * thread , void * obj )
{
enterprise_originate_handle_t * handle = ( enterprise_originate_handle_t * ) obj ;
2022-11-30 20:18:55 +00:00
switch_status_t status ;
2010-02-06 03:38:24 +00:00
2022-11-30 20:18:55 +00:00
switch_mutex_lock ( handle - > fence_mutex ) ;
2009-11-12 22:21:30 +00:00
handle - > done = 0 ;
2022-11-30 20:18:55 +00:00
switch_mutex_unlock ( handle - > fence_mutex ) ;
status = switch_ivr_originate ( NULL , & handle - > bleg , & handle - > cause ,
2009-11-12 22:21:30 +00:00
handle - > bridgeto , handle - > timelimit_sec ,
handle - > table ,
handle - > cid_name_override ,
FS-11346: [core] add api to pass pre-parsed values instead of dial strings to switch_ivr_originate
SWITCH_DECLARE(switch_status_t) switch_dial_handle_create(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_destroy(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_add_leg_list(switch_dial_handle_t *handle, switch_dial_leg_list_t **leg_listP);
SWITCH_DECLARE(void) switch_dial_leg_list_add_leg(switch_dial_leg_list_t *parent, const char *dial_string, switch_dial_leg_t **legP);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var(switch_dial_handle_t *handle, const char *var, const char *val);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var_printf(switch_dial_handle_t *handle, const char *var, const char *fmt, ...);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var(switch_dial_leg_t *leg, const char *var, const char *val);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var_printf(switch_dial_leg_t *leg, const char *var, const char *fmt, ...);
SWITCH_DECLARE(int) switch_dial_handle_get_peers(switch_dial_handle_t *handle, int idx, char **array, int max);
SWITCH_DECLARE(int) switch_dial_handle_get_vars(switch_dial_handle_t *handle, int idx, switch_event_t **array, int max);
SWITCH_DECLARE(switch_event_t *) switch_dial_handle_get_global_vars(switch_dial_handle_t *handle);
SWITCH_DECLARE(switch_event_t *) switch_dial_leg_get_vars(switch_dial_leg_t *leg);
SWITCH_DECLARE(int) switch_dial_handle_get_total(switch_dial_handle_t *handle);
SWITCH_DECLARE(void) switch_ivr_orig_and_bridge(switch_core_session_t *session, const char *data, switch_dial_handle_t *dh);
add switch_dial_handle_t *dh to end of args for switch_ivr_originate
2018-08-16 00:40:30 +00:00
handle - > cid_num_override ,
handle - > caller_profile_override ,
handle - > ovars ,
handle - > flags ,
& handle - > cancel_cause ,
2021-03-18 23:28:40 +00:00
handle - > dh ) ;
2009-11-12 22:21:30 +00:00
2022-11-30 20:18:55 +00:00
switch_mutex_lock ( handle - > fence_mutex ) ;
handle - > status = status ;
2009-11-12 22:21:30 +00:00
handle - > done = 1 ;
2022-11-30 20:18:55 +00:00
switch_mutex_unlock ( handle - > fence_mutex ) ;
2009-11-20 02:17:08 +00:00
switch_mutex_lock ( handle - > mutex ) ;
switch_mutex_unlock ( handle - > mutex ) ;
2010-02-06 03:38:24 +00:00
2009-11-20 02:17:08 +00:00
if ( handle - > done ! = 2 ) {
2013-05-21 15:21:45 +00:00
if ( handle - > status = = SWITCH_STATUS_SUCCESS & & handle - > bleg ) {
2012-09-04 16:24:13 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( handle - > bleg ) ;
switch_channel_set_variable ( channel , " group_dial_status " , " loser " ) ;
switch_channel_hangup ( channel , SWITCH_CAUSE_LOSE_RACE ) ;
2009-11-20 02:17:08 +00:00
switch_core_session_rwunlock ( handle - > bleg ) ;
}
}
2009-11-12 22:21:30 +00:00
return NULL ;
}
2009-11-13 16:37:42 +00:00
static void * SWITCH_THREAD_FUNC enterprise_originate_ringback_thread ( switch_thread_t * thread , void * obj )
{
struct ent_originate_ringback * rb_data = ( struct ent_originate_ringback * ) obj ;
switch_core_session_t * session = rb_data - > session ;
2017-03-09 19:22:11 +00:00
switch_channel_t * channel ;
2009-11-13 16:37:42 +00:00
switch_status_t status = SWITCH_STATUS_FALSE ;
2017-03-09 19:22:11 +00:00
if ( switch_core_session_read_lock ( session ) ! = SWITCH_STATUS_SUCCESS ) {
return NULL ;
}
channel = switch_core_session_get_channel ( session ) ;
2010-02-06 03:38:24 +00:00
while ( rb_data - > running & & switch_channel_ready ( channel ) ) {
2012-04-18 19:49:00 +00:00
switch_ivr_parse_all_messages ( session ) ;
2009-11-13 16:37:42 +00:00
if ( status ! = SWITCH_STATUS_BREAK ) {
if ( zstr ( rb_data - > ringback_data ) | | ! strcasecmp ( rb_data - > ringback_data , " silence " ) ) {
status = switch_ivr_collect_digits_callback ( session , NULL , 0 , 0 ) ;
} else if ( switch_is_file_path ( rb_data - > ringback_data ) ) {
status = switch_ivr_play_file ( session , NULL , rb_data - > ringback_data , NULL ) ;
} else {
status = switch_ivr_gentones ( session , rb_data - > ringback_data , 0 , NULL ) ;
}
}
if ( status = = SWITCH_STATUS_BREAK ) {
switch_channel_set_flag ( channel , CF_NOT_READY ) ;
}
}
switch_core_session_rwunlock ( session ) ;
rb_data - > running = 0 ;
return NULL ;
}
2009-11-12 22:21:30 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_ivr_enterprise_originate ( switch_core_session_t * session ,
2009-11-13 16:37:42 +00:00
switch_core_session_t * * bleg ,
switch_call_cause_t * cause ,
const char * bridgeto ,
uint32_t timelimit_sec ,
const switch_state_handler_table_t * table ,
const char * cid_name_override ,
const char * cid_num_override ,
2010-02-06 03:38:24 +00:00
switch_caller_profile_t * caller_profile_override ,
2017-01-06 07:10:15 +00:00
switch_event_t * ovars , switch_originate_flag_t flags ,
2021-03-18 23:28:40 +00:00
switch_call_cause_t * cancel_cause ,
switch_dial_handle_list_t * hl )
2009-11-12 22:21:30 +00:00
{
2009-11-14 18:36:41 +00:00
int x_argc = 0 ;
2009-11-12 22:21:30 +00:00
char * x_argv [ MAX_PEERS ] = { 0 } ;
2010-02-06 03:38:24 +00:00
enterprise_originate_handle_t * hp = NULL , handles [ MAX_PEERS ] = { { 0 } } ;
2009-11-12 22:21:30 +00:00
int i ;
switch_caller_profile_t * cp = NULL ;
switch_channel_t * channel = NULL ;
2021-03-18 23:28:40 +00:00
char * data = NULL ;
2009-11-12 22:21:30 +00:00
switch_status_t status = SWITCH_STATUS_FALSE ;
switch_threadattr_t * thd_attr = NULL ;
2009-11-20 02:17:08 +00:00
int running = 0 , over = 0 ;
2009-11-12 22:21:30 +00:00
switch_status_t tstatus = SWITCH_STATUS_FALSE ;
switch_memory_pool_t * pool ;
switch_event_header_t * hi = NULL ;
2009-11-13 16:37:42 +00:00
struct ent_originate_ringback rb_data = { 0 } ;
const char * ringback_data = NULL ;
2009-11-14 18:36:41 +00:00
switch_event_t * var_event = NULL ;
2012-09-11 15:38:29 +00:00
int getcause = 1 ;
* cause = SWITCH_CAUSE_SUCCESS ;
2009-11-12 22:21:30 +00:00
switch_core_new_memory_pool ( & pool ) ;
2021-03-18 23:28:40 +00:00
if ( zstr ( bridgeto ) & & ( ! hl | | hl - > handle_idx = = 0 ) ) {
2009-11-12 22:21:30 +00:00
* cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ;
2012-09-11 15:38:29 +00:00
getcause = 0 ;
2009-11-12 22:21:30 +00:00
switch_goto_status ( SWITCH_STATUS_FALSE , end ) ;
}
2021-03-18 23:28:40 +00:00
if ( ! hl ) {
data = switch_core_strdup ( pool , bridgeto ) ;
}
2009-11-12 22:21:30 +00:00
2010-11-12 01:21:35 +00:00
if ( session ) {
switch_caller_profile_t * cpp = NULL ;
channel = switch_core_session_get_channel ( session ) ;
if ( ( cpp = switch_channel_get_caller_profile ( channel ) ) ) {
cp = switch_caller_profile_dup ( pool , cpp ) ;
}
}
2009-11-14 18:36:41 +00:00
if ( ovars ) {
var_event = ovars ;
} else {
if ( switch_event_create_plain ( & var_event , SWITCH_EVENT_CHANNEL_DATA ) ! = SWITCH_STATUS_SUCCESS ) {
abort ( ) ;
}
}
2011-03-10 00:01:50 +00:00
if ( session ) {
switch_event_add_header_string ( var_event , SWITCH_STACK_BOTTOM , " ent_originate_aleg_uuid " , switch_core_session_get_uuid ( session ) ) ;
}
2017-01-06 07:10:15 +00:00
2010-10-01 22:26:03 +00:00
if ( channel ) {
2013-10-17 16:18:01 +00:00
const char * tmp_var = NULL ;
2011-06-29 20:57:59 +00:00
2010-10-01 22:26:03 +00:00
switch_channel_process_export ( channel , NULL , var_event , SWITCH_EXPORT_VARS_VARIABLE ) ;
2011-06-29 20:57:59 +00:00
2013-10-17 16:18:01 +00:00
if ( ( tmp_var = switch_channel_get_variable ( channel , " effective_ani " ) ) ) {
switch_event_add_header_string ( var_event , SWITCH_STACK_BOTTOM , " origination_ani " , tmp_var ) ;
2011-06-29 20:57:59 +00:00
}
2013-10-17 16:18:01 +00:00
if ( ( tmp_var = switch_channel_get_variable ( channel , " effective_aniii " ) ) ) {
switch_event_add_header_string ( var_event , SWITCH_STACK_BOTTOM , " origination_aniii " , tmp_var ) ;
}
if ( ( tmp_var = switch_channel_get_variable ( channel , " effective_caller_id_name " ) ) ) {
switch_event_add_header_string ( var_event , SWITCH_STACK_BOTTOM , " origination_caller_id_name " , tmp_var ) ;
}
if ( ( tmp_var = switch_channel_get_variable ( channel , " effective_caller_id_number " ) ) ) {
switch_event_add_header_string ( var_event , SWITCH_STACK_BOTTOM , " origination_caller_id_number " , tmp_var ) ;
2011-06-29 20:57:59 +00:00
}
2010-10-01 22:26:03 +00:00
}
2011-04-14 22:44:22 +00:00
/* strip leading spaces */
while ( data & & * data & & * data = = ' ' ) {
data + + ;
}
/* extract channel variables, allowing multiple sets of braces */
2012-04-10 21:17:16 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Parsing ultra-global variables \n " ) ;
2019-10-31 20:05:40 +00:00
while ( data & & * data = = ' < ' ) {
2011-04-14 22:44:22 +00:00
char * parsed = NULL ;
if ( switch_event_create_brackets ( data , ' < ' , ' > ' , ' , ' , & var_event , & parsed , SWITCH_FALSE ) ! = SWITCH_STATUS_SUCCESS | | ! parsed ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Parse Error! \n " ) ;
switch_goto_status ( SWITCH_STATUS_GENERR , done ) ;
2009-11-14 18:36:41 +00:00
}
2011-04-14 22:44:22 +00:00
data = parsed ;
}
2021-03-18 23:28:40 +00:00
if ( hl & & hl - > global_vars ) {
switch_event_merge ( var_event , hl - > global_vars ) ;
}
2011-04-14 22:44:22 +00:00
/* strip leading spaces (again) */
while ( data & & * data & & * data = = ' ' ) {
data + + ;
2009-11-14 18:36:41 +00:00
}
2010-03-05 13:38:40 +00:00
if ( ovars & & ovars ! = var_event ) {
2009-11-14 18:36:41 +00:00
for ( hi = ovars - > headers ; hi ; hi = hi - > next ) {
switch_event_add_header_string ( var_event , SWITCH_STACK_BOTTOM , hi - > name , hi - > value ) ;
}
}
2009-11-20 02:17:08 +00:00
switch_event_add_header_string ( var_event , SWITCH_STACK_BOTTOM , " ignore_early_media " , " true " ) ;
2009-11-14 18:36:41 +00:00
2021-03-18 23:28:40 +00:00
if ( data ) {
if ( ! ( x_argc = switch_separate_string_string ( data , SWITCH_ENT_ORIGINATE_DELIM , x_argv , MAX_PEERS ) ) ) {
* cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ;
getcause = 0 ;
switch_goto_status ( SWITCH_STATUS_FALSE , end ) ;
}
2021-04-19 18:16:28 +00:00
} else if ( hl ) {
2021-03-18 23:28:40 +00:00
x_argc = hl - > handle_idx ;
2009-11-12 22:21:30 +00:00
}
switch_threadattr_create ( & thd_attr , pool ) ;
switch_threadattr_stacksize_set ( thd_attr , SWITCH_THREAD_STACKSIZE ) ;
2010-02-06 03:38:24 +00:00
for ( i = 0 ; i < x_argc ; i + + ) {
2009-11-12 22:21:30 +00:00
handles [ i ] . session = session ;
handles [ i ] . bleg = NULL ;
handles [ i ] . cause = 0 ;
2009-11-20 02:17:08 +00:00
handles [ i ] . cancel_cause = 0 ;
2009-11-12 22:21:30 +00:00
handles [ i ] . bridgeto = x_argv [ i ] ;
handles [ i ] . timelimit_sec = timelimit_sec ;
handles [ i ] . table = table ;
handles [ i ] . cid_name_override = cid_name_override ;
handles [ i ] . cid_num_override = cid_num_override ;
handles [ i ] . caller_profile_override = cp ;
2010-02-06 03:38:24 +00:00
switch_event_dup ( & handles [ i ] . ovars , var_event ) ;
2009-11-12 22:21:30 +00:00
handles [ i ] . flags = flags ;
2021-03-18 23:28:40 +00:00
if ( hl ) {
switch_dial_handle_dup ( & handles [ i ] . dh , hl - > handles [ i ] ) ;
}
2009-11-20 02:17:08 +00:00
switch_mutex_init ( & handles [ i ] . mutex , SWITCH_MUTEX_NESTED , pool ) ;
2022-11-30 20:18:55 +00:00
switch_mutex_init ( & handles [ i ] . fence_mutex , SWITCH_MUTEX_NESTED , pool ) ;
2009-11-20 02:17:08 +00:00
switch_mutex_lock ( handles [ i ] . mutex ) ;
2009-11-12 22:21:30 +00:00
switch_thread_create ( & handles [ i ] . thread , thd_attr , enterprise_originate_thread , & handles [ i ] , pool ) ;
}
2010-02-06 03:38:24 +00:00
2009-11-13 16:37:42 +00:00
if ( channel & & ! switch_channel_test_flag ( channel , CF_PROXY_MODE ) & & ! switch_channel_test_flag ( channel , CF_PROXY_MEDIA ) ) {
if ( switch_channel_test_flag ( channel , CF_ANSWERED ) ) {
ringback_data = switch_channel_get_variable ( channel , " transfer_ringback " ) ;
}
2010-02-06 03:38:24 +00:00
2009-11-13 16:37:42 +00:00
if ( ! ringback_data ) {
ringback_data = switch_channel_get_variable ( channel , " ringback " ) ;
}
if ( ringback_data | | switch_channel_media_ready ( channel ) ) {
rb_data . ringback_data = ringback_data ;
rb_data . session = session ;
rb_data . running = 1 ;
if ( ! switch_channel_media_ready ( channel ) ) {
if ( switch_channel_pre_answer ( channel ) ! = SWITCH_STATUS_SUCCESS ) {
goto done ;
}
}
switch_thread_create ( & rb_data . thread , thd_attr , enterprise_originate_ringback_thread , & rb_data , pool ) ;
}
}
2009-11-12 22:21:30 +00:00
2010-02-06 03:38:24 +00:00
for ( ; ; ) {
2009-11-12 22:21:30 +00:00
running = 0 ;
2009-11-20 02:17:08 +00:00
over = 0 ;
2010-02-06 03:38:24 +00:00
2009-11-13 16:37:42 +00:00
if ( channel & & ! switch_channel_ready ( channel ) ) {
break ;
}
2009-11-12 22:21:30 +00:00
2011-09-01 17:37:58 +00:00
if ( cancel_cause & & * cancel_cause > 0 ) {
break ;
}
2010-02-06 03:38:24 +00:00
for ( i = 0 ; i < x_argc ; i + + ) {
2009-11-20 02:17:08 +00:00
2022-11-30 20:18:55 +00:00
switch_mutex_lock ( handles [ i ] . fence_mutex ) ;
2009-11-12 22:21:30 +00:00
if ( handles [ i ] . done = = 0 ) {
running + + ;
} else if ( handles [ i ] . done = = 1 ) {
if ( handles [ i ] . status = = SWITCH_STATUS_SUCCESS ) {
2009-11-20 02:17:08 +00:00
handles [ i ] . done = 2 ;
2009-11-12 22:21:30 +00:00
hp = & handles [ i ] ;
2022-11-30 20:18:55 +00:00
switch_mutex_unlock ( handles [ i ] . fence_mutex ) ;
2009-11-12 22:21:30 +00:00
goto done ;
} else {
2009-11-20 02:17:08 +00:00
handles [ i ] . done = - 1 ;
2009-11-12 22:21:30 +00:00
}
2009-11-20 02:17:08 +00:00
} else {
over + + ;
2009-11-12 22:21:30 +00:00
}
2009-11-20 02:17:08 +00:00
2022-11-30 20:18:55 +00:00
switch_mutex_unlock ( handles [ i ] . fence_mutex ) ;
2009-11-20 02:17:08 +00:00
switch_yield ( 10000 ) ;
2009-11-12 22:21:30 +00:00
}
2009-11-20 02:17:08 +00:00
if ( ! running | | over = = x_argc ) {
2009-11-12 22:21:30 +00:00
break ;
}
}
2010-02-06 03:38:24 +00:00
done :
2009-11-12 22:21:30 +00:00
2009-11-20 02:17:08 +00:00
if ( hp ) {
* cause = hp - > cause ;
2012-09-11 15:38:29 +00:00
getcause = 0 ;
2009-11-20 02:17:08 +00:00
status = hp - > status ;
* bleg = hp - > bleg ;
2017-08-17 20:47:17 +00:00
if ( * bleg ) {
switch_channel_t * bchan = switch_core_session_get_channel ( * bleg ) ;
2017-09-01 16:19:34 +00:00
switch_caller_profile_t * cloned_profile ;
if ( session ) {
cloned_profile = switch_caller_profile_clone ( * bleg , cp ) ;
2017-08-17 20:47:17 +00:00
switch_channel_set_originator_caller_profile ( bchan , cloned_profile ) ;
2017-09-01 16:19:34 +00:00
cloned_profile = switch_caller_profile_clone ( session , switch_channel_get_caller_profile ( bchan ) ) ;
switch_channel_set_originatee_caller_profile ( channel , cloned_profile ) ;
2017-08-17 20:47:17 +00:00
}
}
2009-11-20 02:17:08 +00:00
switch_mutex_unlock ( hp - > mutex ) ;
switch_thread_join ( & tstatus , hp - > thread ) ;
switch_event_destroy ( & hp - > ovars ) ;
2021-03-18 23:28:40 +00:00
switch_dial_handle_destroy ( & hp - > dh ) ;
2009-11-13 16:37:42 +00:00
}
2010-02-06 03:38:24 +00:00
for ( i = 0 ; i < x_argc ; i + + ) {
2009-11-20 02:17:08 +00:00
if ( hp = = & handles [ i ] ) {
2009-11-12 22:21:30 +00:00
continue ;
}
2011-09-01 17:37:58 +00:00
if ( cancel_cause & & * cancel_cause > 0 ) {
handles [ i ] . cancel_cause = * cancel_cause ;
} else {
2022-10-26 17:53:01 +00:00
/* Was this call taken by another destination? */
if ( hp ! = NULL & & hp - > cause = = SWITCH_CAUSE_SUCCESS ) {
/* Yes, the race was lost */
handles [ i ] . cancel_cause = SWITCH_CAUSE_LOSE_RACE ;
} else {
/* No, something else happened, probably Originator Cancel */
handles [ i ] . cancel_cause = SWITCH_CAUSE_ORIGINATOR_CANCEL ;
}
2011-09-01 17:37:58 +00:00
}
2009-11-20 02:17:08 +00:00
}
2009-11-12 22:21:30 +00:00
2010-02-06 03:38:24 +00:00
for ( i = 0 ; i < x_argc ; i + + ) {
2013-05-22 16:01:39 +00:00
2009-11-20 02:17:08 +00:00
if ( hp = = & handles [ i ] ) {
continue ;
}
2015-01-23 19:14:58 +00:00
2017-01-10 22:06:33 +00:00
if ( getcause & & channel & & handles [ i ] . cause & & handles [ i ] . cause ! = SWITCH_CAUSE_SUCCESS ) {
2015-01-23 19:14:58 +00:00
switch_channel_handle_cause ( channel , handles [ i ] . cause ) ;
}
2009-11-20 02:17:08 +00:00
switch_mutex_unlock ( handles [ i ] . mutex ) ;
2012-09-11 15:38:29 +00:00
2012-09-12 15:22:03 +00:00
if ( getcause & & * cause ! = handles [ i ] . cause & & handles [ i ] . cause ! = SWITCH_CAUSE_LOSE_RACE & & handles [ i ] . cause ! = SWITCH_CAUSE_NO_PICKUP ) {
2012-09-11 15:38:29 +00:00
* cause = handles [ i ] . cause ;
getcause + + ;
}
2009-11-12 22:21:30 +00:00
switch_thread_join ( & tstatus , handles [ i ] . thread ) ;
switch_event_destroy ( & handles [ i ] . ovars ) ;
2021-03-18 23:28:40 +00:00
switch_dial_handle_destroy ( & handles [ i ] . dh ) ;
2009-11-12 22:21:30 +00:00
}
2010-02-06 03:38:24 +00:00
2009-11-20 02:17:08 +00:00
if ( channel & & rb_data . thread ) {
switch_channel_set_flag ( channel , CF_NOT_READY ) ;
switch_thread_join ( & tstatus , rb_data . thread ) ;
switch_channel_clear_flag ( channel , CF_NOT_READY ) ;
2009-11-12 22:21:30 +00:00
}
2009-11-20 02:17:08 +00:00
2010-02-06 03:38:24 +00:00
end :
2009-11-12 22:21:30 +00:00
2012-09-11 15:38:29 +00:00
if ( getcause = = 1 & & * cause = = SWITCH_CAUSE_SUCCESS ) {
* cause = SWITCH_CAUSE_NO_ANSWER ;
}
2013-07-19 18:25:54 +00:00
if ( channel ) {
if ( * cause = = SWITCH_CAUSE_SUCCESS ) {
switch_channel_set_variable ( channel , " originate_disposition " , " success " ) ;
} else {
switch_channel_set_variable ( channel , " originate_disposition " , " failure " ) ;
switch_channel_set_variable ( channel , " hangup_cause " , switch_channel_cause2str ( * cause ) ) ;
}
}
2009-11-14 18:36:41 +00:00
if ( var_event & & var_event ! = ovars ) {
switch_event_destroy ( & var_event ) ;
}
2009-11-12 22:21:30 +00:00
switch_core_destroy_memory_pool ( & pool ) ;
return status ;
}
2009-10-29 05:47:17 +00:00
2010-01-15 21:10:31 +00:00
struct early_state {
originate_global_t * oglobals ;
switch_mutex_t * mutex ;
switch_buffer_t * buffer ;
int ready ;
2010-04-23 21:09:27 +00:00
ringback_t * ringback ;
2014-12-08 18:53:28 +00:00
int ttl ;
2010-01-15 21:10:31 +00:00
} ;
typedef struct early_state early_state_t ;
static void * SWITCH_THREAD_FUNC early_thread_run ( switch_thread_t * thread , void * obj )
{
early_state_t * state = ( early_state_t * ) obj ;
2021-07-09 11:52:00 +00:00
originate_status_t originate_status [ MAX_PEERS ] = { { 0 } } ;
uint8_t array_pos = 0 ;
2010-02-06 03:38:24 +00:00
int16_t mux_data [ SWITCH_RECOMMENDED_BUFFER_SIZE / 2 ] = { 0 } ;
2010-01-15 21:10:31 +00:00
int32_t sample ;
2013-03-01 00:44:38 +00:00
switch_codec_t read_codecs [ MAX_PEERS ] = { { 0 } } ;
2013-02-28 20:52:26 +00:00
int i , x , ready = 0 , answered = 0 , ring_ready = 0 ;
2010-01-15 21:10:31 +00:00
int16_t * data ;
uint32_t datalen = 0 ;
switch_status_t status ;
2010-05-04 13:33:39 +00:00
switch_frame_t * read_frame = NULL ;
2013-03-01 00:44:38 +00:00
switch_codec_implementation_t read_impl = { 0 } ;
2010-02-06 03:38:24 +00:00
2014-12-08 18:53:28 +00:00
for ( i = 0 ; i < MAX_PEERS & & i < state - > ttl ; i + + ) {
2021-07-09 11:52:00 +00:00
switch_core_session_t * session = state - > oglobals - > originate_status [ i ] . peer_session ;
2016-07-28 21:27:17 +00:00
switch_channel_t * channel = NULL ;
2017-01-06 07:10:15 +00:00
2016-07-28 21:27:17 +00:00
if ( session ) channel = switch_core_session_get_channel ( session ) ;
if ( ! session | | ! channel | | ! switch_channel_up ( channel ) ) {
continue ;
}
if ( switch_core_session_read_lock ( session ) = = SWITCH_STATUS_SUCCESS ) {
2021-07-09 11:52:00 +00:00
originate_status [ array_pos ] . peer_session = session ;
originate_status [ array_pos ] . peer_channel = channel ;
originate_status [ array_pos ] . array_pos = ( uint8_t ) i ;
array_pos + + ;
2014-12-08 18:53:28 +00:00
}
}
2020-05-07 17:04:54 +00:00
2013-03-01 00:44:38 +00:00
if ( state - > oglobals - > session ) {
switch_core_session_get_read_impl ( state - > oglobals - > session , & read_impl ) ;
}
2010-02-06 03:38:24 +00:00
2010-01-15 21:10:31 +00:00
while ( state - > ready ) {
datalen = 0 ;
memset ( mux_data , 0 , sizeof ( mux_data ) ) ;
2010-01-16 00:41:10 +00:00
ready = 0 ;
answered = 0 ;
2021-07-09 11:52:00 +00:00
for ( array_pos = 0 ; array_pos < MAX_PEERS & & originate_status [ array_pos ] . peer_session ; array_pos + + ) {
switch_core_session_t * session = originate_status [ array_pos ] . peer_session ;
switch_channel_t * channel = originate_status [ array_pos ] . peer_channel ;
i = originate_status [ array_pos ] . array_pos ;
2014-12-08 18:53:28 +00:00
2015-01-21 22:16:56 +00:00
if ( ! session | | ! channel | | ! switch_channel_up ( channel ) ) {
2014-12-08 18:53:28 +00:00
continue ;
}
2017-01-06 07:10:15 +00:00
2010-01-15 21:10:31 +00:00
if ( switch_channel_media_ready ( channel ) ) {
2010-01-16 00:41:10 +00:00
ready + + ;
2013-02-28 20:52:26 +00:00
if ( switch_channel_test_flag ( channel , CF_RING_READY ) ) {
ring_ready = 1 ;
state - > oglobals - > bridge_early_media = - 1 ;
state - > oglobals - > ignore_early_media = 1 ;
}
2017-01-06 07:10:15 +00:00
2010-01-16 00:41:10 +00:00
if ( switch_channel_test_flag ( channel , CF_ANSWERED ) ) {
answered + + ;
}
2010-02-06 03:38:24 +00:00
2010-04-23 21:09:27 +00:00
if ( ! state - > ringback - > asis ) {
if ( ! switch_core_codec_ready ( ( & read_codecs [ i ] ) ) ) {
if ( switch_core_codec_init ( & read_codecs [ i ] ,
" L16 " ,
NULL ,
2015-03-19 19:26:47 +00:00
NULL ,
2013-03-01 00:44:38 +00:00
read_impl . actual_samples_per_second ,
read_impl . microseconds_per_packet / 1000 ,
2015-10-12 22:00:13 +00:00
read_impl . number_of_channels , SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE , NULL ,
2010-04-23 21:09:27 +00:00
switch_core_session_get_pool ( session ) ) ! = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Codec Error! \n " ) ;
}
2013-03-01 00:44:38 +00:00
switch_core_session_set_read_codec ( session , NULL ) ;
switch_core_session_set_read_codec ( session , & read_codecs [ i ] ) ;
2010-01-15 21:10:31 +00:00
}
2010-04-23 21:09:27 +00:00
status = switch_core_session_read_frame ( session , & read_frame , SWITCH_IO_FLAG_NONE , 0 ) ;
2014-12-26 05:27:43 +00:00
if ( SWITCH_READ_ACCEPTABLE ( status ) & & ! switch_test_flag ( read_frame , SFF_CNG ) ) {
2010-04-23 21:09:27 +00:00
data = ( int16_t * ) read_frame - > data ;
if ( datalen < read_frame - > datalen ) {
datalen = read_frame - > datalen ;
}
for ( x = 0 ; x < ( int ) read_frame - > datalen / 2 ; x + + ) {
sample = data [ x ] + mux_data [ x ] ;
switch_normalize_to_16bit ( sample ) ;
mux_data [ x ] = ( int16_t ) sample ;
}
2010-01-15 21:10:31 +00:00
}
2010-04-23 21:09:27 +00:00
} else {
status = switch_core_session_read_frame ( session , & read_frame , SWITCH_IO_FLAG_NONE , 0 ) ;
2014-12-26 05:27:43 +00:00
if ( SWITCH_READ_ACCEPTABLE ( status ) & & ! switch_test_flag ( read_frame , SFF_CNG ) ) {
2010-04-23 21:09:27 +00:00
datalen = read_frame - > datalen ;
2010-01-15 21:10:31 +00:00
}
2010-04-23 21:09:27 +00:00
break ;
2010-01-15 21:10:31 +00:00
}
}
}
2017-01-06 07:10:15 +00:00
2014-12-08 18:53:28 +00:00
if ( ! ready | | answered | | ring_ready ) {
break ;
}
2017-01-06 07:10:15 +00:00
2014-12-08 18:53:28 +00:00
if ( ! datalen ) {
continue ;
}
if ( state - > ringback - > asis ) {
2010-04-26 15:55:46 +00:00
uint16_t flen = ( uint16_t ) datalen ;
2010-04-23 21:09:27 +00:00
switch_mutex_lock ( state - > mutex ) ;
switch_buffer_write ( state - > buffer , & flen , sizeof ( uint16_t ) ) ;
switch_buffer_write ( state - > buffer , read_frame - > data , datalen ) ;
switch_mutex_unlock ( state - > mutex ) ;
2014-12-08 18:53:28 +00:00
} else {
2010-01-15 21:10:31 +00:00
switch_mutex_lock ( state - > mutex ) ;
switch_buffer_write ( state - > buffer , mux_data , datalen ) ;
switch_mutex_unlock ( state - > mutex ) ;
}
}
2021-07-09 11:52:00 +00:00
for ( array_pos = 0 ; array_pos < MAX_PEERS & & originate_status [ array_pos ] . peer_session ; array_pos + + ) {
switch_core_session_t * session = originate_status [ array_pos ] . peer_session ;
switch_channel_t * channel = originate_status [ array_pos ] . peer_channel ;
i = originate_status [ array_pos ] . array_pos ;
2017-01-06 07:10:15 +00:00
2015-01-21 22:16:56 +00:00
if ( ! session ) continue ;
2014-12-08 18:53:28 +00:00
2010-01-15 21:10:31 +00:00
if ( switch_core_codec_ready ( ( & read_codecs [ i ] ) ) ) {
2015-12-04 16:33:34 +00:00
switch_core_session_set_read_codec ( session , NULL ) ;
2010-01-15 21:10:31 +00:00
switch_core_codec_destroy ( & read_codecs [ i ] ) ;
}
2014-12-08 18:53:28 +00:00
if ( switch_channel_up_nosig ( channel ) ) {
switch_core_session_reset ( session , SWITCH_FALSE , SWITCH_TRUE ) ;
}
2010-01-15 21:10:31 +00:00
switch_core_session_rwunlock ( session ) ;
}
2013-02-28 20:52:26 +00:00
if ( ! ring_ready ) {
state - > oglobals - > early_ok = 1 ;
}
2010-01-16 00:41:10 +00:00
2010-01-15 21:10:31 +00:00
return NULL ;
}
2009-10-07 04:30:19 +00:00
# define peer_eligible(_peer) (_peer && !(switch_channel_test_flag(_peer, CF_TRANSFER) || \
switch_channel_test_flag ( _peer , CF_REDIRECT ) | | \
switch_channel_test_flag ( _peer , CF_BRIDGED ) | | \
switch_channel_get_state ( _peer ) = = CS_RESET | | \
! switch_channel_test_flag ( _peer , CF_ORIGINATING ) ) )
2011-01-17 16:41:01 +00:00
static void wait_for_cause ( switch_channel_t * channel )
{
int sanity = 5 ;
while ( - - sanity > 0 & & peer_eligible ( channel ) & & switch_channel_get_cause ( channel ) = = SWITCH_CAUSE_NONE ) {
switch_yield ( 10000 ) ;
}
}
2009-11-12 22:21:30 +00:00
2007-03-29 22:34:40 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_ivr_originate ( switch_core_session_t * session ,
switch_core_session_t * * bleg ,
switch_call_cause_t * cause ,
2007-11-01 11:28:26 +00:00
const char * bridgeto ,
2007-03-29 22:34:40 +00:00
uint32_t timelimit_sec ,
const switch_state_handler_table_t * table ,
2008-05-27 04:30:03 +00:00
const char * cid_name_override ,
const char * cid_num_override ,
2010-02-06 03:38:24 +00:00
switch_caller_profile_t * caller_profile_override ,
FS-11346: [core] add api to pass pre-parsed values instead of dial strings to switch_ivr_originate
SWITCH_DECLARE(switch_status_t) switch_dial_handle_create(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_destroy(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_add_leg_list(switch_dial_handle_t *handle, switch_dial_leg_list_t **leg_listP);
SWITCH_DECLARE(void) switch_dial_leg_list_add_leg(switch_dial_leg_list_t *parent, const char *dial_string, switch_dial_leg_t **legP);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var(switch_dial_handle_t *handle, const char *var, const char *val);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var_printf(switch_dial_handle_t *handle, const char *var, const char *fmt, ...);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var(switch_dial_leg_t *leg, const char *var, const char *val);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var_printf(switch_dial_leg_t *leg, const char *var, const char *fmt, ...);
SWITCH_DECLARE(int) switch_dial_handle_get_peers(switch_dial_handle_t *handle, int idx, char **array, int max);
SWITCH_DECLARE(int) switch_dial_handle_get_vars(switch_dial_handle_t *handle, int idx, switch_event_t **array, int max);
SWITCH_DECLARE(switch_event_t *) switch_dial_handle_get_global_vars(switch_dial_handle_t *handle);
SWITCH_DECLARE(switch_event_t *) switch_dial_leg_get_vars(switch_dial_leg_t *leg);
SWITCH_DECLARE(int) switch_dial_handle_get_total(switch_dial_handle_t *handle);
SWITCH_DECLARE(void) switch_ivr_orig_and_bridge(switch_core_session_t *session, const char *data, switch_dial_handle_t *dh);
add switch_dial_handle_t *dh to end of args for switch_ivr_originate
2018-08-16 00:40:30 +00:00
switch_event_t * ovars , switch_originate_flag_t flags ,
switch_call_cause_t * cancel_cause ,
switch_dial_handle_t * dh )
2007-03-29 22:34:40 +00:00
{
2020-05-07 17:04:54 +00:00
//originate_status_t originate_status[MAX_PEERS] = { {0} };
2020-02-12 21:49:43 +00:00
switch_originate_flag_t dftflags = SOF_NONE , myflags ;
2007-03-29 22:34:40 +00:00
char * pipe_names [ MAX_PEERS ] = { 0 } ;
char * data = NULL ;
switch_status_t status = SWITCH_STATUS_SUCCESS ;
switch_channel_t * caller_channel = NULL ;
char * peer_names [ MAX_PEERS ] = { 0 } ;
FS-11346: [core] add api to pass pre-parsed values instead of dial strings to switch_ivr_originate
SWITCH_DECLARE(switch_status_t) switch_dial_handle_create(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_destroy(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_add_leg_list(switch_dial_handle_t *handle, switch_dial_leg_list_t **leg_listP);
SWITCH_DECLARE(void) switch_dial_leg_list_add_leg(switch_dial_leg_list_t *parent, const char *dial_string, switch_dial_leg_t **legP);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var(switch_dial_handle_t *handle, const char *var, const char *val);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var_printf(switch_dial_handle_t *handle, const char *var, const char *fmt, ...);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var(switch_dial_leg_t *leg, const char *var, const char *val);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var_printf(switch_dial_leg_t *leg, const char *var, const char *fmt, ...);
SWITCH_DECLARE(int) switch_dial_handle_get_peers(switch_dial_handle_t *handle, int idx, char **array, int max);
SWITCH_DECLARE(int) switch_dial_handle_get_vars(switch_dial_handle_t *handle, int idx, switch_event_t **array, int max);
SWITCH_DECLARE(switch_event_t *) switch_dial_handle_get_global_vars(switch_dial_handle_t *handle);
SWITCH_DECLARE(switch_event_t *) switch_dial_leg_get_vars(switch_dial_leg_t *leg);
SWITCH_DECLARE(int) switch_dial_handle_get_total(switch_dial_handle_t *handle);
SWITCH_DECLARE(void) switch_ivr_orig_and_bridge(switch_core_session_t *session, const char *data, switch_dial_handle_t *dh);
add switch_dial_handle_t *dh to end of args for switch_ivr_originate
2018-08-16 00:40:30 +00:00
switch_event_t * peer_vars [ MAX_PEERS ] = { 0 } ;
2015-06-19 06:34:31 +00:00
switch_core_session_t * new_session = NULL , * peer_session = NULL ;
2009-01-19 17:54:54 +00:00
switch_caller_profile_t * new_profile = NULL , * caller_caller_profile ;
2007-03-29 22:34:40 +00:00
char * chan_type = NULL , * chan_data ;
2009-01-19 17:54:54 +00:00
switch_channel_t * peer_channel = NULL ;
2007-03-29 22:34:40 +00:00
ringback_t ringback = { 0 } ;
2016-09-01 14:59:06 +00:00
time_t start , global_start ;
switch_time_t last_retry_start = 0 ;
2007-03-29 22:34:40 +00:00
switch_frame_t * read_frame = NULL ;
2017-07-11 22:25:48 +00:00
int r = 0 , i , and_argc = 0 , or_argc = 0 ;
2016-09-01 14:59:06 +00:00
int32_t sleep_ms = 1000 , try = 0 , retries = 1 , retry_timelimit_sec = 0 ;
int32_t min_retry_period_ms = sleep_ms ;
2007-03-29 22:34:40 +00:00
switch_codec_t write_codec = { 0 } ;
switch_frame_t write_frame = { 0 } ;
2009-01-19 17:54:54 +00:00
char * odata , * var ;
2008-07-03 22:51:09 +00:00
switch_call_cause_t reason = SWITCH_CAUSE_NONE ;
2009-10-07 04:30:19 +00:00
switch_call_cause_t force_reason = SWITCH_CAUSE_NONE ;
2007-03-29 22:34:40 +00:00
uint8_t to = 0 ;
2011-04-14 22:44:22 +00:00
char * var_val ;
2007-11-01 11:28:26 +00:00
const char * ringback_data = NULL ;
2007-03-29 22:34:40 +00:00
switch_event_t * var_event = NULL ;
2010-10-25 19:54:13 +00:00
int8_t fail_on_single_reject = 0 ;
2013-05-22 16:01:39 +00:00
int8_t hangup_on_single_reject = 0 ;
2008-10-09 00:38:59 +00:00
char * fail_on_single_reject_var = NULL ;
2007-03-29 22:34:40 +00:00
char * loop_data = NULL ;
2008-06-23 22:07:22 +00:00
uint32_t progress_timelimit_sec = 0 ;
2009-06-18 16:35:41 +00:00
const char * cid_tmp , * lc ;
2009-01-19 17:54:54 +00:00
originate_global_t oglobals = { 0 } ;
2009-04-30 13:53:29 +00:00
int cdr_total = 0 ;
2009-06-18 16:35:41 +00:00
int local_clobber = 0 ;
2009-08-26 19:49:35 +00:00
const char * cancel_key = NULL ;
2009-10-07 04:30:19 +00:00
const char * holding = NULL ;
2009-12-08 00:05:40 +00:00
const char * soft_holding = NULL ;
2010-01-15 21:10:31 +00:00
early_state_t early_state = { 0 } ;
2010-04-28 17:59:29 +00:00
int read_packet = 0 ;
2010-10-25 18:03:06 +00:00
int check_reject = 1 ;
2010-12-16 02:01:34 +00:00
switch_codec_implementation_t read_impl = { 0 } ;
2013-10-17 16:18:01 +00:00
const char * ani_override = NULL ;
const char * aniii_override = NULL ;
2014-01-22 17:40:29 +00:00
const char * ent_aleg_uuid = NULL ;
switch_core_session_t * a_session = session , * l_session = NULL ;
FS-11346: [core] add api to pass pre-parsed values instead of dial strings to switch_ivr_originate
SWITCH_DECLARE(switch_status_t) switch_dial_handle_create(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_destroy(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_add_leg_list(switch_dial_handle_t *handle, switch_dial_leg_list_t **leg_listP);
SWITCH_DECLARE(void) switch_dial_leg_list_add_leg(switch_dial_leg_list_t *parent, const char *dial_string, switch_dial_leg_t **legP);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var(switch_dial_handle_t *handle, const char *var, const char *val);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var_printf(switch_dial_handle_t *handle, const char *var, const char *fmt, ...);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var(switch_dial_leg_t *leg, const char *var, const char *val);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var_printf(switch_dial_leg_t *leg, const char *var, const char *fmt, ...);
SWITCH_DECLARE(int) switch_dial_handle_get_peers(switch_dial_handle_t *handle, int idx, char **array, int max);
SWITCH_DECLARE(int) switch_dial_handle_get_vars(switch_dial_handle_t *handle, int idx, switch_event_t **array, int max);
SWITCH_DECLARE(switch_event_t *) switch_dial_handle_get_global_vars(switch_dial_handle_t *handle);
SWITCH_DECLARE(switch_event_t *) switch_dial_leg_get_vars(switch_dial_leg_t *leg);
SWITCH_DECLARE(int) switch_dial_handle_get_total(switch_dial_handle_t *handle);
SWITCH_DECLARE(void) switch_ivr_orig_and_bridge(switch_core_session_t *session, const char *data, switch_dial_handle_t *dh);
add switch_dial_handle_t *dh to end of args for switch_ivr_originate
2018-08-16 00:40:30 +00:00
char * event_string ;
if ( ! bridgeto | | dh ) {
bridgeto = " " ;
}
2012-10-18 17:22:35 +00:00
if ( session ) {
2014-01-22 17:40:29 +00:00
caller_channel = switch_core_session_get_channel ( session ) ;
if ( switch_false ( switch_channel_get_variable ( caller_channel , " preserve_originated_vars " ) ) ) {
switch_channel_set_variable ( caller_channel , " originated_legs " , NULL ) ;
switch_channel_set_variable ( caller_channel , " originate_causes " , NULL ) ;
}
2012-10-18 17:22:35 +00:00
}
2017-01-06 07:10:15 +00:00
2009-11-18 20:25:49 +00:00
if ( strstr ( bridgeto , SWITCH_ENT_ORIGINATE_DELIM ) ) {
2009-11-12 22:21:30 +00:00
return switch_ivr_enterprise_originate ( session , bleg , cause , bridgeto , timelimit_sec , table , cid_name_override , cid_num_override ,
2021-03-18 23:28:40 +00:00
caller_profile_override , ovars , flags , cancel_cause , NULL ) ;
2009-11-12 22:21:30 +00:00
}
2012-04-11 20:30:37 +00:00
oglobals . check_vars = SWITCH_TRUE ;
2009-10-29 05:47:17 +00:00
oglobals . ringback_ok = 1 ;
2010-01-14 21:02:11 +00:00
oglobals . bridge_early_media = - 1 ;
2011-08-25 13:27:23 +00:00
oglobals . file = NULL ;
oglobals . error_file = NULL ;
2010-05-03 17:13:37 +00:00
switch_core_new_memory_pool ( & oglobals . pool ) ;
if ( caller_profile_override ) {
oglobals . caller_profile_override = switch_caller_profile_dup ( oglobals . pool , caller_profile_override ) ;
} else if ( session ) {
2014-01-22 17:40:29 +00:00
switch_caller_profile_t * cp = switch_channel_get_caller_profile ( caller_channel ) ;
2010-05-03 17:13:37 +00:00
if ( cp ) {
oglobals . caller_profile_override = switch_caller_profile_dup ( oglobals . pool , cp ) ;
}
}
2009-10-29 05:47:17 +00:00
2009-09-30 23:50:51 +00:00
if ( session ) {
2022-10-28 15:34:18 +00:00
const char * to_var , * bypass_media = NULL , * proxy_media = NULL ;
2009-10-07 04:30:19 +00:00
switch_channel_set_flag ( caller_channel , CF_ORIGINATOR ) ;
2009-09-30 23:50:51 +00:00
oglobals . session = session ;
2012-10-30 16:06:33 +00:00
switch_channel_execute_on ( caller_channel , SWITCH_CHANNEL_EXECUTE_ON_PRE_ORIGINATE_VARIABLE ) ;
switch_channel_api_on ( caller_channel , SWITCH_CHANNEL_API_ON_PRE_ORIGINATE_VARIABLE ) ;
2010-12-16 02:01:34 +00:00
switch_core_session_get_read_impl ( session , & read_impl ) ;
2009-10-08 17:43:51 +00:00
if ( ( to_var = switch_channel_get_variable ( caller_channel , SWITCH_CALL_TIMEOUT_VARIABLE ) ) ) {
timelimit_sec = atoi ( to_var ) ;
}
2010-01-18 19:36:30 +00:00
proxy_media = switch_channel_get_variable ( caller_channel , SWITCH_PROXY_MEDIA_VARIABLE ) ;
bypass_media = switch_channel_get_variable ( caller_channel , SWITCH_BYPASS_MEDIA_VARIABLE ) ;
2010-01-21 00:12:24 +00:00
if ( ! zstr ( proxy_media ) ) {
if ( switch_true ( proxy_media ) ) {
switch_channel_set_flag ( caller_channel , CF_PROXY_MEDIA ) ;
} else if ( switch_channel_test_flag ( caller_channel , CF_PROXY_MEDIA ) ) {
switch_channel_clear_flag ( caller_channel , CF_PROXY_MEDIA ) ;
}
2010-01-18 19:36:30 +00:00
}
2010-01-21 00:12:24 +00:00
2010-06-18 21:52:39 +00:00
if ( bypass_media & & switch_channel_test_flag ( caller_channel , CF_EARLY_MEDIA ) & & ! switch_channel_test_flag ( caller_channel , CF_ANSWERED ) ) {
switch_core_session_message_t msg = { 0 } ;
msg . message_id = SWITCH_MESSAGE_INDICATE_CLEAR_PROGRESS ;
msg . from = __FILE__ ;
switch_core_session_receive_message ( session , & msg ) ;
}
2010-05-04 16:24:35 +00:00
if ( ! zstr ( bypass_media ) & & ! switch_channel_test_flag ( caller_channel , CF_PROXY_MEDIA ) ) {
2010-01-21 00:12:24 +00:00
if ( switch_true ( bypass_media ) ) {
switch_channel_set_flag ( caller_channel , CF_PROXY_MODE ) ;
} else if ( switch_channel_test_flag ( caller_channel , CF_PROXY_MODE ) ) {
2010-05-04 16:24:35 +00:00
if ( ! switch_channel_test_flag ( caller_channel , CF_ANSWERED ) & & switch_channel_test_flag ( caller_channel , CF_EARLY_MEDIA ) ) {
switch_channel_set_variable ( caller_channel , SWITCH_B_SDP_VARIABLE , NULL ) ;
switch_channel_answer ( caller_channel ) ;
2017-01-06 07:10:15 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING ,
2010-05-04 16:24:35 +00:00
" Must answer channel %s due to SIP PARADOX \n " , switch_channel_get_name ( caller_channel ) ) ;
}
switch_channel_set_variable ( caller_channel , SWITCH_B_SDP_VARIABLE , NULL ) ;
2010-01-21 00:12:24 +00:00
switch_ivr_media ( switch_core_session_get_uuid ( session ) , SMF_NONE ) ;
}
2009-09-30 23:50:51 +00:00
}
2017-01-06 07:10:15 +00:00
2010-06-03 02:57:16 +00:00
if ( switch_channel_test_flag ( caller_channel , CF_PROXY_MODE ) & & switch_channel_test_flag ( caller_channel , CF_ANSWERED ) ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG ,
2010-01-18 19:36:30 +00:00
" Channel is already up, delaying proxy mode 'till both legs are answered. \n " ) ;
switch_channel_set_variable ( caller_channel , " bypass_media_after_bridge " , " true " ) ;
switch_channel_set_variable ( caller_channel , SWITCH_BYPASS_MEDIA_VARIABLE , NULL ) ;
switch_channel_clear_flag ( caller_channel , CF_PROXY_MODE ) ;
2009-09-30 23:50:51 +00:00
}
}
2009-10-08 17:43:51 +00:00
if ( timelimit_sec < = 0 ) {
2017-08-24 03:01:22 +00:00
timelimit_sec = SWITCH_DEFAULT_TIMEOUT ;
2009-10-08 17:43:51 +00:00
}
2010-02-06 03:38:24 +00:00
2009-01-19 17:54:54 +00:00
oglobals . idx = IDX_NADA ;
oglobals . early_ok = 1 ;
2009-09-30 23:50:51 +00:00
2008-08-11 16:12:55 +00:00
* bleg = NULL ;
2008-02-18 21:34:06 +00:00
switch_zmalloc ( write_frame . data , SWITCH_RECOMMENDED_BUFFER_SIZE ) ;
2008-02-18 21:32:35 +00:00
write_frame . buflen = SWITCH_RECOMMENDED_BUFFER_SIZE ;
2007-03-29 22:34:40 +00:00
odata = strdup ( bridgeto ) ;
2007-12-17 22:52:32 +00:00
if ( ! odata ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Memory Error! \n " ) ;
2007-12-17 22:52:32 +00:00
status = SWITCH_STATUS_MEMERR ;
goto done ;
}
2007-03-29 22:34:40 +00:00
data = odata ;
/* Some channel are created from an originating channel and some aren't so not all outgoing calls have a way to get params
2017-01-06 07:10:15 +00:00
so we will normalize dialstring params and channel variables ( when there is an originator ) into an event that we
2007-03-29 22:34:40 +00:00
will use as a pseudo hash to consult for params as needed .
2010-02-06 03:38:24 +00:00
*/
2008-12-05 14:59:24 +00:00
if ( ovars ) {
var_event = ovars ;
} else {
2009-06-18 19:47:29 +00:00
if ( switch_event_create_plain ( & var_event , SWITCH_EVENT_CHANNEL_DATA ) ! = SWITCH_STATUS_SUCCESS ) {
2008-12-05 14:59:24 +00:00
abort ( ) ;
}
2007-03-29 22:34:40 +00:00
}
2014-01-22 17:40:29 +00:00
ent_aleg_uuid = switch_event_get_header ( var_event , " ent_originate_aleg_uuid " ) ;
2011-08-09 07:09:19 +00:00
if ( caller_channel ) {
switch_channel_process_export ( caller_channel , NULL , var_event , SWITCH_EXPORT_VARS_VARIABLE ) ;
}
2011-04-14 22:44:22 +00:00
/* strip leading spaces */
while ( data & & * data & & * data = = ' ' ) {
data + + ;
}
2017-01-06 07:10:15 +00:00
if ( ( ovars & & switch_true ( switch_event_get_header ( ovars , " origination_nested_vars " ) ) ) | |
( caller_channel & & switch_true ( switch_channel_get_variable ( caller_channel , " origination_nested_vars " ) ) )
2012-04-11 20:30:37 +00:00
| | switch_true ( switch_core_get_variable ( " origination_nested_vars " ) ) | | switch_stristr ( " origination_nested_vars=true " , data ) ) {
oglobals . check_vars = SWITCH_FALSE ;
}
2019-04-27 21:20:36 +00:00
FS-11346: [core] add api to pass pre-parsed values instead of dial strings to switch_ivr_originate
SWITCH_DECLARE(switch_status_t) switch_dial_handle_create(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_destroy(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_add_leg_list(switch_dial_handle_t *handle, switch_dial_leg_list_t **leg_listP);
SWITCH_DECLARE(void) switch_dial_leg_list_add_leg(switch_dial_leg_list_t *parent, const char *dial_string, switch_dial_leg_t **legP);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var(switch_dial_handle_t *handle, const char *var, const char *val);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var_printf(switch_dial_handle_t *handle, const char *var, const char *fmt, ...);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var(switch_dial_leg_t *leg, const char *var, const char *val);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var_printf(switch_dial_leg_t *leg, const char *var, const char *fmt, ...);
SWITCH_DECLARE(int) switch_dial_handle_get_peers(switch_dial_handle_t *handle, int idx, char **array, int max);
SWITCH_DECLARE(int) switch_dial_handle_get_vars(switch_dial_handle_t *handle, int idx, switch_event_t **array, int max);
SWITCH_DECLARE(switch_event_t *) switch_dial_handle_get_global_vars(switch_dial_handle_t *handle);
SWITCH_DECLARE(switch_event_t *) switch_dial_leg_get_vars(switch_dial_leg_t *leg);
SWITCH_DECLARE(int) switch_dial_handle_get_total(switch_dial_handle_t *handle);
SWITCH_DECLARE(void) switch_ivr_orig_and_bridge(switch_core_session_t *session, const char *data, switch_dial_handle_t *dh);
add switch_dial_handle_t *dh to end of args for switch_ivr_originate
2018-08-16 00:40:30 +00:00
if ( dh ) {
switch_event_t * vp = switch_dial_handle_get_global_vars ( dh ) ;
if ( vp ) {
2019-04-27 21:20:36 +00:00
if ( var_event & & var_event ! = ovars ) {
switch_event_destroy ( & var_event ) ;
}
FS-11346: [core] add api to pass pre-parsed values instead of dial strings to switch_ivr_originate
SWITCH_DECLARE(switch_status_t) switch_dial_handle_create(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_destroy(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_add_leg_list(switch_dial_handle_t *handle, switch_dial_leg_list_t **leg_listP);
SWITCH_DECLARE(void) switch_dial_leg_list_add_leg(switch_dial_leg_list_t *parent, const char *dial_string, switch_dial_leg_t **legP);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var(switch_dial_handle_t *handle, const char *var, const char *val);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var_printf(switch_dial_handle_t *handle, const char *var, const char *fmt, ...);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var(switch_dial_leg_t *leg, const char *var, const char *val);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var_printf(switch_dial_leg_t *leg, const char *var, const char *fmt, ...);
SWITCH_DECLARE(int) switch_dial_handle_get_peers(switch_dial_handle_t *handle, int idx, char **array, int max);
SWITCH_DECLARE(int) switch_dial_handle_get_vars(switch_dial_handle_t *handle, int idx, switch_event_t **array, int max);
SWITCH_DECLARE(switch_event_t *) switch_dial_handle_get_global_vars(switch_dial_handle_t *handle);
SWITCH_DECLARE(switch_event_t *) switch_dial_leg_get_vars(switch_dial_leg_t *leg);
SWITCH_DECLARE(int) switch_dial_handle_get_total(switch_dial_handle_t *handle);
SWITCH_DECLARE(void) switch_ivr_orig_and_bridge(switch_core_session_t *session, const char *data, switch_dial_handle_t *dh);
add switch_dial_handle_t *dh to end of args for switch_ivr_originate
2018-08-16 00:40:30 +00:00
switch_event_dup ( & var_event , vp ) ;
}
}
2012-04-17 21:51:40 +00:00
/* extract channel variables, allowing multiple sets of braces */
if ( * data = = ' < ' ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Parsing ultra-global variables \n " ) ;
while ( * data = = ' < ' ) {
char * parsed = NULL ;
if ( switch_event_create_brackets ( data , ' < ' , ' > ' , ' , ' , & var_event , & parsed , SWITCH_FALSE ) ! = SWITCH_STATUS_SUCCESS | | ! parsed ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Parse Error! \n " ) ;
switch_goto_status ( SWITCH_STATUS_GENERR , done ) ;
}
2017-01-06 07:10:15 +00:00
2012-04-17 21:51:40 +00:00
data = parsed ;
}
}
2011-04-14 22:44:22 +00:00
/* extract channel variables, allowing multiple sets of braces */
2012-04-10 21:17:16 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Parsing global variables \n " ) ;
2011-04-14 22:44:22 +00:00
while ( * data = = ' { ' ) {
char * parsed = NULL ;
if ( switch_event_create_brackets ( data , ' { ' , ' } ' , ' , ' , & var_event , & parsed , SWITCH_FALSE ) ! = SWITCH_STATUS_SUCCESS | | ! parsed ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Parse Error! \n " ) ;
switch_goto_status ( SWITCH_STATUS_GENERR , done ) ;
2009-05-07 02:05:16 +00:00
}
2011-04-14 22:44:22 +00:00
data = parsed ;
2009-05-07 02:05:16 +00:00
}
FS-11346: [core] add api to pass pre-parsed values instead of dial strings to switch_ivr_originate
SWITCH_DECLARE(switch_status_t) switch_dial_handle_create(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_destroy(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_add_leg_list(switch_dial_handle_t *handle, switch_dial_leg_list_t **leg_listP);
SWITCH_DECLARE(void) switch_dial_leg_list_add_leg(switch_dial_leg_list_t *parent, const char *dial_string, switch_dial_leg_t **legP);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var(switch_dial_handle_t *handle, const char *var, const char *val);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var_printf(switch_dial_handle_t *handle, const char *var, const char *fmt, ...);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var(switch_dial_leg_t *leg, const char *var, const char *val);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var_printf(switch_dial_leg_t *leg, const char *var, const char *fmt, ...);
SWITCH_DECLARE(int) switch_dial_handle_get_peers(switch_dial_handle_t *handle, int idx, char **array, int max);
SWITCH_DECLARE(int) switch_dial_handle_get_vars(switch_dial_handle_t *handle, int idx, switch_event_t **array, int max);
SWITCH_DECLARE(switch_event_t *) switch_dial_handle_get_global_vars(switch_dial_handle_t *handle);
SWITCH_DECLARE(switch_event_t *) switch_dial_leg_get_vars(switch_dial_leg_t *leg);
SWITCH_DECLARE(int) switch_dial_handle_get_total(switch_dial_handle_t *handle);
SWITCH_DECLARE(void) switch_ivr_orig_and_bridge(switch_core_session_t *session, const char *data, switch_dial_handle_t *dh);
add switch_dial_handle_t *dh to end of args for switch_ivr_originate
2018-08-16 00:40:30 +00:00
if ( dh & & var_event & & switch_event_serialize ( var_event , & event_string , SWITCH_FALSE ) = = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Global Vars \n ====================== \n %s \n " , event_string ) ;
switch_safe_free ( event_string ) ;
}
2011-04-14 22:44:22 +00:00
/* strip leading spaces (again) */
while ( data & & * data & & * data = = ' ' ) {
data + + ;
}
FS-11346: [core] add api to pass pre-parsed values instead of dial strings to switch_ivr_originate
SWITCH_DECLARE(switch_status_t) switch_dial_handle_create(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_destroy(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_add_leg_list(switch_dial_handle_t *handle, switch_dial_leg_list_t **leg_listP);
SWITCH_DECLARE(void) switch_dial_leg_list_add_leg(switch_dial_leg_list_t *parent, const char *dial_string, switch_dial_leg_t **legP);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var(switch_dial_handle_t *handle, const char *var, const char *val);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var_printf(switch_dial_handle_t *handle, const char *var, const char *fmt, ...);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var(switch_dial_leg_t *leg, const char *var, const char *val);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var_printf(switch_dial_leg_t *leg, const char *var, const char *fmt, ...);
SWITCH_DECLARE(int) switch_dial_handle_get_peers(switch_dial_handle_t *handle, int idx, char **array, int max);
SWITCH_DECLARE(int) switch_dial_handle_get_vars(switch_dial_handle_t *handle, int idx, switch_event_t **array, int max);
SWITCH_DECLARE(switch_event_t *) switch_dial_handle_get_global_vars(switch_dial_handle_t *handle);
SWITCH_DECLARE(switch_event_t *) switch_dial_leg_get_vars(switch_dial_leg_t *leg);
SWITCH_DECLARE(int) switch_dial_handle_get_total(switch_dial_handle_t *handle);
SWITCH_DECLARE(void) switch_ivr_orig_and_bridge(switch_core_session_t *session, const char *data, switch_dial_handle_t *dh);
add switch_dial_handle_t *dh to end of args for switch_ivr_originate
2018-08-16 00:40:30 +00:00
if ( zstr ( data ) & & ! dh ) {
2011-04-14 22:44:22 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING , " No origination URL specified! \n " ) ;
status = SWITCH_STATUS_GENERR ;
goto done ;
}
2013-05-08 14:18:45 +00:00
if ( ! ( flags & SOF_NOBLOCK ) & & var_event & & ( var = switch_event_get_header ( var_event , " originate_delay_start " ) ) ) {
2013-04-24 20:07:45 +00:00
int tmp = atoi ( var ) ;
if ( tmp > 0 ) {
while ( tmp & & ( ! cancel_cause | | * cancel_cause = = 0 ) ) {
switch_cond_next ( ) ;
tmp - - ;
}
}
}
2017-01-06 07:10:15 +00:00
2009-01-19 17:54:54 +00:00
if ( oglobals . session ) {
2007-09-29 01:06:08 +00:00
switch_event_header_t * hi ;
2009-04-30 13:53:29 +00:00
const char * cdr_total_var ;
2010-01-19 15:32:30 +00:00
const char * cdr_var ;
2013-02-28 15:58:53 +00:00
const char * json_cdr_var ;
2010-01-19 15:32:30 +00:00
2017-05-18 16:57:37 +00:00
if ( switch_channel_var_true ( caller_channel , " originate_xfer_zombie " ) ) {
switch_channel_set_flag ( caller_channel , CF_XFER_ZOMBIE ) ;
oglobals . early_ok = 0 ;
oglobals . ignore_early_media = 1 ;
}
2010-01-19 15:46:55 +00:00
if ( ( cdr_var = switch_channel_get_variable ( caller_channel , " failed_xml_cdr_prefix " ) ) ) {
2010-01-19 15:32:30 +00:00
char buf [ 128 ] = " " ;
switch_snprintf ( buf , sizeof ( buf ) , " %s_total " , cdr_var ) ;
if ( ( cdr_total_var = switch_channel_get_variable ( caller_channel , buf ) ) ) {
int tmp = atoi ( cdr_total_var ) ;
if ( tmp > 0 ) {
cdr_total = tmp ;
}
2009-04-30 13:53:29 +00:00
}
}
2010-02-06 03:38:24 +00:00
2013-02-28 15:58:53 +00:00
if ( ( json_cdr_var = switch_channel_get_variable ( caller_channel , " failed_json_cdr_prefix " ) ) ) {
char buf [ 128 ] = " " ;
switch_snprintf ( buf , sizeof ( buf ) , " %s_total " , json_cdr_var ) ;
if ( ( cdr_total_var = switch_channel_get_variable ( caller_channel , buf ) ) ) {
int tmp = atoi ( cdr_total_var ) ;
if ( tmp > 0 ) {
cdr_total = tmp ;
}
}
}
2009-04-30 13:53:29 +00:00
2009-05-07 02:05:16 +00:00
/* Copy all the missing applicable channel variables from A-leg into the event */
2007-09-29 01:06:08 +00:00
if ( ( hi = switch_channel_variable_first ( caller_channel ) ) ) {
for ( ; hi ; hi = hi - > next ) {
2007-12-11 00:09:04 +00:00
int ok = 0 ;
2008-05-27 04:30:03 +00:00
if ( ! strcasecmp ( ( char * ) hi - > name , " group_confirm_key " ) ) {
2007-12-11 00:09:04 +00:00
ok = 1 ;
2008-05-27 04:30:03 +00:00
} else if ( ! strcasecmp ( ( char * ) hi - > name , " group_confirm_file " ) ) {
2007-12-11 00:09:04 +00:00
ok = 1 ;
2012-04-09 17:35:26 +00:00
} else if ( ! strcasecmp ( ( char * ) hi - > name , " group_confirm_read_timeout " ) ) {
ok = 1 ;
2009-07-15 15:24:47 +00:00
} else if ( ! strcasecmp ( ( char * ) hi - > name , " group_confirm_cancel_timeout " ) ) {
2009-07-14 17:19:14 +00:00
ok = 1 ;
2020-01-06 12:25:44 +00:00
} else if ( ! strcasecmp ( ( char * ) hi - > name , " group_confirm_timeout " ) ) {
ok = 1 ;
2008-05-27 04:30:03 +00:00
} else if ( ! strcasecmp ( ( char * ) hi - > name , " forked_dial " ) ) {
2008-01-07 21:14:24 +00:00
ok = 1 ;
2008-05-27 04:30:03 +00:00
} else if ( ! strcasecmp ( ( char * ) hi - > name , " fail_on_single_reject " ) ) {
2007-12-11 00:09:04 +00:00
ok = 1 ;
2013-05-22 16:01:39 +00:00
} else if ( ! strcasecmp ( ( char * ) hi - > name , " hangup_on_single_reject " ) ) {
ok = 1 ;
2008-05-27 04:30:03 +00:00
} else if ( ! strcasecmp ( ( char * ) hi - > name , " ignore_early_media " ) ) {
2007-12-11 00:09:04 +00:00
ok = 1 ;
2010-01-14 21:02:11 +00:00
} else if ( ! strcasecmp ( ( char * ) hi - > name , " bridge_early_media " ) ) {
ok = 1 ;
2009-10-08 17:43:51 +00:00
} else if ( ! strcasecmp ( ( char * ) hi - > name , " originate_continue_on_timeout " ) ) {
ok = 1 ;
2009-01-20 15:39:32 +00:00
} else if ( ! strcasecmp ( ( char * ) hi - > name , " ignore_ring_ready " ) ) {
ok = 1 ;
2009-01-19 23:15:59 +00:00
} else if ( ! strcasecmp ( ( char * ) hi - > name , " monitor_early_media_ring " ) ) {
ok = 1 ;
2009-02-11 00:16:36 +00:00
} else if ( ! strcasecmp ( ( char * ) hi - > name , " monitor_early_media_ring_total " ) ) {
ok = 1 ;
2009-01-19 23:15:59 +00:00
} else if ( ! strcasecmp ( ( char * ) hi - > name , " monitor_early_media_fail " ) ) {
ok = 1 ;
2008-05-27 04:30:03 +00:00
} else if ( ! strcasecmp ( ( char * ) hi - > name , " return_ring_ready " ) ) {
2008-01-05 14:58:26 +00:00
ok = 1 ;
2008-09-23 19:01:22 +00:00
} else if ( ! strcasecmp ( ( char * ) hi - > name , " ring_ready " ) ) {
ok = 1 ;
2009-02-11 00:22:41 +00:00
} else if ( ! strcasecmp ( ( char * ) hi - > name , " instant_ringback " ) ) {
ok = 1 ;
2008-06-23 22:07:22 +00:00
} else if ( ! strcasecmp ( ( char * ) hi - > name , " progress_timeout " ) ) {
ok = 1 ;
2010-02-27 20:39:23 +00:00
} else if ( ! strcasecmp ( ( char * ) hi - > name , " language " ) ) {
ok = 1 ;
2007-12-11 00:09:04 +00:00
}
2009-05-07 02:05:16 +00:00
if ( ok & & ! switch_event_get_header ( var_event , hi - > name ) ) {
2008-08-16 02:17:09 +00:00
switch_event_add_header_string ( var_event , SWITCH_STACK_BOTTOM , ( char * ) hi - > name , ( char * ) hi - > value ) ;
2007-12-11 00:09:04 +00:00
}
2007-09-29 01:06:08 +00:00
}
switch_channel_variable_last ( caller_channel ) ;
}
/*
2010-02-06 03:38:24 +00:00
if ( ( hi = switch_channel_variable_first ( caller_channel ) ) ) {
2014-04-01 20:20:19 +00:00
for ( ; hi ; hi = switch_core_hash_next ( & hi ) ) {
2014-03-08 19:37:09 +00:00
switch_core_hash_this ( hi , & vvar , NULL , & vval ) ;
2010-02-06 03:38:24 +00:00
if ( vvar & & vval ) {
switch_event_add_header_string ( var_event , SWITCH_STACK_BOTTOM , ( void * ) vvar , ( char * ) vval ) ;
}
}
switch_channel_variable_last ( caller_channel ) ;
}
*/
2007-03-29 22:34:40 +00:00
}
if ( caller_channel ) { /* ringback is only useful when there is an originator */
2007-12-20 21:42:00 +00:00
ringback_data = NULL ;
2009-08-26 19:49:35 +00:00
cancel_key = switch_channel_get_variable ( caller_channel , " origination_cancel_key " ) ;
2007-12-20 21:42:00 +00:00
2008-01-05 16:20:39 +00:00
if ( switch_channel_test_flag ( caller_channel , CF_ANSWERED ) ) {
2007-12-20 21:42:00 +00:00
ringback_data = switch_channel_get_variable ( caller_channel , " transfer_ringback " ) ;
2008-05-27 04:30:03 +00:00
}
2007-12-20 21:42:00 +00:00
if ( ! ringback_data ) {
ringback_data = switch_channel_get_variable ( caller_channel , " ringback " ) ;
}
2008-05-27 04:30:03 +00:00
2007-03-29 22:34:40 +00:00
switch_channel_set_variable ( caller_channel , " originate_disposition " , " failure " ) ;
2011-08-10 13:38:55 +00:00
switch_channel_set_variable ( caller_channel , " DIALSTATUS " , " INVALIDARGS " ) ;
2008-10-08 18:15:00 +00:00
if ( switch_channel_test_flag ( caller_channel , CF_PROXY_MODE ) | | switch_channel_test_flag ( caller_channel , CF_PROXY_MEDIA ) ) {
ringback_data = NULL ;
}
}
2009-09-30 20:15:00 +00:00
#if 0
/* changing behaviour ignore_early_media=true must also be explicitly set for previous behaviour */
2008-10-08 18:15:00 +00:00
if ( ringback_data ) {
2009-01-19 17:54:54 +00:00
oglobals . early_ok = 0 ;
2007-03-29 22:34:40 +00:00
}
2009-09-30 20:15:00 +00:00
# endif
2007-03-29 22:34:40 +00:00
2020-01-06 12:25:44 +00:00
if ( ( var = switch_event_get_header ( var_event , " group_confirm_timeout " ) ) ) {
// has precedence over group_confirm_cancel_timeout
if ( switch_is_number ( var ) ) {
oglobals . confirm_timeout = atoi ( var ) ;
if ( oglobals . confirm_timeout = = 0 ) {
oglobals . cancel_timeout = SWITCH_TRUE ;
}
}
} else if ( switch_true ( switch_event_get_header ( var_event , " group_confirm_cancel_timeout " ) ) ) {
2016-02-04 22:14:43 +00:00
oglobals . cancel_timeout = SWITCH_TRUE ;
2009-07-14 17:19:14 +00:00
}
2019-11-06 14:10:54 +00:00
if ( ( var = switch_event_get_header ( var_event , " group_confirm_early_ok " ) ) ) {
oglobals . early_ok = switch_true ( var ) ;
}
2007-03-29 22:34:40 +00:00
if ( ( var = switch_event_get_header ( var_event , " group_confirm_key " ) ) ) {
2009-01-19 17:54:54 +00:00
switch_copy_string ( oglobals . key , var , sizeof ( oglobals . key ) ) ;
2007-03-29 22:34:40 +00:00
if ( ( var = switch_event_get_header ( var_event , " group_confirm_file " ) ) ) {
2011-08-25 13:27:23 +00:00
oglobals . file = strdup ( var ) ;
2007-03-29 22:34:40 +00:00
}
2010-03-12 23:49:51 +00:00
if ( ( var = switch_event_get_header ( var_event , " group_confirm_error_file " ) ) ) {
2011-08-25 13:27:23 +00:00
oglobals . error_file = strdup ( var ) ;
2010-03-12 23:49:51 +00:00
}
if ( ( var = switch_event_get_header ( var_event , " group_confirm_read_timeout " ) ) ) {
int tmp = atoi ( var ) ;
if ( tmp > = 0 ) {
2020-01-06 12:25:44 +00:00
oglobals . confirm_read_timeout = tmp ;
2010-03-12 23:49:51 +00:00
}
}
2007-03-29 22:34:40 +00:00
}
2008-09-02 10:46:44 +00:00
/* When using the AND operator, the fail_on_single_reject flag may be set in order to indicate that a single
2017-01-06 07:10:15 +00:00
rejections should terminate the attempt rather than a timeout , answer , or rejection by all .
2008-10-09 00:38:59 +00:00
If the value is set to ' true ' any fail cause will end the attempt otherwise it can contain a comma ( , ) separated
list of cause names which should be considered fatal
2010-02-06 03:38:24 +00:00
*/
2013-05-22 16:01:39 +00:00
if ( ( var = switch_event_get_header ( var_event , " hangup_on_single_reject " ) ) ) {
2015-06-19 06:34:31 +00:00
hangup_on_single_reject = switch_true ( var ) ;
2013-05-22 16:01:39 +00:00
}
2015-06-19 06:34:31 +00:00
if ( ( var = switch_event_get_header ( var_event , " fail_on_single_reject " ) ) | | hangup_on_single_reject ) {
if ( var ) {
fail_on_single_reject_var = strdup ( var ) ;
}
2010-10-25 18:03:06 +00:00
if ( switch_true ( var ) ) {
fail_on_single_reject = 1 ;
} else {
fail_on_single_reject = - 1 ;
}
2007-03-29 22:34:40 +00:00
}
2011-08-25 13:27:23 +00:00
if ( ( ! zstr ( oglobals . file ) ) & & ( ! strcmp ( oglobals . file , " undef " ) ) ) {
switch_safe_free ( oglobals . file ) ;
oglobals . file = NULL ;
2007-03-29 22:34:40 +00:00
}
2011-08-25 13:27:23 +00:00
if ( ( ! zstr ( oglobals . error_file ) ) & & ( ! strcmp ( oglobals . error_file , " undef " ) ) ) {
switch_safe_free ( oglobals . error_file ) ;
oglobals . error_file = NULL ;
2010-03-12 23:49:51 +00:00
}
2010-01-14 21:02:11 +00:00
if ( ( var_val = switch_event_get_header ( var_event , " bridge_early_media " ) ) ) {
if ( switch_true ( var_val ) ) {
oglobals . early_ok = 0 ;
oglobals . ignore_early_media = 3 ;
}
}
2009-10-22 22:11:28 +00:00
if ( ( var_val = switch_event_get_header ( var_event , " ignore_early_media " ) ) ) {
if ( switch_true ( var_val ) ) {
oglobals . early_ok = 0 ;
oglobals . ignore_early_media = 1 ;
2012-08-30 20:14:33 +00:00
} else if ( ! strcmp ( var_val , " consume " ) ) {
oglobals . early_ok = 0 ;
oglobals . ignore_early_media = 4 ;
2009-10-22 22:11:28 +00:00
} else if ( ! strcmp ( var_val , " ring_ready " ) ) {
oglobals . early_ok = 0 ;
oglobals . ignore_early_media = 2 ;
}
2009-01-20 15:39:32 +00:00
}
2009-10-08 17:43:51 +00:00
if ( ( var_val = switch_event_get_header ( var_event , " originate_continue_on_timeout " ) ) & & switch_true ( var_val ) ) {
oglobals . continue_on_timeout = 1 ;
}
2009-01-20 15:39:32 +00:00
if ( ( var_val = switch_event_get_header ( var_event , " ignore_ring_ready " ) ) & & switch_true ( var_val ) ) {
oglobals . ignore_ring_ready = 1 ;
2007-03-29 22:34:40 +00:00
}
2022-01-11 16:16:53 +00:00
if ( ( var_val = switch_event_get_header ( var_event , " monitor_early_media_ring " ) ) & & switch_true ( var_val ) ) {
2009-01-19 23:15:59 +00:00
oglobals . early_ok = 0 ;
oglobals . monitor_early_media_ring = 1 ;
}
2022-01-11 16:16:53 +00:00
if ( ( var_val = switch_event_get_header ( var_event , " monitor_early_media_fail " ) ) & & switch_true ( var_val ) ) {
2009-01-19 23:15:59 +00:00
oglobals . early_ok = 0 ;
oglobals . monitor_early_media_fail = 1 ;
}
2008-01-05 14:58:26 +00:00
if ( ( var_val = switch_event_get_header ( var_event , " return_ring_ready " ) ) & & switch_true ( var_val ) ) {
2009-01-19 17:54:54 +00:00
oglobals . return_ring_ready = 1 ;
2008-01-05 14:58:26 +00:00
}
2008-09-23 19:01:22 +00:00
if ( ( var_val = switch_event_get_header ( var_event , " ring_ready " ) ) & & switch_true ( var_val ) ) {
2009-01-19 19:32:44 +00:00
oglobals . ring_ready = 1 ;
2008-09-23 19:01:22 +00:00
}
2009-02-11 00:22:41 +00:00
if ( ( var_val = switch_event_get_header ( var_event , " instant_ringback " ) ) & & switch_true ( var_val ) ) {
oglobals . instant_ringback = 1 ;
}
2008-06-23 22:07:22 +00:00
if ( ( var_val = switch_event_get_header ( var_event , " originate_timeout " ) ) ) {
2008-04-15 18:43:12 +00:00
int tmp = atoi ( var_val ) ;
if ( tmp > 0 ) {
timelimit_sec = ( uint32_t ) tmp ;
}
}
2008-06-23 22:07:22 +00:00
if ( ( var_val = switch_event_get_header ( var_event , " progress_timeout " ) ) ) {
int tmp = atoi ( var_val ) ;
if ( tmp > 0 ) {
progress_timelimit_sec = ( uint32_t ) tmp ;
}
}
2016-09-01 14:59:06 +00:00
if ( ( var_val = switch_event_get_header ( var_event , " originate_retry_timeout " ) ) & & switch_true ( var_val ) ) {
int32_t tmp ;
tmp = atoi ( var_val ) ;
if ( tmp > 0 ) {
retry_timelimit_sec = tmp ;
} else {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING ,
" Invalid originate_retry_timeout setting of %s ignored, value must be > 0 \n " , var_val ) ;
}
}
2007-03-29 22:34:40 +00:00
if ( ( var_val = switch_event_get_header ( var_event , " originate_retries " ) ) & & switch_true ( var_val ) ) {
int32_t tmp ;
tmp = atoi ( var_val ) ;
2016-09-01 14:59:06 +00:00
/* allow large number of retries if timeout is set */
if ( tmp > 0 & & ( retry_timelimit_sec > 0 | | tmp < 101 ) ) {
2007-03-29 22:34:40 +00:00
retries = tmp ;
} else {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING ,
2007-03-30 00:13:31 +00:00
" Invalid originate_retries setting of %d ignored, value must be between 1 and 100 \n " , tmp ) ;
2007-03-29 22:34:40 +00:00
}
}
if ( ( var_val = switch_event_get_header ( var_event , " originate_retry_sleep_ms " ) ) & & switch_true ( var_val ) ) {
int32_t tmp ;
tmp = atoi ( var_val ) ;
2008-06-11 16:40:36 +00:00
if ( tmp > = 500 & & tmp < = 60000 ) {
2007-03-29 22:34:40 +00:00
sleep_ms = tmp ;
} else {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING ,
2007-03-30 00:13:31 +00:00
" Invalid originate_retry_sleep_ms setting of %d ignored, value must be between 500 and 60000 \n " , tmp ) ;
2007-03-29 22:34:40 +00:00
}
}
2016-09-01 14:59:06 +00:00
if ( ( var_val = switch_event_get_header ( var_event , " originate_retry_min_period_ms " ) ) & & switch_true ( var_val ) ) {
int32_t tmp ;
tmp = atoi ( var_val ) ;
if ( tmp > = 500 & & tmp < = 300000 ) {
min_retry_period_ms = tmp ;
} else {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING ,
" Invalid originate_retry_min_period_ms setting of %d ignored, value must be between 500 and 300000 \n " , tmp ) ;
}
}
2013-10-17 16:18:01 +00:00
/* variable to force ANI / ANIII */
ani_override = switch_event_get_header ( var_event , " origination_ani " ) ;
aniii_override = switch_event_get_header ( var_event , " origination_aniii " ) ;
2008-08-11 21:27:20 +00:00
if ( ( cid_tmp = switch_event_get_header ( var_event , " origination_caller_id_name " ) ) ) {
cid_name_override = cid_tmp ;
}
2008-06-23 19:04:17 +00:00
if ( cid_name_override ) {
2010-07-01 01:09:06 +00:00
if ( ! cid_tmp ) {
switch_event_add_header_string ( var_event , SWITCH_STACK_BOTTOM , " origination_caller_id_name " , cid_name_override ) ;
}
2008-06-23 19:04:17 +00:00
} else {
2007-03-29 22:34:40 +00:00
cid_name_override = switch_event_get_header ( var_event , " origination_caller_id_name " ) ;
}
2008-08-11 21:27:20 +00:00
if ( ( cid_tmp = switch_event_get_header ( var_event , " origination_caller_id_number " ) ) ) {
cid_num_override = cid_tmp ;
}
2008-06-23 19:04:17 +00:00
if ( cid_num_override ) {
2010-07-01 01:09:06 +00:00
if ( ! cid_tmp ) {
switch_event_add_header_string ( var_event , SWITCH_STACK_BOTTOM , " origination_caller_id_number " , cid_num_override ) ;
}
2008-06-23 19:04:17 +00:00
} else {
2007-03-29 22:34:40 +00:00
cid_num_override = switch_event_get_header ( var_event , " origination_caller_id_number " ) ;
}
2010-08-26 17:19:49 +00:00
if ( flags & SOF_NO_LIMITS ) {
dftflags | = SOF_NO_LIMITS ;
}
2013-10-17 16:18:01 +00:00
if ( ani_override ) {
dftflags | = SOF_NO_EFFECTIVE_ANI ;
}
if ( aniii_override ) {
dftflags | = SOF_NO_EFFECTIVE_ANIII ;
}
2008-08-11 21:27:20 +00:00
if ( cid_num_override ) {
dftflags | = SOF_NO_EFFECTIVE_CID_NUM ;
}
2017-01-06 07:10:15 +00:00
2008-08-11 21:27:20 +00:00
if ( cid_name_override ) {
dftflags | = SOF_NO_EFFECTIVE_CID_NAME ;
}
2008-06-23 22:07:22 +00:00
if ( ! progress_timelimit_sec ) {
progress_timelimit_sec = timelimit_sec ;
}
2016-09-01 14:59:06 +00:00
switch_epoch_time_now ( & global_start ) ;
last_retry_start = switch_micro_time_now ( ) ;
2007-03-29 22:34:40 +00:00
for ( try = 0 ; try < retries ; try + + ) {
2016-09-01 14:59:06 +00:00
if ( try > 0 ) {
2016-09-08 08:02:49 +00:00
int64_t elapsed = switch_epoch_time_now ( NULL ) - global_start ;
2016-09-01 14:59:06 +00:00
/* check if retry time limit has been exceeded */
if ( retry_timelimit_sec > 0 ) {
2016-09-08 08:02:49 +00:00
if ( elapsed > retry_timelimit_sec ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_NOTICE ,
" Elapsed = % " SWITCH_INT64_T_FMT " , originate retry timeout. \n " , elapsed ) ;
2016-09-01 14:59:06 +00:00
break ;
} else if ( cancel_cause & & * cancel_cause ! = 0 ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Originate cancelled \n " ) ;
break ;
} else {
2016-09-08 08:02:49 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG ,
" Elapsed = % " SWITCH_INT64_T_FMT " , originate retry not timed out yet \n " , elapsed ) ;
2016-09-01 14:59:06 +00:00
}
}
/* don't allow retry to start too quickly since last attempt */
if ( min_retry_period_ms > sleep_ms ) {
int64_t retry_sleep_ms = min_retry_period_ms - sleep_ms - ( ( switch_micro_time_now ( ) - last_retry_start ) / 1000 ) ;
if ( retry_sleep_ms > 0 & & retry_sleep_ms < = 300000 ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_INFO , " Minimum retry period has not elapsed yet, waiting % " SWITCH_INT64_T_FMT " ms \n " , retry_sleep_ms ) ;
if ( caller_channel ) {
switch_ivr_sleep ( oglobals . session , retry_sleep_ms , SWITCH_TRUE , NULL ) ;
if ( ! switch_channel_ready ( caller_channel ) ) {
status = SWITCH_STATUS_FALSE ;
goto done ;
}
} else {
switch_yield ( retry_sleep_ms * 1000 ) ;
}
}
}
}
2007-03-29 22:34:40 +00:00
switch_safe_free ( loop_data ) ;
2007-10-19 00:21:50 +00:00
loop_data = strdup ( data ) ;
2007-12-11 19:23:57 +00:00
switch_assert ( loop_data ) ;
2007-03-29 22:34:40 +00:00
FS-11346: [core] add api to pass pre-parsed values instead of dial strings to switch_ivr_originate
SWITCH_DECLARE(switch_status_t) switch_dial_handle_create(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_destroy(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_add_leg_list(switch_dial_handle_t *handle, switch_dial_leg_list_t **leg_listP);
SWITCH_DECLARE(void) switch_dial_leg_list_add_leg(switch_dial_leg_list_t *parent, const char *dial_string, switch_dial_leg_t **legP);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var(switch_dial_handle_t *handle, const char *var, const char *val);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var_printf(switch_dial_handle_t *handle, const char *var, const char *fmt, ...);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var(switch_dial_leg_t *leg, const char *var, const char *val);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var_printf(switch_dial_leg_t *leg, const char *var, const char *fmt, ...);
SWITCH_DECLARE(int) switch_dial_handle_get_peers(switch_dial_handle_t *handle, int idx, char **array, int max);
SWITCH_DECLARE(int) switch_dial_handle_get_vars(switch_dial_handle_t *handle, int idx, switch_event_t **array, int max);
SWITCH_DECLARE(switch_event_t *) switch_dial_handle_get_global_vars(switch_dial_handle_t *handle);
SWITCH_DECLARE(switch_event_t *) switch_dial_leg_get_vars(switch_dial_leg_t *leg);
SWITCH_DECLARE(int) switch_dial_handle_get_total(switch_dial_handle_t *handle);
SWITCH_DECLARE(void) switch_ivr_orig_and_bridge(switch_core_session_t *session, const char *data, switch_dial_handle_t *dh);
add switch_dial_handle_t *dh to end of args for switch_ivr_originate
2018-08-16 00:40:30 +00:00
if ( dh ) {
or_argc = switch_dial_handle_get_total ( dh ) ;
} else {
or_argc = switch_separate_string ( loop_data , ' | ' , pipe_names , ( sizeof ( pipe_names ) / sizeof ( pipe_names [ 0 ] ) ) ) ;
}
2007-12-20 21:42:00 +00:00
if ( ( flags & SOF_NOBLOCK ) & & or_argc > 1 ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING , " Only calling the first element in the list in this mode. \n " ) ;
2007-12-20 21:42:00 +00:00
or_argc = 1 ;
}
FS-11346: [core] add api to pass pre-parsed values instead of dial strings to switch_ivr_originate
SWITCH_DECLARE(switch_status_t) switch_dial_handle_create(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_destroy(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_add_leg_list(switch_dial_handle_t *handle, switch_dial_leg_list_t **leg_listP);
SWITCH_DECLARE(void) switch_dial_leg_list_add_leg(switch_dial_leg_list_t *parent, const char *dial_string, switch_dial_leg_t **legP);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var(switch_dial_handle_t *handle, const char *var, const char *val);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var_printf(switch_dial_handle_t *handle, const char *var, const char *fmt, ...);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var(switch_dial_leg_t *leg, const char *var, const char *val);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var_printf(switch_dial_leg_t *leg, const char *var, const char *fmt, ...);
SWITCH_DECLARE(int) switch_dial_handle_get_peers(switch_dial_handle_t *handle, int idx, char **array, int max);
SWITCH_DECLARE(int) switch_dial_handle_get_vars(switch_dial_handle_t *handle, int idx, switch_event_t **array, int max);
SWITCH_DECLARE(switch_event_t *) switch_dial_handle_get_global_vars(switch_dial_handle_t *handle);
SWITCH_DECLARE(switch_event_t *) switch_dial_leg_get_vars(switch_dial_leg_t *leg);
SWITCH_DECLARE(int) switch_dial_handle_get_total(switch_dial_handle_t *handle);
SWITCH_DECLARE(void) switch_ivr_orig_and_bridge(switch_core_session_t *session, const char *data, switch_dial_handle_t *dh);
add switch_dial_handle_t *dh to end of args for switch_ivr_originate
2018-08-16 00:40:30 +00:00
if ( or_argc < = 0 ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Nothing to do \n " ) ;
goto outer_for ;
}
2013-03-19 14:16:36 +00:00
for ( r = 0 ; r < or_argc & & ( ! cancel_cause | | * cancel_cause = = 0 ) ; r + + ) {
2008-10-23 01:39:04 +00:00
char * p , * end = NULL ;
2011-04-14 22:44:22 +00:00
int q = 0 , alt = 0 ;
2010-10-25 18:03:06 +00:00
check_reject = 1 ;
2009-01-19 21:11:01 +00:00
oglobals . hups = 0 ;
2010-02-06 03:38:24 +00:00
2008-07-03 22:51:09 +00:00
reason = SWITCH_CAUSE_NONE ;
2007-03-29 22:34:40 +00:00
memset ( peer_names , 0 , sizeof ( peer_names ) ) ;
peer_session = NULL ;
2020-05-07 17:04:54 +00:00
memset ( oglobals . originate_status , 0 , sizeof ( oglobals . originate_status ) ) ;
2007-04-16 19:32:08 +00:00
new_profile = NULL ;
new_session = NULL ;
2007-03-29 22:34:40 +00:00
chan_type = NULL ;
chan_data = NULL ;
peer_channel = NULL ;
start = 0 ;
read_frame = NULL ;
2009-10-29 05:47:17 +00:00
oglobals . ringback_ok = 1 ;
2007-03-29 22:34:40 +00:00
var = NULL ;
to = 0 ;
2009-01-19 17:54:54 +00:00
oglobals . sent_ring = 0 ;
oglobals . progress = 0 ;
2008-08-11 21:27:20 +00:00
myflags = dftflags ;
2017-01-06 07:10:15 +00:00
2010-02-06 03:38:24 +00:00
2007-03-29 22:34:40 +00:00
if ( try > 0 ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_NOTICE , " Originate attempt %d/%d in %d ms \n " , try + 1 , retries ,
sleep_ms ) ;
2008-10-13 21:17:10 +00:00
if ( caller_channel ) {
2009-01-19 17:54:54 +00:00
switch_ivr_sleep ( oglobals . session , sleep_ms , SWITCH_TRUE , NULL ) ;
2009-05-04 14:09:32 +00:00
if ( ! switch_channel_ready ( caller_channel ) ) {
status = SWITCH_STATUS_FALSE ;
2014-11-20 03:51:09 +00:00
/* set try and retries to 0 */
try = 0 ;
retries = 0 ;
2009-05-04 14:09:32 +00:00
goto done ;
}
2008-10-13 21:17:10 +00:00
} else {
switch_yield ( sleep_ms * 1000 ) ;
}
2007-03-29 22:34:40 +00:00
}
2016-09-01 14:59:06 +00:00
if ( r = = 0 ) {
last_retry_start = switch_micro_time_now ( ) ;
}
FS-11346: [core] add api to pass pre-parsed values instead of dial strings to switch_ivr_originate
SWITCH_DECLARE(switch_status_t) switch_dial_handle_create(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_destroy(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_add_leg_list(switch_dial_handle_t *handle, switch_dial_leg_list_t **leg_listP);
SWITCH_DECLARE(void) switch_dial_leg_list_add_leg(switch_dial_leg_list_t *parent, const char *dial_string, switch_dial_leg_t **legP);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var(switch_dial_handle_t *handle, const char *var, const char *val);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var_printf(switch_dial_handle_t *handle, const char *var, const char *fmt, ...);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var(switch_dial_leg_t *leg, const char *var, const char *val);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var_printf(switch_dial_leg_t *leg, const char *var, const char *fmt, ...);
SWITCH_DECLARE(int) switch_dial_handle_get_peers(switch_dial_handle_t *handle, int idx, char **array, int max);
SWITCH_DECLARE(int) switch_dial_handle_get_vars(switch_dial_handle_t *handle, int idx, switch_event_t **array, int max);
SWITCH_DECLARE(switch_event_t *) switch_dial_handle_get_global_vars(switch_dial_handle_t *handle);
SWITCH_DECLARE(switch_event_t *) switch_dial_leg_get_vars(switch_dial_leg_t *leg);
SWITCH_DECLARE(int) switch_dial_handle_get_total(switch_dial_handle_t *handle);
SWITCH_DECLARE(void) switch_ivr_orig_and_bridge(switch_core_session_t *session, const char *data, switch_dial_handle_t *dh);
add switch_dial_handle_t *dh to end of args for switch_ivr_originate
2018-08-16 00:40:30 +00:00
if ( ! dh ) {
p = pipe_names [ r ] ;
2017-01-06 07:10:15 +00:00
FS-11346: [core] add api to pass pre-parsed values instead of dial strings to switch_ivr_originate
SWITCH_DECLARE(switch_status_t) switch_dial_handle_create(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_destroy(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_add_leg_list(switch_dial_handle_t *handle, switch_dial_leg_list_t **leg_listP);
SWITCH_DECLARE(void) switch_dial_leg_list_add_leg(switch_dial_leg_list_t *parent, const char *dial_string, switch_dial_leg_t **legP);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var(switch_dial_handle_t *handle, const char *var, const char *val);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var_printf(switch_dial_handle_t *handle, const char *var, const char *fmt, ...);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var(switch_dial_leg_t *leg, const char *var, const char *val);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var_printf(switch_dial_leg_t *leg, const char *var, const char *fmt, ...);
SWITCH_DECLARE(int) switch_dial_handle_get_peers(switch_dial_handle_t *handle, int idx, char **array, int max);
SWITCH_DECLARE(int) switch_dial_handle_get_vars(switch_dial_handle_t *handle, int idx, switch_event_t **array, int max);
SWITCH_DECLARE(switch_event_t *) switch_dial_handle_get_global_vars(switch_dial_handle_t *handle);
SWITCH_DECLARE(switch_event_t *) switch_dial_leg_get_vars(switch_dial_leg_t *leg);
SWITCH_DECLARE(int) switch_dial_handle_get_total(switch_dial_handle_t *handle);
SWITCH_DECLARE(void) switch_ivr_orig_and_bridge(switch_core_session_t *session, const char *data, switch_dial_handle_t *dh);
add switch_dial_handle_t *dh to end of args for switch_ivr_originate
2018-08-16 00:40:30 +00:00
while ( p & & * p ) {
if ( ! end & & * p = = ' [ ' ) {
end = switch_find_end_paren ( p , ' [ ' , ' ] ' ) ;
if ( * ( p + 1 ) = = ' ^ ' & & * ( p + 2 ) = = ' ^ ' ) {
alt = 1 ;
} else {
alt = 0 ;
}
q = 0 ;
2011-04-14 22:44:22 +00:00
}
2017-01-06 07:10:15 +00:00
FS-11346: [core] add api to pass pre-parsed values instead of dial strings to switch_ivr_originate
SWITCH_DECLARE(switch_status_t) switch_dial_handle_create(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_destroy(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_add_leg_list(switch_dial_handle_t *handle, switch_dial_leg_list_t **leg_listP);
SWITCH_DECLARE(void) switch_dial_leg_list_add_leg(switch_dial_leg_list_t *parent, const char *dial_string, switch_dial_leg_t **legP);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var(switch_dial_handle_t *handle, const char *var, const char *val);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var_printf(switch_dial_handle_t *handle, const char *var, const char *fmt, ...);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var(switch_dial_leg_t *leg, const char *var, const char *val);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var_printf(switch_dial_leg_t *leg, const char *var, const char *fmt, ...);
SWITCH_DECLARE(int) switch_dial_handle_get_peers(switch_dial_handle_t *handle, int idx, char **array, int max);
SWITCH_DECLARE(int) switch_dial_handle_get_vars(switch_dial_handle_t *handle, int idx, switch_event_t **array, int max);
SWITCH_DECLARE(switch_event_t *) switch_dial_handle_get_global_vars(switch_dial_handle_t *handle);
SWITCH_DECLARE(switch_event_t *) switch_dial_leg_get_vars(switch_dial_leg_t *leg);
SWITCH_DECLARE(int) switch_dial_handle_get_total(switch_dial_handle_t *handle);
SWITCH_DECLARE(void) switch_ivr_orig_and_bridge(switch_core_session_t *session, const char *data, switch_dial_handle_t *dh);
add switch_dial_handle_t *dh to end of args for switch_ivr_originate
2018-08-16 00:40:30 +00:00
if ( * p = = ' \' ' ) {
q = ! q ;
}
2010-07-16 02:09:48 +00:00
FS-11346: [core] add api to pass pre-parsed values instead of dial strings to switch_ivr_originate
SWITCH_DECLARE(switch_status_t) switch_dial_handle_create(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_destroy(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_add_leg_list(switch_dial_handle_t *handle, switch_dial_leg_list_t **leg_listP);
SWITCH_DECLARE(void) switch_dial_leg_list_add_leg(switch_dial_leg_list_t *parent, const char *dial_string, switch_dial_leg_t **legP);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var(switch_dial_handle_t *handle, const char *var, const char *val);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var_printf(switch_dial_handle_t *handle, const char *var, const char *fmt, ...);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var(switch_dial_leg_t *leg, const char *var, const char *val);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var_printf(switch_dial_leg_t *leg, const char *var, const char *fmt, ...);
SWITCH_DECLARE(int) switch_dial_handle_get_peers(switch_dial_handle_t *handle, int idx, char **array, int max);
SWITCH_DECLARE(int) switch_dial_handle_get_vars(switch_dial_handle_t *handle, int idx, switch_event_t **array, int max);
SWITCH_DECLARE(switch_event_t *) switch_dial_handle_get_global_vars(switch_dial_handle_t *handle);
SWITCH_DECLARE(switch_event_t *) switch_dial_leg_get_vars(switch_dial_leg_t *leg);
SWITCH_DECLARE(int) switch_dial_handle_get_total(switch_dial_handle_t *handle);
SWITCH_DECLARE(void) switch_ivr_orig_and_bridge(switch_core_session_t *session, const char *data, switch_dial_handle_t *dh);
add switch_dial_handle_t *dh to end of args for switch_ivr_originate
2018-08-16 00:40:30 +00:00
if ( end & & p < end & & * p = = ' , ' & & * ( p - 1 ) ! = ' \\ ' ) {
2017-01-06 07:10:15 +00:00
FS-11346: [core] add api to pass pre-parsed values instead of dial strings to switch_ivr_originate
SWITCH_DECLARE(switch_status_t) switch_dial_handle_create(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_destroy(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_add_leg_list(switch_dial_handle_t *handle, switch_dial_leg_list_t **leg_listP);
SWITCH_DECLARE(void) switch_dial_leg_list_add_leg(switch_dial_leg_list_t *parent, const char *dial_string, switch_dial_leg_t **legP);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var(switch_dial_handle_t *handle, const char *var, const char *val);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var_printf(switch_dial_handle_t *handle, const char *var, const char *fmt, ...);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var(switch_dial_leg_t *leg, const char *var, const char *val);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var_printf(switch_dial_leg_t *leg, const char *var, const char *fmt, ...);
SWITCH_DECLARE(int) switch_dial_handle_get_peers(switch_dial_handle_t *handle, int idx, char **array, int max);
SWITCH_DECLARE(int) switch_dial_handle_get_vars(switch_dial_handle_t *handle, int idx, switch_event_t **array, int max);
SWITCH_DECLARE(switch_event_t *) switch_dial_handle_get_global_vars(switch_dial_handle_t *handle);
SWITCH_DECLARE(switch_event_t *) switch_dial_leg_get_vars(switch_dial_leg_t *leg);
SWITCH_DECLARE(int) switch_dial_handle_get_total(switch_dial_handle_t *handle);
SWITCH_DECLARE(void) switch_ivr_orig_and_bridge(switch_core_session_t *session, const char *data, switch_dial_handle_t *dh);
add switch_dial_handle_t *dh to end of args for switch_ivr_originate
2018-08-16 00:40:30 +00:00
if ( q | | alt ) {
* p = QUOTED_ESC_COMMA ;
} else {
* p = UNQUOTED_ESC_COMMA ;
}
2010-07-16 02:09:48 +00:00
}
2007-03-29 22:34:40 +00:00
FS-11346: [core] add api to pass pre-parsed values instead of dial strings to switch_ivr_originate
SWITCH_DECLARE(switch_status_t) switch_dial_handle_create(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_destroy(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_add_leg_list(switch_dial_handle_t *handle, switch_dial_leg_list_t **leg_listP);
SWITCH_DECLARE(void) switch_dial_leg_list_add_leg(switch_dial_leg_list_t *parent, const char *dial_string, switch_dial_leg_t **legP);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var(switch_dial_handle_t *handle, const char *var, const char *val);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var_printf(switch_dial_handle_t *handle, const char *var, const char *fmt, ...);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var(switch_dial_leg_t *leg, const char *var, const char *val);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var_printf(switch_dial_leg_t *leg, const char *var, const char *fmt, ...);
SWITCH_DECLARE(int) switch_dial_handle_get_peers(switch_dial_handle_t *handle, int idx, char **array, int max);
SWITCH_DECLARE(int) switch_dial_handle_get_vars(switch_dial_handle_t *handle, int idx, switch_event_t **array, int max);
SWITCH_DECLARE(switch_event_t *) switch_dial_handle_get_global_vars(switch_dial_handle_t *handle);
SWITCH_DECLARE(switch_event_t *) switch_dial_leg_get_vars(switch_dial_leg_t *leg);
SWITCH_DECLARE(int) switch_dial_handle_get_total(switch_dial_handle_t *handle);
SWITCH_DECLARE(void) switch_ivr_orig_and_bridge(switch_core_session_t *session, const char *data, switch_dial_handle_t *dh);
add switch_dial_handle_t *dh to end of args for switch_ivr_originate
2018-08-16 00:40:30 +00:00
if ( p = = end ) {
end = NULL ;
}
2008-06-05 15:24:14 +00:00
FS-11346: [core] add api to pass pre-parsed values instead of dial strings to switch_ivr_originate
SWITCH_DECLARE(switch_status_t) switch_dial_handle_create(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_destroy(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_add_leg_list(switch_dial_handle_t *handle, switch_dial_leg_list_t **leg_listP);
SWITCH_DECLARE(void) switch_dial_leg_list_add_leg(switch_dial_leg_list_t *parent, const char *dial_string, switch_dial_leg_t **legP);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var(switch_dial_handle_t *handle, const char *var, const char *val);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var_printf(switch_dial_handle_t *handle, const char *var, const char *fmt, ...);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var(switch_dial_leg_t *leg, const char *var, const char *val);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var_printf(switch_dial_leg_t *leg, const char *var, const char *fmt, ...);
SWITCH_DECLARE(int) switch_dial_handle_get_peers(switch_dial_handle_t *handle, int idx, char **array, int max);
SWITCH_DECLARE(int) switch_dial_handle_get_vars(switch_dial_handle_t *handle, int idx, switch_event_t **array, int max);
SWITCH_DECLARE(switch_event_t *) switch_dial_handle_get_global_vars(switch_dial_handle_t *handle);
SWITCH_DECLARE(switch_event_t *) switch_dial_leg_get_vars(switch_dial_leg_t *leg);
SWITCH_DECLARE(int) switch_dial_handle_get_total(switch_dial_handle_t *handle);
SWITCH_DECLARE(void) switch_ivr_orig_and_bridge(switch_core_session_t *session, const char *data, switch_dial_handle_t *dh);
add switch_dial_handle_t *dh to end of args for switch_ivr_originate
2018-08-16 00:40:30 +00:00
p + + ;
}
and_argc = switch_separate_string ( pipe_names [ r ] , ' , ' , peer_names , ( sizeof ( peer_names ) / sizeof ( peer_names [ 0 ] ) ) ) ;
} else {
and_argc = switch_dial_handle_get_peers ( dh , r , peer_names , MAX_PEERS ) ;
switch_dial_handle_get_vars ( dh , r , peer_vars , MAX_PEERS ) ;
2008-06-05 15:24:14 +00:00
}
FS-11346: [core] add api to pass pre-parsed values instead of dial strings to switch_ivr_originate
SWITCH_DECLARE(switch_status_t) switch_dial_handle_create(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_destroy(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_add_leg_list(switch_dial_handle_t *handle, switch_dial_leg_list_t **leg_listP);
SWITCH_DECLARE(void) switch_dial_leg_list_add_leg(switch_dial_leg_list_t *parent, const char *dial_string, switch_dial_leg_t **legP);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var(switch_dial_handle_t *handle, const char *var, const char *val);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var_printf(switch_dial_handle_t *handle, const char *var, const char *fmt, ...);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var(switch_dial_leg_t *leg, const char *var, const char *val);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var_printf(switch_dial_leg_t *leg, const char *var, const char *fmt, ...);
SWITCH_DECLARE(int) switch_dial_handle_get_peers(switch_dial_handle_t *handle, int idx, char **array, int max);
SWITCH_DECLARE(int) switch_dial_handle_get_vars(switch_dial_handle_t *handle, int idx, switch_event_t **array, int max);
SWITCH_DECLARE(switch_event_t *) switch_dial_handle_get_global_vars(switch_dial_handle_t *handle);
SWITCH_DECLARE(switch_event_t *) switch_dial_leg_get_vars(switch_dial_leg_t *leg);
SWITCH_DECLARE(int) switch_dial_handle_get_total(switch_dial_handle_t *handle);
SWITCH_DECLARE(void) switch_ivr_orig_and_bridge(switch_core_session_t *session, const char *data, switch_dial_handle_t *dh);
add switch_dial_handle_t *dh to end of args for switch_ivr_originate
2018-08-16 00:40:30 +00:00
2007-12-20 21:42:00 +00:00
if ( ( flags & SOF_NOBLOCK ) & & and_argc > 1 ) {
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING , " Only calling the first element in the list in this mode. \n " ) ;
2007-12-20 21:42:00 +00:00
and_argc = 1 ;
}
FS-11346: [core] add api to pass pre-parsed values instead of dial strings to switch_ivr_originate
SWITCH_DECLARE(switch_status_t) switch_dial_handle_create(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_destroy(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_add_leg_list(switch_dial_handle_t *handle, switch_dial_leg_list_t **leg_listP);
SWITCH_DECLARE(void) switch_dial_leg_list_add_leg(switch_dial_leg_list_t *parent, const char *dial_string, switch_dial_leg_t **legP);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var(switch_dial_handle_t *handle, const char *var, const char *val);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var_printf(switch_dial_handle_t *handle, const char *var, const char *fmt, ...);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var(switch_dial_leg_t *leg, const char *var, const char *val);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var_printf(switch_dial_leg_t *leg, const char *var, const char *fmt, ...);
SWITCH_DECLARE(int) switch_dial_handle_get_peers(switch_dial_handle_t *handle, int idx, char **array, int max);
SWITCH_DECLARE(int) switch_dial_handle_get_vars(switch_dial_handle_t *handle, int idx, switch_event_t **array, int max);
SWITCH_DECLARE(switch_event_t *) switch_dial_handle_get_global_vars(switch_dial_handle_t *handle);
SWITCH_DECLARE(switch_event_t *) switch_dial_leg_get_vars(switch_dial_leg_t *leg);
SWITCH_DECLARE(int) switch_dial_handle_get_total(switch_dial_handle_t *handle);
SWITCH_DECLARE(void) switch_ivr_orig_and_bridge(switch_core_session_t *session, const char *data, switch_dial_handle_t *dh);
add switch_dial_handle_t *dh to end of args for switch_ivr_originate
2018-08-16 00:40:30 +00:00
2017-07-11 22:25:48 +00:00
for ( i = 0 ; i < and_argc ; i + + ) {
2009-03-14 14:30:37 +00:00
const char * current_variable ;
2012-10-29 16:46:17 +00:00
switch_event_t * local_var_event = NULL , * originate_var_event = NULL ;
2010-06-11 16:08:51 +00:00
2009-03-16 19:53:17 +00:00
end = NULL ;
2017-01-06 07:10:15 +00:00
2019-10-31 20:05:40 +00:00
if ( ! ( chan_type = peer_names [ i ] ) ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Empty dial string \n " ) ;
switch_goto_status ( SWITCH_STATUS_FALSE , done ) ;
}
2017-01-06 07:10:15 +00:00
2011-04-14 22:44:22 +00:00
/* strip leading spaces */
2007-12-10 21:55:46 +00:00
while ( chan_type & & * chan_type & & * chan_type = = ' ' ) {
chan_type + + ;
}
2017-01-06 07:10:15 +00:00
2011-04-14 22:44:22 +00:00
/* extract channel variables, allowing multiple sets of braces */
2017-01-06 07:10:15 +00:00
2011-04-14 22:44:22 +00:00
if ( * chan_type = = ' [ ' ) {
switch_event_create_plain ( & local_var_event , SWITCH_EVENT_CHANNEL_DATA ) ;
2012-04-10 21:17:16 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Parsing session specific variables \n " ) ;
2011-04-14 22:44:22 +00:00
}
2007-12-10 21:55:46 +00:00
2011-04-14 22:44:22 +00:00
while ( * chan_type = = ' [ ' ) {
char * parsed = NULL ;
2017-01-06 07:10:15 +00:00
char * bend = switch_find_end_paren ( chan_type , ' [ ' , ' ] ' ) ;
2012-07-21 00:15:04 +00:00
for ( p = chan_type + 1 ; p & & p < bend & & * p ; p + + ) {
2011-04-14 22:44:22 +00:00
if ( * p = = QUOTED_ESC_COMMA ) {
* p = ' , ' ;
}
2017-01-06 07:10:15 +00:00
}
if ( switch_event_create_brackets ( chan_type , ' [ ' , ' ] ' , UNQUOTED_ESC_COMMA ,
2011-04-14 22:44:22 +00:00
& local_var_event , & parsed , SWITCH_FALSE ) ! = SWITCH_STATUS_SUCCESS | | ! parsed ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Parse Error! \n " ) ;
switch_goto_status ( SWITCH_STATUS_GENERR , done ) ;
2010-07-01 01:09:06 +00:00
}
2017-01-06 07:10:15 +00:00
2012-07-21 00:15:04 +00:00
if ( chan_type = = parsed ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Parse Error! \n " ) ;
2017-01-06 07:10:15 +00:00
switch_goto_status ( SWITCH_STATUS_GENERR , done ) ;
2012-07-21 00:15:04 +00:00
} else {
chan_type = parsed ;
}
2010-07-01 01:09:06 +00:00
}
2017-01-06 07:10:15 +00:00
FS-11346: [core] add api to pass pre-parsed values instead of dial strings to switch_ivr_originate
SWITCH_DECLARE(switch_status_t) switch_dial_handle_create(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_destroy(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_add_leg_list(switch_dial_handle_t *handle, switch_dial_leg_list_t **leg_listP);
SWITCH_DECLARE(void) switch_dial_leg_list_add_leg(switch_dial_leg_list_t *parent, const char *dial_string, switch_dial_leg_t **legP);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var(switch_dial_handle_t *handle, const char *var, const char *val);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var_printf(switch_dial_handle_t *handle, const char *var, const char *fmt, ...);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var(switch_dial_leg_t *leg, const char *var, const char *val);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var_printf(switch_dial_leg_t *leg, const char *var, const char *fmt, ...);
SWITCH_DECLARE(int) switch_dial_handle_get_peers(switch_dial_handle_t *handle, int idx, char **array, int max);
SWITCH_DECLARE(int) switch_dial_handle_get_vars(switch_dial_handle_t *handle, int idx, switch_event_t **array, int max);
SWITCH_DECLARE(switch_event_t *) switch_dial_handle_get_global_vars(switch_dial_handle_t *handle);
SWITCH_DECLARE(switch_event_t *) switch_dial_leg_get_vars(switch_dial_leg_t *leg);
SWITCH_DECLARE(int) switch_dial_handle_get_total(switch_dial_handle_t *handle);
SWITCH_DECLARE(void) switch_ivr_orig_and_bridge(switch_core_session_t *session, const char *data, switch_dial_handle_t *dh);
add switch_dial_handle_t *dh to end of args for switch_ivr_originate
2018-08-16 00:40:30 +00:00
if ( peer_vars [ i ] ) {
if ( local_var_event ) {
switch_event_merge ( local_var_event , peer_vars [ i ] ) ;
} else {
switch_event_dup ( & local_var_event , peer_vars [ i ] ) ;
}
2017-01-06 07:10:15 +00:00
FS-11346: [core] add api to pass pre-parsed values instead of dial strings to switch_ivr_originate
SWITCH_DECLARE(switch_status_t) switch_dial_handle_create(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_destroy(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_add_leg_list(switch_dial_handle_t *handle, switch_dial_leg_list_t **leg_listP);
SWITCH_DECLARE(void) switch_dial_leg_list_add_leg(switch_dial_leg_list_t *parent, const char *dial_string, switch_dial_leg_t **legP);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var(switch_dial_handle_t *handle, const char *var, const char *val);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var_printf(switch_dial_handle_t *handle, const char *var, const char *fmt, ...);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var(switch_dial_leg_t *leg, const char *var, const char *val);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var_printf(switch_dial_leg_t *leg, const char *var, const char *fmt, ...);
SWITCH_DECLARE(int) switch_dial_handle_get_peers(switch_dial_handle_t *handle, int idx, char **array, int max);
SWITCH_DECLARE(int) switch_dial_handle_get_vars(switch_dial_handle_t *handle, int idx, switch_event_t **array, int max);
SWITCH_DECLARE(switch_event_t *) switch_dial_handle_get_global_vars(switch_dial_handle_t *handle);
SWITCH_DECLARE(switch_event_t *) switch_dial_leg_get_vars(switch_dial_leg_t *leg);
SWITCH_DECLARE(int) switch_dial_handle_get_total(switch_dial_handle_t *handle);
SWITCH_DECLARE(void) switch_ivr_orig_and_bridge(switch_core_session_t *session, const char *data, switch_dial_handle_t *dh);
add switch_dial_handle_t *dh to end of args for switch_ivr_originate
2018-08-16 00:40:30 +00:00
if ( dh & & local_var_event & & switch_event_serialize ( local_var_event , & event_string , SWITCH_FALSE ) = = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " Local Vars for %s \n ====================== \n %s \n " ,
peer_names [ i ] , event_string ) ;
switch_safe_free ( event_string ) ;
}
}
2011-04-14 22:44:22 +00:00
/* strip leading spaces (again) */
while ( chan_type & & * chan_type & & * chan_type = = ' ' ) {
chan_type + + ;
}
2017-01-06 07:10:15 +00:00
2007-03-29 22:34:40 +00:00
if ( ( chan_data = strchr ( chan_type , ' / ' ) ) ! = 0 ) {
* chan_data = ' \0 ' ;
chan_data + + ;
}
2009-01-19 17:54:54 +00:00
if ( oglobals . session ) {
2007-03-29 22:34:40 +00:00
if ( ! switch_channel_ready ( caller_channel ) ) {
status = SWITCH_STATUS_FALSE ;
2020-10-04 22:49:08 +00:00
if ( local_var_event ) switch_event_destroy ( & local_var_event ) ;
2007-03-29 22:34:40 +00:00
goto done ;
}
2017-01-06 07:10:15 +00:00
2010-05-03 17:13:37 +00:00
if ( ( caller_caller_profile = oglobals . caller_profile_override ) ) {
new_profile = switch_caller_profile_dup ( oglobals . pool , caller_caller_profile ) ;
} else {
new_profile = switch_caller_profile_new ( oglobals . pool ,
NULL ,
NULL ,
2013-10-17 16:18:01 +00:00
cid_name_override , cid_num_override , NULL , ani_override , aniii_override , NULL , __FILE__ , NULL , chan_data ) ;
2010-05-03 17:13:37 +00:00
}
2007-03-29 22:34:40 +00:00
2007-09-29 01:06:08 +00:00
new_profile - > uuid = SWITCH_BLANK_STRING ;
new_profile - > chan_name = SWITCH_BLANK_STRING ;
new_profile - > destination_number = switch_core_strdup ( new_profile - > pool , chan_data ) ;
2010-02-06 03:38:24 +00:00
2013-10-17 16:18:01 +00:00
if ( ani_override ) {
new_profile - > ani = switch_core_strdup ( new_profile - > pool , ani_override ) ;
}
if ( aniii_override ) {
new_profile - > aniii = switch_core_strdup ( new_profile - > pool , aniii_override ) ;
}
2007-08-28 21:55:30 +00:00
if ( cid_name_override ) {
2007-09-29 01:06:08 +00:00
new_profile - > caller_id_name = switch_core_strdup ( new_profile - > pool , cid_name_override ) ;
2007-03-29 22:34:40 +00:00
}
2007-08-28 21:55:30 +00:00
if ( cid_num_override ) {
2007-09-29 01:06:08 +00:00
new_profile - > caller_id_number = switch_core_strdup ( new_profile - > pool , cid_num_override ) ;
2007-03-29 22:34:40 +00:00
}
} else {
2010-05-03 17:13:37 +00:00
if ( oglobals . caller_profile_override ) {
2010-07-06 15:32:04 +00:00
new_profile = switch_caller_profile_dup ( oglobals . pool , oglobals . caller_profile_override ) ;
2007-12-22 01:00:10 +00:00
new_profile - > destination_number = switch_core_strdup ( new_profile - > pool , switch_str_nil ( chan_data ) ) ;
2007-09-29 01:06:08 +00:00
new_profile - > uuid = SWITCH_BLANK_STRING ;
new_profile - > chan_name = SWITCH_BLANK_STRING ;
2007-03-29 22:34:40 +00:00
} else {
2007-08-28 21:55:30 +00:00
if ( ! cid_name_override ) {
2010-01-23 20:35:40 +00:00
cid_name_override = SWITCH_DEFAULT_CLID_NAME ;
2007-08-28 21:55:30 +00:00
}
if ( ! cid_num_override ) {
2012-09-17 19:26:00 +00:00
cid_num_override = SWITCH_DEFAULT_CLID_NUMBER ;
2007-08-28 21:55:30 +00:00
}
2010-05-03 17:13:37 +00:00
new_profile = switch_caller_profile_new ( oglobals . pool ,
2007-08-28 22:44:02 +00:00
NULL ,
NULL ,
2013-10-17 16:18:01 +00:00
cid_name_override , cid_num_override , NULL , ani_override , aniii_override , NULL , __FILE__ , NULL , chan_data ) ;
2007-03-29 22:34:40 +00:00
}
}
2008-05-27 04:30:03 +00:00
2011-08-25 13:46:40 +00:00
if ( zstr ( new_profile - > destination_number ) ) {
2011-08-29 15:31:41 +00:00
new_profile - > destination_number = switch_core_strdup ( new_profile - > pool , " service " ) ;
2011-08-25 13:46:40 +00:00
}
2010-12-21 02:19:36 +00:00
new_profile - > callee_id_name = switch_core_strdup ( new_profile - > pool , " Outbound Call " ) ;
2011-08-04 14:50:23 +00:00
new_profile - > callee_id_number = switch_sanitize_number ( switch_core_strdup ( new_profile - > pool , new_profile - > destination_number ) ) ;
2010-12-21 02:19:36 +00:00
2020-05-07 17:04:54 +00:00
oglobals . originate_status [ i ] . caller_profile = NULL ;
oglobals . originate_status [ i ] . peer_channel = NULL ;
oglobals . originate_status [ i ] . peer_session = NULL ;
2015-06-19 06:34:31 +00:00
2007-04-16 19:32:08 +00:00
new_session = NULL ;
2008-05-27 04:30:03 +00:00
2007-12-20 21:42:00 +00:00
if ( and_argc > 1 | | or_argc > 1 ) {
myflags | = SOF_FORKED_DIAL ;
2017-01-06 07:10:15 +00:00
}
2010-08-26 17:19:49 +00:00
if ( var_event ) {
2008-01-07 21:14:24 +00:00
const char * vvar ;
if ( ( vvar = switch_event_get_header ( var_event , " forked_dial " ) ) & & switch_true ( vvar ) ) {
myflags | = SOF_FORKED_DIAL ;
}
2010-08-26 17:19:49 +00:00
if ( ( vvar = switch_event_get_header ( var_event , " no_throttle_limits " ) ) & & switch_true ( vvar ) ) {
myflags | = SOF_NO_LIMITS ;
}
2007-12-20 21:42:00 +00:00
}
2010-02-06 03:38:24 +00:00
2017-01-06 07:10:15 +00:00
2011-04-14 22:44:22 +00:00
/* Valid in both {} and [] with [] taking precedence */
2009-03-14 14:30:37 +00:00
2017-01-06 07:10:15 +00:00
/* make a special var event with mixture of the {} and the [] vars to pass down as global vars to the outgoing channel
2011-04-14 22:44:22 +00:00
so if something like the user channel does another originate our options will be passed down properly
*/
2017-01-06 07:10:15 +00:00
2011-04-14 22:44:22 +00:00
switch_event_dup ( & originate_var_event , var_event ) ;
2009-03-14 14:30:37 +00:00
2011-04-14 22:44:22 +00:00
if ( local_var_event ) {
switch_event_merge ( originate_var_event , local_var_event ) ;
2009-03-14 14:30:37 +00:00
}
2010-02-06 03:38:24 +00:00
2013-10-17 16:18:01 +00:00
if ( ( current_variable = switch_event_get_header ( originate_var_event , " origination_ani " ) ) ) {
new_profile - > ani = switch_core_strdup ( new_profile - > pool , current_variable ) ;
myflags | = SOF_NO_EFFECTIVE_ANI ;
}
if ( ( current_variable = switch_event_get_header ( originate_var_event , " origination_aniii " ) ) ) {
new_profile - > aniii = switch_core_strdup ( new_profile - > pool , current_variable ) ;
myflags | = SOF_NO_EFFECTIVE_ANIII ;
}
2011-04-14 22:44:22 +00:00
if ( ( current_variable = switch_event_get_header ( originate_var_event , " origination_caller_id_number " ) ) ) {
2009-03-14 14:30:37 +00:00
new_profile - > caller_id_number = switch_core_strdup ( new_profile - > pool , current_variable ) ;
myflags | = SOF_NO_EFFECTIVE_CID_NUM ;
2008-06-06 18:24:35 +00:00
}
2011-04-14 22:44:22 +00:00
if ( ( current_variable = switch_event_get_header ( originate_var_event , " origination_caller_id_name " ) ) ) {
2009-03-17 16:23:32 +00:00
new_profile - > caller_id_name = switch_core_strdup ( new_profile - > pool , current_variable ) ;
2009-03-14 14:30:37 +00:00
myflags | = SOF_NO_EFFECTIVE_CID_NAME ;
}
2010-02-06 03:38:24 +00:00
2011-04-14 22:44:22 +00:00
if ( ( current_variable = switch_event_get_header ( originate_var_event , " origination_privacy " ) ) ) {
2009-03-10 13:16:14 +00:00
new_profile - > flags = SWITCH_CPF_NONE ;
2010-02-06 03:38:24 +00:00
2009-03-14 14:30:37 +00:00
if ( switch_stristr ( " screen " , current_variable ) ) {
2009-03-10 13:16:14 +00:00
switch_set_flag ( new_profile , SWITCH_CPF_SCREEN ) ;
}
2009-03-14 14:30:37 +00:00
if ( switch_stristr ( " hide_name " , current_variable ) ) {
2009-03-10 13:16:14 +00:00
switch_set_flag ( new_profile , SWITCH_CPF_HIDE_NAME ) ;
}
2009-03-14 14:30:37 +00:00
if ( switch_stristr ( " hide_number " , current_variable ) ) {
2009-03-10 13:16:14 +00:00
switch_set_flag ( new_profile , SWITCH_CPF_HIDE_NUMBER ) ;
}
}
2017-01-06 07:10:15 +00:00
2009-03-14 14:30:37 +00:00
switch_event_add_header_string ( var_event , SWITCH_STACK_BOTTOM , " originate_early_media " , oglobals . early_ok ? " true " : " false " ) ;
2010-06-11 16:08:51 +00:00
2011-01-13 00:06:01 +00:00
if ( caller_channel & & switch_true ( switch_channel_get_variable ( caller_channel , " push_channel_name " ) ) ) {
char * new_name = switch_core_session_sprintf ( session , " %s__B " , switch_channel_get_name ( caller_channel ) ) ;
switch_event_add_header_string ( var_event , SWITCH_STACK_BOTTOM , " origination_channel_name " , new_name ) ;
new_name = switch_core_session_sprintf ( session , " _%s " , switch_channel_get_name ( caller_channel ) ) ;
2011-01-13 01:34:19 +00:00
switch_event_add_header_string ( var_event , SWITCH_STACK_BOTTOM , " sip_h_X-FS-Channel-Name " , new_name ) ;
2011-01-13 00:06:01 +00:00
}
2017-01-06 07:10:15 +00:00
2012-03-28 18:41:48 +00:00
reason = switch_core_session_outgoing_channel ( oglobals . session , originate_var_event , chan_type ,
2010-06-11 16:08:51 +00:00
new_profile , & new_session , NULL , myflags , cancel_cause ) ;
switch_event_destroy ( & originate_var_event ) ;
if ( reason ! = SWITCH_CAUSE_SUCCESS ) {
2011-06-06 17:48:34 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_NOTICE , " Cannot create outgoing channel of type [%s] cause: [%s] \n " ,
2008-10-09 00:38:59 +00:00
chan_type , switch_channel_cause2str ( reason ) ) ;
2010-06-11 16:08:51 +00:00
if ( local_var_event ) switch_event_destroy ( & local_var_event ) ;
2017-01-06 07:10:15 +00:00
2010-10-25 18:03:06 +00:00
if ( fail_on_single_reject_var ) {
const char * cause_str = switch_channel_cause2str ( reason ) ;
2011-11-09 16:07:54 +00:00
int neg = * fail_on_single_reject_var = = ' ! ' ;
int pos = ! ! switch_stristr ( cause_str , fail_on_single_reject_var ) ;
if ( neg ) {
pos = ! pos ;
}
2010-10-25 18:03:06 +00:00
check_reject = 0 ;
2011-11-09 16:07:54 +00:00
if ( fail_on_single_reject = = 1 | | pos ) {
2010-10-26 18:43:21 +00:00
force_reason = reason ;
2011-05-18 21:10:46 +00:00
status = SWITCH_STATUS_FALSE ;
2010-10-25 18:03:06 +00:00
goto outer_for ;
}
}
2007-03-29 22:34:40 +00:00
continue ;
}
2009-01-09 20:34:01 +00:00
if ( switch_core_session_read_lock ( new_session ) ! = SWITCH_STATUS_SUCCESS ) {
status = SWITCH_STATUS_FALSE ;
2010-06-11 16:08:51 +00:00
if ( local_var_event ) switch_event_destroy ( & local_var_event ) ;
2009-01-09 20:34:01 +00:00
goto done ;
}
2007-03-29 22:34:40 +00:00
2020-05-07 17:04:54 +00:00
oglobals . originate_status [ i ] . peer_channel = switch_core_session_get_channel ( new_session ) ;
oglobals . originate_status [ i ] . caller_profile = switch_channel_get_caller_profile ( oglobals . originate_status [ i ] . peer_channel ) ;
oglobals . originate_status [ i ] . peer_session = new_session ;
2010-05-03 17:13:37 +00:00
2020-05-07 17:04:54 +00:00
switch_channel_set_flag ( oglobals . originate_status [ i ] . peer_channel , CF_ORIGINATING ) ;
2017-01-06 07:10:15 +00:00
2011-08-04 06:04:21 +00:00
if ( caller_channel ) {
2020-05-07 17:04:54 +00:00
switch_channel_set_variable ( oglobals . originate_status [ i ] . peer_channel , " call_uuid " , switch_channel_get_variable ( caller_channel , " call_uuid " ) ) ;
2011-08-04 06:04:21 +00:00
}
2017-01-06 07:10:15 +00:00
2008-05-27 04:30:03 +00:00
2013-06-05 16:19:44 +00:00
if ( local_var_event ) {
const char * device_id = switch_event_get_header ( local_var_event , " device_id " ) ;
2020-05-07 17:04:54 +00:00
switch_channel_set_profile_var ( oglobals . originate_status [ i ] . peer_channel , " device_id " , device_id ) ;
2013-06-05 16:19:44 +00:00
}
2009-06-18 16:35:41 +00:00
if ( ( lc = switch_event_get_header ( var_event , " local_var_clobber " ) ) ) {
local_clobber = switch_true ( lc ) ;
}
2020-05-07 17:04:54 +00:00
if ( switch_channel_test_flag ( oglobals . originate_status [ i ] . peer_channel , CF_NO_PRESENCE ) ) {
2012-07-19 22:39:12 +00:00
if ( var_event ) {
switch_event_del_header ( var_event , " presence_id " ) ;
}
if ( local_var_event ) {
switch_event_del_header ( local_var_event , " presence_id " ) ;
}
}
2009-06-18 19:47:29 +00:00
if ( local_clobber ) {
2009-06-18 16:35:41 +00:00
if ( var_event ) {
switch_event_header_t * header ;
/* install the vars from the {} params */
for ( header = var_event - > headers ; header ; header = header - > next ) {
2020-05-07 17:04:54 +00:00
switch_channel_set_variable_var_check ( oglobals . originate_status [ i ] . peer_channel , header - > name , header - > value , oglobals . check_vars ) ;
2009-06-18 16:35:41 +00:00
}
}
}
2010-06-11 16:08:51 +00:00
/* copy local originate vars to the channel */
if ( local_var_event ) {
switch_event_header_t * header ;
for ( header = local_var_event - > headers ; header ; header = header - > next ) {
2020-05-07 17:04:54 +00:00
switch_channel_set_variable_var_check ( oglobals . originate_status [ i ] . peer_channel , header - > name , header - > value , oglobals . check_vars ) ;
2007-12-10 21:55:46 +00:00
}
2010-06-11 16:08:51 +00:00
switch_event_destroy ( & local_var_event ) ;
2007-12-10 21:55:46 +00:00
}
2008-05-27 04:30:03 +00:00
2009-06-18 19:47:29 +00:00
if ( ! local_clobber ) {
2009-06-18 16:35:41 +00:00
if ( var_event ) {
switch_event_header_t * header ;
/* install the vars from the {} params */
for ( header = var_event - > headers ; header ; header = header - > next ) {
2020-05-07 17:04:54 +00:00
switch_channel_set_variable_var_check ( oglobals . originate_status [ i ] . peer_channel , header - > name , header - > value , oglobals . check_vars ) ;
2009-06-18 16:35:41 +00:00
}
2008-04-14 17:30:45 +00:00
}
}
2020-05-07 17:04:54 +00:00
if ( oglobals . originate_status [ i ] . peer_channel ) {
2008-10-09 00:38:59 +00:00
const char * vvar ;
2010-01-16 00:41:10 +00:00
2020-05-07 17:04:54 +00:00
if ( switch_true ( switch_channel_get_variable ( oglobals . originate_status [ i ] . peer_channel , " leg_required " ) ) ) {
oglobals . originate_status [ i ] . tagged = 1 ;
2010-01-16 00:41:10 +00:00
}
2017-01-06 07:10:15 +00:00
2020-05-07 17:04:54 +00:00
if ( ( vvar = switch_channel_get_variable ( oglobals . originate_status [ i ] . peer_channel , " origination_channel_name " ) ) ) {
switch_channel_set_name ( oglobals . originate_status [ i ] . peer_channel , vvar ) ;
2011-01-12 23:48:49 +00:00
}
2020-05-07 17:04:54 +00:00
if ( ( vvar = switch_channel_get_variable ( oglobals . originate_status [ i ] . peer_channel , " origination_callee_id_name " ) ) ) {
switch_channel_set_profile_var ( oglobals . originate_status [ i ] . peer_channel , " callee_id_name " , vvar ) ;
2009-10-19 19:58:23 +00:00
}
2020-05-07 17:04:54 +00:00
if ( ( vvar = switch_channel_get_variable ( oglobals . originate_status [ i ] . peer_channel , " origination_callee_id_number " ) ) ) {
switch_channel_set_profile_var ( oglobals . originate_status [ i ] . peer_channel , " callee_id_number " , vvar ) ;
2009-10-19 19:58:23 +00:00
}
2020-05-07 17:04:54 +00:00
if ( ( vvar = switch_channel_get_variable ( oglobals . originate_status [ i ] . peer_channel , " leg_timeout " ) ) ) {
2008-10-09 00:38:59 +00:00
int val = atoi ( vvar ) ;
2017-01-06 07:10:15 +00:00
2008-10-09 00:38:59 +00:00
if ( val > 0 ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " %s Setting leg timeout to %d \n " ,
2020-05-07 17:04:54 +00:00
switch_channel_get_name ( oglobals . originate_status [ i ] . peer_channel ) , val ) ;
oglobals . originate_status [ i ] . per_channel_timelimit_sec = ( uint32_t ) val ;
2008-10-09 00:38:59 +00:00
}
}
2017-01-06 07:10:15 +00:00
2020-05-07 17:04:54 +00:00
if ( ( vvar = switch_channel_get_variable ( oglobals . originate_status [ i ] . peer_channel , " leg_progress_timeout " ) ) ) {
2008-10-09 00:38:59 +00:00
int val = atoi ( vvar ) ;
if ( val > 0 ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " %s Setting leg progress timeout to %d \n " ,
2020-05-07 17:04:54 +00:00
switch_channel_get_name ( oglobals . originate_status [ i ] . peer_channel ) , val ) ;
oglobals . originate_status [ i ] . per_channel_progress_timelimit_sec = ( uint32_t ) val ;
2008-10-09 00:38:59 +00:00
}
}
2009-03-04 04:19:33 +00:00
2020-05-07 17:04:54 +00:00
if ( ( vvar = switch_channel_get_variable ( oglobals . originate_status [ i ] . peer_channel , " leg_delay_start " ) ) ) {
2009-03-04 04:19:33 +00:00
int val = atoi ( vvar ) ;
if ( val > 0 ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " %s Setting leg delay start to %d \n " ,
2020-05-07 17:04:54 +00:00
switch_channel_get_name ( oglobals . originate_status [ i ] . peer_channel ) , val ) ;
oglobals . originate_status [ i ] . per_channel_delay_start = ( uint32_t ) val ;
2009-09-30 23:28:49 +00:00
2020-05-07 17:04:54 +00:00
if ( oglobals . originate_status [ i ] . per_channel_progress_timelimit_sec ! = 0 ) {
oglobals . originate_status [ i ] . per_channel_progress_timelimit_sec + = oglobals . originate_status [ i ] . per_channel_delay_start ;
2009-09-30 23:28:49 +00:00
}
2020-05-07 17:04:54 +00:00
if ( oglobals . originate_status [ i ] . per_channel_timelimit_sec ! = 0 ) {
oglobals . originate_status [ i ] . per_channel_timelimit_sec + = oglobals . originate_status [ i ] . per_channel_delay_start ;
2009-09-30 23:28:49 +00:00
}
2009-03-04 04:19:33 +00:00
}
}
2011-01-20 19:52:00 +00:00
2014-01-22 17:40:29 +00:00
if ( ! zstr ( ent_aleg_uuid ) ) {
l_session = switch_core_session_locate ( ent_aleg_uuid ) ;
a_session = l_session ;
}
if ( a_session ) {
switch_channel_t * channel = switch_core_session_get_channel ( a_session ) ;
2017-01-06 07:10:15 +00:00
char * val =
switch_core_session_sprintf ( a_session , " %s;%s;%s " ,
2020-05-07 17:04:54 +00:00
switch_core_session_get_uuid ( oglobals . originate_status [ i ] . peer_session ) ,
switch_str_nil ( switch_channel_get_variable ( oglobals . originate_status [ i ] . peer_channel , " callee_id_name " ) ) ,
switch_str_nil ( switch_channel_get_variable ( oglobals . originate_status [ i ] . peer_channel , " callee_id_number " ) ) ) ;
2017-01-06 07:10:15 +00:00
2012-10-18 17:22:35 +00:00
2020-05-07 17:04:54 +00:00
switch_channel_set_variable ( oglobals . originate_status [ i ] . peer_channel , " originating_leg_uuid " , switch_core_session_get_uuid ( a_session ) ) ;
2017-01-06 07:10:15 +00:00
2012-10-18 17:22:35 +00:00
switch_channel_add_variable_var_check ( channel , " originated_legs " , val , SWITCH_FALSE , SWITCH_STACK_PUSH ) ;
2017-01-06 07:10:15 +00:00
2011-01-20 19:52:00 +00:00
}
2014-01-22 17:40:29 +00:00
if ( l_session ) {
switch_core_session_rwunlock ( l_session ) ;
l_session = NULL ;
}
2017-01-06 07:10:15 +00:00
2020-05-07 17:04:54 +00:00
switch_channel_execute_on ( oglobals . originate_status [ i ] . peer_channel , SWITCH_CHANNEL_EXECUTE_ON_ORIGINATE_VARIABLE ) ;
switch_channel_api_on ( oglobals . originate_status [ i ] . peer_channel , SWITCH_CHANNEL_API_ON_ORIGINATE_VARIABLE ) ;
2008-10-09 00:38:59 +00:00
}
2017-01-06 07:10:15 +00:00
2007-03-29 22:34:40 +00:00
if ( table ) {
2020-05-07 17:04:54 +00:00
switch_channel_add_state_handler ( oglobals . originate_status [ i ] . peer_channel , table ) ;
2007-03-29 22:34:40 +00:00
}
2017-01-06 07:10:15 +00:00
2012-08-30 20:14:33 +00:00
if ( oglobals . monitor_early_media_ring | | oglobals . monitor_early_media_fail | | oglobals . ignore_early_media = = 4 ) {
2020-05-07 17:04:54 +00:00
switch_channel_set_flag ( oglobals . originate_status [ i ] . peer_channel , CF_CONSUME_ON_ORIGINATE ) ;
2010-06-02 22:31:08 +00:00
}
2007-03-29 22:34:40 +00:00
2020-05-07 17:04:54 +00:00
switch_channel_add_state_handler ( oglobals . originate_status [ i ] . peer_channel , & originate_state_handlers ) ;
2009-10-27 15:59:25 +00:00
2020-05-07 17:04:54 +00:00
if ( ( flags & SOF_NOBLOCK ) & & oglobals . originate_status [ i ] . peer_session ) {
2007-12-20 21:42:00 +00:00
status = SWITCH_STATUS_SUCCESS ;
2020-05-07 17:04:54 +00:00
* bleg = oglobals . originate_status [ i ] . peer_session ;
2007-12-20 21:42:00 +00:00
* cause = SWITCH_CAUSE_SUCCESS ;
goto outer_for ;
}
2017-01-06 07:10:15 +00:00
2020-05-07 17:04:54 +00:00
if ( ! switch_core_session_running ( oglobals . originate_status [ i ] . peer_session ) ) {
if ( oglobals . originate_status [ i ] . per_channel_delay_start ) {
switch_channel_set_flag ( oglobals . originate_status [ i ] . peer_channel , CF_BLOCK_STATE ) ;
2009-03-04 04:19:33 +00:00
}
2020-05-07 17:04:54 +00:00
switch_core_session_thread_launch ( oglobals . originate_status [ i ] . peer_session ) ;
2007-03-29 22:34:40 +00:00
}
2008-05-27 04:30:03 +00:00
}
2007-03-29 22:34:40 +00:00
2009-01-25 21:23:07 +00:00
switch_epoch_time_now ( & start ) ;
2007-03-29 22:34:40 +00:00
for ( ; ; ) {
uint32_t valid_channels = 0 ;
2017-07-11 22:25:48 +00:00
for ( i = 0 ; i < and_argc ; i + + ) {
2007-03-29 22:34:40 +00:00
int state ;
2008-10-09 00:38:59 +00:00
time_t elapsed ;
2007-03-29 22:34:40 +00:00
2020-05-07 17:04:54 +00:00
if ( ! oglobals . originate_status [ i ] . peer_channel ) {
2007-03-29 22:34:40 +00:00
continue ;
}
2008-03-25 22:05:52 +00:00
2020-05-07 17:04:54 +00:00
state = switch_channel_get_state ( oglobals . originate_status [ i ] . peer_channel ) ;
2007-03-29 22:34:40 +00:00
2008-03-25 22:05:52 +00:00
if ( state < CS_HANGUP ) {
valid_channels + + ;
} else {
continue ;
}
2008-05-05 15:30:55 +00:00
if ( state > = CS_ROUTING ) {
2007-03-29 22:34:40 +00:00
goto endfor1 ;
}
if ( caller_channel & & ! switch_channel_ready ( caller_channel ) ) {
goto notready ;
}
2010-02-06 03:38:24 +00:00
2009-01-25 21:23:07 +00:00
elapsed = switch_epoch_time_now ( NULL ) - start ;
2010-02-06 03:38:24 +00:00
2008-10-09 00:38:59 +00:00
if ( elapsed > ( time_t ) timelimit_sec ) {
2007-03-29 22:34:40 +00:00
to + + ;
2009-01-19 17:54:54 +00:00
oglobals . idx = IDX_TIMEOUT ;
2007-03-29 22:34:40 +00:00
goto notready ;
}
2010-02-06 03:38:24 +00:00
if ( ! oglobals . sent_ring & & ! oglobals . ignore_ring_ready & &
2009-10-19 23:19:37 +00:00
! oglobals . progress & & ( progress_timelimit_sec & & elapsed > ( time_t ) progress_timelimit_sec ) ) {
2008-06-23 22:07:22 +00:00
to + + ;
2009-01-19 17:54:54 +00:00
oglobals . idx = IDX_TIMEOUT ;
2010-01-17 00:26:29 +00:00
if ( force_reason = = SWITCH_CAUSE_NONE ) {
force_reason = SWITCH_CAUSE_PROGRESS_TIMEOUT ;
}
2008-06-23 22:07:22 +00:00
goto notready ;
}
2010-02-06 03:38:24 +00:00
2009-02-20 19:51:34 +00:00
switch_cond_next ( ) ;
2008-03-25 22:05:52 +00:00
}
2008-05-27 04:30:03 +00:00
2020-05-07 17:04:54 +00:00
check_per_channel_timeouts ( & oglobals , and_argc , start , & force_reason ) ;
2008-10-09 00:38:59 +00:00
2007-03-29 22:34:40 +00:00
if ( valid_channels = = 0 ) {
status = SWITCH_STATUS_GENERR ;
goto done ;
}
}
2008-03-25 22:05:52 +00:00
2010-02-06 03:38:24 +00:00
endfor1 :
2007-03-29 22:34:40 +00:00
2008-07-18 19:29:29 +00:00
if ( caller_channel ) {
2010-02-06 03:38:24 +00:00
if ( 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_channel_test_flag ( caller_channel , CF_DISABLE_RINGBACK ) ) {
2008-07-18 19:29:29 +00:00
ringback_data = NULL ;
}
}
2007-03-29 22:34:40 +00:00
2009-09-30 20:15:00 +00:00
#if 0
/* changing behaviour ignore_early_media=true must also be explicitly set for previous behaviour */
2007-03-29 22:34:40 +00:00
if ( ringback_data ) {
2009-01-19 17:54:54 +00:00
oglobals . early_ok = 0 ;
2007-03-29 22:34:40 +00:00
}
2009-09-30 20:15:00 +00:00
# endif
2009-10-07 04:30:19 +00:00
2009-10-29 05:47:17 +00:00
if ( ringback_data ) {
oglobals . sending_ringback = 1 ;
} else {
oglobals . ringback_ok = 0 ;
}
2009-12-08 17:22:42 +00:00
2009-12-08 20:19:58 +00:00
if ( caller_channel ) {
soft_holding = switch_channel_get_variable ( caller_channel , SWITCH_SOFT_HOLDING_UUID_VARIABLE ) ;
}
2009-12-08 17:22:42 +00:00
2009-11-20 02:17:08 +00:00
while ( ( ! caller_channel | | switch_channel_ready ( caller_channel ) | | switch_channel_test_flag ( caller_channel , CF_XFER_ZOMBIE ) ) & &
2020-01-06 12:25:44 +00:00
check_channel_status ( & oglobals , and_argc , & force_reason , start ) ) {
2009-01-25 21:23:07 +00:00
time_t elapsed = switch_epoch_time_now ( NULL ) - start ;
2010-04-28 17:59:29 +00:00
read_packet = 0 ;
2010-02-06 03:38:24 +00:00
2009-11-20 02:17:08 +00:00
if ( cancel_cause & & * cancel_cause > 0 ) {
2010-01-17 00:26:29 +00:00
if ( force_reason = = SWITCH_CAUSE_NONE ) {
force_reason = * cancel_cause ;
}
2009-11-20 02:17:08 +00:00
oglobals . idx = IDX_CANCEL ;
goto notready ;
}
2020-05-07 17:04:54 +00:00
check_per_channel_timeouts ( & oglobals , and_argc , start , & force_reason ) ;
2008-10-09 00:38:59 +00:00
2009-10-12 22:23:55 +00:00
if ( oglobals . session ) {
2009-01-19 17:54:54 +00:00
switch_ivr_parse_all_events ( oglobals . session ) ;
2008-12-08 17:08:26 +00:00
}
2009-01-19 17:54:54 +00:00
if ( ! oglobals . sent_ring & & ! oglobals . progress & & ( progress_timelimit_sec & & elapsed > ( time_t ) progress_timelimit_sec ) ) {
oglobals . idx = IDX_TIMEOUT ;
2010-01-17 00:26:29 +00:00
if ( force_reason = = SWITCH_CAUSE_NONE ) {
force_reason = SWITCH_CAUSE_PROGRESS_TIMEOUT ;
}
2007-03-29 22:34:40 +00:00
goto notready ;
}
2017-01-06 07:10:15 +00:00
2009-01-19 17:54:54 +00:00
if ( ( to = ( uint8_t ) ( elapsed > = ( time_t ) timelimit_sec ) ) | | ( fail_on_single_reject & & oglobals . hups ) ) {
2008-10-09 00:38:59 +00:00
int ok = 0 ;
2010-02-06 03:38:24 +00:00
2010-10-25 18:03:06 +00:00
if ( fail_on_single_reject_var ) {
if ( ! switch_true ( fail_on_single_reject_var ) ) {
ok = 1 ;
2010-02-06 03:38:24 +00:00
2010-10-25 18:03:06 +00:00
for ( i = 0 ; i < and_argc ; i + + ) {
switch_channel_t * pchannel ;
const char * cause_str ;
2017-01-06 07:10:15 +00:00
2020-05-07 17:04:54 +00:00
if ( ! oglobals . originate_status [ i ] . peer_session ) {
2010-10-25 18:03:06 +00:00
continue ;
}
2020-05-07 17:04:54 +00:00
pchannel = switch_core_session_get_channel ( oglobals . originate_status [ i ] . peer_session ) ;
2010-02-06 03:38:24 +00:00
2011-11-18 19:17:56 +00:00
if ( switch_channel_down_nosig ( pchannel ) ) {
2011-11-09 16:07:54 +00:00
int neg , pos ;
2010-10-25 18:03:06 +00:00
cause_str = switch_channel_cause2str ( switch_channel_get_cause ( pchannel ) ) ;
2011-11-09 16:07:54 +00:00
neg = * fail_on_single_reject_var = = ' ! ' ;
pos = ! ! switch_stristr ( cause_str , fail_on_single_reject_var ) ;
if ( neg ) {
pos = ! pos ;
}
2017-01-06 07:10:15 +00:00
2011-11-09 16:07:54 +00:00
if ( pos ) {
2010-10-25 18:03:06 +00:00
ok = 0 ;
break ;
}
2008-10-09 00:38:59 +00:00
}
}
}
}
if ( ! ok ) {
2009-01-19 17:54:54 +00:00
oglobals . idx = IDX_TIMEOUT ;
2008-10-09 00:38:59 +00:00
goto notready ;
}
}
2009-11-05 06:56:38 +00:00
2008-05-27 04:30:03 +00:00
/* read from the channel while we wait if the audio is up on it */
2009-01-19 17:54:54 +00:00
if ( oglobals . session & &
2008-05-27 04:30:03 +00:00
! switch_channel_test_flag ( caller_channel , CF_PROXY_MODE ) & &
! switch_channel_test_flag ( caller_channel , CF_PROXY_MEDIA ) & &
2017-05-20 00:05:44 +00:00
//!switch_channel_test_flag(caller_channel, CF_XFER_ZOMBIE) &&
switch_channel_up ( caller_channel ) & &
2009-10-29 05:47:17 +00:00
( oglobals . ringback_ok
2008-05-27 04:30:03 +00:00
| | ( switch_channel_test_flag ( caller_channel , CF_ANSWERED ) | | switch_channel_test_flag ( caller_channel , CF_EARLY_MEDIA ) ) ) ) {
2010-02-06 03:38:24 +00:00
2008-09-04 18:29:43 +00:00
switch_status_t tstatus = SWITCH_STATUS_SUCCESS ;
2008-12-09 18:52:16 +00:00
int silence = 0 ;
2008-05-27 04:30:03 +00:00
2009-08-26 19:49:35 +00:00
if ( caller_channel & & cancel_key ) {
if ( switch_channel_has_dtmf ( caller_channel ) ) {
switch_dtmf_t dtmf = { 0 , 0 } ;
if ( switch_channel_dequeue_dtmf ( caller_channel , & dtmf ) = = SWITCH_STATUS_SUCCESS ) {
if ( dtmf . digit = = * cancel_key ) {
2009-10-07 04:30:19 +00:00
oglobals . idx = IDX_KEY_CANCEL ;
2009-08-26 19:49:35 +00:00
goto notready ;
}
}
}
}
2008-09-04 18:29:43 +00:00
if ( switch_channel_media_ready ( caller_channel ) ) {
2009-01-19 17:54:54 +00:00
tstatus = switch_core_session_read_frame ( oglobals . session , & read_frame , SWITCH_IO_FLAG_NONE , 0 ) ;
2008-09-04 18:29:43 +00:00
if ( ! SWITCH_READ_ACCEPTABLE ( tstatus ) ) {
2009-12-08 17:22:42 +00:00
if ( soft_holding ) {
switch_channel_set_flag ( caller_channel , CF_XFER_ZOMBIE ) ;
}
2009-10-09 20:48:24 +00:00
if ( switch_channel_test_flag ( caller_channel , CF_XFER_ZOMBIE ) ) {
2010-04-28 17:59:29 +00:00
goto do_continue ;
2009-10-09 20:48:24 +00:00
}
2008-09-04 18:29:43 +00:00
break ;
}
2010-04-28 17:59:29 +00:00
read_packet + + ;
2008-09-04 18:29:43 +00:00
} else {
read_frame = NULL ;
2007-03-29 22:34:40 +00:00
}
2010-01-14 21:02:11 +00:00
2010-02-06 03:38:24 +00:00
if ( oglobals . ringback_ok & & ( oglobals . ring_ready | | oglobals . instant_ringback | |
2010-01-14 21:02:11 +00:00
oglobals . sending_ringback > 1 | | oglobals . bridge_early_media > - 1 ) ) {
2009-10-29 05:47:17 +00:00
if ( oglobals . ringback_ok = = 1 ) {
2010-04-23 21:09:27 +00:00
switch_status_t rst ;
2013-05-09 15:29:45 +00:00
2020-05-07 17:04:54 +00:00
rst = setup_ringback ( & oglobals , oglobals . originate_status , and_argc , ringback_data , & ringback , & write_frame , & write_codec ) ;
2017-01-06 07:10:15 +00:00
2010-01-15 21:10:31 +00:00
if ( oglobals . bridge_early_media > - 1 ) {
switch_threadattr_t * thd_attr = NULL ;
switch_threadattr_create ( & thd_attr , switch_core_session_get_pool ( session ) ) ;
switch_threadattr_stacksize_set ( thd_attr , SWITCH_THREAD_STACKSIZE ) ;
early_state . oglobals = & oglobals ;
2020-05-07 17:04:54 +00:00
//early_state.originate_status = oglobals.originate_status;
2010-01-15 21:10:31 +00:00
early_state . ready = 1 ;
2010-04-23 21:09:27 +00:00
early_state . ringback = & ringback ;
2014-12-08 18:53:28 +00:00
early_state . ttl = and_argc ;
2010-01-15 21:10:31 +00:00
switch_mutex_init ( & early_state . mutex , SWITCH_MUTEX_NESTED , switch_core_session_get_pool ( session ) ) ;
switch_buffer_create_dynamic ( & early_state . buffer , 1024 , 1024 , 0 ) ;
switch_thread_create ( & oglobals . ethread , thd_attr , early_thread_run , & early_state , switch_core_session_get_pool ( session ) ) ;
}
2010-02-06 03:38:24 +00:00
2009-10-29 05:47:17 +00:00
switch ( rst ) {
case SWITCH_STATUS_SUCCESS :
oglobals . ringback_ok + + ;
break ;
case SWITCH_STATUS_FALSE :
goto notready ;
break ;
case SWITCH_STATUS_BREAK :
2013-03-27 16:28:43 +00:00
status = SWITCH_STATUS_FALSE ;
2009-10-29 05:47:17 +00:00
goto done ;
break ;
default :
ringback_data = NULL ;
oglobals . ringback_ok = 0 ;
oglobals . sending_ringback = 0 ;
break ;
}
2010-04-28 17:59:29 +00:00
goto do_continue ;
2009-10-29 05:47:17 +00:00
}
2010-02-06 03:38:24 +00:00
2017-01-06 07:10:15 +00:00
if ( oglobals . bridge_early_media > - 1 ) {
2010-01-15 21:10:31 +00:00
write_frame . datalen = 0 ;
switch_mutex_lock ( early_state . mutex ) ;
2010-04-23 21:09:27 +00:00
if ( ringback . asis ) {
uint16_t mlen ;
switch_size_t buflen = switch_buffer_inuse ( early_state . buffer ) ;
if ( buflen > sizeof ( uint16_t ) ) {
switch_buffer_peek ( early_state . buffer , & mlen , sizeof ( uint16_t ) ) ;
if ( buflen > = ( mlen + sizeof ( uint16_t ) ) ) {
switch_buffer_toss ( early_state . buffer , sizeof ( uint16_t ) ) ;
2014-01-22 21:28:53 +00:00
write_frame . datalen = ( uint32_t ) switch_buffer_read ( early_state . buffer , write_frame . data , mlen ) ;
2010-04-23 21:09:27 +00:00
}
}
} else {
2021-04-19 18:16:28 +00:00
if ( write_frame . codec & & switch_buffer_inuse ( early_state . buffer ) > = write_frame . codec - > implementation - > decoded_bytes_per_packet ) {
2014-01-22 21:28:53 +00:00
write_frame . datalen = ( uint32_t ) switch_buffer_read ( early_state . buffer , write_frame . data ,
2010-04-23 21:09:27 +00:00
write_frame . codec - > implementation - > decoded_bytes_per_packet ) ;
}
2010-01-14 21:02:11 +00:00
}
2010-01-15 21:10:31 +00:00
switch_mutex_unlock ( early_state . mutex ) ;
2010-01-14 21:02:11 +00:00
} else if ( ringback . fh ) {
2007-03-29 22:34:40 +00:00
switch_size_t mlen , olen ;
unsigned int pos = 0 ;
2008-05-27 04:30:03 +00:00
2007-03-29 22:34:40 +00:00
if ( ringback . asis ) {
2008-10-20 17:48:42 +00:00
mlen = write_frame . codec - > implementation - > encoded_bytes_per_packet ;
2007-03-29 22:34:40 +00:00
} else {
2008-10-20 17:48:42 +00:00
mlen = write_frame . codec - > implementation - > samples_per_packet ;
2007-03-29 22:34:40 +00:00
}
olen = mlen ;
2010-02-06 03:38:24 +00:00
2009-01-09 20:34:01 +00:00
//if (ringback.fh->resampler && ringback.fh->resampler->rfactor > 1) {
//olen = (switch_size_t) (olen * ringback.fh->resampler->rfactor);
//}
2010-02-06 03:38:24 +00:00
2008-02-18 21:32:35 +00:00
switch_core_file_read ( ringback . fh , write_frame . data , & olen ) ;
2007-03-29 22:34:40 +00:00
if ( olen = = 0 ) {
olen = mlen ;
ringback . fh - > speed = 0 ;
switch_core_file_seek ( ringback . fh , & pos , 0 , SEEK_SET ) ;
2008-02-18 21:32:35 +00:00
switch_core_file_read ( ringback . fh , write_frame . data , & olen ) ;
2007-03-29 22:34:40 +00:00
if ( olen = = 0 ) {
break ;
}
}
2014-06-13 00:28:14 +00:00
write_frame . datalen = ( uint32_t ) ( ringback . asis ? olen : olen * 2 * ringback . fh - > channels ) ;
2013-02-28 20:52:26 +00:00
write_frame . samples = ( uint32_t ) olen ;
2012-12-06 16:11:11 +00:00
2007-03-29 22:34:40 +00:00
} else if ( ringback . audio_buffer ) {
2007-04-04 18:22:59 +00:00
if ( ( write_frame . datalen = ( uint32_t ) switch_buffer_read_loop ( ringback . audio_buffer ,
write_frame . data ,
2010-02-06 03:38:24 +00:00
write_frame . codec - > implementation - > decoded_bytes_per_packet ) ) < =
0 ) {
2009-12-08 17:22:42 +00:00
if ( soft_holding ) {
switch_channel_set_flag ( caller_channel , CF_XFER_ZOMBIE ) ;
2010-04-28 17:59:29 +00:00
goto do_continue ;
2009-12-08 17:22:42 +00:00
}
2007-04-04 18:22:59 +00:00
break ;
2007-03-29 22:34:40 +00:00
}
2008-12-09 00:32:51 +00:00
} else if ( ringback . silence ) {
2008-12-09 18:52:16 +00:00
silence = ringback . silence ;
2007-03-29 22:34:40 +00:00
}
2008-12-09 18:52:16 +00:00
} else {
2009-03-23 01:59:35 +00:00
silence = 600 ;
2008-12-09 18:52:16 +00:00
}
2010-02-06 03:38:24 +00:00
2014-12-26 05:27:43 +00:00
if ( ( ringback . fh | | silence | | ringback . audio_buffer | | oglobals . bridge_early_media > - 1 ) & & write_frame . codec & & write_frame . codec - > implementation & & write_frame . datalen ) {
2008-12-09 20:28:12 +00:00
if ( silence ) {
2010-12-16 02:01:34 +00:00
write_frame . datalen = read_impl . decoded_bytes_per_packet ;
2014-06-12 23:49:37 +00:00
switch_generate_sln_silence ( ( int16_t * ) write_frame . data , write_frame . datalen / 2 , write_frame . codec - > implementation - > number_of_channels , silence ) ;
2008-12-09 20:28:12 +00:00
}
2010-02-06 03:38:24 +00:00
2009-01-19 17:54:54 +00:00
if ( switch_core_session_write_frame ( oglobals . session , & write_frame , SWITCH_IO_FLAG_NONE , 0 ) ! = SWITCH_STATUS_SUCCESS ) {
2009-12-08 17:22:42 +00:00
if ( soft_holding ) {
switch_channel_set_flag ( caller_channel , CF_XFER_ZOMBIE ) ;
}
2009-10-09 20:48:24 +00:00
if ( switch_channel_test_flag ( caller_channel , CF_XFER_ZOMBIE ) ) {
2010-04-28 17:59:29 +00:00
goto do_continue ;
2009-10-09 20:48:24 +00:00
}
2008-12-09 18:52:16 +00:00
break ;
2007-03-29 22:34:40 +00:00
}
}
2010-02-06 03:38:24 +00:00
2017-01-06 07:10:15 +00:00
}
2010-04-28 17:59:29 +00:00
do_continue :
if ( ! read_packet ) {
2012-11-29 05:12:35 +00:00
switch_yield ( 20000 ) ;
2007-03-29 22:34:40 +00:00
}
}
2010-02-06 03:38:24 +00:00
2007-03-29 22:34:40 +00:00
notready :
2009-10-07 04:30:19 +00:00
if ( caller_channel ) {
holding = switch_channel_get_variable ( caller_channel , SWITCH_HOLDING_UUID_VARIABLE ) ;
switch_channel_set_variable ( caller_channel , SWITCH_HOLDING_UUID_VARIABLE , NULL ) ;
if ( soft_holding & & switch_channel_test_flag ( caller_channel , CF_XFER_ZOMBIE ) ) {
holding = soft_holding ;
2009-12-08 17:22:42 +00:00
soft_holding = NULL ;
2009-10-07 04:30:19 +00:00
switch_channel_set_variable ( caller_channel , SWITCH_SOFT_HOLDING_UUID_VARIABLE , NULL ) ;
}
}
2010-02-06 03:38:24 +00:00
2009-10-09 20:48:24 +00:00
if ( caller_channel & & ! switch_channel_ready ( caller_channel ) & & ! switch_channel_test_flag ( caller_channel , CF_XFER_ZOMBIE ) ) {
2009-01-19 17:54:54 +00:00
oglobals . idx = IDX_CANCEL ;
2007-03-29 22:34:40 +00:00
}
2011-06-15 15:29:07 +00:00
if ( oglobals . session & & ( ringback_data | | ! ( switch_channel_test_flag ( caller_channel , CF_PROXY_MODE ) | |
2010-02-06 03:38:24 +00:00
switch_channel_test_flag ( caller_channel , CF_PROXY_MEDIA ) ) ) ) {
2009-01-19 17:54:54 +00:00
switch_core_session_reset ( oglobals . session , SWITCH_FALSE , SWITCH_TRUE ) ;
2007-03-29 22:34:40 +00:00
}
2008-05-27 04:30:03 +00:00
2009-10-07 04:30:19 +00:00
if ( holding ) {
if ( oglobals . idx > IDX_NADA ) {
2020-05-07 17:04:54 +00:00
peer_session = oglobals . originate_status [ oglobals . idx ] . peer_session ;
peer_channel = oglobals . originate_status [ oglobals . idx ] . peer_channel ;
oglobals . originate_status [ oglobals . idx ] . peer_channel = NULL ;
2009-10-07 04:30:19 +00:00
} else if ( and_argc = = 1 ) {
2020-05-07 17:04:54 +00:00
peer_session = oglobals . originate_status [ 0 ] . peer_session ;
peer_channel = oglobals . originate_status [ 0 ] . peer_channel ;
oglobals . originate_status [ 0 ] . peer_channel = NULL ;
2009-10-07 04:30:19 +00:00
} else {
for ( i = 0 ; i < and_argc ; i + + ) {
2020-05-07 17:04:54 +00:00
if ( ! peer_eligible ( oglobals . originate_status [ i ] . peer_channel ) ) {
2009-10-07 04:30:19 +00:00
continue ;
}
2020-05-07 17:04:54 +00:00
if ( switch_channel_media_ready ( oglobals . originate_status [ i ] . peer_channel ) ) {
peer_session = oglobals . originate_status [ i ] . peer_session ;
peer_channel = oglobals . originate_status [ i ] . peer_channel ;
oglobals . originate_status [ i ] . peer_channel = NULL ;
2009-10-07 04:30:19 +00:00
goto end_search ;
}
}
for ( i = 0 ; i < and_argc ; i + + ) {
2020-05-07 17:04:54 +00:00
if ( ! peer_eligible ( oglobals . originate_status [ i ] . peer_channel ) ) {
2009-10-07 04:30:19 +00:00
continue ;
}
2020-05-07 17:04:54 +00:00
if ( switch_channel_up_nosig ( oglobals . originate_status [ i ] . peer_channel ) ) {
peer_session = oglobals . originate_status [ i ] . peer_session ;
peer_channel = oglobals . originate_status [ i ] . peer_channel ;
oglobals . originate_status [ i ] . peer_channel = NULL ;
2009-10-07 04:30:19 +00:00
break ;
}
}
2007-03-29 22:34:40 +00:00
}
2010-02-06 03:38:24 +00:00
end_search :
2009-03-04 04:19:33 +00:00
2011-11-18 19:17:56 +00:00
if ( peer_channel & & switch_channel_down_nosig ( peer_channel ) ) {
2009-10-09 22:28:31 +00:00
switch_core_session_rwunlock ( peer_session ) ;
peer_session = NULL ;
peer_channel = NULL ;
}
2010-02-06 03:38:24 +00:00
if ( oglobals . idx = = IDX_TIMEOUT | | to | | oglobals . idx = = IDX_KEY_CANCEL | | oglobals . idx = = IDX_CANCEL | |
2009-10-09 22:28:31 +00:00
( ! peer_session & & oglobals . idx = = IDX_NADA ) ) {
const char * dest = NULL ;
const char * context = NULL ;
const char * dialplan = NULL ;
2009-10-09 00:52:25 +00:00
switch_core_session_t * holding_session ;
2009-11-05 06:56:38 +00:00
2009-10-07 04:30:19 +00:00
if ( caller_channel ) {
2009-10-23 16:03:42 +00:00
if ( zstr ( context ) ) {
2010-02-06 03:38:24 +00:00
context = switch_channel_get_variable ( caller_channel , " context " ) ;
2009-10-09 00:52:25 +00:00
}
2009-10-23 16:03:42 +00:00
if ( zstr ( dialplan ) ) {
2010-02-06 03:38:24 +00:00
dialplan = switch_channel_get_variable ( caller_channel , " dialplan " ) ;
2009-10-09 00:52:25 +00:00
}
}
2010-02-06 03:38:24 +00:00
2009-10-23 16:03:42 +00:00
if ( zstr ( context ) ) {
2009-10-09 00:52:25 +00:00
context = " default " ;
}
2009-10-23 16:03:42 +00:00
if ( zstr ( context ) ) {
2009-10-09 00:52:25 +00:00
dialplan = " XML " ;
}
if ( ( holding_session = switch_core_session_locate ( holding ) ) ) {
2009-10-09 20:48:24 +00:00
switch_channel_t * holding_channel = switch_core_session_get_channel ( holding_session ) ;
switch_status_t mstatus = SWITCH_STATUS_FALSE ;
2009-11-05 06:56:38 +00:00
2009-10-09 20:48:24 +00:00
if ( caller_channel ) {
2010-01-22 21:56:20 +00:00
if ( ( mstatus = switch_channel_caller_extension_masquerade ( caller_channel , holding_channel , 0 ) ) = = SWITCH_STATUS_SUCCESS ) {
2009-10-09 22:28:31 +00:00
switch_channel_restart ( holding_channel ) ;
2009-10-09 20:48:24 +00:00
}
}
if ( mstatus ! = SWITCH_STATUS_SUCCESS ) {
2009-10-09 22:28:31 +00:00
if ( peer_channel ) {
dest = switch_channel_get_variable ( peer_channel , " destination_number " ) ;
context = switch_channel_get_variable ( peer_channel , " context " ) ;
dialplan = switch_channel_get_variable ( peer_channel , " dialplan " ) ;
} else if ( caller_channel ) {
dest = switch_channel_get_variable ( caller_channel , " destination_number " ) ;
}
if ( dest ) {
switch_ivr_session_transfer ( holding_session , dest , dialplan , context ) ;
}
2009-10-09 20:48:24 +00:00
}
2009-10-09 00:52:25 +00:00
switch_core_session_rwunlock ( holding_session ) ;
holding = NULL ;
holding_session = NULL ;
2009-10-07 04:30:19 +00:00
}
2009-10-09 00:52:25 +00:00
2009-10-09 22:28:31 +00:00
if ( peer_channel ) {
switch_channel_hangup ( peer_channel , SWITCH_CAUSE_ATTENDED_TRANSFER ) ;
switch_core_session_rwunlock ( peer_session ) ;
}
2010-01-17 00:26:29 +00:00
if ( force_reason = = SWITCH_CAUSE_NONE ) {
force_reason = SWITCH_CAUSE_ATTENDED_TRANSFER ;
}
2009-12-08 00:05:40 +00:00
} else if ( zstr ( soft_holding ) ) {
2009-11-05 06:56:38 +00:00
2009-10-09 00:52:25 +00:00
if ( peer_channel & & switch_channel_ready ( peer_channel ) ) {
2009-11-05 06:56:38 +00:00
switch_core_session_t * holding_session ;
2010-01-17 00:26:29 +00:00
if ( force_reason = = SWITCH_CAUSE_NONE ) {
force_reason = SWITCH_CAUSE_ATTENDED_TRANSFER ;
}
2009-11-05 06:56:38 +00:00
if ( ( holding_session = switch_core_session_locate ( holding ) ) ) {
2009-11-05 13:41:11 +00:00
switch_channel_set_variable ( switch_core_session_get_channel ( holding_session ) , SWITCH_HANGUP_AFTER_BRIDGE_VARIABLE , " true " ) ;
2009-11-05 06:56:38 +00:00
switch_core_session_rwunlock ( holding_session ) ;
}
2011-03-11 19:00:16 +00:00
switch_channel_set_flag ( peer_channel , CF_LAZY_ATTENDED_TRANSFER ) ;
2009-10-09 00:52:25 +00:00
switch_ivr_uuid_bridge ( holding , switch_core_session_get_uuid ( peer_session ) ) ;
2009-11-05 06:56:38 +00:00
holding = NULL ;
2013-12-04 23:46:02 +00:00
oglobals . idx = IDX_XFER ;
2012-04-30 22:51:31 +00:00
if ( caller_channel & & switch_channel_up_nosig ( caller_channel ) & & ! switch_channel_test_flag ( caller_channel , CF_INTERCEPTED ) ) {
2009-10-09 00:52:25 +00:00
switch_channel_hangup ( caller_channel , SWITCH_CAUSE_ATTENDED_TRANSFER ) ;
}
caller_channel = NULL ;
oglobals . session = NULL ;
session = NULL ;
switch_core_session_rwunlock ( peer_session ) ;
} else {
switch_core_session_t * holding_session ;
2009-10-07 04:30:19 +00:00
2009-10-09 00:52:25 +00:00
if ( ( holding_session = switch_core_session_locate ( holding ) ) ) {
switch_channel_t * holding_channel = switch_core_session_get_channel ( holding_session ) ;
2009-11-05 06:56:38 +00:00
2009-10-09 00:52:25 +00:00
if ( caller_channel & & switch_channel_ready ( caller_channel ) ) {
2009-11-05 13:41:11 +00:00
switch_channel_set_variable ( holding_channel , SWITCH_HANGUP_AFTER_BRIDGE_VARIABLE , " true " ) ;
2009-10-09 00:52:25 +00:00
switch_ivr_uuid_bridge ( holding , switch_core_session_get_uuid ( session ) ) ;
2009-11-05 06:56:38 +00:00
holding = NULL ;
2009-10-09 00:52:25 +00:00
} else {
switch_channel_hangup ( holding_channel , SWITCH_CAUSE_NORMAL_UNSPECIFIED ) ;
}
switch_core_session_rwunlock ( holding_session ) ;
2009-10-07 04:30:19 +00:00
}
}
2008-01-05 01:03:08 +00:00
}
2009-10-07 04:30:19 +00:00
peer_session = NULL ;
peer_channel = NULL ;
}
2010-02-06 03:38:24 +00:00
2009-10-07 04:30:19 +00:00
for ( i = 0 ; i < and_argc ; i + + ) {
2020-05-07 17:04:54 +00:00
if ( ! peer_eligible ( oglobals . originate_status [ i ] . peer_channel ) ) {
2009-10-07 04:30:19 +00:00
continue ;
}
2010-02-06 03:38:24 +00:00
2009-01-19 17:54:54 +00:00
if ( i ! = oglobals . idx ) {
2009-10-07 04:30:19 +00:00
holding = NULL ;
2017-01-06 07:10:15 +00:00
2009-10-09 20:48:24 +00:00
if ( oglobals . idx = = IDX_TIMEOUT | | to ) {
2008-04-16 21:29:57 +00:00
reason = SWITCH_CAUSE_NO_ANSWER ;
2007-03-29 22:34:40 +00:00
} else {
2009-01-19 17:54:54 +00:00
if ( oglobals . idx = = IDX_CANCEL ) {
2008-04-16 21:29:57 +00:00
reason = SWITCH_CAUSE_ORIGINATOR_CANCEL ;
2007-03-29 22:34:40 +00:00
} else {
2008-04-16 21:29:57 +00:00
if ( and_argc > 1 ) {
reason = SWITCH_CAUSE_LOSE_RACE ;
2020-05-07 17:04:54 +00:00
} else if ( ! switch_channel_ready ( oglobals . originate_status [ i ] . peer_channel ) ) {
wait_for_cause ( oglobals . originate_status [ i ] . peer_channel ) ;
if ( switch_channel_down_nosig ( oglobals . originate_status [ i ] . peer_channel ) ) {
reason = switch_channel_get_cause ( oglobals . originate_status [ i ] . peer_channel ) ;
2011-01-17 16:41:01 +00:00
}
2008-04-16 21:29:57 +00:00
} else {
reason = SWITCH_CAUSE_NO_ANSWER ;
}
2007-03-29 22:34:40 +00:00
}
}
2020-05-07 17:04:54 +00:00
if ( switch_channel_up_nosig ( oglobals . originate_status [ i ] . peer_channel ) ) {
2008-05-19 21:02:26 +00:00
if ( caller_channel & & i = = 0 ) {
2010-02-06 03:38:24 +00:00
holding = switch_channel_get_variable ( caller_channel , SWITCH_SOFT_HOLDING_UUID_VARIABLE ) ;
switch_channel_set_variable ( caller_channel , SWITCH_SOFT_HOLDING_UUID_VARIABLE , NULL ) ;
}
2012-05-07 15:05:51 +00:00
if ( holding & & oglobals . idx ! = IDX_TIMEOUT & & oglobals . idx ! = IDX_KEY_CANCEL & & oglobals . idx < 0 ) {
2009-11-05 13:41:11 +00:00
switch_core_session_t * holding_session ;
if ( ( holding_session = switch_core_session_locate ( holding ) ) ) {
2011-06-01 03:22:09 +00:00
switch_channel_t * holding_channel = switch_core_session_get_channel ( holding_session ) ;
2017-01-06 07:10:15 +00:00
2011-06-01 03:22:09 +00:00
switch_channel_set_variable ( holding_channel , SWITCH_HANGUP_AFTER_BRIDGE_VARIABLE , " true " ) ;
if ( caller_channel & & switch_true ( switch_channel_get_variable ( caller_channel , " recording_follow_transfer " ) ) ) {
2020-05-07 17:04:54 +00:00
switch_ivr_transfer_recordings ( session , oglobals . originate_status [ i ] . peer_session ) ;
2011-06-01 03:22:09 +00:00
}
if ( switch_true ( switch_channel_get_variable ( holding_channel , " recording_follow_transfer " ) ) ) {
2020-05-07 17:04:54 +00:00
switch_ivr_transfer_recordings ( holding_session , oglobals . originate_status [ i ] . peer_session ) ;
2011-06-01 03:22:09 +00:00
}
2017-01-06 07:10:15 +00:00
2009-11-05 13:41:11 +00:00
switch_core_session_rwunlock ( holding_session ) ;
}
2020-05-07 17:04:54 +00:00
switch_channel_set_flag ( oglobals . originate_status [ i ] . peer_channel , CF_LAZY_ATTENDED_TRANSFER ) ;
switch_ivr_uuid_bridge ( holding , switch_core_session_get_uuid ( oglobals . originate_status [ i ] . peer_session ) ) ;
2009-11-05 13:41:11 +00:00
holding = NULL ;
2010-02-06 03:38:24 +00:00
} else {
2012-09-04 16:24:13 +00:00
if ( force_reason = = SWITCH_CAUSE_LOSE_RACE | | reason = = SWITCH_CAUSE_LOSE_RACE ) {
2020-05-07 17:04:54 +00:00
switch_channel_set_variable ( oglobals . originate_status [ i ] . peer_channel , " group_dial_status " , " loser " ) ;
2012-09-04 16:24:13 +00:00
}
2020-05-07 17:04:54 +00:00
switch_channel_hangup ( oglobals . originate_status [ i ] . peer_channel , force_reason ? force_reason : reason ) ;
2008-05-19 21:02:26 +00:00
}
2008-03-13 01:08:42 +00:00
}
2007-03-29 22:34:40 +00:00
}
}
2010-02-06 03:38:24 +00:00
2009-12-08 00:05:40 +00:00
2009-01-19 17:54:54 +00:00
if ( oglobals . idx > IDX_NADA ) {
2020-05-07 17:04:54 +00:00
if ( ( peer_session = oglobals . originate_status [ oglobals . idx ] . peer_session ) ) {
peer_channel = switch_core_session_get_channel ( oglobals . originate_status [ oglobals . idx ] . peer_session ) ;
2009-12-08 00:05:40 +00:00
}
2007-03-29 22:34:40 +00:00
} else {
status = SWITCH_STATUS_FALSE ;
2008-06-05 00:23:58 +00:00
if ( caller_channel & & peer_channel ) {
2010-11-05 23:20:09 +00:00
switch_process_import ( oglobals . session , peer_channel , " import " , NULL ) ;
2008-06-04 23:33:29 +00:00
}
2008-01-05 01:03:08 +00:00
peer_channel = NULL ;
2007-03-29 22:34:40 +00:00
goto done ;
}
if ( caller_channel ) {
2017-05-18 16:57:37 +00:00
if ( switch_channel_test_flag ( caller_channel , CF_XFER_ZOMBIE ) & & ! switch_channel_up ( caller_channel ) ) {
if ( switch_channel_media_up ( peer_channel ) ) {
oglobals . idx = IDX_XFER ;
reason = force_reason = SWITCH_CAUSE_ATTENDED_TRANSFER ;
switch_channel_execute_on ( peer_channel , " execute_on_orphaned_bleg " ) ;
switch_channel_api_on ( peer_channel , " api_on_orphaned_bleg " ) ;
}
} else if ( switch_channel_test_flag ( peer_channel , CF_ANSWERED ) ) {
2009-10-21 18:48:28 +00:00
switch_channel_pass_callee_id ( peer_channel , caller_channel ) ;
2011-08-19 21:25:26 +00:00
if ( switch_channel_test_flag ( caller_channel , CF_PROXY_MODE ) ) {
status = SWITCH_STATUS_SUCCESS ;
} else {
2012-11-29 05:12:35 +00:00
status = switch_channel_answer ( caller_channel ) ;
2011-08-19 21:25:26 +00:00
}
2007-03-29 22:34:40 +00:00
} else if ( switch_channel_test_flag ( peer_channel , CF_EARLY_MEDIA ) ) {
2011-08-19 21:25:26 +00:00
if ( switch_channel_test_flag ( caller_channel , CF_PROXY_MODE ) ) {
status = SWITCH_STATUS_SUCCESS ;
} else {
2013-11-22 21:53:05 +00:00
switch_channel_pass_callee_id ( peer_channel , caller_channel ) ;
2012-11-29 05:12:35 +00:00
status = switch_channel_pre_answer ( caller_channel ) ;
2011-08-19 21:25:26 +00:00
}
2008-02-20 03:57:01 +00:00
} else {
status = SWITCH_STATUS_SUCCESS ;
}
if ( status ! = SWITCH_STATUS_SUCCESS ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_CHANNEL_LOG ( peer_channel ) , SWITCH_LOG_DEBUG , " %s Media Establishment Failed. \n " ,
2009-10-29 05:47:17 +00:00
switch_channel_get_name ( caller_channel ) ) ;
2008-02-20 03:57:01 +00:00
switch_channel_hangup ( peer_channel , SWITCH_CAUSE_INCOMPATIBLE_DESTINATION ) ;
2007-03-29 22:34:40 +00:00
}
}
2008-05-27 04:30:03 +00:00
if ( switch_channel_test_flag ( peer_channel , CF_ANSWERED ) | |
2009-01-19 17:54:54 +00:00
( oglobals . early_ok & & switch_channel_test_flag ( peer_channel , CF_EARLY_MEDIA ) ) | |
( oglobals . return_ring_ready & & switch_channel_test_flag ( peer_channel , CF_RING_READY ) )
2008-01-05 16:20:39 +00:00
) {
2007-03-29 22:34:40 +00:00
* bleg = peer_session ;
2009-01-19 23:15:59 +00:00
if ( oglobals . monitor_early_media_ring | | oglobals . monitor_early_media_fail ) {
switch_ivr_stop_tone_detect_session ( peer_session ) ;
switch_channel_set_private ( peer_channel , " _oglobals_ " , NULL ) ;
}
2007-03-29 22:34:40 +00:00
status = SWITCH_STATUS_SUCCESS ;
} else {
status = SWITCH_STATUS_FALSE ;
}
done :
2010-02-06 03:38:24 +00:00
2008-07-03 22:51:09 +00:00
* cause = SWITCH_CAUSE_NONE ;
2007-03-29 22:34:40 +00:00
2008-02-21 02:27:27 +00:00
if ( caller_channel & & ! switch_channel_ready ( caller_channel ) ) {
status = SWITCH_STATUS_FALSE ;
}
2007-03-29 22:34:40 +00:00
if ( status = = SWITCH_STATUS_SUCCESS ) {
if ( caller_channel ) {
switch_channel_set_variable ( caller_channel , " originate_disposition " , " call accepted " ) ;
2008-06-05 00:23:58 +00:00
if ( peer_channel ) {
2010-11-05 23:20:09 +00:00
switch_process_import ( oglobals . session , peer_channel , " import " , NULL ) ;
2011-08-10 13:38:55 +00:00
if ( switch_channel_test_flag ( peer_channel , CF_ANSWERED ) ) {
switch_channel_set_variable ( caller_channel , " DIALSTATUS " , " EARLY " ) ;
} else {
switch_channel_set_variable ( caller_channel , " DIALSTATUS " , " ANSWER " ) ;
}
2008-06-05 00:23:58 +00:00
}
2007-03-29 22:34:40 +00:00
}
2020-05-12 18:56:30 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( oglobals . session ) , SWITCH_LOG_DEBUG , " Originate Resulted in Success: [%s] Peer UUID: %s \n " ,
switch_channel_get_name ( peer_channel ) , switch_channel_get_uuid ( peer_channel ) ) ;
2007-03-29 22:34:40 +00:00
* cause = SWITCH_CAUSE_SUCCESS ;
} else {
2008-05-30 18:11:05 +00:00
const char * cdr_var = NULL ;
2013-02-28 15:58:53 +00:00
const char * json_cdr_var = NULL ;
2010-07-01 20:19:40 +00:00
switch_xml_t cdr = NULL ;
2013-02-28 15:58:53 +00:00
cJSON * json_cdr = NULL ;
char * json_text ;
2008-05-30 18:11:05 +00:00
char * xml_text ;
char buf [ 128 ] = " " , buf2 [ 128 ] = " " ;
if ( caller_channel ) {
cdr_var = switch_channel_get_variable ( caller_channel , " failed_xml_cdr_prefix " ) ;
}
2013-02-28 15:58:53 +00:00
if ( caller_channel ) {
json_cdr_var = switch_channel_get_variable ( caller_channel , " failed_json_cdr_prefix " ) ;
}
2007-03-29 22:34:40 +00:00
if ( peer_channel ) {
2011-01-17 16:41:01 +00:00
wait_for_cause ( peer_channel ) ;
2010-02-06 03:38:24 +00:00
* cause = switch_channel_get_cause ( peer_channel ) ;
2007-03-29 22:34:40 +00:00
} else {
for ( i = 0 ; i < and_argc ; i + + ) {
2020-05-07 17:04:54 +00:00
if ( ! oglobals . originate_status [ i ] . peer_channel ) {
2007-03-29 22:34:40 +00:00
continue ;
}
2020-05-07 17:04:54 +00:00
* cause = switch_channel_get_cause ( oglobals . originate_status [ i ] . peer_channel ) ;
2007-03-29 22:34:40 +00:00
break ;
}
}
2010-02-06 03:38:24 +00:00
2008-05-30 18:11:05 +00:00
if ( cdr_var ) {
for ( i = 0 ; i < and_argc ; i + + ) {
2009-05-11 16:52:01 +00:00
switch_channel_t * channel ;
2020-05-07 17:04:54 +00:00
if ( ! oglobals . originate_status [ i ] . peer_session ) {
2010-02-06 03:38:24 +00:00
continue ;
}
2009-05-11 16:52:01 +00:00
2020-05-07 17:04:54 +00:00
channel = switch_core_session_get_channel ( oglobals . originate_status [ i ] . peer_session ) ;
2010-02-06 03:38:24 +00:00
2009-05-12 14:54:34 +00:00
switch_channel_wait_for_state_timeout ( channel , CS_REPORTING , 5000 ) ;
2010-02-06 03:38:24 +00:00
2009-05-12 14:54:34 +00:00
if ( ! switch_channel_test_flag ( channel , CF_TIMESTAMP_SET ) ) {
switch_channel_set_timestamps ( channel ) ;
2009-05-11 16:52:01 +00:00
}
2010-02-06 03:38:24 +00:00
2020-05-07 17:04:54 +00:00
if ( switch_ivr_generate_xml_cdr ( oglobals . originate_status [ i ] . peer_session , & cdr ) = = SWITCH_STATUS_SUCCESS ) {
2008-05-30 18:11:05 +00:00
if ( ( xml_text = switch_xml_toxml ( cdr , SWITCH_FALSE ) ) ) {
switch_snprintf ( buf , sizeof ( buf ) , " %s_%d " , cdr_var , + + cdr_total ) ;
switch_channel_set_variable ( caller_channel , buf , xml_text ) ;
switch_safe_free ( xml_text ) ;
}
switch_xml_free ( cdr ) ;
cdr = NULL ;
}
}
switch_snprintf ( buf , sizeof ( buf ) , " %s_total " , cdr_var ) ;
switch_snprintf ( buf2 , sizeof ( buf2 ) , " %d " , cdr_total ? cdr_total : 0 ) ;
switch_channel_set_variable ( caller_channel , buf , buf2 ) ;
2013-02-28 15:58:53 +00:00
}
if ( json_cdr_var ) {
for ( i = 0 ; i < and_argc ; i + + ) {
switch_channel_t * channel ;
2020-05-07 17:04:54 +00:00
if ( ! oglobals . originate_status [ i ] . peer_session ) {
2013-02-28 15:58:53 +00:00
continue ;
}
2020-05-07 17:04:54 +00:00
channel = switch_core_session_get_channel ( oglobals . originate_status [ i ] . peer_session ) ;
2013-02-28 15:58:53 +00:00
switch_channel_wait_for_state_timeout ( channel , CS_REPORTING , 5000 ) ;
if ( ! switch_channel_test_flag ( channel , CF_TIMESTAMP_SET ) ) {
switch_channel_set_timestamps ( channel ) ;
}
2020-05-07 17:04:54 +00:00
if ( switch_ivr_generate_json_cdr ( oglobals . originate_status [ i ] . peer_session , & json_cdr , SWITCH_TRUE ) = = SWITCH_STATUS_SUCCESS ) {
2013-02-28 15:58:53 +00:00
json_text = cJSON_PrintUnformatted ( json_cdr ) ;
switch_snprintf ( buf , sizeof ( buf ) , " %s_%d " , json_cdr_var , + + cdr_total ) ;
switch_channel_set_variable ( caller_channel , buf , json_text ) ;
// switch_safe_free(json_text);
cJSON_Delete ( json_cdr ) ;
json_cdr = NULL ;
}
}
switch_snprintf ( buf , sizeof ( buf ) , " %s_total " , json_cdr_var ) ;
switch_snprintf ( buf2 , sizeof ( buf2 ) , " %d " , cdr_total ? cdr_total : 0 ) ;
switch_channel_set_variable ( caller_channel , buf , buf2 ) ;
2008-05-30 18:11:05 +00:00
}
2007-03-29 22:34:40 +00:00
2011-11-02 13:54:03 +00:00
if ( caller_channel & & switch_channel_test_flag ( caller_channel , CF_INTERCEPTED ) ) {
* cause = SWITCH_CAUSE_PICKED_OFF ;
}
2007-03-29 22:34:40 +00:00
if ( ! * cause ) {
if ( reason ) {
* cause = reason ;
} else if ( caller_channel ) {
* cause = switch_channel_get_cause ( caller_channel ) ;
} else {
* cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ;
2011-01-17 16:41:01 +00:00
for ( i = 0 ; i < and_argc ; i + + ) {
2020-05-07 17:04:54 +00:00
if ( ! peer_eligible ( oglobals . originate_status [ i ] . peer_channel ) ) {
2011-01-17 16:41:01 +00:00
continue ;
}
2020-05-07 17:04:54 +00:00
wait_for_cause ( oglobals . originate_status [ i ] . peer_channel ) ;
2017-01-06 07:10:15 +00:00
2020-05-07 17:04:54 +00:00
if ( switch_channel_down_nosig ( oglobals . originate_status [ i ] . peer_channel ) ) {
* cause = switch_channel_get_cause ( oglobals . originate_status [ i ] . peer_channel ) ;
2011-01-17 16:41:01 +00:00
break ;
}
2017-01-06 07:10:15 +00:00
2011-01-17 16:41:01 +00:00
}
2007-03-29 22:34:40 +00:00
}
}
2008-07-03 22:51:09 +00:00
if ( * cause = = SWITCH_CAUSE_SUCCESS | | * cause = = SWITCH_CAUSE_NONE ) {
2008-01-05 01:03:08 +00:00
* cause = SWITCH_CAUSE_ORIGINATOR_CANCEL ;
}
2009-01-19 17:54:54 +00:00
if ( oglobals . idx = = IDX_CANCEL ) {
2008-03-25 22:05:52 +00:00
* cause = SWITCH_CAUSE_ORIGINATOR_CANCEL ;
2009-08-13 20:35:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( oglobals . session ) , SWITCH_LOG_DEBUG ,
2007-03-30 00:13:31 +00:00
" Originate Cancelled by originator termination Cause: %d [%s] \n " , * cause , switch_channel_cause2str ( * cause ) ) ;
2007-03-29 22:34:40 +00:00
2009-10-09 20:48:24 +00:00
} else if ( oglobals . idx = = IDX_TIMEOUT ) {
* cause = SWITCH_CAUSE_NO_ANSWER ;
2007-03-29 22:34:40 +00:00
} else {
2013-12-04 23:46:02 +00:00
if ( oglobals . idx = = IDX_XFER ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( oglobals . session ) , SWITCH_LOG_DEBUG ,
" Originate Resulted in Attended Transfer Cause: %d [%s] \n " , * cause , switch_channel_cause2str ( * cause ) ) ;
} else {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( oglobals . session ) , SWITCH_LOG_DEBUG ,
" Originate Resulted in Error Cause: %d [%s] \n " , * cause , switch_channel_cause2str ( * cause ) ) ;
}
2007-03-29 22:34:40 +00:00
}
}
if ( caller_channel ) {
switch_channel_set_variable ( caller_channel , " originate_disposition " , switch_channel_cause2str ( * cause ) ) ;
2011-08-10 13:38:55 +00:00
switch ( * cause ) {
case SWITCH_CAUSE_ORIGINATOR_CANCEL :
switch_channel_set_variable ( caller_channel , " DIALSTATUS " , " CANCEL " ) ;
break ;
case SWITCH_CAUSE_USER_BUSY :
switch_channel_set_variable ( caller_channel , " DIALSTATUS " , " BUSY " ) ;
break ;
case SWITCH_CAUSE_NO_ANSWER :
switch_channel_set_variable ( caller_channel , " DIALSTATUS " , " NOANSWER " ) ;
break ;
case SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER :
2011-12-15 17:16:41 +00:00
case SWITCH_CAUSE_INVALID_PROFILE :
2011-08-10 13:38:55 +00:00
switch_channel_set_variable ( caller_channel , " DIALSTATUS " , " INVALIDARGS " ) ;
break ;
case SWITCH_CAUSE_CALL_REJECTED :
switch_channel_set_variable ( caller_channel , " DIALSTATUS " , " DONTCALL " ) ;
break ;
default :
switch_channel_set_variable ( caller_channel , " DIALSTATUS " , switch_channel_cause2str ( * cause ) ) ;
break ;
}
2007-03-29 22:34:40 +00:00
}
2010-01-15 21:10:31 +00:00
early_state . ready = 0 ;
2010-02-06 03:38:24 +00:00
2010-01-15 21:10:31 +00:00
if ( oglobals . ethread ) {
switch_status_t st ;
switch_thread_join ( & st , oglobals . ethread ) ;
}
if ( early_state . buffer ) {
switch_buffer_destroy ( & early_state . buffer ) ;
}
2007-03-29 22:34:40 +00:00
if ( ringback . fh ) {
switch_core_file_close ( ringback . fh ) ;
ringback . fh = NULL ;
2008-01-05 01:03:08 +00:00
} else if ( ringback . audio_buffer ) {
teletone_destroy_session ( & ringback . ts ) ;
2015-10-12 22:00:13 +00:00
switch_safe_free ( ringback . mux_buf ) ;
2008-01-05 01:03:08 +00:00
switch_buffer_destroy ( & ringback . audio_buffer ) ;
}
2009-01-19 17:54:54 +00:00
if ( oglobals . session ) {
switch_core_session_reset ( oglobals . session , SWITCH_FALSE , SWITCH_TRUE ) ;
2008-07-15 19:14:15 +00:00
}
2008-07-15 17:39:16 +00:00
2009-04-09 17:17:12 +00:00
if ( switch_core_codec_ready ( & write_codec ) ) {
2008-12-09 20:46:26 +00:00
switch_core_codec_destroy ( & write_codec ) ;
2007-03-29 22:34:40 +00:00
}
2008-05-27 04:30:03 +00:00
2007-03-29 22:34:40 +00:00
for ( i = 0 ; i < and_argc ; i + + ) {
2008-11-11 14:26:21 +00:00
switch_channel_state_t state ;
2014-12-08 18:53:28 +00:00
switch_core_session_t * peer_session ;
2017-01-06 07:10:15 +00:00
char * val ;
2008-11-11 14:26:21 +00:00
2020-05-07 17:04:54 +00:00
if ( ! oglobals . originate_status [ i ] . peer_channel ) {
2007-03-29 22:34:40 +00:00
continue ;
}
2017-01-06 07:10:15 +00:00
2012-10-18 17:22:35 +00:00
if ( session ) {
2020-05-07 17:04:54 +00:00
val = switch_core_session_sprintf ( oglobals . originate_status [ i ] . peer_session , " %s;%s " ,
switch_core_session_get_uuid ( oglobals . originate_status [ i ] . peer_session ) ,
switch_channel_cause2str ( switch_channel_get_cause ( oglobals . originate_status [ i ] . peer_channel ) ) ) ;
2017-01-06 07:10:15 +00:00
2012-10-18 17:22:35 +00:00
switch_channel_add_variable_var_check ( switch_core_session_get_channel ( session ) , " originate_causes " , val , SWITCH_FALSE , SWITCH_STACK_PUSH ) ;
}
2010-02-06 03:38:24 +00:00
if ( status = = SWITCH_STATUS_SUCCESS ) {
2020-05-07 17:04:54 +00:00
switch_channel_clear_flag ( oglobals . originate_status [ i ] . peer_channel , CF_ORIGINATING ) ;
if ( bleg & & * bleg & & * bleg = = oglobals . originate_status [ i ] . peer_session ) {
2008-06-24 22:14:47 +00:00
continue ;
}
2020-05-07 17:04:54 +00:00
} else if ( ( state = switch_channel_get_state ( oglobals . originate_status [ i ] . peer_channel ) ) < CS_HANGUP & &
switch_channel_test_flag ( oglobals . originate_status [ i ] . peer_channel , CF_ORIGINATING ) ) {
if ( ! ( state = = CS_RESET | | switch_channel_test_flag ( oglobals . originate_status [ i ] . peer_channel , CF_TRANSFER ) | |
switch_channel_test_flag ( oglobals . originate_status [ i ] . peer_channel , CF_REDIRECT ) | |
switch_channel_test_flag ( oglobals . originate_status [ i ] . peer_channel , CF_BRIDGED ) ) ) {
2011-11-02 13:54:03 +00:00
if ( caller_channel & & switch_channel_test_flag ( caller_channel , CF_INTERCEPTED ) ) {
2020-05-07 17:04:54 +00:00
switch_channel_set_flag ( oglobals . originate_status [ i ] . peer_channel , CF_INTERCEPT ) ;
2011-11-02 13:54:03 +00:00
}
2020-05-07 17:04:54 +00:00
switch_channel_hangup ( oglobals . originate_status [ i ] . peer_channel , * cause ) ;
2008-11-11 14:26:21 +00:00
}
2007-04-13 22:15:58 +00:00
}
2020-05-07 17:04:54 +00:00
switch_channel_clear_flag ( oglobals . originate_status [ i ] . peer_channel , CF_ORIGINATING ) ;
2008-06-24 22:14:47 +00:00
2020-05-07 17:04:54 +00:00
peer_session = oglobals . originate_status [ i ] . peer_session ;
oglobals . originate_status [ i ] . down_session = oglobals . originate_status [ i ] . peer_session ;
oglobals . originate_status [ i ] . peer_session = NULL ;
oglobals . originate_status [ i ] . peer_channel = NULL ;
2017-01-06 07:10:15 +00:00
2014-12-08 18:53:28 +00:00
switch_core_session_rwunlock ( peer_session ) ;
2007-03-29 22:34:40 +00:00
}
2008-05-27 04:30:03 +00:00
2014-04-16 21:41:40 +00:00
if ( status = = SWITCH_STATUS_SUCCESS | | oglobals . idx = = IDX_XFER ) {
2007-03-29 22:34:40 +00:00
goto outer_for ;
2009-09-18 22:09:47 +00:00
} else {
2011-11-10 16:07:19 +00:00
int ok = 1 ;
2009-09-18 22:09:47 +00:00
2011-11-10 16:07:19 +00:00
if ( fail_on_single_reject & & check_reject & & ! switch_true ( fail_on_single_reject_var ) ) {
for ( i = 0 ; i < and_argc ; i + + ) {
switch_channel_t * pchannel ;
const char * cause_str ;
2017-01-06 07:10:15 +00:00
2020-05-07 17:04:54 +00:00
if ( ! oglobals . originate_status [ i ] . down_session ) {
2011-11-10 16:07:19 +00:00
continue ;
}
2017-01-06 07:10:15 +00:00
2020-05-07 17:04:54 +00:00
pchannel = switch_core_session_get_channel ( oglobals . originate_status [ i ] . down_session ) ;
2011-11-10 16:07:19 +00:00
wait_for_cause ( pchannel ) ;
2011-11-18 19:17:56 +00:00
if ( switch_channel_down_nosig ( pchannel ) ) {
2011-11-10 16:07:19 +00:00
int neg , pos ;
2017-01-06 07:10:15 +00:00
2011-11-10 16:07:19 +00:00
cause_str = switch_channel_cause2str ( switch_channel_get_cause ( pchannel ) ) ;
2011-11-09 16:07:54 +00:00
2011-11-10 16:07:19 +00:00
neg = * fail_on_single_reject_var = = ' ! ' ;
pos = ! ! switch_stristr ( cause_str , fail_on_single_reject_var ) ;
2011-11-09 16:07:54 +00:00
2011-11-10 16:07:19 +00:00
if ( neg ) {
pos = ! pos ;
2017-01-06 07:10:15 +00:00
}
2011-11-10 16:07:19 +00:00
if ( pos ) {
ok = 0 ;
break ;
2009-09-18 22:09:47 +00:00
}
}
}
}
2017-01-06 07:10:15 +00:00
2011-11-10 16:07:19 +00:00
if ( ! ok ) {
2009-09-18 22:09:47 +00:00
goto outer_for ;
}
2009-10-08 17:43:51 +00:00
if ( to & & ! oglobals . continue_on_timeout ) {
goto outer_for ;
}
2007-03-29 22:34:40 +00:00
}
}
}
outer_for :
switch_safe_free ( loop_data ) ;
switch_safe_free ( odata ) ;
2011-08-25 13:27:23 +00:00
switch_safe_free ( oglobals . file ) ;
switch_safe_free ( oglobals . error_file ) ;
2007-04-13 22:15:58 +00:00
if ( bleg & & status ! = SWITCH_STATUS_SUCCESS ) {
* bleg = NULL ;
}
2013-03-28 15:24:49 +00:00
if ( bleg & & ! * bleg & & status = = SWITCH_STATUS_SUCCESS ) {
status = SWITCH_STATUS_FALSE ;
}
2012-12-29 20:57:15 +00:00
if ( bleg & & * bleg ) {
2011-03-13 23:43:23 +00:00
switch_channel_t * bchan = switch_core_session_get_channel ( * bleg ) ;
2009-12-15 01:03:03 +00:00
if ( session & & caller_channel ) {
2009-03-12 16:47:47 +00:00
switch_caller_profile_t * cloned_profile , * peer_profile = switch_channel_get_caller_profile ( switch_core_session_get_channel ( * bleg ) ) ;
2010-02-06 03:38:24 +00:00
2009-03-12 16:47:47 +00:00
if ( peer_profile ) {
2009-03-21 16:47:16 +00:00
if ( ( cloned_profile = switch_caller_profile_clone ( session , peer_profile ) ) ! = 0 ) {
2009-03-12 16:47:47 +00:00
switch_channel_set_originatee_caller_profile ( caller_channel , cloned_profile ) ;
}
}
2011-08-04 14:38:45 +00:00
switch_channel_set_variable ( caller_channel , SWITCH_SIGNAL_BOND_VARIABLE , switch_core_session_get_uuid ( * bleg ) ) ;
2012-03-09 17:43:37 +00:00
// Now main SWITCH_SIGNAL_BOND_VARIABLE is populated, don't need this one anymore...
2012-05-29 18:10:15 +00:00
switch_channel_set_variable ( caller_channel , SWITCH_ORIGINATE_SIGNAL_BOND_VARIABLE , NULL ) ;
2009-03-12 16:47:47 +00:00
}
2017-01-06 07:10:15 +00:00
2011-03-21 17:01:51 +00:00
2012-07-05 17:34:09 +00:00
switch_channel_execute_on ( bchan , SWITCH_CHANNEL_EXECUTE_ON_POST_ORIGINATE_VARIABLE ) ;
switch_channel_api_on ( bchan , SWITCH_CHANNEL_API_ON_POST_ORIGINATE_VARIABLE ) ;
2011-03-21 17:01:51 +00:00
while ( switch_channel_state_change_pending ( bchan ) ) {
switch_cond_next ( ) ;
}
2012-12-05 19:17:50 +00:00
switch_channel_audio_sync ( bchan ) ;
2009-03-12 16:47:47 +00:00
2012-12-05 19:17:50 +00:00
if ( caller_channel ) {
switch_channel_audio_sync ( caller_channel ) ;
}
2008-12-01 16:21:27 +00:00
}
2011-08-19 21:25:26 +00:00
if ( oglobals . session ) {
switch_ivr_parse_all_events ( oglobals . session ) ;
}
2009-01-23 14:16:34 +00:00
if ( oglobals . session & & status = = SWITCH_STATUS_SUCCESS ) {
2009-01-19 17:54:54 +00:00
switch_ivr_sleep ( oglobals . session , 0 , SWITCH_TRUE , NULL ) ;
2008-12-01 16:21:27 +00:00
}
2008-05-27 04:30:03 +00:00
2008-12-05 14:59:24 +00:00
if ( var_event & & var_event ! = ovars ) {
2007-10-04 20:30:59 +00:00
switch_event_destroy ( & var_event ) ;
}
2009-09-18 22:09:47 +00:00
2008-02-18 21:32:35 +00:00
switch_safe_free ( write_frame . data ) ;
2009-09-18 22:09:47 +00:00
switch_safe_free ( fail_on_single_reject_var ) ;
2010-02-06 03:38:24 +00:00
2013-05-22 16:01:39 +00:00
if ( force_reason ! = SWITCH_CAUSE_NONE ) {
* cause = force_reason ;
}
2009-10-07 04:30:19 +00:00
if ( caller_channel ) {
2012-10-30 14:05:41 +00:00
switch_channel_execute_on ( caller_channel , SWITCH_CHANNEL_EXECUTE_ON_POST_ORIGINATE_VARIABLE ) ;
switch_channel_api_on ( caller_channel , SWITCH_CHANNEL_API_ON_POST_ORIGINATE_VARIABLE ) ;
2009-10-07 04:30:19 +00:00
switch_channel_clear_flag ( caller_channel , CF_ORIGINATOR ) ;
switch_channel_clear_flag ( caller_channel , CF_XFER_ZOMBIE ) ;
2009-10-09 20:48:24 +00:00
2013-05-22 16:01:39 +00:00
if ( hangup_on_single_reject ) {
switch_channel_hangup ( caller_channel , * cause ) ;
}
2013-05-21 18:29:05 +00:00
}
2013-05-21 18:22:17 +00:00
2013-05-22 16:01:39 +00:00
2010-05-03 17:13:37 +00:00
switch_core_destroy_memory_pool ( & oglobals . pool ) ;
2007-03-29 22:34:40 +00:00
return status ;
}
2008-01-27 05:02:52 +00:00
2021-03-18 23:28:40 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_dial_handle_list_create ( switch_dial_handle_list_t * * hl )
{
switch_dial_handle_list_t * hlP = NULL ;
switch_memory_pool_t * pool = NULL ;
switch_core_new_memory_pool ( & pool ) ;
switch_assert ( pool ) ;
hlP = switch_core_alloc ( pool , sizeof ( * hlP ) ) ;
switch_assert ( hlP ) ;
hlP - > pool = pool ;
* hl = hlP ;
return SWITCH_STATUS_SUCCESS ;
}
static switch_status_t switch_dial_handle_list_add_handle ( switch_dial_handle_list_t * hl , switch_dial_handle_t * handle )
{
if ( hl - > handle_idx < MAX_PEERS & & handle ) {
hl - > handles [ hl - > handle_idx + + ] = handle ;
return SWITCH_STATUS_SUCCESS ;
}
return SWITCH_STATUS_FALSE ;
}
SWITCH_DECLARE ( switch_status_t ) switch_dial_handle_list_create_handle ( switch_dial_handle_list_t * hl , switch_dial_handle_t * * handle )
{
switch_dial_handle_t * hp = NULL ;
if ( hl - > handle_idx < MAX_PEERS & & switch_dial_handle_create ( & hp ) = = SWITCH_STATUS_SUCCESS & & hp ) {
hl - > handles [ hl - > handle_idx + + ] = hp ;
* handle = hp ;
return SWITCH_STATUS_SUCCESS ;
}
return SWITCH_STATUS_FALSE ;
}
SWITCH_DECLARE ( void ) switch_dial_handle_list_destroy ( switch_dial_handle_list_t * * hl )
{
switch_dial_handle_list_t * hlP = * hl ;
switch_memory_pool_t * pool = NULL ;
* hl = NULL ;
if ( hlP ) {
int i ;
for ( i = 0 ; i < hlP - > handle_idx ; i + + ) {
switch_dial_handle_destroy ( & hlP - > handles [ i ] ) ;
}
switch_event_destroy ( & hlP - > global_vars ) ;
pool = hlP - > pool ;
hlP = NULL ;
switch_core_destroy_memory_pool ( & pool ) ;
}
}
SWITCH_DECLARE ( void ) switch_dial_handle_list_add_global_var ( switch_dial_handle_list_t * hl , const char * var , const char * val )
{
switch_assert ( hl ) ;
if ( ! hl - > global_vars ) {
switch_event_create_plain ( & hl - > global_vars , SWITCH_EVENT_CHANNEL_DATA ) ;
}
switch_event_add_header_string ( hl - > global_vars , SWITCH_STACK_BOTTOM , var , val ) ;
}
SWITCH_DECLARE ( void ) switch_dial_handle_list_add_global_var_printf ( switch_dial_handle_list_t * hl , const char * var , const char * fmt , . . . )
{
int ret = 0 ;
char * data = NULL ;
va_list ap ;
va_start ( ap , fmt ) ;
ret = switch_vasprintf ( & data , fmt , ap ) ;
va_end ( ap ) ;
if ( ret = = - 1 ) {
abort ( ) ;
}
switch_dial_handle_list_add_global_var ( hl , var , data ) ;
free ( data ) ;
}
static switch_status_t switch_dial_handle_dup ( switch_dial_handle_t * * handle , switch_dial_handle_t * todup )
{
int i ;
switch_dial_handle_t * hp ;
if ( ! todup | | ! handle ) {
return SWITCH_STATUS_FALSE ;
}
* handle = NULL ;
switch_dial_handle_create ( & hp ) ;
switch_assert ( hp ) ;
for ( i = 0 ; i < todup - > leg_list_idx ; i + + ) {
int j ;
switch_dial_leg_list_t * ll_todup = todup - > leg_lists [ i ] ;
switch_dial_leg_list_t * ll = NULL ;
switch_dial_handle_add_leg_list ( hp , & ll ) ;
for ( j = 0 ; j < ll_todup - > leg_idx ; j + + ) {
switch_dial_leg_t * leg ;
switch_dial_leg_t * leg_todup = ll_todup - > legs [ j ] ;
switch_dial_leg_list_add_leg ( ll , & leg , leg_todup - > dial_string ) ;
if ( leg_todup - > leg_vars ) {
switch_event_dup ( & leg - > leg_vars , leg_todup - > leg_vars ) ;
}
}
}
if ( todup - > global_vars ) {
switch_event_dup ( & hp - > global_vars , todup - > global_vars ) ;
}
hp - > is_sub = todup - > is_sub ;
* handle = hp ;
return SWITCH_STATUS_SUCCESS ;
}
FS-11346: [core] add api to pass pre-parsed values instead of dial strings to switch_ivr_originate
SWITCH_DECLARE(switch_status_t) switch_dial_handle_create(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_destroy(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_add_leg_list(switch_dial_handle_t *handle, switch_dial_leg_list_t **leg_listP);
SWITCH_DECLARE(void) switch_dial_leg_list_add_leg(switch_dial_leg_list_t *parent, const char *dial_string, switch_dial_leg_t **legP);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var(switch_dial_handle_t *handle, const char *var, const char *val);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var_printf(switch_dial_handle_t *handle, const char *var, const char *fmt, ...);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var(switch_dial_leg_t *leg, const char *var, const char *val);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var_printf(switch_dial_leg_t *leg, const char *var, const char *fmt, ...);
SWITCH_DECLARE(int) switch_dial_handle_get_peers(switch_dial_handle_t *handle, int idx, char **array, int max);
SWITCH_DECLARE(int) switch_dial_handle_get_vars(switch_dial_handle_t *handle, int idx, switch_event_t **array, int max);
SWITCH_DECLARE(switch_event_t *) switch_dial_handle_get_global_vars(switch_dial_handle_t *handle);
SWITCH_DECLARE(switch_event_t *) switch_dial_leg_get_vars(switch_dial_leg_t *leg);
SWITCH_DECLARE(int) switch_dial_handle_get_total(switch_dial_handle_t *handle);
SWITCH_DECLARE(void) switch_ivr_orig_and_bridge(switch_core_session_t *session, const char *data, switch_dial_handle_t *dh);
add switch_dial_handle_t *dh to end of args for switch_ivr_originate
2018-08-16 00:40:30 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_dial_handle_create ( switch_dial_handle_t * * handle )
{
switch_dial_handle_t * hp ;
switch_memory_pool_t * pool = NULL ;
switch_core_new_memory_pool ( & pool ) ;
switch_assert ( pool ) ;
hp = switch_core_alloc ( pool , sizeof ( * hp ) ) ;
switch_assert ( hp ) ;
hp - > pool = pool ;
* handle = hp ;
return SWITCH_STATUS_SUCCESS ;
}
SWITCH_DECLARE ( void ) switch_dial_handle_destroy ( switch_dial_handle_t * * handle )
{
switch_dial_handle_t * hp = * handle ;
switch_memory_pool_t * pool = NULL ;
* handle = NULL ;
if ( hp ) {
int i , j ;
for ( i = 0 ; i < hp - > leg_list_idx ; i + + ) {
for ( j = 0 ; j < hp - > leg_lists [ i ] - > leg_idx ; j + + ) {
switch_event_destroy ( & hp - > leg_lists [ i ] - > legs [ j ] - > leg_vars ) ;
}
}
switch_event_destroy ( & hp - > global_vars ) ;
pool = hp - > pool ;
hp = NULL ;
switch_core_destroy_memory_pool ( & pool ) ;
}
}
SWITCH_DECLARE ( void ) switch_dial_handle_add_leg_list ( switch_dial_handle_t * handle , switch_dial_leg_list_t * * leg_listP )
{
switch_dial_leg_list_t * leg_list ;
switch_assert ( handle ) ;
leg_list = switch_core_alloc ( handle - > pool , sizeof ( * leg_list ) ) ;
leg_list - > handle = handle ;
handle - > leg_lists [ handle - > leg_list_idx + + ] = leg_list ;
* leg_listP = leg_list ;
}
SWITCH_DECLARE ( void ) switch_dial_leg_list_add_leg_printf ( switch_dial_leg_list_t * parent , switch_dial_leg_t * * legP , const char * fmt , . . . )
{
int ret = 0 ;
char * data = NULL ;
va_list ap ;
va_start ( ap , fmt ) ;
ret = switch_vasprintf ( & data , fmt , ap ) ;
va_end ( ap ) ;
if ( ret = = - 1 ) {
abort ( ) ;
}
switch_dial_leg_list_add_leg ( parent , legP , data ) ;
free ( data ) ;
}
SWITCH_DECLARE ( void ) switch_dial_leg_list_add_leg ( switch_dial_leg_list_t * parent , switch_dial_leg_t * * legP , const char * dial_string )
{
switch_dial_leg_t * leg ;
switch_assert ( parent ) ;
leg = switch_core_alloc ( parent - > handle - > pool , sizeof ( * leg ) ) ;
leg - > handle = parent - > handle ;
leg - > dial_string = switch_core_strdup ( parent - > handle - > pool , dial_string ) ;
parent - > legs [ parent - > leg_idx + + ] = leg ;
if ( legP ) {
* legP = leg ;
}
}
SWITCH_DECLARE ( void ) switch_dial_handle_add_global_var ( switch_dial_handle_t * handle , const char * var , const char * val )
{
switch_assert ( handle ) ;
if ( ! handle - > global_vars ) {
switch_event_create_plain ( & handle - > global_vars , SWITCH_EVENT_CHANNEL_DATA ) ;
}
switch_event_add_header_string ( handle - > global_vars , SWITCH_STACK_BOTTOM , var , val ) ;
}
SWITCH_DECLARE ( void ) switch_dial_handle_add_global_var_printf ( switch_dial_handle_t * handle , const char * var , const char * fmt , . . . )
{
int ret = 0 ;
char * data = NULL ;
va_list ap ;
va_start ( ap , fmt ) ;
ret = switch_vasprintf ( & data , fmt , ap ) ;
va_end ( ap ) ;
if ( ret = = - 1 ) {
abort ( ) ;
}
switch_dial_handle_add_global_var ( handle , var , data ) ;
free ( data ) ;
}
SWITCH_DECLARE ( switch_status_t ) switch_dial_handle_add_leg_var ( switch_dial_leg_t * leg , const char * var , const char * val )
{
if ( ! leg ) return SWITCH_STATUS_NOTFOUND ;
if ( ! leg - > leg_vars ) {
switch_event_create_plain ( & leg - > leg_vars , SWITCH_EVENT_CHANNEL_DATA ) ;
}
switch_event_add_header_string ( leg - > leg_vars , SWITCH_STACK_BOTTOM , var , val ) ;
return SWITCH_STATUS_SUCCESS ;
}
SWITCH_DECLARE ( switch_status_t ) switch_dial_handle_add_leg_var_printf ( switch_dial_leg_t * leg , const char * var , const char * fmt , . . . )
{
int ret = 0 ;
char * data = NULL ;
va_list ap ;
switch_status_t status ;
va_start ( ap , fmt ) ;
ret = switch_vasprintf ( & data , fmt , ap ) ;
va_end ( ap ) ;
if ( ret = = - 1 ) {
abort ( ) ;
}
status = switch_dial_handle_add_leg_var ( leg , var , data ) ;
free ( data ) ;
return status ;
}
SWITCH_DECLARE ( int ) switch_dial_handle_get_total ( switch_dial_handle_t * handle )
{
return handle - > leg_list_idx ;
}
SWITCH_DECLARE ( int ) switch_dial_handle_get_peers ( switch_dial_handle_t * handle , int idx , char * * array , int max )
{
int i , j = 0 ;
if ( ! handle - > leg_lists [ idx ] ) return 0 ;
for ( i = 0 ; i < max & & handle - > leg_lists [ idx ] - > legs [ i ] ; i + + ) {
array [ j + + ] = handle - > leg_lists [ idx ] - > legs [ i ] - > dial_string ;
}
return j ;
}
SWITCH_DECLARE ( int ) switch_dial_handle_get_vars ( switch_dial_handle_t * handle , int idx , switch_event_t * * array , int max )
{
int i , j = 0 ;
if ( ! handle - > leg_lists [ idx ] ) return 0 ;
for ( i = 0 ; i < max & & handle - > leg_lists [ idx ] - > legs [ i ] ; i + + ) {
array [ j + + ] = handle - > leg_lists [ idx ] - > legs [ i ] - > leg_vars ;
}
return j ;
}
SWITCH_DECLARE ( switch_event_t * ) switch_dial_handle_get_global_vars ( switch_dial_handle_t * handle )
{
switch_assert ( handle ) ;
return handle - > global_vars ;
}
SWITCH_DECLARE ( switch_event_t * ) switch_dial_leg_get_vars ( switch_dial_leg_t * leg )
{
switch_assert ( leg ) ;
return leg - > leg_vars ;
}
2019-10-30 12:03:43 +00:00
SWITCH_DECLARE ( const char * ) switch_dial_leg_get_var ( switch_dial_leg_t * leg , const char * key )
{
switch_assert ( leg ) ;
return switch_event_get_header ( leg - > leg_vars , key ) ;
}
FS-11346: [core] add api to pass pre-parsed values instead of dial strings to switch_ivr_originate
SWITCH_DECLARE(switch_status_t) switch_dial_handle_create(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_destroy(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_add_leg_list(switch_dial_handle_t *handle, switch_dial_leg_list_t **leg_listP);
SWITCH_DECLARE(void) switch_dial_leg_list_add_leg(switch_dial_leg_list_t *parent, const char *dial_string, switch_dial_leg_t **legP);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var(switch_dial_handle_t *handle, const char *var, const char *val);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var_printf(switch_dial_handle_t *handle, const char *var, const char *fmt, ...);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var(switch_dial_leg_t *leg, const char *var, const char *val);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var_printf(switch_dial_leg_t *leg, const char *var, const char *fmt, ...);
SWITCH_DECLARE(int) switch_dial_handle_get_peers(switch_dial_handle_t *handle, int idx, char **array, int max);
SWITCH_DECLARE(int) switch_dial_handle_get_vars(switch_dial_handle_t *handle, int idx, switch_event_t **array, int max);
SWITCH_DECLARE(switch_event_t *) switch_dial_handle_get_global_vars(switch_dial_handle_t *handle);
SWITCH_DECLARE(switch_event_t *) switch_dial_leg_get_vars(switch_dial_leg_t *leg);
SWITCH_DECLARE(int) switch_dial_handle_get_total(switch_dial_handle_t *handle);
SWITCH_DECLARE(void) switch_ivr_orig_and_bridge(switch_core_session_t *session, const char *data, switch_dial_handle_t *dh);
add switch_dial_handle_t *dh to end of args for switch_ivr_originate
2018-08-16 00:40:30 +00:00
2019-06-18 14:56:57 +00:00
static switch_status_t vars_serialize_json_obj ( switch_event_t * event , cJSON * * json )
{
switch_event_header_t * hp ;
* json = cJSON_CreateObject ( ) ;
for ( hp = event - > headers ; hp ; hp = hp - > next ) {
if ( hp - > name & & hp - > value ) {
cJSON_AddItemToObject ( * json , hp - > name , cJSON_CreateString ( hp - > value ) ) ;
}
}
return SWITCH_STATUS_SUCCESS ;
}
static switch_status_t leg_serialize_json_obj ( switch_dial_leg_t * leg , cJSON * * json )
{
cJSON * vars_json = NULL ;
* json = cJSON_CreateObject ( ) ;
if ( leg - > dial_string ) {
cJSON_AddStringToObject ( * json , " dial_string " , leg - > dial_string ) ;
}
if ( leg - > leg_vars & & vars_serialize_json_obj ( leg - > leg_vars , & vars_json ) = = SWITCH_STATUS_SUCCESS & & vars_json ) {
cJSON_AddItemToObject ( * json , " vars " , vars_json ) ;
}
return SWITCH_STATUS_SUCCESS ;
}
static switch_status_t leg_list_serialize_json_obj ( switch_dial_leg_list_t * ll , cJSON * * json )
{
int i ;
cJSON * legs_json = cJSON_CreateArray ( ) ;
* json = cJSON_CreateObject ( ) ;
cJSON_AddItemToObject ( * json , " legs " , legs_json ) ;
for ( i = 0 ; i < ll - > leg_idx ; i + + ) {
switch_dial_leg_t * leg = ll - > legs [ i ] ;
cJSON * leg_json = NULL ;
if ( leg_serialize_json_obj ( leg , & leg_json ) = = SWITCH_STATUS_SUCCESS & & leg_json ) {
cJSON_AddItemToArray ( legs_json , leg_json ) ;
}
}
return SWITCH_STATUS_SUCCESS ;
}
SWITCH_DECLARE ( switch_status_t ) switch_dial_handle_serialize_json_obj ( switch_dial_handle_t * handle , cJSON * * json )
{
int i ;
cJSON * global_vars_json = NULL ;
cJSON * leg_lists_json = NULL ;
if ( ! handle ) {
return SWITCH_STATUS_FALSE ;
}
* json = cJSON_CreateObject ( ) ;
if ( handle - > global_vars & & vars_serialize_json_obj ( handle - > global_vars , & global_vars_json ) = = SWITCH_STATUS_SUCCESS & & global_vars_json ) {
cJSON_AddItemToObject ( * json , " vars " , global_vars_json ) ;
}
leg_lists_json = cJSON_CreateArray ( ) ;
cJSON_AddItemToObject ( * json , " leg_lists " , leg_lists_json ) ;
for ( i = 0 ; i < handle - > leg_list_idx ; i + + ) {
switch_dial_leg_list_t * ll = handle - > leg_lists [ i ] ;
cJSON * leg_list_json = NULL ;
if ( leg_list_serialize_json_obj ( ll , & leg_list_json ) = = SWITCH_STATUS_SUCCESS & & leg_list_json ) {
cJSON_AddItemToArray ( leg_lists_json , leg_list_json ) ;
}
}
return SWITCH_STATUS_SUCCESS ;
}
SWITCH_DECLARE ( switch_status_t ) switch_dial_handle_serialize_json ( switch_dial_handle_t * handle , char * * str )
{
cJSON * json = NULL ;
if ( switch_dial_handle_serialize_json_obj ( handle , & json ) = = SWITCH_STATUS_SUCCESS & & json ) {
* str = cJSON_PrintUnformatted ( json ) ;
cJSON_Delete ( json ) ;
return SWITCH_STATUS_SUCCESS ;
}
return SWITCH_STATUS_FALSE ;
}
SWITCH_DECLARE ( switch_status_t ) switch_dial_handle_create_json_obj ( switch_dial_handle_t * * handle , cJSON * json )
{
cJSON * vars_json = NULL ;
cJSON * var_json = NULL ;
cJSON * leg_lists_json = NULL ;
if ( ! json ) {
return SWITCH_STATUS_FALSE ;
}
switch_dial_handle_create ( handle ) ;
leg_lists_json = cJSON_GetObjectItem ( json , " leg_lists " ) ;
if ( leg_lists_json & & leg_lists_json - > type = = cJSON_Array ) {
cJSON * leg_list_json = NULL ;
cJSON_ArrayForEach ( leg_list_json , leg_lists_json ) {
cJSON * legs_json = cJSON_GetObjectItem ( leg_list_json , " legs " ) ;
cJSON * leg_json = NULL ;
switch_dial_leg_list_t * ll = NULL ;
if ( ! legs_json | | legs_json - > type ! = cJSON_Array ) {
continue ;
}
switch_dial_handle_add_leg_list ( * handle , & ll ) ;
cJSON_ArrayForEach ( leg_json , legs_json ) {
switch_dial_leg_t * leg = NULL ;
const char * dial_string = NULL ;
if ( ! leg_json | | leg_json - > type ! = cJSON_Object ) {
continue ;
}
dial_string = cJSON_GetObjectCstr ( leg_json , " dial_string " ) ;
if ( ! dial_string ) {
continue ;
}
switch_dial_leg_list_add_leg ( ll , & leg , dial_string ) ;
vars_json = cJSON_GetObjectItem ( leg_json , " vars " ) ;
if ( vars_json & & vars_json - > type = = cJSON_Object ) {
cJSON_ArrayForEach ( var_json , vars_json ) {
if ( ! var_json | | var_json - > type ! = cJSON_String | | ! var_json - > valuestring | | ! var_json - > string ) {
continue ;
}
switch_dial_handle_add_leg_var ( leg , var_json - > string , var_json - > valuestring ) ;
}
}
}
}
}
vars_json = cJSON_GetObjectItem ( json , " vars " ) ;
if ( vars_json & & vars_json - > type = = cJSON_Object ) {
cJSON_ArrayForEach ( var_json , vars_json ) {
if ( ! var_json | | var_json - > type ! = cJSON_String | | ! var_json - > valuestring | | ! var_json - > string ) {
continue ;
}
switch_dial_handle_add_global_var ( * handle , var_json - > string , var_json - > valuestring ) ;
}
}
return SWITCH_STATUS_SUCCESS ;
}
SWITCH_DECLARE ( switch_status_t ) switch_dial_handle_create_json ( switch_dial_handle_t * * handle , const char * handle_string )
{
switch_status_t status ;
cJSON * handle_json = NULL ;
if ( zstr ( handle_string ) ) {
return SWITCH_STATUS_FALSE ;
}
handle_json = cJSON_Parse ( handle_string ) ;
if ( ! handle_json ) {
return SWITCH_STATUS_FALSE ;
}
status = switch_dial_handle_create_json_obj ( handle , handle_json ) ;
cJSON_Delete ( handle_json ) ;
return status ;
}
2021-03-18 23:28:40 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_dial_handle_list_serialize_json_obj ( switch_dial_handle_list_t * hl , cJSON * * json )
{
int i ;
cJSON * global_vars_json = NULL ;
cJSON * handles_json = NULL ;
if ( ! hl ) {
return SWITCH_STATUS_FALSE ;
}
* json = cJSON_CreateObject ( ) ;
if ( hl - > global_vars & & vars_serialize_json_obj ( hl - > global_vars , & global_vars_json ) = = SWITCH_STATUS_SUCCESS & & global_vars_json ) {
cJSON_AddItemToObject ( * json , " vars " , global_vars_json ) ;
}
handles_json = cJSON_CreateArray ( ) ;
cJSON_AddItemToObject ( * json , " handles " , handles_json ) ;
for ( i = 0 ; i < hl - > handle_idx ; i + + ) {
switch_dial_handle_t * handle = hl - > handles [ i ] ;
cJSON * handle_json = NULL ;
if ( switch_dial_handle_serialize_json_obj ( handle , & handle_json ) = = SWITCH_STATUS_SUCCESS & & handle_json ) {
cJSON_AddItemToArray ( handles_json , handle_json ) ;
}
}
return SWITCH_STATUS_SUCCESS ;
}
SWITCH_DECLARE ( switch_status_t ) switch_dial_handle_list_serialize_json ( switch_dial_handle_list_t * hl , char * * str )
{
cJSON * json = NULL ;
if ( switch_dial_handle_list_serialize_json_obj ( hl , & json ) = = SWITCH_STATUS_SUCCESS & & json ) {
* str = cJSON_PrintUnformatted ( json ) ;
cJSON_Delete ( json ) ;
return SWITCH_STATUS_SUCCESS ;
}
return SWITCH_STATUS_FALSE ;
}
SWITCH_DECLARE ( switch_status_t ) switch_dial_handle_list_create_json_obj ( switch_dial_handle_list_t * * hl , cJSON * handle_list_json )
{
cJSON * handle_json = NULL ;
cJSON * handles_json = NULL ;
cJSON * vars_json = NULL ;
* hl = NULL ;
handles_json = cJSON_GetObjectItem ( handle_list_json , " handles " ) ;
if ( ! handles_json | | ! cJSON_IsArray ( handles_json ) ) {
return SWITCH_STATUS_FALSE ;
}
switch_dial_handle_list_create ( hl ) ;
switch_assert ( * hl ) ;
for ( handle_json = handles_json - > child ; handle_json ; handle_json = handle_json - > next ) {
switch_dial_handle_t * handle = NULL ;
if ( switch_dial_handle_create_json_obj ( & handle , handle_json ) = = SWITCH_STATUS_SUCCESS & & handle ) {
if ( switch_dial_handle_list_add_handle ( * hl , handle ) ! = SWITCH_STATUS_SUCCESS ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Not adding remaining dial handles: exceeded limit of %d handles \n " , MAX_PEERS ) ;
switch_dial_handle_destroy ( & handle ) ;
break ;
}
} else {
char * handle_json_str = cJSON_PrintUnformatted ( handle_json ) ;
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Failed to create dial handle: %s \n " , handle_json_str ) ;
switch_safe_free ( handle_json_str ) ;
}
}
if ( ( * hl ) - > handle_idx = = 0 ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_WARNING , " Failed to create dial handle list: no handles added! \n " ) ;
switch_dial_handle_list_destroy ( hl ) ;
return SWITCH_STATUS_FALSE ;
}
vars_json = cJSON_GetObjectItem ( handle_list_json , " vars " ) ;
if ( vars_json & & vars_json - > type = = cJSON_Object ) {
cJSON * var_json = NULL ;
cJSON_ArrayForEach ( var_json , vars_json ) {
if ( ! var_json | | var_json - > type ! = cJSON_String | | ! var_json - > valuestring | | ! var_json - > string ) {
continue ;
}
switch_dial_handle_list_add_global_var ( * hl , var_json - > string , var_json - > valuestring ) ;
}
}
return SWITCH_STATUS_SUCCESS ;
}
SWITCH_DECLARE ( switch_status_t ) switch_dial_handle_list_create_json ( switch_dial_handle_list_t * * hl , const char * handle_list_string )
{
switch_status_t status ;
cJSON * handle_list_json = NULL ;
if ( zstr ( handle_list_string ) ) {
return SWITCH_STATUS_FALSE ;
}
handle_list_json = cJSON_Parse ( handle_list_string ) ;
if ( ! handle_list_json ) {
return SWITCH_STATUS_FALSE ;
}
status = switch_dial_handle_list_create_json_obj ( hl , handle_list_json ) ;
cJSON_Delete ( handle_list_json ) ;
return status ;
}
FS-11346: [core] add api to pass pre-parsed values instead of dial strings to switch_ivr_originate
SWITCH_DECLARE(switch_status_t) switch_dial_handle_create(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_destroy(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_add_leg_list(switch_dial_handle_t *handle, switch_dial_leg_list_t **leg_listP);
SWITCH_DECLARE(void) switch_dial_leg_list_add_leg(switch_dial_leg_list_t *parent, const char *dial_string, switch_dial_leg_t **legP);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var(switch_dial_handle_t *handle, const char *var, const char *val);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var_printf(switch_dial_handle_t *handle, const char *var, const char *fmt, ...);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var(switch_dial_leg_t *leg, const char *var, const char *val);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var_printf(switch_dial_leg_t *leg, const char *var, const char *fmt, ...);
SWITCH_DECLARE(int) switch_dial_handle_get_peers(switch_dial_handle_t *handle, int idx, char **array, int max);
SWITCH_DECLARE(int) switch_dial_handle_get_vars(switch_dial_handle_t *handle, int idx, switch_event_t **array, int max);
SWITCH_DECLARE(switch_event_t *) switch_dial_handle_get_global_vars(switch_dial_handle_t *handle);
SWITCH_DECLARE(switch_event_t *) switch_dial_leg_get_vars(switch_dial_leg_t *leg);
SWITCH_DECLARE(int) switch_dial_handle_get_total(switch_dial_handle_t *handle);
SWITCH_DECLARE(void) switch_ivr_orig_and_bridge(switch_core_session_t *session, const char *data, switch_dial_handle_t *dh);
add switch_dial_handle_t *dh to end of args for switch_ivr_originate
2018-08-16 00:40:30 +00:00
static switch_status_t o_bridge_on_dtmf ( switch_core_session_t * session , void * input , switch_input_type_t itype , void * buf , unsigned int buflen )
{
char * str = ( char * ) buf ;
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 ;
}
2021-03-18 23:28:40 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_ivr_enterprise_orig_and_bridge ( switch_core_session_t * session , const char * data , switch_dial_handle_list_t * hl , switch_call_cause_t * cause )
{
switch_channel_t * caller_channel = switch_core_session_get_channel ( session ) ;
switch_core_session_t * peer_session = NULL ;
switch_status_t status = SWITCH_STATUS_FALSE ;
int fail = 0 ;
if ( ( status = switch_ivr_enterprise_originate ( session ,
& peer_session ,
cause , data , 0 , NULL , NULL , NULL , NULL , NULL , SOF_NONE , NULL , hl ) ) ! = SWITCH_STATUS_SUCCESS ) {
fail = 1 ;
}
if ( fail ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_INFO , " Originate Failed. Cause: %s \n " , switch_channel_cause2str ( * cause ) ) ;
switch_channel_set_variable ( caller_channel , " originate_failed_cause " , switch_channel_cause2str ( * cause ) ) ;
switch_channel_handle_cause ( caller_channel , * cause ) ;
return status ;
} else {
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 ) ;
}
if ( switch_channel_test_flag ( caller_channel , CF_PROXY_MODE ) ) {
switch_ivr_signal_bridge ( session , peer_session ) ;
} else {
char * a_key = ( char * ) switch_channel_get_variable ( caller_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 = o_bridge_on_dtmf ;
} else {
a_key = NULL ;
b_key = NULL ;
}
switch_ivr_multi_threaded_bridge ( session , peer_session , func , a_key , b_key ) ;
}
if ( peer_session ) {
switch_core_session_rwunlock ( peer_session ) ;
}
}
return status ;
}
2019-10-30 12:03:43 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_ivr_orig_and_bridge ( switch_core_session_t * session , const char * data , switch_dial_handle_t * dh , switch_call_cause_t * cause )
FS-11346: [core] add api to pass pre-parsed values instead of dial strings to switch_ivr_originate
SWITCH_DECLARE(switch_status_t) switch_dial_handle_create(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_destroy(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_add_leg_list(switch_dial_handle_t *handle, switch_dial_leg_list_t **leg_listP);
SWITCH_DECLARE(void) switch_dial_leg_list_add_leg(switch_dial_leg_list_t *parent, const char *dial_string, switch_dial_leg_t **legP);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var(switch_dial_handle_t *handle, const char *var, const char *val);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var_printf(switch_dial_handle_t *handle, const char *var, const char *fmt, ...);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var(switch_dial_leg_t *leg, const char *var, const char *val);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var_printf(switch_dial_leg_t *leg, const char *var, const char *fmt, ...);
SWITCH_DECLARE(int) switch_dial_handle_get_peers(switch_dial_handle_t *handle, int idx, char **array, int max);
SWITCH_DECLARE(int) switch_dial_handle_get_vars(switch_dial_handle_t *handle, int idx, switch_event_t **array, int max);
SWITCH_DECLARE(switch_event_t *) switch_dial_handle_get_global_vars(switch_dial_handle_t *handle);
SWITCH_DECLARE(switch_event_t *) switch_dial_leg_get_vars(switch_dial_leg_t *leg);
SWITCH_DECLARE(int) switch_dial_handle_get_total(switch_dial_handle_t *handle);
SWITCH_DECLARE(void) switch_ivr_orig_and_bridge(switch_core_session_t *session, const char *data, switch_dial_handle_t *dh);
add switch_dial_handle_t *dh to end of args for switch_ivr_originate
2018-08-16 00:40:30 +00:00
{
switch_channel_t * caller_channel = switch_core_session_get_channel ( session ) ;
switch_core_session_t * peer_session = NULL ;
switch_status_t status = SWITCH_STATUS_FALSE ;
int fail = 0 ;
if ( ( status = switch_ivr_originate ( session ,
& peer_session ,
2019-10-30 12:03:43 +00:00
cause , data , 0 , NULL , NULL , NULL , NULL , NULL , SOF_NONE , NULL , dh ) ) ! = SWITCH_STATUS_SUCCESS ) {
FS-11346: [core] add api to pass pre-parsed values instead of dial strings to switch_ivr_originate
SWITCH_DECLARE(switch_status_t) switch_dial_handle_create(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_destroy(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_add_leg_list(switch_dial_handle_t *handle, switch_dial_leg_list_t **leg_listP);
SWITCH_DECLARE(void) switch_dial_leg_list_add_leg(switch_dial_leg_list_t *parent, const char *dial_string, switch_dial_leg_t **legP);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var(switch_dial_handle_t *handle, const char *var, const char *val);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var_printf(switch_dial_handle_t *handle, const char *var, const char *fmt, ...);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var(switch_dial_leg_t *leg, const char *var, const char *val);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var_printf(switch_dial_leg_t *leg, const char *var, const char *fmt, ...);
SWITCH_DECLARE(int) switch_dial_handle_get_peers(switch_dial_handle_t *handle, int idx, char **array, int max);
SWITCH_DECLARE(int) switch_dial_handle_get_vars(switch_dial_handle_t *handle, int idx, switch_event_t **array, int max);
SWITCH_DECLARE(switch_event_t *) switch_dial_handle_get_global_vars(switch_dial_handle_t *handle);
SWITCH_DECLARE(switch_event_t *) switch_dial_leg_get_vars(switch_dial_leg_t *leg);
SWITCH_DECLARE(int) switch_dial_handle_get_total(switch_dial_handle_t *handle);
SWITCH_DECLARE(void) switch_ivr_orig_and_bridge(switch_core_session_t *session, const char *data, switch_dial_handle_t *dh);
add switch_dial_handle_t *dh to end of args for switch_ivr_originate
2018-08-16 00:40:30 +00:00
fail = 1 ;
}
if ( fail ) {
2019-10-30 12:03:43 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_INFO , " Originate Failed. Cause: %s \n " , switch_channel_cause2str ( * cause ) ) ;
FS-11346: [core] add api to pass pre-parsed values instead of dial strings to switch_ivr_originate
SWITCH_DECLARE(switch_status_t) switch_dial_handle_create(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_destroy(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_add_leg_list(switch_dial_handle_t *handle, switch_dial_leg_list_t **leg_listP);
SWITCH_DECLARE(void) switch_dial_leg_list_add_leg(switch_dial_leg_list_t *parent, const char *dial_string, switch_dial_leg_t **legP);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var(switch_dial_handle_t *handle, const char *var, const char *val);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var_printf(switch_dial_handle_t *handle, const char *var, const char *fmt, ...);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var(switch_dial_leg_t *leg, const char *var, const char *val);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var_printf(switch_dial_leg_t *leg, const char *var, const char *fmt, ...);
SWITCH_DECLARE(int) switch_dial_handle_get_peers(switch_dial_handle_t *handle, int idx, char **array, int max);
SWITCH_DECLARE(int) switch_dial_handle_get_vars(switch_dial_handle_t *handle, int idx, switch_event_t **array, int max);
SWITCH_DECLARE(switch_event_t *) switch_dial_handle_get_global_vars(switch_dial_handle_t *handle);
SWITCH_DECLARE(switch_event_t *) switch_dial_leg_get_vars(switch_dial_leg_t *leg);
SWITCH_DECLARE(int) switch_dial_handle_get_total(switch_dial_handle_t *handle);
SWITCH_DECLARE(void) switch_ivr_orig_and_bridge(switch_core_session_t *session, const char *data, switch_dial_handle_t *dh);
add switch_dial_handle_t *dh to end of args for switch_ivr_originate
2018-08-16 00:40:30 +00:00
2019-10-30 12:03:43 +00:00
switch_channel_set_variable ( caller_channel , " originate_failed_cause " , switch_channel_cause2str ( * cause ) ) ;
FS-11346: [core] add api to pass pre-parsed values instead of dial strings to switch_ivr_originate
SWITCH_DECLARE(switch_status_t) switch_dial_handle_create(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_destroy(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_add_leg_list(switch_dial_handle_t *handle, switch_dial_leg_list_t **leg_listP);
SWITCH_DECLARE(void) switch_dial_leg_list_add_leg(switch_dial_leg_list_t *parent, const char *dial_string, switch_dial_leg_t **legP);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var(switch_dial_handle_t *handle, const char *var, const char *val);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var_printf(switch_dial_handle_t *handle, const char *var, const char *fmt, ...);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var(switch_dial_leg_t *leg, const char *var, const char *val);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var_printf(switch_dial_leg_t *leg, const char *var, const char *fmt, ...);
SWITCH_DECLARE(int) switch_dial_handle_get_peers(switch_dial_handle_t *handle, int idx, char **array, int max);
SWITCH_DECLARE(int) switch_dial_handle_get_vars(switch_dial_handle_t *handle, int idx, switch_event_t **array, int max);
SWITCH_DECLARE(switch_event_t *) switch_dial_handle_get_global_vars(switch_dial_handle_t *handle);
SWITCH_DECLARE(switch_event_t *) switch_dial_leg_get_vars(switch_dial_leg_t *leg);
SWITCH_DECLARE(int) switch_dial_handle_get_total(switch_dial_handle_t *handle);
SWITCH_DECLARE(void) switch_ivr_orig_and_bridge(switch_core_session_t *session, const char *data, switch_dial_handle_t *dh);
add switch_dial_handle_t *dh to end of args for switch_ivr_originate
2018-08-16 00:40:30 +00:00
2019-10-30 12:03:43 +00:00
switch_channel_handle_cause ( caller_channel , * cause ) ;
FS-11346: [core] add api to pass pre-parsed values instead of dial strings to switch_ivr_originate
SWITCH_DECLARE(switch_status_t) switch_dial_handle_create(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_destroy(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_add_leg_list(switch_dial_handle_t *handle, switch_dial_leg_list_t **leg_listP);
SWITCH_DECLARE(void) switch_dial_leg_list_add_leg(switch_dial_leg_list_t *parent, const char *dial_string, switch_dial_leg_t **legP);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var(switch_dial_handle_t *handle, const char *var, const char *val);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var_printf(switch_dial_handle_t *handle, const char *var, const char *fmt, ...);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var(switch_dial_leg_t *leg, const char *var, const char *val);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var_printf(switch_dial_leg_t *leg, const char *var, const char *fmt, ...);
SWITCH_DECLARE(int) switch_dial_handle_get_peers(switch_dial_handle_t *handle, int idx, char **array, int max);
SWITCH_DECLARE(int) switch_dial_handle_get_vars(switch_dial_handle_t *handle, int idx, switch_event_t **array, int max);
SWITCH_DECLARE(switch_event_t *) switch_dial_handle_get_global_vars(switch_dial_handle_t *handle);
SWITCH_DECLARE(switch_event_t *) switch_dial_leg_get_vars(switch_dial_leg_t *leg);
SWITCH_DECLARE(int) switch_dial_handle_get_total(switch_dial_handle_t *handle);
SWITCH_DECLARE(void) switch_ivr_orig_and_bridge(switch_core_session_t *session, const char *data, switch_dial_handle_t *dh);
add switch_dial_handle_t *dh to end of args for switch_ivr_originate
2018-08-16 00:40:30 +00:00
2019-10-30 12:03:43 +00:00
return status ;
FS-11346: [core] add api to pass pre-parsed values instead of dial strings to switch_ivr_originate
SWITCH_DECLARE(switch_status_t) switch_dial_handle_create(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_destroy(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_add_leg_list(switch_dial_handle_t *handle, switch_dial_leg_list_t **leg_listP);
SWITCH_DECLARE(void) switch_dial_leg_list_add_leg(switch_dial_leg_list_t *parent, const char *dial_string, switch_dial_leg_t **legP);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var(switch_dial_handle_t *handle, const char *var, const char *val);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var_printf(switch_dial_handle_t *handle, const char *var, const char *fmt, ...);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var(switch_dial_leg_t *leg, const char *var, const char *val);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var_printf(switch_dial_leg_t *leg, const char *var, const char *fmt, ...);
SWITCH_DECLARE(int) switch_dial_handle_get_peers(switch_dial_handle_t *handle, int idx, char **array, int max);
SWITCH_DECLARE(int) switch_dial_handle_get_vars(switch_dial_handle_t *handle, int idx, switch_event_t **array, int max);
SWITCH_DECLARE(switch_event_t *) switch_dial_handle_get_global_vars(switch_dial_handle_t *handle);
SWITCH_DECLARE(switch_event_t *) switch_dial_leg_get_vars(switch_dial_leg_t *leg);
SWITCH_DECLARE(int) switch_dial_handle_get_total(switch_dial_handle_t *handle);
SWITCH_DECLARE(void) switch_ivr_orig_and_bridge(switch_core_session_t *session, const char *data, switch_dial_handle_t *dh);
add switch_dial_handle_t *dh to end of args for switch_ivr_originate
2018-08-16 00:40:30 +00:00
} else {
switch_channel_t * peer_channel = switch_core_session_get_channel ( peer_session ) ;
2019-10-30 12:03:43 +00:00
FS-11346: [core] add api to pass pre-parsed values instead of dial strings to switch_ivr_originate
SWITCH_DECLARE(switch_status_t) switch_dial_handle_create(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_destroy(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_add_leg_list(switch_dial_handle_t *handle, switch_dial_leg_list_t **leg_listP);
SWITCH_DECLARE(void) switch_dial_leg_list_add_leg(switch_dial_leg_list_t *parent, const char *dial_string, switch_dial_leg_t **legP);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var(switch_dial_handle_t *handle, const char *var, const char *val);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var_printf(switch_dial_handle_t *handle, const char *var, const char *fmt, ...);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var(switch_dial_leg_t *leg, const char *var, const char *val);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var_printf(switch_dial_leg_t *leg, const char *var, const char *fmt, ...);
SWITCH_DECLARE(int) switch_dial_handle_get_peers(switch_dial_handle_t *handle, int idx, char **array, int max);
SWITCH_DECLARE(int) switch_dial_handle_get_vars(switch_dial_handle_t *handle, int idx, switch_event_t **array, int max);
SWITCH_DECLARE(switch_event_t *) switch_dial_handle_get_global_vars(switch_dial_handle_t *handle);
SWITCH_DECLARE(switch_event_t *) switch_dial_leg_get_vars(switch_dial_leg_t *leg);
SWITCH_DECLARE(int) switch_dial_handle_get_total(switch_dial_handle_t *handle);
SWITCH_DECLARE(void) switch_ivr_orig_and_bridge(switch_core_session_t *session, const char *data, switch_dial_handle_t *dh);
add switch_dial_handle_t *dh to end of args for switch_ivr_originate
2018-08-16 00:40:30 +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 ) ) ) {
switch_channel_set_flag ( caller_channel , CF_BYPASS_MEDIA_AFTER_BRIDGE ) ;
}
if ( switch_channel_test_flag ( caller_channel , CF_PROXY_MODE ) ) {
switch_ivr_signal_bridge ( session , peer_session ) ;
} else {
char * a_key = ( char * ) switch_channel_get_variable ( caller_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 = o_bridge_on_dtmf ;
} else {
a_key = NULL ;
b_key = NULL ;
}
switch_ivr_multi_threaded_bridge ( session , peer_session , func , a_key , b_key ) ;
}
if ( peer_session ) {
switch_core_session_rwunlock ( peer_session ) ;
}
}
2019-10-30 12:03:43 +00:00
return status ;
FS-11346: [core] add api to pass pre-parsed values instead of dial strings to switch_ivr_originate
SWITCH_DECLARE(switch_status_t) switch_dial_handle_create(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_destroy(switch_dial_handle_t **handle);
SWITCH_DECLARE(void) switch_dial_handle_add_leg_list(switch_dial_handle_t *handle, switch_dial_leg_list_t **leg_listP);
SWITCH_DECLARE(void) switch_dial_leg_list_add_leg(switch_dial_leg_list_t *parent, const char *dial_string, switch_dial_leg_t **legP);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var(switch_dial_handle_t *handle, const char *var, const char *val);
SWITCH_DECLARE(void) switch_dial_handle_add_global_var_printf(switch_dial_handle_t *handle, const char *var, const char *fmt, ...);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var(switch_dial_leg_t *leg, const char *var, const char *val);
SWITCH_DECLARE(switch_status_t) switch_dial_handle_add_leg_var_printf(switch_dial_leg_t *leg, const char *var, const char *fmt, ...);
SWITCH_DECLARE(int) switch_dial_handle_get_peers(switch_dial_handle_t *handle, int idx, char **array, int max);
SWITCH_DECLARE(int) switch_dial_handle_get_vars(switch_dial_handle_t *handle, int idx, switch_event_t **array, int max);
SWITCH_DECLARE(switch_event_t *) switch_dial_handle_get_global_vars(switch_dial_handle_t *handle);
SWITCH_DECLARE(switch_event_t *) switch_dial_leg_get_vars(switch_dial_leg_t *leg);
SWITCH_DECLARE(int) switch_dial_handle_get_total(switch_dial_handle_t *handle);
SWITCH_DECLARE(void) switch_ivr_orig_and_bridge(switch_core_session_t *session, const char *data, switch_dial_handle_t *dh);
add switch_dial_handle_t *dh to end of args for switch_ivr_originate
2018-08-16 00:40:30 +00:00
}
2008-01-27 05:02:52 +00:00
/* For Emacs:
* Local Variables :
* mode : c
2008-02-03 22:14:57 +00:00
* indent - tabs - mode : t
2008-01-27 05:02:52 +00:00
* tab - width : 4
* c - basic - offset : 4
* End :
* For VIM :
2013-06-25 16:50:17 +00:00
* vim : set softtabstop = 4 shiftwidth = 4 tabstop = 4 noet :
2008-01-27 05:02:52 +00:00
*/