IVR Menu Library
[IVR Library]

Collaboration diagram for IVR Menu Library:

Defines

#define switch_ivr_phrase_macro(session, macro_name, data, lang, args)   switch_ivr_phrase_macro_event(session, macro_name, data, NULL, lang, args)

Typedefs

typedef switch_ivr_action_t switch_ivr_menu_action_function_t (struct switch_ivr_menu *, char *, char *, size_t, void *)
typedef switch_ivr_menu switch_ivr_menu_t
typedef switch_ivr_menu_action switch_ivr_menu_action_t
typedef switch_ivr_menu_xml_ctx switch_ivr_menu_xml_ctx_t

Enumerations

enum  switch_ivr_menu_flags { SWITCH_IVR_MENU_FLAG_FALLTOMAIN = (1 << 0), SWITCH_IVR_MENU_FLAG_FREEPOOL = (1 << 1), SWITCH_IVR_MENU_FLAG_STACK = (1 << 2) }
enum  switch_ivr_action_t {
  SWITCH_IVR_ACTION_DIE, SWITCH_IVR_ACTION_EXECMENU, SWITCH_IVR_ACTION_EXECAPP, SWITCH_IVR_ACTION_PLAYSOUND,
  SWITCH_IVR_ACTION_BACK, SWITCH_IVR_ACTION_TOMAIN, SWITCH_IVR_ACTION_NOOP
}

Functions

switch_status_t switch_ivr_menu_init (switch_ivr_menu_t **new_menu, switch_ivr_menu_t *main, const char *name, const char *greeting_sound, const char *short_greeting_sound, const char *invalid_sound, const char *exit_sound, const char *confirm_macro, const char *confirm_key, const char *tts_engine, const char *tts_voice, int confirm_attempts, int inter_timeout, int digit_len, int timeout, int max_failures, int max_timeouts, switch_memory_pool_t *pool)
 Create a new menu object.
switch_status_t switch_ivr_menu_bind_action (switch_ivr_menu_t *menu, switch_ivr_action_t ivr_action, const char *arg, const char *bind)
 switch_ivr_menu_bind_action: Bind a keystroke to an action.
switch_status_t switch_ivr_menu_bind_function (switch_ivr_menu_t *menu, switch_ivr_menu_action_function_t *function, const char *arg, const char *bind)
 Bind a keystroke to a callback function.
switch_status_t switch_ivr_menu_execute (switch_core_session_t *session, switch_ivr_menu_t *stack, char *name, void *obj)
 Execute a menu.
switch_status_t switch_ivr_menu_stack_free (switch_ivr_menu_t *stack)
 free a stack of menu objects.
switch_status_t switch_ivr_menu_stack_xml_build (switch_ivr_menu_xml_ctx_t *xml_menu_ctx, switch_ivr_menu_t **menu_stack, switch_xml_t xml_menus, switch_xml_t xml_menu)
 Build a menu stack from an xml source.
switch_status_t switch_ivr_menu_str2action (const char *action_name, switch_ivr_action_t *action)
switch_status_t switch_ivr_menu_stack_xml_add_custom (switch_ivr_menu_xml_ctx_t *xml_menu_ctx, const char *name, switch_ivr_menu_action_function_t *function)
switch_status_t switch_ivr_menu_stack_xml_init (switch_ivr_menu_xml_ctx_t **xml_menu_ctx, switch_memory_pool_t *pool)
switch_status_t switch_ivr_phrase_macro_event (switch_core_session_t *session, const char *macro_name, const char *data, switch_event_t *event, const char *lang, switch_input_args_t *args)
void switch_ivr_delay_echo (switch_core_session_t *session, uint32_t delay_ms)
switch_status_t switch_ivr_find_bridged_uuid (const char *uuid, char *b_uuid, switch_size_t blen)
void switch_ivr_intercept_session (switch_core_session_t *session, const char *uuid, switch_bool_t bleg)
void switch_ivr_park_session (switch_core_session_t *session)
switch_status_t switch_ivr_wait_for_answer (switch_core_session_t *session, switch_core_session_t *peer_session)
switch_status_t switch_ivr_read (switch_core_session_t *session, uint32_t min_digits, uint32_t max_digits, const char *prompt_audio_file, const char *var_name, char *digit_buffer, switch_size_t digit_buffer_length, uint32_t timeout, const char *valid_terminators, uint32_t digit_timeout)
switch_status_t switch_ivr_block_dtmf_session (switch_core_session_t *session)
switch_status_t switch_ivr_unblock_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)
switch_status_t switch_ivr_unbind_dtmf_meta_session (switch_core_session_t *session, uint32_t key)
switch_status_t switch_ivr_soft_hold (switch_core_session_t *session, const char *unhold_key, const char *moh_a, const char *moh_b)
switch_status_t switch_ivr_say (switch_core_session_t *session, const char *tosay, const char *module_name, const char *say_type, const char *say_method, const char *say_gender, switch_input_args_t *args)
switch_status_t switch_ivr_say_string (switch_core_session_t *session, const char *lang, const char *ext, const char *tosay, const char *module_name, const char *say_type, const char *say_method, const char *say_gender, char **rstr)
switch_say_method_t switch_ivr_get_say_method_by_name (const char *name)
switch_say_gender_t switch_ivr_get_say_gender_by_name (const char *name)
switch_say_type_t switch_ivr_get_say_type_by_name (const char *name)
switch_status_t switch_ivr_say_spell (switch_core_session_t *session, char *tosay, switch_say_args_t *say_args, switch_input_args_t *args)
switch_status_t switch_ivr_say_ip (switch_core_session_t *session, char *tosay, switch_say_callback_t number_func, switch_say_args_t *say_args, switch_input_args_t *args)
switch_status_t switch_ivr_set_user (switch_core_session_t *session, const char *data)
switch_status_t switch_ivr_sound_test (switch_core_session_t *session)
void switch_process_import (switch_core_session_t *session, switch_channel_t *peer_channel, const char *varname, const char *prefix)
switch_bool_t switch_ivr_uuid_exists (const char *uuid)
switch_status_t switch_ivr_dmachine_last_ping (switch_ivr_dmachine_t *dmachine)
const char * switch_ivr_dmachine_get_name (switch_ivr_dmachine_t *dmachine)
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)
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, uint32_t input_timeout, switch_ivr_dmachine_callback_t match_callback, switch_ivr_dmachine_callback_t nonmatch_callback, void *user_data)
void switch_ivr_dmachine_destroy (switch_ivr_dmachine_t **dmachine)
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)
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)
switch_status_t switch_ivr_dmachine_ping (switch_ivr_dmachine_t *dmachine, switch_ivr_dmachine_match_t **match_p)
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)
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)
switch_status_t switch_ivr_dmachine_clear_realm (switch_ivr_dmachine_t *dmachine, const char *realm)
switch_status_t switch_ivr_dmachine_set_realm (switch_ivr_dmachine_t *dmachine, const char *realm)
switch_status_t switch_ivr_get_file_handle (switch_core_session_t *session, switch_file_handle_t **fh)
switch_status_t switch_ivr_release_file_handle (switch_core_session_t *session, switch_file_handle_t **fh)
switch_status_t switch_ivr_process_fh (switch_core_session_t *session, const char *cmd, switch_file_handle_t *fhp)
switch_status_t switch_ivr_insert_file (switch_core_session_t *session, const char *file, const char *insert_file, switch_size_t sample_point)
switch_status_t switch_ivr_create_message_reply (switch_event_t **reply, switch_event_t *message, const char *new_proto)
char * switch_ivr_check_presence_mapping (const char *exten_name, const char *domain_name)
switch_status_t switch_ivr_kill_uuid (const char *uuid, switch_call_cause_t cause)
switch_status_t switch_ivr_blind_transfer_ack (switch_core_session_t *session, switch_bool_t success)


Detailed Description

IVR menu functions

Define Documentation

#define switch_ivr_phrase_macro ( session,
macro_name,
data,
lang,
args   )     switch_ivr_phrase_macro_event(session, macro_name, data, NULL, lang, args)

Definition at line 872 of file switch_ivr.h.

Referenced by play_and_collect(), CoreSession::sayPhrase(), switch_ivr_eavesdrop_session(), switch_ivr_phrase_macro_event(), and switch_ivr_play_file().


Typedef Documentation

typedef switch_ivr_action_t switch_ivr_menu_action_function_t(struct switch_ivr_menu *, char *, char *, size_t, void *)

Definition at line 754 of file switch_ivr.h.

typedef struct switch_ivr_menu_action switch_ivr_menu_action_t

Definition at line 756 of file switch_ivr.h.

typedef struct switch_ivr_menu switch_ivr_menu_t

Definition at line 755 of file switch_ivr.h.

typedef struct switch_ivr_menu_xml_ctx switch_ivr_menu_xml_ctx_t

Definition at line 840 of file switch_ivr.h.


Enumeration Type Documentation

enum switch_ivr_action_t

Enumerator:
SWITCH_IVR_ACTION_DIE 
SWITCH_IVR_ACTION_EXECMENU 
SWITCH_IVR_ACTION_EXECAPP 
SWITCH_IVR_ACTION_PLAYSOUND 
SWITCH_IVR_ACTION_BACK 
SWITCH_IVR_ACTION_TOMAIN 
SWITCH_IVR_ACTION_NOOP 

Definition at line 744 of file switch_ivr.h.

00744                       {
00745                  SWITCH_IVR_ACTION_DIE, /* Exit the menu.                  */
00746                  SWITCH_IVR_ACTION_EXECMENU,    /* Goto another menu in the stack. */
00747                  SWITCH_IVR_ACTION_EXECAPP,     /* Execute an application.         */
00748                  SWITCH_IVR_ACTION_PLAYSOUND,   /* Play a sound.                   */
00749                  SWITCH_IVR_ACTION_BACK,        /* Go back 1 menu.                 */
00750                  SWITCH_IVR_ACTION_TOMAIN,      /* Go back to the top level menu.  */
00751                  SWITCH_IVR_ACTION_NOOP /* No operation                    */
00752          } switch_ivr_action_t;

enum switch_ivr_menu_flags

Enumerator:
SWITCH_IVR_MENU_FLAG_FALLTOMAIN 
SWITCH_IVR_MENU_FLAG_FREEPOOL 
SWITCH_IVR_MENU_FLAG_STACK 

Definition at line 738 of file switch_ivr.h.

00738                       {
00739                  SWITCH_IVR_MENU_FLAG_FALLTOMAIN = (1 << 0),
00740                  SWITCH_IVR_MENU_FLAG_FREEPOOL = (1 << 1),
00741                  SWITCH_IVR_MENU_FLAG_STACK = (1 << 2)
00742          } switch_ivr_menu_flags;


Function Documentation

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 
)

Definition at line 3272 of file switch_ivr_async.c.

References dtmf_meta_app_t::app, dtmf_meta_app_t::bind_flags, dtmf_meta_app_t::flags, is_dtmf, dtmf_meta_settings_t::map, dtmf_meta_settings_t::meta, meta_on_dtmf(), SBF_DIAL_ALEG, SBF_DIAL_BLEG, SMF_HOLD_BLEG, dtmf_meta_data_t::sr, switch_channel_get_private(), switch_channel_get_variable, SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_private(), switch_core_session_alloc, switch_core_session_get_channel(), switch_core_session_strdup, SWITCH_DTMF_RECV, SWITCH_DTMF_SEND, switch_dtmftoi(), switch_itodtmf(), SWITCH_LOG_ERROR, SWITCH_LOG_INFO, switch_log_printf(), SWITCH_LOG_WARNING, SWITCH_META_VAR_KEY, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, dtmf_meta_settings_t::up, and zstr.

03274 {
03275         switch_channel_t *channel = switch_core_session_get_channel(session);
03276         dtmf_meta_data_t *md = switch_channel_get_private(channel, SWITCH_META_VAR_KEY);
03277         const char *meta_var = switch_channel_get_variable(channel, "bind_meta_key");
03278         char meta = '*';
03279         char str[2] = "";
03280 
03281         if (meta_var) {
03282                 char t_meta = *meta_var;
03283                 if (is_dtmf(t_meta)) {
03284                         meta = t_meta;
03285                 } else {
03286                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Invalid META KEY %c\n", t_meta);
03287                 }
03288         }
03289 
03290         if (meta != '*' && meta != '#') {
03291                 str[0] = meta;
03292 
03293                 if (switch_dtmftoi(str) == (char)key) {
03294                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid key %u, same as META CHAR\n", key);
03295                         return SWITCH_STATUS_FALSE;
03296                 }
03297         }
03298 
03299 
03300         if (key > 13) {
03301                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid key %u\n", key);
03302                 return SWITCH_STATUS_FALSE;
03303         }
03304 
03305         if (!md) {
03306                 md = switch_core_session_alloc(session, sizeof(*md));
03307                 switch_channel_set_private(channel, SWITCH_META_VAR_KEY, md);
03308                 switch_core_event_hook_add_send_dtmf(session, meta_on_dtmf);
03309                 switch_core_event_hook_add_recv_dtmf(session, meta_on_dtmf);
03310         }
03311 
03312         if (!zstr(app)) {
03313                 if ((bind_flags & SBF_DIAL_ALEG)) {
03314                         md->sr[SWITCH_DTMF_RECV].meta = meta;
03315                         md->sr[SWITCH_DTMF_RECV].up = 1;
03316                         md->sr[SWITCH_DTMF_RECV].map[key].app = switch_core_session_strdup(session, app);
03317                         md->sr[SWITCH_DTMF_RECV].map[key].flags |= SMF_HOLD_BLEG;
03318                         md->sr[SWITCH_DTMF_RECV].map[key].bind_flags = bind_flags;
03319                         
03320                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Bound A-Leg: %c%c %s\n", meta, switch_itodtmf((char)key), app);
03321                 }
03322                 if ((bind_flags & SBF_DIAL_BLEG)) {
03323                         md->sr[SWITCH_DTMF_SEND].meta = meta;
03324                         md->sr[SWITCH_DTMF_SEND].up = 1;
03325                         md->sr[SWITCH_DTMF_SEND].map[key].app = switch_core_session_strdup(session, app);
03326                         md->sr[SWITCH_DTMF_SEND].map[key].flags |= SMF_HOLD_BLEG;
03327                         md->sr[SWITCH_DTMF_SEND].map[key].bind_flags = bind_flags;
03328                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Bound B-Leg: %c%c %s\n", meta, switch_itodtmf((char)key), app);
03329                 }
03330 
03331         } else {
03332                 if ((bind_flags & SBF_DIAL_ALEG)) {
03333                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "UnBound A-Leg: %c%c\n", meta, switch_itodtmf((char)key));
03334                         md->sr[SWITCH_DTMF_SEND].map[key].app = NULL;
03335                 } else {
03336                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "UnBound: B-Leg %c%d\n", meta, key);
03337                         md->sr[SWITCH_DTMF_SEND].map[key].app = NULL;
03338                 }
03339         }
03340 
03341         return SWITCH_STATUS_SUCCESS;
03342 }

switch_status_t switch_ivr_blind_transfer_ack ( switch_core_session_t session,
switch_bool_t  success 
)

Definition at line 3504 of file switch_ivr.c.

References CF_CONFIRM_BLIND_TRANSFER, switch_core_session_message::from, switch_core_session_message::message_id, switch_core_session_message::numeric_arg, switch_channel_clear_flag(), switch_channel_get_variable, switch_channel_test_flag(), switch_core_session_get_channel(), switch_core_session_locate(), switch_core_session_receive_message, switch_core_session_rwunlock(), SWITCH_MESSAGE_INDICATE_BLIND_TRANSFER_RESPONSE, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, and zstr.

Referenced by switch_core_standard_on_routing().

03505 {
03506         switch_channel_t *channel = switch_core_session_get_channel(session);
03507         switch_status_t status = SWITCH_STATUS_FALSE;
03508 
03509         if (switch_channel_test_flag(channel, CF_CONFIRM_BLIND_TRANSFER)) {
03510                 switch_core_session_t *other_session;
03511                 const char *uuid = switch_channel_get_variable(channel, "blind_transfer_uuid");
03512 
03513                 switch_channel_clear_flag(channel, CF_CONFIRM_BLIND_TRANSFER);
03514 
03515                 if (!zstr(uuid) && (other_session = switch_core_session_locate(uuid))) {
03516                         switch_core_session_message_t msg = { 0 };                      
03517                         msg.message_id = SWITCH_MESSAGE_INDICATE_BLIND_TRANSFER_RESPONSE;
03518                         msg.from = __FILE__;
03519                         msg.numeric_arg = success;
03520                         switch_core_session_receive_message(other_session, &msg);
03521                         switch_core_session_rwunlock(other_session);
03522                         status = SWITCH_STATUS_SUCCESS;
03523                 }
03524         }
03525 
03526         return status;
03527 
03528 }

switch_status_t switch_ivr_block_dtmf_session ( switch_core_session_t session  ) 

Definition at line 3258 of file switch_ivr_async.c.

References block_on_dtmf(), SWITCH_BLOCK_DTMF_KEY, switch_channel_get_private(), switch_channel_set_private(), switch_core_session_get_channel(), and SWITCH_STATUS_SUCCESS.

03259 {
03260         switch_channel_t *channel = switch_core_session_get_channel(session);
03261         uint8_t enabled = (uint8_t)(intptr_t)switch_channel_get_private(channel, SWITCH_BLOCK_DTMF_KEY);
03262 
03263         if (!enabled) {
03264                 switch_channel_set_private(channel, SWITCH_BLOCK_DTMF_KEY, (void *)(intptr_t)1);
03265                 switch_core_event_hook_add_send_dtmf(session, block_on_dtmf);
03266                 switch_core_event_hook_add_recv_dtmf(session, block_on_dtmf);
03267         }
03268 
03269         return SWITCH_STATUS_SUCCESS;
03270 }

char* switch_ivr_check_presence_mapping ( const char *  exten_name,
const char *  domain_name 
)

Definition at line 3426 of file switch_ivr.c.

References switch_xml::next, switch_assert, SWITCH_CHANNEL_LOG, switch_event_add_header_string(), switch_event_create, switch_event_destroy(), SWITCH_EVENT_REQUEST_PARAMS, SWITCH_LOG_DEBUG1, SWITCH_LOG_ERROR, switch_log_printf(), switch_regex_perform(), switch_regex_safe_free, SWITCH_STACK_BOTTOM, switch_xml_attr(), switch_xml_child(), switch_xml_free(), switch_xml_open_cfg(), and zstr.

03427 {
03428         char *cf = "presence_map.conf";
03429         switch_xml_t cfg, xml, x_domains, x_domain, x_exten;
03430         char *r = NULL;
03431         switch_event_t *params = NULL;
03432         switch_regex_t *re = NULL;
03433         int proceed = 0, ovector[100];
03434 
03435         switch_event_create(&params, SWITCH_EVENT_REQUEST_PARAMS);
03436         switch_assert(params);
03437 
03438         if ( !zstr(domain_name) ) {
03439                 switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "domain", domain_name);
03440         }
03441 
03442         if ( !zstr(exten_name) ) {
03443                 switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "exten", exten_name);
03444         }
03445 
03446         if (!(xml = switch_xml_open_cfg(cf, &cfg, params))) {
03447                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", cf);
03448                 goto end;
03449         }
03450 
03451         if (!(x_domains = switch_xml_child(cfg, "domains"))) {
03452                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't find any domains!\n");
03453                 goto end;
03454         }
03455 
03456         for (x_domain = switch_xml_child(x_domains, "domain"); x_domain; x_domain = x_domain->next) {
03457                 const char *dname = switch_xml_attr(x_domain, "name");
03458                 if (!dname || (strcasecmp(dname, "*") && strcasecmp(domain_name, dname))) continue;
03459                 
03460                 for (x_exten = switch_xml_child(x_domain, "exten"); x_exten; x_exten = x_exten->next) {
03461                         const char *regex = switch_xml_attr(x_exten, "regex");
03462                         const char *proto = switch_xml_attr(x_exten, "proto");
03463                         
03464                         if (!zstr(regex) && !zstr(proto)) {
03465                                 proceed = switch_regex_perform(exten_name, regex, &re, ovector, sizeof(ovector) / sizeof(ovector[0]));
03466                                 switch_regex_safe_free(re);
03467                                 
03468                                 if (proceed) {
03469                                         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Mapping %s@%s to proto %s matching expression [%s]\n", 
03470                                                                           exten_name, domain_name, proto, regex);
03471                                         r = strdup(proto);
03472                                         goto end;
03473                                 }
03474                                 
03475                         }
03476                 }
03477         }
03478 
03479  end:
03480         switch_event_destroy(&params);
03481 
03482         if (xml) {
03483                 switch_xml_free(xml);
03484         }
03485 
03486         return r;
03487         
03488 }

