FreeSWITCH API Documentation  1.7.0
Macros | Typedefs | Enumerations | Functions
IVR Menu Library
+ Collaboration diagram for IVR Menu Library:

Macros

#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 struct switch_ivr_menu switch_ivr_menu_t
 
typedef struct
switch_ivr_menu_action 
switch_ivr_menu_action_t
 
typedef struct
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 *transfer_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. More...
 
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. More...
 
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. More...
 
switch_status_t switch_ivr_menu_execute (switch_core_session_t *session, switch_ivr_menu_t *stack, char *name, void *obj)
 Execute a menu. More...
 
switch_status_t switch_ivr_menu_stack_free (switch_ivr_menu_t *stack)
 free a stack of menu objects. More...
 
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. More...
 
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_set_user_xml (switch_core_session_t *session, const char *prefix, const char *user, const char *domain, switch_xml_t x_user)
 
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_bool_t switch_ivr_uuid_force_exists (const char *uuid)
 
switch_bool_t switch_ivr_dmachine_is_parsing (switch_ivr_dmachine_t *dmachine)
 
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)
 
switch_status_t switch_ivr_record_session_mask (switch_core_session_t *session, const char *file, switch_bool_t on)
 
switch_status_t switch_ivr_stop_video_write_overlay_session (switch_core_session_t *session)
 
switch_status_t switch_ivr_video_write_overlay_session (switch_core_session_t *session, const char *img_path, switch_img_position_t pos, uint8_t alpha)
 

Detailed Description

IVR menu functions

Macro Definition Documentation

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

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 783 of file switch_ivr.h.

Definition at line 785 of file switch_ivr.h.

Definition at line 784 of file switch_ivr.h.

Definition at line 871 of file switch_ivr.h.

Enumeration Type Documentation

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 773 of file switch_ivr.h.

773  {
774  SWITCH_IVR_ACTION_DIE, /* Exit the menu. */
775  SWITCH_IVR_ACTION_EXECMENU, /* Goto another menu in the stack. */
776  SWITCH_IVR_ACTION_EXECAPP, /* Execute an application. */
777  SWITCH_IVR_ACTION_PLAYSOUND, /* Play a sound. */
778  SWITCH_IVR_ACTION_BACK, /* Go back 1 menu. */
779  SWITCH_IVR_ACTION_TOMAIN, /* Go back to the top level menu. */
780  SWITCH_IVR_ACTION_NOOP /* No operation */
switch_ivr_action_t
Definition: switch_ivr.h:773
Enumerator
SWITCH_IVR_MENU_FLAG_FALLTOMAIN 
SWITCH_IVR_MENU_FLAG_FREEPOOL 
SWITCH_IVR_MENU_FLAG_STACK 

Definition at line 767 of file switch_ivr.h.

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 4110 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.

4112 {
4115  const char *meta_var = switch_channel_get_variable(channel, "bind_meta_key");
4116  char meta = '*';
4117  char str[2] = "";
4118 
4119  if (meta_var) {
4120  char t_meta = *meta_var;
4121  if (is_dtmf(t_meta)) {
4122  meta = t_meta;
4123  } else {
4124  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Invalid META KEY %c\n", t_meta);
4125  }
4126  }
4127 
4128  if (meta != '*' && meta != '#') {
4129  str[0] = meta;
4130 
4131  if (switch_dtmftoi(str) == (char)key) {
4132  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid key %u, same as META CHAR\n", key);
4133  return SWITCH_STATUS_FALSE;
4134  }
4135  }
4136 
4137 
4138  if (key > 13) {
4139  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid key %u\n", key);
4140  return SWITCH_STATUS_FALSE;
4141  }
4142 
4143  if (!md) {
4144  md = switch_core_session_alloc(session, sizeof(*md));
4146  switch_core_event_hook_add_send_dtmf(session, meta_on_dtmf);
4147  switch_core_event_hook_add_recv_dtmf(session, meta_on_dtmf);
4148  }
4149 
4150  if (!zstr(app)) {
4151  if ((bind_flags & SBF_DIAL_ALEG)) {
4152  md->sr[SWITCH_DTMF_RECV].meta = meta;
4153  md->sr[SWITCH_DTMF_RECV].up = 1;
4154  md->sr[SWITCH_DTMF_RECV].map[key].app = switch_core_session_strdup(session, app);
4155  md->sr[SWITCH_DTMF_RECV].map[key].flags |= SMF_HOLD_BLEG;
4156  md->sr[SWITCH_DTMF_RECV].map[key].bind_flags = bind_flags;
4157 
4158  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Bound A-Leg: %c%c %s\n", meta, switch_itodtmf((char)key), app);
4159  }
4160  if ((bind_flags & SBF_DIAL_BLEG)) {
4161  md->sr[SWITCH_DTMF_SEND].meta = meta;
4162  md->sr[SWITCH_DTMF_SEND].up = 1;
4163  md->sr[SWITCH_DTMF_SEND].map[key].app = switch_core_session_strdup(session, app);
4164  md->sr[SWITCH_DTMF_SEND].map[key].flags |= SMF_HOLD_BLEG;
4165  md->sr[SWITCH_DTMF_SEND].map[key].bind_flags = bind_flags;
4166  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Bound B-Leg: %c%c %s\n", meta, switch_itodtmf((char)key), app);
4167  }
4168 
4169  } else {
4170  if ((bind_flags & SBF_DIAL_ALEG)) {
4171  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "UnBound A-Leg: %c%c\n", meta, switch_itodtmf((char)key));
4172  md->sr[SWITCH_DTMF_SEND].map[key].app = NULL;
4173  } else {
4174  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "UnBound: B-Leg %c%d\n", meta, key);
4175  md->sr[SWITCH_DTMF_SEND].map[key].app = NULL;
4176  }
4177  }
4178 
4179  return SWITCH_STATUS_SUCCESS;
4180 }
#define SWITCH_CHANNEL_SESSION_LOG(x)
switch_status_t switch_channel_set_private(switch_channel_t *channel, const char *key, const void *private_info)
Set private data on channel.
#define zstr(x)
Definition: switch_utils.h:281
#define is_dtmf(key)
determine if a character is a valid DTMF key
Definition: switch_utils.h:614
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
#define switch_channel_get_variable(_c, _v)
static char switch_itodtmf(char i)
Definition: switch_utils.h:389
void * switch_channel_get_private(switch_channel_t *channel, const char *key)
Retrieve private from a given channel.
switch_bind_flag_t bind_flags
#define switch_core_session_alloc(_session, _memory)
Allocate memory from a session's pool.
Definition: switch_core.h:694
static int switch_dtmftoi(char *s)
Definition: switch_utils.h:402
#define SWITCH_META_VAR_KEY
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
dtmf_meta_settings_t sr[3]
#define switch_core_session_strdup(_session, _todup)
Copy a string using memory allocation from a session's pool.
Definition: switch_core.h:717
dtmf_meta_app_t map[14]
static switch_status_t meta_on_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf, switch_dtmf_direction_t direction)
switch_status_t switch_ivr_blind_transfer_ack ( switch_core_session_t session,
switch_bool_t  success 
)

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

4255 {
4258 
4260  switch_core_session_t *other_session;
4261  const char *uuid = switch_channel_get_variable(channel, "blind_transfer_uuid");
4262 
4264 
4265  if (!zstr(uuid) && (other_session = switch_core_session_locate(uuid))) {
4266  switch_core_session_message_t msg = { 0 };
4268  msg.from = __FILE__;
4269  msg.numeric_arg = success;
4270  switch_core_session_receive_message(other_session, &msg);
4271  switch_core_session_rwunlock(other_session);
4272  status = SWITCH_STATUS_SUCCESS;
4273  }
4274  }
4275 
4276  return status;
4277 
4278 }
switch_core_session_message_types_t message_id
Definition: switch_core.h:181
uint32_t switch_channel_test_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Test for presence of given flag on a given channel.
A message object designed to allow unlike technologies to exchange data.
Definition: switch_core.h:177
#define zstr(x)
Definition: switch_utils.h:281
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
#define switch_channel_get_variable(_c, _v)
#define switch_core_session_receive_message(_session, _message)
Definition: switch_core.h:1217
void switch_core_session_rwunlock(_In_ switch_core_session_t *session)
Unlock a read or write lock on as given session.
switch_status_t
Common return values.
#define switch_core_session_locate(uuid_str)
Locate a session based on it's uuid.
Definition: switch_core.h:916
void switch_channel_clear_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Clear given flag(s) from a channel.
switch_status_t switch_ivr_block_dtmf_session ( switch_core_session_t session)

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

4097 {
4099  uint8_t enabled = (uint8_t)(intptr_t)switch_channel_get_private(channel, SWITCH_BLOCK_DTMF_KEY);
4100 
4101  if (!enabled) {
4102  switch_channel_set_private(channel, SWITCH_BLOCK_DTMF_KEY, (void *)(intptr_t)1);
4103  switch_core_event_hook_add_send_dtmf(session, block_on_dtmf);
4104  switch_core_event_hook_add_recv_dtmf(session, block_on_dtmf);
4105  }
4106 
4107  return SWITCH_STATUS_SUCCESS;
4108 }
switch_status_t switch_channel_set_private(switch_channel_t *channel, const char *key, const void *private_info)
Set private data on channel.
static switch_status_t block_on_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf, switch_dtmf_direction_t direction)
#define SWITCH_BLOCK_DTMF_KEY
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
void * switch_channel_get_private(switch_channel_t *channel, const char *key)
Retrieve private from a given channel.
char* switch_ivr_check_presence_mapping ( const char *  exten_name,
const char *  domain_name 
)

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

4177 {
4178  char *cf = "presence_map.conf";
4179  switch_xml_t cfg, xml, x_domains, x_domain, x_exten;
4180  char *r = NULL;
4181  switch_event_t *params = NULL;
4182  switch_regex_t *re = NULL;
4183  int proceed = 0, ovector[100];
4184 
4186  switch_assert(params);
4187 
4188  if ( !zstr(domain_name) ) {
4189  switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "domain", domain_name);
4190  }
4191 
4192  if ( !zstr(exten_name) ) {
4193  switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "exten", exten_name);
4194  }
4195 
4196  if (!(xml = switch_xml_open_cfg(cf, &cfg, params))) {
4197  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", cf);
4198  goto end;
4199  }
4200 
4201  if (!(x_domains = switch_xml_child(cfg, "domains"))) {
4202  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't find any domains!\n");
4203  goto end;
4204  }
4205 
4206  for (x_domain = switch_xml_child(x_domains, "domain"); x_domain; x_domain = x_domain->next) {
4207  const char *dname = switch_xml_attr(x_domain, "name");
4208  if (!dname || (strcasecmp(dname, "*") && strcasecmp(domain_name, dname))) continue;
4209 
4210  for (x_exten = switch_xml_child(x_domain, "exten"); x_exten; x_exten = x_exten->next) {
4211  const char *regex = switch_xml_attr(x_exten, "regex");
4212  const char *proto = switch_xml_attr(x_exten, "proto");
4213 
4214  if (!zstr(regex) && !zstr(proto)) {
4215  proceed = switch_regex_perform(exten_name, regex, &re, ovector, sizeof(ovector) / sizeof(ovector[0]));
4217 
4218  if (proceed) {
4219  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Mapping %s@%s to proto %s matching expression [%s]\n",
4220  exten_name, domain_name, proto, regex);
4221  r = strdup(proto);
4222  goto end;
4223  }
4224 
4225  }
4226  }
4227  }
4228 
4229  end:
4230  switch_event_destroy(&params);
4231 
4232  if (xml) {
4233  switch_xml_free(xml);
4234  }
4235 
4236  return r;
4237 
4238 }
#define switch_regex_safe_free(re)
Definition: switch_regex.h:79
void switch_xml_free(_In_opt_ switch_xml_t xml)
frees the memory allocated for an switch_xml structure
#define SWITCH_CHANNEL_LOG
const char * switch_xml_attr(_In_opt_ switch_xml_t xml, _In_opt_z_ const char *attr)
returns the value of the requested tag attribute, or NULL if not found
Representation of an event.
Definition: switch_event.h:80
A representation of an XML tree.
Definition: switch_xml.h:76
struct real_pcre switch_regex_t
Definition: switch_regex.h:43
#define zstr(x)
Definition: switch_utils.h:281
switch_xml_t next
Definition: switch_xml.h:88
switch_status_t switch_event_add_header_string(switch_event_t *event, switch_stack_t stack, const char *header_name, const char *data)
Add a string header to an event.
int switch_regex_perform(const char *field, const char *expression, switch_regex_t **new_re, int *ovector, uint32_t olen)
Definition: switch_regex.c:55
switch_xml_t switch_xml_open_cfg(_In_z_ const char *file_path, _Out_ switch_xml_t *node, _In_opt_ switch_event_t *params)
open a config in the core registry
#define switch_event_create(event, id)
Create a new event assuming it will not be custom event and therefore hiding the unused parameters...
Definition: switch_event.h:383
switch_xml_t switch_xml_child(_In_ switch_xml_t xml, _In_z_ const char *name)
returns the first child tag (one level deeper) with the given name or NULL \ if not found ...
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
void switch_event_destroy(switch_event_t **event)
Destroy an event.
#define switch_assert(expr)
switch_status_t switch_ivr_create_message_reply ( switch_event_t **  reply,
switch_event_t message,
const char *  new_proto 
)

Definition at line 4163 of file switch_ivr.c.

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

4164 {
4166 
4167  if ((status = switch_event_dup_reply(reply, message) != SWITCH_STATUS_SUCCESS)) {
4168  abort();
4169  }
4170 
4171  switch_event_add_header_string(*reply, SWITCH_STACK_BOTTOM, "proto", new_proto);
4172 
4173  return status;
4174 }
switch_status_t switch_event_add_header_string(switch_event_t *event, switch_stack_t stack, const char *header_name, const char *data)
Add a string header to an event.
switch_status_t
Common return values.
switch_status_t switch_event_dup_reply(switch_event_t **event, switch_event_t *todup)
void switch_ivr_delay_echo ( switch_core_session_t session,
uint32_t  delay_ms 
)

Definition at line 3419 of file switch_ivr.c.

References switch_rtp_packet_t::body, switch_frame::buflen, switch_frame::codec, switch_frame::data, switch_frame::datalen, switch_rtp_packet_t::header, switch_codec_implementation::microseconds_per_packet, switch_frame::packet, switch_frame::packetlen, switch_codec_implementation::samples_per_packet, switch_rtp_hdr_t::seq, SFF_CNG, SJB_AUDIO, switch_channel_get_variable, switch_channel_ready, SWITCH_CHANNEL_SESSION_LOG, switch_core_session_get_channel(), switch_core_session_get_pool(), 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_jb_create(), switch_jb_debug_level(), switch_jb_destroy(), switch_jb_get_packet(), switch_jb_put_packet(), SWITCH_LOG_DEBUG, SWITCH_LOG_ERROR, switch_log_printf(), SWITCH_LOG_WARNING, SWITCH_READ_ACCEPTABLE, SWITCH_STATUS_SUCCESS, switch_test_flag, switch_rtp_hdr_t::ts, and switch_rtp_hdr_t::version.

