FreeSWITCH API Documentation  1.7.0
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

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, 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 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 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 switch_bool_t record_callback (switch_media_bug_t *bug, void *user_data, switch_abc_type_t type)
 
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_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)
 
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...
 
switch_status_t switch_ivr_record_session (switch_core_session_t *session, 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 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)
 
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_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...
 
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

#define MAX_TONES   16

Definition at line 3499 of file switch_ivr_async.c.

Referenced by switch_ivr_tone_detect_session().

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

Typedef Documentation

typedef struct oht_s overly_helper_t

Definition at line 50 of file switch_ivr_async.c.

Enumeration Type Documentation

enum dm_match_t
Enumerator
DM_MATCH_NONE 
DM_MATCH_EXACT 
DM_MATCH_PARTIAL 
DM_MATCH_BOTH 
DM_MATCH_NEVER 

Definition at line 330 of file switch_ivr_async.c.

Function Documentation

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

Definition at line 3904 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(), and switch_ivr_broadcast().

Referenced by switch_ivr_broadcast_in_thread().

3905 {
3906  bch_t *bch = (bch_t *) obj;
3907 
3908  if (!bch->session) {
3909  return NULL;
3910  }
3911 
3915 
3916  return NULL;
3917 
3918 }
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
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 4072 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().

4073 {
4075  uint8_t enabled = (uint8_t)(intptr_t)switch_channel_get_private(channel, SWITCH_BLOCK_DTMF_KEY);
4076 
4077  if (!enabled || switch_channel_test_flag(channel, CF_INNER_BRIDGE)) {
4078  return SWITCH_STATUS_SUCCESS;
4079  }
4080 
4081  return SWITCH_STATUS_FALSE;
4082 }
#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.
static void display_exec_cb ( switch_media_bug_t bug,
void *  user_data 
)
static

Definition at line 1815 of file switch_ivr_async.c.

References exec_cb_data::caller, eavesdrop_pvt::eavesdropper, ep, 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().

1816 {
1817  struct exec_cb_data *data = (struct exec_cb_data *) user_data;
1819 
1820  if (ep && ep->eavesdropper && ep->eavesdropper != data->caller) {
1821  switch_core_session_message_t msg = { 0 };
1822 
1823  msg.from = __FILE__;
1825  msg.string_array_arg[0] = data->var;
1826  msg.string_array_arg[1] = data->val;
1827 
1829  }
1830 }
switch_core_session_message_types_t message_id
Definition: switch_core.h:181
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:209
switch_core_session_t * eavesdropper
A message object designed to allow unlike technologies to exchange data.
Definition: switch_core.h:177
#define switch_core_session_receive_message(_session, _message)
Definition: switch_core.h:1217
static const char * ep
Definition: switch_json.c:36
static switch_bool_t eavesdrop_callback ( switch_media_bug_t bug,
void *  user_data,
switch_abc_type_t  type 
)
static

Definition at line 1620 of file switch_ivr_async.c.

References eavesdrop_pvt::buffer, switch_frame::buflen, CF_VIDEO_DECODED_READ, switch_frame::channels, switch_frame::data, eavesdrop_pvt::data, switch_frame::datalen, eavesdrop_pvt::demux_frame, eavesdrop_pvt::eavesdropper, ED_MUX_READ, ED_MUX_WRITE, ep, 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_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_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_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().

1621 {
1622  struct eavesdrop_pvt *ep = (struct eavesdrop_pvt *) user_data;
1624  switch_frame_t frame = { 0 };
1627  int show_spy = 0;
1628 
1629  frame.data = data;
1631 
1633 
1634  if (show_spy) {
1635  if (!ep->set_decoded_read) {
1636  ep->set_decoded_read = 1;
1639  }
1640  } else {
1641  if (ep->set_decoded_read) {
1642  ep->set_decoded_read = 0;
1645  }
1646  }
1647 
1648  switch (type) {
1649  case SWITCH_ABC_TYPE_INIT:
1650 
1656  }
1657  break;
1658  case SWITCH_ABC_TYPE_CLOSE:
1659  if (ep->set_decoded_read) {
1661  }
1662 
1667  }
1668 
1670 
1671  break;
1672  case SWITCH_ABC_TYPE_WRITE:
1673  break;
1675  if (ep->buffer) {
1678  switch_buffer_zwrite(ep->buffer, frame.data, frame.datalen);
1680  }
1681  } else {
1682  return SWITCH_FALSE;
1683  }
1684  break;
1685  case SWITCH_ABC_TYPE_READ:
1686  break;
1687 
1689  {
1690 
1691  if (switch_test_flag(ep, ED_MUX_READ)) {
1693 
1694  if (switch_buffer_inuse(ep->r_buffer) >= rframe->datalen) {
1695  uint32_t bytes;
1696  int channels = rframe->channels ? rframe->channels : 1;
1697 
1699  bytes = (uint32_t) switch_buffer_read(ep->r_buffer, ep->data, rframe->datalen);
1700 
1701  rframe->datalen = switch_merge_sln(rframe->data, rframe->samples, (int16_t *) ep->data, bytes / 2, channels) * 2 * channels;
1702  rframe->samples = rframe->datalen / 2;
1703 
1704  ep->demux_frame.data = ep->data;
1705  ep->demux_frame.datalen = bytes;
1706  ep->demux_frame.samples = bytes / 2;
1707  ep->demux_frame.channels = rframe->channels;
1708 
1712  }
1713  }
1714 
1715  }
1716  break;
1717 
1719  {
1720  if (switch_test_flag(ep, ED_MUX_WRITE)) {
1722 
1723  if (switch_buffer_inuse(ep->w_buffer) >= rframe->datalen) {
1724  uint32_t bytes;
1725  int channels = rframe->channels ? rframe->channels : 1;
1726 
1728  bytes = (uint32_t) switch_buffer_read(ep->w_buffer, data, rframe->datalen);
1729 
1730  rframe->datalen = switch_merge_sln(rframe->data, rframe->samples, (int16_t *) data, bytes / 2, channels) * 2 * channels;
1731  rframe->samples = rframe->datalen / 2;
1732 
1735  }
1736  }
1737  }
1738  break;
1739 
1742  {
1743 
1744  if (!bug->video_ping_frame || !bug->video_ping_frame->img) {
1745  break;
1746  }
1747 
1751  ep->errs++;
1752 
1753  if (ep->errs > 10) {
1757  return SWITCH_FALSE;
1758  }
1759  } else {
1760  ep->errs = 0;
1761  }
1763  }
1764  }
1765  break;
1766  default:
1767  break;
1768  }
1769 
1770  return SWITCH_TRUE;
1771 }
#define switch_channel_hangup(channel, hangup_cause)
Hangup a channel flagging it'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)
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:557
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:271
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
_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:59
uint32_t datalen
Definition: switch_frame.h:57
void switch_buffer_lock(_In_ switch_buffer_t *buffer)
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:43
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_status_t switch_core_session_request_video_refresh(switch_core_session_t *session)
static const char * ep
Definition: switch_json.c:36
switch_image_t * img
Definition: switch_frame.h:77
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:61
uint32_t channels
Definition: switch_frame.h:65
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:624
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.
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.
static void exec_cb ( switch_media_bug_t bug,
void *  user_data 
)
static

Definition at line 1799 of file switch_ivr_async.c.

References exec_cb_data::caller, eavesdrop_pvt::eavesdropper, ep, 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().

1800 {
1801  struct exec_cb_data *data = (struct exec_cb_data *) user_data;
1803 
1804  if (ep && ep->eavesdropper && ep->eavesdropper != data->caller) {
1807 
1808  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s telling %s to exec %s:%s\n",
1810 
1812  }
1813 }
#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.
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:1103
_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.
static const char * ep
Definition: switch_json.c:36
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.
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 3288 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().

3289 {
3291  switch_media_bug_t *bug = switch_channel_get_private(channel, "dtmf_generate");
3293 
3294  if (bug) {
3296 
3297  if (pvt) {
3298  switch_mutex_lock(pvt->mutex);
3299 
3300  if (pvt->ready) {
3301  switch_dtmf_t *dt = NULL;
3302  switch_zmalloc(dt, sizeof(*dt));
3303  *dt = *dtmf;
3304  if (!switch_buffer_inuse(pvt->audio_buffer)) {
3305  pvt->skip = 10;
3306  }
3308  switch_event_t *event;
3309 
3311  switch_channel_event_set_data(channel, event);
3312  switch_event_add_header(event, SWITCH_STACK_BOTTOM, "DTMF-Digit", "%c", dtmf->digit);
3313  switch_event_add_header(event, SWITCH_STACK_BOTTOM, "DTMF-Duration", "%u", dtmf->duration);
3314  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "DTMF-Source", "APP");
3315  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "DTMF-Conversion", "native:inband");
3317  switch_core_session_queue_event(session, &event);
3318  } else {
3319  switch_event_fire(&event);
3320  }
3321  }
3322 
3323  dt = NULL;
3324  /*
3325  SWITCH_STATUS_FALSE indicates pretend there never was a DTMF
3326  since we will be generating it inband now.
3327  */
3328  status = SWITCH_STATUS_FALSE;
3329  } else {
3330  free(dt);
3331  }
3332  }
3333  switch_mutex_unlock(pvt->mutex);
3334  }
3335  }
3336 
3337  return status;
3338 }
#define switch_event_fire(event)
Fire an event filling in most of the arguements with obvious values.
Definition: switch_event.h:412
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:288
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:290
_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:285
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:383
switch_status_t switch_queue_trypush(switch_queue_t *queue, void *data)
Definition: switch_apr.c:1155
switch_size_t switch_buffer_inuse(_In_ switch_buffer_t *buffer)
Get the in use amount of a switch_buffer_t.
static switch_bool_t inband_dtmf_callback ( switch_media_bug_t bug,
void *  user_data,
switch_abc_type_t  type 
)
static