switch_status_t switch_ivr_create_message_reply ( switch_event_t **  reply,
switch_event_t message,
const char *  new_proto 
)

Definition at line 3413 of file switch_ivr.c.

References switch_event_add_header_string(), switch_event_dup_reply(), SWITCH_STACK_BOTTOM, and SWITCH_STATUS_SUCCESS.

03414 {
03415         switch_status_t status = SWITCH_STATUS_SUCCESS;
03416 
03417         if ((status = switch_event_dup_reply(reply, message) != SWITCH_STATUS_SUCCESS)) {
03418                 abort();
03419         }
03420 
03421         switch_event_add_header_string(*reply, SWITCH_STACK_BOTTOM, "proto", new_proto);
03422 
03423         return status;
03424 }

void switch_ivr_delay_echo ( switch_core_session_t session,
uint32_t  delay_ms 
)

Definition at line 2737 of file switch_ivr.c.

References switch_frame::buflen, switch_frame::codec, switch_frame::data, switch_frame::datalen, switch_codec_implementation::microseconds_per_packet, switch_frame::payload, switch_codec_implementation::samples_per_packet, switch_codec_implementation::samples_per_second, switch_channel_ready, SWITCH_CHANNEL_SESSION_LOG, switch_core_session_get_channel(), switch_core_session_get_read_codec(), switch_core_session_get_read_impl(), switch_core_session_read_frame(), switch_core_session_write_frame(), SWITCH_IO_FLAG_NONE, SWITCH_LOG_DEBUG, SWITCH_LOG_ERROR, switch_log_printf(), and SWITCH_READ_ACCEPTABLE.

02738 {
02739         stfu_instance_t *jb;
02740         int qlen = 0;
02741         stfu_frame_t *jb_frame;
02742         switch_frame_t *read_frame, write_frame = { 0 };
02743         switch_status_t status;
02744         switch_channel_t *channel = switch_core_session_get_channel(session);
02745         uint32_t interval;
02746         uint32_t ts = 0;
02747         switch_codec_implementation_t read_impl = { 0 };
02748         switch_core_session_get_read_impl(session, &read_impl);
02749 
02750 
02751         if (delay_ms < 1 || delay_ms > 10000) {
02752                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid delay [%d] must be between 1 and 10000\n", delay_ms);
02753                 return;
02754         }
02755 
02756         interval = read_impl.microseconds_per_packet / 1000;
02757         //samples = switch_samples_per_packet(read_impl.samples_per_second, interval);
02758 
02759         qlen = delay_ms / (interval) / 2;
02760         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Setting delay to %dms (%d frames)\n", delay_ms, qlen);
02761         jb = stfu_n_init(qlen, qlen, read_impl.samples_per_packet, read_impl.samples_per_second, 0);
02762 
02763         write_frame.codec = switch_core_session_get_read_codec(session);
02764 
02765         while (switch_channel_ready(channel)) {
02766                 status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
02767                 if (!SWITCH_READ_ACCEPTABLE(status)) {
02768                         break;
02769                 }
02770 
02771                 stfu_n_eat(jb, ts, read_frame->payload, read_frame->data, read_frame->datalen, 0);
02772                 ts += read_impl.samples_per_packet;
02773 
02774                 if ((jb_frame = stfu_n_read_a_frame(jb))) {
02775                         write_frame.data = jb_frame->data;
02776                         write_frame.datalen = (uint32_t) jb_frame->dlen;
02777                         write_frame.buflen = (uint32_t) jb_frame->dlen;
02778                         status = switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0);
02779                         if (!SWITCH_READ_ACCEPTABLE(status)) {
02780                                 break;
02781                         }
02782                 }
02783         }
02784 
02785         stfu_n_destroy(&jb);
02786 }

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 
)

Definition at line 228 of file switch_ivr_async.c.

References dm_binding_head_t::binding_list, DMACHINE_MAX_DIGIT_LEN, switch_ivr_dmachine_binding::next, SWITCH_CHANNEL_LOG, switch_core_alloc, switch_core_hash_find(), switch_core_hash_insert(), switch_core_strdup, switch_ivr_dmachine_set_realm(), SWITCH_LOG_DEBUG, switch_log_printf(), SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, dm_binding_head_t::tail, and zstr.

00234 {
00235         switch_ivr_dmachine_binding_t *binding;
00236         switch_size_t len;
00237         dm_binding_head_t *headp;
00238 
00239         if (strlen(digits) > DMACHINE_MAX_DIGIT_LEN -1) {
00240                 return SWITCH_STATUS_FALSE;
00241         }
00242 
00243         if (zstr(realm)) {
00244                 realm = "default";
00245         }
00246 
00247         if (!(headp = switch_core_hash_find(dmachine->binding_hash, realm))) {
00248                 headp = switch_core_alloc(dmachine->pool, sizeof(*headp));
00249                 switch_core_hash_insert(dmachine->binding_hash, realm, headp);
00250         }
00251         
00252         binding = switch_core_alloc(dmachine->pool, sizeof(*binding));
00253 
00254         if (*digits == '~') {
00255                 binding->is_regex = 1;
00256                 digits++;
00257         }
00258 
00259         binding->key = key;
00260         binding->digits = switch_core_strdup(dmachine->pool, digits);
00261         binding->callback = callback;
00262         binding->user_data = user_data;
00263 
00264         if (headp->tail) {
00265                 headp->tail->next = binding;
00266         } else {
00267                 headp->binding_list = binding;
00268         }
00269 
00270         headp->tail = binding;
00271 
00272         len = strlen(digits);
00273 
00274         if (dmachine->realm != headp) {
00275                 switch_ivr_dmachine_set_realm(dmachine, realm);
00276         }
00277 
00278         if (binding->is_regex && dmachine->max_digit_len != DMACHINE_MAX_DIGIT_LEN -1) { 
00279                 dmachine->max_digit_len = DMACHINE_MAX_DIGIT_LEN -1;
00280         } else if (len > dmachine->max_digit_len) {
00281                 dmachine->max_digit_len = (uint32_t) len;
00282         }
00283         
00284         if (binding->is_regex) {
00285                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Digit parser %s: binding %s/%s/%d callback: %p data: %p\n", 
00286                                                   dmachine->name, digits, realm, key, (void *)(intptr_t) callback, user_data);
00287         } else {
00288                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Digit parser %s: binding %s/%s/%d callback: %p data: %p\n", 
00289                                                   dmachine->name, digits, realm, key, (void *)(intptr_t) callback, user_data);
00290         }
00291 
00292         return SWITCH_STATUS_SUCCESS;
00293 }

switch_status_t switch_ivr_dmachine_clear ( switch_ivr_dmachine_t dmachine  ) 

Definition at line 555 of file switch_ivr_async.c.

References SWITCH_STATUS_SUCCESS.

Referenced by switch_ivr_dmachine_ping().

00556 {
00557 
00558         memset(dmachine->digits, 0, sizeof(dmachine->digits));
00559         dmachine->cur_digit_len = 0;
00560         dmachine->last_digit_time = 0;
00561         return SWITCH_STATUS_SUCCESS;
00562 }

switch_status_t switch_ivr_dmachine_clear_realm ( switch_ivr_dmachine_t dmachine,
const char *  realm 
)

Definition at line 204 of file switch_ivr_async.c.

References SWITCH_CHANNEL_LOG, switch_core_hash_delete(), switch_core_hash_find(), SWITCH_LOG_ERROR, SWITCH_LOG_INFO, switch_log_printf(), SWITCH_LOG_WARNING, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, and zstr.

00205 {
00206         dm_binding_head_t *headp;
00207 
00208         if (zstr(realm)) {
00209                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Digit parser %s: Error unknown realm: '%s'\n", dmachine->name, realm);
00210                 return SWITCH_STATUS_FALSE;
00211         }
00212 
00213         headp = switch_core_hash_find(dmachine->binding_hash, realm);
00214 
00215         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Digit parser %s: Clearing realm '%s'\n", dmachine->name, realm);
00216 
00217         if (headp == dmachine->realm) {
00218                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, 
00219                                                   "Digit parser %s: '%s' was the active realm, no realm currently selected.\n", dmachine->name, realm);
00220                 dmachine->realm = NULL;
00221         }
00222 
00223         /* pool alloc'd just ditch it and it will give back the memory when we destroy ourselves */
00224         switch_core_hash_delete(dmachine->binding_hash, realm);
00225         return SWITCH_STATUS_SUCCESS;
00226 }

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,
uint32_t  input_timeout,
switch_ivr_dmachine_callback_t  match_callback,
switch_ivr_dmachine_callback_t  nonmatch_callback,
void *  user_data 
)

Definition at line 120 of file switch_ivr_async.c.

References switch_core_alloc, switch_core_hash_init, switch_core_new_memory_pool, switch_core_strdup, switch_mutex_init(), SWITCH_MUTEX_NESTED, and SWITCH_STATUS_SUCCESS.

00128 {
00129         switch_byte_t my_pool = 0;
00130         switch_ivr_dmachine_t *dmachine;
00131 
00132         if (!pool) {
00133                 switch_core_new_memory_pool(&pool);
00134                 my_pool = 1;
00135         }
00136 
00137         dmachine = switch_core_alloc(pool, sizeof(*dmachine));
00138         dmachine->pool = pool;
00139         dmachine->my_pool = my_pool;
00140         dmachine->digit_timeout_ms = digit_timeout_ms;
00141         dmachine->input_timeout_ms = input_timeout_ms;
00142         dmachine->match.dmachine = dmachine;
00143         dmachine->name = switch_core_strdup(dmachine->pool, name);
00144         switch_mutex_init(&dmachine->mutex, SWITCH_MUTEX_NESTED, dmachine->pool);
00145         
00146         switch_core_hash_init(&dmachine->binding_hash, dmachine->pool);
00147         
00148         if (match_callback) {
00149                 dmachine->match_callback = match_callback;
00150         }
00151 
00152         if (nonmatch_callback) {
00153                 dmachine->nonmatch_callback = nonmatch_callback;
00154         }
00155 
00156         dmachine->user_data = user_data;
00157         
00158         *dmachine_p = dmachine;
00159         
00160         return SWITCH_STATUS_SUCCESS;
00161 }

void switch_ivr_dmachine_destroy ( switch_ivr_dmachine_t **  dmachine  ) 

Definition at line 174 of file switch_ivr_async.c.

References pool, switch_core_destroy_memory_pool, and switch_core_hash_destroy().

Referenced by switch_core_session_perform_destroy().

00175 {
00176         switch_memory_pool_t *pool;
00177 
00178         if (!(dmachine && *dmachine)) return;
00179         
00180         pool = (*dmachine)->pool;
00181 
00182         switch_core_hash_destroy(&(*dmachine)->binding_hash);
00183         
00184         if ((*dmachine)->my_pool) {
00185                 switch_core_destroy_memory_pool(&pool);
00186         }
00187 }

switch_status_t switch_ivr_dmachine_feed ( switch_ivr_dmachine_t dmachine,
const char *  digits,
switch_ivr_dmachine_match_t **  match 
)

Definition at line 523 of file switch_ivr_async.c.

References SWITCH_CHANNEL_LOG, switch_ivr_dmachine_ping(), SWITCH_LOG_ERROR, switch_log_printf(), switch_mutex_lock(), switch_mutex_unlock(), SWITCH_STATUS_BREAK, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_time_now(), and zstr.

Referenced by switch_core_session_recv_dtmf(), switch_core_session_send_dtmf(), switch_ivr_collect_digits_callback(), switch_ivr_gentones(), switch_ivr_park(), switch_ivr_play_file(), switch_ivr_record_file(), switch_ivr_sleep(), and switch_ivr_speak_text_handle().

00524 {
00525         const char *p;
00526         switch_status_t status = SWITCH_STATUS_BREAK;
00527         
00528         if (!zstr(digits)) {
00529                 status = SWITCH_STATUS_SUCCESS;
00530         }
00531 
00532         for (p = digits; p && *p; p++) {
00533                 switch_mutex_lock(dmachine->mutex);
00534                 if (dmachine->cur_digit_len < dmachine->max_digit_len) {
00535                         switch_status_t istatus;
00536                         char *e = dmachine->digits + strlen(dmachine->digits);
00537                         
00538                         *e++ = *p;
00539                         *e = '\0';
00540                         dmachine->cur_digit_len++;
00541                         switch_mutex_unlock(dmachine->mutex);
00542                         dmachine->last_digit_time = switch_time_now();
00543                         if (status == SWITCH_STATUS_SUCCESS && (istatus = switch_ivr_dmachine_ping(dmachine, match)) != SWITCH_STATUS_SUCCESS) {
00544                                 status = istatus;
00545                         }
00546                 } else {
00547                         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "dmachine overflow error!\n");
00548                         status = SWITCH_STATUS_FALSE;
00549                 }
00550         }
00551                 
00552         return status;
00553 }

const char* switch_ivr_dmachine_get_failed_digits ( switch_ivr_dmachine_t dmachine  ) 

Definition at line 407 of file switch_ivr_async.c.

00408 {
00409 
00410         return dmachine->last_failed_digits;
00411 }

switch_ivr_dmachine_match_t* switch_ivr_dmachine_get_match ( switch_ivr_dmachine_t dmachine  ) 

Definition at line 397 of file switch_ivr_async.c.

00398 {
00399         if (dmachine->is_match) {
00400                 dmachine->is_match = 0;
00401                 return &dmachine->match;
00402         }
00403 
00404         return NULL;
00405 }

const char* switch_ivr_dmachine_get_name ( switch_ivr_dmachine_t dmachine  ) 

Definition at line 115 of file switch_ivr_async.c.

00116 {
00117         return (const char *) dmachine->name;
00118 }

switch_status_t switch_ivr_dmachine_last_ping ( switch_ivr_dmachine_t dmachine  ) 

Definition at line 81 of file switch_ivr_async.c.

Referenced by switch_ivr_play_and_detect_speech().

00082 {
00083         return dmachine->last_return;
00084 }

switch_status_t switch_ivr_dmachine_ping ( switch_ivr_dmachine_t dmachine,
switch_ivr_dmachine_match_t **  match_p 
)

Definition at line 413 of file switch_ivr_async.c.

References DM_MATCH_BOTH, DM_MATCH_EXACT, DM_MATCH_NEGATIVE, DM_MATCH_NEVER, DM_MATCH_NONE, DM_MATCH_POSITIVE, switch_ivr_dmachine_check_match(), switch_ivr_dmachine_check_timeout(), switch_ivr_dmachine_clear(), switch_mutex_lock(), switch_mutex_unlock(), switch_set_string, SWITCH_STATUS_BREAK, SWITCH_STATUS_CONTINUE, SWITCH_STATUS_FALSE, SWITCH_STATUS_FOUND, SWITCH_STATUS_NOTFOUND, SWITCH_STATUS_SUCCESS, SWITCH_STATUS_TIMEOUT, and zstr.

Referenced by signal_bridge_on_hibernate(), switch_core_session_read_frame(), switch_ivr_collect_digits_callback(), switch_ivr_dmachine_feed(), switch_ivr_gentones(), switch_ivr_park(), switch_ivr_play_file(), switch_ivr_record_file(), switch_ivr_sleep(), and switch_ivr_speak_text_handle().

00414 {
00415         switch_bool_t is_timeout = switch_ivr_dmachine_check_timeout(dmachine);
00416         dm_match_t is_match = switch_ivr_dmachine_check_match(dmachine, is_timeout);
00417         switch_status_t r, s;
00418         int clear = 0;
00419 
00420         if (is_match == DM_MATCH_NEVER) {
00421                 is_timeout++;
00422         }
00423         
00424         switch_mutex_lock(dmachine->mutex);
00425 
00426         if (zstr(dmachine->digits) && !is_timeout) {
00427                 r = SWITCH_STATUS_SUCCESS;
00428         } else if (dmachine->cur_digit_len > dmachine->max_digit_len) {
00429                 r = SWITCH_STATUS_FALSE;
00430         } else if (is_match == DM_MATCH_EXACT || (is_match == DM_MATCH_BOTH && is_timeout)) {
00431                 r = SWITCH_STATUS_FOUND;
00432                 
00433                 dmachine->match.match_digits = dmachine->last_matching_digits;
00434                 dmachine->match.match_key = dmachine->last_matching_binding->key;
00435                 dmachine->match.user_data = dmachine->last_matching_binding->user_data;
00436                 
00437                 if (match_p) {
00438                         *match_p = &dmachine->match;
00439                 }
00440 
00441                 dmachine->is_match = 1;
00442 
00443                 dmachine->match.type = DM_MATCH_POSITIVE;
00444                 
00445                 if (dmachine->last_matching_binding->callback) {
00446                         s = dmachine->last_matching_binding->callback(&dmachine->match);
00447                         
00448                         switch(s) {
00449                         case SWITCH_STATUS_CONTINUE:
00450                                 r = SWITCH_STATUS_SUCCESS;
00451                                 break;
00452                         case SWITCH_STATUS_SUCCESS:
00453                                 break;
00454                         default:
00455                                 r = SWITCH_STATUS_BREAK;
00456                                 break;
00457                         }
00458                 }
00459 
00460                 if (dmachine->match_callback) {
00461                         dmachine->match.user_data = dmachine->user_data;
00462                         s = dmachine->match_callback(&dmachine->match);
00463 
00464                         switch(s) {
00465                         case SWITCH_STATUS_CONTINUE:
00466                                 r = SWITCH_STATUS_SUCCESS;
00467                                 break;
00468                         case SWITCH_STATUS_SUCCESS:
00469                                 break;
00470                         default:
00471                                 r = SWITCH_STATUS_BREAK;
00472                                 break;
00473                         }
00474 
00475                 }
00476 
00477                 clear++;
00478         } else if (is_timeout) {
00479                 r = SWITCH_STATUS_TIMEOUT;
00480         } else if (is_match == DM_MATCH_NONE && dmachine->cur_digit_len == dmachine->max_digit_len) {
00481                 r = SWITCH_STATUS_NOTFOUND;
00482         } else {
00483                 r = SWITCH_STATUS_SUCCESS;
00484         }
00485         
00486         if (r != SWITCH_STATUS_FOUND && r != SWITCH_STATUS_SUCCESS && r != SWITCH_STATUS_BREAK) {
00487                 switch_set_string(dmachine->last_failed_digits, dmachine->digits);
00488                 dmachine->match.match_digits = dmachine->last_failed_digits;
00489                 
00490                 dmachine->match.type = DM_MATCH_NEGATIVE;
00491                 
00492                 if (dmachine->nonmatch_callback) {
00493                         dmachine->match.user_data = dmachine->user_data;
00494                         s = dmachine->nonmatch_callback(&dmachine->match);
00495 
00496                         switch(s) {
00497                         case SWITCH_STATUS_CONTINUE:
00498                                 r = SWITCH_STATUS_SUCCESS;
00499                                 break;
00500                         case SWITCH_STATUS_SUCCESS:
00501                                 break;
00502                         default:
00503                                 r = SWITCH_STATUS_BREAK;
00504                                 break;
00505                         }
00506 
00507                 }
00508                 
00509                 clear++;
00510         }
00511         
00512         if (clear) {
00513                 switch_ivr_dmachine_clear(dmachine);
00514         }
00515 
00516         dmachine->last_return = r;
00517 
00518         switch_mutex_unlock(dmachine->mutex);
00519 
00520         return r;
00521 }

void switch_ivr_dmachine_set_digit_timeout_ms ( switch_ivr_dmachine_t dmachine,
uint32_t  digit_timeout_ms 
)

Definition at line 164 of file switch_ivr_async.c.

00165 {
00166         dmachine->digit_timeout_ms = digit_timeout_ms;
00167 }

void switch_ivr_dmachine_set_input_timeout_ms ( switch_ivr_dmachine_t dmachine,
uint32_t  input_timeout_ms 
)

Definition at line 169 of file switch_ivr_async.c.

