switch_ivr_async.c File Reference

#include <switch.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

Defines

#define MAX_TONES   16
#define SWITCH_META_VAR_KEY   "__dtmf_meta"
#define SWITCH_BLOCK_DTMF_KEY   "__dtmf_block"

Typedefs

typedef switch_ivr_dmachine_binding switch_ivr_dmachine_binding_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_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_status_t switch_ivr_dmachine_clear (switch_ivr_dmachine_t *dmachine)
void switch_ivr_session_echo (switch_core_session_t *session, switch_input_args_t *args)
 
  • NEEDDESC -

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.
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
static switch_bool_t record_callback (switch_media_bug_t *bug, void *user_data, switch_abc_type_t type)
switch_status_t switch_ivr_stop_record_session (switch_core_session_t *session, const char *file)
 Stop Recording a session.
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.
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.
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.
switch_status_t switch_ivr_inband_dtmf_session (switch_core_session_t *session)
 Start looking for DTMF inband.
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.
switch_status_t switch_ivr_inband_dtmf_generate_session (switch_core_session_t *session, switch_bool_t read_stream)
 Start generating DTMF inband.
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.
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.
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.
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.
switch_status_t switch_ivr_pause_detect_speech (switch_core_session_t *session)
 Pause background Speech detection on a session.
switch_status_t switch_ivr_resume_detect_speech (switch_core_session_t *session)
 Resume background Speech detection on a session.
switch_status_t switch_ivr_detect_speech_load_grammar (switch_core_session_t *session, char *grammar, char *name)
 Load a grammar on a background speech detection handle.
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.
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.
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.
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.
switch_status_t switch_ivr_detect_speech_disable_all_grammars (switch_core_session_t *session)
 Disable all grammars on a background speech detection handle.
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.
 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.
 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.
 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.
switch_status_t switch_ivr_broadcast (const char *uuid, const char *path, switch_media_flag_t flags)
 Signal the session to broadcast audio.


Define Documentation

#define MAX_TONES   16

Definition at line 2675 of file switch_ivr_async.c.

Referenced by switch_ivr_tone_detect_session().

#define SWITCH_BLOCK_DTMF_KEY   "__dtmf_block"

Definition at line 3058 of file switch_ivr_async.c.

Referenced by block_on_dtmf(), switch_ivr_block_dtmf_session(), and switch_ivr_unblock_dtmf_session().

#define SWITCH_META_VAR_KEY   "__dtmf_meta"

Definition at line 3057 of file switch_ivr_async.c.

Referenced by meta_on_dtmf(), switch_ivr_bind_dtmf_meta_session(), and switch_ivr_unbind_dtmf_meta_session().


Typedef Documentation

typedef struct switch_ivr_dmachine_binding switch_ivr_dmachine_binding_t

Definition at line 48 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 295 of file switch_ivr_async.c.

00295              {
00296         DM_MATCH_NONE,
00297         DM_MATCH_EXACT,
00298         DM_MATCH_PARTIAL,
00299         DM_MATCH_BOTH,
00300         DM_MATCH_NEVER
00301 } dm_match_t;


Function Documentation

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

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

03067 {
03068         bch_t *bch = (bch_t *) obj;
03069 
03070         if (!bch->session) {
03071                 return NULL;
03072         }
03073 
03074         switch_core_session_read_lock(bch->session);
03075         switch_ivr_broadcast(switch_core_session_get_uuid(bch->session), bch->app, bch->flags);
03076         switch_core_session_rwunlock(bch->session);
03077 
03078         return NULL;
03079 
03080 }

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

03235 {
03236         switch_channel_t *channel = switch_core_session_get_channel(session);
03237         uint8_t enabled = (uint8_t)(intptr_t)switch_channel_get_private(channel, SWITCH_BLOCK_DTMF_KEY);
03238 
03239         if (!enabled || switch_channel_test_flag(channel, CF_INNER_BRIDGE)) {
03240                 return SWITCH_STATUS_SUCCESS;
03241         }
03242 
03243         return SWITCH_STATUS_FALSE;
03244 }

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

Definition at line 1284 of file switch_ivr_async.c.

References eavesdrop_pvt::data, eavesdrop_pvt::eavesdropper, switch_core_session_message::from, switch_core_session_message::message_id, switch_core_session_message::string_array_arg, switch_core_media_bug_get_user_data(), switch_core_session_receive_message, and SWITCH_MESSAGE_INDICATE_DISPLAY.

Referenced by switch_ivr_eavesdrop_update_display().

01285 {
01286         struct exec_cb_data *data = (struct exec_cb_data *) user_data;
01287         struct eavesdrop_pvt *ep = (struct eavesdrop_pvt *) switch_core_media_bug_get_user_data(bug);
01288 
01289         if (ep && ep->eavesdropper && ep->eavesdropper != data->caller) {
01290                 switch_core_session_message_t msg = { 0 };
01291 
01292                 msg.from = __FILE__;
01293                 msg.message_id = SWITCH_MESSAGE_INDICATE_DISPLAY;
01294                 msg.string_array_arg[0] = data->var;
01295                 msg.string_array_arg[1] = data->val;
01296                 
01297                 switch_core_session_receive_message(ep->eavesdropper, &msg);            
01298         }
01299 }

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

Definition at line 1159 of file switch_ivr_async.c.

References eavesdrop_pvt::buffer, switch_frame::buflen, switch_frame::data, eavesdrop_pvt::data, switch_frame::datalen, eavesdrop_pvt::demux_frame, ED_MUX_READ, ED_MUX_WRITE, eavesdrop_pvt::r_buffer, switch_frame::samples, 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_WRITE, SWITCH_ABC_TYPE_WRITE_REPLACE, switch_buffer_inuse(), switch_buffer_lock(), switch_buffer_read(), switch_buffer_unlock(), switch_buffer_zwrite(), switch_core_media_bug_get_read_replace_frame(), 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_FALSE, switch_merge_sln(), SWITCH_RECOMMENDED_BUFFER_SIZE, SWITCH_STATUS_FALSE, switch_test_flag, SWITCH_TRUE, and eavesdrop_pvt::w_buffer.

Referenced by switch_ivr_eavesdrop_session().

01160 {
01161         struct eavesdrop_pvt *ep = (struct eavesdrop_pvt *) user_data;
01162         uint8_t data[SWITCH_RECOMMENDED_BUFFER_SIZE];
01163         switch_frame_t frame = { 0 };
01164 
01165         frame.data = data;
01166         frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE;
01167 
01168         switch (type) {
01169         case SWITCH_ABC_TYPE_INIT:
01170                 break;
01171         case SWITCH_ABC_TYPE_CLOSE:
01172                 break;
01173         case SWITCH_ABC_TYPE_WRITE:
01174                 break;
01175         case SWITCH_ABC_TYPE_READ_PING:
01176                 if (ep->buffer) {
01177                         if (switch_core_media_bug_read(bug, &frame, SWITCH_FALSE) != SWITCH_STATUS_FALSE) {
01178                                 switch_buffer_lock(ep->buffer);
01179                                 switch_buffer_zwrite(ep->buffer, frame.data, frame.datalen);
01180                                 switch_buffer_unlock(ep->buffer);
01181                         }
01182                 } else {
01183                         return SWITCH_FALSE;
01184                 }
01185                 break;
01186         case SWITCH_ABC_TYPE_READ:
01187                 break;
01188 
01189         case SWITCH_ABC_TYPE_READ_REPLACE:
01190                 {
01191 
01192                         if (switch_test_flag(ep, ED_MUX_READ)) {
01193                                 switch_frame_t *rframe = switch_core_media_bug_get_read_replace_frame(bug);
01194 
01195                                 if (switch_buffer_inuse(ep->r_buffer) >= rframe->datalen) {
01196                                         uint32_t bytes;
01197                                         switch_buffer_lock(ep->r_buffer);
01198                                         bytes = (uint32_t) switch_buffer_read(ep->r_buffer, ep->data, rframe->datalen);
01199 
01200                                         rframe->datalen = switch_merge_sln(rframe->data, rframe->samples, (int16_t *) ep->data, bytes / 2) * 2;
01201                                         rframe->samples = rframe->datalen / 2;
01202 
01203                                         ep->demux_frame.data = ep->data;
01204                                         ep->demux_frame.datalen = bytes;
01205                                         ep->demux_frame.samples = bytes / 2;
01206                                         
01207                                         switch_buffer_unlock(ep->r_buffer);
01208                                         switch_core_media_bug_set_read_replace_frame(bug, rframe);
01209                                         switch_core_media_bug_set_read_demux_frame(bug, &ep->demux_frame);
01210                                 }
01211                         }
01212                 }
01213                 break;
01214 
01215         case SWITCH_ABC_TYPE_WRITE_REPLACE:
01216                 {
01217                         if (switch_test_flag(ep, ED_MUX_WRITE)) {
01218                                 switch_frame_t *rframe = switch_core_media_bug_get_write_replace_frame(bug);
01219 
01220                                 if (switch_buffer_inuse(ep->w_buffer) >= rframe->datalen) {
01221                                         uint32_t bytes;
01222                                         switch_buffer_lock(ep->w_buffer);
01223                                         bytes = (uint32_t) switch_buffer_read(ep->w_buffer, data, rframe->datalen);
01224 
01225                                         rframe->datalen = switch_merge_sln(rframe->data, rframe->samples, (int16_t *) data, bytes / 2) * 2;
01226                                         rframe->samples = rframe->datalen / 2;
01227 
01228                                         switch_buffer_unlock(ep->w_buffer);
01229                                         switch_core_media_bug_set_write_replace_frame(bug, rframe);
01230                                 }
01231                         }
01232                 }
01233                 break;
01234 
01235         default:
01236                 break;
01237         }
01238 
01239         return SWITCH_TRUE;
01240 }

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