Definition at line 3182 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().

3183 {
3184  switch_inband_dtmf_t *pvt = (switch_inband_dtmf_t *) user_data;
3185  switch_frame_t *frame = NULL;
3187  teletone_hit_type_t hit;
3188 
3189  switch (type) {
3190  case SWITCH_ABC_TYPE_INIT:
3191  break;
3192  case SWITCH_ABC_TYPE_CLOSE:
3193  break;
3195  if ((frame = switch_core_media_bug_get_read_replace_frame(bug))) {
3196  if ((hit = teletone_dtmf_detect(&pvt->dtmf_detect, frame->data, frame->samples)) == TT_HIT_END) {
3197  switch_dtmf_t dtmf = {0};
3198 
3199  teletone_dtmf_get(&pvt->dtmf_detect, &dtmf.digit, &dtmf.duration);
3201  dtmf.digit, dtmf.duration);
3203  switch_channel_queue_dtmf(channel, &dtmf);
3204  }
3206  }
3207  break;
3208  case SWITCH_ABC_TYPE_WRITE:
3209  default:
3210  break;
3211  }
3212 
3213  return SWITCH_TRUE;
3214 }
#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.
teletone_hit_type_t
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:288
_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:43
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:61
switch_dtmf_source_t source
Definition: switch_types.h:290
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.
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 3341 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().

3342 {
3344  switch_frame_t *frame;
3346  switch_core_session_get_read_impl(pvt->session, &read_impl);
3347 
3348  switch (type) {
3349  case SWITCH_ABC_TYPE_INIT:
3350  {
3352  switch_buffer_create_dynamic(&pvt->audio_buffer, 512, 1024, 0);
3354  pvt->ts.rate = read_impl.actual_samples_per_second;
3355  pvt->ts.channels = 1;
3357  if (pvt->read) {
3358  switch_core_event_hook_add_recv_dtmf(pvt->session, generate_on_dtmf);
3359  } else {
3360  switch_core_event_hook_add_send_dtmf(pvt->session, generate_on_dtmf);
3361  }
3362  switch_mutex_lock(pvt->mutex);
3363  pvt->ready = 1;
3364  switch_mutex_unlock(pvt->mutex);
3365  }
3366  break;
3367  case SWITCH_ABC_TYPE_CLOSE:
3368  {
3369  switch_mutex_lock(pvt->mutex);
3370  pvt->ready = 0;
3371  switch_core_event_hook_remove_recv_dtmf(pvt->session, generate_on_dtmf);
3374  switch_mutex_unlock(pvt->mutex);
3375  }
3376  break;
3379  {
3380  switch_size_t bytes;
3381  void *pop;
3382 
3383  if (pvt->skip) {
3384  pvt->skip--;
3385  return SWITCH_TRUE;
3386  }
3387 
3388 
3389  switch_mutex_lock(pvt->mutex);
3390 
3391  if (!pvt->ready) {
3392  switch_mutex_unlock(pvt->mutex);
3393  return SWITCH_FALSE;
3394  }
3395 
3396  if (pvt->read) {
3398  } else {
3400  }
3401 
3402  if (!switch_buffer_inuse(pvt->audio_buffer)) {
3404  switch_dtmf_t *dtmf = (switch_dtmf_t *) pop;
3405 
3406 
3407  if (dtmf->source != SWITCH_DTMF_INBAND_AUDIO) {
3408  char buf[2] = "";
3409  int duration = dtmf->duration;
3410 
3411  buf[0] = dtmf->digit;
3412  if (duration > (int)switch_core_max_dtmf_duration(0)) {
3413  duration = switch_core_default_dtmf_duration(0);
3415  SWITCH_LOG_WARNING, "%s Truncating DTMF duration %d ms to %d ms\n",
3417  }
3418 
3419 
3420  pvt->ts.duration = duration;
3421  teletone_run(&pvt->ts, buf);
3422  }
3423  free(pop);
3424  }
3425  }
3426 
3427  if (switch_buffer_inuse(pvt->audio_buffer) && (bytes = switch_buffer_read(pvt->audio_buffer, frame->data, frame->datalen))) {
3428  if (bytes < frame->datalen) {
3429  switch_byte_t *dp = frame->data;
3430  memset(dp + bytes, 0, frame->datalen - bytes);
3431  }
3432  }
3433 
3434  if (pvt->read) {
3436  } else {
3438  }
3439 
3440  switch_mutex_unlock(pvt->mutex);
3441  }
3442  break;
3443  default:
3444  break;
3445  }
3446 
3447  return SWITCH_TRUE;
3448 }
#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:1140
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:288
uint8_t switch_byte_t
Definition: switch_types.h:246
uint32_t switch_core_max_dtmf_duration(uint32_t duration)
Definition: switch_core.c:1664
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:290
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:57
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:285
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:270
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:43
uintptr_t switch_size_t
uint32_t switch_core_default_dtmf_duration(uint32_t duration)
Definition: switch_core.c:1681
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:290
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:1109
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.
static switch_bool_t is_silence_frame ( switch_frame_t frame,
int  silence_threshold,
switch_codec_implementation_t codec_impl 
)
static

Definition at line 1067 of file switch_ivr_async.c.

References 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().

1068 {
1069  int16_t *fdata = (int16_t *) frame->data;
1070  uint32_t samples = frame->datalen / sizeof(*fdata);
1071  switch_bool_t is_silence = SWITCH_TRUE;
1072  uint32_t channel_num = 0;
1073 
1074  int divisor = 0;
1075  if (!(divisor = codec_impl->samples_per_second / 8000)) {
1076  divisor = 1;
1077  }
1078 
1079  /* is silence only if every channel is silent */
1080  for (channel_num = 0; channel_num < codec_impl->number_of_channels && is_silence; channel_num++) {
1081  uint32_t count = 0, j = channel_num;
1082  double energy = 0;
1083  for (count = 0; count < samples; count++) {
1084  energy += abs(fdata[j]);
1085  j += codec_impl->number_of_channels;
1086  }
1087  is_silence &= (uint32_t) ((energy / (samples / divisor)) < silence_threshold);
1088  }
1089 
1090  return is_silence;
1091 }
switch_bool_t
Definition: switch_types.h:405
uint32_t datalen
Definition: switch_frame.h:57
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 3942 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().

3943 {
3946  time_t now = switch_epoch_time_now(NULL);
3947  char digit[2] = "";
3948  int dval;
3949 
3950  if (!md || switch_channel_test_flag(channel, CF_INNER_BRIDGE)) {
3951  return SWITCH_STATUS_SUCCESS;
3952  }
3953 
3954  if (direction == SWITCH_DTMF_RECV && !md->sr[SWITCH_DTMF_RECV].up) {
3955  return SWITCH_STATUS_SUCCESS;
3956  }
3957 
3958  if (direction == SWITCH_DTMF_SEND && !md->sr[SWITCH_DTMF_SEND].up) {
3959  return SWITCH_STATUS_SUCCESS;
3960  }
3961 
3962  if (md->sr[direction].meta_on && now - md->sr[direction].last_digit > 5) {
3963  md->sr[direction].meta_on = SWITCH_FALSE;
3964  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s Meta digit timeout parsing %c\n", switch_channel_get_name(channel),
3965  dtmf->digit);
3966  return SWITCH_STATUS_SUCCESS;
3967  }
3968 
3969  md->sr[direction].last_digit = now;
3970 
3971  if (dtmf->digit == md->sr[direction].meta) {
3972  if (md->sr[direction].meta_on) {
3973  md->sr[direction].meta_on = SWITCH_FALSE;
3974  return SWITCH_STATUS_SUCCESS;
3975  } else {
3976  md->sr[direction].meta_on = SWITCH_TRUE;
3977  return SWITCH_STATUS_FALSE;
3978  }
3979  }
3980 
3981  if (md->sr[direction].meta_on) {
3982  if (is_dtmf(dtmf->digit)) {
3983  int ok = 0;
3984  *digit = dtmf->digit;
3985  dval = switch_dtmftoi(digit);
3986 
3987  if (direction == SWITCH_DTMF_RECV && (md->sr[direction].map[dval].bind_flags & SBF_DIAL_ALEG)) {
3988  ok = 1;
3989  } else if (direction == SWITCH_DTMF_SEND && (md->sr[direction].map[dval].bind_flags & SBF_DIAL_BLEG)) {
3990  ok = 1;
3991  }
3992 
3993  if (ok && md->sr[direction].map[dval].app) {
3994  uint32_t flags = md->sr[direction].map[dval].flags;
3995 
3996  if ((md->sr[direction].map[dval].bind_flags & SBF_EXEC_OPPOSITE)) {
3997  if (direction == SWITCH_DTMF_SEND) {
3998  flags |= SMF_ECHO_ALEG;
3999  } else {
4000  flags |= SMF_ECHO_BLEG;
4001  }
4002  } else if ((md->sr[direction].map[dval].bind_flags & SBF_EXEC_SAME)) {
4003  if (direction == SWITCH_DTMF_SEND) {
4004  flags |= SMF_ECHO_BLEG;
4005  } else {
4006  flags |= SMF_ECHO_ALEG;
4007  }
4008  } else if ((md->sr[direction].map[dval].bind_flags & SBF_EXEC_ALEG)) {
4009  flags |= SMF_ECHO_ALEG;
4010  } else if ((md->sr[direction].map[dval].bind_flags & SBF_EXEC_BLEG)) {
4011  flags |= SMF_ECHO_BLEG;
4012  } else {
4013  flags |= SMF_ECHO_ALEG;
4014  }
4015 
4016  if ((md->sr[direction].map[dval].bind_flags & SBF_EXEC_INLINE)) {
4017  flags |= SMF_EXEC_INLINE;
4018  }
4019 
4020  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Processing meta digit '%c' [%s]\n",
4021  switch_channel_get_name(channel), dtmf->digit, md->sr[direction].map[dval].app);
4022 
4023  if (switch_channel_test_flag(channel, CF_PROXY_MODE)) {
4024  switch_ivr_broadcast_in_thread(session, md->sr[direction].map[dval].app, flags | SMF_REBRIDGE);
4025  } else {
4026  switch_ivr_broadcast(switch_core_session_get_uuid(session), md->sr[direction].map[dval].app, flags);
4027  }
4028 
4029  if ((md->sr[direction].map[dval].bind_flags & SBF_ONCE)) {
4030  memset(&md->sr[direction].map[dval], 0, sizeof(md->sr[direction].map[dval]));
4031  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Unbinding meta digit '%c'\n",
4032  switch_channel_get_name(channel), dtmf->digit);
4033  }
4034 
4035  } else {
4036  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s Ignoring meta digit '%c' not mapped\n",
4037  switch_channel_get_name(channel), dtmf->digit);
4038 
4039  }
4040  }
4041  md->sr[direction].meta_on = SWITCH_FALSE;
4042  return SWITCH_STATUS_FALSE;
4043  }
4044 
4045  return SWITCH_STATUS_SUCCESS;
4046 }
#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:614
_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:321
static int switch_dtmftoi(char *s)
Definition: switch_utils.h:402
#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)
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 4189 of file switch_ivr_async.c.