00170 {
00171         dmachine->input_timeout_ms = input_timeout_ms;
00172 }

void switch_ivr_dmachine_set_match_callback ( switch_ivr_dmachine_t dmachine,
switch_ivr_dmachine_callback_t  match_callback 
)

Definition at line 99 of file switch_ivr_async.c.

References switch_assert.

00100 {
00101 
00102         switch_assert(dmachine);
00103         dmachine->match_callback = match_callback;
00104 
00105 }

void switch_ivr_dmachine_set_nonmatch_callback ( switch_ivr_dmachine_t dmachine,
switch_ivr_dmachine_callback_t  nonmatch_callback 
)

Definition at line 107 of file switch_ivr_async.c.

References switch_assert.

00108 {
00109 
00110         switch_assert(dmachine);
00111         dmachine->nonmatch_callback = nonmatch_callback;
00112 
00113 }

switch_status_t switch_ivr_dmachine_set_realm ( switch_ivr_dmachine_t dmachine,
const char *  realm 
)

Definition at line 189 of file switch_ivr_async.c.

References SWITCH_CHANNEL_LOG, switch_core_hash_find(), SWITCH_LOG_ERROR, SWITCH_LOG_INFO, switch_log_printf(), SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.

Referenced by switch_ivr_dmachine_bind().

00190 {
00191         dm_binding_head_t *headp = switch_core_hash_find(dmachine->binding_hash, realm);
00192 
00193         if (headp) {
00194                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Digit parser %s: Setting realm to '%s'\n", dmachine->name, realm);
00195                 dmachine->realm = headp;
00196                 return SWITCH_STATUS_SUCCESS;
00197         }
00198 
00199         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Digit parser %s: Error Setting realm to '%s'\n", dmachine->name, realm);
00200 
00201         return SWITCH_STATUS_FALSE;
00202 }

switch_status_t switch_ivr_find_bridged_uuid ( const char *  uuid,
char *  b_uuid,
switch_size_t  blen 
)

Definition at line 1695 of file switch_ivr_bridge.c.

References switch_assert, switch_channel_get_variable, switch_copy_string(), switch_core_session_get_channel(), switch_core_session_locate(), switch_core_session_rwunlock(), SWITCH_SIGNAL_BOND_VARIABLE, SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.

Referenced by switch_ivr_intercept_session().

01696 {
01697         switch_core_session_t *rsession;
01698         switch_status_t status = SWITCH_STATUS_FALSE;
01699 
01700         switch_assert(uuid);
01701 
01702         if ((rsession = switch_core_session_locate(uuid))) {
01703                 switch_channel_t *rchannel = switch_core_session_get_channel(rsession);
01704                 const char *brto;
01705 
01706                 if ((brto = switch_channel_get_variable(rchannel, "orignate_signal_bond")) || 
01707                         (brto = switch_channel_get_variable(rchannel, SWITCH_SIGNAL_BOND_VARIABLE))) {
01708                         switch_copy_string(b_uuid, brto, blen);
01709                         status = SWITCH_STATUS_SUCCESS;
01710                 }
01711                 switch_core_session_rwunlock(rsession);
01712         }
01713 
01714         return status;
01715 
01716 }

switch_status_t switch_ivr_get_file_handle ( switch_core_session_t session,
switch_file_handle_t **  fh 
)

Definition at line 952 of file switch_ivr_play_say.c.

References switch_channel_get_private(), switch_core_session_get_channel(), switch_core_session_io_read_lock(), switch_core_session_io_rwunlock(), SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.

00953 {
00954         switch_file_handle_t *fhp;
00955         switch_channel_t *channel = switch_core_session_get_channel(session);
00956 
00957         *fh = NULL;
00958         switch_core_session_io_read_lock(session);
00959         
00960         if ((fhp = switch_channel_get_private(channel, "__fh"))) {
00961                 *fh = fhp;
00962                 return SWITCH_STATUS_SUCCESS;
00963         }
00964 
00965         switch_core_session_io_rwunlock(session);
00966 
00967         return SWITCH_STATUS_FALSE;
00968 }

switch_say_gender_t switch_ivr_get_say_gender_by_name ( const char *  name  ) 

Definition at line 74 of file switch_ivr_say.c.

References SAY_GENDER_NAMES.

Referenced by switch_ivr_phrase_macro_event(), switch_ivr_say(), and switch_ivr_say_string().

00075 {
00076         int x = 0;
00077 
00078         if (!name) return (switch_say_gender_t)0;
00079 
00080         for (x = 0; SAY_GENDER_NAMES[x]; x++) {
00081                 if (!strcasecmp(SAY_GENDER_NAMES[x], name)) {
00082                         break;
00083                 }
00084         }
00085 
00086         return (switch_say_gender_t) x;
00087 }

switch_say_method_t switch_ivr_get_say_method_by_name ( const char *  name  ) 

Definition at line 89 of file switch_ivr_say.c.

References SAY_METHOD_NAMES.

Referenced by switch_ivr_phrase_macro_event(), switch_ivr_say(), and switch_ivr_say_string().

00090 {
00091         int x = 0;
00092 
00093         if (!name) return (switch_say_method_t)0;
00094 
00095         for (x = 0; SAY_METHOD_NAMES[x]; x++) {
00096                 if (!strcasecmp(SAY_METHOD_NAMES[x], name)) {
00097                         break;
00098                 }
00099         }
00100 
00101         return (switch_say_method_t) x;
00102 }

switch_say_type_t switch_ivr_get_say_type_by_name ( const char *  name  ) 

Definition at line 104 of file switch_ivr_say.c.

References SAY_TYPE_NAMES.

Referenced by switch_ivr_phrase_macro_event(), switch_ivr_say(), and switch_ivr_say_string().

00105 {
00106         int x = 0;
00107 
00108         if (!name) return (switch_say_type_t)0;
00109 
00110         for (x = 0; SAY_TYPE_NAMES[x]; x++) {
00111                 if (!strcasecmp(SAY_TYPE_NAMES[x], name)) {
00112                         break;
00113                 }
00114         }
00115 
00116         return (switch_say_type_t) x;
00117 }

switch_status_t switch_ivr_insert_file ( switch_core_session_t session,
const char *  file,
const char *  insert_file,
switch_size_t  sample_point 
)

Definition at line 3259 of file switch_ivr.c.

References switch_codec_implementation::actual_samples_per_second, switch_file_handle::channels, switch_file_handle::native_rate, switch_codec_implementation::number_of_channels, START_SAMPLES, switch_channel_ready, SWITCH_CHANNEL_SESSION_LOG, switch_core_file_close(), switch_core_file_open, switch_core_file_read(), switch_core_file_seek(), switch_core_file_write(), switch_core_session_get_channel(), switch_core_session_get_pool(), switch_core_session_get_read_impl(), switch_core_session_sprintf(), SWITCH_FILE_DATA_SHORT, SWITCH_FILE_FLAG_READ, SWITCH_FILE_FLAG_WRITE, SWITCH_FILE_NATIVE, SWITCH_FILE_OPEN, switch_file_rename(), SWITCH_GLOBAL_dirs, SWITCH_LOG_ERROR, switch_log_printf(), SWITCH_PATH_SEPARATOR, switch_safe_free, SWITCH_STATUS_SUCCESS, switch_test_flag, switch_uuid_format(), SWITCH_UUID_FORMATTED_LENGTH, switch_uuid_get(), switch_zmalloc, and switch_directories::temp_dir.

Referenced by CoreSession::insertFile().

03260 {
03261         switch_file_handle_t orig_fh = { 0 };
03262         switch_file_handle_t new_fh = { 0 };
03263         switch_codec_implementation_t read_impl = { 0 };
03264         char *tmp_file;
03265         switch_uuid_t uuid;
03266         char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
03267         int16_t *abuf = NULL;
03268         switch_size_t olen = 0;
03269         int asis = 0;
03270         switch_channel_t *channel = switch_core_session_get_channel(session);
03271         switch_size_t sample_count = 0;
03272         uint32_t pos = 0;
03273         char *ext;
03274 
03275         switch_uuid_get(&uuid);
03276         switch_uuid_format(uuid_str, &uuid);
03277 
03278         if ((ext = strrchr(file, '.'))) {
03279                 ext++;
03280         } else {
03281                 ext = "wav";
03282         }
03283         
03284         tmp_file = switch_core_session_sprintf(session, "%s%smsg_%s.%s", 
03285                                                                                    SWITCH_GLOBAL_dirs.temp_dir, SWITCH_PATH_SEPARATOR, uuid_str, ext);  
03286         
03287         switch_core_session_get_read_impl(session, &read_impl);
03288         
03289         new_fh.channels = read_impl.number_of_channels;
03290         new_fh.native_rate = read_impl.actual_samples_per_second;
03291 
03292 
03293         if (switch_core_file_open(&new_fh,
03294                                                           tmp_file,
03295                                                           new_fh.channels,
03296                                                           read_impl.actual_samples_per_second, SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) {
03297                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Failed to open file %s\n", tmp_file);
03298                 goto end;
03299         }
03300 
03301 
03302         if (switch_core_file_open(&orig_fh,
03303                                                           file,
03304                                                           new_fh.channels,
03305                                                           read_impl.actual_samples_per_second, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) {
03306                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Failed to open file %s\n", file);
03307                 goto end;
03308         }
03309 
03310 
03311         switch_zmalloc(abuf, START_SAMPLES * sizeof(*abuf));
03312 
03313         if (switch_test_flag((&orig_fh), SWITCH_FILE_NATIVE)) {
03314                 asis = 1;
03315         }
03316 
03317         while (switch_channel_ready(channel)) {
03318                 olen = START_SAMPLES;
03319 
03320                 if (!asis) {
03321                         olen /= 2;
03322                 }
03323 
03324                 if ((sample_count + olen) > sample_point) {
03325                         olen = sample_point - sample_count;
03326                 }
03327 
03328                 if (!olen || switch_core_file_read(&orig_fh, abuf, &olen) != SWITCH_STATUS_SUCCESS || !olen) {
03329                         break;
03330                 }
03331 
03332                 sample_count += olen;
03333 
03334                 switch_core_file_write(&new_fh, abuf, &olen);
03335         }
03336 
03337         switch_core_file_close(&orig_fh);
03338 
03339 
03340         if (switch_core_file_open(&orig_fh,
03341                                                           insert_file,
03342                                                           new_fh.channels,
03343                                                           read_impl.actual_samples_per_second, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) {
03344                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Failed to open file %s\n", file);
03345                 goto end;
03346         }
03347 
03348 
03349         while (switch_channel_ready(channel)) {
03350                 olen = START_SAMPLES;
03351 
03352                 if (!asis) {
03353                         olen /= 2;
03354                 }
03355 
03356                 if (switch_core_file_read(&orig_fh, abuf, &olen) != SWITCH_STATUS_SUCCESS || !olen) {
03357                         break;
03358                 }
03359 
03360                 sample_count += olen;
03361 
03362                 switch_core_file_write(&new_fh, abuf, &olen);
03363         }
03364 
03365         switch_core_file_close(&orig_fh);
03366 
03367         if (switch_core_file_open(&orig_fh,
03368                                                           file,
03369                                                           new_fh.channels,
03370                                                           read_impl.actual_samples_per_second, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) {
03371                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Failed to open file %s\n", file);
03372                 goto end;
03373         }
03374 
03375         pos = 0;
03376         switch_core_file_seek(&orig_fh, &pos, sample_point, SEEK_SET);
03377 
03378         while (switch_channel_ready(channel)) {
03379                 olen = START_SAMPLES;
03380 
03381                 if (!asis) {
03382                         olen /= 2;
03383                 }
03384 
03385                 if (switch_core_file_read(&orig_fh, abuf, &olen) != SWITCH_STATUS_SUCCESS || !olen) {
03386                         break;
03387                 }
03388 
03389                 sample_count += olen;
03390 
03391                 switch_core_file_write(&new_fh, abuf, &olen);
03392         }
03393 
03394  end:
03395 
03396         if (switch_test_flag((&orig_fh), SWITCH_FILE_OPEN)) {
03397                 switch_core_file_close(&orig_fh);
03398         }
03399 
03400         if (switch_test_flag((&new_fh), SWITCH_FILE_OPEN)) {
03401                 switch_core_file_close(&new_fh);
03402         }
03403 
03404         switch_file_rename(tmp_file, file, switch_core_session_get_pool(session));
03405         unlink(tmp_file);
03406 
03407         switch_safe_free(abuf);
03408 
03409         return SWITCH_STATUS_SUCCESS;
03410 }

void switch_ivr_intercept_session ( switch_core_session_t session,
const char *  uuid,
switch_bool_t  bleg 
)

Definition at line 1718 of file switch_ivr_bridge.c.

References CF_ANSWERED, CF_BRIDGED, CF_INTERCEPT, CF_INTERCEPTED, CF_TRANSFER, CS_PARK, SWITCH_CAUSE_PICKED_OFF, switch_channel_answer, switch_channel_get_variable, switch_channel_hangup, switch_channel_mark_hold(), SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_flag, switch_channel_set_state, switch_channel_set_state_flag(), switch_channel_test_flag(), switch_core_session_get_channel(), switch_core_session_get_uuid(), switch_core_session_locate(), switch_core_session_rwunlock(), switch_core_session_strdup, SWITCH_FALSE, switch_ivr_find_bridged_uuid(), switch_ivr_uuid_bridge(), SWITCH_LOG_DEBUG, switch_log_printf(), SWITCH_SIGNAL_BOND_VARIABLE, SWITCH_STATUS_SUCCESS, switch_true(), SWITCH_UUID_FORMATTED_LENGTH, and zstr.

01719 {
01720         switch_core_session_t *rsession, *bsession = NULL;
01721         switch_channel_t *channel, *rchannel, *bchannel = NULL;
01722         const char *buuid, *var;
01723         char brto[SWITCH_UUID_FORMATTED_LENGTH + 1] = "";
01724         
01725         if (bleg) {
01726                 if (switch_ivr_find_bridged_uuid(uuid, brto, sizeof(brto)) == SWITCH_STATUS_SUCCESS) {
01727                         uuid = switch_core_session_strdup(session, brto);
01728                 } else {
01729                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "no uuid bridged to %s\n", uuid);
01730                         return;
01731                 }
01732         }
01733 
01734         if (zstr(uuid) || !(rsession = switch_core_session_locate(uuid))) {
01735                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "no uuid %s\n", uuid);
01736                 return;
01737         }
01738 
01739         channel = switch_core_session_get_channel(session);
01740         rchannel = switch_core_session_get_channel(rsession);
01741         buuid = switch_channel_get_variable(rchannel, SWITCH_SIGNAL_BOND_VARIABLE);
01742 
01743         if ((var = switch_channel_get_variable(channel, "intercept_unbridged_only")) && switch_true(var)) {
01744                 if ((switch_channel_test_flag(rchannel, CF_BRIDGED))) {
01745                         switch_core_session_rwunlock(rsession);
01746                         return;
01747                 }
01748         }
01749 
01750         if ((var = switch_channel_get_variable(channel, "intercept_unanswered_only")) && switch_true(var)) {
01751                 if ((switch_channel_test_flag(rchannel, CF_ANSWERED))) {
01752                         switch_core_session_rwunlock(rsession);
01753                         return;
01754                 }
01755         }
01756 
01757         switch_channel_answer(channel);
01758 
01759         if (!zstr(buuid)) {
01760                 if ((bsession = switch_core_session_locate(buuid))) {
01761                         bchannel = switch_core_session_get_channel(bsession);
01762                         switch_channel_set_flag(bchannel, CF_INTERCEPT);
01763                 }
01764         }
01765 
01766         if (!switch_channel_test_flag(rchannel, CF_ANSWERED)) {
01767                 switch_channel_answer(rchannel);
01768         }
01769 
01770         switch_channel_mark_hold(rchannel, SWITCH_FALSE);
01771 
01772         switch_channel_set_state_flag(rchannel, CF_TRANSFER);
01773         switch_channel_set_state(rchannel, CS_PARK);
01774 
01775         if (bchannel) {
01776                 switch_channel_set_state_flag(bchannel, CF_TRANSFER);
01777                 switch_channel_set_state(bchannel, CS_PARK);
01778         }
01779 
01780         switch_channel_set_flag(rchannel, CF_INTERCEPTED);
01781         switch_ivr_uuid_bridge(switch_core_session_get_uuid(session), uuid);
01782         switch_core_session_rwunlock(rsession);
01783 
01784         if (bsession) {
01785                 switch_channel_hangup(bchannel, SWITCH_CAUSE_PICKED_OFF);
01786                 switch_core_session_rwunlock(bsession);
01787         }
01788 
01789 
01790 
01791 }

switch_status_t switch_ivr_kill_uuid ( const char *  uuid,
switch_call_cause_t  cause 
)

Definition at line 3490 of file switch_ivr.c.

References switch_channel_hangup, switch_core_session_get_channel(), switch_core_session_locate(), switch_core_session_rwunlock(), SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, and zstr.

03491 {
03492         switch_core_session_t *session;
03493 
03494         if (zstr(uuid) || !(session = switch_core_session_locate(uuid))) {
03495                 return SWITCH_STATUS_FALSE;
03496         } else {
03497                 switch_channel_t *channel = switch_core_session_get_channel(session);
03498                 switch_channel_hangup(channel, cause);
03499                 switch_core_session_rwunlock(session);
03500                 return SWITCH_STATUS_SUCCESS;
03501         }
03502 }

switch_status_t switch_ivr_menu_bind_action ( switch_ivr_menu_t menu,
switch_ivr_action_t  ivr_action,
const char *  arg,
const char *  bind 
)

switch_ivr_menu_bind_action: Bind a keystroke to an action.

Parameters:
menu The menu obj you wish to bind to.
ivr_action switch_ivr_action_t enum of what you want to do.
arg Optional (sometimes necessary) string arguement.
bind KeyStrokes to bind the action to.
Returns:
SWUTCH_STATUS_SUCCESS if the action was binded

Definition at line 215 of file switch_ivr_menu.c.

References switch_ivr_menu_action::next, switch_core_alloc, switch_core_strdup, SWITCH_STATUS_MEMERR, and SWITCH_STATUS_SUCCESS.

Referenced by IVRMenu::bindAction(), and switch_ivr_menu_stack_xml_build().

00216 {
00217         switch_ivr_menu_action_t *action, *ap;
00218         uint32_t len;
00219 
00220         if ((action = switch_core_alloc(menu->pool, sizeof(*action)))) {
00221                 action->bind = switch_core_strdup(menu->pool, bind);
00222                 action->arg = switch_core_strdup(menu->pool, arg);
00223                 if (*action->bind == '/') {
00224                         action->re = 1;
00225                 } else {
00226                         len = (uint32_t) strlen(action->bind);
00227                         if (len > menu->inlen) {
00228                                 menu->inlen = len;
00229                         }
00230                 }
00231                 action->ivr_action = ivr_action;
00232 
00233                 if (menu->actions) {
00234                         for(ap = menu->actions; ap && ap->next; ap = ap->next);
00235                         ap->next = action;
00236                 } else {
00237                 menu->actions = action;
00238                 }
00239 
00240                 return SWITCH_STATUS_SUCCESS;
00241         }
00242 
00243         return SWITCH_STATUS_MEMERR;
00244 }

switch_status_t switch_ivr_menu_bind_function ( switch_ivr_menu_t menu,
switch_ivr_menu_action_function_t function,
const char *  arg,
const char *  bind 
)

Bind a keystroke to a callback function.

Parameters:
menu The menu obj you wish to bind to.
function The function to call [int proto(struct switch_ivr_menu *, char *, size_t, void *)]
arg Optional (sometimes necessary) string arguement.
bind KeyStrokes to bind the action to.
Note:
The function is passed a buffer to fill in with any required argument data.

The function is also passed an optional void pointer to an object set upon menu execution. (think threads)

The function returns an switch_ivr_action_t enum of what you want to do. and looks to your buffer for args.

Returns:
SWUTCH_STATUS_SUCCESS if the function was binded

Definition at line 246 of file switch_ivr_menu.c.

References switch_ivr_menu_action::next, switch_core_alloc, switch_core_strdup, SWITCH_STATUS_MEMERR, and SWITCH_STATUS_SUCCESS.

Referenced by switch_ivr_menu_stack_xml_build().

00248 {
00249         switch_ivr_menu_action_t *action, *ap;
00250         uint32_t len;
00251 
00252         if ((action = switch_core_alloc(menu->pool, sizeof(*action)))) {
00253                 action->bind = switch_core_strdup(menu->pool, bind);
00254                 action->arg = switch_core_strdup(menu->pool, arg);
00255 
00256                 if (*action->bind == '/') {
00257                         action->re = 1;
00258                 } else {
00259                         len = (uint32_t) strlen(action->bind);
00260                         if (len > menu->inlen) {
00261                                 menu->inlen = len;
00262                         }
00263                 }
00264 
00265                 action->function = function;
00266                 
00267                 if (menu->actions) {
00268                         for(ap = menu->actions; ap && ap->next; ap = ap->next);
00269                         ap->next = action;
00270                 } else {
00271                 menu->actions = action;
00272                 }
00273 
00274                 return SWITCH_STATUS_SUCCESS;
00275         }
00276 
00277         return SWITCH_STATUS_MEMERR;
00278 }

switch_status_t switch_ivr_menu_execute ( switch_core_session_t session,
switch_ivr_menu_t stack,
char *  name,
void *  obj 
)

Execute a menu.

Parameters:
session The session running the menu.
stack The top-level menu object (the first one you created.)
name A pointer to the name of the menu.
obj A void pointer to an object you want to make avaliable to your callback functions that you may have binded with switch_ivr_menu_bind_function.
Returns:
SWITCH_STATUS_SUCCESS if all is well

Definition at line 400 of file switch_ivr_menu.c.

References actions, switch_ivr_menu_action::arg, switch_ivr_menu_action::bind, buf, switch_ivr_menu_action::function, greeting_sound, inlen, invalid_sound, switch_ivr_menu_action::ivr_action, max_failures, max_timeouts, name, switch_ivr_menu_action::next, play_and_collect(), switch_ivr_menu_action::re, running, short_greeting_sound, switch_channel_ready, SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_variable, switch_clear_flag, switch_core_session_exec(), switch_core_session_get_channel(), switch_core_session_strdup, SWITCH_FALSE, switch_goto_status, SWITCH_IVR_ACTION_BACK, SWITCH_IVR_ACTION_DIE, SWITCH_IVR_ACTION_EXECAPP, SWITCH_IVR_ACTION_EXECMENU, SWITCH_IVR_ACTION_NOOP, SWITCH_IVR_ACTION_PLAYSOUND, SWITCH_IVR_ACTION_TOMAIN, switch_ivr_menu_execute(), switch_ivr_menu_find(), SWITCH_IVR_MENU_FLAG_FALLTOMAIN, SWITCH_IVR_MENU_FLAG_STACK, switch_ivr_play_file(), switch_ivr_sleep(), switch_loadable_module_get_application_interface(), SWITCH_LOG_DEBUG, SWITCH_LOG_ERROR, switch_log_printf(), SWITCH_LOG_WARNING, switch_perform_substitution(), switch_regex_perform(), switch_regex_safe_free, switch_set_flag, SWITCH_STATUS_BREAK, SWITCH_STATUS_FALSE, SWITCH_STATUS_IS_BREAK, SWITCH_STATUS_SUCCESS, SWITCH_STATUS_TIMEOUT, switch_test_flag, tts_engine, tts_voice, UNPROTECT_INTERFACE, and zstr.

Referenced by IVRMenu::execute(), and switch_ivr_menu_execute().

00401 {
00402         int reps = 0, errs = 0, timeouts = 0, match = 0, running = 1;
00403         char *greeting_sound = NULL, *aptr = NULL;
00404         char arg[512];
00405         switch_ivr_action_t todo = SWITCH_IVR_ACTION_DIE;
00406         switch_ivr_menu_action_t *ap;
00407         switch_ivr_menu_t *menu;
00408         switch_channel_t *channel;
00409         switch_status_t status = SWITCH_STATUS_SUCCESS;
00410 
00411         if (++stack->stack_count > 12) {
00412                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Too many levels of recursion.\n");
00413                 switch_goto_status(SWITCH_STATUS_FALSE, end);
00414         }
00415 
00416         if (!session || !stack || zstr(name)) {
00417                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid menu context\n");
00418                 switch_goto_status(SWITCH_STATUS_FALSE, end);
00419         }
00420 
00421         channel = switch_core_session_get_channel(session);
00422 
00423         if (!(menu = switch_ivr_menu_find(stack, name))) {
00424                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid Menu!\n");
00425                 switch_goto_status(SWITCH_STATUS_FALSE, end);
00426         }
00427 
00428         if (!zstr(menu->tts_engine) && !zstr(menu->tts_voice)) {
00429                 switch_channel_set_variable(channel, "tts_engine", menu->tts_engine);
00430                 switch_channel_set_variable(channel, "tts_voice", menu->tts_voice);
00431         }
00432 
00433         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Executing IVR menu %s\n", menu->name);
00434         switch_channel_set_variable(channel, "ivr_menu_status", "success");
00435 
00436         for (reps = 0; running && status == SWITCH_STATUS_SUCCESS; reps++) {
00437                 if (!switch_channel_ready(channel)) {
00438                         break;
00439                 }
00440                 if (errs == menu->max_failures) {
00441                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Maximum failures\n");
00442                         switch_channel_set_variable(channel, "ivr_menu_status", "failure");
00443                         break;
00444                 }
00445                 if (timeouts == menu->max_timeouts) {
00446                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Maximum timeouts\n");
00447                         switch_channel_set_variable(channel, "ivr_menu_status", "timeout");
00448                         break;
00449                 }
00450 
00451                 if (reps > 0 && menu->short_greeting_sound) {
00452                         greeting_sound = menu->short_greeting_sound;
00453                 } else {
00454                         greeting_sound = menu->greeting_sound;
00455                 }
00456 
00457                 match = 0;
00458                 aptr = NULL;
00459 
00460                 memset(arg, 0, sizeof(arg));
00461 
00462                 memset(menu->buf, 0, menu->inlen + 1);
00463 
00464                 if (play_and_collect(session, menu, greeting_sound, menu->inlen) == SWITCH_STATUS_TIMEOUT && *menu->buf == '\0') {
00465                         timeouts++;
00466                         continue;
00467                 }
00468 
00469                 if (*menu->buf != '\0') {
00470 
00471                         for (ap = menu->actions; ap; ap = ap->next) {
00472                                 int ok = 0;
00473                                 char substituted[1024];
00474                                 char *use_arg = ap->arg;
00475 
00476                                 if (!zstr(menu->tts_engine) && !zstr(menu->tts_voice)) {
00477                                         switch_channel_set_variable(channel, "tts_engine", menu->tts_engine);
00478                                         switch_channel_set_variable(channel, "tts_voice", menu->tts_voice);
00479                                 }
00480 
00481                                 if (ap->re) {
00482                                         switch_regex_t *re = NULL;
00483                                         int ovector[30];
00484 
00485                                         if ((ok = switch_regex_perform(menu->buf, ap->bind, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
00486                                                 switch_perform_substitution(re, ok, ap->arg, menu->buf, substituted, sizeof(substituted), ovector);
00487                                                 use_arg = substituted;
00488                                         }
00489                                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "action regex [%s] [%s] [%d]\n", menu->buf, ap->bind, ok);
00490 
00491                                         switch_regex_safe_free(re);
00492                                 } else {
00493                                         ok = !strcmp(menu->buf, ap->bind);
00494                                 }
00495 
00496                                 if (ok) {
00497                                         match++;
00498                                         errs = 0;
00499                                         if (ap->function) {
00500                                                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
00501                                                                                   "IVR function on menu '%s' matched '%s' param '%s'\n", menu->name, menu->buf, use_arg);
00502                                                 todo = ap->function(menu, use_arg, arg, sizeof(arg), obj);
00503                                                 aptr = arg;
00504                                         } else {
00505                                                 todo = ap->ivr_action;
00506                                                 aptr = use_arg;
00507                                                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
00508                                                                                   "IVR action on menu '%s' matched '%s' param '%s'\n", menu->name, menu->buf, aptr);
00509                                         }
00510 
00511                                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "switch_ivr_menu_execute todo=[%d]\n", todo);
00512 
00513                                         switch (todo) {
00514                                         case SWITCH_IVR_ACTION_DIE:
00515                                                 status = SWITCH_STATUS_FALSE;
00516                                                 break;
00517                                         case SWITCH_IVR_ACTION_PLAYSOUND:
00518                                                 status = switch_ivr_play_file(session, NULL, aptr, NULL);
00519                                                 break;
00520                                         case SWITCH_IVR_ACTION_EXECMENU:
00521                                                 if (!strcmp(aptr, menu->name)) {
00522                                                         status = SWITCH_STATUS_SUCCESS;
00523                                                 } else {
00524                                                         reps = -1;
00525                                                         status = switch_ivr_menu_execute(session, stack, aptr, obj);
00526                                                 }
00527                                                 break;
00528                                         case SWITCH_IVR_ACTION_EXECAPP:
00529                                                 {
00530                                                         switch_application_interface_t *application_interface;
00531                                                         char *app_name;
00532                                                         char *app_arg = NULL;
00533 
00534                                                         status = SWITCH_STATUS_FALSE;
00535 
00536                                                         if (!zstr(aptr)) {
00537                                                                 app_name = switch_core_session_strdup(session, aptr);
00538                                                                 if ((app_arg = strchr(app_name, ' '))) {
00539                                                                         *app_arg++ = '\0';
00540                                                                 }
00541 
00542                                                                 if ((application_interface = switch_loadable_module_get_application_interface(app_name))) {
00543                                                                         switch_core_session_exec(session, application_interface, app_arg);
00544                                                                         UNPROTECT_INTERFACE(application_interface);
00545                                                                         status = SWITCH_STATUS_SUCCESS;
00546                                                                 }
00547                                                         }
00548                                                 }
00549                                                 break;
00550                                         case SWITCH_IVR_ACTION_BACK:
00551                                                 running = 0;
00552                                                 status = SWITCH_STATUS_SUCCESS;
00553                                                 break;
00554                                         case SWITCH_IVR_ACTION_TOMAIN:
00555                                                 switch_set_flag(stack, SWITCH_IVR_MENU_FLAG_FALLTOMAIN);
00556                                                 status = SWITCH_STATUS_BREAK;
00557                                                 break;
00558                                         case SWITCH_IVR_ACTION_NOOP:
00559                                                 status = SWITCH_STATUS_SUCCESS;
00560                                                 break;
00561                                         default:
00562                                                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Invalid TODO!\n");
00563                                                 break;
00564                                         }
00565                                 }
00566                         }
00567 
00568                         if (switch_test_flag(menu, SWITCH_IVR_MENU_FLAG_STACK)) {       /* top level */
00569                                 if (switch_test_flag(stack, SWITCH_IVR_MENU_FLAG_FALLTOMAIN)) { /* catch the fallback and recover */
00570                                         switch_clear_flag(stack, SWITCH_IVR_MENU_FLAG_FALLTOMAIN);
00571                                         status = SWITCH_STATUS_SUCCESS;
00572                                         running = 1;
00573                                         continue;
00574                                 }
00575                         }
00576                 }
00577                 if (!match) {
00578                         if (*menu->buf) {
00579                                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "IVR menu '%s' caught invalid input '%s'\n", menu->name,
00580                                                                   menu->buf);
00581                                 if (menu->invalid_sound) {
00582                                         play_and_collect(session, menu, menu->invalid_sound, 0);
00583                                 }
00584                         } else {
00585                                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "IVR menu '%s' no input detected\n", menu->name);
00586                         }
00587                         errs++;
00588                         if (status == SWITCH_STATUS_SUCCESS) {
00589                                 status = switch_ivr_sleep(session, 1000, SWITCH_FALSE, NULL);
00590                         }
00591                         /* breaks are ok too */
00592                         if (SWITCH_STATUS_IS_BREAK(status)) {
00593                                 status = SWITCH_STATUS_SUCCESS;
00594                         }
00595                 }
00596         }
00597 
00598         if (stack->stack_count == 1) {
00599                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "exit-sound '%s'\n", menu->exit_sound);
00600                 if (!zstr(menu->exit_sound)) {
00601                         status = play_and_collect(session, menu, menu->exit_sound, 0);
00602                 }
00603         }
00604 
00605   end:
00606 
00607         stack->stack_count--;
00608 
00609         return status;
00610 }