Definition at line 1268 of file switch_ivr_async.c.

References eavesdrop_pvt::data, eavesdrop_pvt::eavesdropper, switch_channel_get_name(), SWITCH_CHANNEL_LOG, switch_core_media_bug_get_user_data(), switch_core_session_execute_application, switch_core_session_get_channel(), SWITCH_LOG_DEBUG, and switch_log_printf().

Referenced by switch_ivr_eavesdrop_exec_all().

01269 {
01270         struct exec_cb_data *data = (struct exec_cb_data *) user_data;
01271         struct eavesdrop_pvt *ep = (struct eavesdrop_pvt *) switch_core_media_bug_get_user_data(bug);
01272 
01273         if (ep && ep->eavesdropper && ep->eavesdropper != data->caller) {
01274                 switch_channel_t *a = switch_core_session_get_channel(ep->eavesdropper);
01275                 switch_channel_t *b = switch_core_session_get_channel(data->caller);
01276 
01277                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s telling %s to exec %s:%s\n", 
01278                                                   switch_channel_get_name(b), switch_channel_get_name(a), data->var, data->val);
01279 
01280                 switch_core_session_execute_application(ep->eavesdropper, data->var, data->val);
01281         }
01282 }

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

02466 {
02467         switch_channel_t *channel = switch_core_session_get_channel(session);
02468         switch_media_bug_t *bug = switch_channel_get_private(channel, "dtmf_generate");
02469         switch_status_t status = SWITCH_STATUS_SUCCESS;
02470 
02471         if (bug) {
02472                 switch_inband_dtmf_generate_t *pvt = (switch_inband_dtmf_generate_t *) switch_core_media_bug_get_user_data(bug);
02473 
02474                 if (pvt) {
02475                         switch_mutex_lock(pvt->mutex);
02476                         
02477                         if (pvt->ready) {
02478                                 switch_dtmf_t *dt = NULL;
02479                                 switch_zmalloc(dt, sizeof(*dt));
02480                                 *dt = *dtmf;
02481                                 if (!switch_buffer_inuse(pvt->audio_buffer)) {
02482                                         pvt->skip = 10;
02483                                 }
02484                                 if (switch_queue_trypush(pvt->digit_queue, dt) == SWITCH_STATUS_SUCCESS) {
02485                                         switch_event_t *event;
02486 
02487                                         if (switch_event_create(&event, SWITCH_EVENT_DTMF) == SWITCH_STATUS_SUCCESS) {
02488                                                 switch_channel_event_set_data(channel, event);
02489                                                 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "DTMF-Digit", "%c", dtmf->digit);
02490                                                 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "DTMF-Duration", "%u", dtmf->duration);
02491                                                 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "DTMF-Conversion", "native:inband");
02492                                                 if (switch_channel_test_flag(channel, CF_DIVERT_EVENTS)) {
02493                                                         switch_core_session_queue_event(session, &event);
02494                                                 } else {
02495                                                         switch_event_fire(&event);
02496                                                 }
02497                                         }
02498                                         
02499                                         dt = NULL;
02500                                         /* 
02501                                            SWITCH_STATUS_FALSE indicates pretend there never was a DTMF
02502                                            since we will be generating it inband now.
02503                                          */
02504                                         status = SWITCH_STATUS_FALSE;
02505                                 } else {
02506                                         free(dt);
02507                                 }
02508                         }
02509                         switch_mutex_unlock(pvt->mutex);
02510                 }
02511         }
02512 
02513         return status;
02514 }

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

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

02360 {
02361         switch_inband_dtmf_t *pvt = (switch_inband_dtmf_t *) user_data;
02362         switch_frame_t *frame = NULL;
02363         switch_channel_t *channel = switch_core_session_get_channel(pvt->session);
02364         teletone_hit_type_t hit;
02365 
02366         switch (type) {
02367         case SWITCH_ABC_TYPE_INIT:
02368                 break;
02369         case SWITCH_ABC_TYPE_CLOSE:
02370                 break;
02371         case SWITCH_ABC_TYPE_READ_REPLACE:
02372                 if ((frame = switch_core_media_bug_get_read_replace_frame(bug))) {
02373                         if ((hit = teletone_dtmf_detect(&pvt->dtmf_detect, frame->data, frame->samples)) == TT_HIT_END) {
02374                                 switch_dtmf_t dtmf = {0};
02375 
02376                                 teletone_dtmf_get(&pvt->dtmf_detect, &dtmf.digit, &dtmf.duration);
02377                                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(switch_core_media_bug_get_session(bug)), SWITCH_LOG_DEBUG, "DTMF DETECTED: [%c][%d]\n",
02378                                                                   dtmf.digit, dtmf.duration);
02379                                 dtmf.source = SWITCH_DTMF_INBAND_AUDIO;
02380                                 switch_channel_queue_dtmf(channel, &dtmf);
02381                         }
02382                         switch_core_media_bug_set_read_replace_frame(bug, frame);
02383                 }
02384                 break;
02385         case SWITCH_ABC_TYPE_WRITE:
02386         default:
02387                 break;
02388         }
02389 
02390         return SWITCH_TRUE;
02391 }

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 2517 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(), 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().