3420 {
3421  switch_jb_t *jb;
3422  int qlen = 0;
3423  switch_frame_t *read_frame, write_frame = { 0 };
3424  switch_status_t status;
3426  uint32_t interval;
3427  uint32_t ts = 0;
3428  uint16_t seq = 0;
3429  switch_codec_implementation_t read_impl = { 0 };
3430  int is_rtp = 0;
3431  int debug = 0;
3432  const char *var;
3433 
3434 
3435  switch_core_session_get_read_impl(session, &read_impl);
3436 
3437  if (delay_ms < 1 || delay_ms > 10000) {
3438  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid delay [%d] must be between 1 and 10000\n", delay_ms);
3439  return;
3440  }
3441 
3442  interval = read_impl.microseconds_per_packet / 1000;
3443 
3444  if (delay_ms < interval * 2) {
3445  delay_ms = interval * 2;
3446  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Minimum possible delay for this codec (%d) has been chosen\n", delay_ms);
3447  }
3448 
3449  qlen = delay_ms / (interval);
3450  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Setting delay to %dms (%d frames)\n", delay_ms, qlen);
3451 
3452  switch_jb_create(&jb, SJB_AUDIO, qlen, qlen, switch_core_session_get_pool(session));
3453 
3454  if ((var = switch_channel_get_variable(channel, "delay_echo_debug_level"))) {
3455  debug = atoi(var);
3456  }
3457 
3458  if (debug) {
3459  switch_jb_debug_level(jb, debug);
3460  }
3461 
3462  write_frame.codec = switch_core_session_get_read_codec(session);
3463 
3464  while (switch_channel_ready(channel)) {
3465  switch_rtp_packet_t packet = { {0} };
3466  switch_size_t plen = sizeof(packet);
3467 
3468  status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
3469 
3470  if (!SWITCH_READ_ACCEPTABLE(status)) {
3471  break;
3472  }
3473 
3474  if (switch_test_flag(read_frame, SFF_CNG)) {
3475  continue;
3476  }
3477 
3478  if (read_frame->packet) {
3479  is_rtp = 1;
3480  switch_jb_put_packet(jb, (switch_rtp_packet_t *) read_frame->packet, read_frame->packetlen);
3481  } else if (is_rtp) {
3482  continue;
3483  } else {
3484  ts += read_impl.samples_per_packet;
3485  memcpy(packet.body, read_frame->data, read_frame->datalen);
3486  packet.header.ts = htonl(ts);
3487  packet.header.seq = htons(++seq);
3488  packet.header.version = 2;
3489  }
3490 
3491  if (switch_jb_get_packet(jb, (switch_rtp_packet_t *) &packet, &plen) == SWITCH_STATUS_SUCCESS) {
3492  write_frame.data = packet.body;
3493  write_frame.datalen = (uint32_t) plen - 12;
3494  write_frame.buflen = (uint32_t) plen;
3495 
3496  status = switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0);
3497 
3498  if (!SWITCH_READ_ACCEPTABLE(status)) {
3499  break;
3500  }
3501  }
3502  }
3503 
3504  switch_jb_destroy(&jb);
3505 }
switch_status_t switch_jb_get_packet(switch_jb_t *jb, switch_rtp_packet_t *packet, switch_size_t *len)
#define SWITCH_CHANNEL_SESSION_LOG(x)
switch_rtp_hdr_t header
Definition: switch_rtp.h:53
#define switch_channel_ready(_channel)
switch_status_t switch_jb_put_packet(switch_jb_t *jb, switch_rtp_packet_t *packet, switch_size_t len)
switch_status_t switch_jb_destroy(switch_jb_t **jbp)
switch_status_t switch_core_session_read_frame(_In_ switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id)
Read a frame from a session.
switch_codec_t * codec
Definition: switch_frame.h:45
switch_codec_t * switch_core_session_get_read_codec(_In_ switch_core_session_t *session)
Retrieve the read codec from a given session.
switch_status_t switch_core_session_write_frame(_In_ switch_core_session_t *session, switch_frame_t *frame, switch_io_flag_t flags, int stream_id)
Write a frame to a session.
switch_status_t switch_core_session_get_read_impl(switch_core_session_t *session, switch_codec_implementation_t *impp)
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
uint32_t buflen
Definition: switch_frame.h:59
SWITCH_BEGIN_EXTERN_C switch_status_t switch_jb_create(switch_jb_t **jbp, switch_jb_type_t type, uint32_t min_frame_len, uint32_t max_frame_len, switch_memory_pool_t *pool)
uint32_t datalen
Definition: switch_frame.h:57
uint32_t packetlen
Definition: switch_frame.h:51
#define switch_channel_get_variable(_c, _v)
An abstraction of a data frame.
Definition: switch_frame.h:43
uintptr_t switch_size_t
void switch_jb_debug_level(switch_jb_t *jb, uint8_t level)
void * packet
Definition: switch_frame.h:49
switch_status_t
Common return values.
char body[SWITCH_RTP_MAX_BUF_LEN+4+sizeof(char *)]
Definition: switch_rtp.h:54
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:624
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
A table of settings and callbacks that define a paticular implementation of a codec.
#define SWITCH_READ_ACCEPTABLE(status)
Definition: switch_utils.h:995
switch_memory_pool_t * switch_core_session_get_pool(_In_ switch_core_session_t *session)
Retrieve the memory pool from a session.
switch_status_t switch_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 248 of file switch_ivr_async.c.

References dm_binding_head_t::binding_list, switch_ivr_dmachine_binding::callback, switch_ivr_dmachine_binding::digits, DMACHINE_MAX_DIGIT_LEN, switch_ivr_dmachine_binding::is_regex, switch_ivr_dmachine_binding::key, dm_binding_head_t::name, 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, switch_ivr_dmachine_binding::user_data, and zstr.

254 {
255  switch_ivr_dmachine_binding_t *binding = NULL, *ptr;
256  switch_size_t len;
257  dm_binding_head_t *headp;
258  const char *msg = "";
259 
260  if (strlen(digits) > DMACHINE_MAX_DIGIT_LEN -1) {
261  return SWITCH_STATUS_FALSE;
262  }
263 
264  if (zstr(realm)) {
265  realm = "default";
266  }
267 
268  if (!(headp = switch_core_hash_find(dmachine->binding_hash, realm))) {
269  headp = switch_core_alloc(dmachine->pool, sizeof(*headp));
270  headp->name = switch_core_strdup(dmachine->pool, realm);
271  switch_core_hash_insert(dmachine->binding_hash, realm, headp);
272  }
273 
274  for(ptr = headp->binding_list; ptr; ptr = ptr->next) {
275  if ((ptr->is_regex && !strcmp(ptr->digits, digits+1)) || !strcmp(ptr->digits, digits)) {
276  msg = "Reuse Existing ";
277  binding = ptr;
278  binding->callback = callback;
279  binding->user_data = user_data;
280  goto done;
281  }
282  }
283 
284 
285  binding = switch_core_alloc(dmachine->pool, sizeof(*binding));
286 
287  if (*digits == '~') {
288  binding->is_regex = 1;
289  digits++;
290  }
291 
292  binding->key = key;
293  binding->digits = switch_core_strdup(dmachine->pool, digits);
294  binding->callback = callback;
295  binding->user_data = user_data;
296 
297  if (headp->tail) {
298  headp->tail->next = binding;
299  } else {
300  headp->binding_list = binding;
301  }
302 
303  headp->tail = binding;
304 
305  len = strlen(digits);
306 
307  if (dmachine->realm != headp) {
308  switch_ivr_dmachine_set_realm(dmachine, realm);
309  }
310 
311  if (binding->is_regex && dmachine->max_digit_len != DMACHINE_MAX_DIGIT_LEN -1) {
312  dmachine->max_digit_len = DMACHINE_MAX_DIGIT_LEN -1;
313  } else if (len > dmachine->max_digit_len) {
314  dmachine->max_digit_len = (uint32_t) len;
315  }
316 
317  done:
318 
319  if (binding->is_regex) {
320  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%sDigit parser %s: binding %s/%s/%d callback: %p data: %p\n",
321  msg, dmachine->name, digits, realm, key, (void *)(intptr_t) callback, user_data);
322  } else {
323  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%sDigit parser %s: binding %s/%s/%d callback: %p data: %p\n",
324  msg, dmachine->name, digits, realm, key, (void *)(intptr_t) callback, user_data);
325  }
326 
327  return SWITCH_STATUS_SUCCESS;
328 }
struct switch_ivr_dmachine_binding * next
#define SWITCH_CHANNEL_LOG
void * switch_core_hash_find(_In_ switch_hash_t *hash, _In_z_ const char *key)
Retrieve data from a given hash.
switch_hash_t * binding_hash
#define switch_core_strdup(_pool, _todup)
Copy a string using memory allocation from a given pool.
Definition: switch_core.h:729
dm_binding_head_t * realm
switch_ivr_dmachine_binding_t * binding_list
#define zstr(x)
Definition: switch_utils.h:281
switch_ivr_dmachine_binding_t * tail
#define switch_core_alloc(_pool, _mem)
Allocate memory directly from a memory pool.
Definition: switch_core.h:682
uintptr_t switch_size_t
switch_ivr_dmachine_callback_t callback
switch_status_t switch_ivr_dmachine_set_realm(switch_ivr_dmachine_t *dmachine, const char *realm)
#define switch_core_hash_insert(_h, _k, _d)
Definition: switch_core.h:1410
switch_memory_pool_t * pool
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
#define DMACHINE_MAX_DIGIT_LEN
switch_status_t switch_ivr_dmachine_clear ( switch_ivr_dmachine_t dmachine)

Definition at line 634 of file switch_ivr_async.c.

References memset(), and SWITCH_STATUS_SUCCESS.

Referenced by switch_ivr_dmachine_ping().

635 {
636 
637  memset(dmachine->digits, 0, sizeof(dmachine->digits));
638  dmachine->cur_digit_len = 0;
639  dmachine->last_digit_time = 0;
640  return SWITCH_STATUS_SUCCESS;
641 }
char digits[DMACHINE_MAX_DIGIT_LEN]
switch_time_t last_digit_time
memset(buf, 0, buflen)
switch_status_t switch_ivr_dmachine_clear_realm ( switch_ivr_dmachine_t dmachine,
const char *  realm 
)

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

225 {
226  dm_binding_head_t *headp;
227 
228  if (zstr(realm)) {
229  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Digit parser %s: Error unknown realm: '%s'\n", dmachine->name, realm);
230  return SWITCH_STATUS_FALSE;
231  }
232 
233  headp = switch_core_hash_find(dmachine->binding_hash, realm);
234 
235  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Digit parser %s: Clearing realm '%s'\n", dmachine->name, realm);
236 
237  if (headp == dmachine->realm) {
239  "Digit parser %s: '%s' was the active realm, no realm currently selected.\n", dmachine->name, realm);
240  dmachine->realm = NULL;
241  }
242 
243  /* pool alloc'd just ditch it and it will give back the memory when we destroy ourselves */
244  switch_core_hash_delete(dmachine->binding_hash, realm);
245  return SWITCH_STATUS_SUCCESS;
246 }
#define SWITCH_CHANNEL_LOG
void * switch_core_hash_find(_In_ switch_hash_t *hash, _In_z_ const char *key)
Retrieve data from a given hash.
switch_hash_t * binding_hash
dm_binding_head_t * realm
#define zstr(x)
Definition: switch_utils.h:281
void * switch_core_hash_delete(_In_ switch_hash_t *hash, _In_z_ const char *key)
Delete data from a hash based on desired key.
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
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 125 of file switch_ivr_async.c.

References switch_ivr_dmachine::binding_hash, switch_ivr_dmachine::digit_timeout_ms, switch_ivr_dmachine_match::dmachine, switch_ivr_dmachine::input_timeout_ms, switch_ivr_dmachine::match, switch_ivr_dmachine::match_callback, switch_ivr_dmachine::mutex, switch_ivr_dmachine::my_pool, switch_ivr_dmachine::name, switch_ivr_dmachine::nonmatch_callback, pool, switch_ivr_dmachine::pool, switch_core_alloc, switch_core_hash_init, switch_core_new_memory_pool, switch_core_strdup, switch_mutex_init(), SWITCH_MUTEX_NESTED, SWITCH_STATUS_SUCCESS, and switch_ivr_dmachine::user_data.

133 {
134  switch_byte_t my_pool = 0;
135  switch_ivr_dmachine_t *dmachine;
136 
137  if (!pool) {
139  my_pool = 1;
140  }
141 
142  dmachine = switch_core_alloc(pool, sizeof(*dmachine));
143  dmachine->pool = pool;
144  dmachine->my_pool = my_pool;
145  dmachine->digit_timeout_ms = digit_timeout_ms;
146  dmachine->input_timeout_ms = input_timeout_ms;
147  dmachine->match.dmachine = dmachine;
148  dmachine->name = switch_core_strdup(dmachine->pool, name);
149  switch_mutex_init(&dmachine->mutex, SWITCH_MUTEX_NESTED, dmachine->pool);
150 
152 
153  if (match_callback) {
154  dmachine->match_callback = match_callback;
155  }
156 
157  if (nonmatch_callback) {
158  dmachine->nonmatch_callback = nonmatch_callback;
159  }
160 
161  dmachine->user_data = user_data;
162 
163  *dmachine_p = dmachine;
164 
165  return SWITCH_STATUS_SUCCESS;
166 }
#define switch_core_new_memory_pool(p)
Create a new sub memory pool from the core's master pool.
Definition: switch_core.h:631
switch_ivr_dmachine_callback_t nonmatch_callback
switch_hash_t * binding_hash
#define switch_core_hash_init(_hash)
Definition: switch_core.h:1390
switch_ivr_dmachine_t * dmachine
#define switch_core_strdup(_pool, _todup)
Copy a string using memory allocation from a given pool.
Definition: switch_core.h:729
switch_memory_pool_t * pool
uint8_t switch_byte_t
Definition: switch_types.h:246
#define SWITCH_MUTEX_NESTED
Definition: switch_apr.h:318
#define switch_core_alloc(_pool, _mem)
Allocate memory directly from a memory pool.
Definition: switch_core.h:682
switch_ivr_dmachine_match_t match
switch_ivr_dmachine_callback_t match_callback
switch_status_t switch_mutex_init(switch_mutex_t **lock, unsigned int flags, switch_memory_pool_t *pool)
Definition: switch_apr.c:270
switch_memory_pool_t * pool
switch_byte_t my_pool
switch_mutex_t * mutex
void switch_ivr_dmachine_destroy ( switch_ivr_dmachine_t **  dmachine)

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

180 {
182 
183  if (!(dmachine && *dmachine)) return;
184 
185  pool = (*dmachine)->pool;
186 
187  switch_core_hash_destroy(&(*dmachine)->binding_hash);
188 
189  if ((*dmachine)->my_pool) {
191  }
192 }
switch_status_t switch_core_hash_destroy(_Inout_ switch_hash_t **hash)
Destroy an existing hash table.
#define switch_core_destroy_memory_pool(p)
Returns a subpool back to the main pool.
Definition: switch_core.h:640
switch_memory_pool_t * pool
struct apr_pool_t switch_memory_pool_t
switch_status_t switch_ivr_dmachine_feed ( switch_ivr_dmachine_t dmachine,
const char *  digits,
switch_ivr_dmachine_match_t **  match 
)

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

597 {
598  const char *p;
600 
601  if (!zstr(digits)) {
602  status = SWITCH_STATUS_SUCCESS;
603  }
604 
605  for (p = digits; p && *p; p++) {
606  switch_mutex_lock(dmachine->mutex);
607  if (dmachine->cur_digit_len < dmachine->max_digit_len) {
608  switch_status_t istatus;
609  char *e = dmachine->digits + strlen(dmachine->digits);
610 
611  *e++ = *p;
612  *e = '\0';
613  dmachine->cur_digit_len++;
614  switch_mutex_unlock(dmachine->mutex);
615  dmachine->last_digit_time = switch_time_now();
616  if (status == SWITCH_STATUS_SUCCESS && (istatus = switch_ivr_dmachine_ping(dmachine, match)) != SWITCH_STATUS_SUCCESS) {
617  status = istatus;
618  }
619  } else {
620  switch_mutex_unlock(dmachine->mutex);
621  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "dmachine overflow error!\n");
622  status = SWITCH_STATUS_FALSE;
623  }
624  }
625 
626  return status;
627 }
#define SWITCH_CHANNEL_LOG
#define zstr(x)
Definition: switch_utils.h:281
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:290
char digits[DMACHINE_MAX_DIGIT_LEN]
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:285
switch_status_t
Common return values.
switch_time_t last_digit_time
switch_status_t switch_ivr_dmachine_ping(switch_ivr_dmachine_t *dmachine, switch_ivr_dmachine_match_t **match_p)
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
switch_mutex_t * mutex
switch_time_t switch_time_now(void)
Definition: switch_apr.c:302
const char* switch_ivr_dmachine_get_failed_digits ( switch_ivr_dmachine_t dmachine)

Definition at line 470 of file switch_ivr_async.c.

471 {
472 
473  return dmachine->last_failed_digits;
474 }
char last_failed_digits[DMACHINE_MAX_DIGIT_LEN]
switch_ivr_dmachine_match_t* switch_ivr_dmachine_get_match ( switch_ivr_dmachine_t dmachine)

Definition at line 460 of file switch_ivr_async.c.

461 {
462  if (dmachine->is_match) {
463  dmachine->is_match = 0;
464  return &dmachine->match;
465  }
466 
467  return NULL;
468 }
switch_ivr_dmachine_match_t match
switch_byte_t is_match
const char* switch_ivr_dmachine_get_name ( switch_ivr_dmachine_t dmachine)

Definition at line 120 of file switch_ivr_async.c.

121 {
122  return (const char *) dmachine->name;
123 }
switch_bool_t switch_ivr_dmachine_is_parsing ( switch_ivr_dmachine_t dmachine)

Definition at line 629 of file switch_ivr_async.c.

Referenced by switch_ivr_play_file().

630 {
631  return !!dmachine->cur_digit_len;
632 }
switch_status_t switch_ivr_dmachine_last_ping ( switch_ivr_dmachine_t dmachine)

Definition at line 86 of file switch_ivr_async.c.

Referenced by switch_ivr_play_and_detect_speech().

87 {
88  return dmachine->last_return;
89 }
switch_status_t last_return
switch_status_t switch_ivr_dmachine_ping ( switch_ivr_dmachine_t dmachine,
switch_ivr_dmachine_match_t **  match_p 
)

Definition at line 476 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_trylock(), 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().