switch_status_t switch_ivr_menu_init ( switch_ivr_menu_t **  new_menu,
switch_ivr_menu_t main,
const char *  name,
const char *  greeting_sound,
const char *  short_greeting_sound,
const char *  invalid_sound,
const char *  exit_sound,
const char *  confirm_macro,
const char *  confirm_key,
const char *  tts_engine,
const char *  tts_voice,
int  confirm_attempts,
int  inter_timeout,
int  digit_len,
int  timeout,
int  max_failures,
int  max_timeouts,
switch_memory_pool_t pool 
)

Create a new menu object.

Parameters:
new_menu the pointer to the new menu
main The top level menu, (NULL if this is the top level one).
name A pointer to the name of this menu.
greeting_sound Optional pointer to a main sound (press 1 for this 2 for that).
short_greeting_sound Optional pointer to a shorter main sound for subsequent loops.
invalid_sound Optional pointer to a sound to play after invalid input.
exit_sound Optional pointer to a sound to play upon exiting the menu.
confirm_macro phrase macro name to confirm input
confirm_key the dtmf key required for positive confirmation
tts_engine the tts engine to use for this menu
tts_voice the tts voice to use for this menu
confirm_attempts number of times to prompt to confirm input before failure
inter_timeout inter-digit timeout
digit_len max number of digits
timeout A number of milliseconds to pause before looping.
max_failures Maximum number of failures to withstand before hangingup This resets everytime you enter the menu.
pool memory pool (NULL to create one).
Returns:
SWITCH_STATUS_SUCCESS if the menu was created.

Definition at line 96 of file switch_ivr_menu.c.

References SWITCH_CHANNEL_LOG, switch_core_alloc, switch_core_destroy_memory_pool, switch_core_new_memory_pool, switch_core_strdup, SWITCH_IVR_MENU_FLAG_FREEPOOL, SWITCH_IVR_MENU_FLAG_STACK, switch_ivr_menu_stack_add(), SWITCH_LOG_CRIT, switch_log_printf(), switch_set_flag, SWITCH_STATUS_MEMERR, SWITCH_STATUS_SUCCESS, and zstr.

Referenced by IVRMenu::IVRMenu(), and switch_ivr_menu_stack_xml_build().

00110 {
00111         switch_ivr_menu_t *menu;
00112         uint8_t newpool = 0;
00113 
00114         if (!pool) {
00115                 if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) {
00116                         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "OH OH no pool\n");
00117                         return SWITCH_STATUS_MEMERR;
00118                 }
00119                 newpool = 1;
00120         }
00121 
00122         if (!(menu = switch_core_alloc(pool, sizeof(*menu)))) {
00123                 if (newpool) {
00124                         switch_core_destroy_memory_pool(&pool);
00125                         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Memory Error!\n");
00126                         return SWITCH_STATUS_MEMERR;
00127                 }
00128         }
00129 
00130         menu->pool = pool;
00131 
00132         if (!confirm_attempts) {
00133                 confirm_attempts = 3;
00134         }
00135 
00136         if (!inter_timeout) {
00137                 inter_timeout = timeout / 2;
00138         }
00139 
00140         if (!zstr(name)) {
00141                 menu->name = switch_core_strdup(menu->pool, name);
00142         }
00143 
00144         if (!zstr(greeting_sound)) {
00145                 menu->greeting_sound = switch_core_strdup(menu->pool, greeting_sound);
00146         }
00147 
00148         if (!zstr(short_greeting_sound)) {
00149                 menu->short_greeting_sound = switch_core_strdup(menu->pool, short_greeting_sound);
00150         }
00151 
00152         if (!zstr(invalid_sound)) {
00153                 menu->invalid_sound = switch_core_strdup(menu->pool, invalid_sound);
00154         }
00155 
00156         if (!zstr(exit_sound)) {
00157                 menu->exit_sound = switch_core_strdup(menu->pool, exit_sound);
00158         }
00159 
00160         if (!zstr(confirm_macro)) {
00161                 menu->confirm_macro = switch_core_strdup(menu->pool, confirm_macro);
00162         }
00163 
00164         if (!zstr(tts_engine)) {
00165                 menu->tts_engine = switch_core_strdup(menu->pool, tts_engine);
00166         }
00167 
00168         if (!zstr(tts_voice)) {
00169                 menu->tts_voice = switch_core_strdup(menu->pool, tts_voice);
00170         }
00171 
00172         menu->confirm_attempts = confirm_attempts;
00173 
00174         menu->inlen = digit_len;
00175 
00176         if (max_failures > 0) {
00177                 menu->max_failures = max_failures;
00178         } else {
00179                 menu->max_failures = 3;
00180         }
00181 
00182         if (max_timeouts > 0) {
00183                 menu->max_timeouts = max_timeouts;
00184         } else {
00185                 menu->max_timeouts = 3;
00186         }
00187 
00188         menu->timeout = timeout;
00189 
00190         menu->inter_timeout = inter_timeout;
00191 
00192         menu->actions = NULL;
00193 
00194         if (newpool) {
00195                 switch_set_flag(menu, SWITCH_IVR_MENU_FLAG_FREEPOOL);
00196         }
00197 
00198         if (menu->timeout <= 0) {
00199                 menu->timeout = 10000;
00200         }
00201 
00202         if (main) {
00203                 switch_ivr_menu_stack_add(&main, menu);
00204         } else {
00205                 switch_set_flag(menu, SWITCH_IVR_MENU_FLAG_STACK);
00206         }
00207 
00208         menu->buf = switch_core_alloc(menu->pool, 1024);
00209 
00210         *new_menu = menu;
00211 
00212         return SWITCH_STATUS_SUCCESS;
00213 }

switch_status_t switch_ivr_menu_stack_free ( switch_ivr_menu_t stack  ) 

free a stack of menu objects.

Parameters:
stack The top level menu you wish to destroy.
Returns:
SWITCH_STATUS_SUCCESS if the object was a top level menu and it was freed

Definition at line 280 of file switch_ivr_menu.c.

References pool, switch_core_destroy_memory_pool, SWITCH_IVR_MENU_FLAG_FREEPOOL, SWITCH_IVR_MENU_FLAG_STACK, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, and switch_test_flag.

Referenced by IVRMenu::~IVRMenu().

00281 {
00282         switch_status_t status = SWITCH_STATUS_FALSE;
00283 
00284         if (stack != NULL && stack->pool != NULL) {
00285                 if (switch_test_flag(stack, SWITCH_IVR_MENU_FLAG_STACK)
00286                         && switch_test_flag(stack, SWITCH_IVR_MENU_FLAG_FREEPOOL)) {
00287                         switch_memory_pool_t *pool = stack->pool;
00288                         status = switch_core_destroy_memory_pool(&pool);
00289                 } else {
00290                         status = SWITCH_STATUS_SUCCESS;
00291                 }
00292         }
00293 
00294         return status;
00295 }

switch_status_t switch_ivr_menu_stack_xml_add_custom ( switch_ivr_menu_xml_ctx_t xml_menu_ctx,
const char *  name,
switch_ivr_menu_action_function_t function 
)

Parameters:
xml_menu_ctx The XML menu parser context previously created by switch_ivr_menu_stack_xml_init
name The xml tag name to add to the parser engine
function The menu function callback that will be executed when menu digits are bound to this name
Returns:
SWITCH_STATUS_SUCCESS if all is well

Definition at line 762 of file switch_ivr_menu.c.

References switch_ivr_menu_stack_xml_add().

00764 {
00765         return switch_ivr_menu_stack_xml_add(xml_menu_ctx, name, -1, function);
00766 }

switch_status_t switch_ivr_menu_stack_xml_build ( switch_ivr_menu_xml_ctx_t xml_menu_ctx,
switch_ivr_menu_t **  menu_stack,
switch_xml_t  xml_menus,
switch_xml_t  xml_menu 
)

Build a menu stack from an xml source.

Parameters:
xml_menu_ctx The XML menu parser context previously created by switch_ivr_menu_stack_xml_init
menu_stack The menu stack object that will be created for you
xml_menus The xml Menus source
xml_menu The xml Menu source of the menu to be created
Returns:
SWITCH_STATUS_SUCCESS if all is well