02518 {
02519         switch_inband_dtmf_generate_t *pvt = (switch_inband_dtmf_generate_t *) user_data;
02520         switch_frame_t *frame;
02521         switch_codec_implementation_t read_impl = { 0 };
02522         switch_core_session_get_read_impl(pvt->session, &read_impl);
02523 
02524         switch (type) {
02525         case SWITCH_ABC_TYPE_INIT:
02526                 {
02527                         switch_queue_create(&pvt->digit_queue, 100, switch_core_session_get_pool(pvt->session));
02528                         switch_buffer_create_dynamic(&pvt->audio_buffer, 512, 1024, 0);
02529                         teletone_init_session(&pvt->ts, 0, teletone_dtmf_generate_handler, pvt->audio_buffer);
02530                         pvt->ts.rate = read_impl.actual_samples_per_second;
02531                         pvt->ts.channels = 1;
02532                         switch_mutex_init(&pvt->mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(pvt->session));
02533                         if (pvt->read) {
02534                                 switch_core_event_hook_add_recv_dtmf(pvt->session, generate_on_dtmf);
02535                         } else {
02536                                 switch_core_event_hook_add_send_dtmf(pvt->session, generate_on_dtmf);
02537                         }
02538                         switch_mutex_lock(pvt->mutex);
02539                         pvt->ready = 1;
02540                         switch_mutex_unlock(pvt->mutex);
02541                 }
02542                 break;
02543         case SWITCH_ABC_TYPE_CLOSE:
02544                 {
02545                         switch_mutex_lock(pvt->mutex);
02546                         pvt->ready = 0;
02547                         switch_core_event_hook_remove_recv_dtmf(pvt->session, generate_on_dtmf);
02548                         switch_buffer_destroy(&pvt->audio_buffer);
02549                         teletone_destroy_session(&pvt->ts);
02550                         switch_mutex_unlock(pvt->mutex);
02551                 }
02552                 break;
02553         case SWITCH_ABC_TYPE_READ_REPLACE:
02554         case SWITCH_ABC_TYPE_WRITE_REPLACE:
02555                 {
02556                         switch_size_t bytes;
02557                         void *pop;
02558                         
02559                         if (pvt->skip) {
02560                                 pvt->skip--;
02561                                 return SWITCH_TRUE;
02562                         }
02563                         
02564 
02565                         switch_mutex_lock(pvt->mutex);
02566 
02567                         if (!pvt->ready) {
02568                                 switch_mutex_unlock(pvt->mutex);
02569                                 return SWITCH_FALSE;
02570                         }
02571 
02572                         if (pvt->read) {
02573                                 frame = switch_core_media_bug_get_read_replace_frame(bug);
02574                         } else {
02575                                 frame = switch_core_media_bug_get_write_replace_frame(bug);
02576                         }
02577 
02578                         if (!switch_buffer_inuse(pvt->audio_buffer)) {
02579                                 if (switch_queue_trypop(pvt->digit_queue, &pop) == SWITCH_STATUS_SUCCESS) {
02580                                         switch_dtmf_t *dtmf = (switch_dtmf_t *) pop;
02581                                         
02582 
02583                                         if (dtmf->source != SWITCH_DTMF_INBAND_AUDIO) {
02584                                                 char buf[2] = "";
02585                                                 int duration = dtmf->duration;
02586 
02587                                                 buf[0] = dtmf->digit;
02588                                                 if (duration > (int)switch_core_max_dtmf_duration(0)) {
02589                                                         duration = switch_core_default_dtmf_duration(0);
02590                                                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(switch_core_media_bug_get_session(bug)),
02591                                                                                   SWITCH_LOG_WARNING, "%s Truncating DTMF duration %d ms to %d ms\n",
02592                                                                                           switch_channel_get_name(switch_core_session_get_channel(pvt->session)), dtmf->duration / 8, duration);
02593                                                 }
02594                                                 
02595 
02596                                                 pvt->ts.duration = duration;
02597                                                 teletone_run(&pvt->ts, buf);
02598                                         }
02599                                         free(pop);
02600                                 }
02601                         }
02602 
02603                         if (switch_buffer_inuse(pvt->audio_buffer) && (bytes = switch_buffer_read(pvt->audio_buffer, frame->data, frame->datalen))) {
02604                                 if (bytes < frame->datalen) {
02605                                         switch_byte_t *dp = frame->data;
02606                                         memset(dp + bytes, 0, frame->datalen - bytes);
02607                                 }
02608                         }
02609 
02610                         if (pvt->read) {
02611                                 switch_core_media_bug_set_read_replace_frame(bug, frame);
02612                         } else {
02613                                 switch_core_media_bug_set_write_replace_frame(bug, frame);
02614                         }
02615 
02616                         switch_mutex_unlock(pvt->mutex);
02617                 }
02618                 break;
02619         default:
02620                 break;
02621         }
02622 
02623         return SWITCH_TRUE;
02624 }

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 3104 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, 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, and SWITCH_TRUE.

Referenced by switch_ivr_bind_dtmf_meta_session().

03105 {
03106         switch_channel_t *channel = switch_core_session_get_channel(session);
03107         dtmf_meta_data_t *md = switch_channel_get_private(channel, SWITCH_META_VAR_KEY);
03108         time_t now = switch_epoch_time_now(NULL);
03109         char digit[2] = "";
03110         int dval;
03111 
03112         if (!md || switch_channel_test_flag(channel, CF_INNER_BRIDGE)) {
03113                 return SWITCH_STATUS_SUCCESS;
03114         }
03115 
03116         if (direction == SWITCH_DTMF_RECV && !md->sr[SWITCH_DTMF_RECV].up) {
03117                 return SWITCH_STATUS_SUCCESS;
03118         }
03119 
03120         if (direction == SWITCH_DTMF_SEND && !md->sr[SWITCH_DTMF_SEND].up) {
03121                 return SWITCH_STATUS_SUCCESS;
03122         }
03123 
03124         if (md->sr[direction].meta_on && now - md->sr[direction].last_digit > 5) {
03125                 md->sr[direction].meta_on = SWITCH_FALSE;
03126                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "%s Meta digit timeout parsing %c\n", switch_channel_get_name(channel),
03127                                                   dtmf->digit);
03128                 return SWITCH_STATUS_SUCCESS;
03129         }
03130 
03131         md->sr[direction].last_digit = now;
03132 
03133         if (dtmf->digit == md->sr[direction].meta) {
03134                 if (md->sr[direction].meta_on) {
03135                         md->sr[direction].meta_on = SWITCH_FALSE;
03136                         return SWITCH_STATUS_SUCCESS;
03137                 } else {
03138                         md->sr[direction].meta_on = SWITCH_TRUE;
03139                         return SWITCH_STATUS_FALSE;
03140                 }
03141         }
03142 
03143         if (md->sr[direction].meta_on) {
03144                 if (is_dtmf(dtmf->digit)) {
03145                         int ok = 0;
03146                         *digit = dtmf->digit;
03147                         dval = switch_dtmftoi(digit);
03148                         
03149                         if (direction == SWITCH_DTMF_RECV && (md->sr[direction].map[dval].bind_flags & SBF_DIAL_ALEG)) {
03150                                 ok = 1;
03151                         } else if (direction == SWITCH_DTMF_SEND && (md->sr[direction].map[dval].bind_flags & SBF_DIAL_BLEG)) {
03152                                 ok = 1;
03153                         }
03154 
03155                         if (ok && md->sr[direction].map[dval].app) {
03156                                 uint32_t flags = md->sr[direction].map[dval].flags;
03157 
03158                                 if ((md->sr[direction].map[dval].bind_flags & SBF_EXEC_OPPOSITE)) {
03159                                         if (direction == SWITCH_DTMF_SEND) {
03160                                                 flags |= SMF_ECHO_ALEG;
03161                                         } else {
03162                                                 flags |= SMF_ECHO_BLEG;
03163                                         }
03164                                 } else if ((md->sr[direction].map[dval].bind_flags & SBF_EXEC_SAME)) {
03165                                         if (direction == SWITCH_DTMF_SEND) {
03166                                                 flags |= SMF_ECHO_BLEG;
03167                                         } else {
03168                                                 flags |= SMF_ECHO_ALEG;
03169                                         }
03170                                 } else if ((md->sr[direction].map[dval].bind_flags & SBF_EXEC_ALEG)) {
03171                                         flags |= SMF_ECHO_ALEG;
03172                                 } else if ((md->sr[direction].map[dval].bind_flags & SBF_EXEC_BLEG)) {
03173                                         flags |= SMF_ECHO_BLEG;
03174                                 } else {
03175                                         flags |= SMF_ECHO_ALEG;
03176                                 }
03177 
03178                                 if ((md->sr[direction].map[dval].bind_flags & SBF_EXEC_INLINE)) {
03179                                         flags |= SMF_EXEC_INLINE;
03180                                 }
03181 
03182                                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Processing meta digit '%c' [%s]\n",
03183                                                                   switch_channel_get_name(channel), dtmf->digit, md->sr[direction].map[dval].app);
03184 
03185                                 if (switch_channel_test_flag(channel, CF_PROXY_MODE)) {
03186                                         switch_ivr_broadcast_in_thread(session, md->sr[direction].map[dval].app, flags | SMF_REBRIDGE);
03187                                 } else {
03188                                         switch_ivr_broadcast(switch_core_session_get_uuid(session), md->sr[direction].map[dval].app, flags);
03189                                 }
03190 
03191                                 if ((md->sr[direction].map[dval].bind_flags & SBF_ONCE)) {
03192                                         memset(&md->sr[direction].map[dval], 0, sizeof(md->sr[direction].map[dval]));
03193                                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Unbinding meta digit '%c'\n",
03194                                                                           switch_channel_get_name(channel), dtmf->digit);
03195                                 }
03196 
03197                         } else {
03198                                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "%s Ignoring meta digit '%c' not mapped\n",
03199                                                                   switch_channel_get_name(channel), dtmf->digit);
03200 
03201                         }
03202                 }
03203                 md->sr[direction].meta_on = SWITCH_FALSE;
03204                 return SWITCH_STATUS_FALSE;
03205         }
03206 
03207         return SWITCH_STATUS_SUCCESS;
03208 }

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 3349 of file switch_ivr_async.c.

References play_and_detect_speech_state_t::done, switch_event::event_id, play_and_detect_speech_state_t::result, switch_channel_get_name(), SWITCH_CHANNEL_SESSION_LOG, switch_core_session_get_channel(), switch_core_session_strdup, SWITCH_EVENT_DETECTED_SPEECH, switch_event_get_body(), switch_event_get_header, SWITCH_INPUT_TYPE_EVENT, SWITCH_LOG_INFO, switch_log_printf(), SWITCH_STATUS_BREAK, SWITCH_STATUS_SUCCESS, and zstr.