477 {
478  switch_bool_t is_timeout = switch_ivr_dmachine_check_timeout(dmachine);
479  dm_match_t is_match = switch_ivr_dmachine_check_match(dmachine, is_timeout);
480  switch_status_t r, s;
481  int clear = 0;
482 
483  if (is_match == DM_MATCH_NEVER) {
484  is_timeout++;
485  }
486 
488  return SWITCH_STATUS_SUCCESS;
489  }
490 
491  if (dmachine->pinging) {
492  return SWITCH_STATUS_BREAK;
493  }
494 
495  dmachine->pinging = 1;
496 
497  if (zstr(dmachine->digits) && !is_timeout) {
499  } else if (dmachine->cur_digit_len > dmachine->max_digit_len) {
501  } else if (is_match == DM_MATCH_EXACT || (is_match == DM_MATCH_BOTH && is_timeout)) {
503 
504  dmachine->match.match_digits = dmachine->last_matching_digits;
505  dmachine->match.match_key = dmachine->last_matching_binding->key;
506  dmachine->match.user_data = dmachine->last_matching_binding->user_data;
507 
508  if (match_p) {
509  *match_p = &dmachine->match;
510  }
511 
512  dmachine->is_match = 1;
513 
514  dmachine->match.type = DM_MATCH_POSITIVE;
515 
516  if (dmachine->last_matching_binding->callback) {
517  s = dmachine->last_matching_binding->callback(&dmachine->match);
518 
519  switch(s) {
522  break;
524  break;
525  default:
527  break;
528  }
529  }
530 
531  if (dmachine->match_callback) {
532  dmachine->match.user_data = dmachine->user_data;
533  s = dmachine->match_callback(&dmachine->match);
534 
535  switch(s) {
538  break;
540  break;
541  default:
543  break;
544  }
545 
546  }
547 
548  clear++;
549  } else if (is_timeout) {
551  } else if (is_match == DM_MATCH_NONE && dmachine->cur_digit_len == dmachine->max_digit_len) {
553  } else {
555  }
556 
558  switch_set_string(dmachine->last_failed_digits, dmachine->digits);
559  dmachine->match.match_digits = dmachine->last_failed_digits;
560 
561  dmachine->match.type = DM_MATCH_NEGATIVE;
562 
563  if (dmachine->nonmatch_callback) {
564  dmachine->match.user_data = dmachine->user_data;
565  s = dmachine->nonmatch_callback(&dmachine->match);
566 
567  switch(s) {
570  break;
572  break;
573  default:
575  break;
576  }
577 
578  }
579 
580  clear++;
581  }
582 
583  if (clear) {
584  switch_ivr_dmachine_clear(dmachine);
585  }
586 
587  dmachine->last_return = r;
588 
589  dmachine->pinging = 0;
590 
591  switch_mutex_unlock(dmachine->mutex);
592 
593  return r;
594 }
switch_ivr_dmachine_callback_t nonmatch_callback
char last_failed_digits[DMACHINE_MAX_DIGIT_LEN]
switch_status_t switch_mutex_trylock(switch_mutex_t *lock)
Definition: switch_apr.c:295
static switch_bool_t switch_ivr_dmachine_check_timeout(switch_ivr_dmachine_t *dmachine)
switch_bool_t
Definition: switch_types.h:405
switch_ivr_dmachine_binding_t * last_matching_binding
switch_status_t switch_ivr_dmachine_clear(switch_ivr_dmachine_t *dmachine)
static dm_match_t switch_ivr_dmachine_check_match(switch_ivr_dmachine_t *dmachine, switch_bool_t is_timeout)
#define zstr(x)
Definition: switch_utils.h:281
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:290
char digits[DMACHINE_MAX_DIGIT_LEN]
switch_ivr_dmachine_match_t match
switch_ivr_dmachine_callback_t match_callback
switch_ivr_dmachine_callback_t callback
switch_byte_t is_match
dm_match_t
switch_status_t
Common return values.
char last_matching_digits[DMACHINE_MAX_DIGIT_LEN]
#define switch_set_string(_dst, _src)
Definition: switch_utils.h:665
switch_mutex_t * mutex
switch_status_t last_return
void switch_ivr_dmachine_set_digit_timeout_ms ( switch_ivr_dmachine_t dmachine,
uint32_t  digit_timeout_ms 
)

Definition at line 169 of file switch_ivr_async.c.

170 {
171  dmachine->digit_timeout_ms = digit_timeout_ms;
172 }
void switch_ivr_dmachine_set_input_timeout_ms ( switch_ivr_dmachine_t dmachine,
uint32_t  input_timeout_ms 
)

Definition at line 174 of file switch_ivr_async.c.

175 {
176  dmachine->input_timeout_ms = input_timeout_ms;
177 }
void switch_ivr_dmachine_set_match_callback ( switch_ivr_dmachine_t dmachine,
switch_ivr_dmachine_callback_t  match_callback 
)

Definition at line 104 of file switch_ivr_async.c.

References switch_assert.

105 {
106 
107  switch_assert(dmachine);
108  dmachine->match_callback = match_callback;
109 
110 }
switch_ivr_dmachine_callback_t match_callback
#define switch_assert(expr)
void switch_ivr_dmachine_set_nonmatch_callback ( switch_ivr_dmachine_t dmachine,
switch_ivr_dmachine_callback_t  nonmatch_callback 
)

Definition at line 112 of file switch_ivr_async.c.

References switch_assert.

113 {
114 
115  switch_assert(dmachine);
116  dmachine->nonmatch_callback = nonmatch_callback;
117 
118 }
switch_ivr_dmachine_callback_t nonmatch_callback
#define switch_assert(expr)
switch_status_t switch_ivr_dmachine_set_realm ( switch_ivr_dmachine_t dmachine,
const char *  realm 
)

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

210 {
211  dm_binding_head_t *headp = switch_core_hash_find(dmachine->binding_hash, realm);
212 
213  if (headp) {
214  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Digit parser %s: Setting realm to '%s'\n", dmachine->name, realm);
215  dmachine->realm = headp;
216  return SWITCH_STATUS_SUCCESS;
217  }
218 
219  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Digit parser %s: Error Setting realm to '%s'\n", dmachine->name, realm);
220 
221  return SWITCH_STATUS_FALSE;
222 }
#define SWITCH_CHANNEL_LOG
void * switch_core_hash_find(_In_ switch_hash_t *hash, _In_z_ const char *key)
Retrieve data from a given hash.
switch_hash_t * binding_hash
dm_binding_head_t * realm
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
switch_status_t switch_ivr_find_bridged_uuid ( const char *  uuid,
char *  b_uuid,
switch_size_t  blen 
)

Definition at line 2033 of file switch_ivr_bridge.c.

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

Referenced by switch_ivr_intercept_session().

2034 {
2035  switch_core_session_t *rsession;
2037 
2038  switch_assert(uuid);
2039 
2040  if ((rsession = switch_core_session_locate(uuid))) {
2041  switch_channel_t *rchannel = switch_core_session_get_channel(rsession);
2042  const char *brto;
2043 
2045  (brto = switch_channel_get_partner_uuid(rchannel))) {
2046  switch_copy_string(b_uuid, brto, blen);
2047  status = SWITCH_STATUS_SUCCESS;
2048  }
2049  switch_core_session_rwunlock(rsession);
2050  }
2051 
2052  return status;
2053 
2054 }
const char * switch_channel_get_partner_uuid(switch_channel_t *channel)
#define SWITCH_ORIGINATE_SIGNAL_BOND_VARIABLE
Definition: switch_types.h:203
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
#define switch_channel_get_variable(_c, _v)
char * switch_copy_string(_Out_z_cap_(dst_size) char *dst, _In_z_ const char *src, _In_ switch_size_t dst_size)
void switch_core_session_rwunlock(_In_ switch_core_session_t *session)
Unlock a read or write lock on as given session.
switch_status_t
Common return values.
#define switch_core_session_locate(uuid_str)
Locate a session based on it's uuid.
Definition: switch_core.h:916
#define switch_assert(expr)
switch_status_t switch_ivr_get_file_handle ( switch_core_session_t session,
switch_file_handle_t **  fh 
)

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

1124 {
1125  switch_file_handle_t *fhp;
1127 
1128  *fh = NULL;
1130 
1131  if ((fhp = switch_channel_get_private(channel, "__fh"))) {
1132  *fh = fhp;
1133  return SWITCH_STATUS_SUCCESS;
1134  }
1135 
1137 
1138  return SWITCH_STATUS_FALSE;
1139 }
switch_status_t switch_core_session_io_read_lock(switch_core_session_t *session)
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
switch_status_t switch_core_session_io_rwunlock(switch_core_session_t *session)
void * switch_channel_get_private(switch_channel_t *channel, const char *key)
Retrieve private from a given channel.
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().

75 {
76  int x = 0;
77 
78  if (!name) return (switch_say_gender_t)0;
79 
80  for (x = 0; SAY_GENDER_NAMES[x]; x++) {
81  if (!strcasecmp(SAY_GENDER_NAMES[x], name)) {
82  break;
83  }
84  }
85 
86  return (switch_say_gender_t) x;
87 }
static char * SAY_GENDER_NAMES[]
switch_say_gender_t
Definition: switch_types.h:442
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().

90 {
91  int x = 0;
92 
93  if (!name) return (switch_say_method_t)0;
94 
95  for (x = 0; SAY_METHOD_NAMES[x]; x++) {
96  if (!strcasecmp(SAY_METHOD_NAMES[x], name)) {
97  break;
98  }
99  }
100 
101  return (switch_say_method_t) x;
102 }
static char * SAY_METHOD_NAMES[]
switch_say_method_t
Definition: switch_types.h:411
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().

105 {
106  int x = 0;
107 
108  if (!name) return (switch_say_type_t)0;
109 
110  for (x = 0; SAY_TYPE_NAMES[x]; x++) {
111  if (!strcasecmp(SAY_TYPE_NAMES[x], name)) {
112  break;
113  }
114  }
115 
116  return (switch_say_type_t) x;
117 }
switch_say_type_t
Definition: switch_types.h:420
static char * SAY_TYPE_NAMES[]
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 4009 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().