Definition at line 768 of file switch_ivr_menu.c.

References switch_ivr_menu_xml_map::action, switch_ivr_menu_xml_map::function, is_valid_action(), switch_ivr_menu_xml_map::name, switch_xml::next, switch_ivr_menu_xml_map::next, pool, SWITCH_CHANNEL_LOG, SWITCH_IVR_ACTION_EXECMENU, switch_ivr_menu_bind_action(), switch_ivr_menu_bind_function(), switch_ivr_menu_find(), SWITCH_IVR_MENU_FLAG_FREEPOOL, switch_ivr_menu_init(), switch_ivr_menu_stack_xml_build(), SWITCH_LOG_DEBUG, SWITCH_LOG_ERROR, switch_log_printf(), switch_set_flag, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_xml_attr(), switch_xml_attr_soft(), switch_xml_child(), switch_xml_find_child(), and zstr.

Referenced by switch_ivr_menu_stack_xml_build().

00770 {
00771         switch_status_t status = SWITCH_STATUS_FALSE;
00772 
00773         if (xml_menu_ctx != NULL && menu_stack != NULL && xml_menu != NULL) {
00774                 const char *menu_name = switch_xml_attr_soft(xml_menu, "name"); /* if the attr doesn't exist, return "" */
00775                 const char *greet_long = switch_xml_attr(xml_menu, "greet-long");       /* if the attr doesn't exist, return NULL */
00776                 const char *greet_short = switch_xml_attr(xml_menu, "greet-short");     /* if the attr doesn't exist, return NULL */
00777                 const char *invalid_sound = switch_xml_attr(xml_menu, "invalid-sound"); /* if the attr doesn't exist, return NULL */
00778                 const char *exit_sound = switch_xml_attr(xml_menu, "exit-sound");       /* if the attr doesn't exist, return NULL */
00779                 const char *timeout = switch_xml_attr_soft(xml_menu, "timeout");        /* if the attr doesn't exist, return "" */
00780                 const char *max_failures = switch_xml_attr_soft(xml_menu, "max-failures");      /* if the attr doesn't exist, return "" */
00781                 const char *max_timeouts = switch_xml_attr_soft(xml_menu, "max-timeouts");
00782                 const char *confirm_macro = switch_xml_attr(xml_menu, "confirm-macro");
00783                 const char *confirm_key = switch_xml_attr(xml_menu, "confirm-key");
00784                 const char *tts_engine = switch_xml_attr(xml_menu, "tts-engine");
00785                 const char *tts_voice = switch_xml_attr(xml_menu, "tts-voice");
00786                 const char *confirm_attempts = switch_xml_attr_soft(xml_menu, "confirm-attempts");
00787                 const char *digit_len = switch_xml_attr_soft(xml_menu, "digit-len");
00788                 const char *inter_timeout = switch_xml_attr_soft(xml_menu, "inter-digit-timeout");
00789 
00790                 switch_ivr_menu_t *menu = NULL;
00791 
00792                 if (zstr(max_timeouts)) {
00793                         max_timeouts = max_failures;
00794                 }
00795 
00796                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "building menu '%s'\n", menu_name);
00797 
00798                 status = switch_ivr_menu_init(&menu,
00799                                                                           *menu_stack,
00800                                                                           menu_name,
00801                                                                           greet_long,
00802                                                                           greet_short,
00803                                                                           invalid_sound,
00804                                                                           exit_sound,
00805                                                                           confirm_macro,
00806                                                                           confirm_key,
00807                                                                           tts_engine,
00808                                                                           tts_voice,
00809                                                                           atoi(confirm_attempts),
00810                                                                           atoi(inter_timeout),
00811                                                                           atoi(digit_len),
00812                                                                           atoi(timeout),
00813                                                                           strlen(max_failures) ? atoi(max_failures) : 0, strlen(max_timeouts) ? atoi(max_timeouts) : 0, xml_menu_ctx->pool);
00814                 /* set the menu_stack for the caller */
00815                 if (status == SWITCH_STATUS_SUCCESS && *menu_stack == NULL) {
00816                         *menu_stack = menu;
00817 
00818                         if (xml_menu_ctx->autocreated) {
00819                                 switch_set_flag(menu, SWITCH_IVR_MENU_FLAG_FREEPOOL);
00820                         }
00821                 }
00822 
00823                 if (status == SWITCH_STATUS_SUCCESS && menu != NULL) {
00824                         switch_xml_t xml_kvp;
00825 
00826                         /* build menu entries */
00827                         for (xml_kvp = switch_xml_child(xml_menu, "entry"); xml_kvp != NULL && status == SWITCH_STATUS_SUCCESS; xml_kvp = xml_kvp->next) {
00828                                 const char *action = switch_xml_attr(xml_kvp, "action");
00829                                 const char *digits = switch_xml_attr(xml_kvp, "digits");
00830                                 const char *param = switch_xml_attr_soft(xml_kvp, "param");
00831 
00832                                 if (is_valid_action(action) && !zstr(digits)) {
00833                                         switch_ivr_menu_xml_map_t *xml_map = xml_menu_ctx->map;
00834                                         int found = 0;
00835 
00836                                         /* find and appropriate xml handler */
00837                                         while (xml_map != NULL && !found) {
00838                                                 if (!(found = (strcasecmp(xml_map->name, action) == 0))) {
00839                                                         xml_map = xml_map->next;
00840                                                 }
00841                                         }
00842 
00843                                         if (found && xml_map != NULL) {
00844                                                 /* do we need to build a new sub-menu ? */
00845                                                 if (xml_map->action == SWITCH_IVR_ACTION_EXECMENU && switch_ivr_menu_find(*menu_stack, param) == NULL) {
00846                                                         if ((xml_menu = switch_xml_find_child(xml_menus, "menu", "name", param)) != NULL) {
00847                                                                 status = switch_ivr_menu_stack_xml_build(xml_menu_ctx, menu_stack, xml_menus, xml_menu);
00848                                                         }
00849                                                 }
00850                                                 /* finally bind the menu entry */
00851                                                 if (status == SWITCH_STATUS_SUCCESS) {
00852                                                         if (xml_map->function != NULL) {
00853                                                                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
00854                                                                                                   "binding menu caller control '%s'/'%s' to '%s'\n", xml_map->name, param, digits);
00855                                                                 status = switch_ivr_menu_bind_function(menu, xml_map->function, param, digits);
00856                                                         } else {
00857                                                                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "binding menu action '%s' to '%s'\n", xml_map->name, digits);
00858                                                                 status = switch_ivr_menu_bind_action(menu, xml_map->action, param, digits);
00859                                                         }
00860                                                 }
00861                                         }
00862                                 } else {
00863                                         status = SWITCH_STATUS_FALSE;
00864                                 }
00865                         }
00866                 }
00867         }
00868 
00869         if (status != SWITCH_STATUS_SUCCESS) {
00870                 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to build xml menu\n");
00871         }
00872 
00873         return status;
00874 }

switch_status_t switch_ivr_menu_stack_xml_init ( switch_ivr_menu_xml_ctx_t **  xml_menu_ctx,
switch_memory_pool_t pool 
)

Parameters:
xml_menu_ctx A pointer of a XML menu parser context to be created
pool memory pool (NULL to create one)
Returns:
SWITCH_STATUS_SUCCESS if all is well

Definition at line 727 of file switch_ivr_menu.c.

References iam, iam_s::name, SWITCH_CHANNEL_LOG, switch_core_alloc, switch_core_new_memory_pool, switch_ivr_menu_stack_xml_add(), SWITCH_LOG_ERROR, switch_log_printf(), SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.

00728 {
00729         switch_status_t status = SWITCH_STATUS_FALSE;
00730         int autocreated = 0;
00731 
00732         /* build a memory pool ? */
00733         if (pool == NULL) {
00734                 status = switch_core_new_memory_pool(&pool);
00735                 autocreated = 1;
00736         }
00737         /* allocate the xml context */
00738         if (xml_menu_ctx != NULL && pool != NULL) {
00739                 *xml_menu_ctx = switch_core_alloc(pool, sizeof(switch_ivr_menu_xml_ctx_t));
00740                 if (*xml_menu_ctx != NULL) {
00741                         (*xml_menu_ctx)->pool = pool;
00742                         (*xml_menu_ctx)->autocreated = autocreated;
00743                         (*xml_menu_ctx)->map = NULL;
00744                         status = SWITCH_STATUS_SUCCESS;
00745                 } else {
00746                         switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to alloc xml_ctx\n");
00747                         status = SWITCH_STATUS_FALSE;
00748                 }
00749         }
00750         /* build the standard/default xml menu handler mappings */
00751         if (status == SWITCH_STATUS_SUCCESS && xml_menu_ctx != NULL && *xml_menu_ctx != NULL) {
00752                 int i;
00753 
00754                 for (i = 0; iam[i].name && status == SWITCH_STATUS_SUCCESS; i++) {
00755                         status = switch_ivr_menu_stack_xml_add(*xml_menu_ctx, iam[i].name, iam[i].action, NULL);
00756                 }
00757         }
00758 
00759         return status;
00760 }

switch_status_t switch_ivr_menu_str2action ( const char *  action_name,
switch_ivr_action_t action 
)

Definition at line 687 of file switch_ivr_menu.c.

References iam, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, and zstr.

Referenced by IVRMenu::bindAction().

00688 {
00689         int i;
00690 
00691         if (!zstr(action_name)) {
00692                 for (i = 0;; i++) {
00693                         if (!iam[i].name) {
00694                                 break;
00695                         }
00696 
00697                         if (!strcasecmp(iam[i].name, action_name)) {
00698                                 *action = iam[i].action;
00699                                 return SWITCH_STATUS_SUCCESS;
00700                         }
00701                 }
00702         }
00703 
00704         return SWITCH_STATUS_FALSE;
00705 }

void switch_ivr_park_session ( switch_core_session_t session  ) 

Definition at line 2729 of file switch_ivr.c.

References CF_TRANSFER, CS_PARK, switch_channel_set_flag, switch_channel_set_state, and switch_core_session_get_channel().

Referenced by audio_bridge_on_exchange_media(), signal_bridge_on_hangup(), and switch_ivr_multi_threaded_bridge().

02730 {
02731         switch_channel_t *channel = switch_core_session_get_channel(session);
02732         switch_channel_set_state(channel, CS_PARK);
02733         switch_channel_set_flag(channel, CF_TRANSFER);
02734 
02735 }

switch_status_t switch_ivr_phrase_macro_event ( switch_core_session_t session,
const char *  macro_name,
const char *  data,
switch_event_t event,
const char *  lang,
switch_input_args_t args 
)

Definition at line 39 of file switch_ivr_play_say.c.

References switch_say_args_t::gender, switch_say_args_t::method, switch_say_interface::say_function, switch_assert, switch_channel_event_set_data(), switch_channel_expand_variables, switch_channel_get_variable, switch_channel_pre_answer, SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_variable, switch_core_session_exec(), switch_core_session_get_channel(), switch_core_session_strdup, switch_event_add_header_string(), switch_event_create, switch_event_destroy(), switch_event_expand_headers, SWITCH_EVENT_REQUEST_PARAMS, SWITCH_FALSE, switch_ivr_get_say_gender_by_name(), switch_ivr_get_say_method_by_name(), switch_ivr_get_say_type_by_name(), switch_ivr_phrase_macro, switch_ivr_play_file(), switch_ivr_sleep(), switch_ivr_speak_text(), switch_loadable_module_get_application_interface(), switch_loadable_module_get_say_interface(), SWITCH_LOG_DEBUG, SWITCH_LOG_ERROR, switch_log_printf(), SWITCH_LOG_WARNING, switch_perform_substitution(), switch_regex_perform(), switch_regex_safe_free, switch_safe_free, switch_separate_paren_args(), SWITCH_STACK_BOTTOM, SWITCH_STATUS_BREAK, SWITCH_STATUS_FALSE, SWITCH_STATUS_GENERR, SWITCH_STATUS_SUCCESS, switch_str_nil, switch_true(), SWITCH_TRUE, switch_xml_attr(), switch_xml_attr_soft(), switch_xml_child(), switch_xml_find_child(), switch_xml_free(), switch_xml_locate_language(), switch_say_args_t::type, UNPROTECT_INTERFACE, and zstr.

00041 {
00042         switch_event_t *hint_data;
00043         switch_xml_t cfg, xml = NULL, language = NULL, macros = NULL, phrases = NULL, macro, input, action;
00044         switch_status_t status = SWITCH_STATUS_GENERR;
00045         const char *old_sound_prefix = NULL, *sound_path = NULL, *tts_engine = NULL, *tts_voice = NULL;
00046         const char *module_name = NULL, *chan_lang = NULL;
00047         switch_channel_t *channel = switch_core_session_get_channel(session);
00048         uint8_t done = 0;
00049         int matches = 0;
00050         const char *pause_val;
00051         int pause = 100;
00052         const char *group_macro_name = NULL;
00053         const char *local_macro_name = macro_name;
00054         switch_bool_t sound_prefix_enforced = switch_true(switch_channel_get_variable(channel, "sound_prefix_enforced"));
00055         switch_bool_t local_sound_prefix_enforced = SWITCH_FALSE;
00056 
00057         if (!macro_name) {
00058                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No phrase macro specified.\n");
00059                 return status;
00060         }
00061 
00062         if (!lang) {
00063                 chan_lang = switch_channel_get_variable(channel, "default_language");
00064                 if (!chan_lang) {
00065                         chan_lang = "en";
00066                 }
00067                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "No language specified - Using [%s]\n", chan_lang);
00068         } else {
00069                 chan_lang = lang;
00070         }
00071 
00072         switch_event_create(&hint_data, SWITCH_EVENT_REQUEST_PARAMS);
00073         switch_assert(hint_data);
00074 
00075         switch_event_add_header_string(hint_data, SWITCH_STACK_BOTTOM, "macro_name", macro_name);
00076         switch_event_add_header_string(hint_data, SWITCH_STACK_BOTTOM, "lang", chan_lang);
00077         if (data) {
00078                 switch_event_add_header_string(hint_data, SWITCH_STACK_BOTTOM, "data", data);
00079                 if (event) {
00080                         switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "data", data);
00081                 }
00082         } else {
00083                 data = "";
00084         }
00085         switch_channel_event_set_data(channel, hint_data);
00086 
00087         if (switch_xml_locate_language(&xml, &cfg, hint_data, &language, &phrases, &macros, chan_lang) != SWITCH_STATUS_SUCCESS) {
00088                 goto done;
00089         }
00090 
00091         if ((module_name = switch_xml_attr(language, "say-module"))) {
00092         } else if ((module_name = switch_xml_attr(language, "module"))) {
00093                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Deprecated usage of module attribute. Use say-module instead\n");
00094         } else {
00095                 module_name = chan_lang;
00096         }
00097 
00098         if (!(sound_path = (char *) switch_xml_attr(language, "sound-prefix"))) {
00099                 if (!(sound_path = (char *) switch_xml_attr(language, "sound-path"))) {
00100                         sound_path = (char *) switch_xml_attr(language, "sound_path");
00101                 }
00102         }
00103 
00104         if (!(tts_engine = (char *) switch_xml_attr(language, "tts-engine"))) {
00105                 tts_engine = (char *) switch_xml_attr(language, "tts_engine");
00106         }
00107 
00108         if (!(tts_voice = (char *) switch_xml_attr(language, "tts-voice"))) {
00109                 tts_voice = (char *) switch_xml_attr(language, "tts_voice");
00110         }
00111 
00112         /* If we use the new structure, check for a group name */
00113         if (language != macros) {
00114                 char *p;
00115                 char *macro_name_dup = switch_core_session_strdup(session, macro_name);
00116                 const char *group_sound_path;
00117                 const char *sound_prefix_enforced_str;
00118 
00119                 if ((p = strchr(macro_name_dup, '@'))) {
00120                         *p++ = '\0';
00121                         local_macro_name = macro_name_dup;
00122                         group_macro_name = p;
00123 
00124                         if (!(macros = switch_xml_find_child(phrases, "macros", "name", group_macro_name))) {
00125                                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find macros group %s.\n", group_macro_name);
00126                                 goto done;
00127                         }
00128                 }
00129                 /* Support override of certain language attribute */
00130                 if ((group_sound_path = (char *) switch_xml_attr(macros, "sound-prefix")) || (group_sound_path = (char *) switch_xml_attr(macros, "sound-path")) || (group_sound_path = (char *) switch_xml_attr(macros, "sound_path"))) {
00131                         sound_path = group_sound_path;
00132                 }
00133 
00134                 if (sound_prefix_enforced == SWITCH_FALSE && (sound_prefix_enforced_str = switch_xml_attr(macros, "sound-prefix-enforced"))
00135                                 && (local_sound_prefix_enforced = switch_true(sound_prefix_enforced_str)) == SWITCH_TRUE) {
00136                         switch_channel_set_variable(channel, "sound_prefix_enforced", sound_prefix_enforced_str);
00137                 }
00138 
00139         }
00140 
00141         if (!(macro = switch_xml_find_child(macros, "macro", "name", local_macro_name))) {
00142                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find macro %s.\n", macro_name);
00143                 goto done;
00144         }
00145 
00146         if (sound_path && sound_prefix_enforced == SWITCH_FALSE) {
00147                 char *p;
00148                 old_sound_prefix = switch_str_nil(switch_channel_get_variable(channel, "sound_prefix"));
00149                 p = switch_core_session_strdup(session, old_sound_prefix);
00150                 old_sound_prefix = p;
00151                 switch_channel_set_variable(channel, "sound_prefix", sound_path);
00152         }
00153 
00154         if ((pause_val = switch_xml_attr(macro, "pause"))) {
00155                 int tmp = atoi(pause_val);
00156                 if (tmp >= 0) {
00157                         pause = tmp;
00158                 }
00159         }
00160 
00161         if (!(input = switch_xml_child(macro, "input"))) {
00162                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find any input tags.\n");
00163                 goto done;
00164         }
00165 
00166         if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) {
00167                 status = SWITCH_STATUS_FALSE;
00168                 goto done;
00169         }
00170 
00171         while (input && !done) {
00172                 char *field = (char *) switch_xml_attr(input, "field");
00173                 char *pattern = (char *) switch_xml_attr(input, "pattern");
00174                 const char *do_break = switch_xml_attr_soft(input, "break_on_match");
00175                 char *field_expanded = NULL;
00176                 char *field_expanded_alloc = NULL;
00177 
00178                 if (!field) {
00179                         field = (char *) data;
00180                 }
00181                 if (event) {
00182                         field_expanded_alloc = switch_event_expand_headers(event, field);
00183                 } else {
00184                         field_expanded_alloc = switch_channel_expand_variables(channel, field);
00185                 }
00186 
00187                 if (field_expanded_alloc == field) {
00188                         field_expanded_alloc = NULL;
00189                         field_expanded = field;
00190                 } else {
00191                         field_expanded = field_expanded_alloc;
00192                 }
00193 
00194                 if (pattern) {
00195                         switch_regex_t *re = NULL;
00196                         int proceed = 0, ovector[100];
00197                         char *substituted = NULL;
00198                         uint32_t len = 0;
00199                         char *odata = NULL;
00200                         char *expanded = NULL;
00201                         switch_xml_t match = NULL;
00202 
00203                         status = SWITCH_STATUS_SUCCESS;
00204 
00205                         if ((proceed = switch_regex_perform(field_expanded, pattern, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
00206                                 match = switch_xml_child(input, "match");
00207                         } else {
00208                                 match = switch_xml_child(input, "nomatch");
00209                         }
00210 
00211                         if (match) {
00212                                 matches++;
00213                                 for (action = switch_xml_child(match, "action"); action && status == SWITCH_STATUS_SUCCESS; action = action->next) {
00214                                         char *adata = (char *) switch_xml_attr_soft(action, "data");
00215                                         char *func = (char *) switch_xml_attr_soft(action, "function");
00216 
00217                                         if (strchr(pattern, '(') && strchr(adata, '$') && proceed > 0) {
00218                                                 len = (uint32_t) (strlen(data) + strlen(adata) + 10) * proceed;
00219                                                 if (!(substituted = malloc(len))) {
00220                                                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Memory Error!\n");
00221                                                         switch_regex_safe_free(re);
00222                                                         switch_safe_free(expanded);
00223                                                         goto done;
00224                                                 }
00225                                                 memset(substituted, 0, len);
00226                                                 switch_perform_substitution(re, proceed, adata, field_expanded, substituted, len, ovector);
00227                                                 odata = substituted;
00228                                         } else {
00229                                                 odata = adata;
00230                                         }
00231 
00232                                         if (event) {
00233                                                 expanded = switch_event_expand_headers(event, odata);
00234                                         } else {
00235                                                 expanded = switch_channel_expand_variables(channel, odata);
00236                                         }
00237 
00238                                         if (expanded == odata) {
00239                                                 expanded = NULL;
00240                                         } else {
00241                                                 odata = expanded;
00242                                         }
00243 
00244                                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Handle %s:[%s] (%s:%s)\n", func, odata, chan_lang,
00245                                                                           module_name);
00246 
00247                                         if (!strcasecmp(func, "play-file")) {
00248                                                 status = switch_ivr_play_file(session, NULL, odata, args);
00249                                         } else if (!strcasecmp(func, "phrase")) {
00250                                                 char *name = (char *) switch_xml_attr_soft(action, "phrase");
00251                                                 status = switch_ivr_phrase_macro(session, name, odata, chan_lang, args);
00252                                         } else if (!strcasecmp(func, "break")) {
00253                                                 done = 1;
00254                                                 /* must allow the switch_safe_free below to execute or we leak - do not break here */
00255                                         } else if (!strcasecmp(func, "execute")) {
00256                                                 switch_application_interface_t *app;
00257                                                 char *cmd, *cmd_args;
00258                                                 status = SWITCH_STATUS_FALSE;
00259 
00260                                                 cmd = switch_core_session_strdup(session, odata);
00261                                                 cmd_args = switch_separate_paren_args(cmd);
00262 
00263                                                 if (!cmd_args) {
00264                                                         cmd_args = "";
00265                                                 }
00266 
00267                                                 if ((app = switch_loadable_module_get_application_interface(cmd)) != NULL) {
00268                                                         status = switch_core_session_exec(session, app, cmd_args);
00269                                                         UNPROTECT_INTERFACE(app);
00270                                                 } else {
00271                                                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid Application %s\n", cmd);
00272                                                 }
00273                                         } else if (!strcasecmp(func, "say")) {
00274                                                 switch_say_interface_t *si;
00275                                                 if ((si = switch_loadable_module_get_say_interface(module_name))) {
00276                                                         char *say_type = (char *) switch_xml_attr_soft(action, "type");
00277                                                         char *say_method = (char *) switch_xml_attr_soft(action, "method");
00278                                                         char *say_gender = (char *) switch_xml_attr_soft(action, "gender");
00279                                                         switch_say_args_t say_args = {0};
00280 
00281                                                         say_args.type = switch_ivr_get_say_type_by_name(say_type);
00282                                                         say_args.method = switch_ivr_get_say_method_by_name(say_method);
00283                                                         say_args.gender = switch_ivr_get_say_gender_by_name(say_gender);
00284 
00285                                                         status = si->say_function(session, odata, &say_args, args);
00286                                                 } else {
00287                                                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid SAY Interface [%s]!\n", module_name);
00288                                                 }
00289                                         } else if (!strcasecmp(func, "speak-text")) {
00290                                                 const char *my_tts_engine = switch_xml_attr(action, "tts-engine");
00291                                                 const char *my_tts_voice = switch_xml_attr(action, "tts-voice");
00292 
00293                                                 if (!my_tts_engine) {
00294                                                         my_tts_engine = tts_engine;
00295                                                 }
00296 
00297                                                 if (!my_tts_voice) {
00298                                                         my_tts_voice = tts_voice;
00299                                                 }
00300                                                 if (zstr(tts_engine) || zstr(tts_voice)) {
00301                                                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "TTS is not configured\n");
00302                                                 } else {
00303                                                         status = switch_ivr_speak_text(session, my_tts_engine, my_tts_voice, odata, args);
00304                                                 }
00305                                         }
00306 
00307                                         switch_ivr_sleep(session, pause, SWITCH_FALSE, NULL);
00308                                         switch_safe_free(expanded);
00309                                         switch_safe_free(substituted);
00310                                         
00311                                 }
00312                         }
00313 
00314                         switch_regex_safe_free(re);
00315                         
00316                         if ((match && do_break && switch_true(do_break)) || status == SWITCH_STATUS_BREAK) {
00317                                 break;
00318                         }
00319 
00320                 }
00321 
00322                 switch_safe_free(field_expanded_alloc);
00323 
00324                 if (status != SWITCH_STATUS_SUCCESS) {
00325                         done = 1;
00326                         break;
00327                 }
00328 
00329                 input = input->next;
00330         }
00331 
00332   done:
00333 
00334         if (hint_data) {
00335                 switch_event_destroy(&hint_data);
00336         }
00337 
00338         if (!matches) {
00339                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Macro [%s]: '%s' did not match any patterns\n", macro_name, data);
00340         }
00341 
00342         if (old_sound_prefix) {
00343                 switch_channel_set_variable(channel, "sound_prefix", old_sound_prefix);
00344         }
00345         if (local_sound_prefix_enforced == SWITCH_TRUE) {
00346                 switch_channel_set_variable(channel, "sound_prefix_enforced", NULL);
00347         }
00348 
00349         if (xml) {
00350                 switch_xml_free(xml);
00351         }
00352 
00353         return status;
00354 }