Referenced by switch_ivr_play_and_detect_speech().

03350 {
03351         play_and_detect_speech_state_t *state = (play_and_detect_speech_state_t *)data;
03352         switch_event_t *event;
03353         switch_channel_t *channel = switch_core_session_get_channel(session);
03354         if (input_type == SWITCH_INPUT_TYPE_EVENT) {
03355                 event = (switch_event_t *)input;
03356                 if (event->event_id == SWITCH_EVENT_DETECTED_SPEECH && !state->done) {
03357                         const char *speech_type = switch_event_get_header(event, "Speech-Type");
03358                         if (!zstr(speech_type)) {
03359                                 if (!strcasecmp(speech_type, "detected-speech")) {
03360                                         const char *result;
03361                                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "(%s) DETECTED SPEECH\n", switch_channel_get_name(channel));
03362                                         result = switch_event_get_body(event);
03363                                         if (!zstr(result)) {
03364                                                 state->result = switch_core_session_strdup(session, result);
03365                                         } else {
03366                                                 state->result = "";
03367                                         }
03368                                         state->done = 1;
03369                                         return SWITCH_STATUS_BREAK;
03370                                 } else if (!strcasecmp(speech_type, "begin-speaking")) {
03371                                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "(%s) START OF SPEECH\n", switch_channel_get_name(channel));
03372                                         return SWITCH_STATUS_BREAK;
03373                                 }
03374                         }
03375                 }
03376         }
03377         return SWITCH_STATUS_SUCCESS;
03378 }

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

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

01930 {
01931         switch_core_session_t *session = switch_core_media_bug_get_session(bug);
01932         switch_channel_t *channel = switch_core_session_get_channel(session);
01933         pp_cb_t *cb = (pp_cb_t *) user_data;
01934         switch_codec_implementation_t read_impl = { 0 };
01935         switch_frame_t *frame = NULL;
01936 
01937         switch_core_session_get_read_impl(session, &read_impl);
01938 
01939         switch (type) {
01940         case SWITCH_ABC_TYPE_INIT:
01941                 {
01942                         switch_mutex_init(&cb->read_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
01943                         switch_mutex_init(&cb->write_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session));
01944                 }
01945                 break;
01946         case SWITCH_ABC_TYPE_CLOSE:
01947                 {
01948                         if (cb->read_st) {
01949                                 speex_preprocess_state_destroy(cb->read_st);
01950                         }
01951 
01952                         if (cb->write_st) {
01953                                 speex_preprocess_state_destroy(cb->write_st);
01954                         }
01955 
01956                         if (cb->read_ec) {
01957                                 speex_echo_state_destroy(cb->read_ec);
01958                         }
01959 
01960                         if (cb->write_ec) {
01961                                 speex_echo_state_destroy(cb->write_ec);
01962                         }
01963 
01964                         switch_channel_set_private(channel, "_preprocess", NULL);
01965                 }
01966                 break;
01967         case SWITCH_ABC_TYPE_READ_REPLACE:
01968                 {
01969                         if (cb->done)
01970                                 return SWITCH_FALSE;
01971                         frame = switch_core_media_bug_get_read_replace_frame(bug);
01972 
01973                         if (cb->read_st) {
01974 
01975                                 if (cb->read_ec) {
01976                                         speex_echo_cancellation(cb->read_ec, (int16_t *) frame->data, (int16_t *) cb->write_data, (int16_t *) cb->read_out);
01977                                         memcpy(frame->data, cb->read_out, frame->datalen);
01978                                 }
01979 
01980                                 speex_preprocess_run(cb->read_st, frame->data);
01981                         }
01982 
01983                         if (cb->write_ec) {
01984                                 memcpy(cb->read_data, frame->data, frame->datalen);
01985                         }
01986                 }
01987                 break;
01988         case SWITCH_ABC_TYPE_WRITE_REPLACE:
01989                 {
01990                         if (cb->done)
01991                                 return SWITCH_FALSE;
01992                         frame = switch_core_media_bug_get_write_replace_frame(bug);
01993 
01994                         if (cb->write_st) {
01995 
01996                                 if (cb->write_ec) {
01997                                         speex_echo_cancellation(cb->write_ec, (int16_t *) frame->data, (int16_t *) cb->read_data, (int16_t *) cb->write_out);
01998                                         memcpy(frame->data, cb->write_out, frame->datalen);
01999                                 }
02000 
02001                                 speex_preprocess_run(cb->write_st, frame->data);
02002                         }
02003 
02004                         if (cb->read_ec) {
02005                                 memcpy(cb->write_data, frame->data, frame->datalen);
02006                         }
02007                 }
02008                 break;
02009         default:
02010                 break;
02011         }
02012 
02013         return SWITCH_TRUE;
02014 }

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

Definition at line 787 of file switch_ivr_async.c.

References buf, switch_frame::data, switch_frame::datalen, displace_helper_t::fh, displace_helper_t::file, displace_helper_t::loop, 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().

00788 {
00789         displace_helper_t *dh = (displace_helper_t *) user_data;
00790 
00791         switch (type) {
00792         case SWITCH_ABC_TYPE_INIT:
00793                 break;
00794         case SWITCH_ABC_TYPE_CLOSE:
00795                 if (dh) {
00796                         switch_core_session_t *session = switch_core_media_bug_get_session(bug);
00797                         switch_channel_t *channel;
00798 
00799                         switch_core_file_close(&dh->fh);
00800 
00801                         if (session && (channel = switch_core_session_get_channel(session))) {
00802                                 switch_channel_set_private(channel, dh->file, NULL);
00803                         }
00804                 }
00805                 break;
00806         case SWITCH_ABC_TYPE_WRITE_REPLACE:
00807                 {
00808                         switch_frame_t *rframe = switch_core_media_bug_get_write_replace_frame(bug);
00809                         if (dh && !dh->mux) {
00810                                 memset(rframe->data, 255, rframe->datalen);
00811                         }
00812                         switch_core_media_bug_set_write_replace_frame(bug, rframe);
00813                 }
00814                 break;
00815         case SWITCH_ABC_TYPE_READ_REPLACE:
00816                 if (dh) {
00817                         switch_frame_t *rframe = NULL;
00818                         switch_size_t len;
00819                         switch_status_t st;
00820                         rframe = switch_core_media_bug_get_read_replace_frame(bug);
00821                         len = rframe->samples;
00822 
00823                         if (dh->mux) {
00824                                 int16_t buf[SWITCH_RECOMMENDED_BUFFER_SIZE / 2];
00825                                 int16_t *fp = rframe->data;
00826                                 uint32_t x;
00827 
00828                                 st = switch_core_file_read(&dh->fh, buf, &len);
00829 
00830                                 for (x = 0; x < (uint32_t) len; x++) {
00831                                         int32_t mixed = fp[x] + buf[x];
00832                                         switch_normalize_to_16bit(mixed);
00833                                         fp[x] = (int16_t) mixed;
00834                                 }
00835                         } else {
00836                                 st = switch_core_file_read(&dh->fh, rframe->data, &len);
00837                                 rframe->samples = (uint32_t) len;
00838                                 rframe->datalen = rframe->samples * 2;
00839                         }
00840 
00841                         if (st != SWITCH_STATUS_SUCCESS || len == 0) {
00842                                 if (dh->loop) {
00843                                         uint32_t pos = 0;
00844                                         switch_core_file_seek(&dh->fh, &pos, 0, SEEK_SET);
00845                                 } else {
00846                                         switch_core_session_t *session = switch_core_media_bug_get_session(bug);
00847                                         switch_channel_t *channel;
00848 
00849                                         if (session && (channel = switch_core_session_get_channel(session))) {
00850                                                 switch_channel_set_private(channel, dh->file, NULL);
00851                                         }
00852                                         return SWITCH_FALSE;
00853                                 }
00854                         }
00855 
00856                         switch_core_media_bug_set_read_replace_frame(bug, rframe);
00857                 }
00858                 break;
00859         case SWITCH_ABC_TYPE_WRITE:
00860         default:
00861                 break;
00862         }
00863 
00864         return SWITCH_TRUE;
00865 }

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

Definition at line 996 of file switch_ivr_async.c.

