RTS API Documentation  1.10.11
Data Structures | Macros | Typedefs | Enumerations | Functions
switch_ivr_async.c File Reference
#include <switch.h>
#include "private/switch_core_pvt.h"
#include <speex/speex_preprocess.h>
#include <speex/speex_echo.h>
+ Include dependency graph for switch_ivr_async.c:

Go to the source code of this file.

Data Structures

struct  switch_ivr_dmachine_binding
 
struct  dm_binding_head_t
 
struct  switch_ivr_dmachine
 
struct  displace_helper_t
 
struct  record_helper
 
struct  eavesdrop_pvt
 
struct  exec_cb_data
 
struct  pp_cb_t
 
struct  switch_session_audio_t
 
struct  switch_inband_dtmf_t
 
struct  switch_inband_dtmf_generate_t
 
struct  switch_tone_detect_t
 
struct  switch_tone_container_t
 
struct  dtmf_meta_app_t
 
struct  dtmf_meta_settings_t
 
struct  dtmf_meta_data_t
 
struct  bch_t
 
struct  play_and_detect_speech_state_t
 
struct  speech_thread_handle
 
struct  hangup_helper
 
struct  transfer_helper
 
struct  broadcast_helper
 
struct  oht_s
 

Macros

#define MAX_TONES   16
 
#define SWITCH_META_VAR_KEY   "__dtmf_meta"
 
#define SWITCH_BLOCK_DTMF_KEY   "__dtmf_block"
 
#define PLAY_AND_DETECT_DONE   1
 
#define PLAY_AND_DETECT_DONE_RECOGNIZING   2
 

Typedefs

typedef struct switch_ivr_dmachine_binding switch_ivr_dmachine_binding_t
 
typedef struct oht_s overly_helper_t
 

Enumerations

enum  dm_match_t {
  DM_MATCH_NONE, DM_MATCH_EXACT, DM_MATCH_PARTIAL, DM_MATCH_BOTH,
  DM_MATCH_NEVER
}
 

Functions

static const char * get_recording_var (switch_channel_t *channel, switch_event_t *vars, const char *name)
 
static int recording_var_true (switch_channel_t *channel, switch_event_t *vars, const char *name)
 
static switch_status_t speech_on_dtmf (switch_core_session_t *session, const switch_dtmf_t *dtmf, switch_dtmf_direction_t direction)
 
switch_status_t switch_ivr_dmachine_last_ping (switch_ivr_dmachine_t *dmachine)
 
switch_digit_action_target_t switch_ivr_dmachine_get_target (switch_ivr_dmachine_t *dmachine)
 
void switch_ivr_dmachine_set_target (switch_ivr_dmachine_t *dmachine, switch_digit_action_target_t target)
 
void switch_ivr_dmachine_set_match_callback (switch_ivr_dmachine_t *dmachine, switch_ivr_dmachine_callback_t match_callback)
 
void switch_ivr_dmachine_set_nonmatch_callback (switch_ivr_dmachine_t *dmachine, switch_ivr_dmachine_callback_t nonmatch_callback)
 
const char * switch_ivr_dmachine_get_name (switch_ivr_dmachine_t *dmachine)
 
switch_status_t switch_ivr_dmachine_create (switch_ivr_dmachine_t **dmachine_p, const char *name, switch_memory_pool_t *pool, uint32_t digit_timeout_ms, uint32_t input_timeout_ms, switch_ivr_dmachine_callback_t match_callback, switch_ivr_dmachine_callback_t nonmatch_callback, void *user_data)
 
void switch_ivr_dmachine_set_digit_timeout_ms (switch_ivr_dmachine_t *dmachine, uint32_t digit_timeout_ms)
 
void switch_ivr_dmachine_set_input_timeout_ms (switch_ivr_dmachine_t *dmachine, uint32_t input_timeout_ms)
 
void switch_ivr_dmachine_destroy (switch_ivr_dmachine_t **dmachine)
 
switch_status_t switch_ivr_dmachine_set_terminators (switch_ivr_dmachine_t *dmachine, const char *terminators)
 
switch_status_t switch_ivr_dmachine_set_realm (switch_ivr_dmachine_t *dmachine, const char *realm)
 
switch_status_t switch_ivr_dmachine_clear_realm (switch_ivr_dmachine_t *dmachine, const char *realm)
 
switch_status_t switch_ivr_dmachine_bind (switch_ivr_dmachine_t *dmachine, const char *realm, const char *digits, switch_byte_t is_priority, int32_t key, switch_ivr_dmachine_callback_t callback, void *user_data)
 
static dm_match_t switch_ivr_dmachine_check_match (switch_ivr_dmachine_t *dmachine, switch_bool_t is_timeout)
 
static switch_bool_t switch_ivr_dmachine_check_timeout (switch_ivr_dmachine_t *dmachine)
 
switch_ivr_dmachine_match_tswitch_ivr_dmachine_get_match (switch_ivr_dmachine_t *dmachine)
 
const char * switch_ivr_dmachine_get_failed_digits (switch_ivr_dmachine_t *dmachine)
 
switch_status_t switch_ivr_dmachine_ping (switch_ivr_dmachine_t *dmachine, switch_ivr_dmachine_match_t **match_p)
 
switch_status_t switch_ivr_dmachine_feed (switch_ivr_dmachine_t *dmachine, const char *digits, switch_ivr_dmachine_match_t **match)
 
switch_bool_t switch_ivr_dmachine_is_parsing (switch_ivr_dmachine_t *dmachine)
 
switch_status_t switch_ivr_dmachine_clear (switch_ivr_dmachine_t *dmachine)
 
switch_status_t switch_ivr_session_echo (switch_core_session_t *session, switch_input_args_t *args)
 
  • NEEDDESC -
More...
 
static switch_bool_t write_displace_callback (switch_media_bug_t *bug, void *user_data, switch_abc_type_t type)
 
static switch_bool_t read_displace_callback (switch_media_bug_t *bug, void *user_data, switch_abc_type_t type)
 
switch_status_t switch_ivr_stop_displace_session (switch_core_session_t *session, const char *file)
 Stop displacing a session. More...
 
switch_status_t switch_ivr_displace_session (switch_core_session_t *session, const char *file, uint32_t limit, const char *flags)
 displace the media for a session with the audio from a file More...
 
static switch_status_t record_helper_destroy (struct record_helper **rh, switch_core_session_t *session)
 
static void set_completion_cause (struct record_helper *rh, const char *completion_cause)
 
static switch_bool_t is_silence_frame (switch_frame_t *frame, int silence_threshold, switch_codec_implementation_t *codec_impl)
 
static void merge_recording_variables (struct record_helper *rh, switch_event_t *event)
 
static void send_record_stop_event (switch_channel_t *channel, switch_codec_implementation_t *read_impl, struct record_helper *rh)
 
static void *SWITCH_THREAD_FUNC recording_thread (switch_thread_t *thread, void *obj)
 
static void record_helper_post_process (struct record_helper *rh, switch_core_session_t *session)
 
static switch_bool_t record_callback (switch_media_bug_t *bug, void *user_data, switch_abc_type_t type)
 
static switch_bool_t text_callback (switch_media_bug_t *bug, void *user_data, switch_abc_type_t type)
 
switch_status_t switch_ivr_capture_text (switch_core_session_t *session, switch_bool_t on)
 
switch_status_t switch_ivr_record_session_mask (switch_core_session_t *session, const char *file, switch_bool_t on)
 
switch_status_t switch_ivr_record_session_pause (switch_core_session_t *session, const char *file, switch_bool_t on)
 
switch_status_t switch_ivr_stop_record_session (switch_core_session_t *session, const char *file)
 Stop Recording a session. More...
 
static void * switch_ivr_record_user_data_dup (switch_core_session_t *session, void *user_data)
 
switch_status_t switch_ivr_transfer_recordings (switch_core_session_t *orig_session, switch_core_session_t *new_session)
 
static switch_status_t video_eavesdrop_callback (switch_core_session_t *session, switch_frame_t *frame, void *user_data)
 
static switch_bool_t eavesdrop_callback (switch_media_bug_t *bug, void *user_data, switch_abc_type_t type)
 
switch_status_t switch_ivr_eavesdrop_pop_eavesdropper (switch_core_session_t *session, switch_core_session_t **sessionp)
 
static void exec_cb (switch_media_bug_t *bug, void *user_data)
 
static void display_exec_cb (switch_media_bug_t *bug, void *user_data)
 
switch_status_t switch_ivr_eavesdrop_exec_all (switch_core_session_t *session, const char *app, const char *arg)
 
switch_status_t switch_ivr_eavesdrop_update_display (switch_core_session_t *session, const char *name, const char *number)
 
static uint32_t switch_gcd (uint32_t x, uint32_t y)
 
static uint32_t switch_lcm (uint32_t x, uint32_t y)
 
switch_status_t switch_ivr_eavesdrop_session (switch_core_session_t *session, const char *uuid, const char *require_group, switch_eavesdrop_flag_t flags)
 Eavesdrop on a another session. More...
 
static switch_status_t record_helper_create (struct record_helper **rh, switch_core_session_t *session)
 
switch_status_t switch_ivr_record_session_event (switch_core_session_t *session, const char *file, uint32_t limit, switch_file_handle_t *fh, switch_event_t *vars)
 
switch_status_t switch_ivr_record_session (switch_core_session_t *session, const char *file, uint32_t limit, switch_file_handle_t *fh)
 Record a session to disk. More...
 
static switch_bool_t preprocess_callback (switch_media_bug_t *bug, void *user_data, switch_abc_type_t type)
 
switch_status_t switch_ivr_preprocess_session (switch_core_session_t *session, const char *cmds)
 
static switch_bool_t session_audio_callback (switch_media_bug_t *bug, void *user_data, switch_abc_type_t type)
 
switch_status_t switch_ivr_stop_session_audio (switch_core_session_t *session)
 
switch_status_t switch_ivr_session_audio (switch_core_session_t *session, const char *cmd, const char *direction, int level)
 
static switch_bool_t inband_dtmf_callback (switch_media_bug_t *bug, void *user_data, switch_abc_type_t type)
 
switch_status_t switch_ivr_stop_inband_dtmf_session (switch_core_session_t *session)
 Stop looking for DTMF inband. More...
 
switch_status_t switch_ivr_inband_dtmf_session (switch_core_session_t *session)
 Start looking for DTMF inband. More...
 
static int teletone_dtmf_generate_handler (teletone_generation_session_t *ts, teletone_tone_map_t *map)
 
static switch_status_t generate_on_dtmf (switch_core_session_t *session, const switch_dtmf_t *dtmf, switch_dtmf_direction_t direction)
 
static switch_bool_t inband_dtmf_generate_callback (switch_media_bug_t *bug, void *user_data, switch_abc_type_t type)
 
switch_status_t switch_ivr_stop_inband_dtmf_generate_session (switch_core_session_t *session)
 Stop generating DTMF inband. More...
 
switch_status_t switch_ivr_inband_dtmf_generate_session (switch_core_session_t *session, switch_bool_t read_stream)
 Start generating DTMF inband. More...
 
static void tone_detect_set_total_time (switch_tone_container_t *cont, int index)
 
static switch_status_t tone_on_dtmf (switch_core_session_t *session, const switch_dtmf_t *dtmf, switch_dtmf_direction_t direction)
 
static switch_bool_t tone_detect_callback (switch_media_bug_t *bug, void *user_data, switch_abc_type_t type)
 
switch_status_t switch_ivr_stop_tone_detect_session (switch_core_session_t *session)
 Stop looking for TONES. More...
 
switch_status_t switch_ivr_tone_detect_session (switch_core_session_t *session, const char *key, const char *tone_spec, const char *flags, time_t timeout, int hits, const char *app, const char *data, switch_tone_detect_callback_t callback)
 Start looking for TONES. More...
 
static void *SWITCH_THREAD_FUNC bcast_thread (switch_thread_t *thread, void *obj)
 
void switch_ivr_broadcast_in_thread (switch_core_session_t *session, const char *app, int flags)
 
static switch_status_t meta_on_dtmf (switch_core_session_t *session, const switch_dtmf_t *dtmf, switch_dtmf_direction_t direction)
 
switch_status_t switch_ivr_unbind_dtmf_meta_session (switch_core_session_t *session, uint32_t key)
 
static switch_status_t block_on_dtmf (switch_core_session_t *session, const switch_dtmf_t *dtmf, switch_dtmf_direction_t direction)
 
switch_status_t switch_ivr_unblock_dtmf_session (switch_core_session_t *session)
 
switch_status_t switch_ivr_block_dtmf_session (switch_core_session_t *session)
 
switch_status_t switch_ivr_bind_dtmf_meta_session (switch_core_session_t *session, uint32_t key, switch_bind_flag_t bind_flags, const char *app)
 
static void deliver_asr_event (switch_core_session_t *session, switch_event_t *event, switch_input_args_t *args)
 
static switch_status_t play_and_detect_input_callback (switch_core_session_t *session, void *input, switch_input_type_t input_type, void *data, unsigned int len)
 
switch_status_t switch_ivr_play_and_detect_speech (switch_core_session_t *session, const char *file, const char *mod_name, const char *grammar, char **result, uint32_t input_timeout, switch_input_args_t *args)
 play a file to the session while doing speech recognition. More...
 
static void *SWITCH_THREAD_FUNC speech_thread (switch_thread_t *thread, void *obj)
 
static switch_bool_t speech_callback (switch_media_bug_t *bug, void *user_data, switch_abc_type_t type)
 
switch_status_t switch_ivr_stop_detect_speech (switch_core_session_t *session)
 Stop background Speech detection on a session. More...
 
switch_status_t switch_ivr_pause_detect_speech (switch_core_session_t *session)
 Pause background Speech detection on a session. More...
 
switch_status_t switch_ivr_resume_detect_speech (switch_core_session_t *session)
 Resume background Speech detection on a session. More...
 
switch_status_t switch_ivr_detect_speech_load_grammar (switch_core_session_t *session, const char *grammar, const char *name)
 Load a grammar on a background speech detection handle. More...
 
switch_status_t switch_ivr_set_param_detect_speech (switch_core_session_t *session, const char *name, const char *val)
 
switch_status_t switch_ivr_detect_speech_start_input_timers (switch_core_session_t *session)
 Start input timers on a background speech detection handle. More...
 
switch_status_t switch_ivr_detect_speech_unload_grammar (switch_core_session_t *session, const char *name)
 Unload a grammar on a background speech detection handle. More...
 
switch_status_t switch_ivr_detect_speech_enable_grammar (switch_core_session_t *session, const char *name)
 Enable a grammar on a background speech detection handle. More...
 
switch_status_t switch_ivr_detect_speech_disable_grammar (switch_core_session_t *session, const char *name)
 Disable a grammar on a background speech detection handle. More...
 
switch_status_t switch_ivr_detect_speech_disable_all_grammars (switch_core_session_t *session)
 Disable all grammars on a background speech detection handle. More...
 
switch_status_t switch_ivr_detect_speech_init (switch_core_session_t *session, const char *mod_name, const char *dest, switch_asr_handle_t *ah)
 Initialize background Speech detection on a session, so that parameters can be set, and grammars loaded. After calling this function, it is possible to call switch_ivr_set_param_detect_speech() to set recognition parameters. Calling switch_ivr_detect_speech_load_grammar() starts the speech recognition. More...
 
static void asr_set_json_text_params (switch_core_session_t *session, switch_asr_handle_t *ah)
 
switch_status_t switch_ivr_detect_speech (switch_core_session_t *session, const char *mod_name, const char *grammar, const char *name, const char *dest, switch_asr_handle_t *ah)
 Engage background Speech detection on a session. More...
 
 SWITCH_STANDARD_SCHED_FUNC (sch_hangup_callback)
 
uint32_t switch_ivr_schedule_hangup (time_t runtime, const char *uuid, switch_call_cause_t cause, switch_bool_t bleg)
 Hangup an existing session in the future. More...
 
 SWITCH_STANDARD_SCHED_FUNC (sch_transfer_callback)
 
uint32_t switch_ivr_schedule_transfer (time_t runtime, const char *uuid, char *extension, char *dialplan, char *context)
 Transfer an existing session to another location in the future. More...
 
 SWITCH_STANDARD_SCHED_FUNC (sch_broadcast_callback)
 
uint32_t switch_ivr_schedule_broadcast (time_t runtime, const char *uuid, const char *path, switch_media_flag_t flags)
 Signal the session to broadcast audio in the future. More...
 
switch_status_t switch_ivr_broadcast (const char *uuid, const char *path, switch_media_flag_t flags)
 Signal the session to broadcast audio. More...
 
static switch_bool_t video_write_overlay_callback (switch_media_bug_t *bug, void *user_data, switch_abc_type_t type)
 
switch_status_t switch_ivr_stop_video_write_overlay_session (switch_core_session_t *session)
 
switch_status_t switch_ivr_video_write_overlay_session (switch_core_session_t *session, const char *img_path, switch_img_position_t pos, uint8_t alpha)
 

Macro Definition Documentation

◆ MAX_TONES

#define MAX_TONES   16

Definition at line 4124 of file switch_ivr_async.c.

Referenced by switch_ivr_tone_detect_session().

◆ PLAY_AND_DETECT_DONE

#define PLAY_AND_DETECT_DONE   1

◆ PLAY_AND_DETECT_DONE_RECOGNIZING

#define PLAY_AND_DETECT_DONE_RECOGNIZING   2

◆ SWITCH_BLOCK_DTMF_KEY

#define SWITCH_BLOCK_DTMF_KEY   "__dtmf_block"

◆ SWITCH_META_VAR_KEY

#define SWITCH_META_VAR_KEY   "__dtmf_meta"

Typedef Documentation

◆ overly_helper_t

typedef struct oht_s overly_helper_t

◆ switch_ivr_dmachine_binding_t

Definition at line 54 of file switch_ivr_async.c.

Enumeration Type Documentation

◆ dm_match_t

enum dm_match_t
Enumerator
DM_MATCH_NONE 
DM_MATCH_EXACT 
DM_MATCH_PARTIAL 
DM_MATCH_BOTH 
DM_MATCH_NEVER 

Definition at line 353 of file switch_ivr_async.c.

Function Documentation

◆ asr_set_json_text_params()

static void asr_set_json_text_params ( switch_core_session_t session,
switch_asr_handle_t ah 
)
static

Definition at line 5434 of file switch_ivr_async.c.

References switch_event::headers, switch_event_header::name, switch_event_header::next, switch_channel_get_variables(), SWITCH_CHANNEL_LOG, switch_core_asr_text_param(), switch_core_get_variables(), switch_core_session_get_channel(), switch_event_destroy(), switch_event_merge(), SWITCH_LOG_DEBUG, switch_log_printf(), switch_event_header::value, and zstr.

Referenced by switch_ivr_detect_speech().

5435 {
5437  switch_event_t *event, *cevent;
5438  const char *variable_prefix = "asr_json_param_";
5440 
5441  switch_core_get_variables(&event);
5442  switch_channel_get_variables(channel, &cevent);
5443  switch_event_merge(event, cevent);
5444 
5445  for (hp = event->headers; hp; hp = hp->next) {
5446  char *var = hp->name;
5447  char *val = hp->value;
5448 
5449  if (!strncasecmp(var, variable_prefix, strlen(variable_prefix)) && !zstr(val)) {
5450  char *json_var = var + strlen(variable_prefix);
5451 
5452  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "setting json param %s = %s\n", json_var, val);
5453  switch_core_asr_text_param(ah, json_var, val);
5454  }
5455  }
5456 
5457  switch_event_destroy(&event);
5458  switch_event_destroy(&cevent);
5459 }
#define SWITCH_CHANNEL_LOG
Representation of an event.
Definition: switch_event.h:80
An event Header.
Definition: switch_event.h:65
#define zstr(x)
Definition: switch_utils.h:314
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
switch_status_t switch_core_get_variables(switch_event_t **event)
Definition: switch_core.c:386
void switch_event_merge(switch_event_t *event, switch_event_t *tomerge)
switch_status_t switch_channel_get_variables(switch_channel_t *channel, switch_event_t **event)
struct switch_event_header * next
Definition: switch_event.h:76
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
void switch_event_destroy(switch_event_t **event)
Destroy an event.
void switch_core_asr_text_param(switch_asr_handle_t *ah, char *param, const char *val)
Set a text parameter on an asr handle.
switch_event_header_t * headers
Definition: switch_event.h:90

◆ bcast_thread()

static void* SWITCH_THREAD_FUNC bcast_thread ( switch_thread_t thread,
void *  obj 
)
static

Definition at line 4524 of file switch_ivr_async.c.

References bch_t::app, bch_t::flags, bch_t::session, switch_core_session_get_uuid(), switch_core_session_read_lock(), switch_core_session_rwunlock(), switch_ivr_broadcast(), and SWITCH_STATUS_SUCCESS.

Referenced by switch_ivr_broadcast_in_thread().

4525 {
4526  bch_t *bch = (bch_t *) obj;
4527 
4528  if (!bch->session) {
4529  return NULL;
4530  }
4531 
4535  }
4536 
4537  return NULL;
4538 
4539 }
switch_status_t switch_ivr_broadcast(const char *uuid, const char *path, switch_media_flag_t flags)
Signal the session to broadcast audio.
switch_status_t switch_core_session_read_lock(_In_ switch_core_session_t *session)
Acquire a read lock on the session.
const char * app
void switch_core_session_rwunlock(_In_ switch_core_session_t *session)
Unlock a read or write lock on as given session.
char * switch_core_session_get_uuid(_In_ switch_core_session_t *session)
Retrieve the unique identifier from a session.
switch_core_session_t * session

◆ block_on_dtmf()

static switch_status_t block_on_dtmf ( switch_core_session_t session,
const switch_dtmf_t dtmf,
switch_dtmf_direction_t  direction 
)
static

Definition at line 4693 of file switch_ivr_async.c.

References CF_INNER_BRIDGE, SWITCH_BLOCK_DTMF_KEY, switch_channel_get_private(), switch_channel_test_flag(), switch_core_session_get_channel(), SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.

Referenced by switch_ivr_block_dtmf_session().

4694 {
4696  uint8_t enabled = (uint8_t)(intptr_t)switch_channel_get_private(channel, SWITCH_BLOCK_DTMF_KEY);
4697 
4698  if (!enabled || switch_channel_test_flag(channel, CF_INNER_BRIDGE)) {
4699  return SWITCH_STATUS_SUCCESS;
4700  }
4701 
4702  return SWITCH_STATUS_FALSE;
4703 }
#define SWITCH_BLOCK_DTMF_KEY
uint32_t switch_channel_test_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Test for presence of given flag on a given channel.
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
void * switch_channel_get_private(switch_channel_t *channel, const char *key)
Retrieve private from a given channel.

◆ deliver_asr_event()

static void deliver_asr_event ( switch_core_session_t session,
switch_event_t event,
switch_input_args_t args 
)
static

Definition at line 4811 of file switch_ivr_async.c.

References switch_input_args_t::buf, switch_input_args_t::buflen, switch_input_args_t::input_callback, and SWITCH_INPUT_TYPE_EVENT.

Referenced by play_and_detect_input_callback().

4812 {
4813  if (args && args->input_callback) {
4814  args->input_callback(session, (void *)event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen);
4815  }
4816 }
switch_input_callback_function_t input_callback

◆ display_exec_cb()

static void display_exec_cb ( switch_media_bug_t bug,
void *  user_data 
)
static

Definition at line 2215 of file switch_ivr_async.c.