4010 {
4011  switch_file_handle_t orig_fh = { 0 };
4012  switch_file_handle_t new_fh = { 0 };
4013  switch_codec_implementation_t read_impl = { 0 };
4014  char *tmp_file;
4015  switch_uuid_t uuid;
4016  char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
4017  int16_t *abuf = NULL;
4018  switch_size_t olen = 0;
4019  int asis = 0;
4021  switch_size_t sample_count = 0;
4022  uint32_t pos = 0;
4023  char *ext;
4024 
4025  switch_uuid_get(&uuid);
4026  switch_uuid_format(uuid_str, &uuid);
4027 
4028  if ((ext = strrchr(file, '.'))) {
4029  ext++;
4030  } else {
4031  ext = "wav";
4032  }
4033 
4034  tmp_file = switch_core_session_sprintf(session, "%s%smsg_%s.%s",
4036 
4037  switch_core_session_get_read_impl(session, &read_impl);
4038 
4039  new_fh.channels = read_impl.number_of_channels;
4040  new_fh.native_rate = read_impl.actual_samples_per_second;
4041 
4042 
4043  if (switch_core_file_open(&new_fh,
4044  tmp_file,
4045  new_fh.channels,
4047  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Failed to open file %s\n", tmp_file);
4048  goto end;
4049  }
4050 
4051 
4052  if (switch_core_file_open(&orig_fh,
4053  file,
4054  new_fh.channels,
4056  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Failed to open file %s\n", file);
4057  goto end;
4058  }
4059 
4060 
4061  switch_zmalloc(abuf, START_SAMPLES * sizeof(*abuf));
4062 
4063  if (switch_test_flag((&orig_fh), SWITCH_FILE_NATIVE)) {
4064  asis = 1;
4065  }
4066 
4067  while (switch_channel_ready(channel)) {
4068  olen = START_SAMPLES;
4069 
4070  if (!asis) {
4071  olen /= 2;
4072  }
4073 
4074  if ((sample_count + olen) > sample_point) {
4075  olen = sample_point - sample_count;
4076  }
4077 
4078  if (!olen || switch_core_file_read(&orig_fh, abuf, &olen) != SWITCH_STATUS_SUCCESS || !olen) {
4079  break;
4080  }
4081 
4082  sample_count += olen;
4083 
4084  switch_core_file_write(&new_fh, abuf, &olen);
4085  }
4086 
4087  switch_core_file_close(&orig_fh);
4088 
4089 
4090  if (switch_core_file_open(&orig_fh,
4091  insert_file,
4092  new_fh.channels,
4094  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Failed to open file %s\n", file);
4095  goto end;
4096  }
4097 
4098 
4099  while (switch_channel_ready(channel)) {
4100  olen = START_SAMPLES;
4101 
4102  if (!asis) {
4103  olen /= 2;
4104  }
4105 
4106  if (switch_core_file_read(&orig_fh, abuf, &olen) != SWITCH_STATUS_SUCCESS || !olen) {
4107  break;
4108  }
4109 
4110  sample_count += olen;
4111 
4112  switch_core_file_write(&new_fh, abuf, &olen);
4113  }
4114 
4115  switch_core_file_close(&orig_fh);
4116 
4117  if (switch_core_file_open(&orig_fh,
4118  file,
4119  new_fh.channels,
4121  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Failed to open file %s\n", file);
4122  goto end;
4123  }
4124 
4125  pos = 0;
4126  switch_core_file_seek(&orig_fh, &pos, sample_point, SEEK_SET);
4127 
4128  while (switch_channel_ready(channel)) {
4129  olen = START_SAMPLES;
4130 
4131  if (!asis) {
4132  olen /= 2;
4133  }
4134 
4135  if (switch_core_file_read(&orig_fh, abuf, &olen) != SWITCH_STATUS_SUCCESS || !olen) {
4136  break;
4137  }
4138 
4139  sample_count += olen;
4140 
4141  switch_core_file_write(&new_fh, abuf, &olen);
4142  }
4143 
4144  end:
4145 
4146  if (switch_test_flag((&orig_fh), SWITCH_FILE_OPEN)) {
4147  switch_core_file_close(&orig_fh);
4148  }
4149 
4150  if (switch_test_flag((&new_fh), SWITCH_FILE_OPEN)) {
4151  switch_core_file_close(&new_fh);
4152  }
4153 
4154  switch_file_rename(tmp_file, file, switch_core_session_get_pool(session));
4155  unlink(tmp_file);
4156 
4157  switch_safe_free(abuf);
4158 
4159  return SWITCH_STATUS_SUCCESS;
4160 }
char * switch_core_session_sprintf(_In_ switch_core_session_t *session, _In_z_ _Printf_format_string_ const char *fmt,...)
printf-style style printing routine. The data is output to a string allocated from the session ...
#define SWITCH_CHANNEL_SESSION_LOG(x)
#define switch_core_file_open(_fh, _file_path, _channels, _rate, _flags, _pool)
Open a media file using file format modules.
Definition: switch_core.h:1865
switch_status_t switch_core_file_close(_In_ switch_file_handle_t *fh)
Close an open file handle.
#define switch_channel_ready(_channel)
switch_status_t switch_core_file_seek(_In_ switch_file_handle_t *fh, unsigned int *cur_pos, int64_t samples, int whence)
Seek a position in a file.
#define START_SAMPLES
Definition: switch_ivr.c:4007
switch_status_t switch_core_file_read(_In_ switch_file_handle_t *fh, void *data, switch_size_t *len)
Read media from a file handle.
switch_status_t switch_core_session_get_read_impl(switch_core_session_t *session, switch_codec_implementation_t *impp)
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
switch_status_t switch_file_rename(const char *from_path, const char *to_path, switch_memory_pool_t *pool)
Definition: switch_apr.c:424
#define SWITCH_PATH_SEPARATOR
Definition: switch_types.h:122
#define switch_zmalloc(ptr, len)
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:789
uintptr_t switch_size_t
switch_directories SWITCH_GLOBAL_dirs
Definition: switch_core.c:60
void switch_uuid_format(char *buffer, const switch_uuid_t *uuid)
Definition: switch_apr.c:1055
switch_status_t switch_core_file_write(_In_ switch_file_handle_t *fh, void *data, switch_size_t *len)
Write media to a file handle.
void switch_uuid_get(switch_uuid_t *uuid)
Definition: switch_apr.c:1067
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:624
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
A table of settings and callbacks that define a paticular implementation of a codec.
switch_memory_pool_t * switch_core_session_get_pool(_In_ switch_core_session_t *session)
Retrieve the memory pool from a session.
#define SWITCH_UUID_FORMATTED_LENGTH
Definition: switch_apr.h:545
void switch_ivr_intercept_session ( switch_core_session_t session,
const char *  uuid,
switch_bool_t  bleg 
)

Definition at line 2056 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_partner_uuid(), 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_set_variable, 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_STATUS_SUCCESS, switch_true(), SWITCH_UUID_FORMATTED_LENGTH, and zstr.

2057 {
2058  switch_core_session_t *rsession, *bsession = NULL;
2059  switch_channel_t *channel, *rchannel, *bchannel = NULL;
2060  const char *buuid, *var;
2061  char brto[SWITCH_UUID_FORMATTED_LENGTH + 1] = "";
2062 
2063  if (bleg) {
2064  if (switch_ivr_find_bridged_uuid(uuid, brto, sizeof(brto)) == SWITCH_STATUS_SUCCESS) {
2065  uuid = switch_core_session_strdup(session, brto);
2066  } else {
2067  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "no uuid bridged to %s\n", uuid);
2068  return;
2069  }
2070  }
2071 
2072  if (zstr(uuid) || !(rsession = switch_core_session_locate(uuid))) {
2073  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "no uuid %s\n", uuid);
2074  return;
2075  }
2076 
2077  channel = switch_core_session_get_channel(session);
2078  rchannel = switch_core_session_get_channel(rsession);
2079  buuid = switch_channel_get_partner_uuid(rchannel);
2080 
2081  if ((var = switch_channel_get_variable(channel, "intercept_unbridged_only")) && switch_true(var)) {
2082  if ((switch_channel_test_flag(rchannel, CF_BRIDGED))) {
2083  switch_core_session_rwunlock(rsession);
2084  return;
2085  }
2086  }
2087 
2088  if ((var = switch_channel_get_variable(channel, "intercept_unanswered_only")) && switch_true(var)) {
2089  if ((switch_channel_test_flag(rchannel, CF_ANSWERED))) {
2090  switch_core_session_rwunlock(rsession);
2091  return;
2092  }
2093  }
2094 
2095  switch_channel_answer(channel);
2096 
2097  if (!zstr(buuid)) {
2098  if ((bsession = switch_core_session_locate(buuid))) {
2099  bchannel = switch_core_session_get_channel(bsession);
2101  }
2102  }
2103 
2104  if (!switch_channel_test_flag(rchannel, CF_ANSWERED)) {
2105  switch_channel_answer(rchannel);
2106  }
2107 
2109 
2111  switch_channel_set_state(rchannel, CS_PARK);
2112 
2113  if (bchannel) {
2114  switch_channel_set_variable(bchannel, "park_after_bridge", "true");
2115  }
2116 
2119  switch_core_session_rwunlock(rsession);
2120 
2121  if (bsession) {
2123  switch_core_session_rwunlock(bsession);
2124  }
2125 
2126 
2127 
2128 }
#define switch_channel_hangup(channel, hangup_cause)
Hangup a channel flagging it's state machine to end.
#define switch_channel_answer(channel)
Answer a channel (initiate/acknowledge a successful connection)
#define SWITCH_CHANNEL_SESSION_LOG(x)
const char * switch_channel_get_partner_uuid(switch_channel_t *channel)
#define switch_channel_set_state(channel, state)
Set the current state of a channel.
void switch_channel_set_state_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Set given flag(s) on a given channel to be applied on the next state change.
static int switch_true(const char *expr)
Evaluate the truthfullness of a string expression.
Definition: switch_utils.h:450
uint32_t switch_channel_test_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Test for presence of given flag on a given channel.
#define zstr(x)
Definition: switch_utils.h:281
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
void switch_channel_mark_hold(switch_channel_t *channel, switch_bool_t on)
switch_status_t switch_ivr_find_bridged_uuid(const char *uuid, char *b_uuid, switch_size_t blen)
#define switch_channel_get_variable(_c, _v)
switch_status_t switch_ivr_uuid_bridge(const char *originator_uuid, const char *originatee_uuid)
Bridge two existing sessions.
void switch_core_session_rwunlock(_In_ switch_core_session_t *session)
Unlock a read or write lock on as given session.
char * switch_core_session_get_uuid(_In_ switch_core_session_t *session)
Retrieve the unique identifier from a session.
#define switch_core_session_locate(uuid_str)
Locate a session based on it's uuid.
Definition: switch_core.h:916
#define switch_channel_set_flag(_c, _f)
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
#define switch_core_session_strdup(_session, _todup)
Copy a string using memory allocation from a session's pool.
Definition: switch_core.h:717
#define switch_channel_set_variable(_channel, _var, _val)
#define SWITCH_UUID_FORMATTED_LENGTH
Definition: switch_apr.h:545
switch_status_t switch_ivr_kill_uuid ( const char *  uuid,
switch_call_cause_t  cause 
)

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

4241 {
4243 
4244  if (zstr(uuid) || !(session = switch_core_session_locate(uuid))) {
4245  return SWITCH_STATUS_FALSE;
4246  } else {
4248  switch_channel_hangup(channel, cause);
4250  return SWITCH_STATUS_SUCCESS;
4251  }
4252 }
#define switch_channel_hangup(channel, hangup_cause)
Hangup a channel flagging it's state machine to end.
switch_core_session_t * session
#define zstr(x)
Definition: switch_utils.h:281
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
void switch_core_session_rwunlock(_In_ switch_core_session_t *session)
Unlock a read or write lock on as given session.
#define switch_core_session_locate(uuid_str)
Locate a session based on it's uuid.
Definition: switch_core.h:916
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
menuThe menu obj you wish to bind to.
ivr_actionswitch_ivr_action_t enum of what you want to do.
argOptional (sometimes necessary) string arguement.
bindKeyStrokes to bind the action to.
Returns
SWUTCH_STATUS_SUCCESS if the action was binded

Definition at line 244 of file switch_ivr_menu.c.

References switch_ivr_menu_action::arg, switch_ivr_menu_action::bind, switch_ivr_menu_action::ivr_action, switch_ivr_menu_action::next, switch_ivr_menu_action::re, switch_core_alloc, switch_core_strdup, SWITCH_STATUS_MEMERR, and SWITCH_STATUS_SUCCESS.

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

245 {
246  switch_ivr_menu_action_t *action, *ap;
247  uint32_t len;
248 
249  if ((action = switch_core_alloc(menu->pool, sizeof(*action)))) {
250  action->bind = switch_core_strdup(menu->pool, bind);
251  action->arg = switch_core_strdup(menu->pool, arg);
252  if (*action->bind == '/') {
253  action->re = 1;
254  } else {
255  len = (uint32_t) strlen(action->bind);
256  if (len > menu->inlen) {
257  menu->inlen = len;
258  }
259  }
260  action->ivr_action = ivr_action;
261 
262  if (menu->actions) {
263  for(ap = menu->actions; ap && ap->next; ap = ap->next);
264  ap->next = action;
265  } else {
266  menu->actions = action;
267  }
268 
269  return SWITCH_STATUS_SUCCESS;
270  }
271 
272  return SWITCH_STATUS_MEMERR;
273 }
#define switch_core_strdup(_pool, _todup)
Copy a string using memory allocation from a given pool.
Definition: switch_core.h:729
struct switch_ivr_menu_action * actions
switch_size_t inlen
#define switch_core_alloc(_pool, _mem)
Allocate memory directly from a memory pool.
Definition: switch_core.h:682
switch_ivr_action_t ivr_action
switch_memory_pool_t * pool
struct switch_ivr_menu_action * next
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
menuThe menu obj you wish to bind to.
functionThe function to call [int proto(struct switch_ivr_menu *, char *, size_t, void *)]
argOptional (sometimes necessary) string arguement.
bindKeyStrokes 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 275 of file switch_ivr_menu.c.

References switch_ivr_menu_action::arg, switch_ivr_menu_action::bind, switch_ivr_menu_action::function, switch_ivr_menu_action::next, switch_ivr_menu_action::re, switch_core_alloc, switch_core_strdup, SWITCH_STATUS_MEMERR, and SWITCH_STATUS_SUCCESS.

Referenced by switch_ivr_menu_stack_xml_build().

277 {
278  switch_ivr_menu_action_t *action, *ap;
279  uint32_t len;
280 
281  if ((action = switch_core_alloc(menu->pool, sizeof(*action)))) {
282  action->bind = switch_core_strdup(menu->pool, bind);
283  action->arg = switch_core_strdup(menu->pool, arg);
284 
285  if (*action->bind == '/') {
286  action->re = 1;
287  } else {
288  len = (uint32_t) strlen(action->bind);
289  if (len > menu->inlen) {
290  menu->inlen = len;
291  }
292  }
293 
294  action->function = function;
295 
296  if (menu->actions) {
297  for(ap = menu->actions; ap && ap->next; ap = ap->next);
298  ap->next = action;
299  } else {
300  menu->actions = action;
301  }
302 
303  return SWITCH_STATUS_SUCCESS;
304  }
305 
306  return SWITCH_STATUS_MEMERR;
307 }
switch_ivr_menu_action_function_t * function
#define switch_core_strdup(_pool, _todup)
Copy a string using memory allocation from a given pool.
Definition: switch_core.h:729
struct switch_ivr_menu_action * actions
switch_size_t inlen
#define switch_core_alloc(_pool, _mem)
Allocate memory directly from a memory pool.
Definition: switch_core.h:682
switch_memory_pool_t * pool
struct switch_ivr_menu_action * next
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
sessionThe session running the menu.
stackThe top-level menu object (the first one you created.)
nameA pointer to the name of the menu.
objA 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 450 of file switch_ivr_menu.c.

References actions, switch_ivr_menu_action::arg, bad_pin_file, switch_ivr_menu_action::bind, buf, exec_app(), exec_on_max_fail, exec_on_max_timeout, exit_sound, switch_ivr_menu_action::function, greeting_sound, inlen, invalid_sound, switch_ivr_menu_action::ivr_action, ivr_send_event(), max_failures, max_timeouts, memset(), MENU_EVENT_ENTER, MENU_EVENT_EXIT, name, switch_ivr_menu_action::next, pin, play_and_collect(), prompt_pin_file, 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_sprintf(), switch_core_session_strdup, 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_find(), SWITCH_IVR_MENU_FLAG_FALLTOMAIN, SWITCH_IVR_MENU_FLAG_STACK, switch_ivr_play_file(), switch_loadable_module_get_application_interface(), SWITCH_LOG_DEBUG, SWITCH_LOG_ERROR, switch_log_printf(), SWITCH_LOG_WARNING, switch_perform_substitution(), switch_play_and_get_digits(), 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, transfer_sound, tts_engine, tts_voice, UNPROTECT_INTERFACE, and zstr.

Referenced by IVRMenu::execute().

451 {
452  int reps = 0, errs = 0, timeouts = 0, match = 0, running = 1;
453  char *greeting_sound = NULL, *aptr = NULL;
454  char arg[512];
457  switch_ivr_menu_t *menu = NULL;
458  switch_channel_t *channel;
460 
461  if (++stack->stack_count > 12) {
462  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Too many levels of recursion.\n");
464  }
465 
466  if (!session || !stack || zstr(name)) {
467  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid menu context\n");
469  }
470 
471  channel = switch_core_session_get_channel(session);
472 
473  if (!(menu = switch_ivr_menu_find(stack, name))) {
474  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid Menu!\n");
476  }
477 
478  if (!zstr(menu->tts_engine) && !zstr(menu->tts_voice)) {
479  switch_channel_set_variable(channel, "tts_engine", menu->tts_engine);
480  switch_channel_set_variable(channel, "tts_voice", menu->tts_voice);
481  }
482 
483  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Executing IVR menu %s\n", menu->name);
484  switch_channel_set_variable(channel, "ivr_menu_status", "success");
485 
486  ivr_send_event(session, MENU_EVENT_ENTER, menu);
487 
488  if (!zstr(menu->pin)) {
489  char digit_buffer[128] = "";
490  char *digits_regex = switch_core_session_sprintf(session, "^%s$", menu->pin);
491 
492  if (switch_play_and_get_digits(session, (uint32_t)strlen(menu->pin), (uint32_t)strlen(menu->pin), 3, 3000, "#",
493  menu->prompt_pin_file, menu->bad_pin_file, NULL, digit_buffer, sizeof(digit_buffer),
494  digits_regex, 10000, NULL) != SWITCH_STATUS_SUCCESS) {
496  }
497  }
498 
499 
500  for (reps = 0; running && status == SWITCH_STATUS_SUCCESS; reps++) {
501  if (!switch_channel_ready(channel)) {
502  break;
503  }
504  if (errs == menu->max_failures) {
505  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Maximum failures\n");
506  switch_channel_set_variable(channel, "ivr_menu_status", "failure");
507  if (!zstr(menu->exec_on_max_fail)) {
508  exec_app(session, menu->exec_on_max_fail);
509  }
510  break;
511  }
512  if (timeouts == menu->max_timeouts) {
513  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Maximum timeouts\n");
514  switch_channel_set_variable(channel, "ivr_menu_status", "timeout");
515  if (!zstr(menu->exec_on_max_timeout)) {
516  exec_app(session, menu->exec_on_max_timeout);
517  }
518  break;
519  }
520 
521  if (reps > 0 && menu->short_greeting_sound) {
522  greeting_sound = menu->short_greeting_sound;
523  } else {
524  greeting_sound = menu->greeting_sound;
525  }
526 
527  match = 0;
528  aptr = NULL;
529 
530  memset(arg, 0, sizeof(arg));
531 
532  memset(menu->buf, 0, menu->inlen + 1);
533 
534  if (play_and_collect(session, menu, greeting_sound, menu->inlen) == SWITCH_STATUS_TIMEOUT && *menu->buf == '\0') {
535  timeouts++;
536  continue;
537  }
538 
539  if (*menu->buf != '\0') {
540 
541  for (ap = menu->actions; ap; ap = ap->next) {
542  int ok = 0;
543  char substituted[1024];
544  char *use_arg = ap->arg;
545 
546  if (!zstr(menu->tts_engine) && !zstr(menu->tts_voice)) {
547  switch_channel_set_variable(channel, "tts_engine", menu->tts_engine);
548  switch_channel_set_variable(channel, "tts_voice", menu->tts_voice);
549  }
550 
551  if (ap->re) {
552  switch_regex_t *re = NULL;
553  int ovector[30];
554 
555  if ((ok = switch_regex_perform(menu->buf, ap->bind, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
556  switch_perform_substitution(re, ok, ap->arg, menu->buf, substituted, sizeof(substituted), ovector);
557  use_arg = substituted;
558  }
559  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "action regex [%s] [%s] [%d]\n", menu->buf, ap->bind, ok);
560 
562  } else {
563  ok = !strcmp(menu->buf, ap->bind);
564  }
565 
566  if (ok) {
567  match++;
568  errs = 0;
569  if (ap->function) {
571  "IVR function on menu '%s' matched '%s' param '%s'\n", menu->name, menu->buf, use_arg);
572  todo = ap->function(menu, use_arg, arg, sizeof(arg), obj);
573  aptr = arg;
574  } else {
575  todo = ap->ivr_action;
576  aptr = use_arg;
578  "IVR action on menu '%s' matched '%s' param '%s'\n", menu->name, menu->buf, aptr);
579  }
580 
581  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "switch_ivr_menu_execute todo=[%d]\n", todo);
582 
583  switch (todo) {
585  status = SWITCH_STATUS_FALSE;
586  break;
588  status = switch_ivr_play_file(session, NULL, aptr, NULL);
589  break;
591  if (!strcmp(aptr, menu->name)) {
592  status = SWITCH_STATUS_SUCCESS;
593  } else {
594  reps = -1;
595  ivr_send_event(session, MENU_EVENT_EXIT, menu);
596  status = switch_ivr_menu_execute(session, stack, aptr, obj);
597  ivr_send_event(session, MENU_EVENT_ENTER, menu);
598  }
599  break;
601  {
602  switch_application_interface_t *application_interface;
603  char *app_name;
604  char *app_arg = NULL;
605 
606  status = SWITCH_STATUS_FALSE;
607 
608  if (!zstr(aptr)) {
609  app_name = switch_core_session_strdup(session, aptr);
610  if ((app_arg = strchr(app_name, ' '))) {
611  *app_arg++ = '\0';
612  }
613 
614  if ((application_interface = switch_loadable_module_get_application_interface(app_name))) {
615  if (!zstr(menu->transfer_sound) && !strcmp(app_name, "transfer")) {
616  status = play_and_collect(session, menu, menu->transfer_sound, 0);
617  }
618 
619  switch_core_session_exec(session, application_interface, app_arg);
620  UNPROTECT_INTERFACE(application_interface);
621  status = SWITCH_STATUS_SUCCESS;
622  }
623  }
624  }
625  break;
627  running = 0;
628  status = SWITCH_STATUS_SUCCESS;
629  break;
632  status = SWITCH_STATUS_BREAK;
633  break;
635  status = SWITCH_STATUS_SUCCESS;
636  break;
637  default:
639  break;
640  }
641  }
642  }
643 
644  if (switch_test_flag(menu, SWITCH_IVR_MENU_FLAG_STACK)) { /* top level */
645  if (switch_test_flag(stack, SWITCH_IVR_MENU_FLAG_FALLTOMAIN)) { /* catch the fallback and recover */
647  status = SWITCH_STATUS_SUCCESS;
648  running = 1;
649  continue;
650  }
651  }
652  }
653  if (!match) {
654  if (*menu->buf) {
655  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "IVR menu '%s' caught invalid input '%s'\n", menu->name,
656  menu->buf);
657  if (menu->invalid_sound) {
658  play_and_collect(session, menu, menu->invalid_sound, 0);
659  }
660  } else {
661  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "IVR menu '%s' no input detected\n", menu->name);
662  }
663  errs++;
664 
665  /* breaks are ok too */
666  if (SWITCH_STATUS_IS_BREAK(status)) {
667  status = SWITCH_STATUS_SUCCESS;
668  }
669  }
670  }
671 
672  if (stack->stack_count == 1) {
673  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "exit-sound '%s'\n", menu->exit_sound);
674  if (!zstr(menu->exit_sound)) {
675  status = play_and_collect(session, menu, menu->exit_sound, 0);
676  }
677  }
678 
679  end:
680 
681  stack->stack_count--;
682 
683  if (menu) {
684  ivr_send_event(session, MENU_EVENT_EXIT, menu);
685  }
686 
687  return status;
688 }
#define switch_regex_safe_free(re)
Definition: switch_regex.h:79
A module interface to implement an application.
char * switch_core_session_sprintf(_In_ switch_core_session_t *session, _In_z_ _Printf_format_string_ const char *fmt,...)
printf-style style printing routine. The data is output to a string allocated from the session ...
switch_ivr_menu_action_function_t * function
#define SWITCH_CHANNEL_SESSION_LOG(x)
#define switch_set_flag(obj, flag)
Set a flag on an arbitrary object.
Definition: switch_utils.h:631
switch_status_t switch_play_and_get_digits(switch_core_session_t *session, uint32_t min_digits, uint32_t max_digits, uint32_t max_tries, uint32_t timeout, const char *valid_terminators, const char *audio_file, const char *bad_input_audio_file, const char *var_name, char *digit_buffer, uint32_t digit_buffer_length, const char *digits_regex, uint32_t digit_timeout, const char *transfer_on_failure)
Play a sound and gather digits with the number of retries specified if the user doesn't give digits i...
#define SWITCH_STATUS_IS_BREAK(x)
Definition: switch_utils.h:564
void switch_perform_substitution(switch_regex_t *re, int match_count, const char *data, const char *field_data, char *substituted, switch_size_t len, int *ovector)
Definition: switch_regex.c:131
#define switch_channel_ready(_channel)
switch_status_t switch_core_session_exec(_In_ switch_core_session_t *session, _In_ const switch_application_interface_t *application_interface, _In_opt_z_ const char *arg)
Execute an application on a session.
switch_status_t switch_ivr_play_file(switch_core_session_t *session, switch_file_handle_t *fh, const char *file, switch_input_args_t *args)
play a file from the disk to the session
struct real_pcre switch_regex_t
Definition: switch_regex.h:43
switch_status_t switch_ivr_menu_execute(switch_core_session_t *session, switch_ivr_menu_t *stack, char *name, void *obj)
Execute a menu.
struct switch_ivr_menu_action * actions
#define zstr(x)
Definition: switch_utils.h:281
switch_size_t inlen
static void ivr_send_event(switch_core_session_t *session, char *event_type, switch_ivr_menu_t *menu)
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
#define UNPROTECT_INTERFACE(_it)
#define switch_clear_flag(obj, flag)
Clear a flag on an arbitrary object while locked.
Definition: switch_utils.h:655
static void exec_app(switch_core_session_t *session, char *app_str)
switch_application_interface_t * switch_loadable_module_get_application_interface(const char *name)
Retrieve the application interface by it's registered name.
switch_ivr_action_t ivr_action
static switch_status_t play_and_collect(switch_core_session_t *session, switch_ivr_menu_t *menu, char *sound, switch_size_t need)
int switch_regex_perform(const char *field, const char *expression, switch_regex_t **new_re, int *ovector, uint32_t olen)
Definition: switch_regex.c:55
#define MENU_EVENT_EXIT
static int32_t running
switch_status_t
Common return values.
#define switch_goto_status(_status, _label)
Definition: switch_utils.h:256
char * exec_on_max_timeout
switch_ivr_action_t
Definition: switch_ivr.h:773
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:624
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
#define MENU_EVENT_ENTER
#define switch_core_session_strdup(_session, _todup)
Copy a string using memory allocation from a session's pool.
Definition: switch_core.h:717
struct switch_ivr_menu_action * next
#define switch_channel_set_variable(_channel, _var, _val)
memset(buf, 0, buflen)
char * short_greeting_sound
static switch_ivr_menu_t * switch_ivr_menu_find(switch_ivr_menu_t *stack, const char *name)
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 *  transfer_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_menuthe pointer to the new menu
mainThe top level menu, (NULL if this is the top level one).
nameA pointer to the name of this menu.
greeting_soundOptional pointer to a main sound (press 1 for this 2 for that).
short_greeting_soundOptional pointer to a shorter main sound for subsequent loops.
invalid_soundOptional pointer to a sound to play after invalid input.
exit_soundOptional pointer to a sound to play upon exiting the menu.
transfer_soundOptional pointer to a sound to play upon transfer away from the menu.
confirm_macrophrase macro name to confirm input
confirm_keythe dtmf key required for positive confirmation
tts_enginethe tts engine to use for this menu
tts_voicethe tts voice to use for this menu
confirm_attemptsnumber of times to prompt to confirm input before failure
inter_timeoutinter-digit timeout
digit_lenmax number of digits
timeoutA number of milliseconds to pause before looping.
max_failuresMaximum number of failures to withstand before hangingup This resets everytime you enter the menu.
poolmemory pool (NULL to create one).
Returns
SWITCH_STATUS_SUCCESS if the menu was created.