References switch_dtmf_t::digit, play_and_detect_speech_state_t::done, switch_event::event_id, 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_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_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().

4190 {
4192  if (!state->done) {
4194  if (input_type == SWITCH_INPUT_TYPE_EVENT) {
4195  switch_event_t *event;
4196  event = (switch_event_t *)input;
4197  if (event->event_id == SWITCH_EVENT_DETECTED_SPEECH) {
4198  const char *speech_type = switch_event_get_header(event, "Speech-Type");
4199  if (!zstr(speech_type)) {
4200  if (!strcasecmp(speech_type, "detected-speech")) {
4201  const char *result;
4202  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "(%s) DETECTED SPEECH\n", switch_channel_get_name(channel));
4203  result = switch_event_get_body(event);
4204  if (!zstr(result)) {
4205  state->result = switch_core_session_strdup(session, result);
4206  } else {
4207  state->result = "";
4208  }
4210  return SWITCH_STATUS_BREAK;
4211  } else if (!strcasecmp(speech_type, "begin-speaking")) {
4212  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "(%s) START OF SPEECH\n", switch_channel_get_name(channel));
4213  return SWITCH_STATUS_BREAK;
4214  } else if (!strcasecmp("closed", speech_type)) {
4216  state->result = "";
4217  return SWITCH_STATUS_BREAK;
4218  }
4219  }
4220  }
4221  } else if (input_type == SWITCH_INPUT_TYPE_DTMF) {
4222  switch_dtmf_t *dtmf = (switch_dtmf_t *) input;
4223  const char *terminators = switch_channel_get_variable(channel, SWITCH_PLAYBACK_TERMINATORS_VARIABLE);
4224  if (terminators) {
4225  if (!strcasecmp(terminators, "any")) {
4226  terminators = "1234567890*#";
4227  } else if (!strcasecmp(terminators, "none")) {
4228  terminators = NULL;
4229  }
4230  }
4231  if (terminators && strchr(terminators, dtmf->digit)) {
4232  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "(%s) ACCEPT TERMINATOR %c\n", switch_channel_get_name(channel), dtmf->digit);
4234  state->result = switch_core_session_sprintf(session, "DIGIT: %c", dtmf->digit);
4235  state->done = PLAY_AND_DETECT_DONE;
4236  return SWITCH_STATUS_BREAK;
4237  } else {
4238  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);
4239  }
4240  }
4241  }
4242  return SWITCH_STATUS_SUCCESS;
4243 }
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
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)
Representation of an event.
Definition: switch_event.h:80
#define SWITCH_PLAYBACK_TERMINATOR_USED
Definition: switch_types.h:185
#define PLAY_AND_DETECT_DONE_RECOGNIZING
#define PLAY_AND_DETECT_DONE
#define zstr(x)
Definition: switch_utils.h:281
_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:838
#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:184
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's pool.
Definition: switch_core.h:717
char * switch_channel_get_name(switch_channel_t *channel)
Retrieve the name of a given channel.
static switch_bool_t preprocess_callback ( switch_media_bug_t bug,
void *  user_data,
switch_abc_type_t  type 
)
static

Definition at line 2748 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().

2749 {
2752  pp_cb_t *cb = (pp_cb_t *) user_data;
2754  switch_frame_t *frame = NULL;
2755 
2756  switch_core_session_get_read_impl(session, &read_impl);
2757 
2758  switch (type) {
2759  case SWITCH_ABC_TYPE_INIT:
2760  {
2763  }
2764  break;
2765  case SWITCH_ABC_TYPE_CLOSE:
2766  {
2767  if (cb->read_st) {
2768  speex_preprocess_state_destroy(cb->read_st);
2769  }
2770 
2771  if (cb->write_st) {
2772  speex_preprocess_state_destroy(cb->write_st);
2773  }
2774 
2775  if (cb->read_ec) {
2776  speex_echo_state_destroy(cb->read_ec);
2777  }
2778 
2779  if (cb->write_ec) {
2780  speex_echo_state_destroy(cb->write_ec);
2781  }
2782 
2783  switch_channel_set_private(channel, "_preprocess", NULL);
2784  }
2785  break;
2787  {
2788  if (cb->done)
2789  return SWITCH_FALSE;
2791 
2792  if (cb->read_st) {
2793 
2794  if (cb->read_ec) {
2795  speex_echo_cancellation(cb->read_ec, (int16_t *) frame->data, (int16_t *) cb->write_data, (int16_t *) cb->read_out);
2796  memcpy(frame->data, cb->read_out, frame->datalen);
2797  }
2798 
2799  speex_preprocess_run(cb->read_st, frame->data);
2800  }
2801 
2802  if (cb->write_ec) {
2803  memcpy(cb->read_data, frame->data, frame->datalen);
2804  }
2805  }
2806  break;
2808  {
2809  if (cb->done)
2810  return SWITCH_FALSE;
2812 
2813  if (cb->write_st) {
2814 
2815  if (cb->write_ec) {
2816  speex_echo_cancellation(cb->write_ec, (int16_t *) frame->data, (int16_t *) cb->read_data, (int16_t *) cb->write_out);
2817  memcpy(frame->data, cb->write_out, frame->datalen);
2818  }
2819 
2820  speex_preprocess_run(cb->write_st, frame->data);
2821  }
2822 
2823  if (cb->read_ec) {
2824  memcpy(cb->write_data, frame->data, frame->datalen);
2825  }
2826  }
2827  break;
2828  default:
2829  break;
2830  }
2831 
2832  return SWITCH_TRUE;
2833 }
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:57
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:270
switch_byte_t write_out[2048]
An abstraction of a data frame.
Definition: switch_frame.h:43
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
static switch_bool_t read_displace_callback ( switch_media_bug_t bug,
void *  user_data,
switch_abc_type_t  type 
)
static

Definition at line 815 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().

816 {
817  displace_helper_t *dh = (displace_helper_t *) user_data;
818 
819  switch (type) {
821  break;
823  if (dh) {
825  switch_channel_t *channel;
826 
828 
829  if (session && (channel = switch_core_session_get_channel(session))) {
830  switch_channel_set_private(channel, dh->file, NULL);
831  }
832  }
833  break;
835  {
837  if (dh && !dh->mux) {
838  memset(rframe->data, 255, rframe->datalen);
839  }
841  }
842  break;
844  if (dh) {
845  switch_frame_t *rframe = NULL;
846  switch_size_t len;
847  switch_status_t st;
849  len = rframe->samples;
850 
851  if (dh->mux) {
853  int16_t *fp = rframe->data;
854  uint32_t x;
855 
856  st = switch_core_file_read(&dh->fh, buf, &len);
857 
858  for (x = 0; x < (uint32_t) len * dh->fh.channels; x++) {
859  int32_t mixed = fp[x] + buf[x];
861  fp[x] = (int16_t) mixed;
862  }
863 
864  } else {
865  st = switch_core_file_read(&dh->fh, rframe->data, &len);
866  rframe->samples = (uint32_t) len;
867  }
868 
869  rframe->datalen = rframe->samples * 2 * dh->fh.channels;
870 
871 
872  if (st != SWITCH_STATUS_SUCCESS || len == 0) {
873  if (dh->loop) {
874  uint32_t pos = 0;
875  switch_core_file_seek(&dh->fh, &pos, 0, SEEK_SET);
876  } else {
878  switch_channel_t *channel;
879 
880  if (session && (channel = switch_core_session_get_channel(session))) {
881  switch_channel_set_private(channel, dh->file, NULL);
882  }
883  return SWITCH_FALSE;
884  }
885  }
886 
888  }
889  break;
891  default:
892  break;
893  }
894 
895  return SWITCH_TRUE;
896 }
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:557
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:57
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:43
uintptr_t switch_size_t
switch_status_t
Common return values.
uint32_t samples
Definition: switch_frame.h:61
#define switch_normalize_to_16bit(n)
Definition: switch_utils.h:261
memset(buf, 0, buflen)
static switch_bool_t record_callback ( switch_media_bug_t bug,
void *  user_data,
switch_abc_type_t  type 
)
static

Definition at line 1180 of file switch_ivr_async.c.