References exec_cb_data::caller, eavesdrop_pvt::eavesdropper, switch_core_session_message::from, switch_core_session_message::message_id, switch_core_session_message::string_array_arg, switch_core_media_bug_get_user_data(), switch_core_session_receive_message, SWITCH_MESSAGE_INDICATE_DISPLAY, exec_cb_data::val, and exec_cb_data::var.

Referenced by switch_ivr_eavesdrop_update_display().

2216 {
2217  struct exec_cb_data *data = (struct exec_cb_data *) user_data;
2219 
2220  if (ep && ep->eavesdropper && ep->eavesdropper != data->caller) {
2221  switch_core_session_message_t msg = { 0 };
2222 
2223  msg.from = __FILE__;
2225  msg.string_array_arg[0] = data->var;
2226  msg.string_array_arg[1] = data->val;
2227 
2229  }
2230 }
switch_core_session_message_types_t message_id
Definition: switch_core.h:183
void * switch_core_media_bug_get_user_data(_In_ switch_media_bug_t *bug)
Obtain private data from a media bug.
switch_core_session_t * caller
const char * string_array_arg[MESSAGE_STRING_ARG_MAX]
Definition: switch_core.h:211
switch_core_session_t * eavesdropper
A message object designed to allow unlike technologies to exchange data.
Definition: switch_core.h:179
#define switch_core_session_receive_message(_session, _message)
Definition: switch_core.h:1247

◆ eavesdrop_callback()

static switch_bool_t eavesdrop_callback ( switch_media_bug_t bug,
void *  user_data,
switch_abc_type_t  type 
)
static

Definition at line 2000 of file switch_ivr_async.c.

References buf, eavesdrop_pvt::buffer, switch_frame::buflen, CF_VIDEO_DECODED_READ, switch_frame::channels, switch_frame::codec, switch_frame::data, eavesdrop_pvt::data, switch_frame::datalen, eavesdrop_pvt::demux_frame, eavesdrop_pvt::eavesdropper, ED_MUX_READ, ED_MUX_WRITE, eavesdrop_pvt::errs, switch_frame::img, eavesdrop_pvt::r_buffer, switch_frame::samples, eavesdrop_pvt::set_decoded_read, SMBF_READ_VIDEO_PING, SMBF_READ_VIDEO_STREAM, SMBF_SPY_VIDEO_STREAM, SMBF_SPY_VIDEO_STREAM_BLEG, SMBF_WRITE_VIDEO_STREAM, SWITCH_ABC_TYPE_CLOSE, SWITCH_ABC_TYPE_INIT, SWITCH_ABC_TYPE_READ, SWITCH_ABC_TYPE_READ_PING, SWITCH_ABC_TYPE_READ_REPLACE, SWITCH_ABC_TYPE_READ_VIDEO_PING, SWITCH_ABC_TYPE_STREAM_VIDEO_PING, SWITCH_ABC_TYPE_TAP_NATIVE_READ, SWITCH_ABC_TYPE_TAP_NATIVE_WRITE, SWITCH_ABC_TYPE_WRITE, SWITCH_ABC_TYPE_WRITE_REPLACE, switch_buffer_inuse(), switch_buffer_lock(), switch_buffer_read(), switch_buffer_unlock(), switch_buffer_zwrite(), SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER, switch_channel_clear_flag_recursive(), switch_channel_hangup, SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_flag_recursive(), switch_core_media_bug_get_native_read_frame(), switch_core_media_bug_get_native_write_frame(), switch_core_media_bug_get_read_replace_frame(), switch_core_media_bug_get_session(), switch_core_media_bug_get_write_replace_frame(), switch_core_media_bug_read(), switch_core_media_bug_set_read_demux_frame(), switch_core_media_bug_set_read_replace_frame(), switch_core_media_bug_set_write_replace_frame(), switch_core_media_bug_test_flag(), switch_core_session_get_channel(), switch_core_session_get_name, switch_core_session_read_lock(), switch_core_session_request_video_refresh, switch_core_session_reset(), switch_core_session_rwunlock(), switch_core_session_set_video_read_callback(), switch_core_session_write_frame(), switch_core_session_write_video_frame(), SWITCH_FALSE, SWITCH_IO_FLAG_NONE, SWITCH_LOG_ERROR, switch_log_printf(), switch_merge_sln(), SWITCH_RECOMMENDED_BUFFER_SIZE, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_test_flag, SWITCH_TRUE, video_eavesdrop_callback(), switch_media_bug::video_ping_frame, and eavesdrop_pvt::w_buffer.

Referenced by switch_ivr_eavesdrop_session().

2001 {
2002  struct eavesdrop_pvt *ep = (struct eavesdrop_pvt *) user_data;
2004  switch_frame_t frame = { 0 };
2007  int show_spy = 0;
2008  switch_frame_t *nframe = NULL;
2009 
2010  frame.data = data;
2012 
2014 
2015  if (show_spy) {
2016  if (!ep->set_decoded_read) {
2017  ep->set_decoded_read = 1;
2020  }
2021  } else {
2022  if (ep->set_decoded_read) {
2023  ep->set_decoded_read = 0;
2026  }
2027  }
2028 
2029  switch (type) {
2030  case SWITCH_ABC_TYPE_INIT:
2031 
2037  }
2038  break;
2039  case SWITCH_ABC_TYPE_CLOSE:
2040  if (ep->set_decoded_read) {
2042  }
2043 
2048  }
2049 
2051 
2052  break;
2055  break;
2058  break;
2059  case SWITCH_ABC_TYPE_WRITE:
2060  break;
2062  if (ep->buffer) {
2065  switch_buffer_zwrite(ep->buffer, frame.data, frame.datalen);
2067  }
2068  }
2069  break;
2070  case SWITCH_ABC_TYPE_READ:
2071  break;
2072 
2074  {
2075 
2076  if (switch_test_flag(ep, ED_MUX_READ)) {
2078 
2079  if (switch_buffer_inuse(ep->r_buffer) >= rframe->datalen) {
2080  uint32_t bytes;
2081  int channels = rframe->channels ? rframe->channels : 1;
2082 
2084  bytes = (uint32_t) switch_buffer_read(ep->r_buffer, ep->data, rframe->datalen);
2085 
2086  rframe->datalen = switch_merge_sln(rframe->data, rframe->samples, (int16_t *) ep->data, bytes / 2, channels) * 2 * channels;
2087  rframe->samples = rframe->datalen / 2;
2088 
2089  ep->demux_frame.data = ep->data;
2090  ep->demux_frame.datalen = bytes;
2091  ep->demux_frame.samples = bytes / 2;
2092  ep->demux_frame.channels = rframe->channels;
2093 
2097  }
2098  }
2099 
2100  }
2101  break;
2102 
2104  {
2105  if (switch_test_flag(ep, ED_MUX_WRITE)) {
2107 
2108  if (switch_buffer_inuse(ep->w_buffer) >= rframe->datalen) {
2109  uint32_t bytes;
2110  int channels = rframe->channels ? rframe->channels : 1;
2111 
2113  bytes = (uint32_t) switch_buffer_read(ep->w_buffer, data, rframe->datalen);
2114 
2115  rframe->datalen = switch_merge_sln(rframe->data, rframe->samples, (int16_t *) data, bytes / 2, channels) * 2 * channels;
2116  rframe->samples = rframe->datalen / 2;
2117 
2120  }
2121  }
2122  }
2123  break;
2124 
2127  {
2128 
2129  if (!bug->video_ping_frame || !bug->video_ping_frame->img) {
2130  break;
2131  }
2132 
2136  ep->errs++;
2137 
2138  if (ep->errs > 10) {
2142  return SWITCH_FALSE;
2143  }
2144  } else {
2145  ep->errs = 0;
2146  }
2148  }
2149  }
2150  break;
2151  default:
2152  break;
2153  }
2154 
2155  if (nframe) {
2156  switch_frame_t frame = *nframe;
2157  uint8_t buf[SWITCH_RECOMMENDED_BUFFER_SIZE] = "";
2158 
2159  frame.data = buf;
2160  frame.codec = nframe->codec;
2161 
2162  memcpy(frame.data, nframe->data, nframe->datalen);
2163 
2165  return SWITCH_FALSE;
2166  }
2167  }
2168 
2169  return SWITCH_TRUE;
2170 }
#define switch_channel_hangup(channel, hangup_cause)
Hangup a channel flagging it&#39;s state machine to end.
void switch_channel_set_flag_recursive(switch_channel_t *channel, switch_channel_flag_t flag)
#define SWITCH_CHANNEL_SESSION_LOG(x)
switch_size_t switch_buffer_zwrite(_In_ switch_buffer_t *buffer, _In_bytecount_(datalen) const void *data, _In_ switch_size_t datalen)
void switch_core_session_reset(_In_ switch_core_session_t *session, switch_bool_t flush_dtmf, switch_bool_t reset_read_codec)
Reset the buffers and resampler on a session.
switch_size_t switch_buffer_read(_In_ switch_buffer_t *buffer, _In_ void *data, _In_ switch_size_t datalen)
Read data from a switch_buffer_t up to the ammount of datalen if it is available. Remove read data fr...
switch_status_t switch_core_session_set_video_read_callback(switch_core_session_t *session, switch_core_video_thread_callback_func_t func, void *user_data)
switch_frame_t * switch_core_media_bug_get_native_read_frame(switch_media_bug_t *bug)
void switch_core_media_bug_set_write_replace_frame(_In_ switch_media_bug_t *bug, _In_ switch_frame_t *frame)
Set a return replace frame.
#define SWITCH_RECOMMENDED_BUFFER_SIZE
Definition: switch_types.h:590
switch_buffer_t * r_buffer
switch_status_t switch_core_session_read_lock(_In_ switch_core_session_t *session)
Acquire a read lock on the session.
switch_core_session_t * switch_core_media_bug_get_session(_In_ switch_media_bug_t *bug)
Obtain the session from a media bug.
#define switch_core_session_get_name(_s)
Definition: switch_core.h:265
void switch_core_media_bug_set_read_replace_frame(_In_ switch_media_bug_t *bug, _In_ switch_frame_t *frame)
Set a return replace frame.
switch_core_session_t * eavesdropper
switch_codec_t * codec
Definition: switch_frame.h:56
switch_status_t switch_core_session_write_frame(_In_ switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id)
Write a frame to a session.
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
switch_frame_t * switch_core_media_bug_get_read_replace_frame(_In_ switch_media_bug_t *bug)
Obtain a replace frame from a media bug.
uint8_t data[SWITCH_RECOMMENDED_BUFFER_SIZE]
uint32_t buflen
Definition: switch_frame.h:70
switch_byte_t switch_byte_t * buf
uint32_t datalen
Definition: switch_frame.h:68
void switch_buffer_lock(_In_ switch_buffer_t *buffer)
#define switch_core_session_request_video_refresh(_s)
Definition: switch_core.h:2881
switch_frame_t * switch_core_media_bug_get_write_replace_frame(_In_ switch_media_bug_t *bug)
Obtain a replace frame from a media bug.
switch_buffer_t * w_buffer
An abstraction of a data frame.
Definition: switch_frame.h:54
switch_frame_t * video_ping_frame
switch_status_t switch_core_media_bug_read(_In_ switch_media_bug_t *bug, _In_ switch_frame_t *frame, switch_bool_t fill)
Read a frame from the bug.
static switch_status_t video_eavesdrop_callback(switch_core_session_t *session, switch_frame_t *frame, void *user_data)
void switch_core_session_rwunlock(_In_ switch_core_session_t *session)
Unlock a read or write lock on as given session.
switch_status_t switch_core_session_write_video_frame(_In_ switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id)
Write a video frame to a session.
switch_image_t * img
Definition: switch_frame.h:88
void switch_buffer_unlock(_In_ switch_buffer_t *buffer)
uint32_t switch_merge_sln(int16_t *data, uint32_t samples, int16_t *other_data, uint32_t other_samples, int channels)
uint32_t samples
Definition: switch_frame.h:72
uint32_t channels
Definition: switch_frame.h:76
void switch_core_media_bug_set_read_demux_frame(_In_ switch_media_bug_t *bug, _In_ switch_frame_t *frame)
switch_frame_t demux_frame
switch_buffer_t * buffer
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:693
void switch_channel_clear_flag_recursive(switch_channel_t *channel, switch_channel_flag_t flag)
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
switch_frame_t * switch_core_media_bug_get_native_write_frame(switch_media_bug_t *bug)
uint32_t switch_core_media_bug_test_flag(_In_ switch_media_bug_t *bug, _In_ uint32_t flag)
Test for the existance of a flag on an media bug.
switch_size_t switch_buffer_inuse(_In_ switch_buffer_t *buffer)
Get the in use amount of a switch_buffer_t.

◆ exec_cb()

static void exec_cb ( switch_media_bug_t bug,
void *  user_data 
)
static

Definition at line 2199 of file switch_ivr_async.c.

References b, exec_cb_data::caller, eavesdrop_pvt::eavesdropper, switch_channel_get_name(), SWITCH_CHANNEL_LOG, switch_core_media_bug_get_user_data(), switch_core_session_execute_application, switch_core_session_get_channel(), SWITCH_LOG_DEBUG, switch_log_printf(), exec_cb_data::val, and exec_cb_data::var.

Referenced by switch_ivr_eavesdrop_exec_all().

2200 {
2201  struct exec_cb_data *data = (struct exec_cb_data *) user_data;
2203 
2204  if (ep && ep->eavesdropper && ep->eavesdropper != data->caller) {
2207 
2208  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s telling %s to exec %s:%s\n",
2210 
2212  }
2213 }
#define SWITCH_CHANNEL_LOG
void * switch_core_media_bug_get_user_data(_In_ switch_media_bug_t *bug)
Obtain private data from a media bug.
const cJSON *const b
Definition: switch_cJSON.h:243
switch_core_session_t * caller
switch_core_session_t * eavesdropper
#define switch_core_session_execute_application(_a, _b, _c)
Execute an application on a session.
Definition: switch_core.h:1129
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
char * switch_channel_get_name(switch_channel_t *channel)
Retrieve the name of a given channel.

◆ generate_on_dtmf()

static switch_status_t generate_on_dtmf ( switch_core_session_t session,
const switch_dtmf_t dtmf,
switch_dtmf_direction_t  direction 
)
static

Definition at line 3913 of file switch_ivr_async.c.

References switch_inband_dtmf_generate_t::audio_buffer, CF_DIVERT_EVENTS, switch_dtmf_t::digit, switch_inband_dtmf_generate_t::digit_queue, switch_dtmf_t::duration, switch_inband_dtmf_generate_t::mutex, switch_inband_dtmf_generate_t::ready, switch_inband_dtmf_generate_t::skip, switch_buffer_inuse(), switch_channel_event_set_data(), switch_channel_get_private(), switch_channel_test_flag(), switch_core_media_bug_get_user_data(), switch_core_session_get_channel(), switch_core_session_queue_event(), switch_event_add_header(), switch_event_add_header_string(), switch_event_create, SWITCH_EVENT_DTMF, switch_event_fire, switch_mutex_lock(), switch_mutex_unlock(), switch_queue_trypush(), SWITCH_STACK_BOTTOM, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, and switch_zmalloc.

Referenced by inband_dtmf_generate_callback().

3914 {
3916  switch_media_bug_t *bug = switch_channel_get_private(channel, "dtmf_generate");
3918 
3919  if (bug) {
3921 
3922  if (pvt) {
3923  switch_mutex_lock(pvt->mutex);
3924 
3925  if (pvt->ready) {
3926  switch_dtmf_t *dt = NULL;
3927  switch_zmalloc(dt, sizeof(*dt));
3928  *dt = *dtmf;
3929  if (!switch_buffer_inuse(pvt->audio_buffer)) {
3930  pvt->skip = 10;
3931  }
3933  switch_event_t *event;
3934 
3936  switch_channel_event_set_data(channel, event);
3937  switch_event_add_header(event, SWITCH_STACK_BOTTOM, "DTMF-Digit", "%c", dtmf->digit);
3938  switch_event_add_header(event, SWITCH_STACK_BOTTOM, "DTMF-Duration", "%u", dtmf->duration);
3939  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "DTMF-Source", "APP");
3940  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "DTMF-Conversion", "native:inband");
3942  switch_core_session_queue_event(session, &event);
3943  } else {
3944  switch_event_fire(&event);
3945  }
3946  }
3947 
3948  dt = NULL;
3949  /*
3950  SWITCH_STATUS_FALSE indicates pretend there never was a DTMF
3951  since we will be generating it inband now.
3952  */
3953  status = SWITCH_STATUS_FALSE;
3954  } else {
3955  free(dt);
3956  }
3957  }
3958  switch_mutex_unlock(pvt->mutex);
3959  }
3960  }
3961 
3962  return status;
3963 }
#define switch_event_fire(event)
Fire an event filling in most of the arguements with obvious values.
Definition: switch_event.h:413
void * switch_core_media_bug_get_user_data(_In_ switch_media_bug_t *bug)
Obtain private data from a media bug.
void switch_channel_event_set_data(_In_ switch_channel_t *channel, _In_ switch_event_t *event)
Add information about a given channel to an event object.
switch_status_t switch_event_add_header(switch_event_t *event, switch_stack_t stack, const char *header_name, const char *fmt,...) PRINTF_FUNCTION(4
Add a header to an event.
Representation of an event.
Definition: switch_event.h:80
uint32_t duration
Definition: switch_types.h:298
uint32_t switch_channel_test_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Test for presence of given flag on a given channel.
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:313
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:308
switch_status_t switch_event_add_header_string(switch_event_t *event, switch_stack_t stack, const char *header_name, const char *data)
Add a string header to an event.
#define switch_zmalloc(ptr, len)
switch_status_t switch_core_session_queue_event(_In_ switch_core_session_t *session, _Inout_ switch_event_t **event)
Queue an event on a given session.
switch_status_t
Common return values.
void * switch_channel_get_private(switch_channel_t *channel, const char *key)
Retrieve private from a given channel.
#define switch_event_create(event, id)
Create a new event assuming it will not be custom event and therefore hiding the unused parameters...
Definition: switch_event.h:384
switch_status_t switch_queue_trypush(switch_queue_t *queue, void *data)
Definition: switch_apr.c:1279
switch_size_t switch_buffer_inuse(_In_ switch_buffer_t *buffer)
Get the in use amount of a switch_buffer_t.

◆ get_recording_var()

static const char * get_recording_var ( switch_channel_t channel,
switch_event_t vars,
const char *  name 
)
static

Definition at line 2913 of file switch_ivr_async.c.

References switch_channel_get_variable, and switch_event_get_header.

Referenced by record_callback(), recording_var_true(), and switch_ivr_record_session_event().

2914 {
2915  const char *val = NULL;
2916  if (!vars || !(val = switch_event_get_header(vars, name))) {
2917  val = switch_channel_get_variable(channel, name);
2918  }
2919  return val;
2920 }
#define switch_channel_get_variable(_c, _v)
#define switch_event_get_header(_e, _h)
Definition: switch_event.h:172
const char *const name
Definition: switch_cJSON.h:250

◆ inband_dtmf_callback()

static switch_bool_t inband_dtmf_callback ( switch_media_bug_t bug,
void *  user_data,
switch_abc_type_t  type 
)
static

Definition at line 3808 of file switch_ivr_async.c.

References switch_frame::data, switch_dtmf_t::digit, switch_inband_dtmf_t::dtmf_detect, switch_dtmf_t::duration, switch_frame::samples, switch_inband_dtmf_t::session, switch_dtmf_t::source, SWITCH_ABC_TYPE_CLOSE, SWITCH_ABC_TYPE_INIT, SWITCH_ABC_TYPE_READ_REPLACE, SWITCH_ABC_TYPE_WRITE, switch_channel_queue_dtmf(), SWITCH_CHANNEL_SESSION_LOG, switch_core_media_bug_get_read_replace_frame(), switch_core_media_bug_get_session(), switch_core_media_bug_set_read_replace_frame(), switch_core_session_get_channel(), SWITCH_DTMF_INBAND_AUDIO, SWITCH_LOG_DEBUG, switch_log_printf(), SWITCH_TRUE, teletone_dtmf_detect(), teletone_dtmf_get(), and TT_HIT_END.

Referenced by switch_ivr_inband_dtmf_session().

3809 {
3810  switch_inband_dtmf_t *pvt = (switch_inband_dtmf_t *) user_data;
3811  switch_frame_t *frame = NULL;
3813 
3814  switch (type) {
3815  case SWITCH_ABC_TYPE_INIT:
3816  break;
3817  case SWITCH_ABC_TYPE_CLOSE:
3818  break;
3820  if ((frame = switch_core_media_bug_get_read_replace_frame(bug))) {
3821  if (teletone_dtmf_detect(&pvt->dtmf_detect, frame->data, frame->samples) == TT_HIT_END) {
3822  switch_dtmf_t dtmf = {0};
3823 
3824  teletone_dtmf_get(&pvt->dtmf_detect, &dtmf.digit, &dtmf.duration);
3826  dtmf.digit, dtmf.duration);
3828  switch_channel_queue_dtmf(channel, &dtmf);
3829  }
3831  }
3832  break;
3833  case SWITCH_ABC_TYPE_WRITE:
3834  default:
3835  break;
3836  }
3837 
3838  return SWITCH_TRUE;
3839 }
#define SWITCH_CHANNEL_SESSION_LOG(x)
switch_status_t switch_channel_queue_dtmf(_In_ switch_channel_t *channel, _In_ const switch_dtmf_t *dtmf)
Queue DTMF on a given channel.
switch_core_session_t * switch_core_media_bug_get_session(_In_ switch_media_bug_t *bug)
Obtain the session from a media bug.
void switch_core_media_bug_set_read_replace_frame(_In_ switch_media_bug_t *bug, _In_ switch_frame_t *frame)
Set a return replace frame.
uint32_t duration
Definition: switch_types.h:298
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
switch_frame_t * switch_core_media_bug_get_read_replace_frame(_In_ switch_media_bug_t *bug)
Obtain a replace frame from a media bug.
switch_core_session_t * session
teletone_hit_type_t teletone_dtmf_detect(teletone_dtmf_detect_state_t *dtmf_detect_state, int16_t sample_buffer[], int samples)
Check a sample buffer for the presence of DTMF digits.
An abstraction of a data frame.
Definition: switch_frame.h:54
int teletone_dtmf_get(teletone_dtmf_detect_state_t *dtmf_detect_state, char *buf, unsigned int *dur)
retrieve any collected digits into a string buffer
teletone_dtmf_detect_state_t dtmf_detect
uint32_t samples
Definition: switch_frame.h:72
switch_dtmf_source_t source
Definition: switch_types.h:300
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.

◆ inband_dtmf_generate_callback()

static switch_bool_t inband_dtmf_generate_callback ( switch_media_bug_t bug,
void *  user_data,
switch_abc_type_t  type 
)
static

Definition at line 3966 of file switch_ivr_async.c.