References switch_frame::buflen, switch_stream_handle::data, switch_frame::data, switch_frame::datalen, record_helper::fh, record_helper::file, record_helper::hangup_on_error, record_helper::min_sec, switch_file_handle::samplerate, switch_file_handle::samples_out, SWITCH_ABC_TYPE_CLOSE, SWITCH_ABC_TYPE_INIT, SWITCH_ABC_TYPE_READ_PING, SWITCH_ABC_TYPE_WRITE, switch_api_execute(), SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER, switch_channel_event_set_data(), 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_media_bug_get_session(), switch_core_media_bug_read(), switch_core_session_execute_application, 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_EVENT_RECORD_STOP, SWITCH_FALSE, switch_file_remove(), SWITCH_LOG_DEBUG, SWITCH_LOG_ERROR, switch_log_printf(), SWITCH_RECOMMENDED_BUFFER_SIZE, switch_safe_free, SWITCH_STACK_BOTTOM, SWITCH_STANDARD_STREAM, SWITCH_STATUS_BREAK, SWITCH_STATUS_SUCCESS, and SWITCH_TRUE.

Referenced by switch_ivr_record_session(), and switch_ivr_stop_record_session().

00997 {
00998         switch_core_session_t *session = switch_core_media_bug_get_session(bug);
00999         switch_channel_t *channel = switch_core_session_get_channel(session);
01000         struct record_helper *rh = (struct record_helper *) user_data;
01001         switch_event_t *event;
01002 
01003 
01004         switch (type) {
01005         case SWITCH_ABC_TYPE_INIT:
01006                 if (switch_event_create(&event, SWITCH_EVENT_RECORD_START) == SWITCH_STATUS_SUCCESS) {
01007                         switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Record-File-Path", rh->file);
01008                         switch_channel_event_set_data(channel, event);
01009                         switch_event_fire(&event);
01010                 }
01011 
01012                 break;
01013         case SWITCH_ABC_TYPE_CLOSE:
01014                 {
01015                         const char *var;
01016 
01017                         switch_codec_implementation_t read_impl = { 0 };
01018                         switch_core_session_get_read_impl(session, &read_impl);
01019 
01020                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Stop recording file %s\n", rh->file);
01021                         switch_channel_set_private(channel, rh->file, NULL);
01022 
01023                         if (rh->fh) {
01024                                 switch_size_t len;
01025                                 uint8_t data[SWITCH_RECOMMENDED_BUFFER_SIZE];
01026                                 switch_frame_t frame = { 0 };
01027 
01028                                 frame.data = data;
01029                                 frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE;
01030 
01031                                 while (switch_core_media_bug_read(bug, &frame, SWITCH_TRUE) == SWITCH_STATUS_SUCCESS) {
01032                                         len = (switch_size_t) frame.datalen / 2;
01033 
01034                                         if (len && switch_core_file_write(rh->fh, data, &len) != SWITCH_STATUS_SUCCESS && rh->hangup_on_error) {
01035                                                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error writing %s\n", rh->file);
01036                                                 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
01037                                                 switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
01038                                                 return SWITCH_FALSE;
01039                                         }
01040                                 }
01041 
01042 
01043                                 switch_core_file_close(rh->fh);
01044                                 if (rh->fh->samples_out < rh->fh->samplerate * rh->min_sec) {
01045                                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Discarding short file %s\n", rh->file);
01046                                         switch_channel_set_variable(channel, "RECORD_DISCARDED", "true");
01047                                         switch_file_remove(rh->file, switch_core_session_get_pool(session));
01048                                 }
01049                         }
01050 
01051                         if (switch_event_create(&event, SWITCH_EVENT_RECORD_STOP) == SWITCH_STATUS_SUCCESS) {
01052                                 switch_channel_event_set_data(channel, event);
01053                                 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Record-File-Path", rh->file);
01054                                 switch_event_fire(&event);
01055                         }
01056 
01057                         if ((var = switch_channel_get_variable(channel, "record_post_process_exec_app"))) {
01058                                 char *app = switch_core_session_strdup(session, var);
01059                                 char *data;
01060 
01061                                 if ((data = strchr(app, ':'))) {
01062                                         *data++ = '\0';
01063                                 }
01064 
01065                                 switch_core_session_execute_application(session, app, data);
01066                         }
01067 
01068                         if ((var = switch_channel_get_variable(channel, "record_post_process_exec_api"))) {
01069                                 char *cmd = switch_core_session_strdup(session, var);
01070                                 char *data, *expanded = NULL;
01071                                 switch_stream_handle_t stream = { 0 };
01072 
01073                                 SWITCH_STANDARD_STREAM(stream);
01074 
01075                                 if ((data = strchr(cmd, ':'))) {
01076                                         *data++ = '\0';
01077                                         expanded = switch_channel_expand_variables(channel, data);
01078                                 }
01079 
01080                                 switch_api_execute(cmd, expanded, session, &stream);
01081 
01082                                 if (expanded && expanded != data) {
01083                                         free(expanded);
01084                                 }
01085 
01086                                 switch_safe_free(stream.data);
01087 
01088                         }
01089 
01090 
01091                 }
01092 
01093                 break;
01094         case SWITCH_ABC_TYPE_READ_PING:
01095 
01096                 if (rh->fh) {
01097                         switch_size_t len;
01098                         uint8_t data[SWITCH_RECOMMENDED_BUFFER_SIZE];
01099                         switch_frame_t frame = { 0 };
01100                         switch_status_t status;
01101 
01102                         frame.data = data;
01103                         frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE;
01104 
01105 
01106                         status = switch_core_media_bug_read(bug, &frame, SWITCH_FALSE);
01107 
01108                         if (status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK) {
01109                                 len = (switch_size_t) frame.datalen / 2;
01110 
01111                                 if (len && switch_core_file_write(rh->fh, data, &len) != SWITCH_STATUS_SUCCESS && rh->hangup_on_error) {
01112                                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error writing %s\n", rh->file);
01113                                         switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
01114                                         switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
01115                                         return SWITCH_FALSE;
01116                                 }
01117                         }
01118 
01119                                 
01120                 }
01121                 break;
01122         case SWITCH_ABC_TYPE_WRITE:
01123         default:
01124                 break;
01125         }
01126 
01127         return SWITCH_TRUE;
01128 }

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

Definition at line 2220 of file switch_ivr_async.c.

References switch_frame::data, switch_frame::datalen, 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_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_generate_sln_silence(), SWITCH_TRUE, switch_session_audio_t::write_level, and switch_session_audio_t::write_mute.

Referenced by switch_ivr_session_audio().

02221 {
02222         switch_session_audio_t *pvt = (switch_session_audio_t *) user_data;
02223         switch_frame_t *frame = NULL;
02224         int level = 0, mute = 0;
02225 
02226 
02227         if (type == SWITCH_ABC_TYPE_READ_REPLACE || type == SWITCH_ABC_TYPE_WRITE_REPLACE) {
02228                 if (!(pvt->read_level || pvt->write_level || pvt->read_mute || pvt->write_mute)) {
02229                         switch_channel_set_private(switch_core_session_get_channel(pvt->session), "__audio", NULL);
02230                         return SWITCH_FALSE;
02231                 }
02232         }
02233 
02234         if (type == SWITCH_ABC_TYPE_READ_REPLACE) {
02235                 level = pvt->read_level;
02236                 mute = pvt->read_mute;
02237                 frame = switch_core_media_bug_get_read_replace_frame(bug);
02238         } else if (type == SWITCH_ABC_TYPE_WRITE_REPLACE) {
02239                 level = pvt->write_level;
02240                 mute = pvt->write_mute;
02241                 frame = switch_core_media_bug_get_write_replace_frame(bug);
02242         }
02243 
02244         if (frame) {
02245                 if (mute) {
02246                         if (mute > 1) {
02247                                 switch_generate_sln_silence(frame->data, frame->datalen / 2, mute);
02248                         } else {
02249                                 memset(frame->data, 0, frame->datalen);
02250                         }
02251                 } else if (level) {
02252                         switch_change_sln_volume(frame->data, frame->datalen / 2, level);
02253                 }
02254 
02255                 if (type == SWITCH_ABC_TYPE_READ_REPLACE) {
02256                         switch_core_media_bug_set_read_replace_frame(bug, frame);
02257                 } else if (type == SWITCH_ABC_TYPE_WRITE_REPLACE) {
02258                         switch_core_media_bug_set_write_replace_frame(bug, frame);
02259                 }
02260         }
02261 
02262         return SWITCH_TRUE;
02263 }

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

Definition at line 3585 of file switch_ivr_async.c.