switch_status_t switch_ivr_process_fh ( switch_core_session_t session,
const char *  cmd,
switch_file_handle_t fhp 
)

Definition at line 3141 of file switch_ivr.c.

References switch_codec::implementation, switch_codec_implementation::samples_per_second, switch_atoui(), SWITCH_CHANNEL_SESSION_LOG, switch_clear_flag, switch_core_file_seek(), switch_core_file_truncate(), switch_core_session_get_read_codec(), SWITCH_FILE_DONE, SWITCH_FILE_OPEN, SWITCH_FILE_PAUSE, SWITCH_LOG_DEBUG, switch_log_printf(), switch_normalize_volume, switch_set_flag, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_test_flag, and zstr.

Referenced by CoreSession::process_callback_result().

03142 {
03143     if (zstr(cmd)) {
03144                 return SWITCH_STATUS_SUCCESS;   
03145     }
03146 
03147         if (fhp) {
03148                 if (!switch_test_flag(fhp, SWITCH_FILE_OPEN)) {
03149                         return SWITCH_STATUS_FALSE;
03150                 }
03151 
03152                 if (!strncasecmp(cmd, "speed", 5)) {
03153                         char *p;
03154                 
03155                         if ((p = strchr(cmd, ':'))) {
03156                                 p++;
03157                                 if (*p == '+' || *p == '-') {
03158                                         int step;
03159                                         if (!(step = atoi(p))) {
03160                                                 step = 1;
03161                                         }
03162                                         fhp->speed += step;
03163                                 } else {
03164                                         int speed = atoi(p);
03165                                         fhp->speed = speed;
03166                                 }
03167                                 return SWITCH_STATUS_SUCCESS;
03168                         }
03169 
03170                         return SWITCH_STATUS_FALSE;
03171 
03172                 } else if (!strncasecmp(cmd, "volume", 6)) {
03173                         char *p;
03174                         
03175                         if ((p = strchr(cmd, ':'))) {
03176                                 p++;
03177                                 if (*p == '+' || *p == '-') {
03178                                         int step;
03179                                         if (!(step = atoi(p))) {
03180                                                 step = 1;
03181                                         }
03182                                         fhp->vol += step;
03183                                 } else {
03184                                         int vol = atoi(p);
03185                                         fhp->vol = vol;
03186                                 }
03187                                 return SWITCH_STATUS_SUCCESS;
03188                         }
03189                         
03190                         if (fhp->vol) {
03191                                 switch_normalize_volume(fhp->vol);
03192                         }
03193                         
03194                         return SWITCH_STATUS_FALSE;
03195                 } else if (!strcasecmp(cmd, "pause")) {
03196                         if (switch_test_flag(fhp, SWITCH_FILE_PAUSE)) {
03197                                 switch_clear_flag(fhp, SWITCH_FILE_PAUSE);
03198                         } else {
03199                                 switch_set_flag(fhp, SWITCH_FILE_PAUSE);
03200                         }
03201                         return SWITCH_STATUS_SUCCESS;
03202                 } else if (!strcasecmp(cmd, "stop")) {
03203                         switch_set_flag(fhp, SWITCH_FILE_DONE);
03204                         return SWITCH_STATUS_FALSE;
03205                 } else if (!strcasecmp(cmd, "truncate")) {
03206                         switch_core_file_truncate(fhp, 0);
03207                 } else if (!strcasecmp(cmd, "restart")) {
03208                         unsigned int pos = 0;
03209                         fhp->speed = 0;
03210                         switch_core_file_seek(fhp, &pos, 0, SEEK_SET);
03211                         return SWITCH_STATUS_SUCCESS;
03212                 } else if (!strncasecmp(cmd, "seek", 4)) {
03213                         switch_codec_t *codec;
03214                         unsigned int samps = 0;
03215                         unsigned int pos = 0;
03216                         char *p;
03217                         codec = switch_core_session_get_read_codec(session);
03218                         
03219                         if ((p = strchr(cmd, ':'))) {
03220                                 p++;
03221                                 if (*p == '+' || *p == '-') {
03222                                         int step;
03223                                         int32_t target;
03224                                         if (!(step = atoi(p))) {
03225                                                 step = 1000;
03226                                         }
03227 
03228                                         samps = step * (codec->implementation->samples_per_second / 1000);
03229                                         target = (int32_t)fhp->pos + samps;
03230 
03231                                         if (target < 0) {
03232                                                 target = 0;
03233                                         }
03234 
03235                                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "seek to position %d\n", target);
03236                                         switch_core_file_seek(fhp, &pos, target, SEEK_SET);
03237 
03238                                 } else {
03239                                         samps = switch_atoui(p) * (codec->implementation->samples_per_second / 1000);
03240                                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "seek to position %d\n", samps);
03241                                         switch_core_file_seek(fhp, &pos, samps, SEEK_SET);
03242                                 }
03243                         }
03244 
03245                         return SWITCH_STATUS_SUCCESS;
03246                 }
03247         }
03248 
03249     if (!strcmp(cmd, "true") || !strcmp(cmd, "undefined")) {
03250                 return SWITCH_STATUS_SUCCESS;
03251     }
03252 
03253     return SWITCH_STATUS_FALSE;
03254         
03255 }

switch_status_t switch_ivr_read ( switch_core_session_t session,
uint32_t  min_digits,
uint32_t  max_digits,
const char *  prompt_audio_file,
const char *  var_name,
char *  digit_buffer,
switch_size_t  digit_buffer_length,
uint32_t  timeout,
const char *  valid_terminators,
uint32_t  digit_timeout 
)

Definition at line 1865 of file switch_ivr_play_say.c.

References switch_input_args_t::buf, switch_input_args_t::buflen, switch_assert, switch_channel_pre_answer, SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_variable, switch_core_session_get_channel(), switch_ivr_collect_digits_count(), switch_ivr_play_file(), SWITCH_LOG_ERROR, switch_log_printf(), SWITCH_LOG_WARNING, SWITCH_READ_RESULT_VARIABLE, SWITCH_READ_TERMINATOR_USED_VARIABLE, switch_snprintf(), SWITCH_STATUS_BREAK, SWITCH_STATUS_FALSE, SWITCH_STATUS_RESTART, SWITCH_STATUS_SUCCESS, SWITCH_STATUS_TIMEOUT, SWITCH_STATUS_TOO_SMALL, and zstr.

Referenced by collect_thread_run(), CoreSession::read(), and switch_play_and_get_digits().

01876 {
01877         switch_channel_t *channel;
01878         switch_input_args_t args = { 0 };
01879         switch_status_t status = SWITCH_STATUS_SUCCESS;
01880         size_t len = 0;
01881         char tb[2] = "";
01882 
01883         switch_assert(session);
01884 
01885         if (!digit_timeout) {
01886                 digit_timeout = timeout;
01887         }
01888 
01889         if (max_digits < min_digits) {
01890                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING,
01891                                                   "Max digits %u is less than Min %u, forcing Max to %u\n", max_digits, min_digits, min_digits);
01892                 max_digits = min_digits;
01893         }
01894 
01895         channel = switch_core_session_get_channel(session);
01896         switch_channel_set_variable(channel, SWITCH_READ_RESULT_VARIABLE, NULL);
01897 
01898         if (var_name) {
01899                 switch_channel_set_variable(channel, var_name, NULL);
01900         }
01901 
01902         if ((min_digits && digit_buffer_length < min_digits) || digit_buffer_length < max_digits) {
01903                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Buffer too small!\n");
01904                 return SWITCH_STATUS_FALSE;
01905         }
01906 
01907         if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) {
01908                 return SWITCH_STATUS_FALSE;
01909         }
01910 
01911         memset(digit_buffer, 0, digit_buffer_length);
01912         args.buf = digit_buffer;
01913         args.buflen = (uint32_t) digit_buffer_length;
01914 
01915         if (!zstr(prompt_audio_file) && strcasecmp(prompt_audio_file, "silence")) {
01916                 if ((status = switch_ivr_play_file(session, NULL, prompt_audio_file, &args)) == SWITCH_STATUS_BREAK) {
01917                         status = SWITCH_STATUS_SUCCESS;
01918                 }
01919         }
01920 
01921         if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) {
01922                 goto end;
01923         }
01924 
01925         len = strlen(digit_buffer);
01926 
01927         if ((min_digits && len < min_digits) || len < max_digits) {
01928                 args.buf = digit_buffer + len;
01929                 args.buflen = (uint32_t) (digit_buffer_length - len);
01930                 status = switch_ivr_collect_digits_count(session, digit_buffer, digit_buffer_length, max_digits, valid_terminators, &tb[0], 
01931                                                                                                  len ? digit_timeout : timeout, digit_timeout, 0);
01932         }
01933 
01934 
01935         if (tb[0]) {
01936                 char *p;
01937 
01938                 switch_channel_set_variable(channel, SWITCH_READ_TERMINATOR_USED_VARIABLE, tb);
01939 
01940                 if ((p = strchr(valid_terminators, tb[0]))) {
01941                         if (p >= (valid_terminators + 1) && (*(p - 1) == '+' || *(p - 1) == 'x')) {
01942                                 switch_snprintf(digit_buffer + strlen(digit_buffer), digit_buffer_length - strlen(digit_buffer), "%s", tb);
01943                                 if (*(p - 1) == 'x') {
01944                                         status = SWITCH_STATUS_RESTART;
01945                                 }
01946                         }
01947                 }
01948         }
01949 
01950         len = strlen(digit_buffer);
01951         if ((min_digits && len < min_digits)) {
01952                 status = SWITCH_STATUS_TOO_SMALL;
01953         }
01954 
01955         switch (status) {
01956         case SWITCH_STATUS_SUCCESS:
01957                 switch_channel_set_variable(channel, SWITCH_READ_RESULT_VARIABLE, "success");
01958                 break;
01959         case SWITCH_STATUS_TIMEOUT:
01960                 switch_channel_set_variable(channel, SWITCH_READ_RESULT_VARIABLE, "timeout");
01961                 break;
01962         default:
01963                 switch_channel_set_variable(channel, SWITCH_READ_RESULT_VARIABLE, "failure");
01964                 break;
01965 
01966         }
01967 
01968   end:
01969 
01970         if (status != SWITCH_STATUS_RESTART && max_digits == 1 && len == 1 && valid_terminators && strchr(valid_terminators, *digit_buffer)) {
01971                 *digit_buffer = '\0';
01972         }
01973 
01974         if (var_name && !zstr(digit_buffer)) {
01975                 switch_channel_set_variable(channel, var_name, digit_buffer);
01976         }
01977 
01978         return status;
01979 
01980 }

switch_status_t switch_ivr_release_file_handle ( switch_core_session_t session,
switch_file_handle_t **  fh 
)

Definition at line 970 of file switch_ivr_play_say.c.

References switch_core_session_io_rwunlock(), and SWITCH_STATUS_SUCCESS.

00971 {
00972         *fh = NULL;
00973         switch_core_session_io_rwunlock(session);
00974 
00975         return SWITCH_STATUS_SUCCESS;
00976 }

switch_status_t switch_ivr_say ( switch_core_session_t session,
const char *  tosay,
const char *  module_name,
const char *  say_type,
const char *  say_method,
const char *  say_gender,
switch_input_args_t args 
)

Definition at line 2788 of file switch_ivr.c.

References switch_say_args_t::gender, switch_say_args_t::method, switch_say_interface::say_function, switch_assert, switch_channel_event_set_data(), switch_channel_get_variable, SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_variable, switch_core_session_get_channel(), switch_core_session_strdup, switch_event_add_header_string(), switch_event_create, switch_event_destroy(), SWITCH_EVENT_REQUEST_PARAMS, switch_ivr_get_say_gender_by_name(), switch_ivr_get_say_method_by_name(), switch_ivr_get_say_type_by_name(), switch_loadable_module_get_say_interface(), SWITCH_LOG_DEBUG, SWITCH_LOG_ERROR, switch_log_printf(), SWITCH_LOG_WARNING, SWITCH_STACK_BOTTOM, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_true(), switch_xml_attr(), switch_xml_free(), switch_xml_locate_language(), switch_say_args_t::type, and zstr.

Referenced by CoreSession::say().

02795 {
02796         switch_say_interface_t *si;
02797         switch_channel_t *channel;
02798         switch_status_t status = SWITCH_STATUS_FALSE;
02799         const char *save_path = NULL, *chan_lang = NULL, *lang = NULL, *sound_path = NULL;
02800         switch_event_t *hint_data;
02801         switch_xml_t cfg, xml = NULL, language = NULL, macros = NULL, phrases = NULL;
02802         char *p;
02803 
02804         switch_assert(session);
02805         channel = switch_core_session_get_channel(session);
02806         switch_assert(channel);
02807 
02808         if (zstr(module_name)) {
02809                 module_name = "en";
02810         }
02811 
02812         if (module_name) {
02813                 char *p;
02814                 p = switch_core_session_strdup(session, module_name);
02815                 module_name = p;
02816                 
02817                 if ((p = strchr(module_name, ':'))) {
02818                         *p++ = '\0';
02819                         chan_lang = p;
02820                 }
02821         }
02822 
02823         if (!chan_lang) {
02824                 lang = switch_channel_get_variable(channel, "language");
02825 
02826                 if (!lang) {
02827                         chan_lang = switch_channel_get_variable(channel, "default_language");
02828                         if (!chan_lang) {
02829                                 chan_lang = module_name;
02830                         }
02831                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "No language specified - Using [%s]\n", chan_lang);
02832                 } else {
02833                         chan_lang = lang;
02834                 }
02835         }
02836 
02837         switch_event_create(&hint_data, SWITCH_EVENT_REQUEST_PARAMS);
02838         switch_assert(hint_data);
02839 
02840         switch_event_add_header_string(hint_data, SWITCH_STACK_BOTTOM, "macro_name", "say_app");
02841         switch_event_add_header_string(hint_data, SWITCH_STACK_BOTTOM, "lang", chan_lang);
02842         switch_channel_event_set_data(channel, hint_data);
02843 
02844         if (switch_xml_locate_language(&xml, &cfg, hint_data, &language, &phrases, &macros, chan_lang) != SWITCH_STATUS_SUCCESS) {
02845                 goto done;
02846         }
02847 
02848         if ((p = (char *) switch_xml_attr(language, "say-module"))) {
02849                 module_name = switch_core_session_strdup(session, p);
02850         } else if ((p = (char *) switch_xml_attr(language, "module"))) {
02851                 module_name = switch_core_session_strdup(session, p);
02852                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Deprecated usage of module attribute\n");
02853         } else {
02854                 module_name = chan_lang;
02855         }
02856 
02857         if (!(sound_path = (char *) switch_xml_attr(language, "sound-prefix"))) {
02858                 if (!(sound_path = (char *) switch_xml_attr(language, "sound-path"))) {
02859                         sound_path = (char *) switch_xml_attr(language, "sound_path");
02860                 }
02861         }
02862 
02863         if (channel) {
02864                 const char *p = switch_channel_get_variable(channel, "sound_prefix_enforced");
02865                 if (!switch_true(p)) {
02866                         save_path = switch_channel_get_variable(channel, "sound_prefix");
02867                         if (sound_path) {
02868                                 switch_channel_set_variable(channel, "sound_prefix", sound_path);
02869                         }
02870                 }
02871         }
02872 
02873         if ((si = switch_loadable_module_get_say_interface(module_name))) {
02874                 /* should go back and proto all the say mods to const.... */
02875                 switch_say_args_t say_args = {0};
02876                 
02877                 say_args.type = switch_ivr_get_say_type_by_name(say_type);
02878                 say_args.method = switch_ivr_get_say_method_by_name(say_method);
02879                 say_args.gender = switch_ivr_get_say_gender_by_name(say_gender);
02880                 
02881                 status = si->say_function(session, (char *) tosay, &say_args, args);
02882         } else {
02883                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid SAY Interface [%s]!\n", module_name);
02884                 status = SWITCH_STATUS_FALSE;
02885         }
02886 
02887   done:
02888 
02889         if (hint_data) {
02890                 switch_event_destroy(&hint_data);
02891         }
02892 
02893         if (save_path) {
02894                 switch_channel_set_variable(channel, "sound_prefix", save_path);
02895         }
02896 
02897         if (xml) {
02898                 switch_xml_free(xml);
02899         }
02900 
02901         return status;
02902 }