References switch_codec_implementation::actual_samples_per_second, switch_inband_dtmf_generate_t::audio_buffer, buf, teletone_generation_session::channels, switch_frame::data, switch_frame::datalen, switch_dtmf_t::digit, switch_inband_dtmf_generate_t::digit_queue, teletone_generation_session::duration, switch_dtmf_t::duration, generate_on_dtmf(), memset(), switch_inband_dtmf_generate_t::mutex, teletone_generation_session::rate, switch_inband_dtmf_generate_t::read, switch_inband_dtmf_generate_t::ready, switch_inband_dtmf_generate_t::session, switch_inband_dtmf_generate_t::skip, switch_dtmf_t::source, SWITCH_ABC_TYPE_CLOSE, SWITCH_ABC_TYPE_INIT, SWITCH_ABC_TYPE_READ_REPLACE, SWITCH_ABC_TYPE_WRITE_REPLACE, switch_buffer_create_dynamic(), switch_buffer_destroy(), switch_buffer_inuse(), switch_buffer_read(), switch_channel_get_name(), SWITCH_CHANNEL_SESSION_LOG, switch_core_default_dtmf_duration(), switch_core_max_dtmf_duration(), switch_core_media_bug_get_read_replace_frame(), switch_core_media_bug_get_session(), switch_core_media_bug_get_write_replace_frame(), switch_core_media_bug_set_read_replace_frame(), switch_core_media_bug_set_write_replace_frame(), switch_core_session_get_channel(), switch_core_session_get_pool(), switch_core_session_get_read_impl(), SWITCH_DTMF_INBAND_AUDIO, SWITCH_FALSE, switch_log_printf(), SWITCH_LOG_WARNING, switch_mutex_init(), switch_mutex_lock(), SWITCH_MUTEX_NESTED, switch_mutex_unlock(), switch_queue_create(), switch_queue_trypop(), SWITCH_STATUS_SUCCESS, SWITCH_TRUE, teletone_destroy_session(), teletone_dtmf_generate_handler(), teletone_init_session(), teletone_run(), and switch_inband_dtmf_generate_t::ts.

Referenced by switch_ivr_inband_dtmf_generate_session().

3967 {
3969  switch_frame_t *frame;
3971  switch_core_session_get_read_impl(pvt->session, &read_impl);
3972 
3973  switch (type) {
3974  case SWITCH_ABC_TYPE_INIT:
3975  {
3977  switch_buffer_create_dynamic(&pvt->audio_buffer, 512, 1024, 0);
3979  pvt->ts.rate = read_impl.actual_samples_per_second;
3980  pvt->ts.channels = 1;
3982  if (pvt->read) {
3983  switch_core_event_hook_add_recv_dtmf(pvt->session, generate_on_dtmf);
3984  } else {
3985  switch_core_event_hook_add_send_dtmf(pvt->session, generate_on_dtmf);
3986  }
3987  switch_mutex_lock(pvt->mutex);
3988  pvt->ready = 1;
3989  switch_mutex_unlock(pvt->mutex);
3990  }
3991  break;
3992  case SWITCH_ABC_TYPE_CLOSE:
3993  {
3994  switch_mutex_lock(pvt->mutex);
3995  pvt->ready = 0;
3996  switch_core_event_hook_remove_recv_dtmf(pvt->session, generate_on_dtmf);
3999  switch_mutex_unlock(pvt->mutex);
4000  }
4001  break;
4004  {
4005  switch_size_t bytes;
4006  void *pop;
4007 
4008  if (pvt->skip) {
4009  pvt->skip--;
4010  return SWITCH_TRUE;
4011  }
4012 
4013 
4014  switch_mutex_lock(pvt->mutex);
4015 
4016  if (!pvt->ready) {
4017  switch_mutex_unlock(pvt->mutex);
4018  return SWITCH_FALSE;
4019  }
4020 
4021  if (pvt->read) {
4023  } else {
4025  }
4026 
4027  if (!switch_buffer_inuse(pvt->audio_buffer)) {
4029  switch_dtmf_t *dtmf = (switch_dtmf_t *) pop;
4030 
4031 
4032  if (dtmf->source != SWITCH_DTMF_INBAND_AUDIO) {
4033  char buf[2] = "";
4034  int duration = dtmf->duration;
4035 
4036  buf[0] = dtmf->digit;
4037  if (duration > (int)switch_core_max_dtmf_duration(0)) {
4038  duration = switch_core_default_dtmf_duration(0);
4040  SWITCH_LOG_WARNING, "%s Truncating DTMF duration %d ms to %d ms\n",
4042  }
4043 
4044 
4045  pvt->ts.duration = duration;
4046  teletone_run(&pvt->ts, buf);
4047  }
4048  free(pop);
4049  }
4050  }
4051 
4052  if (switch_buffer_inuse(pvt->audio_buffer) && (bytes = switch_buffer_read(pvt->audio_buffer, frame->data, frame->datalen))) {
4053  if (bytes < frame->datalen) {
4054  switch_byte_t *dp = frame->data;
4055  memset(dp + bytes, 0, frame->datalen - bytes);
4056  }
4057  }
4058 
4059  if (pvt->read) {
4061  } else {
4063  }
4064 
4065  switch_mutex_unlock(pvt->mutex);
4066  }
4067  break;
4068  default:
4069  break;
4070  }
4071 
4072  return SWITCH_TRUE;
4073 }
#define SWITCH_CHANNEL_SESSION_LOG(x)
switch_size_t switch_buffer_read(_In_ switch_buffer_t *buffer, _In_ void *data, _In_ switch_size_t datalen)
Read data from a switch_buffer_t up to the ammount of datalen if it is available. Remove read data fr...
switch_status_t switch_buffer_create_dynamic(_Out_ switch_buffer_t **buffer, _In_ switch_size_t blocksize, _In_ switch_size_t start_len, _In_ switch_size_t max_len)
Allocate a new dynamic switch_buffer.
void switch_core_media_bug_set_write_replace_frame(_In_ switch_media_bug_t *bug, _In_ switch_frame_t *frame)
Set a return replace frame.
switch_core_session_t * session
teletone_generation_session_t ts
switch_status_t switch_queue_trypop(switch_queue_t *queue, void **data)
Definition: switch_apr.c:1264
switch_core_session_t * switch_core_media_bug_get_session(_In_ switch_media_bug_t *bug)
Obtain the session from a media bug.
int teletone_destroy_session(teletone_generation_session_t *ts)
Free the buffer allocated by a tone generation session.
void switch_core_media_bug_set_read_replace_frame(_In_ switch_media_bug_t *bug, _In_ switch_frame_t *frame)
Set a return replace frame.
uint32_t duration
Definition: switch_types.h:298
uint8_t switch_byte_t
Definition: switch_types.h:256
uint32_t switch_core_max_dtmf_duration(uint32_t duration)
Definition: switch_core.c:1704
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:313
int teletone_run(teletone_generation_session_t *ts, const char *cmd)
Execute a tone generation script and call callbacks after each instruction.
switch_status_t switch_core_session_get_read_impl(switch_core_session_t *session, switch_codec_implementation_t *impp)
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
int teletone_init_session(teletone_generation_session_t *ts, int buflen, tone_handler handler, void *user_data)
Initilize a tone generation session.
#define SWITCH_MUTEX_NESTED
Definition: switch_apr.h:318
switch_frame_t * switch_core_media_bug_get_read_replace_frame(_In_ switch_media_bug_t *bug)
Obtain a replace frame from a media bug.
switch_byte_t switch_byte_t * buf
uint32_t datalen
Definition: switch_frame.h:68
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:308
switch_codec_implementation_t read_impl
switch_frame_t * switch_core_media_bug_get_write_replace_frame(_In_ switch_media_bug_t *bug)
Obtain a replace frame from a media bug.
switch_status_t switch_mutex_init(switch_mutex_t **lock, unsigned int flags, switch_memory_pool_t *pool)
Definition: switch_apr.c:293
static switch_status_t generate_on_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf, switch_dtmf_direction_t direction)
An abstraction of a data frame.
Definition: switch_frame.h:54
uintptr_t switch_size_t
uint32_t switch_core_default_dtmf_duration(uint32_t duration)
Definition: switch_core.c:1721
static int teletone_dtmf_generate_handler(teletone_generation_session_t *ts, teletone_tone_map_t *map)
switch_dtmf_source_t source
Definition: switch_types.h:300
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
A table of settings and callbacks that define a paticular implementation of a codec.
switch_status_t switch_queue_create(switch_queue_t **queue, unsigned int queue_capacity, switch_memory_pool_t *pool)
Definition: switch_apr.c:1233
switch_size_t switch_buffer_inuse(_In_ switch_buffer_t *buffer)
Get the in use amount of a switch_buffer_t.
void switch_buffer_destroy(switch_buffer_t **buffer)
Destroy the buffer.
char * switch_channel_get_name(switch_channel_t *channel)
Retrieve the name of a given channel.
memset(buf, 0, buflen)
switch_memory_pool_t * switch_core_session_get_pool(_In_ switch_core_session_t *session)
Retrieve the memory pool from a session.

◆ is_silence_frame()

static switch_bool_t is_silence_frame ( switch_frame_t frame,
int  silence_threshold,
switch_codec_implementation_t codec_impl 
)
static

Definition at line 1180 of file switch_ivr_async.c.

References count, switch_frame::data, switch_frame::datalen, switch_codec_implementation::number_of_channels, switch_codec_implementation::samples_per_second, and SWITCH_TRUE.

Referenced by record_callback().

1181 {
1182  int16_t *fdata = (int16_t *) frame->data;
1183  uint32_t samples = frame->datalen / sizeof(*fdata);
1184  switch_bool_t is_silence = SWITCH_TRUE;
1185  uint32_t channel_num = 0;
1186 
1187  int divisor = 0;
1188  if (!(divisor = codec_impl->samples_per_second / 8000)) {
1189  divisor = 1;
1190  }
1191 
1192  /* is silence only if every channel is silent */
1193  for (channel_num = 0; channel_num < codec_impl->number_of_channels && is_silence; channel_num++) {
1194  uint32_t count = 0, j = channel_num;
1195  double energy = 0;
1196  for (count = 0; count < samples; count++) {
1197  energy += abs(fdata[j]);
1198  j += codec_impl->number_of_channels;
1199  }
1200  is_silence &= (uint32_t) ((energy / (samples / divisor)) < silence_threshold);
1201  }
1202 
1203  return is_silence;
1204 }
switch_bool_t
Definition: switch_types.h:437
uint32_t datalen
Definition: switch_frame.h:68
int count
Definition: switch_cJSON.h:204

◆ merge_recording_variables()

static void merge_recording_variables ( struct record_helper rh,
switch_event_t event 
)
static

Definition at line 1206 of file switch_ivr_async.c.

References buf, switch_event::headers, switch_event_header::name, switch_event_header::next, switch_assert, switch_event_add_header_string(), switch_snprintf(), SWITCH_STACK_BOTTOM, switch_event_header::value, and record_helper::variables.

Referenced by record_callback(), and send_record_stop_event().

1207 {
1209  if (rh->variables) {
1210  for (hi = rh->variables->headers; hi; hi = hi->next) {
1211  char buf[1024];
1212  char *vvar = NULL, *vval = NULL;
1213 
1214  vvar = (char *) hi->name;
1215  vval = (char *) hi->value;
1216 
1217  switch_assert(vvar && vval);
1218  switch_snprintf(buf, sizeof(buf), "Recording-Variable-%s", vvar);
1220  }
1221  }
1222 }
An event Header.
Definition: switch_event.h:65
int switch_snprintf(_Out_z_cap_(len) char *buf, _In_ switch_size_t len, _In_z_ _Printf_format_string_ const char *format,...)
switch_byte_t switch_byte_t * buf
switch_status_t switch_event_add_header_string(switch_event_t *event, switch_stack_t stack, const char *header_name, const char *data)
Add a string header to an event.
struct switch_event_header * next
Definition: switch_event.h:76
switch_event_t * variables
#define switch_assert(expr)
switch_event_header_t * headers
Definition: switch_event.h:90

◆ meta_on_dtmf()

static switch_status_t meta_on_dtmf ( switch_core_session_t session,
const switch_dtmf_t dtmf,
switch_dtmf_direction_t  direction 
)
static

Definition at line 4563 of file switch_ivr_async.c.

References dtmf_meta_app_t::app, dtmf_meta_app_t::bind_flags, CF_INNER_BRIDGE, CF_PROXY_MODE, switch_dtmf_t::digit, dtmf_meta_app_t::flags, is_dtmf, dtmf_meta_settings_t::last_digit, dtmf_meta_settings_t::map, memset(), dtmf_meta_settings_t::meta, dtmf_meta_settings_t::meta_on, SBF_DIAL_ALEG, SBF_DIAL_BLEG, SBF_EXEC_ALEG, SBF_EXEC_BLEG, SBF_EXEC_INLINE, SBF_EXEC_OPPOSITE, SBF_EXEC_SAME, SBF_ONCE, SMF_ECHO_ALEG, SMF_ECHO_BLEG, SMF_EXEC_INLINE, SMF_REBRIDGE, dtmf_meta_data_t::sr, switch_channel_get_name(), switch_channel_get_private(), SWITCH_CHANNEL_SESSION_LOG, switch_channel_test_flag(), switch_core_session_get_channel(), switch_core_session_get_uuid(), SWITCH_DTMF_RECV, SWITCH_DTMF_SEND, switch_dtmftoi(), switch_epoch_time_now(), SWITCH_FALSE, switch_ivr_broadcast(), switch_ivr_broadcast_in_thread(), SWITCH_LOG_DEBUG, SWITCH_LOG_ERROR, switch_log_printf(), SWITCH_LOG_WARNING, SWITCH_META_VAR_KEY, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, SWITCH_TRUE, and dtmf_meta_settings_t::up.

Referenced by switch_ivr_bind_dtmf_meta_session().

4564 {
4567  time_t now = switch_epoch_time_now(NULL);
4568  char digit[2] = "";
4569  int dval;
4570 
4571  if (!md || switch_channel_test_flag(channel, CF_INNER_BRIDGE)) {
4572  return SWITCH_STATUS_SUCCESS;
4573  }
4574 
4575  if (direction == SWITCH_DTMF_RECV && !md->sr[SWITCH_DTMF_RECV].up) {
4576  return SWITCH_STATUS_SUCCESS;
4577  }
4578 
4579  if (direction == SWITCH_DTMF_SEND && !md->sr[SWITCH_DTMF_SEND].up) {
4580  return SWITCH_STATUS_SUCCESS;
4581  }
4582 
4583  if (md->sr[direction].meta_on && now - md->sr[direction].last_digit > 5) {
4584  md->sr[direction].meta_on = SWITCH_FALSE;
4585  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s Meta digit timeout parsing %c\n", switch_channel_get_name(channel),
4586  dtmf->digit);
4587  return SWITCH_STATUS_SUCCESS;
4588  }
4589 
4590  md->sr[direction].last_digit = now;
4591 
4592  if (dtmf->digit == md->sr[direction].meta) {
4593  if (md->sr[direction].meta_on) {
4594  md->sr[direction].meta_on = SWITCH_FALSE;
4595  return SWITCH_STATUS_SUCCESS;
4596  } else {
4597  md->sr[direction].meta_on = SWITCH_TRUE;
4598  return SWITCH_STATUS_FALSE;
4599  }
4600  }
4601 
4602  if (md->sr[direction].meta_on) {
4603  if (is_dtmf(dtmf->digit)) {
4604  int ok = 0;
4605  *digit = dtmf->digit;
4606  dval = switch_dtmftoi(digit);
4607 
4608  if (direction == SWITCH_DTMF_RECV && (md->sr[direction].map[dval].bind_flags & SBF_DIAL_ALEG)) {
4609  ok = 1;
4610  } else if (direction == SWITCH_DTMF_SEND && (md->sr[direction].map[dval].bind_flags & SBF_DIAL_BLEG)) {
4611  ok = 1;
4612  }
4613 
4614  if (ok && md->sr[direction].map[dval].app) {
4615  uint32_t flags = md->sr[direction].map[dval].flags;
4616 
4617  if ((md->sr[direction].map[dval].bind_flags & SBF_EXEC_OPPOSITE)) {
4618  if (direction == SWITCH_DTMF_SEND) {
4619  flags |= SMF_ECHO_ALEG;
4620  } else {
4621  flags |= SMF_ECHO_BLEG;
4622  }
4623  } else if ((md->sr[direction].map[dval].bind_flags & SBF_EXEC_SAME)) {
4624  if (direction == SWITCH_DTMF_SEND) {
4625  flags |= SMF_ECHO_BLEG;
4626  } else {
4627  flags |= SMF_ECHO_ALEG;
4628  }
4629  } else if ((md->sr[direction].map[dval].bind_flags & SBF_EXEC_ALEG)) {
4630  flags |= SMF_ECHO_ALEG;
4631  } else if ((md->sr[direction].map[dval].bind_flags & SBF_EXEC_BLEG)) {
4632  flags |= SMF_ECHO_BLEG;
4633  } else {
4634  flags |= SMF_ECHO_ALEG;
4635  }
4636 
4637  if ((md->sr[direction].map[dval].bind_flags & SBF_EXEC_INLINE)) {
4638  flags |= SMF_EXEC_INLINE;
4639  }
4640 
4641  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Processing meta digit '%c' [%s]\n",
4642  switch_channel_get_name(channel), dtmf->digit, md->sr[direction].map[dval].app);
4643 
4644  if (switch_channel_test_flag(channel, CF_PROXY_MODE)) {
4645  switch_ivr_broadcast_in_thread(session, md->sr[direction].map[dval].app, flags | SMF_REBRIDGE);
4646  } else {
4647  switch_ivr_broadcast(switch_core_session_get_uuid(session), md->sr[direction].map[dval].app, flags);
4648  }
4649 
4650  if ((md->sr[direction].map[dval].bind_flags & SBF_ONCE)) {
4651  memset(&md->sr[direction].map[dval], 0, sizeof(md->sr[direction].map[dval]));
4652  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Unbinding meta digit '%c'\n",
4653  switch_channel_get_name(channel), dtmf->digit);
4654  }
4655 
4656  } else {
4657  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s Ignoring meta digit '%c' not mapped\n",
4658  switch_channel_get_name(channel), dtmf->digit);
4659 
4660  }
4661  }
4662  md->sr[direction].meta_on = SWITCH_FALSE;
4663  return SWITCH_STATUS_FALSE;
4664  }
4665 
4666  return SWITCH_STATUS_SUCCESS;
4667 }
#define SWITCH_CHANNEL_SESSION_LOG(x)
switch_status_t switch_ivr_broadcast(const char *uuid, const char *path, switch_media_flag_t flags)
Signal the session to broadcast audio.
uint32_t switch_channel_test_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Test for presence of given flag on a given channel.
#define is_dtmf(key)
determine if a character is a valid DTMF key
Definition: switch_utils.h:683
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
void switch_ivr_broadcast_in_thread(switch_core_session_t *session, const char *app, int flags)
char * switch_core_session_get_uuid(_In_ switch_core_session_t *session)
Retrieve the unique identifier from a session.
void * switch_channel_get_private(switch_channel_t *channel, const char *key)
Retrieve private from a given channel.
switch_bind_flag_t bind_flags
time_t switch_epoch_time_now(time_t *t)
Get the current epoch time.
Definition: switch_time.c:322
static int switch_dtmftoi(char *s)
Definition: switch_utils.h:463
#define SWITCH_META_VAR_KEY
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
dtmf_meta_settings_t sr[3]
dtmf_meta_app_t map[14]
char * switch_channel_get_name(switch_channel_t *channel)
Retrieve the name of a given channel.
memset(buf, 0, buflen)

◆ play_and_detect_input_callback()

static switch_status_t play_and_detect_input_callback ( switch_core_session_t session,
void *  input,
switch_input_type_t  input_type,
void *  data,
unsigned int  len 
)
static

Definition at line 4818 of file switch_ivr_async.c.

References deliver_asr_event(), switch_dtmf_t::digit, play_and_detect_speech_state_t::done, switch_event::event_id, play_and_detect_speech_state_t::original_args, PLAY_AND_DETECT_DONE, PLAY_AND_DETECT_DONE_RECOGNIZING, play_and_detect_speech_state_t::result, switch_channel_get_name(), switch_channel_get_variable, SWITCH_CHANNEL_LOG, SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_variable_printf(), switch_core_session_get_channel(), switch_core_session_sprintf(), switch_core_session_strdup, SWITCH_EVENT_DETECTED_SPEECH, switch_event_get_body(), switch_event_get_header, SWITCH_INPUT_TYPE_DTMF, SWITCH_INPUT_TYPE_EVENT, SWITCH_LOG_DEBUG, SWITCH_LOG_ERROR, SWITCH_LOG_INFO, switch_log_printf(), SWITCH_PLAYBACK_TERMINATOR_USED, SWITCH_PLAYBACK_TERMINATORS_VARIABLE, SWITCH_STATUS_BREAK, SWITCH_STATUS_SUCCESS, and zstr.

Referenced by switch_ivr_play_and_detect_speech().

4819 {
4821  if (!state->done) {
4823  if (input_type == SWITCH_INPUT_TYPE_EVENT) {
4824  switch_event_t *event;
4825  event = (switch_event_t *)input;
4826  if (event->event_id == SWITCH_EVENT_DETECTED_SPEECH) {
4827  const char *speech_type = switch_event_get_header(event, "Speech-Type");
4828 
4829  if (!zstr(speech_type)) {
4830  deliver_asr_event(session, event, state->original_args);
4831 
4832  if (!strcasecmp(speech_type, "detected-speech")) {
4833  const char *result;
4834  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "(%s) DETECTED SPEECH\n", switch_channel_get_name(channel));
4835  result = switch_event_get_body(event);
4836  if (!zstr(result)) {
4837  state->result = switch_core_session_strdup(session, result);
4838  } else {
4839  state->result = "";
4840  }
4841  state->original_args = NULL;
4843  return SWITCH_STATUS_BREAK;
4844  } else if (!strcasecmp(speech_type, "detected-partial-speech")) {
4845  // ok
4846  } else if (!strcasecmp(speech_type, "begin-speaking")) {
4847  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "(%s) START OF SPEECH\n", switch_channel_get_name(channel));
4848  return SWITCH_STATUS_BREAK;
4849  } else if (!strcasecmp("closed", speech_type)) {
4851  state->result = "";
4852  return SWITCH_STATUS_BREAK;
4853  } else {
4854  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "unhandled speech type %s\n", speech_type);
4855  }
4856  }
4857  }
4858  } else if (input_type == SWITCH_INPUT_TYPE_DTMF) {
4859  switch_dtmf_t *dtmf = (switch_dtmf_t *) input;
4860  const char *terminators = switch_channel_get_variable(channel, SWITCH_PLAYBACK_TERMINATORS_VARIABLE);
4861  if (terminators) {
4862  if (!strcasecmp(terminators, "any")) {
4863  terminators = "1234567890*#";
4864  } else if (!strcasecmp(terminators, "none")) {
4865  terminators = NULL;
4866  }
4867  }
4868  if (terminators && strchr(terminators, dtmf->digit)) {
4869  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "(%s) ACCEPT TERMINATOR %c\n", switch_channel_get_name(channel), dtmf->digit);
4871  state->result = switch_core_session_sprintf(session, "DIGIT: %c", dtmf->digit);
4872  state->done = PLAY_AND_DETECT_DONE;
4873  return SWITCH_STATUS_BREAK;
4874  } else {
4875  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "(%s) IGNORE NON-TERMINATOR DIGIT %c\n", switch_channel_get_name(channel), dtmf->digit);
4876  }
4877  }
4878  }
4879  return SWITCH_STATUS_SUCCESS;
4880 }
switch_status_t switch_channel_set_variable_printf(switch_channel_t *channel, const char *varname, const char *fmt,...)
switch_event_types_t event_id
Definition: switch_event.h:82
switch_input_args_t * original_args
char * switch_core_session_sprintf(_In_ switch_core_session_t *session, _In_z_ _Printf_format_string_ const char *fmt,...)
printf-style style printing routine. The data is output to a string allocated from the session ...
#define SWITCH_CHANNEL_SESSION_LOG(x)
#define SWITCH_CHANNEL_LOG
static void deliver_asr_event(switch_core_session_t *session, switch_event_t *event, switch_input_args_t *args)
Representation of an event.
Definition: switch_event.h:80
#define SWITCH_PLAYBACK_TERMINATOR_USED
Definition: switch_types.h:187
#define PLAY_AND_DETECT_DONE_RECOGNIZING
#define PLAY_AND_DETECT_DONE
#define zstr(x)
Definition: switch_utils.h:314
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
uint8_t data[SWITCH_RECOMMENDED_BUFFER_SIZE]
char * switch_event_get_body(switch_event_t *event)
Retrieve the body value from an event.
Definition: switch_event.c:867
#define switch_channel_get_variable(_c, _v)
#define switch_event_get_header(_e, _h)
Definition: switch_event.h:172
#define SWITCH_PLAYBACK_TERMINATORS_VARIABLE
Definition: switch_types.h:186
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
#define switch_core_session_strdup(_session, _todup)
Copy a string using memory allocation from a session&#39;s pool.
Definition: switch_core.h:719
char * switch_channel_get_name(switch_channel_t *channel)
Retrieve the name of a given channel.