References speech_thread_handle::ah, switch_frame::buflen, speech_thread_handle::bug, 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_unlock(), SWITCH_RECOMMENDED_BUFFER_SIZE, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_thread_cond_signal(), switch_thread_create(), SWITCH_THREAD_STACKSIZE, switch_threadattr_create(), switch_threadattr_detach_set(), switch_threadattr_stacksize_set(), and SWITCH_TRUE.

Referenced by switch_ivr_detect_speech().

03586 {
03587         struct speech_thread_handle *sth = (struct speech_thread_handle *) user_data;
03588         uint8_t data[SWITCH_RECOMMENDED_BUFFER_SIZE];
03589         switch_frame_t frame = { 0 };
03590         switch_asr_flag_t flags = SWITCH_ASR_FLAG_NONE;
03591 
03592         frame.data = data;
03593         frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE;
03594 
03595         switch (type) {
03596         case SWITCH_ABC_TYPE_INIT:{
03597                         switch_thread_t *thread;
03598                         switch_threadattr_t *thd_attr = NULL;
03599 
03600                         switch_threadattr_create(&thd_attr, sth->pool);
03601                         switch_threadattr_detach_set(thd_attr, 1);
03602                         switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
03603                         switch_thread_create(&thread, thd_attr, speech_thread, sth, sth->pool);
03604                 }
03605                 break;
03606         case SWITCH_ABC_TYPE_CLOSE:{
03607                         switch_core_asr_close(sth->ah, &flags);
03608                         if (sth->mutex && sth->cond && sth->ready) {
03609                                 switch_mutex_lock(sth->mutex);
03610                                 switch_thread_cond_signal(sth->cond);
03611                                 switch_mutex_unlock(sth->mutex);
03612                         }
03613                 }
03614                 break;
03615         case SWITCH_ABC_TYPE_READ:
03616                 if (sth->ah) {
03617                         if (switch_core_media_bug_read(bug, &frame, SWITCH_FALSE) != SWITCH_STATUS_FALSE) {
03618                                 if (switch_core_asr_feed(sth->ah, frame.data, frame.datalen, &flags) != SWITCH_STATUS_SUCCESS) {
03619                                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(switch_core_media_bug_get_session(bug)), SWITCH_LOG_DEBUG, "Error Feeding Data\n");
03620                                         return SWITCH_FALSE;
03621                                 }
03622                                 if (switch_core_asr_check_results(sth->ah, &flags) == SWITCH_STATUS_SUCCESS) {
03623                                         if (sth->mutex && sth->cond && sth->ready) {
03624                                                 switch_mutex_lock(sth->mutex);
03625                                                 switch_thread_cond_signal(sth->cond);
03626                                                 switch_mutex_unlock(sth->mutex);
03627                                         }
03628                                 }
03629                         }
03630                 }
03631                 break;
03632         case SWITCH_ABC_TYPE_WRITE:
03633         default:
03634                 break;
03635         }
03636 
03637         return SWITCH_TRUE;
03638 }

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 3640 of file switch_ivr_async.c.

References speech_thread_handle::ah, speech_thread_handle::session, 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(), and switch_ivr_stop_detect_speech().

03641 {
03642         switch_channel_t *channel = switch_core_session_get_channel(session);
03643         struct speech_thread_handle *sth = switch_channel_get_private(channel, SWITCH_SPEECH_KEY);
03644         switch_status_t status = SWITCH_STATUS_SUCCESS;
03645         switch_asr_flag_t flags = SWITCH_ASR_FLAG_NONE;
03646 
03647         if (sth) {
03648                 if (switch_core_asr_feed_dtmf(sth->ah, dtmf, &flags) != SWITCH_STATUS_SUCCESS) {
03649                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error Feeding DTMF\n");
03650                 }
03651         }
03652 
03653         return status;
03654 }

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

Definition at line 3468 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_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_DETECTED_SPEECH, switch_event_dup(), switch_event_fire, 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().

03469 {
03470         struct speech_thread_handle *sth = (struct speech_thread_handle *) obj;
03471         switch_channel_t *channel = switch_core_session_get_channel(sth->session);
03472         switch_asr_flag_t flags = SWITCH_ASR_FLAG_NONE;
03473         switch_status_t status;
03474 
03475         switch_thread_cond_create(&sth->cond, sth->pool);
03476         switch_mutex_init(&sth->mutex, SWITCH_MUTEX_NESTED, sth->pool);
03477 
03478         if (switch_core_session_read_lock(sth->session) != SWITCH_STATUS_SUCCESS) {
03479                 sth->ready = 0;
03480                 return NULL;
03481         }
03482 
03483         switch_mutex_lock(sth->mutex);
03484 
03485         sth->ready = 1;
03486 
03487         while (switch_channel_up_nosig(channel) && !switch_test_flag(sth->ah, SWITCH_ASR_FLAG_CLOSED)) {
03488                 char *xmlstr = NULL;
03489 
03490                 switch_thread_cond_wait(sth->cond, sth->mutex);
03491 
03492                 if (switch_channel_down_nosig(channel) || switch_test_flag(sth->ah, SWITCH_ASR_FLAG_CLOSED)) {
03493                         break;
03494                 }
03495 
03496                 if (switch_core_asr_check_results(sth->ah, &flags) == SWITCH_STATUS_SUCCESS) {
03497                         switch_event_t *event;
03498 
03499                         status = switch_core_asr_get_results(sth->ah, &xmlstr, &flags);
03500 
03501                         if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) {
03502                                 goto done;
03503                         }
03504 
03505                         if (status == SWITCH_STATUS_SUCCESS && switch_true(switch_channel_get_variable(channel, "asr_intercept_dtmf"))) {
03506                                 const char *p;
03507                                 
03508                                 if ((p = switch_stristr("<input>", xmlstr))) {
03509                                         p += 7;
03510                                 }
03511 
03512                                 while (p && *p) {
03513                                         char c;
03514 
03515                                         if (*p == '<') {
03516                                                 break;
03517                                         }
03518 
03519                                         if (!strncasecmp(p, "pound", 5)) {
03520                                                 c = '#';
03521                                                 p += 5;
03522                                         } else if (!strncasecmp(p, "hash", 4)) {
03523                                                 c = '#';
03524                                                 p += 4;
03525                                         } else if (!strncasecmp(p, "star", 4)) {
03526                                                 c = '*';
03527                                                 p += 4;
03528                                         } else if (!strncasecmp(p, "asterisk", 8)) {
03529                                                 c = '*';
03530                                                 p += 8;
03531                                         } else {
03532                                                 c = *p;
03533                                                 p++;
03534                                         }
03535 
03536                                         if (is_dtmf(c)) {
03537                                                 switch_dtmf_t dtmf = {0};
03538                                                 dtmf.digit = c;
03539                                                 dtmf.duration = switch_core_default_dtmf_duration(0);
03540                                                 dtmf.source = SWITCH_DTMF_INBAND_AUDIO;
03541                                                 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "Queue speech detected dtmf %c\n", c);
03542                                                 switch_channel_queue_dtmf(channel, &dtmf);
03543                                         }
03544 
03545                                 }
03546                                 switch_ivr_resume_detect_speech(sth->session);
03547                         }
03548 
03549                         if (switch_event_create(&event, SWITCH_EVENT_DETECTED_SPEECH) == SWITCH_STATUS_SUCCESS) {
03550                                 if (status == SWITCH_STATUS_SUCCESS) {
03551                                         switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Speech-Type", "detected-speech");
03552                                         switch_event_add_body(event, "%s", xmlstr);
03553                                 } else {
03554                                         switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Speech-Type", "begin-speaking");
03555                                 }
03556 
03557                                 if (switch_test_flag(sth->ah, SWITCH_ASR_FLAG_FIRE_EVENTS)) {
03558                                         switch_event_t *dup;
03559 
03560                                         if (switch_event_dup(&dup, event) == SWITCH_STATUS_SUCCESS) {
03561                                                 switch_channel_event_set_data(channel, dup);
03562                                                 switch_event_fire(&dup);
03563                                         }
03564 
03565                                 }
03566 
03567                                 if (switch_core_session_queue_event(sth->session, &event) != SWITCH_STATUS_SUCCESS) {
03568                                         switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_ERROR, "Event queue failed!\n");
03569                                         switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "delivery-failure", "true");
03570                                         switch_event_fire(&event);
03571                                 }
03572                         }
03573 
03574                         switch_safe_free(xmlstr);
03575                 }
03576         }
03577   done:
03578 
03579         switch_mutex_unlock(sth->mutex);
03580         switch_core_session_rwunlock(sth->session);
03581 
03582         return NULL;
03583 }