References record_helper::buffer_mutex, switch_frame::buflen, switch_frame::channels, record_helper::completion_cause, switch_frame::data, switch_stream_handle::data, switch_frame::datalen, record_helper::fh, record_helper::file, record_helper::final_timeout_ms, record_helper::hangup_on_error, 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, switch_codec_implementation::microseconds_per_packet, record_helper::min_sec, record_helper::native, record_helper::out_fh, pool, record_helper::read_impl, 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, 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_api_execute(), switch_buffer_destroy(), switch_buffer_write(), SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER, switch_channel_down_nosig, switch_channel_event_set_data(), switch_channel_execute_on(), switch_channel_expand_variables, switch_channel_get_variable, switch_channel_hangup, SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_private(), switch_channel_set_variable, switch_core_file_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_test_flag(), switch_core_session_get_channel(), switch_core_session_get_pool(), switch_core_session_get_read_impl(), switch_core_session_reset(), switch_core_session_strdup, switch_event_add_header_string(), switch_event_create, switch_event_fire, SWITCH_EVENT_RECORD_START, SWITCH_FALSE, switch_file_remove(), SWITCH_LOG_DEBUG, SWITCH_LOG_ERROR, switch_log_printf(), switch_micro_time_now(), switch_mutex_init(), switch_mutex_lock(), SWITCH_MUTEX_NESTED, switch_mutex_unlock(), SWITCH_RECOMMENDED_BUFFER_SIZE, SWITCH_RECORD_POST_PROCESS_EXEC_API_VARIABLE, SWITCH_RECORD_POST_PROCESS_EXEC_APP_VARIABLE, switch_safe_free, SWITCH_STACK_BOTTOM, SWITCH_STANDARD_STREAM, SWITCH_STATUS_SUCCESS, switch_thread_create(), switch_thread_join(), SWITCH_THREAD_STACKSIZE, switch_threadattr_create(), switch_threadattr_stacksize_set(), switch_time_now(), SWITCH_TRUE, switch_true(), switch_yield, record_helper::thread, record_helper::thread_buffer, record_helper::thread_ready, switch_media_bug::video_ping_frame, record_helper::vwrites, record_helper::wready, record_helper::writes, and zstr.

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

1181 {
1184  struct record_helper *rh = (struct record_helper *) user_data;
1185  switch_event_t *event;
1186  switch_frame_t *nframe;
1187  switch_size_t len = 0;
1188  int mask = switch_core_media_bug_test_flag(bug, SMBF_MASK);
1189  unsigned char null_data[SWITCH_RECOMMENDED_BUFFER_SIZE] = {0};
1190 
1191  switch (type) {
1192  case SWITCH_ABC_TYPE_INIT:
1193  {
1194  const char *var = switch_channel_get_variable(channel, "RECORD_USE_THREAD");
1195 
1196  if (!rh->native && rh->fh && (zstr(var) || switch_true(var))) {
1197  switch_threadattr_t *thd_attr = NULL;
1199  int sanity = 200;
1200 
1201 
1204  switch_threadattr_create(&thd_attr, pool);
1206  switch_thread_create(&rh->thread, thd_attr, recording_thread, bug, pool);
1207 
1208  while(--sanity > 0 && !rh->thread_ready) {
1209  switch_yield(10000);
1210  }
1211  }
1212 
1214  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Record-File-Path", rh->file);
1215  switch_channel_event_set_data(channel, event);
1216  switch_event_fire(&event);
1217  }
1218 
1222  rh->completion_cause = NULL;
1223 
1225  }
1226  break;
1228  {
1230  switch_time_t diff;
1231 
1232  rh->rready = 1;
1233 
1235  len = nframe->datalen;
1236 
1237  if (!rh->wready) {
1238  unsigned char fill_data[SWITCH_RECOMMENDED_BUFFER_SIZE] = {0};
1239  switch_size_t fill_len = len;
1240 
1241  switch_core_gen_encoded_silence(fill_data, &rh->read_impl, len);
1242  switch_core_file_write(&rh->out_fh, fill_data, &fill_len);
1243  }
1244 
1245 
1246  if (rh->last_read_time && rh->last_read_time < now) {
1247  diff = (now - rh->last_read_time) / rh->read_impl.microseconds_per_packet;
1248 
1249  if (diff > 3) {
1250  unsigned char fill_data[SWITCH_RECOMMENDED_BUFFER_SIZE] = {0};
1251  switch_core_gen_encoded_silence(fill_data, &rh->read_impl, len);
1252 
1253  while(diff > 1) {
1254  switch_size_t fill_len = len;
1255  switch_core_file_write(&rh->in_fh, fill_data, &fill_len);
1256  diff--;
1257  }
1258  }
1259  }
1260 
1261  switch_core_file_write(&rh->in_fh, mask ? null_data : nframe->data, &len);
1262  rh->last_read_time = now;
1263  rh->writes++;
1264  }
1265  break;
1267  {
1269  switch_time_t diff;
1270  rh->wready = 1;
1271 
1273  len = nframe->datalen;
1274 
1275  if (!rh->rready) {
1276  unsigned char fill_data[SWITCH_RECOMMENDED_BUFFER_SIZE] = {0};
1277  switch_size_t fill_len = len;
1278  switch_core_gen_encoded_silence(fill_data, &rh->read_impl, len);
1279  switch_core_file_write(&rh->in_fh, fill_data, &fill_len);
1280  }
1281 
1282 
1283 
1284 
1285  if (rh->last_write_time && rh->last_write_time < now) {
1286  diff = (now - rh->last_write_time) / rh->read_impl.microseconds_per_packet;
1287 
1288  if (diff > 3) {
1289  unsigned char fill_data[SWITCH_RECOMMENDED_BUFFER_SIZE] = {0};
1290  switch_core_gen_encoded_silence(fill_data, &rh->read_impl, len);
1291 
1292  while(diff > 1) {
1293  switch_size_t fill_len = len;
1294  switch_core_file_write(&rh->out_fh, fill_data, &fill_len);
1295  diff--;
1296  }
1297  }
1298  }
1299 
1300  switch_core_file_write(&rh->out_fh, mask ? null_data : nframe->data, &len);
1301  rh->last_write_time = now;
1302  rh->writes++;
1303  }
1304  break;
1305  case SWITCH_ABC_TYPE_CLOSE:
1306  {
1307  const char *var;
1308 
1310  switch_core_session_get_read_impl(session, &read_impl);
1311 
1312  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Stop recording file %s\n", rh->file);
1313  switch_channel_set_private(channel, rh->file, NULL);
1314 
1315  if (rh->native) {
1318  } else if (rh->fh) {
1319  switch_size_t len;
1320  uint8_t data[SWITCH_RECOMMENDED_BUFFER_SIZE];
1321  switch_frame_t frame = { 0 };
1322 
1323  if (rh->thread_ready) {
1324  switch_status_t st;
1325 
1326  rh->thread_ready = 0;
1327  switch_thread_join(&st, rh->thread);
1328  }
1329 
1330  if (rh->thread_buffer) {
1332  }
1333 
1334 
1335  frame.data = data;
1337 
1339  len = (switch_size_t) frame.datalen / 2;
1340 
1341  if (len && switch_core_file_write(rh->fh, mask ? null_data : data, &len) != SWITCH_STATUS_SUCCESS) {
1342  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error writing %s\n", rh->file);
1343  /* File write failed */
1344  set_completion_cause(rh, "uri-failure");
1345  if (rh->hangup_on_error) {
1348  }
1349  send_record_stop_event(channel, &read_impl, rh);
1350  return SWITCH_FALSE;
1351  }
1352  }
1353 
1354 
1355  //if (switch_core_file_has_video(rh->fh, SWITCH_TRUE)) {
1356  //switch_core_media_set_video_file(session, NULL, SWITCH_RW_READ);
1357  //switch_channel_clear_flag_recursive(session->channel, CF_VIDEO_DECODED_READ);
1358  //}
1359 
1361 
1362  if (!rh->writes && !rh->vwrites) {
1363  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Discarding empty file %s\n", rh->file);
1364  switch_channel_set_variable(channel, "RECORD_DISCARDED", "true");
1366  set_completion_cause(rh, "empty-file");
1367  } else if (rh->fh->samples_out < rh->fh->samplerate * rh->min_sec) {
1368  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Discarding short file %s\n", rh->file);
1369  switch_channel_set_variable(channel, "RECORD_DISCARDED", "true");
1371  set_completion_cause(rh, "input-too-short");
1372  } else {
1373 
1374  if (switch_channel_down_nosig(channel)) {
1375  /* We got hung up */
1376  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Channel is hung up\n");
1377  if (rh->speech_detected) {
1378  /* Treat it as equivalent with final-silence */
1379  set_completion_cause(rh, "success-silence");
1380  } else {
1381  /* Treat it as equivalent with inital-silence timeout */
1382  set_completion_cause(rh, "no-input-timeout");
1383  }
1384  } else {
1385  /* Set the completion_cause to maxtime reached, unless it's already set */
1386  set_completion_cause(rh, "success-maxtime");
1387  }
1388  }
1389  }
1390 
1391  send_record_stop_event(channel, &read_impl, rh);
1392 
1394 
1396  char *cmd = switch_core_session_strdup(session, var);
1397  char *data, *expanded = NULL;
1398  switch_stream_handle_t stream = { 0 };
1399 
1400  SWITCH_STANDARD_STREAM(stream);
1401 
1402  if ((data = strchr(cmd, ':'))) {
1403  *data++ = '\0';
1404  expanded = switch_channel_expand_variables(channel, data);
1405  }
1406 
1407  switch_api_execute(cmd, expanded, session, &stream);
1408 
1409  if (expanded && expanded != data) {
1410  free(expanded);
1411  }
1412 
1413  switch_safe_free(stream.data);
1414 
1415  }
1416 
1417 
1418  }
1419 
1420  break;
1422 
1423  if (rh->fh) {
1424  switch_size_t len;
1425  uint8_t data[SWITCH_RECOMMENDED_BUFFER_SIZE];
1426  switch_frame_t frame = { 0 };
1427  switch_status_t status;
1428  int i = 0;
1429 
1430  frame.data = data;
1432 
1433  for (;;) {
1434  status = switch_core_media_bug_read(bug, &frame, i++ == 0 ? SWITCH_FALSE : SWITCH_TRUE);
1435 
1436  if (status != SWITCH_STATUS_SUCCESS || !frame.datalen) {
1437  break;
1438  } else {
1439  len = (switch_size_t) frame.datalen / 2 / frame.channels;
1440 
1441  if (rh->thread_buffer) {
1443  switch_buffer_write(rh->thread_buffer, mask ? null_data : data, frame.datalen);
1445  } else if (switch_core_file_write(rh->fh, mask ? null_data : data, &len) != SWITCH_STATUS_SUCCESS) {
1446  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error writing %s\n", rh->file);
1447  /* File write failed */
1448  set_completion_cause(rh, "uri-failure");
1449  if (rh->hangup_on_error) {
1452  }
1453  return SWITCH_FALSE;
1454  }
1455 
1456  rh->writes++;
1457 
1458  /* check for silence timeout */
1459  if (rh->silence_threshold) {
1460  switch_codec_implementation_t read_impl = { 0 };
1461  switch_core_session_get_read_impl(session, &read_impl);
1462  if (is_silence_frame(&frame, rh->silence_threshold, &read_impl)) {
1463  if (!rh->silence_time) {
1464  /* start of silence */
1465  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Start of silence detected\n");
1467  } else {
1468  /* continuing silence */
1469  int duration_ms = (int)((switch_micro_time_now() - rh->silence_time) / 1000);
1470  if (rh->silence_timeout_ms > 0 && duration_ms >= rh->silence_timeout_ms) {
1471  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);
1473  if (rh->speech_detected) {
1474  /* Reached final silence timeout */
1475  set_completion_cause(rh, "success-silence");
1476  } else {
1477  /* Reached initial silence timeout */
1478  set_completion_cause(rh, "no-input-timeout");
1479  /* Discard the silent file? */
1480  }
1481  }
1482  }
1483  } else { /* not silence */
1484  if (rh->silence_time) {
1485  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Start of speech detected\n");
1487  /* end of silence */
1488  rh->silence_time = 0;
1489  /* switch from initial timeout to final timeout */
1491  }
1492  }
1493  } else {
1494  /* no silence detection */
1495  if (!rh->speech_detected) {
1496  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "No silence detection configured; assuming start of speech\n");
1498  }
1499  }
1500  }
1501  }
1502  }
1503  break;
1506  if (rh->fh) {
1507  if (!bug->video_ping_frame) break;
1508 
1510  rh->hangup_on_error) {
1511  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error writing video to %s\n", rh->file);
1514  return SWITCH_FALSE;
1515  }
1516  rh->vwrites++;
1517  }
1518  break;
1519 
1520  case SWITCH_ABC_TYPE_WRITE:
1521  default:
1522  break;
1523  }
1524 
1525  return SWITCH_TRUE;
1526 }
switch_time_t switch_micro_time_now(void)
Get the current epoch time in microseconds.
Definition: switch_time.c:310
#define switch_event_fire(event)
Fire an event filling in most of the arguements with obvious values.
Definition: switch_event.h:412
#define switch_channel_hangup(channel, hangup_cause)
Hangup a channel flagging it's state machine to end.
switch_status_t switch_channel_execute_on(switch_channel_t *channel, const char *variable_prefix)
#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_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)
#define SWITCH_RECORD_POST_PROCESS_EXEC_APP_VARIABLE
Definition: switch_types.h:145
#define SWITCH_RECOMMENDED_BUFFER_SIZE
Definition: switch_types.h:557
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.
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.
switch_status_t switch_threadattr_stacksize_set(switch_threadattr_t *attr, switch_size_t stacksize)
Definition: switch_apr.c:660
switch_memory_pool_t * pool
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_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.
static int switch_true(const char *expr)
Evaluate the truthfullness of a string expression.
Definition: switch_utils.h:450
#define zstr(x)
Definition: switch_utils.h:281
switch_status_t switch_file_remove(const char *path, switch_memory_pool_t *pool)
Definition: switch_apr.c:429
switch_buffer_t * thread_buffer
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:290
switch_status_t switch_thread_join(switch_status_t *retval, switch_thread_t *thd)
Definition: switch_apr.c:1255
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:59
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:908
uint32_t datalen
Definition: switch_frame.h:57
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:285
const char * completion_cause
#define switch_channel_get_variable(_c, _v)
#define SWITCH_THREAD_STACKSIZE
Definition: switch_types.h:551
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
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:789
switch_status_t switch_mutex_init(switch_mutex_t **lock, unsigned int flags, switch_memory_pool_t *pool)
Definition: switch_apr.c:270
#define switch_channel_down_nosig(_channel)
An abstraction of a data frame.
Definition: switch_frame.h:43
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.
#define SWITCH_STANDARD_STREAM(s)
#define switch_channel_expand_variables(_channel, _in)
switch_bool_t speech_detected
switch_image_t * img
Definition: switch_frame.h:77
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.
#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:383
static void send_record_stop_event(switch_channel_t *channel, switch_codec_implementation_t *read_impl, struct record_helper *rh)
uint32_t channels
Definition: switch_frame.h:65
switch_thread_t * thread
switch_bool_t hangup_on_error
struct apr_pool_t switch_memory_pool_t
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:642
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:675
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
#define switch_core_session_strdup(_session, _todup)
Copy a string using memory allocation from a session's pool.
Definition: switch_core.h:717
switch_file_handle_t * fh
#define SWITCH_RECORD_POST_PROCESS_EXEC_API_VARIABLE
Definition: switch_types.h:146
#define switch_channel_set_variable(_channel, _var, _val)
switch_time_t switch_time_now(void)
Definition: switch_apr.c:302
void switch_buffer_destroy(switch_buffer_t **buffer)
Destroy the buffer.
switch_memory_pool_t * switch_core_session_get_pool(_In_ switch_core_session_t *session)
Retrieve the memory pool from a session.
static void* SWITCH_THREAD_FUNC recording_thread ( switch_thread_t thread,
void *  obj 
)
static