◆ preprocess_callback()

static switch_bool_t preprocess_callback ( switch_media_bug_t bug,
void *  user_data,
switch_abc_type_t  type 
)
static

Definition at line 3374 of file switch_ivr_async.c.

References switch_frame::data, switch_frame::datalen, pp_cb_t::done, pp_cb_t::read_data, pp_cb_t::read_ec, pp_cb_t::read_mutex, pp_cb_t::read_out, pp_cb_t::read_st, SWITCH_ABC_TYPE_CLOSE, SWITCH_ABC_TYPE_INIT, SWITCH_ABC_TYPE_READ_REPLACE, SWITCH_ABC_TYPE_WRITE_REPLACE, switch_channel_set_private(), switch_core_media_bug_get_read_replace_frame(), switch_core_media_bug_get_session(), switch_core_media_bug_get_write_replace_frame(), switch_core_session_get_channel(), switch_core_session_get_pool(), switch_core_session_get_read_impl(), SWITCH_FALSE, switch_mutex_init(), SWITCH_MUTEX_NESTED, SWITCH_TRUE, pp_cb_t::write_data, pp_cb_t::write_ec, pp_cb_t::write_mutex, pp_cb_t::write_out, and pp_cb_t::write_st.

Referenced by switch_ivr_preprocess_session().

3375 {
3378  pp_cb_t *cb = (pp_cb_t *) user_data;
3380  switch_frame_t *frame = NULL;
3381 
3382  switch_core_session_get_read_impl(session, &read_impl);
3383 
3384  switch (type) {
3385  case SWITCH_ABC_TYPE_INIT:
3386  {
3389  }
3390  break;
3391  case SWITCH_ABC_TYPE_CLOSE:
3392  {
3393  if (cb->read_st) {
3394  speex_preprocess_state_destroy(cb->read_st);
3395  }
3396 
3397  if (cb->write_st) {
3398  speex_preprocess_state_destroy(cb->write_st);
3399  }
3400 
3401  if (cb->read_ec) {
3402  speex_echo_state_destroy(cb->read_ec);
3403  }
3404 
3405  if (cb->write_ec) {
3406  speex_echo_state_destroy(cb->write_ec);
3407  }
3408 
3409  switch_channel_set_private(channel, "_preprocess", NULL);
3410  }
3411  break;
3413  {
3414  if (cb->done)
3415  return SWITCH_FALSE;
3417 
3418  if (cb->read_st) {
3419 
3420  if (cb->read_ec) {
3421  speex_echo_cancellation(cb->read_ec, (int16_t *) frame->data, (int16_t *) cb->write_data, (int16_t *) cb->read_out);
3422  memcpy(frame->data, cb->read_out, frame->datalen);
3423  }
3424 
3425  speex_preprocess_run(cb->read_st, frame->data);
3426  }
3427 
3428  if (cb->write_ec) {
3429  memcpy(cb->read_data, frame->data, frame->datalen);
3430  }
3431  }
3432  break;
3434  {
3435  if (cb->done)
3436  return SWITCH_FALSE;
3438 
3439  if (cb->write_st) {
3440 
3441  if (cb->write_ec) {
3442  speex_echo_cancellation(cb->write_ec, (int16_t *) frame->data, (int16_t *) cb->read_data, (int16_t *) cb->write_out);
3443  memcpy(frame->data, cb->write_out, frame->datalen);
3444  }
3445 
3446  speex_preprocess_run(cb->write_st, frame->data);
3447  }
3448 
3449  if (cb->read_ec) {
3450  memcpy(cb->write_data, frame->data, frame->datalen);
3451  }
3452  }
3453  break;
3454  default:
3455  break;
3456  }
3457 
3458  return SWITCH_TRUE;
3459 }
switch_mutex_t * read_mutex
SpeexEchoState * write_ec
switch_status_t switch_channel_set_private(switch_channel_t *channel, const char *key, const void *private_info)
Set private data on channel.
SpeexPreprocessState * write_st
switch_core_session_t * switch_core_media_bug_get_session(_In_ switch_media_bug_t *bug)
Obtain the session from a media bug.
switch_status_t switch_core_session_get_read_impl(switch_core_session_t *session, switch_codec_implementation_t *impp)
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
#define SWITCH_MUTEX_NESTED
Definition: switch_apr.h:318
switch_frame_t * switch_core_media_bug_get_read_replace_frame(_In_ switch_media_bug_t *bug)
Obtain a replace frame from a media bug.
uint32_t datalen
Definition: switch_frame.h:68
switch_codec_implementation_t read_impl
switch_frame_t * switch_core_media_bug_get_write_replace_frame(_In_ switch_media_bug_t *bug)
Obtain a replace frame from a media bug.
switch_status_t switch_mutex_init(switch_mutex_t **lock, unsigned int flags, switch_memory_pool_t *pool)
Definition: switch_apr.c:293
switch_byte_t write_out[2048]
An abstraction of a data frame.
Definition: switch_frame.h:54
switch_byte_t read_data[2048]
switch_byte_t write_data[2048]
switch_byte_t read_out[2048]
SpeexPreprocessState * read_st
switch_mutex_t * write_mutex
A table of settings and callbacks that define a paticular implementation of a codec.
switch_memory_pool_t * switch_core_session_get_pool(_In_ switch_core_session_t *session)
Retrieve the memory pool from a session.
SpeexEchoState * read_ec

◆ read_displace_callback()

static switch_bool_t read_displace_callback ( switch_media_bug_t bug,
void *  user_data,
switch_abc_type_t  type 
)
static

Definition at line 880 of file switch_ivr_async.c.

References buf, switch_file_handle::channels, switch_frame::data, switch_frame::datalen, displace_helper_t::fh, displace_helper_t::file, displace_helper_t::loop, memset(), displace_helper_t::mutex, displace_helper_t::mux, switch_frame::samples, SWITCH_ABC_TYPE_CLOSE, SWITCH_ABC_TYPE_INIT, SWITCH_ABC_TYPE_READ_REPLACE, SWITCH_ABC_TYPE_WRITE, SWITCH_ABC_TYPE_WRITE_REPLACE, switch_buffer_destroy(), switch_buffer_inuse(), switch_buffer_read(), switch_buffer_write(), SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_private(), switch_core_file_close(), switch_core_file_read(), switch_core_file_seek(), switch_core_media_bug_get_read_replace_frame(), switch_core_media_bug_get_session(), switch_core_media_bug_get_write_replace_frame(), switch_core_media_bug_set_read_replace_frame(), switch_core_media_bug_set_write_replace_frame(), switch_core_session_get_channel(), SWITCH_FALSE, switch_log_printf(), SWITCH_LOG_WARNING, switch_mutex_destroy(), switch_mutex_lock(), switch_mutex_unlock(), switch_normalize_to_16bit, SWITCH_RECOMMENDED_BUFFER_SIZE, SWITCH_SIZE_T_FMT, SWITCH_STATUS_SUCCESS, SWITCH_TRUE, and displace_helper_t::wbuffer.

Referenced by switch_ivr_displace_session().

881 {
882  displace_helper_t *dh = (displace_helper_t *) user_data;
883 
884  switch (type) {
886  break;
888  if (dh) {
890  switch_channel_t *channel;
891 
892  if (dh->wbuffer) switch_buffer_destroy(&dh->wbuffer);
893  if (dh->mutex) switch_mutex_destroy(dh->mutex);
894 
896 
897  if (session && (channel = switch_core_session_get_channel(session))) {
898  switch_channel_set_private(channel, dh->file, NULL);
899  }
900  }
901  break;
903  {
905 
906  if (dh) {
907  if (dh->wbuffer) {
909  if (switch_buffer_inuse(dh->wbuffer) >= rframe->datalen) {
910  switch_buffer_read(dh->wbuffer, rframe->data, rframe->datalen);
911  } else {
913  SWITCH_LOG_WARNING, "not enough data %" SWITCH_SIZE_T_FMT "\n",
915  memset(rframe->data, 255, rframe->datalen);
916  }
918  } else if (!dh->mux) {
919  memset(rframe->data, 255, rframe->datalen);
920  }
921  }
922 
924  }
925  break;
927  if (dh) {
928  switch_frame_t *rframe = NULL;
929  switch_size_t len;
930  switch_status_t st;
932  len = rframe->samples;
933 
934  if (dh->mux) {
936  int16_t *fp = rframe->data;
937  uint32_t x;
938 
939  st = switch_core_file_read(&dh->fh, buf, &len);
940 
941  for (x = 0; x < (uint32_t) len * dh->fh.channels; x++) {
942  int32_t mixed = fp[x] + buf[x];
944  fp[x] = (int16_t) mixed;
945  }
946 
947  } else {
948  st = switch_core_file_read(&dh->fh, rframe->data, &len);
949  rframe->samples = (uint32_t) len;
950 
951  if (dh->wbuffer) {
953  switch_buffer_write(dh->wbuffer, rframe->data, len * 2 * dh->fh.channels);
955  }
956  }
957 
958  rframe->datalen = rframe->samples * 2 * dh->fh.channels;
959 
960 
961  if (st != SWITCH_STATUS_SUCCESS || len == 0) {
962  if (dh->loop) {
963  uint32_t pos = 0;
964  switch_core_file_seek(&dh->fh, &pos, 0, SEEK_SET);
965  } else {
967  switch_channel_t *channel;
968 
969  if (session && (channel = switch_core_session_get_channel(session))) {
970  switch_channel_set_private(channel, dh->file, NULL);
971  }
972  return SWITCH_FALSE;
973  }
974  }
975 
977  }
978  break;
980  default:
981  break;
982  }
983 
984  return SWITCH_TRUE;
985 }
#define SWITCH_CHANNEL_SESSION_LOG(x)
switch_status_t switch_mutex_destroy(switch_mutex_t *lock)
Definition: switch_apr.c:303
switch_size_t switch_buffer_read(_In_ switch_buffer_t *buffer, _In_ void *data, _In_ switch_size_t datalen)
Read data from a switch_buffer_t up to the ammount of datalen if it is available. Remove read data fr...
switch_status_t switch_channel_set_private(switch_channel_t *channel, const char *key, const void *private_info)
Set private data on channel.
void switch_core_media_bug_set_write_replace_frame(_In_ switch_media_bug_t *bug, _In_ switch_frame_t *frame)
Set a return replace frame.
switch_buffer_t * wbuffer
#define SWITCH_RECOMMENDED_BUFFER_SIZE
Definition: switch_types.h:590
switch_status_t switch_core_file_close(_In_ switch_file_handle_t *fh)
Close an open file handle.
switch_status_t switch_core_file_seek(_In_ switch_file_handle_t *fh, unsigned int *cur_pos, int64_t samples, int whence)
Seek a position in a file.
switch_core_session_t * switch_core_media_bug_get_session(_In_ switch_media_bug_t *bug)
Obtain the session from a media bug.
switch_status_t switch_core_file_read(_In_ switch_file_handle_t *fh, void *data, switch_size_t *len)
Read media from a file handle.
void switch_core_media_bug_set_read_replace_frame(_In_ switch_media_bug_t *bug, _In_ switch_frame_t *frame)
Set a return replace frame.
switch_size_t switch_buffer_write(_In_ switch_buffer_t *buffer, _In_bytecount_(datalen) const void *data, _In_ switch_size_t datalen)
Write data into a switch_buffer_t up to the length of datalen.
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:313
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
switch_frame_t * switch_core_media_bug_get_read_replace_frame(_In_ switch_media_bug_t *bug)
Obtain a replace frame from a media bug.
switch_byte_t switch_byte_t * buf
uint32_t datalen
Definition: switch_frame.h:68
switch_file_handle_t fh
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:308
switch_frame_t * switch_core_media_bug_get_write_replace_frame(_In_ switch_media_bug_t *bug)
Obtain a replace frame from a media bug.
An abstraction of a data frame.
Definition: switch_frame.h:54
uintptr_t switch_size_t
#define SWITCH_SIZE_T_FMT
switch_status_t
Common return values.
uint32_t samples
Definition: switch_frame.h:72
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
#define switch_normalize_to_16bit(n)
Definition: switch_utils.h:292
switch_mutex_t * mutex
switch_size_t switch_buffer_inuse(_In_ switch_buffer_t *buffer)
Get the in use amount of a switch_buffer_t.
void switch_buffer_destroy(switch_buffer_t **buffer)
Destroy the buffer.
memset(buf, 0, buflen)

◆ record_callback()

static switch_bool_t record_callback ( switch_media_bug_t bug,
void *  user_data,
switch_abc_type_t  type 
)
static

Definition at line 1390 of file switch_ivr_async.c.

References switch_codec_implementation::actual_samples_per_second, record_helper::buffer_mutex, switch_frame::buflen, record_helper::bug, switch_frame::channels, record_helper::completion_cause, record_helper::cond, record_helper::cond_mutex, switch_frame::data, switch_frame::datalen, exec_app(), record_helper::fh, record_helper::file, record_helper::final_timeout_ms, get_recording_var(), record_helper::hangup_on_error, record_helper::helper_pool, if(), switch_frame::img, record_helper::in_fh, record_helper::initial_timeout_ms, is_silence_frame(), record_helper::last_read_time, record_helper::last_write_time, merge_recording_variables(), switch_codec_implementation::microseconds_per_packet, record_helper::min_sec, switch_file_handle::mm, record_helper::native, switch_file_handle::native_rate, record_helper::out_fh, record_helper::read_impl, record_helper_destroy(), record_helper_post_process(), record_helper::recording_session, recording_thread(), record_helper::rready, switch_file_handle::samplerate, switch_file_handle::samples_out, send_record_stop_event(), set_completion_cause(), record_helper::silence_threshold, record_helper::silence_time, record_helper::silence_timeout_ms, SMBF_MASK, SMBF_PRUNE, record_helper::speech_detected, record_helper::start_event_sent, SWITCH_ABC_TYPE_CLOSE, SWITCH_ABC_TYPE_INIT, SWITCH_ABC_TYPE_READ_PING, SWITCH_ABC_TYPE_READ_VIDEO_PING, SWITCH_ABC_TYPE_STREAM_VIDEO_PING, SWITCH_ABC_TYPE_TAP_NATIVE_READ, SWITCH_ABC_TYPE_TAP_NATIVE_WRITE, SWITCH_ABC_TYPE_WRITE, SWITCH_AUDIO_COL_STR_FILE_SIZE, SWITCH_AUDIO_COL_STR_FILE_TRIMMED, SWITCH_AUDIO_COL_STR_FILE_TRIMMED_MS, switch_buffer_destroy(), switch_buffer_write(), SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER, switch_channel_api_on(), switch_channel_down_nosig, switch_channel_event_set_data(), switch_channel_execute_on(), switch_channel_execute_on_value(), switch_channel_hangup, SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_private(), switch_channel_set_variable, switch_core_file_close(), switch_core_file_get_string(), switch_core_file_has_video(), switch_core_file_pre_close(), switch_core_file_write(), switch_core_file_write_video(), switch_core_gen_encoded_silence(), switch_core_media_bug_get_native_read_frame(), switch_core_media_bug_get_native_write_frame(), switch_core_media_bug_get_session(), switch_core_media_bug_read(), switch_core_media_bug_set_flag(), switch_core_media_bug_set_media_params(), switch_core_media_bug_test_flag(), switch_core_media_gen_key_frame, switch_core_session_get_channel(), switch_core_session_get_pool(), switch_core_session_get_read_impl(), switch_core_session_request_video_refresh, switch_core_session_reset(), switch_event_add_header_string(), switch_event_create, switch_event_fire, switch_event_get_header, SWITCH_EVENT_RECORD_START, SWITCH_FALSE, SWITCH_FILE_OPEN, switch_file_remove(), SWITCH_FILE_WRITE_APPEND, SWITCH_LOG_DEBUG, SWITCH_LOG_ERROR, switch_log_printf(), switch_micro_time_now(), switch_mutex_init(), switch_mutex_lock(), SWITCH_MUTEX_NESTED, switch_mutex_trylock(), switch_mutex_unlock(), SWITCH_PRI_LOW, SWITCH_RECOMMENDED_BUFFER_SIZE, SWITCH_STACK_BOTTOM, SWITCH_STATUS_SUCCESS, switch_test_flag, switch_thread_cond_create(), switch_thread_cond_signal(), switch_thread_create(), switch_thread_join(), SWITCH_THREAD_STACKSIZE, switch_threadattr_create(), switch_threadattr_priority_set(), switch_threadattr_stacksize_set(), switch_time_now(), SWITCH_TRUE, switch_true(), switch_yield, record_helper::thread, record_helper::thread_buffer, record_helper::thread_needs_transfer, record_helper::thread_ready, record_helper::transfer_complete, record_helper::transfer_from_session, record_helper::variables, switch_media_bug::video_ping_frame, record_helper::vwrites, record_helper::wready, record_helper::writes, and zstr.

Referenced by switch_ivr_record_session_event(), switch_ivr_stop_record_session(), and switch_ivr_transfer_recordings().