Definition at line 116 of file switch_ivr_menu.c.

References actions, buf, confirm_attempts, confirm_key, confirm_macro, exit_sound, greeting_sound, inlen, inter_timeout, invalid_sound, max_failures, max_timeouts, name, pool, pool, short_greeting_sound, 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, timeout, transfer_sound, tts_engine, tts_voice, and zstr.

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

131 {
132  switch_ivr_menu_t *menu;
133  uint8_t newpool = 0;
134 
135  if (!pool) {
138  return SWITCH_STATUS_MEMERR;
139  }
140  newpool = 1;
141  }
142 
143  if (!(menu = switch_core_alloc(pool, sizeof(*menu)))) {
144  if (newpool) {
147  return SWITCH_STATUS_MEMERR;
148  }
149  }
150 
151  menu->pool = pool;
152 
153  if (!confirm_attempts) {
154  confirm_attempts = 3;
155  }
156 
157  if (!inter_timeout) {
158  inter_timeout = timeout / 2;
159  }
160 
161  if (!zstr(name)) {
162  menu->name = switch_core_strdup(menu->pool, name);
163  }
164 
165  if (!zstr(greeting_sound)) {
166  menu->greeting_sound = switch_core_strdup(menu->pool, greeting_sound);
167  }
168 
169  if (!zstr(short_greeting_sound)) {
170  menu->short_greeting_sound = switch_core_strdup(menu->pool, short_greeting_sound);
171  }
172 
173  if (!zstr(invalid_sound)) {
174  menu->invalid_sound = switch_core_strdup(menu->pool, invalid_sound);
175  }
176 
177  if (!zstr(transfer_sound)) {
178  menu->transfer_sound = switch_core_strdup(menu->pool, transfer_sound);
179  }
180 
181  if (!zstr(exit_sound)) {
182  menu->exit_sound = switch_core_strdup(menu->pool, exit_sound);
183  }
184 
185  if (!zstr(confirm_key)) {
186  menu->confirm_key = switch_core_strdup(menu->pool, confirm_key);
187  }
188 
189  if (!zstr(confirm_macro)) {
190  menu->confirm_macro = switch_core_strdup(menu->pool, confirm_macro);
191  }
192 
193  if (!zstr(tts_engine)) {
194  menu->tts_engine = switch_core_strdup(menu->pool, tts_engine);
195  }
196 
197  if (!zstr(tts_voice)) {
198  menu->tts_voice = switch_core_strdup(menu->pool, tts_voice);
199  }
200 
201  menu->confirm_attempts = confirm_attempts;
202 
203  menu->inlen = digit_len;
204 
205  if (max_failures > 0) {
206  menu->max_failures = max_failures;
207  } else {
208  menu->max_failures = 3;
209  }
210 
211  if (max_timeouts > 0) {
212  menu->max_timeouts = max_timeouts;
213  } else {
214  menu->max_timeouts = 3;
215  }
216 
217  menu->timeout = timeout;
218 
219  menu->inter_timeout = inter_timeout;
220 
221  menu->actions = NULL;
222 
223  if (newpool) {
225  }
226 
227  if (menu->timeout <= 0) {
228  menu->timeout = 10000;
229  }
230 
231  if (main) {
232  switch_ivr_menu_stack_add(&main, menu);
233  } else {
235  }
236 
237  menu->buf = switch_core_alloc(menu->pool, 1024);
238 
239  *new_menu = menu;
240 
241  return SWITCH_STATUS_SUCCESS;
242 }
#define switch_core_new_memory_pool(p)
Create a new sub memory pool from the core's master pool.
Definition: switch_core.h:631
#define switch_set_flag(obj, flag)
Set a flag on an arbitrary object.
Definition: switch_utils.h:631
#define SWITCH_CHANNEL_LOG
#define switch_core_strdup(_pool, _todup)
Copy a string using memory allocation from a given pool.
Definition: switch_core.h:729
#define switch_core_destroy_memory_pool(p)
Returns a subpool back to the main pool.
Definition: switch_core.h:640
switch_memory_pool_t * pool
struct switch_ivr_menu_action * actions
#define zstr(x)
Definition: switch_utils.h:281
switch_size_t inlen
#define switch_core_alloc(_pool, _mem)
Allocate memory directly from a memory pool.
Definition: switch_core.h:682
switch_memory_pool_t * pool
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
static void switch_ivr_menu_stack_add(switch_ivr_menu_t **top, switch_ivr_menu_t *bottom)
char * short_greeting_sound
switch_status_t switch_ivr_menu_stack_free ( switch_ivr_menu_t stack)

free a stack of menu objects.

Parameters
stackThe 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 309 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().

310 {
312 
313  if (stack != NULL && stack->pool != NULL) {
316  switch_memory_pool_t *pool = stack->pool;
317  status = switch_core_destroy_memory_pool(&pool);
318  } else {
319  status = SWITCH_STATUS_SUCCESS;
320  }
321  }
322 
323  return status;
324 }
#define switch_core_destroy_memory_pool(p)
Returns a subpool back to the main pool.
Definition: switch_core.h:640
switch_memory_pool_t * pool
switch_status_t
Common return values.
switch_memory_pool_t * pool
struct apr_pool_t switch_memory_pool_t
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:624
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_ctxThe XML menu parser context previously created by switch_ivr_menu_stack_xml_init
nameThe xml tag name to add to the parser engine
functionThe 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 840 of file switch_ivr_menu.c.

References switch_ivr_menu_stack_xml_add().

842 {
843  return switch_ivr_menu_stack_xml_add(xml_menu_ctx, name, -1, function);
844 }
static switch_status_t switch_ivr_menu_stack_xml_add(switch_ivr_menu_xml_ctx_t *xml_ctx, const char *name, int action, switch_ivr_menu_action_function_t *function)
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_ctxThe XML menu parser context previously created by switch_ivr_menu_stack_xml_init
menu_stackThe menu stack object that will be created for you
xml_menusThe xml Menus source
xml_menuThe xml Menu source of the menu to be created
Returns
SWITCH_STATUS_SUCCESS if all is well

Definition at line 846 of file switch_ivr_menu.c.

References switch_ivr_menu_xml_map::action, bad_pin_file, exec_on_max_fail, exec_on_max_timeout, switch_ivr_menu_xml_map::function, is_valid_action(), switch_ivr_menu_xml_map::name, switch_xml::next, switch_ivr_menu_xml_map::next, pin, pool, prompt_pin_file, SWITCH_CHANNEL_LOG, switch_core_strdup, 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_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.

848 {
850 
851  if (xml_menu_ctx != NULL && menu_stack != NULL && xml_menu != NULL) {
852  const char *menu_name = switch_xml_attr_soft(xml_menu, "name"); /* if the attr doesn't exist, return "" */
853  const char *greet_long = switch_xml_attr(xml_menu, "greet-long"); /* if the attr doesn't exist, return NULL */
854  const char *greet_short = switch_xml_attr(xml_menu, "greet-short"); /* if the attr doesn't exist, return NULL */
855  const char *invalid_sound = switch_xml_attr(xml_menu, "invalid-sound"); /* if the attr doesn't exist, return NULL */
856  const char *exit_sound = switch_xml_attr(xml_menu, "exit-sound"); /* if the attr doesn't exist, return NULL */
857  const char *transfer_sound = switch_xml_attr(xml_menu, "transfer-sound"); /* if the attr doesn't exist, return NULL */
858  const char *timeout = switch_xml_attr_soft(xml_menu, "timeout"); /* if the attr doesn't exist, return "" */
859  const char *max_failures = switch_xml_attr_soft(xml_menu, "max-failures"); /* if the attr doesn't exist, return "" */
860  const char *max_timeouts = switch_xml_attr_soft(xml_menu, "max-timeouts");
861  const char *exec_on_max_fail = switch_xml_attr(xml_menu, "exec-on-max-failures");
862  const char *exec_on_max_timeout = switch_xml_attr(xml_menu, "exec-on-max-timeouts");
863  const char *confirm_macro = switch_xml_attr(xml_menu, "confirm-macro");
864  const char *confirm_key = switch_xml_attr(xml_menu, "confirm-key");
865  const char *tts_engine = switch_xml_attr(xml_menu, "tts-engine");
866  const char *tts_voice = switch_xml_attr(xml_menu, "tts-voice");
867  const char *confirm_attempts = switch_xml_attr_soft(xml_menu, "confirm-attempts");
868  const char *digit_len = switch_xml_attr_soft(xml_menu, "digit-len");
869  const char *inter_timeout = switch_xml_attr_soft(xml_menu, "inter-digit-timeout");
870  const char *pin = switch_xml_attr_soft(xml_menu, "pin");
871  const char *prompt_pin_file = switch_xml_attr_soft(xml_menu, "pin-file");
872  const char *bad_pin_file = switch_xml_attr_soft(xml_menu, "bad-pin-file");
873 
874  switch_ivr_menu_t *menu = NULL;
875 
876  if (zstr(max_timeouts)) {
877  max_timeouts = max_failures;
878  }
879 
880  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "building menu '%s'\n", menu_name);
881 
882  status = switch_ivr_menu_init(&menu,
883  *menu_stack,
884  menu_name,
885  greet_long,
886  greet_short,
887  invalid_sound,
888  exit_sound,
889  transfer_sound,
890  confirm_macro,
891  confirm_key,
892  tts_engine,
893  tts_voice,
894  atoi(confirm_attempts),
895  atoi(inter_timeout),
896  atoi(digit_len),
897  atoi(timeout),
898  strlen(max_failures) ? atoi(max_failures) : 0, strlen(max_timeouts) ? atoi(max_timeouts) : 0, xml_menu_ctx->pool);
899 
900 
901  if (!zstr(exec_on_max_fail)) {
902  menu->exec_on_max_fail = switch_core_strdup(menu->pool, exec_on_max_fail);
903  }
904 
905  if (!zstr(exec_on_max_timeout)) {
906  menu->exec_on_max_timeout = switch_core_strdup(menu->pool, exec_on_max_timeout);
907  }
908 
909  if (!zstr(pin)) {
910  if (zstr(prompt_pin_file)) {
911  prompt_pin_file = "ivr/ivr-please_enter_pin_followed_by_pound.wav";
912  }
913  if (zstr(bad_pin_file)) {
914  bad_pin_file = "conference/conf-bad-pin.wav";
915  }
916  menu->pin = switch_core_strdup(menu->pool, pin);
917  menu->prompt_pin_file = switch_core_strdup(menu->pool, prompt_pin_file);
918  menu->bad_pin_file = switch_core_strdup(menu->pool, bad_pin_file);
919  }
920 
921  /* set the menu_stack for the caller */
922  if (status == SWITCH_STATUS_SUCCESS && *menu_stack == NULL) {
923  *menu_stack = menu;
924 
925  if (xml_menu_ctx->autocreated) {
927  }
928  }
929 
930  if (status == SWITCH_STATUS_SUCCESS && menu != NULL) {
931  switch_xml_t xml_kvp;
932 
933  /* build menu entries */
934  for (xml_kvp = switch_xml_child(xml_menu, "entry"); xml_kvp != NULL && status == SWITCH_STATUS_SUCCESS; xml_kvp = xml_kvp->next) {
935  const char *action = switch_xml_attr(xml_kvp, "action");
936  const char *digits = switch_xml_attr(xml_kvp, "digits");
937  const char *param = switch_xml_attr_soft(xml_kvp, "param");
938 
939  if (is_valid_action(action) && !zstr(digits)) {
940  switch_ivr_menu_xml_map_t *xml_map = xml_menu_ctx->map;
941  int found = 0;
942 
943  /* find and appropriate xml handler */
944  while (xml_map != NULL && !found) {
945  if (!(found = (strcasecmp(xml_map->name, action) == 0))) {
946  xml_map = xml_map->next;
947  }
948  }
949 
950  if (found && xml_map != NULL) {
951  /* do we need to build a new sub-menu ? */
952  if (xml_map->action == SWITCH_IVR_ACTION_EXECMENU && switch_ivr_menu_find(*menu_stack, param) == NULL) {
953  if ((xml_menu = switch_xml_find_child(xml_menus, "menu", "name", param)) != NULL) {
954  status = switch_ivr_menu_stack_xml_build(xml_menu_ctx, menu_stack, xml_menus, xml_menu);
955  }
956  }
957  /* finally bind the menu entry */
958  if (status == SWITCH_STATUS_SUCCESS) {
959  if (xml_map->function != NULL) {
961  "binding menu caller control '%s'/'%s' to '%s'\n", xml_map->name, param, digits);
962  status = switch_ivr_menu_bind_function(menu, xml_map->function, param, digits);
963  } else {
964  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "binding menu action '%s' to '%s'\n", xml_map->name, digits);
965  status = switch_ivr_menu_bind_action(menu, xml_map->action, param, digits);
966  }
967  }
968  }
969  } else {
970  status = SWITCH_STATUS_FALSE;
971  }
972  }
973  }
974  }
975 
976  if (status != SWITCH_STATUS_SUCCESS) {
977  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to build xml menu\n");
978  }
979 
980  return status;
981 }
const char * switch_xml_attr_soft(_In_ switch_xml_t xml, _In_z_ const char *attr)
returns the value of the requested tag attribute, or "" if not found
#define switch_set_flag(obj, flag)
Set a flag on an arbitrary object.
Definition: switch_utils.h:631
#define SWITCH_CHANNEL_LOG
switch_xml_t switch_xml_find_child(_In_ switch_xml_t node, _In_z_ const char *childname, _In_opt_z_ const char *attrname, _In_opt_z_ const char *value)
find a child tag in a node called 'childname' with an attribute 'attrname' which equals 'value' ...
const char * switch_xml_attr(_In_opt_ switch_xml_t xml, _In_opt_z_ const char *attr)
returns the value of the requested tag attribute, or NULL if not found
#define switch_core_strdup(_pool, _todup)
Copy a string using memory allocation from a given pool.
Definition: switch_core.h:729
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.
A representation of an XML tree.
Definition: switch_xml.h:76
#define zstr(x)
Definition: switch_utils.h:281
switch_xml_t next
Definition: switch_xml.h:88
switch_memory_pool_t * pool
struct switch_ivr_menu_xml_map * next
static switch_bool_t is_valid_action(const char *action)
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 *transfer_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
Common return values.
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.
char * exec_on_max_timeout
switch_memory_pool_t * pool
switch_xml_t switch_xml_child(_In_ switch_xml_t xml, _In_z_ const char *name)
returns the first child tag (one level deeper) with the given name or NULL \ if not found ...
switch_ivr_menu_action_function_t * function
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
struct switch_ivr_menu_xml_map * map
switch_ivr_action_t action
static switch_ivr_menu_t * switch_ivr_menu_find(switch_ivr_menu_t *stack, const char *name)
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_stack_xml_init ( switch_ivr_menu_xml_ctx_t **  xml_menu_ctx,
switch_memory_pool_t pool 
)
Parameters
xml_menu_ctxA pointer of a XML menu parser context to be created
poolmemory pool (NULL to create one)
Returns
SWITCH_STATUS_SUCCESS if all is well