Definition at line 1119 of file switch_ivr_async.c.

References record_helper::buffer_mutex, switch_codec_implementation::decoded_bytes_per_packet, record_helper::fh, record_helper::file, record_helper::hangup_on_error, switch_codec_implementation::number_of_channels, record_helper::read_impl, 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_channel_up_nosig, 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_alloc, 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_TRUE, switch_yield, record_helper::thread_buffer, and record_helper::thread_ready.

Referenced by record_callback().

1120 {
1121  switch_media_bug_t *bug = (switch_media_bug_t *) obj;
1124  struct record_helper *rh;
1125  switch_size_t bsize = SWITCH_RECOMMENDED_BUFFER_SIZE, samples = 0, inuse = 0;
1126  unsigned char *data;
1127  int channels = 1;
1129 
1131  return NULL;
1132  }
1133 
1135  switch_buffer_create_dynamic(&rh->thread_buffer, 1024 * 512, 1024 * 64, 0);
1136  rh->thread_ready = 1;
1137 
1140 
1141  while(switch_test_flag(rh->fh, SWITCH_FILE_OPEN)) {
1143  switch_core_session_get_read_impl(session, &read_impl);
1145  bsize = read_impl.decoded_bytes_per_packet;
1146  }
1147  }
1148 
1150  inuse = switch_buffer_inuse(rh->thread_buffer);
1151 
1152  if (rh->thread_ready && switch_channel_up_nosig(channel) && inuse < bsize) {
1154  switch_yield(20000);
1155  continue;
1156  } else if ((!rh->thread_ready || switch_channel_down_nosig(channel)) && !inuse) {
1158  break;
1159  }
1160 
1161  samples = switch_buffer_read(rh->thread_buffer, data, bsize) / 2 / channels;
1163 
1164  if (switch_core_file_write(rh->fh, data, &samples) != SWITCH_STATUS_SUCCESS) {
1165  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error writing %s\n", rh->file);
1166  /* File write failed */
1167  set_completion_cause(rh, "uri-failure");
1168  if (rh->hangup_on_error) {
1171  }
1172  }
1173  }
1174 
1176 
1177  return NULL;
1178 }
#define switch_channel_hangup(channel, hangup_cause)
Hangup a channel flagging it's state machine to end.
#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)
#define SWITCH_RECOMMENDED_BUFFER_SIZE
Definition: switch_types.h:557
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_mutex_t * buffer_mutex
switch_buffer_t * thread_buffer
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:290
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_yield(ms)
Wait a desired number of microseconds and yield the CPU.
Definition: switch_utils.h:908
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:285
#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)
#define switch_core_session_alloc(_session, _memory)
Allocate memory from a session's pool.
Definition: switch_core.h:694
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:624
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.
#define switch_channel_up_nosig(_channel)
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.
static void send_record_stop_event ( switch_channel_t channel,
switch_codec_implementation_t read_impl,
struct record_helper rh 
)
static

Definition at line 1093 of file switch_ivr_async.c.

References switch_codec_implementation::actual_samples_per_second, record_helper::completion_cause, record_helper::fh, record_helper::file, switch_file_handle::samples_out, switch_channel_event_set_data(), switch_channel_set_variable_printf(), switch_event_add_header_string(), switch_event_create, switch_event_fire, SWITCH_EVENT_RECORD_STOP, SWITCH_STACK_BOTTOM, SWITCH_STATUS_SUCCESS, and zstr.

Referenced by record_callback().

1094 {
1095  switch_event_t *event;
1096 
1097  if (rh->fh) {
1098  switch_channel_set_variable_printf(channel, "record_samples", "%d", rh->fh->samples_out);
1099  if (read_impl->actual_samples_per_second) {
1100  switch_channel_set_variable_printf(channel, "record_seconds", "%d", rh->fh->samples_out / read_impl->actual_samples_per_second);
1101  switch_channel_set_variable_printf(channel, "record_ms", "%d", rh->fh->samples_out / (read_impl->actual_samples_per_second / 1000));
1102  }
1103  }
1104 
1105  if (!zstr(rh->completion_cause)) {
1106  switch_channel_set_variable_printf(channel, "record_completion_cause", "%s", rh->completion_cause);
1107  }
1108 
1110  switch_channel_event_set_data(channel, event);
1111  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Record-File-Path", rh->file);
1112  if (!zstr(rh->completion_cause)) {
1113  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Record-Completion-Cause", rh->completion_cause);
1114  }
1115  switch_event_fire(&event);
1116  }
1117 }
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:412
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:281
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.
#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:383
switch_file_handle_t * fh
static switch_bool_t session_audio_callback ( switch_media_bug_t bug,
void *  user_data,
switch_abc_type_t  type 
)
static