1391 {
1394  struct record_helper *rh = (struct record_helper *) user_data;
1395  switch_event_t *event;
1396  switch_frame_t *nframe;
1397  switch_size_t len = 0;
1398  int mask = switch_core_media_bug_test_flag(bug, SMBF_MASK);
1399  unsigned char null_data[SWITCH_RECOMMENDED_BUFFER_SIZE] = {0};
1400 
1401  /* Check if the recording was transferred (see recording_follow_transfer) */
1402  if (rh->recording_session != session) {
1403  return SWITCH_FALSE;
1404  }
1405 
1406  switch (type) {
1407  case SWITCH_ABC_TYPE_INIT:
1408  {
1409  const char *var = get_recording_var(channel, rh->variables, "RECORD_USE_THREAD");
1410 
1412 
1413  /* Check if recording is transferred from another session */
1415 
1416  /* If there is a thread, we need to re-initiate it */
1417  if (rh->thread_ready) {
1418  switch_media_bug_t *oldbug = rh->bug;
1419  int sanity = 200;
1420 
1421  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Re-initiating recording thread for file %s\n", rh->file);
1422 
1423  rh->bug = bug;
1424  rh->thread_needs_transfer = 1;
1425 
1429 
1430  while (--sanity > 0 && rh->thread_needs_transfer) {
1431  switch_yield(10000);
1432  }
1433 
1434  /* Check if the thread reacted on the transfer */
1435  if (rh->thread_needs_transfer) {
1436  /* Thread did not react, assuming it is cond_wait'ing */
1437  rh->bug = oldbug;
1439  rh->thread_needs_transfer = 0;
1440 
1441  return SWITCH_FALSE;
1442  }
1443  }
1444 
1445  if (rh->fh) {
1446  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Record session sample rate: %d -> %d\n", rh->fh->native_rate, rh->fh->samplerate);
1450  }
1451  }
1452 
1453  rh->transfer_from_session = NULL;
1454  rh->transfer_complete = 1;
1455 
1456  break;
1457  }
1458 
1459  /* Required for potential record_transfer */
1460  rh->bug = bug;
1461 
1462  if (!rh->native && rh->fh && (zstr(var) || switch_true(var))) {
1463  switch_threadattr_t *thd_attr = NULL;
1464  int sanity = 200;
1465 
1469  switch_threadattr_create(&thd_attr, rh->helper_pool);
1472  switch_thread_create(&rh->thread, thd_attr, recording_thread, bug, rh->helper_pool);
1473 
1474  while(--sanity > 0 && !rh->thread_ready) {
1475  switch_yield(10000);
1476  }
1477  }
1478 
1479  if(rh->start_event_sent == 0) {
1480  rh->start_event_sent = 1;
1482  switch_channel_event_set_data(channel, event);
1483  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Record-File-Path", rh->file);
1484  merge_recording_variables(rh, event);
1485  switch_event_fire(&event);
1486  }
1487  if (rh->variables) {
1488  const char *exec_app = NULL;
1489  exec_app = switch_event_get_header(rh->variables, "execute_on_record_start");
1490  if (exec_app) {
1491  switch_channel_execute_on_value(channel, exec_app);
1492  }
1493  }
1494  switch_channel_execute_on(channel, "execute_on_record_start");
1495  switch_channel_api_on(channel, "api_on_record_start");
1496  }
1497 
1501  rh->completion_cause = NULL;
1502 
1503  if (rh->fh) {
1504  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Record session sample rate: %d -> %d\n", rh->fh->native_rate, rh->fh->samplerate);
1510  }
1511  }
1512  }
1513  break;
1515  {
1517  switch_time_t diff;
1518 
1519  rh->rready = 1;
1520 
1522  len = nframe->datalen;
1523 
1524  if (!rh->wready) {
1525  unsigned char fill_data[SWITCH_RECOMMENDED_BUFFER_SIZE] = {0};
1526  switch_size_t fill_len = len;
1527 
1528  switch_core_gen_encoded_silence(fill_data, &rh->read_impl, len);
1529  switch_core_file_write(&rh->out_fh, fill_data, &fill_len);
1530  }
1531 
1532 
1533  if (rh->last_read_time && rh->last_read_time < now) {
1534  diff = (now - rh->last_read_time) / rh->read_impl.microseconds_per_packet;
1535 
1536  if (diff > 3) {
1537  unsigned char fill_data[SWITCH_RECOMMENDED_BUFFER_SIZE] = {0};
1538  switch_core_gen_encoded_silence(fill_data, &rh->read_impl, len);
1539 
1540  while(diff > 1) {
1541  switch_size_t fill_len = len;
1542  switch_core_file_write(&rh->in_fh, fill_data, &fill_len);
1543  diff--;
1544  }
1545  }
1546  }
1547 
1548  switch_core_file_write(&rh->in_fh, mask ? null_data : nframe->data, &len);
1549  rh->last_read_time = now;
1550  rh->writes++;
1551  }
1552  break;
1554  {
1556  switch_time_t diff;
1557  rh->wready = 1;
1558 
1560  len = nframe->datalen;
1561 
1562  if (!rh->rready) {
1563  unsigned char fill_data[SWITCH_RECOMMENDED_BUFFER_SIZE] = {0};
1564  switch_size_t fill_len = len;
1565  switch_core_gen_encoded_silence(fill_data, &rh->read_impl, len);
1566  switch_core_file_write(&rh->in_fh, fill_data, &fill_len);
1567  }
1568 
1569 
1570 
1571 
1572  if (rh->last_write_time && rh->last_write_time < now) {
1573  diff = (now - rh->last_write_time) / rh->read_impl.microseconds_per_packet;
1574 
1575  if (diff > 3) {
1576  unsigned char fill_data[SWITCH_RECOMMENDED_BUFFER_SIZE] = {0};
1577  switch_core_gen_encoded_silence(fill_data, &rh->read_impl, len);
1578 
1579  while(diff > 1) {
1580  switch_size_t fill_len = len;
1581  switch_core_file_write(&rh->out_fh, fill_data, &fill_len);
1582  diff--;
1583  }
1584  }
1585  }
1586 
1587  switch_core_file_write(&rh->out_fh, mask ? null_data : nframe->data, &len);
1588  rh->last_write_time = now;
1589  rh->writes++;
1590  }
1591  break;
1592  case SWITCH_ABC_TYPE_CLOSE:
1593  {
1595  switch_core_session_get_read_impl(session, &read_impl);
1596 
1597  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Stop recording file %s\n", rh->file);
1598  switch_channel_set_private(channel, rh->file, NULL);
1599 
1600  if (rh->native) {
1603  } else if (rh->fh) {
1604  switch_size_t len;
1605  uint8_t data[SWITCH_RECOMMENDED_BUFFER_SIZE];
1606  switch_frame_t frame = { 0 };
1607  const char *file_trimmed_ms = NULL;
1608  const char *file_size = NULL;
1609  const char *file_trimmed = NULL;
1610 
1611  if (rh->thread_ready) {
1612  switch_status_t st;
1613 
1614  rh->thread_ready = 0;
1615 
1619 
1620  switch_thread_join(&st, rh->thread);
1621  }
1622 
1623  if (rh->thread_buffer) {
1625  }
1626 
1627  frame.data = data;
1629 
1631  len = (switch_size_t) frame.datalen / 2;
1632 
1633  if (len && switch_core_file_write(rh->fh, mask ? null_data : data, &len) != SWITCH_STATUS_SUCCESS) {
1634  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error writing %s\n", rh->file);
1635  /* File write failed */
1636  set_completion_cause(rh, "uri-failure");
1637  if (rh->hangup_on_error) {
1640  }
1641  send_record_stop_event(channel, &read_impl, rh);
1642  record_helper_destroy(&rh, session);
1643 
1644  return SWITCH_FALSE;
1645  }
1646  }
1647 
1648 
1649  //if (switch_core_file_has_video(rh->fh, SWITCH_TRUE)) {
1650  //switch_core_media_set_video_file(session, NULL, SWITCH_RW_READ);
1651  //switch_channel_clear_flag_recursive(session->channel, CF_VIDEO_DECODED_READ);
1652  //}
1653 
1654 
1659  if (file_trimmed_ms) switch_channel_set_variable(channel, "record_trimmed_ms", file_trimmed_ms);
1660  if (file_size) switch_channel_set_variable(channel, "record_file_size", file_size);
1661  if (file_trimmed) switch_channel_set_variable(channel, "record_trimmed", file_trimmed);
1663 
1664  if (!rh->writes && !rh->vwrites && !switch_test_flag(rh->fh, SWITCH_FILE_WRITE_APPEND)) {
1665  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Discarding empty file %s\n", rh->file);
1666  switch_channel_set_variable(channel, "RECORD_DISCARDED", "true");
1668  set_completion_cause(rh, "empty-file");
1669  } else if ((rh->fh->samples_out < rh->fh->samplerate * rh->min_sec) && !switch_test_flag(rh->fh, SWITCH_FILE_WRITE_APPEND)) {
1670  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Discarding short file %s\n", rh->file);
1671  switch_channel_set_variable(channel, "RECORD_DISCARDED", "true");
1673  set_completion_cause(rh, "input-too-short");
1674  } else {
1675 
1676  if (switch_channel_down_nosig(channel)) {
1677  /* We got hung up */
1678  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Channel is hung up\n");
1679  if (rh->speech_detected) {
1680  /* Treat it as equivalent with final-silence */
1681  set_completion_cause(rh, "success-silence");
1682  } else {
1683  /* Treat it as equivalent with inital-silence timeout */
1684  set_completion_cause(rh, "no-input-timeout");
1685  }
1686  } else {
1687  /* Set the completion_cause to maxtime reached, unless it's already set */
1688  set_completion_cause(rh, "success-maxtime");
1689  }
1690  }
1691  }
1692 
1693  send_record_stop_event(channel, &read_impl, rh);
1694  record_helper_post_process(rh, session);
1695  record_helper_destroy(&rh, session);
1696  }
1697 
1698  break;
1700 
1701  if (rh->fh) {
1702  switch_size_t len;
1703  uint8_t data[SWITCH_RECOMMENDED_BUFFER_SIZE];
1704  switch_frame_t frame = { 0 };
1705  switch_status_t status;
1706  int i = 0;
1707 
1708  frame.data = data;
1710 
1711  for (;;) {
1712  status = switch_core_media_bug_read(bug, &frame, i++ == 0 ? SWITCH_FALSE : SWITCH_TRUE);
1713 
1714  if (status != SWITCH_STATUS_SUCCESS || !frame.datalen) {
1715  break;
1716  } else {
1717  len = (switch_size_t) frame.datalen / 2 / frame.channels;
1718 
1719  if (rh->thread_buffer) {
1721  switch_buffer_write(rh->thread_buffer, mask ? null_data : data, frame.datalen);
1726  }
1727  } else if (switch_core_file_write(rh->fh, mask ? null_data : data, &len) != SWITCH_STATUS_SUCCESS) {
1728  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error writing %s\n", rh->file);
1729  /* File write failed */
1730  set_completion_cause(rh, "uri-failure");
1731  if (rh->hangup_on_error) {
1734  }
1735  return SWITCH_FALSE;
1736  }
1737 
1738  rh->writes++;
1739 
1740  /* check for silence timeout */
1741  if (rh->silence_threshold) {
1742  switch_codec_implementation_t read_impl = { 0 };
1743  switch_core_session_get_read_impl(session, &read_impl);
1744  if (is_silence_frame(&frame, rh->silence_threshold, &read_impl)) {
1745  if (!rh->silence_time) {
1746  /* start of silence */
1747  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Start of silence detected\n");
1749  } else {
1750  /* continuing silence */
1751  int duration_ms = (int)((switch_micro_time_now() - rh->silence_time) / 1000);
1752  if (rh->silence_timeout_ms > 0 && duration_ms >= rh->silence_timeout_ms) {
1753  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Recording file %s timeout: %i >= %i\n", rh->file, duration_ms, rh->silence_timeout_ms);
1755  if (rh->speech_detected) {
1756  /* Reached final silence timeout */
1757  set_completion_cause(rh, "success-silence");
1758  } else {
1759  /* Reached initial silence timeout */
1760  set_completion_cause(rh, "no-input-timeout");
1761  /* Discard the silent file? */
1762  }
1763  }
1764  }
1765  } else { /* not silence */
1766  if (rh->silence_time) {
1767  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Start of speech detected\n");
1769  /* end of silence */
1770  rh->silence_time = 0;
1771  /* switch from initial timeout to final timeout */
1773  }
1774  }
1775  } else {
1776  /* no silence detection */
1777  if (!rh->speech_detected) {
1778  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "No silence detection configured; assuming start of speech\n");
1780  }
1781  }
1782  }
1783  }
1784  }
1785  break;
1788  if (rh->fh && switch_test_flag(rh->fh, SWITCH_FILE_OPEN)) {
1789  if (!bug->video_ping_frame) break;
1790 
1792  rh->hangup_on_error) {
1793  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error writing video to %s\n", rh->file);
1796  return SWITCH_FALSE;
1797  }
1798  rh->vwrites++;
1799  }
1800  break;
1801 
1802  case SWITCH_ABC_TYPE_WRITE:
1803  default:
1804  break;
1805  }
1806 
1807  return SWITCH_TRUE;
1808 }
switch_time_t switch_micro_time_now(void)
Get the current epoch time in microseconds.
Definition: switch_time.c:311
#define switch_event_fire(event)
Fire an event filling in most of the arguements with obvious values.
Definition: switch_event.h:413
#define switch_channel_hangup(channel, hangup_cause)
Hangup a channel flagging it&#39;s state machine to end.
#define switch_core_media_gen_key_frame(_session)
switch_status_t switch_channel_execute_on(switch_channel_t *channel, const char *variable_prefix)
switch_status_t switch_core_file_pre_close(_In_ switch_file_handle_t *fh)
Pre close an open file handle, then can get file size etc., no more wirte to the file.
uint8_t thread_needs_transfer
switch_status_t switch_thread_cond_create(switch_thread_cond_t **cond, switch_memory_pool_t *pool)
Definition: switch_apr.c:373
static switch_bool_t switch_true(const char *expr)
Evaluate the truthfullness of a string expression.
Definition: switch_utils.h:519
#define SWITCH_CHANNEL_SESSION_LOG(x)
void switch_core_session_reset(_In_ switch_core_session_t *session, switch_bool_t flush_dtmf, switch_bool_t reset_read_codec)
Reset the buffers and resampler on a session.
switch_time_t last_read_time
switch_status_t switch_mutex_trylock(switch_mutex_t *lock)
Definition: switch_apr.c:318
switch_status_t switch_channel_execute_on_value(switch_channel_t *channel, const char *variable_value)
switch_status_t switch_channel_set_private(switch_channel_t *channel, const char *key, const void *private_info)
Set private data on channel.
static void set_completion_cause(struct record_helper *rh, const char *completion_cause)
switch_frame_t * switch_core_media_bug_get_native_read_frame(switch_media_bug_t *bug)
switch_mutex_t * cond_mutex
switch_memory_pool_t * helper_pool
#define SWITCH_RECOMMENDED_BUFFER_SIZE
Definition: switch_types.h:590
switch_time_t silence_time
void switch_channel_event_set_data(_In_ switch_channel_t *channel, _In_ switch_event_t *event)
Add information about a given channel to an event object.
void switch_core_media_bug_set_media_params(switch_media_bug_t *bug, switch_mm_t *mm)
switch_status_t switch_threadattr_stacksize_set(switch_threadattr_t *attr, switch_size_t stacksize)
Definition: switch_apr.c:683
static switch_status_t record_helper_destroy(struct record_helper **rh, switch_core_session_t *session)
switch_status_t switch_core_file_get_string(_In_ switch_file_handle_t *fh, switch_audio_col_t col, const char **string)
get metadata of the desired string
Representation of an event.
Definition: switch_event.h:80
switch_status_t switch_core_file_close(_In_ switch_file_handle_t *fh)
Close an open file handle.
switch_thread_cond_t * cond
switch_core_session_t * switch_core_media_bug_get_session(_In_ switch_media_bug_t *bug)
Obtain the session from a media bug.
static switch_bool_t is_silence_frame(switch_frame_t *frame, int silence_threshold, switch_codec_implementation_t *codec_impl)
uint32_t switch_core_media_bug_set_flag(_In_ switch_media_bug_t *bug, _In_ uint32_t flag)
switch_time_t last_write_time
static void *SWITCH_THREAD_FUNC recording_thread(switch_thread_t *thread, void *obj)
switch_mutex_t * buffer_mutex
switch_size_t switch_buffer_write(_In_ switch_buffer_t *buffer, _In_bytecount_(datalen) const void *data, _In_ switch_size_t datalen)
Write data into a switch_buffer_t up to the length of datalen.
switch_core_session_t * recording_session
#define zstr(x)
Definition: switch_utils.h:314
switch_status_t switch_file_remove(const char *path, switch_memory_pool_t *pool)
Definition: switch_apr.c:452
switch_buffer_t * thread_buffer
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:313
switch_status_t switch_core_session_get_read_impl(switch_core_session_t *session, switch_codec_implementation_t *impp)
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
switch_codec_implementation_t read_impl
#define SWITCH_MUTEX_NESTED
Definition: switch_apr.h:318
int64_t switch_time_t
Definition: switch_apr.h:188
uint32_t buflen
Definition: switch_frame.h:70
if((uint32_t)(unpack->cur - unpack->buf) > unpack->buflen)
#define switch_yield(ms)
Wait a desired number of microseconds and yield the CPU.
Definition: switch_utils.h:998
uint32_t datalen
Definition: switch_frame.h:68
static void exec_app(switch_core_session_t *session, char *app_str)
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:308
const char * completion_cause
#define switch_core_session_request_video_refresh(_s)
Definition: switch_core.h:2881
#define SWITCH_THREAD_STACKSIZE
Definition: switch_types.h:584
switch_status_t switch_event_add_header_string(switch_event_t *event, switch_stack_t stack, const char *header_name, const char *data)
Add a string header to an event.
switch_file_handle_t in_fh
switch_status_t switch_mutex_init(switch_mutex_t **lock, unsigned int flags, switch_memory_pool_t *pool)
Definition: switch_apr.c:293
switch_status_t switch_thread_join(switch_status_t *retval, switch_thread_t *thd)
Definition: switch_apr.c:1379
#define switch_channel_down_nosig(_channel)
An abstraction of a data frame.
Definition: switch_frame.h:54
uintptr_t switch_size_t
switch_frame_t * video_ping_frame
switch_status_t switch_core_media_bug_read(_In_ switch_media_bug_t *bug, _In_ switch_frame_t *frame, switch_bool_t fill)
Read a frame from the bug.
static void record_helper_post_process(struct record_helper *rh, switch_core_session_t *session)
static void merge_recording_variables(struct record_helper *rh, switch_event_t *event)
switch_status_t switch_thread_cond_signal(switch_thread_cond_t *cond)
Definition: switch_apr.c:394
switch_bool_t speech_detected
switch_image_t * img
Definition: switch_frame.h:88
switch_status_t
Common return values.
switch_status_t switch_core_file_write(_In_ switch_file_handle_t *fh, void *data, switch_size_t *len)
Write media to a file handle.
static const char * get_recording_var(switch_channel_t *channel, switch_event_t *vars, const char *name)
uint8_t transfer_complete
switch_event_t * variables
#define switch_event_create(event, id)
Create a new event assuming it will not be custom event and therefore hiding the unused parameters...
Definition: switch_event.h:384
static void send_record_stop_event(switch_channel_t *channel, switch_codec_implementation_t *read_impl, struct record_helper *rh)
#define switch_event_get_header(_e, _h)
Definition: switch_event.h:172
uint32_t channels
Definition: switch_frame.h:76
switch_bool_t switch_core_file_has_video(switch_file_handle_t *fh, switch_bool_t CHECK_OPEN)
switch_thread_t * thread
switch_bool_t hangup_on_error
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:693
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
void switch_core_gen_encoded_silence(unsigned char *data, const switch_codec_implementation_t *read_impl, switch_size_t len)
switch_status_t switch_threadattr_create(switch_threadattr_t **new_attr, switch_memory_pool_t *pool)
Definition: switch_apr.c:665
switch_status_t switch_thread_create(switch_thread_t **new_thread, switch_threadattr_t *attr, switch_thread_start_t func, void *data, switch_memory_pool_t *cont)
Definition: switch_apr.c:698
A table of settings and callbacks that define a paticular implementation of a codec.
switch_status_t switch_core_file_write_video(_In_ switch_file_handle_t *fh, switch_frame_t *frame)
Write media to a file handle.
switch_frame_t * switch_core_media_bug_get_native_write_frame(switch_media_bug_t *bug)
uint32_t switch_core_media_bug_test_flag(_In_ switch_media_bug_t *bug, _In_ uint32_t flag)
Test for the existance of a flag on an media bug.
switch_file_handle_t out_fh
switch_file_handle_t * fh
switch_core_session_t * transfer_from_session
#define switch_channel_set_variable(_channel, _var, _val)
switch_time_t switch_time_now(void)
Definition: switch_apr.c:325
switch_status_t switch_channel_api_on(switch_channel_t *channel, const char *variable_prefix)
void switch_buffer_destroy(switch_buffer_t **buffer)
Destroy the buffer.
switch_media_bug_t * bug
switch_memory_pool_t * switch_core_session_get_pool(_In_ switch_core_session_t *session)
Retrieve the memory pool from a session.
switch_status_t switch_threadattr_priority_set(switch_threadattr_t *attr, switch_thread_priority_t priority)
Definition: switch_apr.c:688

◆ record_helper_create()

static switch_status_t record_helper_create ( struct record_helper **  rh,
switch_core_session_t session 
)
static

Definition at line 2859 of file switch_ivr_async.c.

References record_helper::helper_pool, pool, record_helper::recording_session, switch_core_alloc, switch_core_destroy_memory_pool, switch_core_new_memory_pool, SWITCH_STATUS_MEMERR, and SWITCH_STATUS_SUCCESS.

Referenced by switch_ivr_record_session_event().

2860 {
2861  switch_status_t status;
2863  struct record_helper *newrh;
2864 
2865  assert(rh);
2866  assert(session);
2867 
2868  if ((status = switch_core_new_memory_pool(&pool)) != SWITCH_STATUS_SUCCESS) {
2869  return status;
2870  }
2871 
2872  if (!(newrh = switch_core_alloc(pool, sizeof(*newrh)))) {
2874  return SWITCH_STATUS_MEMERR;
2875  }
2876 
2877  newrh->helper_pool = pool;
2878  newrh->recording_session = session;
2879 
2880  *rh = newrh;
2881 
2882  return SWITCH_STATUS_SUCCESS;
2883 }
#define switch_core_new_memory_pool(p)
Create a new sub memory pool from the core&#39;s master pool.
Definition: switch_core.h:633
switch_memory_pool_t * helper_pool
#define switch_core_destroy_memory_pool(p)
Returns a subpool back to the main pool.
Definition: switch_core.h:642
switch_memory_pool_t * pool
switch_core_session_t * recording_session
#define switch_core_alloc(_pool, _mem)
Allocate memory directly from a memory pool.
Definition: switch_core.h:684
switch_status_t
Common return values.
struct fspr_pool_t switch_memory_pool_t

◆ record_helper_destroy()

static switch_status_t record_helper_destroy ( struct record_helper **  rh,
switch_core_session_t session 
)
static

Definition at line 2885 of file switch_ivr_async.c.

References pool, SWITCH_CHANNEL_SESSION_LOG, switch_core_destroy_memory_pool, switch_core_file_close(), switch_event_safe_destroy, SWITCH_LOG_ERROR, switch_log_printf(), and SWITCH_STATUS_SUCCESS.

Referenced by record_callback(), and switch_ivr_record_session_event().

2886 {
2888 
2889  assert(rh);
2890  assert(*rh);
2891  assert(session);
2892 
2893  if ((*rh)->recording_session != session) {
2894  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Destroying a record helper of another session!\n");
2895  }
2896 
2897  if ((*rh)->native) {
2898  switch_core_file_close(&(*rh)->in_fh);
2899  switch_core_file_close(&(*rh)->out_fh);
2900  } else if((*rh)->fh) {
2901  switch_core_file_close((*rh)->fh);
2902  }
2903 
2904  switch_event_safe_destroy((*rh)->variables);
2905 
2906  pool = (*rh)->helper_pool;
2908  *rh = NULL;
2909 
2910  return SWITCH_STATUS_SUCCESS;
2911 }
#define SWITCH_CHANNEL_SESSION_LOG(x)
#define switch_core_destroy_memory_pool(p)
Returns a subpool back to the main pool.
Definition: switch_core.h:642
switch_memory_pool_t * pool
switch_status_t switch_core_file_close(_In_ switch_file_handle_t *fh)
Close an open file handle.
#define switch_event_safe_destroy(_event)
Definition: switch_event.h:219
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
struct fspr_pool_t switch_memory_pool_t

◆ record_helper_post_process()

static void record_helper_post_process ( struct record_helper rh,
switch_core_session_t session 
)
static

Definition at line 1356 of file switch_ivr_async.c.

References switch_stream_handle::data, switch_api_execute(), switch_channel_execute_on(), switch_channel_execute_on_value(), switch_channel_expand_variables, switch_channel_get_variable, switch_core_session_get_channel(), switch_core_session_strdup, switch_event_get_header, SWITCH_RECORD_POST_PROCESS_EXEC_API_VARIABLE, SWITCH_RECORD_POST_PROCESS_EXEC_APP_VARIABLE, switch_safe_free, SWITCH_STANDARD_STREAM, and record_helper::variables.

Referenced by record_callback().

1357 {
1359  const char *var = NULL;
1360  const char *post_process_exec = NULL;
1362  switch_channel_execute_on_value(channel, post_process_exec);
1363  }
1365 
1367  char *cmd = switch_core_session_strdup(session, var);
1368  char *data, *expanded = NULL;
1369  switch_stream_handle_t stream = { 0 };
1370 
1371  SWITCH_STANDARD_STREAM(stream);
1372 
1373  if ((data = strchr(cmd, ':'))) {
1374  *data++ = '\0';
1375  expanded = switch_channel_expand_variables(channel, data);
1376  }
1377 
1378  switch_api_execute(cmd, expanded, session, &stream);
1379 
1380  if (expanded && expanded != data) {
1381  free(expanded);
1382  }
1383 
1384  switch_safe_free(stream.data);
1385 
1386  }
1387 
1388 }
switch_status_t switch_channel_execute_on(switch_channel_t *channel, const char *variable_prefix)
switch_status_t switch_channel_execute_on_value(switch_channel_t *channel, const char *variable_value)
#define SWITCH_RECORD_POST_PROCESS_EXEC_APP_VARIABLE
Definition: switch_types.h:147
switch_status_t switch_api_execute(const char *cmd, const char *arg, switch_core_session_t *session, switch_stream_handle_t *stream)
Execute a registered API command.
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
#define switch_channel_get_variable(_c, _v)
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:885
#define SWITCH_STANDARD_STREAM(s)
#define switch_channel_expand_variables(_channel, _in)
switch_event_t * variables
#define switch_event_get_header(_e, _h)
Definition: switch_event.h:172
#define switch_core_session_strdup(_session, _todup)
Copy a string using memory allocation from a session&#39;s pool.
Definition: switch_core.h:719
#define SWITCH_RECORD_POST_PROCESS_EXEC_API_VARIABLE
Definition: switch_types.h:148

◆ recording_thread()

static void* SWITCH_THREAD_FUNC recording_thread ( switch_thread_t thread,
void *  obj 
)
static

Definition at line 1265 of file switch_ivr_async.c.

References record_helper::buffer_mutex, record_helper::bug, record_helper::cond, record_helper::cond_mutex, switch_codec_implementation::decoded_bytes_per_packet, record_helper::fh, record_helper::file, record_helper::hangup_on_error, record_helper::helper_pool, switch_codec_implementation::number_of_channels, record_helper::read_impl, record_helper::recording_session, set_completion_cause(), SMBF_STEREO, switch_buffer_create_dynamic(), switch_buffer_inuse(), switch_buffer_read(), SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER, switch_channel_down_nosig, switch_channel_hangup, SWITCH_CHANNEL_SESSION_LOG, switch_core_alloc, switch_core_file_has_video(), switch_core_file_write(), switch_core_media_bug_get_session(), switch_core_media_bug_get_user_data(), switch_core_media_bug_test_flag(), switch_core_session_get_channel(), switch_core_session_get_read_impl(), switch_core_session_read_lock(), switch_core_session_reset(), switch_core_session_rwunlock(), SWITCH_FILE_OPEN, SWITCH_LOG_ERROR, switch_log_printf(), switch_mutex_lock(), switch_mutex_unlock(), SWITCH_RECOMMENDED_BUFFER_SIZE, SWITCH_STATUS_SUCCESS, switch_test_flag, switch_thread_cond_wait(), SWITCH_TRUE, record_helper::thread_buffer, record_helper::thread_needs_transfer, and record_helper::thread_ready.

Referenced by record_callback().