Definition at line 805 of file switch_ivr_menu.c.

References iam, iam_s::name, pool, 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.

806 {
808  int autocreated = 0;
809 
810  /* build a memory pool ? */
811  if (pool == NULL) {
813  autocreated = 1;
814  }
815  /* allocate the xml context */
816  if (xml_menu_ctx != NULL && pool != NULL) {
817  *xml_menu_ctx = switch_core_alloc(pool, sizeof(switch_ivr_menu_xml_ctx_t));
818  if (*xml_menu_ctx != NULL) {
819  (*xml_menu_ctx)->pool = pool;
820  (*xml_menu_ctx)->autocreated = autocreated;
821  (*xml_menu_ctx)->map = NULL;
822  status = SWITCH_STATUS_SUCCESS;
823  } else {
824  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to alloc xml_ctx\n");
825  status = SWITCH_STATUS_FALSE;
826  }
827  }
828  /* build the standard/default xml menu handler mappings */
829  if (status == SWITCH_STATUS_SUCCESS && xml_menu_ctx != NULL && *xml_menu_ctx != NULL) {
830  int i;
831 
832  for (i = 0; iam[i].name && status == SWITCH_STATUS_SUCCESS; i++) {
833  status = switch_ivr_menu_stack_xml_add(*xml_menu_ctx, iam[i].name, iam[i].action, NULL);
834  }
835  }
836 
837  return status;
838 }
#define switch_core_new_memory_pool(p)
Create a new sub memory pool from the core's master pool.
Definition: switch_core.h:631
const char * name
#define SWITCH_CHANNEL_LOG
switch_memory_pool_t * pool
#define switch_core_alloc(_pool, _mem)
Allocate memory directly from a memory pool.
Definition: switch_core.h:682
switch_status_t
Common return values.
static struct iam_s iam[]
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
static switch_status_t switch_ivr_menu_stack_xml_add(switch_ivr_menu_xml_ctx_t *xml_ctx, const char *name, int action, switch_ivr_menu_action_function_t *function)
switch_status_t switch_ivr_menu_str2action ( const char *  action_name,
switch_ivr_action_t action 
)

Definition at line 765 of file switch_ivr_menu.c.

References iam_s::action, iam, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, and zstr.

Referenced by IVRMenu::bindAction().

766 {
767  int i;
768 
769  if (!zstr(action_name)) {
770  for (i = 0;; i++) {
771  if (!iam[i].name) {
772  break;
773  }
774 
775  if (!strcasecmp(iam[i].name, action_name)) {
776  *action = iam[i].action;
777  return SWITCH_STATUS_SUCCESS;
778  }
779  }
780  }
781 
782  return SWITCH_STATUS_FALSE;
783 }
#define zstr(x)
Definition: switch_utils.h:281
switch_ivr_action_t action
static struct iam_s iam[]
void switch_ivr_park_session ( switch_core_session_t session)

Definition at line 3411 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(), switch_ivr_multi_threaded_bridge(), and uuid_bridge_on_soft_execute().

3412 {
3416 
3417 }
#define switch_channel_set_state(channel, state)
Set the current state of a channel.
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
#define switch_channel_set_flag(_c, _f)
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 arg_recursion_check_start, arg_recursion_check_stop, switch_say_args_t::gender, memset(), switch_say_args_t::method, switch_xml::next, 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_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.

41 {
42  switch_event_t *hint_data;
43  switch_xml_t cfg, xml = NULL, language = NULL, macros = NULL, phrases = NULL, macro, input, action;
45  const char *old_sound_prefix = NULL, *sound_path = NULL, *tts_engine = NULL, *tts_voice = NULL;
46  const char *module_name = NULL, *chan_lang = NULL;
48  uint8_t done = 0, searched = 0;
49  int matches = 0;
50  const char *pause_val;
51  int pause = 100;
52  const char *group_macro_name = NULL;
53  const char *local_macro_name = macro_name;
54  switch_bool_t sound_prefix_enforced = switch_true(switch_channel_get_variable(channel, "sound_prefix_enforced"));
55  switch_bool_t local_sound_prefix_enforced = SWITCH_FALSE;
56 
57 
58  if (!macro_name) {
59  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No phrase macro specified.\n");
60  return status;
61  }
62 
64 
65  if (!lang) {
66  chan_lang = switch_channel_get_variable(channel, "default_language");
67  if (!chan_lang) {
68  chan_lang = "en";
69  }
70  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "No language specified - Using [%s]\n", chan_lang);
71  } else {
72  chan_lang = lang;
73  }
74 
76  switch_assert(hint_data);
77 
78  switch_event_add_header_string(hint_data, SWITCH_STACK_BOTTOM, "macro_name", macro_name);
79  switch_event_add_header_string(hint_data, SWITCH_STACK_BOTTOM, "lang", chan_lang);
80  if (data) {
81  switch_event_add_header_string(hint_data, SWITCH_STACK_BOTTOM, "data", data);
82  if (event) {
84  }
85  } else {
86  data = "";
87  }
88  switch_channel_event_set_data(channel, hint_data);
89 
90  if (switch_xml_locate_language(&xml, &cfg, hint_data, &language, &phrases, &macros, chan_lang) != SWITCH_STATUS_SUCCESS) {
91  goto done;
92  }
93 
94  if ((module_name = switch_xml_attr(language, "say-module"))) {
95  } else if ((module_name = switch_xml_attr(language, "module"))) {
96  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Deprecated usage of module attribute. Use say-module instead\n");
97  } else {
98  module_name = chan_lang;
99  }
100 
101  if (!(sound_path = (char *) switch_xml_attr(language, "sound-prefix"))) {
102  if (!(sound_path = (char *) switch_xml_attr(language, "sound-path"))) {
103  sound_path = (char *) switch_xml_attr(language, "sound_path");
104  }
105  }
106 
107  if (!(tts_engine = (char *) switch_xml_attr(language, "tts-engine"))) {
108  tts_engine = (char *) switch_xml_attr(language, "tts_engine");
109  }
110 
111  if (!(tts_voice = (char *) switch_xml_attr(language, "tts-voice"))) {
112  tts_voice = (char *) switch_xml_attr(language, "tts_voice");
113  }
114 
115  /* If we use the new structure, check for a group name */
116  if (language != macros) {
117  char *p;
118  char *macro_name_dup = switch_core_session_strdup(session, macro_name);
119  const char *group_sound_path;
120  const char *sound_prefix_enforced_str;
121 
122  if ((p = strchr(macro_name_dup, '@'))) {
123  *p++ = '\0';
124  local_macro_name = macro_name_dup;
125  group_macro_name = p;
126 
127  if (!(macros = switch_xml_find_child(phrases, "macros", "name", group_macro_name))) {
128  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find macros group %s.\n", group_macro_name);
129  goto done;
130  }
131  }
132  /* Support override of certain language attribute */
133  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"))) {
134  sound_path = group_sound_path;
135  }
136 
137  if (sound_prefix_enforced == SWITCH_FALSE && (sound_prefix_enforced_str = switch_xml_attr(macros, "sound-prefix-enforced"))
138  && (local_sound_prefix_enforced = switch_true(sound_prefix_enforced_str)) == SWITCH_TRUE) {
139  switch_channel_set_variable(channel, "sound_prefix_enforced", sound_prefix_enforced_str);
140  }
141 
142  }
143 
144  if (!(macro = switch_xml_find_child(macros, "macro", "name", local_macro_name))) {
145  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find macro %s.\n", macro_name);
146  goto done;
147  }
148 
149  if (sound_path && sound_prefix_enforced == SWITCH_FALSE) {
150  char *p;
151  old_sound_prefix = switch_str_nil(switch_channel_get_variable(channel, "sound_prefix"));
152  p = switch_core_session_strdup(session, old_sound_prefix);
153  old_sound_prefix = p;
154  switch_channel_set_variable(channel, "sound_prefix", sound_path);
155  }
156 
157  if ((pause_val = switch_xml_attr(macro, "pause"))) {
158  int tmp = atoi(pause_val);
159  if (tmp >= 0) {
160  pause = tmp;
161  }
162  }
163 
164  if (!(input = switch_xml_child(macro, "input"))) {
165  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't find any input tags.\n");
166  goto done;
167  }
168 
170  status = SWITCH_STATUS_FALSE;
171  goto done;
172  }
173 
174  while (input) {
175  char *field = (char *) switch_xml_attr(input, "field");
176  char *pattern = (char *) switch_xml_attr(input, "pattern");
177  const char *do_break = switch_xml_attr_soft(input, "break_on_match");
178  char *field_expanded = NULL;
179  char *field_expanded_alloc = NULL;
180  switch_regex_t *re = NULL;
181  int proceed = 0, ovector[100];
182  switch_xml_t match = NULL;
183 
184  searched = 1;
185  if (!field) {
186  field = (char *) data;
187  }
188  if (event) {
189  field_expanded_alloc = switch_event_expand_headers(event, field);
190  } else {
191  field_expanded_alloc = switch_channel_expand_variables(channel, field);
192  }
193 
194  if (field_expanded_alloc == field) {
195  field_expanded_alloc = NULL;
196  field_expanded = field;
197  } else {
198  field_expanded = field_expanded_alloc;
199  }
200 
201  if (!pattern) {
202  pattern = ".*";
203  }
204 
205  status = SWITCH_STATUS_SUCCESS;
206 
207  if ((proceed = switch_regex_perform(field_expanded, pattern, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
208  match = switch_xml_child(input, "match");
209  } else {
210  match = switch_xml_child(input, "nomatch");
211  }
212 
213  if (match) {
214  matches++;
215  for (action = switch_xml_child(match, "action"); action; action = action->next) {
216  char *adata = (char *) switch_xml_attr_soft(action, "data");
217  char *func = (char *) switch_xml_attr_soft(action, "function");
218  char *substituted = NULL;
219  uint32_t len = 0;
220  char *odata = NULL;
221  char *expanded = NULL;
222 
223  if (strchr(pattern, '(') && strchr(adata, '$') && proceed > 0) {
224  len = (uint32_t) (strlen(data) + strlen(adata) + 10) * proceed;
225  if (!(substituted = malloc(len))) {
226  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Memory Error!\n");
228  switch_safe_free(field_expanded_alloc);
229  goto done;
230  }
231  memset(substituted, 0, len);
232  switch_perform_substitution(re, proceed, adata, field_expanded, substituted, len, ovector);
233  odata = substituted;
234  } else {
235  odata = adata;
236  }
237 
238  if (event) {
239  expanded = switch_event_expand_headers(event, odata);
240  } else {
241  expanded = switch_channel_expand_variables(channel, odata);
242  }
243 
244  if (expanded == odata) {
245  expanded = NULL;
246  } else {
247  odata = expanded;
248  }
249 
250  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Handle %s:[%s] (%s:%s)\n", func, odata, chan_lang,
251  module_name);
252 
253  if (!strcasecmp(func, "play-file")) {
254  status = switch_ivr_play_file(session, NULL, odata, args);
255  } else if (!strcasecmp(func, "phrase")) {
256  char *name = (char *) switch_xml_attr_soft(action, "phrase");
257  status = switch_ivr_phrase_macro(session, name, odata, chan_lang, args);
258  } else if (!strcasecmp(func, "break")) {
259  done = 1; /* don't break or we leak memory */
260  } else if (!strcasecmp(func, "execute")) {
262  char *cmd, *cmd_args;
263  status = SWITCH_STATUS_FALSE;
264 
265  cmd = switch_core_session_strdup(session, odata);
266  cmd_args = switch_separate_paren_args(cmd);
267 
268  if (!cmd_args) {
269  cmd_args = "";
270  }
271 
272  if ((app = switch_loadable_module_get_application_interface(cmd)) != NULL) {
273  status = switch_core_session_exec(session, app, cmd_args);
274  UNPROTECT_INTERFACE(app);
275  } else {
276  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid Application %s\n", cmd);
277  }
278  } else if (!strcasecmp(func, "say")) {
280  if ((si = switch_loadable_module_get_say_interface(module_name))) {
281  char *say_type = (char *) switch_xml_attr_soft(action, "type");
282  char *say_method = (char *) switch_xml_attr_soft(action, "method");
283  char *say_gender = (char *) switch_xml_attr_soft(action, "gender");
284  switch_say_args_t say_args = {0};
285 
286  say_args.type = switch_ivr_get_say_type_by_name(say_type);
287  say_args.method = switch_ivr_get_say_method_by_name(say_method);
288  say_args.gender = switch_ivr_get_say_gender_by_name(say_gender);
289 
290  status = si->say_function(session, odata, &say_args, args);
291  } else {
292  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid SAY Interface [%s]!\n", module_name);
293  }
294  } else if (!strcasecmp(func, "speak-text")) {
295  const char *my_tts_engine = switch_xml_attr(action, "tts-engine");
296  const char *my_tts_voice = switch_xml_attr(action, "tts-voice");
297 
298  if (!my_tts_engine) {
299  my_tts_engine = tts_engine;
300  }
301 
302  if (!my_tts_voice) {
303  my_tts_voice = tts_voice;
304  }
305  if (zstr(tts_engine) || zstr(tts_voice)) {
306  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "TTS is not configured\n");
307  } else {
308  status = switch_ivr_speak_text(session, my_tts_engine, my_tts_voice, odata, args);
309  }
310  }
311 
312  switch_ivr_sleep(session, pause, SWITCH_FALSE, NULL);
313  switch_safe_free(expanded);
314  switch_safe_free(substituted);
315  if (done || status != SWITCH_STATUS_SUCCESS) break;
316  }
317  }
318 
320  switch_safe_free(field_expanded_alloc);
321 
322  if (done || status != SWITCH_STATUS_SUCCESS
323  || (match && do_break && switch_true(do_break))) {
324  break;
325  }
326 
327  input = input->next;
328  }
329 
330  done:
331 
333 
334  if (hint_data) {
335  switch_event_destroy(&hint_data);
336  }
337 
338  if (searched && !matches) {
339  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Macro [%s]: '%s' did not match any patterns\n", macro_name, data);
340  }
341 
342  if (old_sound_prefix) {
343  switch_channel_set_variable(channel, "sound_prefix", old_sound_prefix);
344  }
345  if (local_sound_prefix_enforced == SWITCH_TRUE) {
346  switch_channel_set_variable(channel, "sound_prefix_enforced", NULL);
347  }
348 
349  if (xml) {
350  switch_xml_free(xml);
351  }
352 
353  return status;
354 }
#define switch_regex_safe_free(re)
Definition: switch_regex.h:79
void switch_xml_free(_In_opt_ switch_xml_t xml)
frees the memory allocated for an switch_xml structure
A module interface to implement an application.
const char * switch_xml_attr_soft(_In_ switch_xml_t xml, _In_z_ const char *attr)
returns the value of the requested tag attribute, or "" if not found
#define SWITCH_CHANNEL_SESSION_LOG(x)
switch_say_type_t switch_ivr_get_say_type_by_name(const char *name)
#define switch_event_expand_headers(_event, _in)
Definition: switch_event.h:354
switch_say_type_t type
switch_xml_t switch_xml_find_child(_In_ switch_xml_t node, _In_z_ const char *childname, _In_opt_z_ const char *attrname, _In_opt_z_ const char *value)
find a child tag in a node called 'childname' with an attribute 'attrname' which equals 'value' ...
switch_say_callback_t say_function
const char * switch_xml_attr(_In_opt_ switch_xml_t xml, _In_opt_z_ const char *attr)
returns the value of the requested tag attribute, or NULL if not found
void switch_perform_substitution(switch_regex_t *re, int match_count, const char *data, const char *field_data, char *substituted, switch_size_t len, int *ovector)
Definition: switch_regex.c:131
switch_status_t switch_ivr_sleep(switch_core_session_t *session, uint32_t ms, switch_bool_t sync, switch_input_args_t *args)
Wait for time to pass for a specified number of milliseconds.
Definition: switch_ivr.c:127
void switch_channel_event_set_data(_In_ switch_channel_t *channel, _In_ switch_event_t *event)
Add information about a given channel to an event object.
switch_status_t switch_xml_locate_language(switch_xml_t *root, switch_xml_t *node, switch_event_t *params, switch_xml_t *language, switch_xml_t *phrases, switch_xml_t *macros, const char *str_language)
Definition: switch_xml.c:3147
switch_bool_t
Definition: switch_types.h:405
switch_say_gender_t switch_ivr_get_say_gender_by_name(const char *name)
switch_say_method_t method
Representation of an event.
Definition: switch_event.h:80
#define arg_recursion_check_stop(_args)
switch_status_t switch_core_session_exec(_In_ switch_core_session_t *session, _In_ const switch_application_interface_t *application_interface, _In_opt_z_ const char *arg)
Execute an application on a session.
switch_status_t switch_ivr_play_file(switch_core_session_t *session, switch_file_handle_t *fh, const char *file, switch_input_args_t *args)
play a file from the disk to the session
A representation of an XML tree.
Definition: switch_xml.h:76
switch_status_t switch_ivr_speak_text(switch_core_session_t *session, const char *tts_name, const char *voice_name, char *text, switch_input_args_t *args)
Speak given text with given tts engine.
struct real_pcre switch_regex_t
Definition: switch_regex.h:43
static int switch_true(const char *expr)
Evaluate the truthfullness of a string expression.
Definition: switch_utils.h:450
#define zstr(x)
Definition: switch_utils.h:281
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
#define UNPROTECT_INTERFACE(_it)
switch_xml_t next
Definition: switch_xml.h:88
switch_application_interface_t * switch_loadable_module_get_application_interface(const char *name)
Retrieve the application interface by it's registered name.
Abstract interface to a say module.
#define switch_channel_get_variable(_c, _v)
switch_status_t switch_event_add_header_string(switch_event_t *event, switch_stack_t stack, const char *header_name, const char *data)
Add a string header to an event.
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:789
#define arg_recursion_check_start(_args)
int switch_regex_perform(const char *field, const char *expression, switch_regex_t **new_re, int *ovector, uint32_t olen)
Definition: switch_regex.c:55
switch_say_gender_t gender
#define switch_str_nil(s)
Make a null string a blank string instead.
Definition: switch_utils.h:903
char * switch_separate_paren_args(char *str)
#define switch_channel_expand_variables(_channel, _in)
switch_status_t
Common return values.
switch_say_interface_t * switch_loadable_module_get_say_interface(const char *name)
Retrieve the say interface by it's registered name.
#define switch_event_create(event, id)
Create a new event assuming it will not be custom event and therefore hiding the unused parameters...
Definition: switch_event.h:383
switch_xml_t switch_xml_child(_In_ switch_xml_t xml, _In_z_ const char *name)
returns the first child tag (one level deeper) with the given name or NULL \ if not found ...
switch_say_method_t switch_ivr_get_say_method_by_name(const char *name)
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
#define switch_ivr_phrase_macro(session, macro_name, data, lang, args)
Definition: switch_ivr.h:903
#define switch_core_session_strdup(_session, _todup)
Copy a string using memory allocation from a session's pool.
Definition: switch_core.h:717
void switch_event_destroy(switch_event_t **event)
Destroy an event.
#define switch_assert(expr)
#define switch_channel_set_variable(_channel, _var, _val)
#define switch_channel_pre_answer(channel)
Indicate progress on a channel to attempt early media.
memset(buf, 0, buflen)
switch_status_t switch_ivr_process_fh ( switch_core_session_t session,
const char *  cmd,
switch_file_handle_t fhp 
)

