#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.
| #define MAX_TONES 16 |
| #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 struct switch_ivr_dmachine_binding switch_ivr_dmachine_binding_t |
Definition at line 48 of file switch_ivr_async.c.
| enum dm_match_t |
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;
| 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 }
1.4.7