1266 {
1270  struct record_helper *rh;
1271  switch_size_t bsize = SWITCH_RECOMMENDED_BUFFER_SIZE, samples = 0, inuse = 0;
1272  unsigned char *data;
1273  int channels = 1;
1275 
1277  return NULL;
1278  }
1279 
1282  rh->thread_ready = 1;
1283 
1286 
1288 
1289  while(switch_test_flag(rh->fh, SWITCH_FILE_OPEN)) {
1290  if (rh->thread_needs_transfer) {
1291  assert(session != rh->recording_session);
1292 
1294  /* Wait until recording is reverted to the original session */
1296  continue;
1297  }
1298 
1300  session = rh->recording_session;
1301  channel = switch_core_session_get_channel(session);
1302  bug = rh->bug;
1304 
1305  /* Tell record_callback that we transferred */
1306  rh->thread_needs_transfer = 0;
1307 
1308  /* Erasing the obj variable for safety because we transferred (we are under another bug) */
1309  obj = NULL;
1310  }
1311 
1313  switch_core_session_get_read_impl(session, &read_impl);
1315  bsize = read_impl.decoded_bytes_per_packet;
1316  }
1317  }
1318 
1320  inuse = switch_buffer_inuse(rh->thread_buffer);
1321 
1322  if ((!rh->thread_ready || switch_channel_down_nosig(channel)) && !inuse) {
1324  break;
1325  }
1326 
1327  if (!inuse) {
1329  if (rh->thread_ready) {
1331  }
1332  continue;
1333  }
1334 
1335  samples = switch_buffer_read(rh->thread_buffer, data, bsize) / 2 / channels;
1337 
1338  if (switch_core_file_write(rh->fh, data, &samples) != SWITCH_STATUS_SUCCESS) {
1339  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error writing %s\n", rh->file);
1340  /* File write failed */
1341  set_completion_cause(rh, "uri-failure");
1342  if (rh->hangup_on_error) {
1345  }
1346  }
1347  }
1348 
1350 
1352 
1353  return NULL;
1354 }
#define switch_channel_hangup(channel, hangup_cause)
Hangup a channel flagging it&#39;s state machine to end.
uint8_t thread_needs_transfer
#define SWITCH_CHANNEL_SESSION_LOG(x)
void switch_core_session_reset(_In_ switch_core_session_t *session, switch_bool_t flush_dtmf, switch_bool_t reset_read_codec)
Reset the buffers and resampler on a session.
switch_size_t switch_buffer_read(_In_ switch_buffer_t *buffer, _In_ void *data, _In_ switch_size_t datalen)
Read data from a switch_buffer_t up to the ammount of datalen if it is available. Remove read data fr...
void * switch_core_media_bug_get_user_data(_In_ switch_media_bug_t *bug)
Obtain private data from a media bug.
switch_status_t switch_buffer_create_dynamic(_Out_ switch_buffer_t **buffer, _In_ switch_size_t blocksize, _In_ switch_size_t start_len, _In_ switch_size_t max_len)
Allocate a new dynamic switch_buffer.
static void set_completion_cause(struct record_helper *rh, const char *completion_cause)
switch_mutex_t * cond_mutex
switch_memory_pool_t * helper_pool
#define SWITCH_RECOMMENDED_BUFFER_SIZE
Definition: switch_types.h:590
switch_thread_cond_t * cond
switch_status_t switch_core_session_read_lock(_In_ switch_core_session_t *session)
Acquire a read lock on the session.
switch_core_session_t * switch_core_media_bug_get_session(_In_ switch_media_bug_t *bug)
Obtain the session from a media bug.
switch_status_t switch_thread_cond_wait(switch_thread_cond_t *cond, switch_mutex_t *mutex)
Definition: switch_apr.c:378
switch_mutex_t * buffer_mutex
switch_core_session_t * recording_session
switch_buffer_t * thread_buffer
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:313
switch_status_t switch_core_session_get_read_impl(switch_core_session_t *session, switch_codec_implementation_t *impp)
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
switch_codec_implementation_t read_impl
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:308
#define switch_core_alloc(_pool, _mem)
Allocate memory directly from a memory pool.
Definition: switch_core.h:684
#define switch_channel_down_nosig(_channel)
uintptr_t switch_size_t
void switch_core_session_rwunlock(_In_ switch_core_session_t *session)
Unlock a read or write lock on as given session.
switch_status_t switch_core_file_write(_In_ switch_file_handle_t *fh, void *data, switch_size_t *len)
Write media to a file handle.
switch_bool_t switch_core_file_has_video(switch_file_handle_t *fh, switch_bool_t CHECK_OPEN)
switch_bool_t hangup_on_error
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:693
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
A table of settings and callbacks that define a paticular implementation of a codec.
uint32_t switch_core_media_bug_test_flag(_In_ switch_media_bug_t *bug, _In_ uint32_t flag)
Test for the existance of a flag on an media bug.
switch_file_handle_t * fh
switch_size_t switch_buffer_inuse(_In_ switch_buffer_t *buffer)
Get the in use amount of a switch_buffer_t.
switch_media_bug_t * bug

◆ recording_var_true()

static int recording_var_true ( switch_channel_t channel,
switch_event_t vars,
const char *  name 
)
static

Definition at line 2922 of file switch_ivr_async.c.

References get_recording_var(), and switch_true().

Referenced by switch_ivr_record_session_event().

2923 {
2924  return switch_true(get_recording_var(channel, vars, name));
2925 }
static switch_bool_t switch_true(const char *expr)
Evaluate the truthfullness of a string expression.
Definition: switch_utils.h:519
static const char * get_recording_var(switch_channel_t *channel, switch_event_t *vars, const char *name)
const char *const name
Definition: switch_cJSON.h:250

◆ send_record_stop_event()

static void send_record_stop_event ( switch_channel_t channel,
switch_codec_implementation_t read_impl,
struct record_helper rh 
)
static

Definition at line 1224 of file switch_ivr_async.c.

References switch_codec_implementation::actual_samples_per_second, record_helper::completion_cause, exec_app(), record_helper::fh, record_helper::file, merge_recording_variables(), switch_file_handle::samples_out, record_helper::start_event_sent, switch_channel_api_on(), switch_channel_event_set_data(), switch_channel_execute_on(), switch_channel_execute_on_value(), switch_channel_set_variable_printf(), switch_event_add_header_string(), switch_event_create, switch_event_fire, switch_event_get_header, SWITCH_EVENT_RECORD_STOP, SWITCH_STACK_BOTTOM, SWITCH_STATUS_SUCCESS, record_helper::variables, and zstr.

Referenced by record_callback().

1225 {
1226  switch_event_t *event;
1227 
1228  if (rh->fh) {
1229  switch_channel_set_variable_printf(channel, "record_samples", "%d", rh->fh->samples_out);
1230  if (read_impl->actual_samples_per_second) {
1231  switch_channel_set_variable_printf(channel, "record_seconds", "%d", rh->fh->samples_out / read_impl->actual_samples_per_second);
1232  switch_channel_set_variable_printf(channel, "record_ms", "%d", rh->fh->samples_out / (read_impl->actual_samples_per_second / 1000));
1233  }
1234  }
1235 
1236  if (!zstr(rh->completion_cause)) {
1237  switch_channel_set_variable_printf(channel, "record_completion_cause", "%s", rh->completion_cause);
1238  }
1239 
1241  switch_channel_event_set_data(channel, event);
1242  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Record-File-Path", rh->file);
1243  merge_recording_variables(rh, event);
1244  if (!zstr(rh->completion_cause)) {
1245  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Record-Completion-Cause", rh->completion_cause);
1246  }
1247  switch_event_fire(&event);
1248  }
1249 
1250  if (rh->start_event_sent) {
1251  if (rh->variables) {
1252  const char *exec_app = NULL;
1253  exec_app = switch_event_get_header(rh->variables, "execute_on_record_stop");
1254  if (exec_app) {
1255  switch_channel_execute_on_value(channel, exec_app);
1256  }
1257  }
1258  switch_channel_execute_on(channel, "execute_on_record_stop");
1259  switch_channel_api_on(channel, "api_on_record_stop");
1260  }
1261 
1262  rh->start_event_sent = 0;
1263 }
switch_status_t switch_channel_set_variable_printf(switch_channel_t *channel, const char *varname, const char *fmt,...)
#define switch_event_fire(event)
Fire an event filling in most of the arguements with obvious values.
Definition: switch_event.h:413
switch_status_t switch_channel_execute_on(switch_channel_t *channel, const char *variable_prefix)
switch_status_t switch_channel_execute_on_value(switch_channel_t *channel, const char *variable_value)
void switch_channel_event_set_data(_In_ switch_channel_t *channel, _In_ switch_event_t *event)
Add information about a given channel to an event object.
Representation of an event.
Definition: switch_event.h:80
#define zstr(x)
Definition: switch_utils.h:314
static void exec_app(switch_core_session_t *session, char *app_str)
const char * completion_cause
switch_status_t switch_event_add_header_string(switch_event_t *event, switch_stack_t stack, const char *header_name, const char *data)
Add a string header to an event.
static void merge_recording_variables(struct record_helper *rh, switch_event_t *event)
switch_event_t * variables
#define switch_event_create(event, id)
Create a new event assuming it will not be custom event and therefore hiding the unused parameters...
Definition: switch_event.h:384
#define switch_event_get_header(_e, _h)
Definition: switch_event.h:172
switch_file_handle_t * fh
switch_status_t switch_channel_api_on(switch_channel_t *channel, const char *variable_prefix)

◆ session_audio_callback()

static switch_bool_t session_audio_callback ( switch_media_bug_t bug,
void *  user_data,
switch_abc_type_t  type 
)
static

Definition at line 3665 of file switch_ivr_async.c.

References switch_frame::data, switch_frame::datalen, memset(), switch_codec_implementation::number_of_channels, switch_session_audio_t::read_level, switch_session_audio_t::read_mute, switch_session_audio_t::session, SWITCH_ABC_TYPE_READ_REPLACE, SWITCH_ABC_TYPE_WRITE_REPLACE, switch_change_sln_volume(), switch_channel_set_private(), switch_core_media_bug_get_read_replace_frame(), switch_core_media_bug_get_session(), switch_core_media_bug_get_write_replace_frame(), switch_core_media_bug_set_read_replace_frame(), switch_core_media_bug_set_write_replace_frame(), switch_core_session_get_channel(), switch_core_session_get_read_impl(), SWITCH_FALSE, switch_generate_sln_silence(), SWITCH_TRUE, switch_session_audio_t::write_level, and switch_session_audio_t::write_mute.

Referenced by switch_ivr_session_audio().

3666 {
3667  switch_session_audio_t *pvt = (switch_session_audio_t *) user_data;
3668  switch_frame_t *frame = NULL;
3669  int level = 0, mute = 0;
3672 
3673  switch_core_session_get_read_impl(session, &read_impl);
3674 
3675 
3677  if (!(pvt->read_level || pvt->write_level || pvt->read_mute || pvt->write_mute)) {
3679  return SWITCH_FALSE;
3680  }
3681  }
3682 
3683  if (type == SWITCH_ABC_TYPE_READ_REPLACE) {
3684  level = pvt->read_level;
3685  mute = pvt->read_mute;
3687  } else if (type == SWITCH_ABC_TYPE_WRITE_REPLACE) {
3688  level = pvt->write_level;
3689  mute = pvt->write_mute;
3691  }
3692 
3693  if (frame) {
3694  if (mute) {
3695  if (mute > 1) {
3696  switch_generate_sln_silence(frame->data, frame->datalen / 2, read_impl.number_of_channels, mute);
3697  } else {
3698  memset(frame->data, 0, frame->datalen);
3699  }
3700  } else if (level) {
3701  switch_change_sln_volume(frame->data, frame->datalen / 2, level);
3702  }
3703 
3704  if (type == SWITCH_ABC_TYPE_READ_REPLACE) {
3706  } else if (type == SWITCH_ABC_TYPE_WRITE_REPLACE) {
3708  }
3709  }
3710 
3711  return SWITCH_TRUE;
3712 }
switch_status_t switch_channel_set_private(switch_channel_t *channel, const char *key, const void *private_info)
Set private data on channel.
void switch_core_media_bug_set_write_replace_frame(_In_ switch_media_bug_t *bug, _In_ switch_frame_t *frame)
Set a return replace frame.
void switch_generate_sln_silence(int16_t *data, uint32_t samples, uint32_t channels, uint32_t divisor)
Generate static noise.
switch_core_session_t * switch_core_media_bug_get_session(_In_ switch_media_bug_t *bug)
Obtain the session from a media bug.
void switch_core_media_bug_set_read_replace_frame(_In_ switch_media_bug_t *bug, _In_ switch_frame_t *frame)
Set a return replace frame.
switch_core_session_t * session
void switch_change_sln_volume(int16_t *data, uint32_t samples, int32_t vol)
Change the volume of a signed linear audio frame.
switch_status_t switch_core_session_get_read_impl(switch_core_session_t *session, switch_codec_implementation_t *impp)
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
switch_codec_implementation_t read_impl
switch_frame_t * switch_core_media_bug_get_read_replace_frame(_In_ switch_media_bug_t *bug)
Obtain a replace frame from a media bug.
uint32_t datalen
Definition: switch_frame.h:68
switch_frame_t * switch_core_media_bug_get_write_replace_frame(_In_ switch_media_bug_t *bug)
Obtain a replace frame from a media bug.
An abstraction of a data frame.
Definition: switch_frame.h:54
A table of settings and callbacks that define a paticular implementation of a codec.
memset(buf, 0, buflen)

◆ set_completion_cause()

static void set_completion_cause ( struct record_helper rh,
const char *  completion_cause 
)
static

Set the recording completion cause. The cause can only be set once, to minimize the logic in the record_callback. [The completion_cause strings are essentially those of an MRCP Recorder resource.]

Definition at line 1173 of file switch_ivr_async.c.

References record_helper::completion_cause.

Referenced by record_callback(), recording_thread(), and switch_ivr_record_session_event().

1174 {
1175  if (!rh->completion_cause) {
1177  }
1178 }
const char * completion_cause

◆ speech_callback()

static switch_bool_t speech_callback ( switch_media_bug_t bug,
void *  user_data,
switch_abc_type_t  type 
)
static

Definition at line 5147 of file switch_ivr_async.c.

References speech_thread_handle::ah, switch_frame::buflen, speech_thread_handle::cond, switch_frame::data, switch_frame::datalen, speech_thread_handle::mutex, speech_thread_handle::pool, speech_thread_handle::ready, speech_thread_handle::session, speech_on_dtmf(), speech_thread(), SWITCH_ABC_TYPE_CLOSE, SWITCH_ABC_TYPE_INIT, SWITCH_ABC_TYPE_READ, SWITCH_ABC_TYPE_WRITE, SWITCH_ASR_FLAG_NONE, SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_private(), switch_core_asr_check_results(), switch_core_asr_close(), switch_core_asr_feed(), switch_core_media_bug_get_session(), switch_core_media_bug_read(), switch_core_session_get_channel(), SWITCH_FALSE, SWITCH_LOG_DEBUG, switch_log_printf(), switch_mutex_lock(), switch_mutex_trylock(), switch_mutex_unlock(), SWITCH_RECOMMENDED_BUFFER_SIZE, SWITCH_SPEECH_KEY, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_thread_cond_signal(), switch_thread_create(), switch_thread_join(), SWITCH_THREAD_STACKSIZE, switch_threadattr_create(), switch_threadattr_stacksize_set(), SWITCH_TRUE, and speech_thread_handle::thread.

Referenced by switch_ivr_detect_speech_init().

5148 {
5149  struct speech_thread_handle *sth = (struct speech_thread_handle *) user_data;
5150  uint8_t data[SWITCH_RECOMMENDED_BUFFER_SIZE];
5151  switch_frame_t frame = { 0 };
5153 
5154  frame.data = data;
5156 
5157  switch (type) {
5158  case SWITCH_ABC_TYPE_INIT:
5159  {
5160  switch_threadattr_t *thd_attr = NULL;
5161 
5162  switch_threadattr_create(&thd_attr, sth->pool);
5164  switch_thread_create(&sth->thread, thd_attr, speech_thread, sth, sth->pool);
5165  }
5166  break;
5167  case SWITCH_ABC_TYPE_CLOSE:
5168  {
5169  switch_status_t st;
5172 
5174  switch_core_event_hook_remove_recv_dtmf(session, speech_on_dtmf);
5175 
5176  switch_core_asr_close(sth->ah, &flags);
5177  if (sth->mutex && sth->cond && sth->ready) {
5180  switch_mutex_unlock(sth->mutex);
5181  }
5182  }
5183 
5184  switch_thread_join(&st, sth->thread);
5185 
5186  }
5187  break;
5188  case SWITCH_ABC_TYPE_READ:
5189  if (sth->ah) {
5191  if (switch_core_asr_feed(sth->ah, frame.data, frame.datalen, &flags) != SWITCH_STATUS_SUCCESS) {
5193  return SWITCH_FALSE;
5194  }
5196  if (sth->mutex && sth->cond && sth->ready) {
5197  switch_mutex_lock(sth->mutex);
5199  switch_mutex_unlock(sth->mutex);
5200  }
5201  }
5202  }
5203  }
5204  break;
5205  case SWITCH_ABC_TYPE_WRITE:
5206  default:
5207  break;
5208  }
5209 
5210  return SWITCH_TRUE;
5211 }
#define SWITCH_CHANNEL_SESSION_LOG(x)
switch_asr_handle_t * ah
switch_status_t switch_mutex_trylock(switch_mutex_t *lock)
Definition: switch_apr.c:318
switch_core_session_t * session
switch_status_t switch_channel_set_private(switch_channel_t *channel, const char *key, const void *private_info)
Set private data on channel.
#define SWITCH_RECOMMENDED_BUFFER_SIZE
Definition: switch_types.h:590
switch_status_t switch_threadattr_stacksize_set(switch_threadattr_t *attr, switch_size_t stacksize)
Definition: switch_apr.c:683
static switch_status_t speech_on_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf, switch_dtmf_direction_t direction)
switch_core_session_t * switch_core_media_bug_get_session(_In_ switch_media_bug_t *bug)
Obtain the session from a media bug.
switch_status_t switch_core_asr_feed(switch_asr_handle_t *ah, void *data, unsigned int len, switch_asr_flag_t *flags)
Feed audio data to an asr handle.
#define SWITCH_SPEECH_KEY
Definition: switch_types.h:233
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:313
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
uint32_t buflen
Definition: switch_frame.h:70
switch_status_t switch_core_asr_close(switch_asr_handle_t *ah, switch_asr_flag_t *flags)
Close an asr handle.
uint32_t datalen
Definition: switch_frame.h:68
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:308
switch_thread_cond_t * cond
switch_memory_pool_t * pool
#define SWITCH_THREAD_STACKSIZE
Definition: switch_types.h:584
switch_thread_t * thread
switch_status_t switch_thread_join(switch_status_t *retval, switch_thread_t *thd)
Definition: switch_apr.c:1379
An abstraction of a data frame.
Definition: switch_frame.h:54
switch_status_t switch_core_media_bug_read(_In_ switch_media_bug_t *bug, _In_ switch_frame_t *frame, switch_bool_t fill)
Read a frame from the bug.
uint32_t switch_asr_flag_t
switch_status_t switch_thread_cond_signal(switch_thread_cond_t *cond)
Definition: switch_apr.c:394
static void *SWITCH_THREAD_FUNC speech_thread(switch_thread_t *thread, void *obj)
switch_status_t switch_core_asr_check_results(switch_asr_handle_t *ah, switch_asr_flag_t *flags)
Check an asr handle for results.
switch_status_t
Common return values.
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
switch_status_t switch_threadattr_create(switch_threadattr_t **new_attr, switch_memory_pool_t *pool)
Definition: switch_apr.c:665
switch_status_t switch_thread_create(switch_thread_t **new_thread, switch_threadattr_t *attr, switch_thread_start_t func, void *data, switch_memory_pool_t *cont)
Definition: switch_apr.c:698
switch_mutex_t * mutex

◆ speech_on_dtmf()

static switch_status_t speech_on_dtmf ( switch_core_session_t session,
const switch_dtmf_t dtmf,
switch_dtmf_direction_t  direction 
)
static

Definition at line 5213 of file switch_ivr_async.c.

References speech_thread_handle::ah, SWITCH_ASR_FLAG_NONE, switch_channel_get_private(), SWITCH_CHANNEL_SESSION_LOG, switch_core_asr_feed_dtmf(), switch_core_session_get_channel(), SWITCH_LOG_ERROR, switch_log_printf(), SWITCH_SPEECH_KEY, and SWITCH_STATUS_SUCCESS.

Referenced by speech_callback(), switch_ivr_detect_speech_init(), and switch_ivr_stop_detect_speech().

5214 {
5219 
5220  if (sth) {
5221  if (switch_core_asr_feed_dtmf(sth->ah, dtmf, &flags) != SWITCH_STATUS_SUCCESS) {
5222  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error Feeding DTMF\n");
5223  }
5224  }
5225 
5226  return status;
5227 }
#define SWITCH_CHANNEL_SESSION_LOG(x)
switch_asr_handle_t * ah
switch_status_t switch_core_asr_feed_dtmf(switch_asr_handle_t *ah, const switch_dtmf_t *dtmf, switch_asr_flag_t *flags)
Feed DTMF to an asr handle.
#define SWITCH_SPEECH_KEY
Definition: switch_types.h:233
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
uint32_t switch_asr_flag_t
switch_status_t
Common return values.
void * switch_channel_get_private(switch_channel_t *channel, const char *key)
Retrieve private from a given channel.
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.

◆ speech_thread()

static void* SWITCH_THREAD_FUNC speech_thread ( switch_thread_t thread,
void *  obj 
)
static

Definition at line 4990 of file switch_ivr_async.c.

References speech_thread_handle::ah, speech_thread_handle::cond, switch_dtmf_t::digit, switch_dtmf_t::duration, is_dtmf, speech_thread_handle::mutex, speech_thread_handle::pool, speech_thread_handle::ready, speech_thread_handle::session, switch_dtmf_t::source, SWITCH_ASR_FLAG_CLOSED, SWITCH_ASR_FLAG_FIRE_EVENTS, SWITCH_ASR_FLAG_NONE, SWITCH_CHANNEL_CHANNEL_LOG, switch_channel_down_nosig, switch_channel_event_set_data(), switch_channel_get_variable, switch_channel_queue_dtmf(), switch_channel_up_nosig, switch_core_asr_check_results(), switch_core_asr_get_result_headers(), switch_core_asr_get_results(), switch_core_default_dtmf_duration(), switch_core_session_get_channel(), switch_core_session_queue_event(), switch_core_session_read_lock(), switch_core_session_rwunlock(), SWITCH_DTMF_INBAND_AUDIO, switch_event_add_body(), switch_event_add_header_string(), switch_event_create, switch_event_destroy(), SWITCH_EVENT_DETECTED_SPEECH, switch_event_dup(), switch_event_fire, switch_event_merge(), switch_ivr_resume_detect_speech(), SWITCH_LOG_DEBUG, SWITCH_LOG_ERROR, switch_log_printf(), switch_mutex_init(), switch_mutex_lock(), SWITCH_MUTEX_NESTED, switch_mutex_unlock(), switch_safe_free, SWITCH_STACK_BOTTOM, SWITCH_STATUS_BREAK, SWITCH_STATUS_MORE_DATA, SWITCH_STATUS_SUCCESS, switch_stristr(), switch_test_flag, switch_thread_cond_create(), switch_thread_cond_wait(), and switch_true().

Referenced by speech_callback().