Definition at line 3039 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().

3040 {
3041  switch_session_audio_t *pvt = (switch_session_audio_t *) user_data;
3042  switch_frame_t *frame = NULL;
3043  int level = 0, mute = 0;
3046 
3047  switch_core_session_get_read_impl(session, &read_impl);
3048 
3049 
3051  if (!(pvt->read_level || pvt->write_level || pvt->read_mute || pvt->write_mute)) {
3053  return SWITCH_FALSE;
3054  }
3055  }
3056 
3057  if (type == SWITCH_ABC_TYPE_READ_REPLACE) {
3058  level = pvt->read_level;
3059  mute = pvt->read_mute;
3061  } else if (type == SWITCH_ABC_TYPE_WRITE_REPLACE) {
3062  level = pvt->write_level;
3063  mute = pvt->write_mute;
3065  }
3066 
3067  if (frame) {
3068  if (mute) {
3069  if (mute > 1) {
3070  switch_generate_sln_silence(frame->data, frame->datalen / 2, read_impl.number_of_channels, mute);
3071  } else {
3072  memset(frame->data, 0, frame->datalen);
3073  }
3074  } else if (level) {
3075  switch_change_sln_volume(frame->data, frame->datalen / 2, level);
3076  }
3077 
3078  if (type == SWITCH_ABC_TYPE_READ_REPLACE) {
3080  } else if (type == SWITCH_ABC_TYPE_WRITE_REPLACE) {
3082  }
3083  }
3084 
3085  return SWITCH_TRUE;
3086 }
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:57
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:43
A table of settings and callbacks that define a paticular implementation of a codec.
memset(buf, 0, buflen)
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 1060 of file switch_ivr_async.c.

References record_helper::completion_cause.

Referenced by record_callback(), and recording_thread().

1061 {
1062  if (!rh->completion_cause) {
1064  }
1065 }
const char * completion_cause
static switch_bool_t speech_callback ( switch_media_bug_t bug,
void *  user_data,
switch_abc_type_t  type 
)
static

Definition at line 4497 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(), 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_core_asr_check_results(), switch_core_asr_close(), switch_core_asr_feed(), switch_core_media_bug_get_session(), switch_core_media_bug_read(), SWITCH_FALSE, SWITCH_LOG_DEBUG, switch_log_printf(), switch_mutex_lock(), switch_mutex_trylock(), switch_mutex_unlock(), SWITCH_RECOMMENDED_BUFFER_SIZE, 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().

4498 {
4499  struct speech_thread_handle *sth = (struct speech_thread_handle *) user_data;
4500  uint8_t data[SWITCH_RECOMMENDED_BUFFER_SIZE];
4501  switch_frame_t frame = { 0 };
4503 
4504  frame.data = data;
4506 
4507  switch (type) {
4508  case SWITCH_ABC_TYPE_INIT:
4509  {
4510  switch_threadattr_t *thd_attr = NULL;
4511 
4512  switch_threadattr_create(&thd_attr, sth->pool);
4514  switch_thread_create(&sth->thread, thd_attr, speech_thread, sth, sth->pool);
4515  }
4516  break;
4517  case SWITCH_ABC_TYPE_CLOSE:
4518  {
4519  switch_status_t st;
4520 
4521  switch_core_asr_close(sth->ah, &flags);
4522  if (sth->mutex && sth->cond && sth->ready) {
4525  switch_mutex_unlock(sth->mutex);
4526  }
4527  }
4528 
4529  switch_thread_join(&st, sth->thread);
4530 
4531  }
4532  break;
4533  case SWITCH_ABC_TYPE_READ:
4534  if (sth->ah) {
4536  if (switch_core_asr_feed(sth->ah, frame.data, frame.datalen, &flags) != SWITCH_STATUS_SUCCESS) {
4538  return SWITCH_FALSE;
4539  }
4541  if (sth->mutex && sth->cond && sth->ready) {
4542  switch_mutex_lock(sth->mutex);
4544  switch_mutex_unlock(sth->mutex);
4545  }
4546  }
4547  }
4548  }
4549  break;
4550  case SWITCH_ABC_TYPE_WRITE:
4551  default:
4552  break;
4553  }
4554 
4555  return SWITCH_TRUE;
4556 }
#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:295
#define SWITCH_RECOMMENDED_BUFFER_SIZE
Definition: switch_types.h:557
switch_status_t switch_threadattr_stacksize_set(switch_threadattr_t *attr, switch_size_t stacksize)
Definition: switch_apr.c:660
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.
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:290
switch_status_t switch_thread_join(switch_status_t *retval, switch_thread_t *thd)
Definition: switch_apr.c:1255
uint32_t buflen
Definition: switch_frame.h:59
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:57
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:285
switch_thread_cond_t * cond
switch_memory_pool_t * pool
#define SWITCH_THREAD_STACKSIZE
Definition: switch_types.h:551
switch_thread_t * thread
An abstraction of a data frame.
Definition: switch_frame.h:43
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:371
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:642
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:675
switch_mutex_t * mutex
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 4558 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 switch_ivr_detect_speech_init(), and switch_ivr_stop_detect_speech().

4559 {
4564 
4565  if (sth) {
4566  if (switch_core_asr_feed_dtmf(sth->ah, dtmf, &flags) != SWITCH_STATUS_SUCCESS) {
4567  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error Feeding DTMF\n");
4568  }
4569  }
4570 
4571  return status;
4572 }
#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:226
_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.
static void* SWITCH_THREAD_FUNC speech_thread ( switch_thread_t thread,
void *  obj 
)
static

Definition at line 4348 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_SUCCESS, switch_stristr(), switch_test_flag, switch_thread_cond_create(), switch_thread_cond_wait(), and switch_true().

Referenced by speech_callback().

4349 {
4350  struct speech_thread_handle *sth = (struct speech_thread_handle *) obj;
4353  switch_status_t status;
4354  switch_event_t *event;
4355 
4356  switch_thread_cond_create(&sth->cond, sth->pool);
4358 
4360  sth->ready = 0;
4361  return NULL;
4362  }
4363 
4364  switch_mutex_lock(sth->mutex);
4365 
4366  sth->ready = 1;
4367 
4369  char *xmlstr = NULL;
4370  switch_event_t *headers = NULL;
4371 
4372  switch_thread_cond_wait(sth->cond, sth->mutex);
4373 
4375  break;
4376  }
4377 
4379 
4380  status = switch_core_asr_get_results(sth->ah, &xmlstr, &flags);
4381 
4382  if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) {
4383  goto done;
4384  } else if (status == SWITCH_STATUS_SUCCESS) {
4385  /* Try to fetch extra information for this result, the return value doesn't really matter here - it's just optional data. */
4386  switch_core_asr_get_result_headers(sth->ah, &headers, &flags);
4387  }
4388 
4389  if (status == SWITCH_STATUS_SUCCESS && switch_true(switch_channel_get_variable(channel, "asr_intercept_dtmf"))) {
4390  const char *p;
4391 
4392  if ((p = switch_stristr("<input>", xmlstr))) {
4393  p += 7;
4394  }
4395 
4396  while (p && *p) {
4397  char c;
4398 
4399  if (*p == '<') {
4400  break;
4401  }
4402 
4403  if (!strncasecmp(p, "pound", 5)) {
4404  c = '#';
4405  p += 5;
4406  } else if (!strncasecmp(p, "hash", 4)) {
4407  c = '#';
4408  p += 4;
4409  } else if (!strncasecmp(p, "star", 4)) {
4410  c = '*';
4411  p += 4;
4412  } else if (!strncasecmp(p, "asterisk", 8)) {
4413  c = '*';
4414  p += 8;
4415  } else {
4416  c = *p;
4417  p++;
4418  }
4419 
4420  if (is_dtmf(c)) {
4421  switch_dtmf_t dtmf = {0};
4422  dtmf.digit = c;
4425  switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "Queue speech detected dtmf %c\n", c);
4426  switch_channel_queue_dtmf(channel, &dtmf);
4427  }
4428 
4429  }
4431  }
4432 
4434  if (status == SWITCH_STATUS_SUCCESS) {
4435  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Speech-Type", "detected-speech");
4436 
4437  if (headers) {
4438  switch_event_merge(event, headers);
4439  }
4440 
4441  switch_event_add_body(event, "%s", xmlstr);
4442  } else {
4443  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Speech-Type", "begin-speaking");
4444  }
4445 
4447  switch_event_t *dup;
4448 
4449  if (switch_event_dup(&dup, event) == SWITCH_STATUS_SUCCESS) {
4450  switch_channel_event_set_data(channel, dup);
4451  switch_event_fire(&dup);
4452  }
4453 
4454  }
4455 
4457  switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_ERROR, "Event queue failed!\n");
4458  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "delivery-failure", "true");
4459  switch_event_fire(&event);
4460  }
4461  }
4462 
4463  switch_safe_free(xmlstr);
4464 
4465  if (headers) {
4466  switch_event_destroy(&headers);
4467  }
4468  }
4469  }
4470  done:
4471 
4473  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Speech-Type", "closed");
4475  switch_event_t *dup;
4476 
4477  if (switch_event_dup(&dup, event) == SWITCH_STATUS_SUCCESS) {
4478  switch_channel_event_set_data(channel, dup);
4479  switch_event_fire(&dup);
4480  }
4481 
4482  }
4483 
4485  switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_ERROR, "Event queue failed!\n");
4486  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "delivery-failure", "true");
4487  switch_event_fire(&event);
4488  }
4489  }
4490 
4491  switch_mutex_unlock(sth->mutex);
4493 
4494  return NULL;
4495 }
#define switch_event_fire(event)
Fire an event filling in most of the arguements with obvious values.
Definition: switch_event.h:412
switch_status_t switch_thread_cond_create(switch_thread_cond_t **cond, switch_memory_pool_t *pool)
Definition: switch_apr.c:350
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:355
uint32_t duration
Definition: switch_types.h:288
switch_status_t switch_event_dup(switch_event_t **event, switch_event_t *todup)
Duplicate an event.
static int switch_true(const char *expr)
Evaluate the truthfullness of a string expression.
Definition: switch_utils.h:450
#define is_dtmf(key)
determine if a character is a valid DTMF key
Definition: switch_utils.h:614
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:290
_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:285
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:789
switch_status_t switch_mutex_init(switch_mutex_t **lock, unsigned int flags, switch_memory_pool_t *pool)
Definition: switch_apr.c:270
#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:1681
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:383
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:624
switch_dtmf_source_t source
Definition: switch_types.h:290
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
static dm_match_t switch_ivr_dmachine_check_match ( switch_ivr_dmachine_t dmachine,
switch_bool_t  is_timeout 
)
static