Definition at line 3888 of file switch_ivr.c.

References if(), SCFC_PAUSE_READ, switch_atoui(), SWITCH_CHANNEL_SESSION_LOG, switch_clear_flag_locked, switch_core_file_command(), switch_core_file_seek(), switch_core_file_truncate(), SWITCH_FILE_DONE, SWITCH_FILE_OPEN, SWITCH_FILE_PAUSE, SWITCH_LOG_DEBUG, switch_log_printf(), switch_normalize_volume, switch_set_flag_locked, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_test_flag, and zstr.

Referenced by CoreSession::process_callback_result().

3889 {
3890  if (zstr(cmd)) {
3891  return SWITCH_STATUS_SUCCESS;
3892  }
3893 
3894  if (fhp) {
3895  if (!switch_test_flag(fhp, SWITCH_FILE_OPEN)) {
3896  return SWITCH_STATUS_FALSE;
3897  }
3898 
3899  if (!strncasecmp(cmd, "speed", 5)) {
3900  char *p;
3901 
3902  if ((p = strchr(cmd, ':'))) {
3903  p++;
3904  if (*p == '+' || *p == '-') {
3905  int step;
3906  if (!(step = atoi(p))) {
3907  step = 1;
3908  }
3909  fhp->speed += step;
3910  } else {
3911  int speed = atoi(p);
3912  fhp->speed = speed;
3913  }
3914  return SWITCH_STATUS_SUCCESS;
3915  }
3916 
3917  return SWITCH_STATUS_FALSE;
3918 
3919  } else if (!strncasecmp(cmd, "volume", 6)) {
3920  char *p;
3921 
3922  if ((p = strchr(cmd, ':'))) {
3923  p++;
3924  if (*p == '+' || *p == '-') {
3925  int step;
3926  if (!(step = atoi(p))) {
3927  step = 1;
3928  }
3929  fhp->vol += step;
3930  } else {
3931  int vol = atoi(p);
3932  fhp->vol = vol;
3933  }
3934  return SWITCH_STATUS_SUCCESS;
3935  }
3936 
3937  if (fhp->vol) {
3939  }
3940 
3941  return SWITCH_STATUS_FALSE;
3942  } else if (!strcasecmp(cmd, "pause")) {
3943  if (switch_test_flag(fhp, SWITCH_FILE_PAUSE)) {
3945  } else {
3947  }
3948 
3950 
3951  return SWITCH_STATUS_SUCCESS;
3952  } else if (!strcasecmp(cmd, "stop")) {
3954  return SWITCH_STATUS_FALSE;
3955  } else if (!strcasecmp(cmd, "truncate")) {
3956  switch_core_file_truncate(fhp, 0);
3957  } else if (!strcasecmp(cmd, "restart")) {
3958  unsigned int pos = 0;
3959  fhp->speed = 0;
3960  switch_core_file_seek(fhp, &pos, 0, SEEK_SET);
3961  return SWITCH_STATUS_SUCCESS;
3962  } else if (!strncasecmp(cmd, "seek", 4)) {
3963  //switch_codec_t *codec;
3964  unsigned int samps = 0;
3965  unsigned int pos = 0;
3966  char *p;
3967  //codec = switch_core_session_get_read_codec(session);
3968 
3969  if ((p = strchr(cmd, ':'))) {
3970  p++;
3971  if (*p == '+' || *p == '-') {
3972  int step;
3973  int32_t target;
3974  if (!(step = atoi(p))) {
3975  step = 1000;
3976  }
3977 
3978  samps = step * (fhp->native_rate / 1000);
3979  target = (int32_t)fhp->offset_pos + samps;
3980 
3981  if (target < 0) {
3982  target = 0;
3983  }
3984 
3985  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "seek to position %d\n", target);
3986  switch_core_file_seek(fhp, &pos, target, SEEK_SET);
3987 
3988  } else {
3989  samps = switch_atoui(p) * (fhp->native_rate / 1000);
3990  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "seek to position %d\n", samps);
3991  switch_core_file_seek(fhp, &pos, samps, SEEK_SET);
3992  }
3993  }
3994 
3995  return SWITCH_STATUS_SUCCESS;
3996  }
3997  }
3998 
3999  if (!strcmp(cmd, "true") || !strcmp(cmd, "undefined")) {
4000  return SWITCH_STATUS_SUCCESS;
4001  }
4002 
4003  return SWITCH_STATUS_FALSE;
4004 
4005 }
unsigned int switch_atoui(const char *nptr)
#define SWITCH_CHANNEL_SESSION_LOG(x)
switch_status_t switch_core_file_command(switch_file_handle_t *fh, switch_file_command_t command)
switch_status_t switch_core_file_seek(_In_ switch_file_handle_t *fh, unsigned int *cur_pos, int64_t samples, int whence)
Seek a position in a file.
#define zstr(x)
Definition: switch_utils.h:281
if((uint32_t)(unpack->cur-unpack->buf) > unpack->buflen)
#define switch_normalize_volume(x)
#define switch_set_flag_locked(obj, flag)
Set a flag on an arbitrary object while locked.
Definition: switch_utils.h:638
#define switch_clear_flag_locked(obj, flag)
Clear a flag on an arbitrary object.
Definition: switch_utils.h:648
switch_status_t switch_core_file_truncate(switch_file_handle_t *fh, int64_t offset)
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:624
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
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 2114 of file switch_ivr_play_say.c.

References switch_input_args_t::buf, switch_input_args_t::buflen, memset(), 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().

2125 {
2126  switch_channel_t *channel;
2127  switch_input_args_t args = { 0 };
2129  size_t len = 0;
2130  char tb[2] = "";
2131  int term_required = 0;
2132 
2133 
2134  if (valid_terminators && *valid_terminators == '=') {
2135  term_required = 1;
2136  }
2137 
2138  switch_assert(session);
2139 
2140  if (!digit_timeout) {
2141  digit_timeout = timeout;
2142  }
2143 
2144  if (max_digits < min_digits) {
2146  "Max digits %u is less than Min %u, forcing Max to %u\n", max_digits, min_digits, min_digits);
2147  max_digits = min_digits;
2148  }
2149 
2150  channel = switch_core_session_get_channel(session);
2152 
2153  if (var_name) {
2154  switch_channel_set_variable(channel, var_name, NULL);
2155  }
2156 
2157  if ((min_digits && digit_buffer_length < min_digits) || digit_buffer_length < max_digits) {
2158  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Buffer too small!\n");
2159  return SWITCH_STATUS_FALSE;
2160  }
2161 
2163  return SWITCH_STATUS_FALSE;
2164  }
2165 
2166  memset(digit_buffer, 0, digit_buffer_length);
2167  args.buf = digit_buffer;
2168  args.buflen = (uint32_t) digit_buffer_length;
2169 
2170  if (!zstr(prompt_audio_file) && strcasecmp(prompt_audio_file, "silence")) {
2171  if ((status = switch_ivr_play_file(session, NULL, prompt_audio_file, &args)) == SWITCH_STATUS_BREAK) {
2172  status = SWITCH_STATUS_SUCCESS;
2173  }
2174  }
2175 
2176  if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) {
2177  goto end;
2178  }
2179 
2180  len = strlen(digit_buffer);
2181 
2182  if ((min_digits && len < min_digits) || len < max_digits) {
2183  args.buf = digit_buffer + len;
2184  args.buflen = (uint32_t) (digit_buffer_length - len);
2185  status = switch_ivr_collect_digits_count(session, digit_buffer, digit_buffer_length, max_digits, valid_terminators, &tb[0],
2186  len ? digit_timeout : timeout, digit_timeout, 0);
2187  }
2188 
2189 
2190  if (tb[0]) {
2191  char *p;
2192 
2194 
2195  if (!zstr(valid_terminators) && (p = strchr(valid_terminators, tb[0]))) {
2196  if (p >= (valid_terminators + 1) && (*(p - 1) == '+' || *(p - 1) == 'x')) {
2197  switch_snprintf(digit_buffer + strlen(digit_buffer), digit_buffer_length - strlen(digit_buffer), "%s", tb);
2198  if (*(p - 1) == 'x') {
2199  status = SWITCH_STATUS_RESTART;
2200  }
2201  }
2202  }
2203  } else if (term_required) {
2204  status = SWITCH_STATUS_TOO_SMALL;
2205  }
2206 
2207  len = strlen(digit_buffer);
2208  if ((min_digits && len < min_digits)) {
2209  status = SWITCH_STATUS_TOO_SMALL;
2210  }
2211 
2212  switch (status) {
2213  case SWITCH_STATUS_SUCCESS:
2215  break;
2216  case SWITCH_STATUS_TIMEOUT:
2218  break;
2219  default:
2221  break;
2222 
2223  }
2224 
2225  end:
2226 
2227  if (status != SWITCH_STATUS_RESTART && max_digits == 1 && len == 1 && valid_terminators && strchr(valid_terminators, *digit_buffer)) {
2228  *digit_buffer = '\0';
2229  }
2230 
2231  if (var_name && !zstr(digit_buffer)) {
2232  switch_channel_set_variable(channel, var_name, digit_buffer);
2233  }
2234 
2235  return status;
2236 
2237 }
#define SWITCH_CHANNEL_SESSION_LOG(x)
switch_status_t switch_ivr_play_file(switch_core_session_t *session, switch_file_handle_t *fh, const char *file, switch_input_args_t *args)
play a file from the disk to the session
int switch_snprintf(_Out_z_cap_(len) char *buf, _In_ switch_size_t len, _In_z_ _Printf_format_string_ const char *format,...)
#define zstr(x)
Definition: switch_utils.h:281
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
switch_status_t switch_ivr_collect_digits_count(switch_core_session_t *session, char *buf, switch_size_t buflen, switch_size_t maxdigits, const char *terminators, char *terminator, uint32_t first_timeout, uint32_t digit_timeout, uint32_t abs_timeout)
Wait for specified number of DTMF digits, untile terminator is received or until the channel hangs up...
Definition: switch_ivr.c:1287
#define SWITCH_READ_RESULT_VARIABLE
Definition: switch_types.h:136
#define SWITCH_READ_TERMINATOR_USED_VARIABLE
Definition: switch_types.h:128
switch_status_t
Common return values.
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
#define switch_assert(expr)
#define switch_channel_set_variable(_channel, _var, _val)
#define switch_channel_pre_answer(channel)
Indicate progress on a channel to attempt early media.
memset(buf, 0, buflen)
switch_status_t switch_ivr_record_session_mask ( switch_core_session_t session,
const char *  file,
switch_bool_t  on 
)

Definition at line 1528 of file switch_ivr_async.c.

References SMBF_MASK, switch_channel_get_private(), switch_core_media_bug_clear_flag(), switch_core_media_bug_set_flag(), switch_core_session_get_channel(), SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.

1529 {
1532 
1533  if ((bug = switch_channel_get_private(channel, file))) {
1534  if (on) {
1536  } else {
1538  }
1539  return SWITCH_STATUS_SUCCESS;
1540  }
1541  return SWITCH_STATUS_FALSE;
1542 }
uint32_t switch_core_media_bug_set_flag(_In_ switch_media_bug_t *bug, _In_ uint32_t flag)
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
uint32_t switch_core_media_bug_clear_flag(_In_ switch_media_bug_t *bug, _In_ uint32_t flag)
void * switch_channel_get_private(switch_channel_t *channel, const char *key)
Retrieve private from a given channel.
switch_media_bug_t * bug
switch_status_t switch_ivr_release_file_handle ( switch_core_session_t session,
switch_file_handle_t **  fh 
)

Definition at line 1141 of file switch_ivr_play_say.c.

References switch_core_session_io_rwunlock(), and SWITCH_STATUS_SUCCESS.

1142 {
1143  *fh = NULL;
1145 
1146  return SWITCH_STATUS_SUCCESS;
1147 }
switch_status_t switch_core_session_io_rwunlock(switch_core_session_t *session)
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 3507 of file switch_ivr.c.

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