4991 {
4992  struct speech_thread_handle *sth = (struct speech_thread_handle *) obj;
4995  switch_status_t status;
4996  switch_event_t *event;
4997 
4998  switch_thread_cond_create(&sth->cond, sth->pool);
5000 
5002  sth->ready = 0;
5003  return NULL;
5004  }
5005 
5006  switch_mutex_lock(sth->mutex);
5007 
5008  sth->ready = 1;
5009 
5011  char *xmlstr = NULL;
5012  switch_event_t *headers = NULL;
5013 
5014  switch_thread_cond_wait(sth->cond, sth->mutex);
5015 
5017  break;
5018  }
5019 
5021 
5022  status = switch_core_asr_get_results(sth->ah, &xmlstr, &flags);
5023 
5024  if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK && status != SWITCH_STATUS_MORE_DATA) {
5025  goto done;
5026  } else {
5027  /* Try to fetch extra information for this result, the return value doesn't really matter here - it's just optional data. */
5028  switch_core_asr_get_result_headers(sth->ah, &headers, &flags);
5029  }
5030 
5031  if (status == SWITCH_STATUS_SUCCESS && switch_true(switch_channel_get_variable(channel, "asr_intercept_dtmf"))) {
5032  const char *p;
5033 
5034  if ((p = switch_stristr("<input>", xmlstr))) {
5035  p += 7;
5036  }
5037 
5038  while (p && *p) {
5039  char c;
5040 
5041  if (*p == '<') {
5042  break;
5043  }
5044 
5045  if (!strncasecmp(p, "pound", 5)) {
5046  c = '#';
5047  p += 5;
5048  } else if (!strncasecmp(p, "hash", 4)) {
5049  c = '#';
5050  p += 4;
5051  } else if (!strncasecmp(p, "star", 4)) {
5052  c = '*';
5053  p += 4;
5054  } else if (!strncasecmp(p, "asterisk", 8)) {
5055  c = '*';
5056  p += 8;
5057  } else {
5058  c = *p;
5059  p++;
5060  }
5061 
5062  if (is_dtmf(c)) {
5063  switch_dtmf_t dtmf = {0};
5064  dtmf.digit = c;
5067  switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "Queue speech detected dtmf %c\n", c);
5068  switch_channel_queue_dtmf(channel, &dtmf);
5069  }
5070 
5071  }
5073  }
5074 
5076  if (status == SWITCH_STATUS_SUCCESS) {
5077  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Speech-Type", "detected-speech");
5078 
5079  if (headers) {
5080  switch_event_merge(event, headers);
5081  }
5082 
5083  switch_event_add_body(event, "%s", xmlstr);
5084  } else if (status == SWITCH_STATUS_MORE_DATA) {
5085  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Speech-Type", "detected-partial-speech");
5086 
5087  if (headers) {
5088  switch_event_merge(event, headers);
5089  }
5090 
5091  switch_event_add_body(event, "%s", xmlstr);
5092  } else {
5093  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Speech-Type", "begin-speaking");
5094  }
5095 
5097  switch_event_t *dup;
5098 
5099  if (switch_event_dup(&dup, event) == SWITCH_STATUS_SUCCESS) {
5100  switch_channel_event_set_data(channel, dup);
5101  switch_event_fire(&dup);
5102  }
5103 
5104  }
5105 
5107  switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_ERROR, "Event queue failed!\n");
5108  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "delivery-failure", "true");
5109  switch_event_fire(&event);
5110  }
5111  }
5112 
5113  switch_safe_free(xmlstr);
5114 
5115  if (headers) {
5116  switch_event_destroy(&headers);
5117  }
5118  }
5119  }
5120  done:
5121 
5123  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Speech-Type", "closed");
5125  switch_event_t *dup;
5126 
5127  if (switch_event_dup(&dup, event) == SWITCH_STATUS_SUCCESS) {
5128  switch_channel_event_set_data(channel, dup);
5129  switch_event_fire(&dup);
5130  }
5131 
5132  }
5133 
5135  switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_ERROR, "Event queue failed!\n");
5136  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "delivery-failure", "true");
5137  switch_event_fire(&event);
5138  }
5139  }
5140 
5141  switch_mutex_unlock(sth->mutex);
5143 
5144  return NULL;
5145 }
#define switch_event_fire(event)
Fire an event filling in most of the arguements with obvious values.
Definition: switch_event.h:413
switch_status_t switch_thread_cond_create(switch_thread_cond_t **cond, switch_memory_pool_t *pool)
Definition: switch_apr.c:373
static switch_bool_t switch_true(const char *expr)
Evaluate the truthfullness of a string expression.
Definition: switch_utils.h:519
switch_asr_handle_t * ah
switch_status_t switch_channel_queue_dtmf(_In_ switch_channel_t *channel, _In_ const switch_dtmf_t *dtmf)
Queue DTMF on a given channel.
switch_status_t switch_core_asr_get_result_headers(switch_asr_handle_t *ah, switch_event_t **headers, switch_asr_flag_t *flags)
Get result headers from an asr handle.
switch_core_session_t * session
void switch_channel_event_set_data(_In_ switch_channel_t *channel, _In_ switch_event_t *event)
Add information about a given channel to an event object.
switch_status_t switch_core_asr_get_results(switch_asr_handle_t *ah, char **xmlstr, switch_asr_flag_t *flags)
Get results from an asr handle.
Representation of an event.
Definition: switch_event.h:80
switch_status_t switch_event_add_body(switch_event_t *event, const char *fmt,...) PRINTF_FUNCTION(2
Add a body to an event.
switch_status_t switch_core_session_read_lock(_In_ switch_core_session_t *session)
Acquire a read lock on the session.
switch_status_t switch_thread_cond_wait(switch_thread_cond_t *cond, switch_mutex_t *mutex)
Definition: switch_apr.c:378
uint32_t duration
Definition: switch_types.h:298
switch_status_t switch_event_dup(switch_event_t **event, switch_event_t *todup)
Duplicate an event.
#define is_dtmf(key)
determine if a character is a valid DTMF key
Definition: switch_utils.h:683
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:313
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
#define SWITCH_MUTEX_NESTED
Definition: switch_apr.h:318
void switch_event_merge(switch_event_t *event, switch_event_t *tomerge)
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:308
switch_thread_cond_t * cond
switch_memory_pool_t * pool
#define switch_channel_get_variable(_c, _v)
switch_status_t switch_event_add_header_string(switch_event_t *event, switch_stack_t stack, const char *header_name, const char *data)
Add a string header to an event.
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:885
switch_status_t switch_mutex_init(switch_mutex_t **lock, unsigned int flags, switch_memory_pool_t *pool)
Definition: switch_apr.c:293
#define switch_channel_down_nosig(_channel)
uint32_t switch_asr_flag_t
switch_status_t switch_core_session_queue_event(_In_ switch_core_session_t *session, _Inout_ switch_event_t **event)
Queue an event on a given session.
switch_status_t switch_ivr_resume_detect_speech(switch_core_session_t *session)
Resume background Speech detection on a session.
void switch_core_session_rwunlock(_In_ switch_core_session_t *session)
Unlock a read or write lock on as given session.
uint32_t switch_core_default_dtmf_duration(uint32_t duration)
Definition: switch_core.c:1721
switch_status_t switch_core_asr_check_results(switch_asr_handle_t *ah, switch_asr_flag_t *flags)
Check an asr handle for results.
switch_status_t
Common return values.
#define switch_event_create(event, id)
Create a new event assuming it will not be custom event and therefore hiding the unused parameters...
Definition: switch_event.h:384
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:693
switch_dtmf_source_t source
Definition: switch_types.h:300
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
const char * switch_stristr(const char *instr, const char *str)
#define switch_channel_up_nosig(_channel)
void switch_event_destroy(switch_event_t **event)
Destroy an event.
#define SWITCH_CHANNEL_CHANNEL_LOG(x)
switch_mutex_t * mutex

◆ switch_gcd()

static uint32_t switch_gcd ( uint32_t  x,
uint32_t  y 
)
static

Definition at line 2266 of file switch_ivr_async.c.

Referenced by switch_lcm().

2267 {
2268  if (y == 0) {
2269  return x;
2270  }
2271 
2272  return switch_gcd(y, x % y);
2273 }
static uint32_t switch_gcd(uint32_t x, uint32_t y)

◆ switch_ivr_dmachine_check_match()

static dm_match_t switch_ivr_dmachine_check_match ( switch_ivr_dmachine_t dmachine,
switch_bool_t  is_timeout 
)
static

Definition at line 362 of file switch_ivr_async.c.

References dm_binding_head_t::binding_list, switch_ivr_dmachine::cur_digit_len, switch_ivr_dmachine_binding::digits, switch_ivr_dmachine::digits, DM_MATCH_BOTH, DM_MATCH_EXACT, DM_MATCH_NEVER, DM_MATCH_NONE, DM_MATCH_PARTIAL, switch_ivr_dmachine_binding::first_match, switch_ivr_dmachine_binding::is_priority, switch_ivr_dmachine_binding::is_regex, switch_ivr_dmachine::last_matching_binding, switch_ivr_dmachine::last_matching_digits, switch_ivr_dmachine::max_digit_len, memset(), switch_ivr_dmachine_binding::next, switch_ivr_dmachine::pool, switch_ivr_dmachine::realm, switch_ivr_dmachine_binding::repl, switch_ivr_dmachine_binding::rmatch, switch_ivr_dmachine_binding::substituted, switch_assert, switch_core_strdup, switch_perform_substitution(), switch_regex_match(), switch_regex_perform(), switch_regex_safe_free, switch_set_string, SWITCH_STATUS_SUCCESS, dm_binding_head_t::terminators, and zstr.

Referenced by switch_ivr_dmachine_ping().

363 {
364  dm_match_t best = DM_MATCH_NONE;
365  switch_ivr_dmachine_binding_t *bp, *exact_bp = NULL, *partial_bp = NULL, *both_bp = NULL, *r_bp = NULL;
366  int pmatches = 0, ematches = 0, rmatches = 0;
367 
368  if (!dmachine->cur_digit_len || !dmachine->realm) goto end;
369 
370  for(bp = dmachine->realm->binding_list; bp; bp = bp->next) {
371  if (bp->is_regex) {
372  if (bp->repl) {
373  int ovector[30] = { 0 };
374  int proceed = 0;
375  switch_regex_t *re = NULL;
376 
377 
378  proceed = switch_regex_perform(dmachine->digits, bp->digits, &re, ovector, sizeof(ovector) / sizeof(ovector[0]));
379 
380  if (proceed) {
381  char *substituted = NULL;
382  switch_size_t len;
383 
384  len = (strlen(dmachine->digits) + strlen(bp->digits) + 10) * proceed;
385  substituted = malloc(len);
386  switch_assert(substituted);
387  memset(substituted, 0, len);
388  switch_perform_substitution(re, proceed, bp->repl, dmachine->digits, substituted, len, ovector);
389 
390  if (!bp->substituted || strcmp(substituted, bp->substituted)) {
391  bp->substituted = switch_core_strdup(dmachine->pool, substituted);
392  }
393  free(substituted);
395  bp->rmatch = 1;
396  } else {
397  bp->substituted = NULL;
398  bp->rmatch = 0;
399  }
400  } else {
401  switch_status_t r_status = switch_regex_match(dmachine->digits, bp->digits);
402  bp->rmatch = r_status == SWITCH_STATUS_SUCCESS;
403  }
404 
405  rmatches++;
406  pmatches++;
407 
408  if (bp->rmatch && bp->first_match) break;
409 
410  } else {
411  if (!strncmp(dmachine->digits, bp->digits, strlen(dmachine->digits))) {
412  pmatches++;
413  if (dmachine->cur_digit_len == strlen(bp->digits)) {
414  ematches++;
415  }
416  }
417  }
418  }
419 
420  if (!zstr(dmachine->realm->terminators)) {
421  char *p = dmachine->realm->terminators;
422  char *q;
423 
424  while(p && *p) {
425  if ((q=strrchr(dmachine->digits, *p))) {
426  *q = '\0';
427  is_timeout = 1;
428  break;
429  }
430  p++;
431  }
432  }
433 
434  for(bp = dmachine->realm->binding_list; bp; bp = bp->next) {
435  if (bp->is_regex) {
436  if (bp->rmatch) {
437  if (bp->first_match || (bp->is_priority && ! ematches) || is_timeout || (bp == dmachine->realm->binding_list && !bp->next)) {
438  best = DM_MATCH_EXACT;
439  exact_bp = bp;
440  break;
441  }
442  best = DM_MATCH_PARTIAL;
443  }
444  } else {
445  int pmatch = !strncmp(dmachine->digits, bp->digits, strlen(dmachine->digits));
446 
447  if (!exact_bp && pmatch && (bp->first_match || !rmatches || bp->is_priority || is_timeout) && !strcmp(bp->digits, dmachine->digits)) {
448  best = DM_MATCH_EXACT;
449  exact_bp = bp;
450  if (bp->first_match || bp->is_priority || dmachine->cur_digit_len == dmachine->max_digit_len) break;
451  }
452 
453  if (!(both_bp && partial_bp) && strlen(bp->digits) != strlen(dmachine->digits) && pmatch) {
454 
455  if (exact_bp) {
456  best = DM_MATCH_BOTH;
457  both_bp = bp;
458  } else {
459  best = DM_MATCH_PARTIAL;
460  partial_bp = bp;
461  }
462  }
463 
464  if (both_bp && exact_bp && partial_bp) break;
465  }
466  }
467 
468  if (!pmatches) {
469  best = DM_MATCH_NEVER;
470  }
471 
472 
473  end:
474 
475  if (is_timeout) {
476  if (both_bp) {
477  r_bp = exact_bp;
478  }
479  }
480 
481  if (best == DM_MATCH_EXACT && exact_bp) {
482  r_bp = exact_bp;
483  }
484 
485 
486  if (r_bp) {
487  dmachine->last_matching_binding = r_bp;
488 
489  if (r_bp->substituted) {
490  switch_set_string(dmachine->last_matching_digits, r_bp->substituted);
491  } else {
492  switch_set_string(dmachine->last_matching_digits, dmachine->digits);
493  }
494  best = DM_MATCH_EXACT;
495  }
496 
497  return best;
498 
499 }
struct switch_ivr_dmachine_binding * next
#define switch_regex_safe_free(re)
Definition: switch_regex.h:79
void switch_perform_substitution(switch_regex_t *re, int match_count, const char *data, const char *field_data, char *substituted, switch_size_t len, int *ovector)
Definition: switch_regex.c:131
#define switch_core_strdup(_pool, _todup)
Copy a string using memory allocation from a given pool.
Definition: switch_core.h:733
switch_ivr_dmachine_binding_t * last_matching_binding
dm_binding_head_t * realm
struct real_pcre switch_regex_t
Definition: switch_regex.h:43
switch_ivr_dmachine_binding_t * binding_list
#define zstr(x)
Definition: switch_utils.h:314
char digits[DMACHINE_MAX_DIGIT_LEN]
uintptr_t switch_size_t
dm_match_t
int switch_regex_perform(const char *field, const char *expression, switch_regex_t **new_re, int *ovector, uint32_t olen)
Definition: switch_regex.c:55
switch_status_t
Common return values.
switch_memory_pool_t * pool
char last_matching_digits[DMACHINE_MAX_DIGIT_LEN]
#define switch_set_string(_dst, _src)
Definition: switch_utils.h:734
#define switch_assert(expr)
memset(buf, 0, buflen)
switch_status_t switch_regex_match(const char *target, const char *expression)
Function to evaluate an expression against a string.
Definition: switch_regex.c:300

◆ switch_ivr_dmachine_check_timeout()

static switch_bool_t switch_ivr_dmachine_check_timeout ( switch_ivr_dmachine_t dmachine)
static

Definition at line 501 of file switch_ivr_async.c.

References switch_ivr_dmachine::cur_digit_len, switch_ivr_dmachine::digit_timeout_ms, switch_ivr_dmachine::input_timeout_ms, switch_ivr_dmachine::last_digit_time, SWITCH_FALSE, switch_time_now(), and SWITCH_TRUE.

Referenced by switch_ivr_dmachine_ping().

502 {
504  uint32_t timeout = dmachine->cur_digit_len ? dmachine->digit_timeout_ms : dmachine->input_timeout_ms;
505 
506  if (!dmachine->last_digit_time) dmachine->last_digit_time = now;
507 
508  if (timeout) {
509  if ((uint32_t)((now - dmachine->last_digit_time) / 1000) > timeout) {
510  return SWITCH_TRUE;
511  }
512  }
513 
514  return SWITCH_FALSE;
515 }
int64_t switch_time_t
Definition: switch_apr.h:188
switch_time_t last_digit_time
switch_time_t switch_time_now(void)
Definition: switch_apr.c:325

◆ switch_ivr_record_user_data_dup()

static void* switch_ivr_record_user_data_dup ( switch_core_session_t session,
void *  user_data 
)
static

Definition at line 1934 of file switch_ivr_async.c.

References record_helper::recording_session, record_helper::transfer_complete, and record_helper::transfer_from_session.

Referenced by switch_ivr_transfer_recordings().

1935 {
1936  struct record_helper *rh = (struct record_helper *) user_data;
1937 
1938  if (!rh->transfer_complete && session == rh->transfer_from_session) {
1939  /* Transfer failed and now we are called to put the original session back */
1941  rh->transfer_from_session = NULL;
1942  } else {
1944  rh->recording_session = session;
1945  rh->transfer_complete = 0;
1946  }
1947 
1948  return rh;
1949 }
switch_core_session_t * recording_session
uint8_t transfer_complete
switch_core_session_t * transfer_from_session

◆ switch_lcm()

static uint32_t switch_lcm ( uint32_t  x,
uint32_t  y 
)
static

Definition at line 2276 of file switch_ivr_async.c.

References switch_gcd().

Referenced by switch_ivr_eavesdrop_session().

2277 {
2278  uint32_t gcd = switch_gcd(x, y);
2279 
2280  if (gcd) return (x * y) / gcd;
2281 
2282  return 0;
2283 }
static uint32_t switch_gcd(uint32_t x, uint32_t y)

◆ SWITCH_STANDARD_SCHED_FUNC() [1/3]

SWITCH_STANDARD_SCHED_FUNC ( sch_hangup_callback  )

Definition at line 5510 of file switch_ivr_async.c.

References hangup_helper::bleg, hangup_helper::cause, if(), switch_assert, switch_channel_hangup, SWITCH_CHANNEL_SESSION_LOG, switch_core_session_get_channel(), switch_core_session_get_partner, switch_core_session_locate, switch_core_session_rwunlock(), switch_log_printf(), SWITCH_LOG_WARNING, SWITCH_STATUS_SUCCESS, and hangup_helper::uuid_str.

5511 {
5512  struct hangup_helper *helper;
5513  switch_core_session_t *session, *other_session;
5514 
5515  switch_assert(task);
5516 
5517  helper = (struct hangup_helper *) task->cmd_arg;
5518 
5519  if ((session = switch_core_session_locate(helper->uuid_str))) {
5521 
5522  if (helper->bleg) {
5523  if (SWITCH_STATUS_SUCCESS == switch_core_session_get_partner(session, &other_session)) {
5524  switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
5525  switch_channel_hangup(other_channel, helper->cause);
5526  switch_core_session_rwunlock(other_session);
5527  } else {
5528  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "No channel to hangup\n");
5529  }
5530  } else {
5531  switch_channel_hangup(channel, helper->cause);
5532  }
5533 
5535  }
5536 }
#define switch_channel_hangup(channel, hangup_cause)
Hangup a channel flagging it&#39;s state machine to end.
#define SWITCH_CHANNEL_SESSION_LOG(x)
char uuid_str[SWITCH_UUID_FORMATTED_LENGTH+1]
switch_bool_t bleg
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
if((uint32_t)(unpack->cur - unpack->buf) > unpack->buflen)
switch_call_cause_t cause
#define switch_core_session_get_partner(_session, _partner)
Definition: switch_core.h:1028
void switch_core_session_rwunlock(_In_ switch_core_session_t *session)
Unlock a read or write lock on as given session.
#define switch_core_session_locate(uuid_str)
Locate a session based on it&#39;s uuid.
Definition: switch_core.h:932
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
#define switch_assert(expr)

◆ SWITCH_STANDARD_SCHED_FUNC() [2/3]

SWITCH_STANDARD_SCHED_FUNC ( sch_transfer_callback  )

Definition at line 5559 of file switch_ivr_async.c.

References transfer_helper::context, transfer_helper::dialplan, transfer_helper::extension, if(), switch_assert, switch_core_session_locate, switch_core_session_rwunlock(), switch_ivr_session_transfer(), and transfer_helper::uuid_str.

5560 {
5561  struct transfer_helper *helper;
5562  switch_core_session_t *session;
5563 
5564  switch_assert(task);
5565 
5566  helper = (struct transfer_helper *) task->cmd_arg;
5567 
5568  if ((session = switch_core_session_locate(helper->uuid_str))) {
5569  switch_ivr_session_transfer(session, helper->extension, helper->dialplan, helper->context);
5571  }
5572 
5573 }
switch_status_t switch_ivr_session_transfer(_In_ switch_core_session_t *session, const char *extension, const char *dialplan, const char *context)
Transfer an existing session to another location.
char uuid_str[SWITCH_UUID_FORMATTED_LENGTH+1]
if((uint32_t)(unpack->cur - unpack->buf) > unpack->buflen)
void switch_core_session_rwunlock(_In_ switch_core_session_t *session)
Unlock a read or write lock on as given session.
#define switch_core_session_locate(uuid_str)
Locate a session based on it&#39;s uuid.
Definition: switch_core.h:932
#define switch_assert(expr)

◆ SWITCH_STANDARD_SCHED_FUNC() [3/3]

SWITCH_STANDARD_SCHED_FUNC ( sch_broadcast_callback  )

Definition at line 5626 of file switch_ivr_async.c.

References broadcast_helper::flags, broadcast_helper::path, switch_assert, switch_ivr_broadcast(), and broadcast_helper::uuid_str.

5627 {
5628  struct broadcast_helper *helper;
5629  switch_assert(task);
5630 
5631  helper = (struct broadcast_helper *) task->cmd_arg;
5632  switch_ivr_broadcast(helper->uuid_str, helper->path, helper->flags);
5633 }
switch_media_flag_t flags
switch_status_t switch_ivr_broadcast(const char *uuid, const char *path, switch_media_flag_t flags)
Signal the session to broadcast audio.
char uuid_str[SWITCH_UUID_FORMATTED_LENGTH+1]
#define switch_assert(expr)

◆ teletone_dtmf_generate_handler()

static int teletone_dtmf_generate_handler ( teletone_generation_session_t ts,
teletone_tone_map_t map 
)
static

Definition at line 3898 of file switch_ivr_async.c.

References teletone_generation_session::buffer, switch_buffer_write(), teletone_mux_tones(), and teletone_generation_session::user_data.

Referenced by inband_dtmf_generate_callback().

3899 {
3900  switch_buffer_t *audio_buffer = ts->user_data;
3901  int wrote;
3902 
3903  if (!audio_buffer) {
3904  return -1;
3905  }
3906 
3907  wrote = teletone_mux_tones(ts, map);
3908  switch_buffer_write(audio_buffer, ts->buffer, wrote * 2);
3909 
3910  return 0;
3911 }
int teletone_mux_tones(teletone_generation_session_t *ts, teletone_tone_map_t *map)
Execute a single tone generation instruction.
switch_size_t switch_buffer_write(_In_ switch_buffer_t *buffer, _In_bytecount_(datalen) const void *data, _In_ switch_size_t datalen)
Write data into a switch_buffer_t up to the length of datalen.