Definition at line 339 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::is_regex, switch_ivr_dmachine::last_matching_binding, switch_ivr_dmachine::last_matching_digits, switch_ivr_dmachine::max_digit_len, switch_ivr_dmachine_binding::next, switch_ivr_dmachine::realm, switch_ivr_dmachine_binding::rmatch, switch_regex_match(), switch_set_string, SWITCH_STATUS_SUCCESS, dm_binding_head_t::terminators, and zstr.

Referenced by switch_ivr_dmachine_ping().

340 {
341  dm_match_t best = DM_MATCH_NONE;
342  switch_ivr_dmachine_binding_t *bp, *exact_bp = NULL, *partial_bp = NULL, *both_bp = NULL, *r_bp = NULL;
343  int pmatches = 0, ematches = 0, rmatches = 0;
344 
345  if (!dmachine->cur_digit_len || !dmachine->realm) goto end;
346 
347  for(bp = dmachine->realm->binding_list; bp; bp = bp->next) {
348  if (bp->is_regex) {
349  switch_status_t r_status = switch_regex_match(dmachine->digits, bp->digits);
350 
351  if (r_status == SWITCH_STATUS_SUCCESS) {
352  bp->rmatch++;
353  } else {
354  bp->rmatch = 0;
355  }
356 
357  rmatches++;
358  pmatches++;
359 
360  } else {
361  if (!strncmp(dmachine->digits, bp->digits, strlen(dmachine->digits))) {
362  pmatches++;
363  ematches = 1;
364  }
365  }
366  }
367 
368  if (!zstr(dmachine->realm->terminators)) {
369  char *p = dmachine->realm->terminators;
370  char *q;
371 
372  while(p && *p) {
373  if ((q=strrchr(dmachine->digits, *p))) {
374  *q = '\0';
375  is_timeout = 1;
376  break;
377  }
378  p++;
379  }
380  }
381 
382  for(bp = dmachine->realm->binding_list; bp; bp = bp->next) {
383  if (bp->is_regex) {
384  if (bp->rmatch) {
385  if (is_timeout || (bp == dmachine->realm->binding_list && !bp->next)) {
386  best = DM_MATCH_EXACT;
387  exact_bp = bp;
388  break;
389  }
390  best = DM_MATCH_PARTIAL;
391  }
392  } else {
393  int pmatch = !strncmp(dmachine->digits, bp->digits, strlen(dmachine->digits));
394 
395  if (!exact_bp && pmatch && (((pmatches == 1 || ematches == 1) && !rmatches) || is_timeout) && !strcmp(bp->digits, dmachine->digits)) {
396  best = DM_MATCH_EXACT;
397  exact_bp = bp;
398  if (dmachine->cur_digit_len == dmachine->max_digit_len) break;
399  }
400 
401  if (!(both_bp && partial_bp) && strlen(bp->digits) != strlen(dmachine->digits) && pmatch) {
402 
403  if (exact_bp) {
404  best = DM_MATCH_BOTH;
405  both_bp = bp;
406  } else {
407  best = DM_MATCH_PARTIAL;
408  partial_bp = bp;
409  }
410  }
411 
412  if (both_bp && exact_bp && partial_bp) break;
413  }
414  }
415 
416  if (!pmatches) {
417  best = DM_MATCH_NEVER;
418  }
419 
420 
421  end:
422 
423  if (is_timeout) {
424  if (both_bp) {
425  r_bp = exact_bp ? exact_bp : both_bp;
426  }
427  }
428 
429  if (best == DM_MATCH_EXACT && exact_bp) {
430  r_bp = exact_bp;
431  }
432 
433 
434  if (r_bp) {
435  dmachine->last_matching_binding = r_bp;
436  switch_set_string(dmachine->last_matching_digits, dmachine->digits);
437  best = DM_MATCH_EXACT;
438  }
439 
440  return best;
441 
442 }
struct switch_ivr_dmachine_binding * next
switch_ivr_dmachine_binding_t * last_matching_binding
dm_binding_head_t * realm
switch_ivr_dmachine_binding_t * binding_list
#define zstr(x)
Definition: switch_utils.h:281
char digits[DMACHINE_MAX_DIGIT_LEN]
dm_match_t
switch_status_t
Common return values.
char last_matching_digits[DMACHINE_MAX_DIGIT_LEN]
#define switch_set_string(_dst, _src)
Definition: switch_utils.h:665
switch_status_t switch_regex_match(const char *target, const char *expression)
Function to evaluate an expression against a string.
Definition: switch_regex.c:295
static switch_bool_t switch_ivr_dmachine_check_timeout ( switch_ivr_dmachine_t dmachine)
static

Definition at line 444 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().

445 {
447  uint32_t timeout = dmachine->cur_digit_len ? dmachine->digit_timeout_ms : dmachine->input_timeout_ms;
448 
449  if (!dmachine->last_digit_time) dmachine->last_digit_time = now;
450 
451  if (timeout) {
452  if ((uint32_t)((now - dmachine->last_digit_time) / 1000) > timeout) {
453  return SWITCH_TRUE;
454  }
455  }
456 
457  return SWITCH_FALSE;
458 }
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:302
static void* switch_ivr_record_user_data_dup ( switch_core_session_t session,
void *  user_data 
)
static

Definition at line 1558 of file switch_ivr_async.c.

References record_helper::fh, record_helper::file, switch_core_session_alloc, and switch_core_session_strdup.

Referenced by switch_ivr_transfer_recordings().

1559 {
1560  struct record_helper *rh = (struct record_helper *) user_data, *dup = NULL;
1561 
1562  dup = switch_core_session_alloc(session, sizeof(*dup));
1563  memcpy(dup, rh, sizeof(*rh));
1564  dup->file = switch_core_session_strdup(session, rh->file);
1565  dup->fh = switch_core_session_alloc(session, sizeof(switch_file_handle_t));
1566  memcpy(dup->fh, rh->fh, sizeof(switch_file_handle_t));
1567 
1568  return dup;
1569 }
#define switch_core_session_alloc(_session, _memory)
Allocate memory from a session's pool.
Definition: switch_core.h:694
#define switch_core_session_strdup(_session, _todup)
Copy a string using memory allocation from a session's pool.
Definition: switch_core.h:717
switch_file_handle_t * fh
SWITCH_STANDARD_SCHED_FUNC ( sch_hangup_callback  )

Definition at line 4818 of file switch_ivr_async.c.

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

4819 {
4820  struct hangup_helper *helper;
4821  switch_core_session_t *session, *other_session;
4822  const char *other_uuid;
4823 
4824  switch_assert(task);
4825 
4826  helper = (struct hangup_helper *) task->cmd_arg;
4827 
4828  if ((session = switch_core_session_locate(helper->uuid_str))) {
4830 
4831  if (helper->bleg) {
4832  if ((other_uuid = switch_channel_get_variable(channel, SWITCH_BRIDGE_VARIABLE)) && (other_session = switch_core_session_locate(other_uuid))) {
4833  switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
4834  switch_channel_hangup(other_channel, helper->cause);
4835  switch_core_session_rwunlock(other_session);
4836  } else {
4837  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "No channel to hangup\n");
4838  }
4839  } else {
4840  switch_channel_hangup(channel, helper->cause);
4841  }
4842 
4844  }
4845 }
#define switch_channel_hangup(channel, hangup_cause)
Hangup a channel flagging it'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)
#define switch_channel_get_variable(_c, _v)
switch_call_cause_t cause
#define SWITCH_BRIDGE_VARIABLE
Definition: switch_types.h:199
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's uuid.
Definition: switch_core.h:916
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 ( sch_transfer_callback  )

Definition at line 4868 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.

4869 {
4870  struct transfer_helper *helper;
4871  switch_core_session_t *session;
4872 
4873  switch_assert(task);
4874 
4875  helper = (struct transfer_helper *) task->cmd_arg;
4876 
4877  if ((session = switch_core_session_locate(helper->uuid_str))) {
4878  switch_ivr_session_transfer(session, helper->extension, helper->dialplan, helper->context);
4880  }
4881 
4882 }
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's uuid.
Definition: switch_core.h:916
#define switch_assert(expr)
SWITCH_STANDARD_SCHED_FUNC ( sch_broadcast_callback  )

Definition at line 4935 of file switch_ivr_async.c.

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