static dm_match_t switch_ivr_dmachine_check_match ( switch_ivr_dmachine_t dmachine,
switch_bool_t  is_timeout 
) [static]

Definition at line 304 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_regex_match(), switch_set_string, and SWITCH_STATUS_SUCCESS.

Referenced by switch_ivr_dmachine_ping().

00305 {
00306         dm_match_t best = DM_MATCH_NONE;
00307         switch_ivr_dmachine_binding_t *bp, *exact_bp = NULL, *partial_bp = NULL, *both_bp = NULL, *r_bp = NULL;
00308         int pmatches = 0;
00309         
00310         if (!dmachine->cur_digit_len || !dmachine->realm) goto end;
00311 
00312         for(bp = dmachine->realm->binding_list; bp; bp = bp->next) {
00313                 if (bp->is_regex) {
00314                         switch_status_t r_status = switch_regex_match(dmachine->digits, bp->digits);
00315                         pmatches = 1;
00316 
00317                         if (r_status == SWITCH_STATUS_SUCCESS) {
00318                                 if (is_timeout || (bp == dmachine->realm->binding_list && !bp->next)) {
00319                                         best = DM_MATCH_EXACT;
00320                                         exact_bp = bp;
00321                                         break;
00322                                 }
00323                                 best = DM_MATCH_PARTIAL;
00324                         }
00325                 } else {
00326                         int pmatch = !strncmp(dmachine->digits, bp->digits, strlen(dmachine->digits));
00327 
00328                         if (pmatch) {
00329                                 pmatches++;
00330                         }
00331 
00332                         if (!exact_bp && pmatch && !strcmp(bp->digits, dmachine->digits)) {
00333                                 best = DM_MATCH_EXACT;
00334                                 exact_bp = bp;
00335                                 if (dmachine->cur_digit_len == dmachine->max_digit_len) break;
00336                         } 
00337 
00338                         if (!(both_bp && partial_bp) && strlen(bp->digits) != strlen(dmachine->digits) && pmatch) {
00339                                 
00340                                 if (exact_bp) {
00341                                         best = DM_MATCH_BOTH;
00342                                         both_bp = bp;
00343                                 } else {
00344                                         best = DM_MATCH_PARTIAL;
00345                                         partial_bp = bp;
00346                                 }
00347                         }
00348 
00349                         if (both_bp && exact_bp && partial_bp) break;
00350                 }
00351         }
00352 
00353         if (!pmatches) {
00354                 best = DM_MATCH_NEVER;
00355         }
00356 
00357         
00358  end:
00359 
00360         if (is_timeout) {
00361                 if (both_bp) {
00362                         r_bp = exact_bp ? exact_bp : both_bp;
00363                 }
00364         } 
00365 
00366         if (best == DM_MATCH_EXACT && exact_bp) {
00367                 r_bp = exact_bp;
00368         }
00369         
00370         
00371         if (r_bp) {
00372                 dmachine->last_matching_binding = r_bp;
00373                 switch_set_string(dmachine->last_matching_digits, dmachine->digits);
00374                 best = DM_MATCH_EXACT;
00375         }
00376 
00377         return best;
00378         
00379 }

static switch_bool_t switch_ivr_dmachine_check_timeout ( switch_ivr_dmachine_t dmachine  )  [static]

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

00382 {
00383         switch_time_t now = switch_time_now();
00384         uint32_t timeout = dmachine->cur_digit_len ? dmachine->digit_timeout_ms : dmachine->input_timeout_ms;
00385 
00386         if (!dmachine->last_digit_time) dmachine->last_digit_time = now;
00387 
00388         if (timeout) {
00389                 if ((uint32_t)((now - dmachine->last_digit_time) / 1000) > timeout) {
00390                         return SWITCH_TRUE;
00391                 }
00392         }
00393 
00394         return SWITCH_FALSE;
00395 }

SWITCH_STANDARD_SCHED_FUNC ( sch_broadcast_callback   ) 

Definition at line 4000 of file switch_ivr_async.c.

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

04001 {
04002         struct broadcast_helper *helper;
04003         switch_assert(task);
04004 
04005         helper = (struct broadcast_helper *) task->cmd_arg;
04006         switch_ivr_broadcast(helper->uuid_str, helper->path, helper->flags);
04007 }

SWITCH_STANDARD_SCHED_FUNC ( sch_transfer_callback   ) 

Definition at line 3933 of file switch_ivr_async.c.

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

03934 {
03935         struct transfer_helper *helper;
03936         switch_core_session_t *session;
03937 
03938         switch_assert(task);
03939 
03940         helper = (struct transfer_helper *) task->cmd_arg;
03941 
03942         if ((session = switch_core_session_locate(helper->uuid_str))) {
03943                 switch_ivr_session_transfer(session, helper->extension, helper->dialplan, helper->context);
03944                 switch_core_session_rwunlock(session);
03945         }
03946 
03947 }

SWITCH_STANDARD_SCHED_FUNC ( sch_hangup_callback   ) 

Definition at line 3883 of file switch_ivr_async.c.

References hangup_helper::bleg, hangup_helper::cause, 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.

03884 {
03885         struct hangup_helper *helper;
03886         switch_core_session_t *session, *other_session;
03887         const char *other_uuid;
03888 
03889         switch_assert(task);
03890 
03891         helper = (struct hangup_helper *) task->cmd_arg;
03892 
03893         if ((session = switch_core_session_locate(helper->uuid_str))) {
03894                 switch_channel_t *channel = switch_core_session_get_channel(session);
03895 
03896                 if (helper->bleg) {
03897                         if ((other_uuid = switch_channel_get_variable(channel, SWITCH_BRIDGE_VARIABLE)) && (other_session = switch_core_session_locate(other_uuid))) {
03898                                 switch_channel_t *other_channel = switch_core_session_get_channel(other_session);
03899                                 switch_channel_hangup(other_channel, helper->cause);
03900                                 switch_core_session_rwunlock(other_session);
03901                         } else {
03902                                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "No channel to hangup\n");
03903                         }
03904                 } else {
03905                         switch_channel_hangup(channel, helper->cause);
03906                 }
03907 
03908                 switch_core_session_rwunlock(session);
03909         }
03910 }

static int teletone_dtmf_generate_handler ( teletone_generation_session_t ts,
teletone_tone_map_t map 
) [static]

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

02451 {
02452         switch_buffer_t *audio_buffer = ts->user_data;
02453         int wrote;
02454 
02455         if (!audio_buffer) {
02456                 return -1;
02457         }
02458 
02459         wrote = teletone_mux_tones(ts, map);
02460         switch_buffer_write(audio_buffer, ts->buffer, wrote * 2);
02461 
02462         return 0;
02463 }

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

Definition at line 2730 of file switch_ivr_async.c.

References skip(), SWITCH_ABC_TYPE_CLOSE, SWITCH_ABC_TYPE_INIT, SWITCH_ABC_TYPE_READ_REPLACE, SWITCH_ABC_TYPE_WRITE_REPLACE, switch_core_media_bug_get_read_replace_frame(), switch_core_media_bug_get_write_replace_frame(), and SWITCH_TRUE.