◆ text_callback()

static switch_bool_t text_callback ( switch_media_bug_t bug,
void *  user_data,
switch_abc_type_t  type 
)
static

Definition at line 1811 of file switch_ivr_async.c.

References SWITCH_ABC_TYPE_READ_TEXT, switch_core_get_variable(), switch_core_media_bug_get_session(), switch_core_media_bug_get_text(), switch_core_session_queue_event(), switch_event_add_body(), switch_event_create, switch_event_dup(), switch_event_fire, SWITCH_EVENT_TEXT, SWITCH_STATUS_SUCCESS, SWITCH_TRUE, switch_true(), SWITCH_VA_NONE, and zstr.

Referenced by switch_ivr_capture_text().

1812 {
1813 
1814  switch (type) {
1816  {
1817  const char *text = switch_core_media_bug_get_text(bug);
1818 
1819 
1820  if (!zstr(text)) {
1821  switch_event_t *event = NULL;
1823  //switch_channel_t *channel = switch_core_session_get_channel(session);
1824 
1826  switch_event_add_body(event, text, SWITCH_VA_NONE);
1827 
1828  if (switch_true(switch_core_get_variable("fire_text_events"))) {
1829  switch_event_t *clone = NULL;
1830 
1831  switch_event_dup(&clone, event);
1832  switch_event_fire(&clone);
1833  }
1834 
1835  switch_core_session_queue_event(session, &event);
1836  }
1837  }
1838  }
1839  break;
1840  default:
1841  break;
1842  }
1843 
1844  return SWITCH_TRUE;
1845 }
#define switch_event_fire(event)
Fire an event filling in most of the arguements with obvious values.
Definition: switch_event.h:413
static switch_bool_t switch_true(const char *expr)
Evaluate the truthfullness of a string expression.
Definition: switch_utils.h:519
Representation of an event.
Definition: switch_event.h:80
switch_status_t switch_event_add_body(switch_event_t *event, const char *fmt,...) PRINTF_FUNCTION(2
Add a body to an event.
switch_core_session_t * switch_core_media_bug_get_session(_In_ switch_media_bug_t *bug)
Obtain the session from a media bug.
switch_status_t switch_event_dup(switch_event_t **event, switch_event_t *todup)
Duplicate an event.
#define zstr(x)
Definition: switch_utils.h:314
const char * switch_core_media_bug_get_text(switch_media_bug_t *bug)
char * switch_core_get_variable(_In_z_ const char *varname)
Retrieve a global variable from the core.
switch_status_t switch_core_session_queue_event(_In_ switch_core_session_t *session, _Inout_ switch_event_t **event)
Queue an event on a given session.
#define switch_event_create(event, id)
Create a new event assuming it will not be custom event and therefore hiding the unused parameters...
Definition: switch_event.h:384
#define SWITCH_VA_NONE

◆ tone_detect_callback()

static switch_bool_t tone_detect_callback ( switch_media_bug_t bug,
void *  user_data,
switch_abc_type_t  type 
)
static

Definition at line 4190 of file switch_ivr_async.c.

References switch_tone_detect_t::app, switch_tone_container_t::bug_running, switch_tone_detect_t::callback, switch_frame::data, switch_tone_detect_t::data, switch_tone_detect_t::default_expires, switch_tone_detect_t::default_sleep, switch_tone_detect_t::expires, switch_tone_detect_t::hits, switch_tone_container_t::index, switch_tone_detect_t::key, switch_tone_container_t::list, switch_tone_detect_t::mt, switch_tone_detect_t::once, switch_frame::samples, switch_tone_container_t::session, switch_tone_detect_t::sleep, SWITCH_ABC_TYPE_CLOSE, SWITCH_ABC_TYPE_INIT, SWITCH_ABC_TYPE_READ_REPLACE, SWITCH_ABC_TYPE_WRITE, SWITCH_ABC_TYPE_WRITE_REPLACE, switch_channel_execute_on(), SWITCH_CHANNEL_EXECUTE_ON_TONE_DETECT_VARIABLE, SWITCH_CHANNEL_SESSION_LOG, switch_core_media_bug_get_read_replace_frame(), switch_core_media_bug_get_session(), switch_core_media_bug_get_write_replace_frame(), switch_core_session_execute_application_async(), switch_core_session_get_channel(), switch_core_session_queue_event(), switch_event_add_header_string(), switch_event_create, SWITCH_EVENT_DETECTED_TONE, switch_event_dup(), switch_event_fire, SWITCH_FALSE, SWITCH_LOG_DEBUG, SWITCH_LOG_ERROR, switch_log_printf(), SWITCH_STACK_BOTTOM, SWITCH_STATUS_SUCCESS, SWITCH_TRUE, teletone_multi_tone_detect(), tone_detect_set_total_time(), switch_tone_detect_t::total_hits, and switch_tone_detect_t::up.

Referenced by switch_ivr_tone_detect_session().

4191 {
4192  switch_tone_container_t *cont = (switch_tone_container_t *) user_data;
4193  switch_frame_t *frame = NULL;
4194  int i = 0;
4195  switch_bool_t rval = SWITCH_TRUE;
4196 
4197  switch (type) {
4198  case SWITCH_ABC_TYPE_INIT:
4199  if (cont) {
4200  cont->bug_running = 1;
4201  }
4202  break;
4203  case SWITCH_ABC_TYPE_CLOSE:
4204  break;
4207  {
4208 
4209  if (type == SWITCH_ABC_TYPE_READ_REPLACE) {
4211  } else {
4213  }
4214 
4215  for (i = 0; i < cont->index; i++) {
4216  int skip = 0;
4217 
4218  if (cont->list[i].sleep) {
4219  cont->list[i].sleep--;
4220  if (cont->list[i].sleep) {
4221  skip = 1;
4222  }
4223  }
4224 
4225  if (cont->list[i].expires) {
4226  cont->list[i].expires--;
4227  if (!cont->list[i].expires) {
4228  cont->list[i].hits = 0;
4229  cont->list[i].sleep = 0;
4230  cont->list[i].expires = 0;
4231  }
4232  }
4233 
4234  if (!cont->list[i].up)
4235  skip = 1;
4236 
4237  if (skip)
4238  continue;
4239 
4240  if (teletone_multi_tone_detect(&cont->list[i].mt, frame->data, frame->samples)) {
4241  switch_event_t *event;
4242  cont->list[i].hits++;
4243 
4245  cont->list[i].key, cont->list[i].hits, cont->list[i].total_hits);
4246  cont->list[i].sleep = cont->list[i].default_sleep;
4247  cont->list[i].expires = cont->list[i].default_expires;
4248 
4249  if (cont->list[i].hits >= cont->list[i].total_hits) {
4251  cont->list[i].key);
4252  tone_detect_set_total_time(cont, i);
4253  cont->list[i].up = 0;
4254 
4255  if (cont->list[i].callback) {
4256  if ((rval = cont->list[i].callback(cont->session, cont->list[i].app, cont->list[i].data)) == SWITCH_TRUE) {
4258  cont->list[i].key);
4259  cont->list[i].up = 1;
4260  cont->list[i].hits = 0;
4261  cont->list[i].sleep = 0;
4262  cont->list[i].expires = 0;
4263  }
4264  } else {
4266  if (cont->list[i].app) {
4268  }
4269  }
4270 
4271  if (cont->list[i].once) {
4272  rval = SWITCH_FALSE;
4273  }
4274 
4276  switch_event_t *dup;
4277  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Detected-Tone", cont->list[i].key);
4278 
4279  if (switch_event_dup(&dup, event) == SWITCH_STATUS_SUCCESS) {
4280  switch_event_fire(&dup);
4281  }
4282 
4285  "Event queue failed!\n");
4286  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "delivery-failure", "true");
4287  switch_event_fire(&event);
4288  }
4289  }
4290  }
4291  }
4292  }
4293  }
4294  break;
4295  case SWITCH_ABC_TYPE_WRITE:
4296  default:
4297  break;
4298  }
4299 
4300  if (rval == SWITCH_FALSE) {
4301  cont->bug_running = 0;
4302  }
4303 
4304  return rval;
4305 }
#define switch_event_fire(event)
Fire an event filling in most of the arguements with obvious values.
Definition: switch_event.h:413
switch_status_t switch_channel_execute_on(switch_channel_t *channel, const char *variable_prefix)
teletone_multi_tone_t mt
#define SWITCH_CHANNEL_SESSION_LOG(x)
switch_bool_t
Definition: switch_types.h:437
Representation of an event.
Definition: switch_event.h:80
switch_core_session_t * switch_core_media_bug_get_session(_In_ switch_media_bug_t *bug)
Obtain the session from a media bug.
static void tone_detect_set_total_time(switch_tone_container_t *cont, int index)
switch_status_t switch_event_dup(switch_event_t **event, switch_event_t *todup)
Duplicate an event.
switch_status_t switch_core_session_execute_application_async(switch_core_session_t *session, const char *app, const char *arg)
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
switch_frame_t * switch_core_media_bug_get_read_replace_frame(_In_ switch_media_bug_t *bug)
Obtain a replace frame from a media bug.
switch_core_session_t * session
switch_frame_t * switch_core_media_bug_get_write_replace_frame(_In_ switch_media_bug_t *bug)
Obtain a replace frame from a media bug.
switch_status_t switch_event_add_header_string(switch_event_t *event, switch_stack_t stack, const char *header_name, const char *data)
Add a string header to an event.
An abstraction of a data frame.
Definition: switch_frame.h:54
switch_status_t switch_core_session_queue_event(_In_ switch_core_session_t *session, _Inout_ switch_event_t **event)
Queue an event on a given session.
int teletone_multi_tone_detect(teletone_multi_tone_t *mt, int16_t sample_buffer[], int samples)
Check a sample buffer for the presence of the mulit-frequency tone described by mt.
#define switch_event_create(event, id)
Create a new event assuming it will not be custom event and therefore hiding the unused parameters...
Definition: switch_event.h:384
uint32_t samples
Definition: switch_frame.h:72
#define SWITCH_CHANNEL_EXECUTE_ON_TONE_DETECT_VARIABLE
Definition: switch_types.h:154
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
switch_tone_detect_callback_t callback
switch_tone_detect_t list[MAX_TONES+1]

◆ tone_detect_set_total_time()

static void tone_detect_set_total_time ( switch_tone_container_t cont,
int  index 
)
static

Definition at line 4153 of file switch_ivr_async.c.

References switch_tone_detect_t::key, switch_tone_container_t::list, switch_tone_container_t::session, switch_tone_detect_t::start_time, switch_channel_set_variable_name_printf(), switch_core_session_get_channel(), switch_micro_time_now(), switch_mprintf(), and switch_safe_free.

Referenced by tone_detect_callback(), and tone_on_dtmf().

4154 {
4155  char *total_time = switch_mprintf("%d", (int)(switch_micro_time_now() - cont->list[index].start_time) / 1000);
4156 
4157  switch_channel_set_variable_name_printf(switch_core_session_get_channel(cont->session), total_time, "tone_detect_%s_total_time",
4158  cont->list[index].key);
4159  switch_safe_free(total_time);
4160 }
switch_time_t switch_micro_time_now(void)
Get the current epoch time in microseconds.
Definition: switch_time.c:311
switch_status_t switch_channel_set_variable_name_printf(switch_channel_t *channel, const char *val, const char *fmt,...)
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
switch_core_session_t * session
int index
Definition: switch_cJSON.h:160
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:885
SWITCH_BEGIN_EXTERN_C char * switch_mprintf(const char *zFormat,...)
switch_tone_detect_t list[MAX_TONES+1]

◆ tone_on_dtmf()

static switch_status_t tone_on_dtmf ( switch_core_session_t session,
const switch_dtmf_t dtmf,
switch_dtmf_direction_t  direction 
)
static

Definition at line 4162 of file switch_ivr_async.c.

References switch_tone_detect_t::app, switch_tone_detect_t::callback, switch_tone_detect_t::data, switch_tone_container_t::detect_fax, switch_dtmf_t::digit, switch_tone_container_t::list, switch_tone_container_t::session, switch_channel_api_on(), SWITCH_CHANNEL_API_ON_TONE_DETECT_VARIABLE, switch_channel_execute_on(), SWITCH_CHANNEL_EXECUTE_ON_TONE_DETECT_VARIABLE, switch_channel_get_private(), switch_core_session_execute_application_async(), switch_core_session_get_channel(), SWITCH_STATUS_SUCCESS, and tone_detect_set_total_time().

Referenced by switch_ivr_tone_detect_session().

4163 {
4165  switch_tone_container_t *cont = switch_channel_get_private(channel, "_tone_detect_");
4166  int i;
4167 
4168  if (!cont || !cont->detect_fax || dtmf->digit != 'f') {
4169  return SWITCH_STATUS_SUCCESS;
4170  }
4171 
4172  i = cont->detect_fax;
4173 
4174  tone_detect_set_total_time(cont, i);
4175  if (cont->list[i].callback) {
4176  cont->list[i].callback(cont->session, cont->list[i].app, cont->list[i].data);
4177  } else {
4180 
4181  if (cont->list[i].app) {
4183  }
4184  }
4185 
4186  return SWITCH_STATUS_SUCCESS;
4187 
4188 }
switch_status_t switch_channel_execute_on(switch_channel_t *channel, const char *variable_prefix)
static void tone_detect_set_total_time(switch_tone_container_t *cont, int index)
switch_status_t switch_core_session_execute_application_async(switch_core_session_t *session, const char *app, const char *arg)
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
switch_core_session_t * session
void * switch_channel_get_private(switch_channel_t *channel, const char *key)
Retrieve private from a given channel.
#define SWITCH_CHANNEL_EXECUTE_ON_TONE_DETECT_VARIABLE
Definition: switch_types.h:154
switch_tone_detect_callback_t callback
switch_status_t switch_channel_api_on(switch_channel_t *channel, const char *variable_prefix)
switch_tone_detect_t list[MAX_TONES+1]
#define SWITCH_CHANNEL_API_ON_TONE_DETECT_VARIABLE
Definition: switch_types.h:166

◆ video_eavesdrop_callback()

static switch_status_t video_eavesdrop_callback ( switch_core_session_t session,
switch_frame_t frame,
void *  user_data 
)
static

Definition at line 1983 of file switch_ivr_async.c.

References switch_frame::img, SMBF_SPY_VIDEO_STREAM, SMBF_SPY_VIDEO_STREAM_BLEG, switch_core_media_bug_push_spy_frame(), switch_core_media_bug_test_flag(), SWITCH_RW_READ, SWITCH_RW_WRITE, and SWITCH_STATUS_SUCCESS.

Referenced by eavesdrop_callback().

1984 {
1985  switch_media_bug_t *bug = (switch_media_bug_t *) user_data;
1986 
1987  if (frame->img) {
1990  }
1991 
1994  }
1995  }
1996 
1997  return SWITCH_STATUS_SUCCESS;
1998 }
switch_status_t switch_core_media_bug_push_spy_frame(switch_media_bug_t *bug, switch_frame_t *frame, switch_rw_t rw)
switch_image_t * img
Definition: switch_frame.h:88
uint32_t switch_core_media_bug_test_flag(_In_ switch_media_bug_t *bug, _In_ uint32_t flag)
Test for the existance of a flag on an media bug.

◆ video_write_overlay_callback()

static switch_bool_t video_write_overlay_callback ( switch_media_bug_t bug,
void *  user_data,
switch_abc_type_t  type 
)
static

Definition at line 5781 of file switch_ivr_async.c.

References oht_s::alpha, CF_VIDEO_DECODED_READ, vpx_image::d_h, vpx_image::d_w, switch_frame::img, oht_s::img, oht_s::pos, SWITCH_ABC_TYPE_CLOSE, SWITCH_ABC_TYPE_INIT, SWITCH_ABC_TYPE_WRITE_VIDEO_PING, switch_channel_test_flag(), switch_core_media_bug_get_session(), switch_core_media_bug_get_video_ping_frame(), switch_core_session_get_channel(), SWITCH_FIT_SIZE, switch_img_copy(), switch_img_find_position(), switch_img_fit(), switch_img_free(), switch_img_overlay(), and SWITCH_TRUE.

Referenced by switch_ivr_video_write_overlay_session().

5782 {
5783  overly_helper_t *oht = (overly_helper_t *) user_data;
5786 
5787  switch (type) {
5788  case SWITCH_ABC_TYPE_INIT:
5789  {
5790  }
5791  break;
5792  case SWITCH_ABC_TYPE_CLOSE:
5793  {
5794  switch_img_free(&oht->img);
5795  }
5796  break;
5800  int x = 0, y = 0;
5801  switch_image_t *oimg = NULL;
5802 
5803  if (frame->img && oht->img) {
5804  switch_img_copy(oht->img, &oimg);
5805  switch_img_fit(&oimg, frame->img->d_w, frame->img->d_h, SWITCH_FIT_SIZE);
5806  switch_img_find_position(oht->pos, frame->img->d_w, frame->img->d_h, oimg->d_w, oimg->d_h, &x, &y);
5807  switch_img_overlay(frame->img, oimg, x, y, oht->alpha);
5808  //switch_img_patch(frame->img, oimg, x, y);
5809  switch_img_free(&oimg);
5810  }
5811  }
5812  break;
5813  default:
5814  break;
5815  }
5816 
5817  return SWITCH_TRUE;
5818 }
switch_frame_t * switch_core_media_bug_get_video_ping_frame(switch_media_bug_t *bug)
Image Descriptor.
Definition: switch_image.h:88
void switch_img_free(switch_image_t **img)
Close an image descriptor.
uint8_t alpha
switch_core_session_t * switch_core_media_bug_get_session(_In_ switch_media_bug_t *bug)
Obtain the session from a media bug.
uint32_t switch_channel_test_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Test for presence of given flag on a given channel.
void switch_img_find_position(switch_img_position_t pos, int sw, int sh, int iw, int ih, int *xP, int *yP)
switch_image_t * img
unsigned int d_w
Definition: switch_image.h:99
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
void switch_img_copy(switch_image_t *img, switch_image_t **new_img)
Copy image to a new image.
switch_status_t switch_img_fit(switch_image_t **srcP, int width, int height, switch_img_fit_t fit)
switch_img_position_t pos
An abstraction of a data frame.
Definition: switch_frame.h:54
switch_image_t * img
Definition: switch_frame.h:88
void switch_img_overlay(switch_image_t *IMG, switch_image_t *img, int x, int y, uint8_t percent)
put a small img over a big IMG at position x,y, with alpha transparency
unsigned int d_h
Definition: switch_image.h:100

◆ write_displace_callback()

static switch_bool_t write_displace_callback ( switch_media_bug_t bug,
void *  user_data,
switch_abc_type_t  type 
)
static

Definition at line 796 of file switch_ivr_async.c.

References buf, switch_file_handle::channels, switch_frame::data, switch_frame::datalen, displace_helper_t::fh, displace_helper_t::file, displace_helper_t::loop, memset(), displace_helper_t::mux, switch_frame::samples, SWITCH_ABC_TYPE_CLOSE, SWITCH_ABC_TYPE_INIT, SWITCH_ABC_TYPE_READ_REPLACE, SWITCH_ABC_TYPE_WRITE, SWITCH_ABC_TYPE_WRITE_REPLACE, switch_channel_set_private(), switch_core_file_close(), switch_core_file_read(), switch_core_file_seek(), switch_core_media_bug_get_read_replace_frame(), switch_core_media_bug_get_session(), switch_core_media_bug_get_write_replace_frame(), switch_core_media_bug_set_read_replace_frame(), switch_core_media_bug_set_write_replace_frame(), switch_core_session_get_channel(), SWITCH_FALSE, switch_normalize_to_16bit, SWITCH_RECOMMENDED_BUFFER_SIZE, SWITCH_STATUS_SUCCESS, and SWITCH_TRUE.

Referenced by switch_ivr_displace_session().

797 {
798  displace_helper_t *dh = (displace_helper_t *) user_data;
799 
800  switch (type) {
802  break;
804  if (dh) {
806  switch_channel_t *channel;
807 
809 
810  if (session && (channel = switch_core_session_get_channel(session))) {
811  switch_channel_set_private(channel, dh->file, NULL);
812  }
813  }
814  break;
816  {
818  if (dh && !dh->mux) {
819  memset(rframe->data, 255, rframe->datalen);
820  }
822  }
823  break;
825  if (dh) {
826  switch_frame_t *rframe = NULL;
827  switch_size_t len;
828  switch_status_t st;
829 
831  len = rframe->samples;
832 
833  if (dh->mux) {
835  int16_t *fp = rframe->data;
836  uint32_t x;
837 
838  st = switch_core_file_read(&dh->fh, buf, &len);
839 
840  for (x = 0; x < (uint32_t) len * dh->fh.channels; x++) {
841  int32_t mixed = fp[x] + buf[x];
843  fp[x] = (int16_t) mixed;
844  }
845  } else {
846  st = switch_core_file_read(&dh->fh, rframe->data, &len);
847  if (len < rframe->samples) {
848  memset((char *)rframe->data + (len * 2 * dh->fh.channels), 0, (rframe->samples - len) * 2 * dh->fh.channels);
849  }
850  }
851 
852  rframe->datalen = rframe->samples * 2 * dh->fh.channels;
853 
854  if (st != SWITCH_STATUS_SUCCESS || len == 0) {
855  if (dh->loop) {
856  uint32_t pos = 0;
857  switch_core_file_seek(&dh->fh, &pos, 0, SEEK_SET);
858  } else {
860  switch_channel_t *channel;
861 
862  if (session && (channel = switch_core_session_get_channel(session))) {
863  switch_channel_set_private(channel, dh->file, NULL);
864  }
865  return SWITCH_FALSE;
866  }
867  }
868 
870  }
871  break;
873  default:
874  break;
875  }
876 
877  return SWITCH_TRUE;
878 }
switch_status_t switch_channel_set_private(switch_channel_t *channel, const char *key, const void *private_info)
Set private data on channel.
void switch_core_media_bug_set_write_replace_frame(_In_ switch_media_bug_t *bug, _In_ switch_frame_t *frame)
Set a return replace frame.
#define SWITCH_RECOMMENDED_BUFFER_SIZE
Definition: switch_types.h:590
switch_status_t switch_core_file_close(_In_ switch_file_handle_t *fh)
Close an open file handle.
switch_status_t switch_core_file_seek(_In_ switch_file_handle_t *fh, unsigned int *cur_pos, int64_t samples, int whence)
Seek a position in a file.
switch_core_session_t * switch_core_media_bug_get_session(_In_ switch_media_bug_t *bug)
Obtain the session from a media bug.
switch_status_t switch_core_file_read(_In_ switch_file_handle_t *fh, void *data, switch_size_t *len)
Read media from a file handle.
void switch_core_media_bug_set_read_replace_frame(_In_ switch_media_bug_t *bug, _In_ switch_frame_t *frame)
Set a return replace frame.
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
switch_frame_t * switch_core_media_bug_get_read_replace_frame(_In_ switch_media_bug_t *bug)
Obtain a replace frame from a media bug.
switch_byte_t switch_byte_t * buf
uint32_t datalen
Definition: switch_frame.h:68
switch_file_handle_t fh
switch_frame_t * switch_core_media_bug_get_write_replace_frame(_In_ switch_media_bug_t *bug)
Obtain a replace frame from a media bug.
An abstraction of a data frame.
Definition: switch_frame.h:54
uintptr_t switch_size_t
switch_status_t
Common return values.
uint32_t samples
Definition: switch_frame.h:72
#define switch_normalize_to_16bit(n)
Definition: switch_utils.h:292
memset(buf, 0, buflen)