3514 {
3516  switch_channel_t *channel;
3518  const char *save_path = NULL, *chan_lang = NULL, *lang = NULL, *sound_path = NULL;
3519  switch_event_t *hint_data;
3520  switch_xml_t cfg, xml = NULL, language = NULL, macros = NULL, phrases = NULL;
3521  char *p;
3522 
3523  switch_assert(session);
3524  channel = switch_core_session_get_channel(session);
3525  switch_assert(channel);
3526 
3528 
3529 
3530  if (zstr(module_name)) {
3531  module_name = "en";
3532  }
3533 
3534  if (module_name) {
3535  char *p;
3536  p = switch_core_session_strdup(session, module_name);
3537  module_name = p;
3538 
3539  if ((p = strchr(module_name, ':'))) {
3540  *p++ = '\0';
3541  chan_lang = p;
3542  }
3543  }
3544 
3545  if (!chan_lang) {
3546  lang = switch_channel_get_variable(channel, "language");
3547 
3548  if (!lang) {
3549  chan_lang = switch_channel_get_variable(channel, "default_language");
3550  if (!chan_lang) {
3551  chan_lang = module_name;
3552  }
3553  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "No language specified - Using [%s]\n", chan_lang);
3554  } else {
3555  chan_lang = lang;
3556  }
3557  }
3558 
3560  switch_assert(hint_data);
3561 
3562  switch_event_add_header_string(hint_data, SWITCH_STACK_BOTTOM, "macro_name", "say_app");
3563  switch_event_add_header_string(hint_data, SWITCH_STACK_BOTTOM, "lang", chan_lang);
3564  switch_channel_event_set_data(channel, hint_data);
3565 
3566  if (switch_xml_locate_language(&xml, &cfg, hint_data, &language, &phrases, &macros, chan_lang) != SWITCH_STATUS_SUCCESS) {
3567  goto done;
3568  }
3569 
3570  if ((p = (char *) switch_xml_attr(language, "say-module"))) {
3571  module_name = switch_core_session_strdup(session, p);
3572  } else if ((p = (char *) switch_xml_attr(language, "module"))) {
3573  module_name = switch_core_session_strdup(session, p);
3574  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Deprecated usage of module attribute\n");
3575  } else {
3576  module_name = chan_lang;
3577  }
3578 
3579  if (!(sound_path = (char *) switch_xml_attr(language, "sound-prefix"))) {
3580  if (!(sound_path = (char *) switch_xml_attr(language, "sound-path"))) {
3581  sound_path = (char *) switch_xml_attr(language, "sound_path");
3582  }
3583  }
3584 
3585  if (channel) {
3586  const char *p = switch_channel_get_variable(channel, "sound_prefix_enforced");
3587  if (!switch_true(p)) {
3588  save_path = switch_channel_get_variable(channel, "sound_prefix");
3589  if (sound_path) {
3590  switch_channel_set_variable(channel, "sound_prefix", sound_path);
3591  }
3592  }
3593  }
3594 
3595  if ((si = switch_loadable_module_get_say_interface(module_name))) {
3596  /* should go back and proto all the say mods to const.... */
3597  switch_say_args_t say_args = {0};
3598 
3599  say_args.type = switch_ivr_get_say_type_by_name(say_type);
3600  say_args.method = switch_ivr_get_say_method_by_name(say_method);
3601  say_args.gender = switch_ivr_get_say_gender_by_name(say_gender);
3602 
3603  status = si->say_function(session, (char *) tosay, &say_args, args);
3604  } else {
3605  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid SAY Interface [%s]!\n", module_name);
3606  status = SWITCH_STATUS_FALSE;
3607  }
3608 
3609  done:
3610 
3612 
3613 
3614  if (hint_data) {
3615  switch_event_destroy(&hint_data);
3616  }
3617 
3618  if (save_path) {
3619  switch_channel_set_variable(channel, "sound_prefix", save_path);
3620  }
3621 
3622  if (xml) {
3623  switch_xml_free(xml);
3624  }
3625 
3626  return status;
3627 }
void switch_xml_free(_In_opt_ switch_xml_t xml)
frees the memory allocated for an switch_xml structure
#define SWITCH_CHANNEL_SESSION_LOG(x)
switch_say_type_t switch_ivr_get_say_type_by_name(const char *name)
switch_say_type_t type
switch_say_callback_t say_function
const char * switch_xml_attr(_In_opt_ switch_xml_t xml, _In_opt_z_ const char *attr)
returns the value of the requested tag attribute, or NULL if not found
void switch_channel_event_set_data(_In_ switch_channel_t *channel, _In_ switch_event_t *event)
Add information about a given channel to an event object.
switch_status_t switch_xml_locate_language(switch_xml_t *root, switch_xml_t *node, switch_event_t *params, switch_xml_t *language, switch_xml_t *phrases, switch_xml_t *macros, const char *str_language)
Definition: switch_xml.c:3147
switch_say_gender_t switch_ivr_get_say_gender_by_name(const char *name)
switch_say_method_t method
Representation of an event.
Definition: switch_event.h:80
#define arg_recursion_check_stop(_args)
A representation of an XML tree.
Definition: switch_xml.h:76
static int switch_true(const char *expr)
Evaluate the truthfullness of a string expression.
Definition: switch_utils.h:450
#define zstr(x)
Definition: switch_utils.h:281
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
Abstract interface to a say module.
#define switch_channel_get_variable(_c, _v)
switch_status_t switch_event_add_header_string(switch_event_t *event, switch_stack_t stack, const char *header_name, const char *data)
Add a string header to an event.
#define arg_recursion_check_start(_args)
switch_say_gender_t gender
switch_status_t
Common return values.
switch_say_interface_t * switch_loadable_module_get_say_interface(const char *name)
Retrieve the say interface by it's registered name.
#define switch_event_create(event, id)
Create a new event assuming it will not be custom event and therefore hiding the unused parameters...
Definition: switch_event.h:383
switch_say_method_t switch_ivr_get_say_method_by_name(const char *name)
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
#define switch_core_session_strdup(_session, _todup)
Copy a string using memory allocation from a session's pool.
Definition: switch_core.h:717
void switch_event_destroy(switch_event_t **event)
Destroy an event.
#define switch_assert(expr)
#define switch_channel_set_variable(_channel, _var, _val)
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 172 of file switch_ivr_say.c.

References arg_recursion_check_start, arg_recursion_check_stop, say_file, say_num, switch_core_session_strdup, switch_goto_status, SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.

177 {
178  char *a, *b, *c, *d;
180 
182 
183  if (!(a = switch_core_session_strdup(session, tosay))) {
185  }
186 
187  if (!(b = strchr(a, '.'))) {
189  }
190 
191  *b++ = '\0';
192 
193  if (!(c = strchr(b, '.'))) {
195  }
196 
197  *c++ = '\0';
198 
199  if (!(d = strchr(c, '.'))) {
201  }
202 
203  *d++ = '\0';
204 
205  say_num(atoi(a), say_args->method);
206  say_file("digits/dot.wav");
207  say_num(atoi(b), say_args->method);
208  say_file("digits/dot.wav");
209  say_num(atoi(c), say_args->method);
210  say_file("digits/dot.wav");
211  say_num(atoi(d), say_args->method);
212 
213  end:
214 
216 
217  return status;
218 }
switch_say_method_t method
#define arg_recursion_check_stop(_args)
#define say_num(num, meth)
#define say_file(...)
#define arg_recursion_check_start(_args)
switch_status_t
Common return values.
#define switch_goto_status(_status, _label)
Definition: switch_utils.h:256
#define switch_core_session_strdup(_session, _todup)
Copy a string using memory allocation from a session's pool.
Definition: switch_core.h:717
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 arg_recursion_check_start, arg_recursion_check_stop, say_file, SST_NAME_PHONETIC, SST_NAME_SPELLED, and SWITCH_STATUS_SUCCESS.

134 {
135  char *p;
136 
138 
139  for (p = tosay; p && *p; p++) {
140  int a = tolower((int) *p);
141  if (a >= '0' && a <= '9') {
142  say_file("digits/%d.wav", a - '0');
143  } else {
144  if (say_args->type == SST_NAME_SPELLED) {
145  say_file("ascii/%d.wav", a);
146  } else if (say_args->type == SST_NAME_PHONETIC) {
147  say_file("phonetic-ascii/%d.wav", a);
148  }
149  }
150  }
151 
153 
154  return SWITCH_STATUS_SUCCESS;
155 }
switch_say_type_t type
#define arg_recursion_check_stop(_args)
#define say_file(...)
#define arg_recursion_check_start(_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 
)

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

3638 {
3640  switch_channel_t *channel = NULL;
3642  const char *save_path = NULL, *chan_lang = NULL, *sound_path = NULL;
3643  switch_event_t *hint_data;
3644  switch_xml_t cfg, xml = NULL, language = NULL, macros = NULL, phrases = NULL;
3645 
3646  if (session) {
3647  channel = switch_core_session_get_channel(session);
3648 
3649  if (!lang) {
3650  lang = switch_channel_get_variable(channel, "language");
3651 
3652  if (!lang) {
3653  chan_lang = switch_channel_get_variable(channel, "default_language");
3654  if (!chan_lang) {
3655  chan_lang = "en";
3656  }
3657  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "No language specified - Using [%s]\n", chan_lang);
3658  } else {
3659  chan_lang = lang;
3660  }
3661  }
3662  }
3663 
3664  if (!lang) lang = "en";
3665  if (!chan_lang) chan_lang = lang;
3666 
3668  switch_assert(hint_data);
3669 
3670  switch_event_add_header_string(hint_data, SWITCH_STACK_BOTTOM, "macro_name", "say_app");
3671  switch_event_add_header_string(hint_data, SWITCH_STACK_BOTTOM, "lang", chan_lang);
3672 
3673  if (channel) {
3674  switch_channel_event_set_data(channel, hint_data);
3675  }
3676 
3677  if (switch_xml_locate_language(&xml, &cfg, hint_data, &language, &phrases, &macros, chan_lang) != SWITCH_STATUS_SUCCESS) {
3678  goto done;
3679  }
3680 
3681  if ((module_name = switch_xml_attr(language, "say-module"))) {
3682  } else if ((module_name = switch_xml_attr(language, "module"))) {
3683  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Deprecated usage of module attribute\n");
3684  } else {
3685  module_name = chan_lang;
3686  }
3687 
3688  if (!(sound_path = (char *) switch_xml_attr(language, "sound-prefix"))) {
3689  if (!(sound_path = (char *) switch_xml_attr(language, "sound-path"))) {
3690  sound_path = (char *) switch_xml_attr(language, "sound_path");
3691  }
3692  }
3693 
3694  if (channel) {
3695  const char *p = switch_channel_get_variable(channel, "sound_prefix_enforced");
3696  if (!switch_true(p)) {
3697  save_path = switch_channel_get_variable(channel, "sound_prefix");
3698  if (sound_path) {
3699  switch_channel_set_variable(channel, "sound_prefix", sound_path);
3700  }
3701  }
3702  }
3703 
3704  if ((si = switch_loadable_module_get_say_interface(module_name)) && si->say_string_function) {
3705  /* should go back and proto all the say mods to const.... */
3706  switch_say_args_t say_args = {0};
3707 
3708  say_args.type = switch_ivr_get_say_type_by_name(say_type);
3709  say_args.method = switch_ivr_get_say_method_by_name(say_method);
3710  say_args.gender = switch_ivr_get_say_gender_by_name(say_gender);
3711  say_args.ext = ext;
3712  status = si->say_string_function(session, (char *) tosay, &say_args, rstr);
3713  } else {
3714  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid SAY Interface [%s]!\n", module_name);
3715  status = SWITCH_STATUS_FALSE;
3716  }
3717 
3718  done:
3719 
3720  if (hint_data) {
3721  switch_event_destroy(&hint_data);
3722  }
3723 
3724  if (save_path && channel) {
3725  switch_channel_set_variable(channel, "sound_prefix", save_path);
3726  }
3727 
3728  if (xml) {
3729  switch_xml_free(xml);
3730  }
3731 
3732  return status;
3733 }
void switch_xml_free(_In_opt_ switch_xml_t xml)
frees the memory allocated for an switch_xml structure
#define SWITCH_CHANNEL_SESSION_LOG(x)
switch_say_type_t switch_ivr_get_say_type_by_name(const char *name)
switch_say_type_t type
const char * switch_xml_attr(_In_opt_ switch_xml_t xml, _In_opt_z_ const char *attr)
returns the value of the requested tag attribute, or NULL if not found
void switch_channel_event_set_data(_In_ switch_channel_t *channel, _In_ switch_event_t *event)
Add information about a given channel to an event object.
switch_status_t switch_xml_locate_language(switch_xml_t *root, switch_xml_t *node, switch_event_t *params, switch_xml_t *language, switch_xml_t *phrases, switch_xml_t *macros, const char *str_language)
Definition: switch_xml.c:3147
switch_say_gender_t switch_ivr_get_say_gender_by_name(const char *name)
switch_say_method_t method
Representation of an event.
Definition: switch_event.h:80
switch_say_string_callback_t say_string_function
A representation of an XML tree.
Definition: switch_xml.h:76
static int switch_true(const char *expr)
Evaluate the truthfullness of a string expression.
Definition: switch_utils.h:450
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
Abstract interface to a say module.
#define switch_channel_get_variable(_c, _v)
switch_status_t switch_event_add_header_string(switch_event_t *event, switch_stack_t stack, const char *header_name, const char *data)
Add a string header to an event.
switch_say_gender_t gender
switch_status_t
Common return values.
switch_say_interface_t * switch_loadable_module_get_say_interface(const char *name)
Retrieve the say interface by it's registered name.
#define switch_event_create(event, id)
Create a new event assuming it will not be custom event and therefore hiding the unused parameters...
Definition: switch_event.h:383
switch_say_method_t switch_ivr_get_say_method_by_name(const char *name)
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
void switch_event_destroy(switch_event_t **event)
Destroy an event.
#define switch_assert(expr)
#define switch_channel_set_variable(_channel, _var, _val)
const char * ext
switch_status_t switch_ivr_set_user ( switch_core_session_t session,
const char *  data 
)

Definition at line 3816 of file switch_ivr.c.

References SWITCH_CHANNEL_SESSION_LOG, switch_core_session_strdup, switch_ivr_set_user_xml(), SWITCH_LOG_ERROR, switch_log_printf(), SWITCH_LOG_WARNING, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_xml_free(), switch_xml_locate_user_merged(), and zstr.

3817 {
3818  switch_xml_t x_user = 0;
3819  char *user, *domain;
3821 
3822  char *prefix;
3823 
3824  if (zstr(data)) {
3825  goto error;
3826  }
3827 
3828  user = switch_core_session_strdup(session, data);
3829 
3830  if ((prefix = strchr(user, ' '))) {
3831  *prefix++ = 0;
3832  }
3833 
3834  if (!(domain = strchr(user, '@'))) {
3835  goto error;
3836  }
3837 
3838  *domain++ = '\0';
3839 
3840 
3841  if (switch_xml_locate_user_merged("id", user, domain, NULL, &x_user, NULL) != SWITCH_STATUS_SUCCESS) {
3842  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "can't find user [%s@%s]\n", user, domain);
3843  goto done;
3844  }
3845 
3846  status = switch_ivr_set_user_xml(session, prefix, user, domain, x_user);
3847 
3848  goto done;
3849 
3850  error:
3851  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No user@domain specified.\n");
3852 
3853  done:
3854 
3855  if (x_user) {
3856  switch_xml_free(x_user);
3857  }
3858 
3859  return status;
3860 }
void switch_xml_free(_In_opt_ switch_xml_t xml)
frees the memory allocated for an switch_xml structure
#define SWITCH_CHANNEL_SESSION_LOG(x)
switch_status_t switch_xml_locate_user_merged(const char *key, const char *user_name, const char *domain_name, const char *ip, switch_xml_t *user, switch_event_t *params)
Definition: switch_xml.c:2034
A representation of an XML tree.
Definition: switch_xml.h:76
#define zstr(x)
Definition: switch_utils.h:281
switch_status_t
Common return values.
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
#define switch_core_session_strdup(_session, _todup)
Copy a string using memory allocation from a session's pool.
Definition: switch_core.h:717
switch_status_t switch_ivr_set_user_xml(switch_core_session_t *session, const char *prefix, const char *user, const char *domain, switch_xml_t x_user)
Definition: switch_ivr.c:3761
switch_status_t switch_ivr_set_user_xml ( switch_core_session_t session,
const char *  prefix,
const char *  user,
const char *  domain,
switch_xml_t  x_user 
)

Definition at line 3761 of file switch_ivr.c.

References get_prefixed_str(), switch_xml::next, switch_channel_get_caller_profile(), switch_channel_set_profile_var(), switch_channel_set_variable, switch_core_session_alloc, switch_core_session_get_channel(), SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_xml_attr(), switch_xml_child(), and zstr.

Referenced by switch_ivr_set_user().

3763 {
3764  switch_xml_t x_params, x_param;
3765  char *number_alias;
3768 
3769  char *prefix_buffer = NULL;
3770  size_t buffer_size = 0;
3771  size_t prefix_size = 0;
3772 
3773 
3774  status = SWITCH_STATUS_SUCCESS;
3775 
3776  if (!zstr(prefix)) {
3777  prefix_size = strlen(prefix);
3778  buffer_size = 1024 + prefix_size + 1;
3779  prefix_buffer = switch_core_session_alloc(session, buffer_size);
3780  }
3781 
3782  if ((number_alias = (char *) switch_xml_attr(x_user, "number-alias"))) {
3783  switch_channel_set_variable(channel, get_prefixed_str(prefix_buffer, buffer_size, prefix, prefix_size, "number_alias"), number_alias);
3784  }
3785 
3786  if ((x_params = switch_xml_child(x_user, "variables"))) {
3787  for (x_param = switch_xml_child(x_params, "variable"); x_param; x_param = x_param->next) {
3788  const char *var = switch_xml_attr(x_param, "name");
3789  const char *val = switch_xml_attr(x_param, "value");
3790 
3791  if (var && val) {