02731 {
02732         switch_tone_container_t *cont = (switch_tone_container_t *) user_data;
02733         switch_frame_t *frame = NULL;
02734         int i = 0;
02735         switch_bool_t rval = SWITCH_TRUE;
02736 
02737         switch (type) {
02738         case SWITCH_ABC_TYPE_INIT:
02739                 if (cont) {
02740                         cont->bug_running = 1;
02741                 }
02742                 break;
02743         case SWITCH_ABC_TYPE_CLOSE:
02744                 break;
02745         case SWITCH_ABC_TYPE_READ_REPLACE:
02746         case SWITCH_ABC_TYPE_WRITE_REPLACE:
02747                 {
02748                         
02749                         if (type == SWITCH_ABC_TYPE_READ_REPLACE) {
02750                                 frame = switch_core_media_bug_get_read_replace_frame(bug);
02751                         } else {
02752                                 frame = switch_core_media_bug_get_write_replace_frame(bug);
02753                         }
02754 
02755                         for (i = 0; i < cont->index; i++) {
02756                                 int skip = 0;
02757 
02758                                 if (cont->list[i].sleep) {
02759                                         cont->list[i].sleep--;
02760                                         if (cont->list[i].sleep) {
02761                                                 skip = 1;
02762                                         }
02763                                 }
02764 
02765                                 if (cont->list[i].expires) {
02766                                         cont->list[i].expires--;
02767                                         if (!cont->list[i].expires) {
02768                                                 cont->list[i].hits = 0;
02769                                                 cont->list[i].sleep = 0;
02770                                                 cont->list[i].expires = 0;
02771                                         }
02772                                 }
02773 
02774                                 if (!cont->list[i].up)
02775                                         skip = 1;
02776 
02777                                 if (skip)
02778                                         continue;
02779 
02780                                 if (teletone_multi_tone_detect(&cont->list[i].mt, frame->data, frame->samples)) {
02781                                         switch_event_t *event;
02782                                         cont->list[i].hits++;
02783 
02784                                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(switch_core_media_bug_get_session(bug)), SWITCH_LOG_DEBUG, "TONE %s HIT %d/%d\n",
02785                                                                           cont->list[i].key, cont->list[i].hits, cont->list[i].total_hits);
02786                                         cont->list[i].sleep = cont->list[i].default_sleep;
02787                                         cont->list[i].expires = cont->list[i].default_expires;
02788 
02789                                         if (cont->list[i].hits >= cont->list[i].total_hits) {
02790                                                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(switch_core_media_bug_get_session(bug)), SWITCH_LOG_DEBUG, "TONE %s DETECTED\n",
02791                                                                                   cont->list[i].key);
02792                                                 cont->list[i].up = 0;
02793 
02794                                                 if (cont->list[i].callback) {
02795                                                         if ((rval = cont->list[i].callback(cont->session, cont->list[i].app, cont->list[i].data)) == SWITCH_TRUE) {
02796                                                                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(switch_core_media_bug_get_session(bug)), SWITCH_LOG_DEBUG, "Re-enabling %s\n",
02797                                                                                                   cont->list[i].key);
02798                                                                 cont->list[i].up = 1;
02799                                                                 cont->list[i].hits = 0;
02800                                                                 cont->list[i].sleep = 0;
02801                                                                 cont->list[i].expires = 0;
02802                                                         }
02803                                                 } else {
02804                                                         switch_channel_execute_on(switch_core_session_get_channel(cont->session), SWITCH_CHANNEL_EXECUTE_ON_TONE_DETECT_VARIABLE);
02805                                                         if (cont->list[i].app) {
02806                                                                 switch_core_session_execute_application_async(cont->session, cont->list[i].app, cont->list[i].data);
02807                                                         }
02808                                                 }
02809 
02810                                                 if (cont->list[i].once) {
02811                                                         rval = SWITCH_FALSE;
02812                                                 }
02813 
02814                                                 if (switch_event_create(&event, SWITCH_EVENT_DETECTED_TONE) == SWITCH_STATUS_SUCCESS) {
02815                                                         switch_event_t *dup;
02816                                                         switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Detected-Tone", cont->list[i].key);
02817 
02818                                                         if (switch_event_dup(&dup, event) == SWITCH_STATUS_SUCCESS) {
02819                                                                 switch_event_fire(&dup);
02820                                                         }
02821 
02822                                                         if (switch_core_session_queue_event(cont->session, &event) != SWITCH_STATUS_SUCCESS) {
02823                                                                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(switch_core_media_bug_get_session(bug)), SWITCH_LOG_ERROR,
02824                                                                                                   "Event queue failed!\n");
02825                                                                 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "delivery-failure", "true");
02826                                                                 switch_event_fire(&event);
02827                                                         }
02828                                                 }
02829                                         }
02830                                 }
02831                         }
02832                 }
02833                 break;
02834         case SWITCH_ABC_TYPE_WRITE:
02835         default:
02836                 break;
02837         }
02838 
02839         if (rval == SWITCH_FALSE) {
02840                 cont->bug_running = 0;
02841         }
02842 
02843         return rval;
02844 }

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 2702 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(), and SWITCH_STATUS_SUCCESS.

02703 {
02704         switch_channel_t *channel = switch_core_session_get_channel(session);
02705         switch_tone_container_t *cont = switch_channel_get_private(channel, "_tone_detect_");
02706         int i;
02707 
02708         if (!cont || !cont->detect_fax || dtmf->digit != 'f') {
02709                 return SWITCH_STATUS_SUCCESS;
02710         }
02711 
02712         i = cont->detect_fax;
02713 
02714         if (cont->list[i].callback) {
02715                 cont->list[i].callback(cont->session, cont->list[i].app, cont->list[i].data);
02716         } else {
02717                 switch_channel_execute_on(switch_core_session_get_channel(cont->session), SWITCH_CHANNEL_EXECUTE_ON_TONE_DETECT_VARIABLE);
02718                 switch_channel_api_on(switch_core_session_get_channel(cont->session), SWITCH_CHANNEL_API_ON_TONE_DETECT_VARIABLE);
02719 
02720                 if (cont->list[i].app) {
02721                         switch_core_session_execute_application_async(cont->session, cont->list[i].app, cont->list[i].data);
02722                 }
02723         }
02724                 
02725         return SWITCH_STATUS_SUCCESS;
02726 
02727 }

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

Definition at line 706 of file switch_ivr_async.c.

References buf, switch_frame::data, switch_frame::datalen, displace_helper_t::fh, displace_helper_t::file, displace_helper_t::loop, 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().

00707 {
00708         displace_helper_t *dh = (displace_helper_t *) user_data;
00709 
00710         switch (type) {
00711         case SWITCH_ABC_TYPE_INIT:
00712                 break;
00713         case SWITCH_ABC_TYPE_CLOSE:
00714                 if (dh) {
00715                         switch_core_session_t *session = switch_core_media_bug_get_session(bug);
00716                         switch_channel_t *channel;
00717 
00718                         switch_core_file_close(&dh->fh);
00719 
00720                         if (session && (channel = switch_core_session_get_channel(session))) {
00721                                 switch_channel_set_private(channel, dh->file, NULL);
00722                         }
00723                 }
00724                 break;
00725         case SWITCH_ABC_TYPE_READ_REPLACE:
00726                 {
00727                         switch_frame_t *rframe = switch_core_media_bug_get_read_replace_frame(bug);
00728                         if (dh && !dh->mux) {
00729                                 memset(rframe->data, 255, rframe->datalen);
00730                         }
00731                         switch_core_media_bug_set_read_replace_frame(bug, rframe);
00732                 }
00733                 break;
00734         case SWITCH_ABC_TYPE_WRITE_REPLACE:
00735                 if (dh) {
00736                         switch_frame_t *rframe = NULL;
00737                         switch_size_t len;
00738                         switch_status_t st;
00739 
00740                         rframe = switch_core_media_bug_get_write_replace_frame(bug);
00741                         len = rframe->samples;
00742 
00743                         if (dh->mux) {
00744                                 int16_t buf[SWITCH_RECOMMENDED_BUFFER_SIZE / 2];
00745                                 int16_t *fp = rframe->data;
00746                                 uint32_t x;
00747 
00748                                 st = switch_core_file_read(&dh->fh, buf, &len);
00749 
00750                                 for (x = 0; x < (uint32_t) len; x++) {
00751                                         int32_t mixed = fp[x] + buf[x];
00752                                         switch_normalize_to_16bit(mixed);
00753                                         fp[x] = (int16_t) mixed;
00754                                 }
00755                         } else {
00756                                 st = switch_core_file_read(&dh->fh, rframe->data, &len);
00757                                 rframe->samples = (uint32_t) len;
00758                                 rframe->datalen = rframe->samples * 2;
00759                         }
00760 
00761                         if (st != SWITCH_STATUS_SUCCESS || len == 0) {
00762                                 if (dh->loop) {
00763                                         uint32_t pos = 0;
00764                                         switch_core_file_seek(&dh->fh, &pos, 0, SEEK_SET);
00765                                 } else {
00766                                         switch_core_session_t *session = switch_core_media_bug_get_session(bug);
00767                                         switch_channel_t *channel;
00768 
00769                                         if (session && (channel = switch_core_session_get_channel(session))) {
00770                                                 switch_channel_set_private(channel, dh->file, NULL);
00771                                         }
00772                                         return SWITCH_FALSE;
00773                                 }
00774                         }
00775 
00776                         switch_core_media_bug_set_write_replace_frame(bug, rframe);
00777                 }
00778                 break;
00779         case SWITCH_ABC_TYPE_WRITE:
00780         default:
00781                 break;
00782         }
00783 
00784         return SWITCH_TRUE;
00785 }


Generated on Sun May 20 04:00:11 2012 for FreeSWITCH API Documentation by  doxygen 1.4.7