switch_status_t switch_ivr_say_ip ( switch_core_session_t session,
char *  tosay,
switch_say_callback_t  number_func,
switch_say_args_t say_args,
switch_input_args_t args 
)

Definition at line 168 of file switch_ivr_say.c.

References say_file, say_num, switch_core_session_strdup, SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.

00173 {
00174         char *a, *b, *c, *d;
00175         if (!(a = switch_core_session_strdup(session, tosay))) {
00176                 return SWITCH_STATUS_FALSE;
00177         }
00178 
00179         if (!(b = strchr(a, '.'))) {
00180                 return SWITCH_STATUS_FALSE;
00181         }
00182 
00183         *b++ = '\0';
00184 
00185         if (!(c = strchr(b, '.'))) {
00186                 return SWITCH_STATUS_FALSE;
00187         }
00188 
00189         *c++ = '\0';
00190 
00191         if (!(d = strchr(c, '.'))) {
00192                 return SWITCH_STATUS_FALSE;
00193         }
00194 
00195         *d++ = '\0';
00196 
00197         say_num(atoi(a), say_args->method);
00198         say_file("digits/dot.wav");
00199         say_num(atoi(b), say_args->method);
00200         say_file("digits/dot.wav");
00201         say_num(atoi(c), say_args->method);
00202         say_file("digits/dot.wav");
00203         say_num(atoi(d), say_args->method);
00204 
00205         return SWITCH_STATUS_SUCCESS;
00206 }

switch_status_t switch_ivr_say_spell ( switch_core_session_t session,
char *  tosay,
switch_say_args_t say_args,
switch_input_args_t args 
)

Definition at line 133 of file switch_ivr_say.c.

References say_file, SST_NAME_PHONETIC, and SST_NAME_SPELLED.

00134 {
00135         char *p;
00136 
00137         for (p = tosay; p && *p; p++) {
00138                 int a = tolower((int) *p);
00139                 if (a >= '0' && a <= '9') {
00140                         say_file("digits/%d.wav", a - '0');
00141                 } else {
00142                         if (say_args->type == SST_NAME_SPELLED) {
00143                                 say_file("ascii/%d.wav", a);
00144                         } else if (say_args->type == SST_NAME_PHONETIC) {
00145                                 say_file("phonetic-ascii/%d.wav", a);
00146                         }
00147                 }
00148         }
00149 
00150         return SWITCH_STATUS_SUCCESS;
00151 }

switch_status_t switch_ivr_say_string ( switch_core_session_t session,
const char *  lang,
const char *  ext,
const char *  tosay,
const char *  module_name,
const char *  say_type,
const char *  say_method,
const char *  say_gender,
char **  rstr 
)

Definition at line 2904 of file switch_ivr.c.

References switch_say_args_t::ext, switch_say_args_t::gender, switch_say_args_t::method, switch_say_interface::say_string_function, switch_assert, switch_channel_event_set_data(), switch_channel_get_variable, SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_variable, switch_core_session_get_channel(), switch_event_add_header_string(), switch_event_create, switch_event_destroy(), SWITCH_EVENT_REQUEST_PARAMS, switch_ivr_get_say_gender_by_name(), switch_ivr_get_say_method_by_name(), switch_ivr_get_say_type_by_name(), switch_loadable_module_get_say_interface(), SWITCH_LOG_DEBUG, SWITCH_LOG_ERROR, switch_log_printf(), SWITCH_LOG_WARNING, SWITCH_STACK_BOTTOM, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_true(), switch_xml_attr(), switch_xml_free(), switch_xml_locate_language(), and switch_say_args_t::type.

02913 {
02914         switch_say_interface_t *si;
02915         switch_channel_t *channel = NULL;
02916         switch_status_t status = SWITCH_STATUS_FALSE;
02917         const char *save_path = NULL, *chan_lang = NULL, *sound_path = NULL;
02918         switch_event_t *hint_data;
02919         switch_xml_t cfg, xml = NULL, language = NULL, macros = NULL, phrases = NULL;
02920 
02921         if (session) {
02922                 channel = switch_core_session_get_channel(session);
02923 
02924                 if (!lang) {
02925                         lang = switch_channel_get_variable(channel, "language");
02926 
02927                         if (!lang) {
02928                                 chan_lang = switch_channel_get_variable(channel, "default_language");
02929                                 if (!chan_lang) {
02930                                         chan_lang = "en";
02931                                 }
02932                                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "No language specified - Using [%s]\n", chan_lang);
02933                         } else {
02934                                 chan_lang = lang;
02935                         }
02936                 }
02937         }
02938 
02939         if (!lang) lang = "en";
02940         if (!chan_lang) chan_lang = lang;
02941 
02942         switch_event_create(&hint_data, SWITCH_EVENT_REQUEST_PARAMS);
02943         switch_assert(hint_data);
02944 
02945         switch_event_add_header_string(hint_data, SWITCH_STACK_BOTTOM, "macro_name", "say_app");
02946         switch_event_add_header_string(hint_data, SWITCH_STACK_BOTTOM, "lang", chan_lang);
02947 
02948         if (channel) {
02949                 switch_channel_event_set_data(channel, hint_data);
02950         }
02951 
02952         if (switch_xml_locate_language(&xml, &cfg, hint_data, &language, &phrases, &macros, chan_lang) != SWITCH_STATUS_SUCCESS) {
02953                 goto done;
02954         }
02955 
02956         if ((module_name = switch_xml_attr(language, "say-module"))) {
02957         } else if ((module_name = switch_xml_attr(language, "module"))) {
02958                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Deprecated usage of module attribute\n");
02959         } else {
02960                 module_name = chan_lang;
02961         }
02962 
02963         if (!(sound_path = (char *) switch_xml_attr(language, "sound-prefix"))) {
02964                 if (!(sound_path = (char *) switch_xml_attr(language, "sound-path"))) {
02965                         sound_path = (char *) switch_xml_attr(language, "sound_path");
02966                 }
02967         }
02968 
02969         if (channel) {
02970                 const char *p = switch_channel_get_variable(channel, "sound_prefix_enforced");  
02971                 if (!switch_true(p)) {
02972                         save_path = switch_channel_get_variable(channel, "sound_prefix");
02973                         if (sound_path) {
02974                                 switch_channel_set_variable(channel, "sound_prefix", sound_path);
02975                         }
02976                 }
02977         }
02978 
02979         if ((si = switch_loadable_module_get_say_interface(module_name))) {
02980                 /* should go back and proto all the say mods to const.... */
02981                 switch_say_args_t say_args = {0};
02982                 
02983                 say_args.type = switch_ivr_get_say_type_by_name(say_type);
02984                 say_args.method = switch_ivr_get_say_method_by_name(say_method);
02985                 say_args.gender = switch_ivr_get_say_gender_by_name(say_gender);
02986                 say_args.ext = ext;
02987                 status = si->say_string_function(session, (char *) tosay, &say_args, rstr);
02988         } else {
02989                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid SAY Interface [%s]!\n", module_name);
02990                 status = SWITCH_STATUS_FALSE;
02991         }
02992 
02993   done:
02994 
02995         if (hint_data) {
02996                 switch_event_destroy(&hint_data);
02997         }
02998 
02999         if (save_path && channel) {
03000                 switch_channel_set_variable(channel, "sound_prefix", save_path);
03001         }
03002 
03003         if (xml) {
03004                 switch_xml_free(xml);
03005         }
03006 
03007         return status;
03008 }

switch_status_t switch_ivr_set_user ( switch_core_session_t session,
const char *  data 
)

Definition at line 3036 of file switch_ivr.c.

References get_prefixed_str(), switch_xml::next, SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_variable, switch_core_session_alloc, switch_core_session_get_channel(), switch_core_session_strdup, SWITCH_LOG_ERROR, switch_log_printf(), SWITCH_LOG_WARNING, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_xml_attr(), switch_xml_child(), switch_xml_free(), switch_xml_locate_user(), and zstr.

03037 {
03038         switch_xml_t x_domain, xml = NULL, x_user, x_param, x_params, x_group = NULL;
03039         char *user, *number_alias, *domain;
03040         switch_channel_t *channel = switch_core_session_get_channel(session);
03041         switch_status_t status = SWITCH_STATUS_FALSE;
03042 
03043         char *prefix_buffer = NULL, *prefix;
03044         size_t buffer_size = 0;
03045         size_t prefix_size = 0;
03046         if (zstr(data)) {
03047                 goto error;
03048         }
03049 
03050         user = switch_core_session_strdup(session, data);
03051 
03052         if ((prefix = strchr(user, ' '))) {
03053                 *prefix++ = 0;
03054         }
03055 
03056         if (!(domain = strchr(user, '@'))) {
03057                 goto error;
03058         }
03059 
03060         *domain++ = '\0';
03061 
03062         if (switch_xml_locate_user("id", user, domain, NULL, &xml, &x_domain, &x_user, &x_group, NULL) != SWITCH_STATUS_SUCCESS) {
03063                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "can't find user [%s@%s]\n", user, domain);
03064                 goto done;
03065         }
03066 
03067         status = SWITCH_STATUS_SUCCESS;
03068 
03069         if (!zstr(prefix)) {
03070                 prefix_size = strlen(prefix);
03071                 buffer_size = 1024 + prefix_size + 1;
03072                 prefix_buffer = switch_core_session_alloc(session, buffer_size);
03073         }
03074 
03075         if ((number_alias = (char *) switch_xml_attr(x_user, "number-alias"))) {
03076                 switch_channel_set_variable(channel, get_prefixed_str(prefix_buffer, buffer_size, prefix, prefix_size, "number_alias"), number_alias);
03077         }
03078 
03079         if ((x_params = switch_xml_child(x_domain, "variables"))) {
03080                 for (x_param = switch_xml_child(x_params, "variable"); x_param; x_param = x_param->next) {
03081                         const char *var = switch_xml_attr(x_param, "name");
03082                         const char *val = switch_xml_attr(x_param, "value");
03083 
03084                         if (var && val) {
03085                                 switch_channel_set_variable(channel, get_prefixed_str(prefix_buffer, buffer_size, prefix, prefix_size, var), val);
03086                         }
03087                 }
03088         }
03089 
03090         if (x_group && (x_params = switch_xml_child(x_group, "variables"))) {
03091                 for (x_param = switch_xml_child(x_params, "variable"); x_param; x_param = x_param->next) {
03092                         const char *var = switch_xml_attr(x_param, "name");
03093                         const char *val = switch_xml_attr(x_param, "value");
03094 
03095                         if (var && val) {
03096                                 switch_channel_set_variable(channel, get_prefixed_str(prefix_buffer, buffer_size, prefix, prefix_size, var), val);
03097                         }
03098                 }
03099         }
03100 
03101         if ((x_params = switch_xml_child(x_user, "variables"))) {
03102                 for (x_param = switch_xml_child(x_params, "variable"); x_param; x_param = x_param->next) {
03103                         const char *var = switch_xml_attr(x_param, "name");
03104                         const char *val = switch_xml_attr(x_param, "value");
03105 
03106                         if (var && val) {
03107                                 switch_channel_set_variable(channel, get_prefixed_str(prefix_buffer, buffer_size, prefix, prefix_size, var), val);
03108                         }
03109                 }
03110         }
03111 
03112         switch_channel_set_variable(channel, get_prefixed_str(prefix_buffer, buffer_size, prefix, prefix_size, "user_name"), user);
03113         switch_channel_set_variable(channel, get_prefixed_str(prefix_buffer, buffer_size, prefix, prefix_size, "domain_name"), domain);
03114 
03115         goto done;
03116 
03117   error:
03118         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No user@domain specified.\n");
03119 
03120   done:
03121         if (xml) {
03122                 switch_xml_free(xml);
03123         }
03124 
03125         return status;
03126 }

switch_status_t switch_ivr_soft_hold ( switch_core_session_t session,
const char *  unhold_key,
const char *  moh_a,
const char *  moh_b 
)

Definition at line 2558 of file switch_ivr_play_say.c.

References switch_input_args_t::buf, switch_input_args_t::buflen, CF_BROADCAST, hold_on_dtmf(), switch_input_args_t::input_callback, SMF_ECHO_ALEG, SMF_LOOP, switch_assert, switch_channel_get_hold_music(), switch_channel_get_name(), switch_channel_get_variable, SWITCH_CHANNEL_SESSION_LOG, switch_channel_stop_broadcast, switch_channel_test_flag(), switch_core_session_get_channel(), switch_core_session_locate(), switch_core_session_rwunlock(), switch_ivr_broadcast(), switch_ivr_collect_digits_callback(), switch_ivr_play_file(), switch_log_printf(), SWITCH_LOG_WARNING, SWITCH_SIGNAL_BOND_VARIABLE, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, and zstr.

02559 {
02560         switch_channel_t *channel, *other_channel;
02561         switch_core_session_t *other_session;
02562         const char *other_uuid, *moh = NULL;
02563         int moh_br = 0;
02564         switch_input_args_t args = { 0 };
02565         args.input_callback = hold_on_dtmf;
02566         args.buf = (void *) unhold_key;
02567         args.buflen = (uint32_t) strlen(unhold_key);
02568 
02569         switch_assert(session != NULL);
02570         channel = switch_core_session_get_channel(session);
02571         switch_assert(channel != NULL);
02572 
02573         if ((other_uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE))) {
02574                 if ((other_session = switch_core_session_locate(other_uuid))) {
02575                         other_channel = switch_core_session_get_channel(other_session);
02576 
02577                         if (moh_b) {
02578                                 moh = moh_b;
02579                         } else {
02580                                 moh = switch_channel_get_hold_music(other_channel);
02581                         }
02582 
02583                         if (!zstr(moh) && strcasecmp(moh, "silence") && !switch_channel_test_flag(other_channel, CF_BROADCAST)) {
02584                                 switch_ivr_broadcast(other_uuid, moh, SMF_ECHO_ALEG | SMF_LOOP);
02585                                 moh_br++;
02586                         }
02587 
02588                         if (moh_a) {
02589                                 moh = moh_a;
02590                         } else {
02591                                 moh = switch_channel_get_hold_music(channel);
02592                         }
02593 
02594                         if (!zstr(moh) && strcasecmp(moh, "silence")) {
02595                                 switch_ivr_play_file(session, NULL, moh, &args);
02596                         } else {
02597                                 switch_ivr_collect_digits_callback(session, &args, 0, 0);
02598                         }
02599 
02600                         if (moh_br) {
02601                                 switch_channel_stop_broadcast(other_channel);
02602                         }
02603 
02604                         switch_core_session_rwunlock(other_session);
02605 
02606 
02607                         return SWITCH_STATUS_SUCCESS;
02608                 }
02609 
02610         }
02611 
02612         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Channel %s is not in a bridge\n", switch_channel_get_name(channel));
02613         return SWITCH_STATUS_FALSE;
02614 
02615 }

switch_status_t switch_ivr_sound_test ( switch_core_session_t session  ) 

Definition at line 42 of file switch_ivr.c.

References switch_codec_implementation::actual_samples_per_second, switch_frame::data, switch_codec_implementation::microseconds_per_packet, switch_codec_implementation::number_of_channels, switch_frame::samples, switch_codec_implementation::samples_per_packet, switch_codec_implementation::samples_per_second, SFF_CNG, switch_channel_ready, SWITCH_CHANNEL_SESSION_LOG, SWITCH_CODEC_FLAG_DECODE, SWITCH_CODEC_FLAG_ENCODE, switch_core_codec_destroy(), switch_core_codec_init, switch_core_session_get_channel(), switch_core_session_get_pool(), switch_core_session_get_read_impl(), switch_core_session_read_frame(), SWITCH_IO_FLAG_NONE, SWITCH_LOG_CONSOLE, SWITCH_LOG_ERROR, switch_log_printf(), SWITCH_READ_ACCEPTABLE, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, and switch_test_flag.

00043 {
00044 
00045         switch_codec_implementation_t imp = { 0 };
00046         switch_codec_t codec = { 0 };
00047         int16_t peak = 0;
00048         int16_t *data;
00049         switch_frame_t *read_frame = NULL;
00050         uint32_t i;
00051         switch_channel_t *channel = switch_core_session_get_channel(session);
00052         switch_status_t status = SWITCH_STATUS_SUCCESS;
00053         int64_t global_total = 0, global_sum = 0, period_sum = 0;
00054         int period_total = 0;
00055         int period_avg = 0, global_avg = 0;
00056         int avg = 0;
00057         int period_len;
00058 
00059         switch_core_session_get_read_impl(session, &imp);
00060 
00061         period_len = imp.actual_samples_per_second / imp.samples_per_packet;
00062 
00063         if (switch_core_codec_init(&codec,
00064                                                            "L16",
00065                                                            NULL,
00066                                                            imp.samples_per_second,
00067                                                            imp.microseconds_per_packet / 1000,
00068                                                            imp.number_of_channels,
00069                                                            SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,
00070                                                            switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
00071                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec Error L16@%uhz %u channels %dms\n",
00072                                                   imp.samples_per_second, imp.number_of_channels, imp.microseconds_per_packet / 1000);
00073                 return SWITCH_STATUS_FALSE;
00074         }
00075 
00076         while (switch_channel_ready(channel)) {
00077                 status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
00078 
00079                 if (!SWITCH_READ_ACCEPTABLE(status)) {
00080                         break;
00081                 }
00082 
00083                 if (switch_test_flag(read_frame, SFF_CNG) || !read_frame->samples) {
00084                         continue;
00085                 }
00086 
00087 
00088                 data = (int16_t *) read_frame->data;
00089                 peak = 0;
00090                 avg = 0;
00091                 for (i = 0; i < read_frame->samples; i++) {
00092                         const int16_t s = (int16_t) abs(data[i]);
00093                         if (s > peak) {
00094                                 peak = s;
00095                         }
00096                         avg += s;
00097                 }
00098 
00099                 avg /= read_frame->samples;
00100 
00101                 period_sum += peak;
00102                 global_sum += peak;
00103 
00104                 global_total++;
00105                 period_total++;
00106 
00107                 period_avg = (int) (period_sum / period_total);
00108 
00109                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CONSOLE,
00110                                                   "\npacket_avg=%d packet_peak=%d period_avg=%d global_avg=%d\n\n", avg, peak, period_avg, global_avg);
00111 
00112                 if (period_total >= period_len) {
00113                         global_avg = (int) (global_sum / global_total);
00114                         period_total = 0;
00115                         period_sum = 0;
00116                 }
00117 
00118         }
00119 
00120 
00121         switch_core_codec_destroy(&codec);
00122 
00123         return SWITCH_STATUS_SUCCESS;
00124 
00125 }

switch_status_t switch_ivr_unbind_dtmf_meta_session ( switch_core_session_t session,
uint32_t  key 
)

Definition at line 3210 of file switch_ivr_async.c.

References dtmf_meta_data_t::sr, switch_channel_get_private(), SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_private(), switch_core_session_get_channel(), SWITCH_DTMF_RECV, SWITCH_DTMF_SEND, SWITCH_LOG_ERROR, SWITCH_LOG_INFO, switch_log_printf(), SWITCH_META_VAR_KEY, SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.