4936 {
4937  struct broadcast_helper *helper;
4938  switch_assert(task);
4939 
4940  helper = (struct broadcast_helper *) task->cmd_arg;
4941  switch_ivr_broadcast(helper->uuid_str, helper->path, helper->flags);
4942 }
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)
static int teletone_dtmf_generate_handler ( teletone_generation_session_t ts,
teletone_tone_map_t map 
)
static

Definition at line 3273 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().

3274 {
3275  switch_buffer_t *audio_buffer = ts->user_data;
3276  int wrote;
3277 
3278  if (!audio_buffer) {
3279  return -1;
3280  }
3281 
3282  wrote = teletone_mux_tones(ts, map);
3283  switch_buffer_write(audio_buffer, ts->buffer, wrote * 2);
3284 
3285  return 0;
3286 }
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.
static switch_bool_t tone_detect_callback ( switch_media_bug_t bug,
void *  user_data,
switch_abc_type_t  type 
)
static

Definition at line 3565 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, skip(), 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().

3566 {
3567  switch_tone_container_t *cont = (switch_tone_container_t *) user_data;
3568  switch_frame_t *frame = NULL;
3569  int i = 0;
3570  switch_bool_t rval = SWITCH_TRUE;
3571 
3572  switch (type) {
3573  case SWITCH_ABC_TYPE_INIT:
3574  if (cont) {
3575  cont->bug_running = 1;
3576  }
3577  break;
3578  case SWITCH_ABC_TYPE_CLOSE:
3579  break;
3582  {
3583 
3584  if (type == SWITCH_ABC_TYPE_READ_REPLACE) {
3586  } else {
3588  }
3589 
3590  for (i = 0; i < cont->index; i++) {
3591  int skip = 0;
3592 
3593  if (cont->list[i].sleep) {
3594  cont->list[i].sleep--;
3595  if (cont->list[i].sleep) {
3596  skip = 1;
3597  }
3598  }
3599 
3600  if (cont->list[i].expires) {
3601  cont->list[i].expires--;
3602  if (!cont->list[i].expires) {
3603  cont->list[i].hits = 0;
3604  cont->list[i].sleep = 0;
3605  cont->list[i].expires = 0;
3606  }
3607  }
3608 
3609  if (!cont->list[i].up)
3610  skip = 1;
3611 
3612  if (skip)
3613  continue;
3614 
3615  if (teletone_multi_tone_detect(&cont->list[i].mt, frame->data, frame->samples)) {
3616  switch_event_t *event;
3617  cont->list[i].hits++;
3618 
3620  cont->list[i].key, cont->list[i].hits, cont->list[i].total_hits);
3621  cont->list[i].sleep = cont->list[i].default_sleep;
3622  cont->list[i].expires = cont->list[i].default_expires;
3623 
3624  if (cont->list[i].hits >= cont->list[i].total_hits) {
3626  cont->list[i].key);
3627  tone_detect_set_total_time(cont, i);
3628  cont->list[i].up = 0;
3629 
3630  if (cont->list[i].callback) {
3631  if ((rval = cont->list[i].callback(cont->session, cont->list[i].app, cont->list[i].data)) == SWITCH_TRUE) {
3633  cont->list[i].key);
3634  cont->list[i].up = 1;
3635  cont->list[i].hits = 0;
3636  cont->list[i].sleep = 0;
3637  cont->list[i].expires = 0;
3638  }
3639  } else {
3641  if (cont->list[i].app) {
3643  }
3644  }
3645 
3646  if (cont->list[i].once) {
3647  rval = SWITCH_FALSE;
3648  }
3649 
3651  switch_event_t *dup;
3652  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Detected-Tone", cont->list[i].key);
3653 
3654  if (switch_event_dup(&dup, event) == SWITCH_STATUS_SUCCESS) {
3655  switch_event_fire(&dup);
3656  }
3657 
3660  "Event queue failed!\n");
3661  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "delivery-failure", "true");
3662  switch_event_fire(&event);
3663  }
3664  }
3665  }
3666  }
3667  }
3668  }
3669  break;
3670  case SWITCH_ABC_TYPE_WRITE:
3671  default:
3672  break;
3673  }
3674 
3675  if (rval == SWITCH_FALSE) {
3676  cont->bug_running = 0;
3677  }
3678 
3679  return rval;
3680 }
#define switch_event_fire(event)
Fire an event filling in most of the arguements with obvious values.
Definition: switch_event.h:412
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:405
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:43
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:383
uint32_t samples
Definition: switch_frame.h:61
#define SWITCH_CHANNEL_EXECUTE_ON_TONE_DETECT_VARIABLE
Definition: switch_types.h:152
static const char * skip(const char *in)
Definition: switch_json.c:270
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]
static void tone_detect_set_total_time ( switch_tone_container_t cont,
int  index 
)
static

Definition at line 3528 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().

3529 {
3530  char *total_time = switch_mprintf("%d", (int)(switch_micro_time_now() - cont->list[index].start_time) / 1000);
3531 
3532  switch_channel_set_variable_name_printf(switch_core_session_get_channel(cont->session), total_time, "tone_detect_%s_total_time",
3533  cont->list[index].key);
3534  switch_safe_free(total_time);
3535 }
switch_time_t switch_micro_time_now(void)
Get the current epoch time in microseconds.
Definition: switch_time.c:310
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
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:789
SWITCH_BEGIN_EXTERN_C char * switch_mprintf(const char *zFormat,...)
switch_tone_detect_t list[MAX_TONES+1]
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 3537 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().

3538 {
3540  switch_tone_container_t *cont = switch_channel_get_private(channel, "_tone_detect_");
3541  int i;
3542 
3543  if (!cont || !cont->detect_fax || dtmf->digit != 'f') {
3544  return SWITCH_STATUS_SUCCESS;
3545  }
3546 
3547  i = cont->detect_fax;
3548 
3549  tone_detect_set_total_time(cont, i);
3550  if (cont->list[i].callback) {
3551  cont->list[i].callback(cont->session, cont->list[i].app, cont->list[i].data);
3552  } else {
3555 
3556  if (cont->list[i].app) {
3558  }
3559  }
3560 
3561  return SWITCH_STATUS_SUCCESS;
3562 
3563 }
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:152
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:164
static switch_status_t video_eavesdrop_callback ( switch_core_session_t session,
switch_frame_t frame,
void *  user_data 
)
static

Definition at line 1603 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().

1604 {
1605  switch_media_bug_t *bug = (switch_media_bug_t *) user_data;
1606 
1607  if (frame->img) {
1610  }
1611 
1614  }
1615  }
1616 
1617  return SWITCH_STATUS_SUCCESS;
1618 }
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:77
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.
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 5093 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().

5094 {
5095  overly_helper_t *oht = (overly_helper_t *) user_data;
5098 
5099  switch (type) {
5100  case SWITCH_ABC_TYPE_INIT:
5101  {
5102  }
5103  break;
5104  case SWITCH_ABC_TYPE_CLOSE:
5105  {
5106  switch_img_free(&oht->img);
5107  }
5108  break;
5112  int x = 0, y = 0;
5113  switch_image_t *oimg = NULL;
5114 
5115  if (frame->img && oht->img) {
5116  switch_img_copy(oht->img, &oimg);
5117  switch_img_fit(&oimg, frame->img->d_w, frame->img->d_h, SWITCH_FIT_SIZE);
5118  switch_img_find_position(oht->pos, frame->img->d_w, frame->img->d_h, oimg->d_w, oimg->d_h, &x, &y);
5119  switch_img_overlay(frame->img, oimg, x, y, oht->alpha);
5120  //switch_img_patch(frame->img, oimg, x, y);
5121  switch_img_free(&oimg);
5122  }
5123  }
5124  break;
5125  default:
5126  break;
5127  }
5128 
5129  return SWITCH_TRUE;
5130 }
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:43
switch_image_t * img
Definition: switch_frame.h:77
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
static switch_bool_t write_displace_callback ( switch_media_bug_t bug,
void *  user_data,
switch_abc_type_t  type 
)
static

Definition at line 731 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().

732 {
733  displace_helper_t *dh = (displace_helper_t *) user_data;
734 
735  switch (type) {
737  break;
739  if (dh) {
741  switch_channel_t *channel;
742 
744 
745  if (session && (channel = switch_core_session_get_channel(session))) {
746  switch_channel_set_private(channel, dh->file, NULL);
747  }
748  }
749  break;
751  {
753  if (dh && !dh->mux) {
754  memset(rframe->data, 255, rframe->datalen);
755  }
757  }
758  break;
760  if (dh) {
761  switch_frame_t *rframe = NULL;
762  switch_size_t len;
763  switch_status_t st;
764 
766  len = rframe->samples;
767 
768  if (dh->mux) {
770  int16_t *fp = rframe->data;
771  uint32_t x;
772 
773  st = switch_core_file_read(&dh->fh, buf, &len);
774 
775  for (x = 0; x < (uint32_t) len * dh->fh.channels; x++) {
776  int32_t mixed = fp[x] + buf[x];
778  fp[x] = (int16_t) mixed;
779  }
780  } else {
781  st = switch_core_file_read(&dh->fh, rframe->data, &len);
782  if (len < rframe->samples) {
783  memset((char *)rframe->data + (len * 2 * dh->fh.channels), 0, (rframe->samples - len) * 2 * dh->fh.channels);
784  }
785  }
786 
787  rframe->datalen = rframe->samples * 2 * dh->fh.channels;
788 
789  if (st != SWITCH_STATUS_SUCCESS || len == 0) {
790  if (dh->loop) {
791  uint32_t pos = 0;
792  switch_core_file_seek(&dh->fh, &pos, 0, SEEK_SET);
793  } else {
795  switch_channel_t *channel;
796 
797  if (session && (channel = switch_core_session_get_channel(session))) {
798  switch_channel_set_private(channel, dh->file, NULL);
799  }
800  return SWITCH_FALSE;
801  }
802  }
803 
805  }
806  break;
808  default:
809  break;
810  }
811 
812  return SWITCH_TRUE;
813 }
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:557
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.