03211 {
03212         switch_channel_t *channel = switch_core_session_get_channel(session);
03213 
03214         if (key) {
03215                 dtmf_meta_data_t *md = switch_channel_get_private(channel, SWITCH_META_VAR_KEY);
03216 
03217                 if (!md || key > 9) {
03218                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid key %u\n", key);
03219                         return SWITCH_STATUS_FALSE;
03220                 }
03221 
03222                 memset(&md->sr[SWITCH_DTMF_RECV].map[key], 0, sizeof(md->sr[SWITCH_DTMF_RECV].map[key]));
03223                 memset(&md->sr[SWITCH_DTMF_SEND].map[key], 0, sizeof(md->sr[SWITCH_DTMF_SEND].map[key]));
03224                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "UnBound A-Leg: %d\n", key);
03225 
03226         } else {
03227                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "UnBound A-Leg: ALL\n");
03228                 switch_channel_set_private(channel, SWITCH_META_VAR_KEY, NULL);
03229         }
03230 
03231         return SWITCH_STATUS_SUCCESS;
03232 }

switch_status_t switch_ivr_unblock_dtmf_session ( switch_core_session_t session  ) 

Definition at line 3246 of file switch_ivr_async.c.

References SWITCH_BLOCK_DTMF_KEY, switch_channel_get_private(), switch_channel_set_private(), switch_core_session_get_channel(), and SWITCH_STATUS_SUCCESS.

03247 {
03248         switch_channel_t *channel = switch_core_session_get_channel(session);
03249         uint8_t enabled = (uint8_t)(intptr_t)switch_channel_get_private(channel, SWITCH_BLOCK_DTMF_KEY);
03250         
03251         if (enabled) {
03252                 switch_channel_set_private(channel, SWITCH_BLOCK_DTMF_KEY, NULL);
03253         }
03254 
03255         return SWITCH_STATUS_SUCCESS;
03256 }

switch_bool_t switch_ivr_uuid_exists ( const char *  uuid  ) 

Definition at line 3128 of file switch_ivr.c.

References switch_core_session_locate(), switch_core_session_rwunlock(), and SWITCH_FALSE.

03129 {
03130         switch_bool_t exists = SWITCH_FALSE;
03131         switch_core_session_t *psession = NULL;
03132 
03133         if ((psession = switch_core_session_locate(uuid))) {
03134                 switch_core_session_rwunlock(psession);
03135                 exists = 1;
03136         }
03137 
03138         return exists;
03139 }

switch_status_t switch_ivr_wait_for_answer ( switch_core_session_t session,
switch_core_session_t peer_session 
)

Definition at line 801 of file switch_ivr_originate.c.

References switch_codec_implementation::actual_samples_per_second, ringback::asis, ringback::audio_buffer, switch_frame::buflen, CF_ANSWERED, CF_DISABLE_RINGBACK, CF_EARLY_MEDIA, CF_PROXY_MEDIA, CF_PROXY_MODE, CF_XFER_ZOMBIE, switch_file_handle::channels, switch_frame::codec, CS_RESET, CS_SOFT_EXECUTE, switch_frame::data, switch_frame::datalen, switch_codec_implementation::decoded_bytes_per_packet, switch_dtmf_t::digit, switch_codec_implementation::encoded_bytes_per_packet, ringback::fh, ringback::fhb, switch_file_handle::file_path, switch_codec_implementation::iananame, switch_codec::implementation, switch_codec_implementation::number_of_channels, teletone_generation_session::rate, switch_file_handle::samplerate, switch_frame::samples, switch_codec_implementation::samples_per_packet, ringback::silence, switch_file_handle::speed, switch_assert, switch_buffer_create_dynamic(), switch_buffer_destroy(), switch_buffer_read_loop(), switch_buffer_set_loops(), SWITCH_CALL_TIMEOUT_VARIABLE, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER, SWITCH_CAUSE_NORMAL_TEMPORARY_FAILURE, SWITCH_CHANNEL_CHANNEL_LOG, switch_channel_dequeue_dtmf(), switch_channel_get_state(), switch_channel_get_variable, switch_channel_hangup, switch_channel_has_dtmf(), switch_channel_media_ready, switch_channel_ready, SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_state, switch_channel_test_flag(), switch_channel_up_nosig, SWITCH_CODEC_FLAG_DECODE, SWITCH_CODEC_FLAG_ENCODE, SWITCH_CODEC_FLAG_PASSTHROUGH, switch_cond_next(), switch_core_codec_destroy(), switch_core_codec_init, switch_core_codec_ready(), switch_core_file_close(), switch_core_file_open, switch_core_file_read(), switch_core_file_seek(), switch_core_session_get_channel(), switch_core_session_get_pool(), switch_core_session_get_read_codec(), switch_core_session_read_frame(), switch_core_session_reset(), switch_core_session_set_read_codec(), switch_core_session_sprintf(), switch_core_session_write_frame(), SWITCH_FILE_DATA_SHORT, SWITCH_FILE_FLAG_READ, switch_generate_sln_silence(), SWITCH_IO_FLAG_NONE, switch_is_file_path(), switch_ivr_parse_all_events(), switch_ivr_parse_all_messages(), SWITCH_IVR_VERIFY_SILENCE_DIVISOR, SWITCH_LOG_DEBUG, SWITCH_LOG_ERROR, switch_log_printf(), switch_micro_time_now(), switch_mprintf(), SWITCH_READ_ACCEPTABLE, SWITCH_RECOMMENDED_BUFFER_SIZE, switch_safe_free, SWITCH_SEND_SILENCE_WHEN_IDLE_VARIABLE, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, SWITCH_STATUS_TIMEOUT, switch_test_flag, SWITCH_TRUE, SWITCH_URL_SEPARATOR, switch_yield, switch_zmalloc, teletone_destroy_session(), teletone_handler(), teletone_init_session(), teletone_run(), ringback::ts, and zstr.

Referenced by switch_ivr_multi_threaded_bridge(), uuid_bridge_on_soft_execute(), and CoreSession::waitForAnswer().

00802 {
00803         switch_channel_t *caller_channel = NULL;
00804         switch_channel_t *peer_channel = switch_core_session_get_channel(peer_session);
00805         const char *ringback_data = NULL;
00806         switch_frame_t write_frame = { 0 };
00807         switch_codec_t write_codec = { 0 };
00808         switch_codec_t *read_codec = switch_core_session_get_read_codec(session);
00809         uint8_t pass = 0;
00810         ringback_t ringback = { 0 };
00811         switch_frame_t *read_frame = NULL;
00812         switch_status_t status = SWITCH_STATUS_SUCCESS;
00813         int timelimit = 60;
00814         const char *var;
00815         switch_time_t start = 0;
00816         const char *cancel_key = NULL;
00817         switch_channel_state_t wait_state = 0;
00818 
00819         switch_assert(peer_channel);
00820 
00821         if (switch_channel_get_state(peer_channel) == CS_RESET) {
00822                 switch_channel_set_state(peer_channel, CS_SOFT_EXECUTE);
00823         }
00824 
00825         if (session) {
00826                 caller_channel = switch_core_session_get_channel(session);
00827         }
00828 
00829         if ((switch_channel_test_flag(peer_channel, CF_ANSWERED) || switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA))) {
00830                 goto end;
00831         }
00832 
00833         switch_zmalloc(write_frame.data, SWITCH_RECOMMENDED_BUFFER_SIZE);
00834         write_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE;
00835 
00836         if (caller_channel && (var = switch_channel_get_variable(caller_channel, SWITCH_CALL_TIMEOUT_VARIABLE))) {
00837                 timelimit = atoi(var);
00838                 if (timelimit < 0) {
00839                         timelimit = 60;
00840                 }
00841         }
00842 
00843         timelimit *= 1000000;
00844         start = switch_micro_time_now();
00845 
00846         if (caller_channel) {
00847                 cancel_key = switch_channel_get_variable(caller_channel, "origination_cancel_key");
00848 
00849                 if (switch_channel_test_flag(caller_channel, CF_ANSWERED)) {
00850                         ringback_data = switch_channel_get_variable(caller_channel, "transfer_ringback");
00851                 }
00852 
00853                 if (!ringback_data) {
00854                         ringback_data = switch_channel_get_variable(caller_channel, "ringback");
00855                 }
00856 
00857                 if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE) || switch_channel_test_flag(caller_channel, CF_PROXY_MEDIA)) {
00858                         ringback_data = NULL;
00859                 } else if (zstr(ringback_data)) {
00860                         if ((var = switch_channel_get_variable(caller_channel, SWITCH_SEND_SILENCE_WHEN_IDLE_VARIABLE))) {
00861                                 int sval = atoi(var);
00862 
00863                                 if (sval) {
00864                                         ringback_data = switch_core_session_sprintf(session, "silence:%d", sval);
00865                                 }
00866                         }
00867                 }
00868         }
00869 
00870 
00871         if (read_codec && ringback_data) {
00872                 if (switch_is_file_path(ringback_data)) {
00873                         if (!(strrchr(ringback_data, '.') || strstr(ringback_data, SWITCH_URL_SEPARATOR))) {
00874                                 ringback.asis++;
00875                         }
00876                 }
00877 
00878 
00879 
00880                 if (!ringback.asis) {
00881                         if ((pass = (uint8_t) switch_test_flag(read_codec, SWITCH_CODEC_FLAG_PASSTHROUGH))) {
00882                                 goto no_ringback;
00883                         }
00884 
00885                         if (switch_core_codec_init(&write_codec,
00886                                                                            "L16",
00887                                                                            NULL,
00888                                                                            read_codec->implementation->actual_samples_per_second,
00889                                                                            read_codec->implementation->microseconds_per_packet / 1000,
00890                                                                            1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL,
00891                                                                            switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
00892                                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec Error!\n");
00893                                 if (caller_channel) {
00894                                         switch_channel_hangup(caller_channel, SWITCH_CAUSE_NORMAL_TEMPORARY_FAILURE);
00895                                 }
00896                                 read_codec = NULL;
00897                                 goto done;
00898                         } else {
00899                                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
00900                                                                   "Raw Codec Activation Success L16@%uhz 1 channel %dms\n",
00901                                                                   read_codec->implementation->actual_samples_per_second, read_codec->implementation->microseconds_per_packet / 1000);
00902 
00903                                 write_frame.codec = &write_codec;
00904                                 write_frame.datalen = read_codec->implementation->decoded_bytes_per_packet;
00905                                 write_frame.samples = write_frame.datalen / 2;
00906                                 memset(write_frame.data, 255, write_frame.datalen);
00907                                 switch_core_session_set_read_codec(session, &write_codec);
00908                         }
00909                 }
00910 
00911                 if (switch_channel_test_flag(caller_channel, CF_DISABLE_RINGBACK)) {
00912                         ringback_data = NULL;
00913                 }
00914 
00915                 if (ringback_data) {
00916                         char *tmp_data = NULL;
00917 
00918                         if (switch_is_file_path(ringback_data)) {
00919                                 char *ext;
00920 
00921                                 if (ringback.asis) {
00922                                         write_frame.codec = read_codec;
00923                                         ext = read_codec->implementation->iananame;
00924                                         tmp_data = switch_mprintf("%s.%s", ringback_data, ext);
00925                                         ringback_data = tmp_data;
00926                                 }
00927 
00928                                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Play Ringback File [%s]\n", ringback_data);
00929 
00930                                 ringback.fhb.channels = read_codec->implementation->number_of_channels;
00931                                 ringback.fhb.samplerate = read_codec->implementation->actual_samples_per_second;
00932                                 if (switch_core_file_open(&ringback.fhb,
00933                                                                                   ringback_data,
00934                                                                                   read_codec->implementation->number_of_channels,
00935                                                                                   read_codec->implementation->actual_samples_per_second,
00936                                                                                   SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) {
00937                                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error Playing File\n");
00938                                         switch_safe_free(tmp_data);
00939                                         goto done;
00940                                 }
00941                                 ringback.fh = &ringback.fhb;
00942                         } else {
00943                                 if (!strncasecmp(ringback_data, "silence", 7)) {
00944                                         const char *p = ringback_data + 7;
00945                                         if (*p == ':') {
00946                                                 p++;
00947                                                 if (p) {
00948                                                         ringback.silence = atoi(p);
00949                                                 }
00950                                         }
00951                                         SWITCH_IVR_VERIFY_SILENCE_DIVISOR(ringback.silence);
00952                                 } else {
00953                                         switch_buffer_create_dynamic(&ringback.audio_buffer, 512, 1024, 0);
00954                                         switch_buffer_set_loops(ringback.audio_buffer, -1);
00955 
00956                                         teletone_init_session(&ringback.ts, 0, teletone_handler, &ringback);
00957                                         ringback.ts.rate = read_codec->implementation->actual_samples_per_second;
00958                                         switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Play Ringback Tone [%s]\n", ringback_data);
00959                                         if (teletone_run(&ringback.ts, ringback_data)) {
00960                                                 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error Playing Tone\n");
00961                                                 teletone_destroy_session(&ringback.ts);
00962                                                 switch_buffer_destroy(&ringback.audio_buffer);
00963                                                 ringback_data = NULL;
00964                                         }
00965                                 }
00966                         }
00967                         switch_safe_free(tmp_data);
00968                 }
00969         }
00970 
00971   no_ringback:
00972 
00973         if (caller_channel) {
00974                 wait_state = switch_channel_get_state(caller_channel);
00975         }
00976 
00977         while (switch_channel_ready(peer_channel) && !switch_channel_media_ready(peer_channel)) {
00978                 int diff = (int) (switch_micro_time_now() - start);
00979 
00980                 switch_ivr_parse_all_messages(session);
00981 
00982                 if (caller_channel && cancel_key) {
00983                         if (switch_channel_has_dtmf(caller_channel)) {
00984                                 switch_dtmf_t dtmf = { 0, 0 };
00985                                 if (switch_channel_dequeue_dtmf(caller_channel, &dtmf) == SWITCH_STATUS_SUCCESS) {
00986                                         if (dtmf.digit == *cancel_key) {
00987                                                 status = SWITCH_STATUS_FALSE;
00988                                                 goto done;
00989                                         }
00990                                 }
00991                         }
00992                 }
00993 
00994                 if (caller_channel && switch_channel_get_state(caller_channel) != wait_state) {
00995                         goto done;
00996                 }
00997 
00998                 if (diff > timelimit) {
00999                         status = SWITCH_STATUS_TIMEOUT;
01000                         goto done;
01001                 }
01002 
01003                 if (switch_channel_media_ready(caller_channel)) {
01004                         status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
01005                         if (!SWITCH_READ_ACCEPTABLE(status)) {
01006                                 break;
01007                         }
01008                 } else {
01009                         read_frame = NULL;
01010                 }
01011 
01012                 if (read_frame && !pass) {
01013 
01014                         if (ringback.fh) {
01015                                 switch_size_t mlen, olen;
01016                                 unsigned int pos = 0;
01017 
01018                                 if (ringback.asis) {
01019                                         mlen = write_frame.codec->implementation->encoded_bytes_per_packet;
01020                                 } else {
01021                                         mlen = write_frame.codec->implementation->samples_per_packet;
01022                                 }
01023 
01024                                 olen = mlen;
01025                                 //if (ringback.fh->resampler && ringback.fh->resampler->rfactor > 1) {
01026                                 //olen = (switch_size_t) (olen * ringback.fh->resampler->rfactor);
01027                                 //}
01028                                 switch_core_file_read(ringback.fh, write_frame.data, &olen);
01029 
01030                                 if (olen == 0) {
01031                                         olen = mlen;
01032                                         ringback.fh->speed = 0;
01033                                         switch_core_file_seek(ringback.fh, &pos, 0, SEEK_SET);
01034                                         switch_core_file_read(ringback.fh, write_frame.data, &olen);
01035                                         if (olen == 0) {
01036                                                 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(caller_channel), SWITCH_LOG_ERROR, 
01037                                                                                   "Failure to read or re-read after seeking to beginning on file [%s]\n", ringback.fh->file_path);
01038                                                 break;
01039                                         }
01040                                 }
01041                                 write_frame.datalen = (uint32_t) (ringback.asis ? olen : olen * 2);
01042                         } else if (ringback.audio_buffer) {
01043                                 if ((write_frame.datalen = (uint32_t) switch_buffer_read_loop(ringback.audio_buffer,
01044                                                                                                                                                           write_frame.data,
01045                                                                                                                                                           write_frame.codec->implementation->decoded_bytes_per_packet)) <= 0) {
01046                                         break;
01047                                 }
01048                         } else if (ringback.silence) {
01049                                 write_frame.datalen = write_frame.codec->implementation->decoded_bytes_per_packet;
01050                                 switch_generate_sln_silence((int16_t *) write_frame.data, write_frame.datalen / 2, ringback.silence);
01051                         }
01052 
01053                         if ((ringback.fh || ringback.silence || ringback.audio_buffer) && write_frame.codec && write_frame.datalen) {
01054                                 if (switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) {
01055                                         break;
01056                                 }
01057                         }
01058                 } else {
01059                         switch_cond_next();
01060                 }
01061         }
01062 
01063   done:
01064 
01065         if (ringback.fh) {
01066                 switch_core_file_close(ringback.fh);
01067                 ringback.fh = NULL;
01068         } else if (ringback.audio_buffer) {
01069                 teletone_destroy_session(&ringback.ts);
01070                 switch_buffer_destroy(&ringback.audio_buffer);
01071         }
01072 
01073         
01074         switch_ivr_parse_all_events(session);
01075         
01076         switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE);
01077 
01078         if (switch_core_codec_ready(&write_codec)) {
01079                 switch_core_codec_destroy(&write_codec);
01080         }
01081 
01082         switch_safe_free(write_frame.data);
01083 
01084   end:
01085 
01086         if (!switch_channel_media_ready(peer_channel)) {
01087                 if (switch_channel_up_nosig(peer_channel)) {
01088                         switch_channel_hangup(peer_channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER);
01089                 }
01090                 status = SWITCH_STATUS_FALSE;
01091         }
01092 
01093         if (switch_channel_test_flag(caller_channel, CF_XFER_ZOMBIE)) {
01094                 switch_channel_state_t peer_state = switch_channel_get_state(peer_channel);
01095 
01096                 while (switch_channel_ready(peer_channel) && switch_channel_get_state(peer_channel) == peer_state) {
01097                         switch_ivr_parse_all_messages(session);
01098                         switch_channel_ready(caller_channel);
01099                         switch_yield(20000);
01100                 }
01101         }
01102 
01103         if (caller_channel && !switch_channel_up_nosig(caller_channel)) {
01104                 status = SWITCH_STATUS_FALSE;
01105         }
01106 
01107         return status;
01108 }

void switch_process_import ( switch_core_session_t session,
switch_channel_t peer_channel,
const char *  varname,
const char *  prefix 
)

Definition at line 1110 of file switch_ivr_originate.c.

References switch_assert, switch_channel_get_variable, switch_channel_set_variable, switch_core_session_get_channel(), switch_core_session_strdup, switch_mprintf(), and switch_separate_string().

01111 {
01112         const char *import, *val;
01113         switch_channel_t *caller_channel;
01114 
01115         switch_assert(session && peer_channel);
01116         caller_channel = switch_core_session_get_channel(session);
01117 
01118         if ((import = switch_channel_get_variable(caller_channel, varname))) {
01119                 char *mydata = switch_core_session_strdup(session, import);
01120                 int i, argc;
01121                 char *argv[64] = { 0 };
01122 
01123                 if ((argc = switch_separate_string(mydata, ',', argv, (sizeof(argv) / sizeof(argv[0]))))) {
01124                         for (i = 0; i < argc; i++) {
01125                                 if ((val = switch_channel_get_variable(peer_channel, argv[i]))) {
01126                                         if (prefix) {
01127                                                 char *var = switch_mprintf("%s%s", prefix, argv[i]);
01128                                                 switch_channel_set_variable(caller_channel, var, val);
01129                                                 free(var);
01130                                         } else {
01131                                                 switch_channel_set_variable(caller_channel, argv[i], val);
01132                                         }
01133                                 }
01134                         }
01135                 }
01136         }
01137 }


Generated on Wed May 16 04:00:19 2012 for FreeSWITCH API Documentation by  doxygen 1.4.7