RTS API Documentation  1.10.11
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)
 
switch_status_t 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_extended (switch_core_session_t *session, const char *data, switch_event_t *params)
 
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, switch_byte_t is_priority, 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_record_session_pause (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)
 
switch_status_t switch_ivr_capture_text (switch_core_session_t *session, switch_bool_t on)
 
switch_status_t switch_dial_handle_create (switch_dial_handle_t **handle)
 
switch_status_t switch_dial_handle_create_json_obj (switch_dial_handle_t **handle, cJSON *json)
 
switch_status_t switch_dial_handle_create_json (switch_dial_handle_t **handle, const char *handle_string)
 
void switch_dial_handle_destroy (switch_dial_handle_t **handle)
 
switch_status_t switch_dial_handle_serialize_json_obj (switch_dial_handle_t *handle, cJSON **json)
 
switch_status_t switch_dial_handle_serialize_json (switch_dial_handle_t *handle, char **str)
 
void switch_dial_handle_add_leg_list (switch_dial_handle_t *handle, switch_dial_leg_list_t **leg_listP)
 
void switch_dial_leg_list_add_leg (switch_dial_leg_list_t *parent, switch_dial_leg_t **legP, const char *dial_string)
 
void switch_dial_leg_list_add_leg_printf (switch_dial_leg_list_t *parent, switch_dial_leg_t **legP, const char *fmt,...)
 
void switch_dial_handle_add_global_var (switch_dial_handle_t *handle, const char *var, const char *val)
 
void switch_dial_handle_add_global_var_printf (switch_dial_handle_t *handle, const char *var, const char *fmt,...)
 
switch_status_t switch_dial_handle_add_leg_var (switch_dial_leg_t *leg, const char *var, const char *val)
 
switch_status_t switch_dial_handle_add_leg_var_printf (switch_dial_leg_t *leg, const char *var, const char *fmt,...)
 
int switch_dial_handle_get_peers (switch_dial_handle_t *handle, int idx, char **array, int max)
 
int switch_dial_handle_get_vars (switch_dial_handle_t *handle, int idx, switch_event_t **array, int max)
 
switch_event_tswitch_dial_handle_get_global_vars (switch_dial_handle_t *handle)
 
switch_event_tswitch_dial_leg_get_vars (switch_dial_leg_t *leg)
 
const char * switch_dial_leg_get_var (switch_dial_leg_t *leg, const char *key)
 
int switch_dial_handle_get_total (switch_dial_handle_t *handle)
 
switch_status_t switch_dial_handle_list_serialize_json_obj (switch_dial_handle_list_t *hl, cJSON **json)
 
switch_status_t switch_dial_handle_list_serialize_json (switch_dial_handle_list_t *hl, char **str)
 
switch_status_t switch_dial_handle_list_create_json_obj (switch_dial_handle_list_t **handle, cJSON *json)
 
switch_status_t switch_dial_handle_list_create_json (switch_dial_handle_list_t **handle, const char *handle_string)
 
switch_status_t switch_dial_handle_list_create (switch_dial_handle_list_t **hl)
 
switch_status_t switch_dial_handle_list_create_handle (switch_dial_handle_list_t *hl, switch_dial_handle_t **handle)
 
void switch_dial_handle_list_destroy (switch_dial_handle_list_t **hl)
 
void switch_dial_handle_list_add_global_var (switch_dial_handle_list_t *hl, const char *var, const char *val)
 
void switch_dial_handle_list_add_global_var_printf (switch_dial_handle_list_t *hl, const char *var, const char *fmt,...)
 
switch_status_t switch_ivr_enterprise_orig_and_bridge (switch_core_session_t *session, const char *data, switch_dial_handle_list_t *hl, switch_call_cause_t *cause)
 
switch_status_t switch_ivr_orig_and_bridge (switch_core_session_t *session, const char *data, switch_dial_handle_t *dh, switch_call_cause_t *cause)
 
switch_status_t switch_ivr_send_prompt (switch_core_session_t *session, const char *type, const char *text, const char *regex)
 
switch_status_t switch_ivr_play_and_collect_input (switch_core_session_t *session, const char *prompt, const char *recognizer_mod_name, const char *recognizer_grammar, int min_digits, int max_digits, const char *terminators, uint32_t digit_timeout, cJSON **recognition_result, char **digits_collected, char *terminator_collected, switch_input_args_t *args)
 Play prompt and collect input. More...
 

Detailed Description

IVR menu functions

Macro Definition Documentation

◆ switch_ivr_phrase_macro

#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

◆ switch_ivr_menu_action_function_t

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

Definition at line 816 of file switch_ivr.h.

◆ switch_ivr_menu_action_t

Definition at line 818 of file switch_ivr.h.

◆ switch_ivr_menu_t

Definition at line 817 of file switch_ivr.h.

◆ switch_ivr_menu_xml_ctx_t

Definition at line 904 of file switch_ivr.h.

Enumeration Type Documentation

◆ switch_ivr_action_t

Enumerator
SWITCH_IVR_ACTION_DIE 
SWITCH_IVR_ACTION_EXECMENU 
SWITCH_IVR_ACTION_EXECAPP 
SWITCH_IVR_ACTION_PLAYSOUND 
SWITCH_IVR_ACTION_BACK 
SWITCH_IVR_ACTION_TOMAIN 
SWITCH_IVR_ACTION_NOOP 

Definition at line 806 of file switch_ivr.h.

806  {
807  SWITCH_IVR_ACTION_DIE, /* Exit the menu. */
808  SWITCH_IVR_ACTION_EXECMENU, /* Goto another menu in the stack. */
809  SWITCH_IVR_ACTION_EXECAPP, /* Execute an application. */
810  SWITCH_IVR_ACTION_PLAYSOUND, /* Play a sound. */
811  SWITCH_IVR_ACTION_BACK, /* Go back 1 menu. */
812  SWITCH_IVR_ACTION_TOMAIN, /* Go back to the top level menu. */
813  SWITCH_IVR_ACTION_NOOP /* No operation */
switch_ivr_action_t
Definition: switch_ivr.h:806

◆ switch_ivr_menu_flags

Enumerator
SWITCH_IVR_MENU_FLAG_FALLTOMAIN 
SWITCH_IVR_MENU_FLAG_FREEPOOL 
SWITCH_IVR_MENU_FLAG_STACK 

Definition at line 800 of file switch_ivr.h.

Function Documentation

◆ switch_dial_handle_add_global_var()

void switch_dial_handle_add_global_var ( switch_dial_handle_t handle,
const char *  var,
const char *  val 
)

Definition at line 4508 of file switch_ivr_originate.c.

References switch_dial_handle_s::global_vars, switch_assert, switch_event_add_header_string(), SWITCH_EVENT_CHANNEL_DATA, switch_event_create_plain(), and SWITCH_STACK_BOTTOM.

Referenced by switch_dial_handle_add_global_var_printf(), and switch_dial_handle_create_json_obj().

4509 {
4510  switch_assert(handle);
4511 
4512  if (!handle->global_vars) {
4514  }
4515 
4517 }
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.
static switch_status_t switch_event_create_plain(switch_event_t **event, switch_event_types_t event_id)
Definition: switch_event.h:386
switch_event_t * global_vars
#define switch_assert(expr)

◆ switch_dial_handle_add_global_var_printf()

void switch_dial_handle_add_global_var_printf ( switch_dial_handle_t handle,
const char *  var,
const char *  fmt,
  ... 
)

Definition at line 4519 of file switch_ivr_originate.c.

References switch_dial_handle_add_global_var(), and switch_vasprintf().

4520 {
4521  int ret = 0;
4522  char *data = NULL;
4523  va_list ap;
4524 
4525  va_start(ap, fmt);
4526  ret = switch_vasprintf(&data, fmt, ap);
4527  va_end(ap);
4528 
4529  if (ret == -1) {
4530  abort();
4531  }
4532 
4533  switch_dial_handle_add_global_var(handle, var, data);
4534  free(data);
4535 }
int cJSON_bool fmt
Definition: switch_cJSON.h:150
int switch_vasprintf(_Out_opt_ char **buf, _In_z_ _Printf_format_string_ const char *format, _In_ va_list ap)
void switch_dial_handle_add_global_var(switch_dial_handle_t *handle, const char *var, const char *val)

◆ switch_dial_handle_add_leg_list()

void switch_dial_handle_add_leg_list ( switch_dial_handle_t handle,
switch_dial_leg_list_t **  leg_listP 
)

Definition at line 4459 of file switch_ivr_originate.c.

References switch_dial_leg_list_s::handle, switch_dial_handle_s::leg_list_idx, switch_dial_handle_s::leg_lists, switch_dial_handle_s::pool, switch_assert, and switch_core_alloc.

Referenced by switch_dial_handle_create_json_obj(), and switch_dial_handle_dup().

4460 {
4461  switch_dial_leg_list_t *leg_list;
4462 
4463  switch_assert(handle);
4464 
4465  leg_list = switch_core_alloc(handle->pool, sizeof(*leg_list));
4466  leg_list->handle = handle;
4467 
4468  handle->leg_lists[handle->leg_list_idx++] = leg_list;
4469 
4470  *leg_listP = leg_list;
4471 }
switch_memory_pool_t * pool
struct switch_dial_handle_s * handle
#define switch_core_alloc(_pool, _mem)
Allocate memory directly from a memory pool.
Definition: switch_core.h:684
switch_dial_leg_list_t * leg_lists[MAX_PEERS]
#define switch_assert(expr)

◆ switch_dial_handle_add_leg_var()

switch_status_t switch_dial_handle_add_leg_var ( switch_dial_leg_t leg,
const char *  var,
const char *  val 
)

Definition at line 4537 of file switch_ivr_originate.c.

References switch_dial_leg_s::leg_vars, switch_event_add_header_string(), SWITCH_EVENT_CHANNEL_DATA, switch_event_create_plain(), SWITCH_STACK_BOTTOM, SWITCH_STATUS_NOTFOUND, and SWITCH_STATUS_SUCCESS.

Referenced by switch_dial_handle_add_leg_var_printf(), and switch_dial_handle_create_json_obj().

4538 {
4539  if (!leg) return SWITCH_STATUS_NOTFOUND;
4540 
4541  if (!leg->leg_vars) {
4543  }
4544 
4546 
4547  return SWITCH_STATUS_SUCCESS;
4548 
4549 }
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.
static switch_status_t switch_event_create_plain(switch_event_t **event, switch_event_types_t event_id)
Definition: switch_event.h:386
switch_event_t * leg_vars

◆ switch_dial_handle_add_leg_var_printf()

switch_status_t switch_dial_handle_add_leg_var_printf ( switch_dial_leg_t leg,
const char *  var,
const char *  fmt,
  ... 
)

Definition at line 4551 of file switch_ivr_originate.c.

References switch_dial_handle_add_leg_var(), and switch_vasprintf().

4552 {
4553  int ret = 0;
4554  char *data = NULL;
4555  va_list ap;
4556  switch_status_t status;
4557 
4558  va_start(ap, fmt);
4559  ret = switch_vasprintf(&data, fmt, ap);
4560  va_end(ap);
4561 
4562  if (ret == -1) {
4563  abort();
4564  }
4565 
4566  status = switch_dial_handle_add_leg_var(leg, var, data);
4567 
4568  free(data);
4569 
4570  return status;
4571 }
int cJSON_bool fmt
Definition: switch_cJSON.h:150
int switch_vasprintf(_Out_opt_ char **buf, _In_z_ _Printf_format_string_ const char *format, _In_ va_list ap)
switch_status_t
Common return values.
switch_status_t switch_dial_handle_add_leg_var(switch_dial_leg_t *leg, const char *var, const char *val)

◆ switch_dial_handle_create()

switch_status_t switch_dial_handle_create ( switch_dial_handle_t **  handle)

Definition at line 4418 of file switch_ivr_originate.c.

References pool, switch_dial_handle_s::pool, switch_assert, switch_core_alloc, switch_core_new_memory_pool, and SWITCH_STATUS_SUCCESS.

Referenced by switch_dial_handle_create_json_obj(), switch_dial_handle_dup(), and switch_dial_handle_list_create_handle().

4419 {
4421  switch_memory_pool_t *pool = NULL;
4422 
4424  switch_assert(pool);
4425 
4426  hp = switch_core_alloc(pool, sizeof(*hp));
4427  switch_assert(hp);
4428 
4429  hp->pool = pool;
4430 
4431  *handle = hp;
4432 
4433  return SWITCH_STATUS_SUCCESS;
4434 }
switch_memory_pool_t * pool
#define switch_core_new_memory_pool(p)
Create a new sub memory pool from the core&#39;s master pool.
Definition: switch_core.h:633
switch_memory_pool_t * pool
#define switch_core_alloc(_pool, _mem)
Allocate memory directly from a memory pool.
Definition: switch_core.h:684
struct fspr_pool_t switch_memory_pool_t
#define switch_assert(expr)

◆ switch_dial_handle_create_json()

switch_status_t switch_dial_handle_create_json ( switch_dial_handle_t **  handle,
const char *  handle_string 
)

Definition at line 4769 of file switch_ivr_originate.c.

References switch_dial_handle_create_json_obj(), SWITCH_STATUS_FALSE, and zstr.

4770 {
4771  switch_status_t status;
4772  cJSON *handle_json = NULL;
4773 
4774  if (zstr(handle_string)) {
4775  return SWITCH_STATUS_FALSE;
4776  }
4777 
4778  handle_json = cJSON_Parse(handle_string);
4779  if (!handle_json) {
4780  return SWITCH_STATUS_FALSE;
4781  }
4782 
4783  status = switch_dial_handle_create_json_obj(handle, handle_json);
4784  cJSON_Delete(handle_json);
4785  return status;
4786 }
#define zstr(x)
Definition: switch_utils.h:314
switch_status_t switch_dial_handle_create_json_obj(switch_dial_handle_t **handle, cJSON *json)
switch_status_t
Common return values.

◆ switch_dial_handle_create_json_obj()

switch_status_t switch_dial_handle_create_json_obj ( switch_dial_handle_t **  handle,
cJSON json 
)

Definition at line 4710 of file switch_ivr_originate.c.

References cJSON_Array, cJSON_ArrayForEach, cJSON_GetObjectCstr(), cJSON_Object, cJSON_String, cJSON::string, switch_dial_handle_add_global_var(), switch_dial_handle_add_leg_list(), switch_dial_handle_add_leg_var(), switch_dial_handle_create(), switch_dial_leg_list_add_leg(), SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, cJSON::type, and cJSON::valuestring.

Referenced by switch_dial_handle_create_json(), and switch_dial_handle_list_create_json_obj().

4711 {
4712  cJSON *vars_json = NULL;
4713  cJSON *var_json = NULL;
4714  cJSON *leg_lists_json = NULL;
4715  if (!json) {
4716  return SWITCH_STATUS_FALSE;
4717  }
4718  switch_dial_handle_create(handle);
4719 
4720  leg_lists_json = cJSON_GetObjectItem(json, "leg_lists");
4721  if (leg_lists_json && leg_lists_json->type == cJSON_Array) {
4722  cJSON *leg_list_json = NULL;
4723  cJSON_ArrayForEach(leg_list_json, leg_lists_json) {
4724  cJSON *legs_json = cJSON_GetObjectItem(leg_list_json, "legs");
4725  cJSON *leg_json = NULL;
4726  switch_dial_leg_list_t *ll = NULL;
4727  if (!legs_json || legs_json->type != cJSON_Array) {
4728  continue;
4729  }
4730  switch_dial_handle_add_leg_list(*handle, &ll);
4731  cJSON_ArrayForEach(leg_json, legs_json) {
4732  switch_dial_leg_t *leg = NULL;
4733  const char *dial_string = NULL;
4734  if (!leg_json || leg_json->type != cJSON_Object) {
4735  continue;
4736  }
4737  dial_string = cJSON_GetObjectCstr(leg_json, "dial_string");
4738  if (!dial_string) {
4739  continue;
4740  }
4741  switch_dial_leg_list_add_leg(ll, &leg, dial_string);
4742 
4743  vars_json = cJSON_GetObjectItem(leg_json, "vars");
4744  if (vars_json && vars_json->type == cJSON_Object) {
4745  cJSON_ArrayForEach(var_json, vars_json) {
4746  if (!var_json || var_json->type != cJSON_String || !var_json->valuestring || !var_json->string) {
4747  continue;
4748  }
4749  switch_dial_handle_add_leg_var(leg, var_json->string, var_json->valuestring);
4750  }
4751  }
4752  }
4753  }
4754  }
4755 
4756  vars_json = cJSON_GetObjectItem(json, "vars");
4757  if (vars_json && vars_json->type == cJSON_Object) {
4758  cJSON_ArrayForEach(var_json, vars_json) {
4759  if (!var_json || var_json->type != cJSON_String || !var_json->valuestring || !var_json->string) {
4760  continue;
4761  }
4762  switch_dial_handle_add_global_var(*handle, var_json->string, var_json->valuestring);
4763  }
4764  }
4765  return SWITCH_STATUS_SUCCESS;
4766 }
#define cJSON_Object
Definition: switch_cJSON.h:88
void switch_dial_handle_add_leg_list(switch_dial_handle_t *handle, switch_dial_leg_list_t **leg_listP)
char * valuestring
Definition: switch_cJSON.h:107
#define cJSON_Array
Definition: switch_cJSON.h:87
#define cJSON_String
Definition: switch_cJSON.h:86
char * string
Definition: switch_cJSON.h:114
void switch_dial_leg_list_add_leg(switch_dial_leg_list_t *parent, switch_dial_leg_t **legP, const char *dial_string)
const char * cJSON_GetObjectCstr(const cJSON *object, const char *string)
Definition: switch_json.c:22
switch_status_t switch_dial_handle_add_leg_var(switch_dial_leg_t *leg, const char *var, const char *val)
int type
Definition: switch_cJSON.h:104
void switch_dial_handle_add_global_var(switch_dial_handle_t *handle, const char *var, const char *val)
#define cJSON_ArrayForEach(element, array)
Definition: switch_cJSON.h:267
switch_status_t switch_dial_handle_create(switch_dial_handle_t **handle)

◆ switch_dial_handle_destroy()

void switch_dial_handle_destroy ( switch_dial_handle_t **  handle)

Definition at line 4436 of file switch_ivr_originate.c.

References switch_dial_handle_s::global_vars, switch_dial_leg_list_s::handle, switch_dial_leg_list_s::leg_idx, switch_dial_handle_s::leg_list_idx, switch_dial_handle_s::leg_lists, switch_dial_leg_s::leg_vars, switch_dial_leg_list_s::legs, pool, switch_dial_handle_s::pool, switch_core_destroy_memory_pool, and switch_event_destroy().

Referenced by switch_dial_handle_list_create_json_obj(), switch_dial_handle_list_destroy(), and switch_ivr_enterprise_originate().

4437 {
4438  switch_dial_handle_t *hp = *handle;
4439  switch_memory_pool_t *pool = NULL;
4440 
4441  *handle = NULL;
4442 
4443  if (hp) {
4444  int i, j;
4445 
4446  for (i = 0; i < hp->leg_list_idx; i++) {
4447  for(j = 0; j < hp->leg_lists[i]->leg_idx; j++) {
4449  }
4450  }
4451 
4453  pool = hp->pool;
4454  hp = NULL;
4456  }
4457 }
switch_memory_pool_t * pool
#define switch_core_destroy_memory_pool(p)
Returns a subpool back to the main pool.
Definition: switch_core.h:642
switch_memory_pool_t * pool
switch_event_t * leg_vars
struct fspr_pool_t switch_memory_pool_t
void switch_event_destroy(switch_event_t **event)
Destroy an event.
switch_event_t * global_vars
switch_dial_leg_list_t * leg_lists[MAX_PEERS]
switch_dial_leg_t * legs[MAX_PEERS]

◆ switch_dial_handle_get_global_vars()

switch_event_t* switch_dial_handle_get_global_vars ( switch_dial_handle_t handle)

Definition at line 4606 of file switch_ivr_originate.c.

References switch_dial_handle_s::global_vars, and switch_assert.

Referenced by switch_ivr_originate().

4607 {
4608  switch_assert(handle);
4609 
4610  return handle->global_vars;
4611 }
switch_event_t * global_vars
#define switch_assert(expr)

◆ switch_dial_handle_get_peers()

int switch_dial_handle_get_peers ( switch_dial_handle_t handle,
int  idx,
char **  array,
int  max 
)

Definition at line 4578 of file switch_ivr_originate.c.

References switch_dial_leg_s::dial_string, switch_dial_handle_s::leg_lists, and switch_dial_leg_list_s::legs.

Referenced by switch_ivr_originate().

4579 {
4580  int i, j = 0;
4581 
4582  if (!handle->leg_lists[idx]) return 0;
4583 
4584  for (i = 0; i < max && handle->leg_lists[idx]->legs[i]; i++) {
4585  array[j++] = handle->leg_lists[idx]->legs[i]->dial_string;
4586  }
4587 
4588  return j;
4589 }
switch_dial_leg_list_t * leg_lists[MAX_PEERS]
switch_dial_leg_t * legs[MAX_PEERS]

◆ switch_dial_handle_get_total()

int switch_dial_handle_get_total ( switch_dial_handle_t handle)

Definition at line 4573 of file switch_ivr_originate.c.

References switch_dial_handle_s::leg_list_idx.

Referenced by switch_ivr_originate().

4574 {
4575  return handle->leg_list_idx;
4576 }

◆ switch_dial_handle_get_vars()

int switch_dial_handle_get_vars ( switch_dial_handle_t handle,
int  idx,
switch_event_t **  array,
int  max 
)

Definition at line 4592 of file switch_ivr_originate.c.

References switch_dial_handle_s::leg_lists, switch_dial_leg_s::leg_vars, and switch_dial_leg_list_s::legs.

Referenced by switch_ivr_originate().

4593 {
4594  int i, j = 0;
4595 
4596  if (!handle->leg_lists[idx]) return 0;
4597 
4598  for (i = 0; i < max && handle->leg_lists[idx]->legs[i]; i++) {
4599  array[j++] = handle->leg_lists[idx]->legs[i]->leg_vars;
4600  }
4601 
4602  return j;
4603 }
switch_event_t * leg_vars
switch_dial_leg_list_t * leg_lists[MAX_PEERS]
switch_dial_leg_t * legs[MAX_PEERS]

◆ switch_dial_handle_list_add_global_var()

void switch_dial_handle_list_add_global_var ( switch_dial_handle_list_t hl,
const char *  var,
const char *  val 
)

Definition at line 4349 of file switch_ivr_originate.c.

References switch_dial_handle_list_s::global_vars, switch_assert, switch_event_add_header_string(), SWITCH_EVENT_CHANNEL_DATA, switch_event_create_plain(), and SWITCH_STACK_BOTTOM.

Referenced by switch_dial_handle_list_add_global_var_printf(), and switch_dial_handle_list_create_json_obj().

4350 {
4351  switch_assert(hl);
4352 
4353  if (!hl->global_vars) {
4355  }
4356 
4358 }
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.
static switch_status_t switch_event_create_plain(switch_event_t **event, switch_event_types_t event_id)
Definition: switch_event.h:386
#define switch_assert(expr)

◆ switch_dial_handle_list_add_global_var_printf()

void switch_dial_handle_list_add_global_var_printf ( switch_dial_handle_list_t hl,
const char *  var,
const char *  fmt,
  ... 
)

Definition at line 4360 of file switch_ivr_originate.c.

References switch_dial_handle_list_add_global_var(), and switch_vasprintf().

4361 {
4362  int ret = 0;
4363  char *data = NULL;
4364  va_list ap;
4365 
4366  va_start(ap, fmt);
4367  ret = switch_vasprintf(&data, fmt, ap);
4368  va_end(ap);
4369 
4370  if (ret == -1) {
4371  abort();
4372  }
4373 
4375  free(data);
4376 }
int cJSON_bool fmt
Definition: switch_cJSON.h:150
void switch_dial_handle_list_add_global_var(switch_dial_handle_list_t *hl, const char *var, const char *val)
int switch_vasprintf(_Out_opt_ char **buf, _In_z_ _Printf_format_string_ const char *format, _In_ va_list ap)

◆ switch_dial_handle_list_create()

switch_status_t switch_dial_handle_list_create ( switch_dial_handle_list_t **  hl)

Definition at line 4291 of file switch_ivr_originate.c.

References pool, switch_dial_handle_list_s::pool, switch_assert, switch_core_alloc, switch_core_new_memory_pool, and SWITCH_STATUS_SUCCESS.

Referenced by switch_dial_handle_list_create_json_obj().

4292 {
4293  switch_dial_handle_list_t *hlP = NULL;
4294  switch_memory_pool_t *pool = NULL;
4295 
4297  switch_assert(pool);
4298 
4299  hlP = switch_core_alloc(pool, sizeof(*hlP));
4300  switch_assert(hlP);
4301 
4302  hlP->pool = pool;
4303 
4304  *hl = hlP;
4305 
4306  return SWITCH_STATUS_SUCCESS;
4307 }
switch_memory_pool_t * pool
#define switch_core_new_memory_pool(p)
Create a new sub memory pool from the core&#39;s master pool.
Definition: switch_core.h:633
switch_memory_pool_t * pool
#define switch_core_alloc(_pool, _mem)
Allocate memory directly from a memory pool.
Definition: switch_core.h:684
struct fspr_pool_t switch_memory_pool_t
#define switch_assert(expr)

◆ switch_dial_handle_list_create_handle()

switch_status_t switch_dial_handle_list_create_handle ( switch_dial_handle_list_t hl,
switch_dial_handle_t **  handle 
)

Definition at line 4318 of file switch_ivr_originate.c.

References switch_dial_handle_list_s::handle_idx, switch_dial_handle_list_s::handles, MAX_PEERS, switch_dial_handle_create(), SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.

4319 {
4320  switch_dial_handle_t *hp = NULL;
4322  hl->handles[hl->handle_idx++] = hp;
4323  *handle = hp;
4324  return SWITCH_STATUS_SUCCESS;
4325  }
4326  return SWITCH_STATUS_FALSE;
4327 }
#define MAX_PEERS
switch_dial_handle_t * handles[MAX_PEERS]
switch_status_t switch_dial_handle_create(switch_dial_handle_t **handle)

◆ switch_dial_handle_list_create_json()

switch_status_t switch_dial_handle_list_create_json ( switch_dial_handle_list_t **  handle,
const char *  handle_string 
)

Definition at line 4878 of file switch_ivr_originate.c.

References switch_dial_handle_list_create_json_obj(), SWITCH_STATUS_FALSE, and zstr.

4879 {
4880  switch_status_t status;
4881  cJSON *handle_list_json = NULL;
4882 
4883  if (zstr(handle_list_string)) {
4884  return SWITCH_STATUS_FALSE;
4885  }
4886 
4887  handle_list_json = cJSON_Parse(handle_list_string);
4888  if (!handle_list_json) {
4889  return SWITCH_STATUS_FALSE;
4890  }
4891 
4892  status = switch_dial_handle_list_create_json_obj(hl, handle_list_json);
4893  cJSON_Delete(handle_list_json);
4894  return status;
4895 }
switch_status_t switch_dial_handle_list_create_json_obj(switch_dial_handle_list_t **hl, cJSON *handle_list_json)
#define zstr(x)
Definition: switch_utils.h:314
switch_status_t
Common return values.

◆ switch_dial_handle_list_create_json_obj()

switch_status_t switch_dial_handle_list_create_json_obj ( switch_dial_handle_list_t **  handle,
cJSON json 
)

Definition at line 4828 of file switch_ivr_originate.c.

References cJSON::child, cJSON_ArrayForEach, cJSON_Object, cJSON_String, switch_dial_leg_list_s::handle, MAX_PEERS, cJSON::next, cJSON::string, switch_assert, SWITCH_CHANNEL_LOG, switch_dial_handle_create_json_obj(), switch_dial_handle_destroy(), switch_dial_handle_list_add_global_var(), switch_dial_handle_list_add_handle(), switch_dial_handle_list_create(), switch_dial_handle_list_destroy(), switch_log_printf(), SWITCH_LOG_WARNING, switch_safe_free, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, cJSON::type, and cJSON::valuestring.

Referenced by switch_dial_handle_list_create_json().

4829 {
4830  cJSON *handle_json = NULL;
4831  cJSON *handles_json = NULL;
4832  cJSON *vars_json = NULL;
4833 
4834  *hl = NULL;
4835 
4836  handles_json = cJSON_GetObjectItem(handle_list_json, "handles");
4837  if (!handles_json || !cJSON_IsArray(handles_json)) {
4838  return SWITCH_STATUS_FALSE;
4839  }
4841  switch_assert(*hl);
4842  for (handle_json = handles_json->child; handle_json; handle_json = handle_json->next) {
4843  switch_dial_handle_t *handle = NULL;
4844  if (switch_dial_handle_create_json_obj(&handle, handle_json) == SWITCH_STATUS_SUCCESS && handle) {
4846  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Not adding remaining dial handles: exceeded limit of %d handles\n", MAX_PEERS);
4847  switch_dial_handle_destroy(&handle);
4848  break;
4849  }
4850  } else {
4851  char *handle_json_str = cJSON_PrintUnformatted(handle_json);
4852  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to create dial handle: %s\n", handle_json_str);
4853  switch_safe_free(handle_json_str);
4854  }
4855  }
4856 
4857  if ((*hl)->handle_idx == 0) {
4858  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Failed to create dial handle list: no handles added!\n");
4860  return SWITCH_STATUS_FALSE;
4861  }
4862 
4863  vars_json = cJSON_GetObjectItem(handle_list_json, "vars");
4864  if (vars_json && vars_json->type == cJSON_Object) {
4865  cJSON *var_json = NULL;
4866  cJSON_ArrayForEach(var_json, vars_json) {
4867  if (!var_json || var_json->type != cJSON_String || !var_json->valuestring || !var_json->string) {
4868  continue;
4869  }
4870  switch_dial_handle_list_add_global_var(*hl, var_json->string, var_json->valuestring);
4871  }
4872  }
4873 
4874  return SWITCH_STATUS_SUCCESS;
4875 }
#define SWITCH_CHANNEL_LOG
#define cJSON_Object
Definition: switch_cJSON.h:88
char * valuestring
Definition: switch_cJSON.h:107
static switch_status_t switch_dial_handle_list_add_handle(switch_dial_handle_list_t *hl, switch_dial_handle_t *handle)
void switch_dial_handle_list_add_global_var(switch_dial_handle_list_t *hl, const char *var, const char *val)
#define cJSON_String
Definition: switch_cJSON.h:86
struct cJSON * child
Definition: switch_cJSON.h:101
char * string
Definition: switch_cJSON.h:114
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:885
void switch_dial_handle_list_destroy(switch_dial_handle_list_t **hl)
struct cJSON * next
Definition: switch_cJSON.h:98
#define MAX_PEERS
switch_status_t switch_dial_handle_create_json_obj(switch_dial_handle_t **handle, cJSON *json)
void switch_dial_handle_destroy(switch_dial_handle_t **handle)
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.
int type
Definition: switch_cJSON.h:104
#define switch_assert(expr)
#define cJSON_ArrayForEach(element, array)
Definition: switch_cJSON.h:267
switch_status_t switch_dial_handle_list_create(switch_dial_handle_list_t **hl)

◆ switch_dial_handle_list_destroy()

void switch_dial_handle_list_destroy ( switch_dial_handle_list_t **  hl)

Definition at line 4329 of file switch_ivr_originate.c.

References switch_dial_handle_list_s::global_vars, switch_dial_handle_list_s::handle_idx, switch_dial_handle_list_s::handles, pool, switch_dial_handle_list_s::pool, switch_core_destroy_memory_pool, switch_dial_handle_destroy(), and switch_event_destroy().

Referenced by switch_dial_handle_list_create_json_obj().

4330 {
4331  switch_dial_handle_list_t *hlP = *hl;
4332  switch_memory_pool_t *pool = NULL;
4333 
4334  *hl = NULL;
4335 
4336  if (hlP) {
4337  int i;
4338  for (i = 0; i < hlP->handle_idx; i++) {
4340  }
4341 
4343  pool = hlP->pool;
4344  hlP = NULL;
4346  }
4347 }
switch_memory_pool_t * pool
#define switch_core_destroy_memory_pool(p)
Returns a subpool back to the main pool.
Definition: switch_core.h:642
switch_memory_pool_t * pool
void switch_dial_handle_destroy(switch_dial_handle_t **handle)
struct fspr_pool_t switch_memory_pool_t
void switch_event_destroy(switch_event_t **event)
Destroy an event.
switch_dial_handle_t * handles[MAX_PEERS]

◆ switch_dial_handle_list_serialize_json()

switch_status_t switch_dial_handle_list_serialize_json ( switch_dial_handle_list_t hl,
char **  str 
)

Definition at line 4816 of file switch_ivr_originate.c.

References switch_dial_handle_list_serialize_json_obj(), SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.

4817 {
4818  cJSON *json = NULL;
4820  *str = cJSON_PrintUnformatted(json);
4821  cJSON_Delete(json);
4822  return SWITCH_STATUS_SUCCESS;
4823  }
4824  return SWITCH_STATUS_FALSE;
4825 }
switch_status_t switch_dial_handle_list_serialize_json_obj(switch_dial_handle_list_t *hl, cJSON **json)

◆ switch_dial_handle_list_serialize_json_obj()

switch_status_t switch_dial_handle_list_serialize_json_obj ( switch_dial_handle_list_t hl,
cJSON **  json 
)

Definition at line 4789 of file switch_ivr_originate.c.

References switch_dial_handle_list_s::global_vars, switch_dial_leg_list_s::handle, switch_dial_handle_list_s::handle_idx, switch_dial_handle_list_s::handles, switch_dial_handle_serialize_json_obj(), SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, and vars_serialize_json_obj().

Referenced by switch_dial_handle_list_serialize_json().

4790 {
4791  int i;
4792  cJSON *global_vars_json = NULL;
4793  cJSON *handles_json = NULL;
4794  if (!hl) {
4795  return SWITCH_STATUS_FALSE;
4796  }
4797  *json = cJSON_CreateObject();
4798  if (hl->global_vars && vars_serialize_json_obj(hl->global_vars, &global_vars_json) == SWITCH_STATUS_SUCCESS && global_vars_json) {
4799  cJSON_AddItemToObject(*json, "vars", global_vars_json);
4800  }
4801 
4802  handles_json = cJSON_CreateArray();
4803  cJSON_AddItemToObject(*json, "handles", handles_json);
4804  for (i = 0; i < hl->handle_idx; i++) {
4805  switch_dial_handle_t *handle = hl->handles[i];
4806  cJSON *handle_json = NULL;
4807  if (switch_dial_handle_serialize_json_obj(handle, &handle_json) == SWITCH_STATUS_SUCCESS && handle_json) {
4808  cJSON_AddItemToArray(handles_json, handle_json);
4809  }
4810  }
4811 
4812  return SWITCH_STATUS_SUCCESS;
4813 }
switch_status_t switch_dial_handle_serialize_json_obj(switch_dial_handle_t *handle, cJSON **json)
static switch_status_t vars_serialize_json_obj(switch_event_t *event, cJSON **json)
switch_dial_handle_t * handles[MAX_PEERS]

◆ switch_dial_handle_serialize_json()

switch_status_t switch_dial_handle_serialize_json ( switch_dial_handle_t handle,
char **  str 
)

Definition at line 4698 of file switch_ivr_originate.c.

References switch_dial_handle_serialize_json_obj(), SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.

4699 {
4700  cJSON *json = NULL;
4701  if (switch_dial_handle_serialize_json_obj(handle, &json) == SWITCH_STATUS_SUCCESS && json) {
4702  *str = cJSON_PrintUnformatted(json);
4703  cJSON_Delete(json);
4704  return SWITCH_STATUS_SUCCESS;
4705  }
4706  return SWITCH_STATUS_FALSE;
4707 }
switch_status_t switch_dial_handle_serialize_json_obj(switch_dial_handle_t *handle, cJSON **json)

◆ switch_dial_handle_serialize_json_obj()

switch_status_t switch_dial_handle_serialize_json_obj ( switch_dial_handle_t handle,
cJSON **  json 
)

Definition at line 4671 of file switch_ivr_originate.c.

References switch_dial_handle_s::global_vars, switch_dial_handle_s::leg_list_idx, leg_list_serialize_json_obj(), switch_dial_handle_s::leg_lists, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, and vars_serialize_json_obj().

Referenced by switch_dial_handle_list_serialize_json_obj(), and switch_dial_handle_serialize_json().

4672 {
4673  int i;
4674  cJSON *global_vars_json = NULL;
4675  cJSON *leg_lists_json = NULL;
4676  if (!handle) {
4677  return SWITCH_STATUS_FALSE;
4678  }
4679  *json = cJSON_CreateObject();
4680  if (handle->global_vars && vars_serialize_json_obj(handle->global_vars, &global_vars_json) == SWITCH_STATUS_SUCCESS && global_vars_json) {
4681  cJSON_AddItemToObject(*json, "vars", global_vars_json);
4682  }
4683 
4684  leg_lists_json = cJSON_CreateArray();
4685  cJSON_AddItemToObject(*json, "leg_lists", leg_lists_json);
4686  for (i = 0; i < handle->leg_list_idx; i++) {
4687  switch_dial_leg_list_t *ll = handle->leg_lists[i];
4688  cJSON *leg_list_json = NULL;
4689  if (leg_list_serialize_json_obj(ll, &leg_list_json) == SWITCH_STATUS_SUCCESS && leg_list_json) {
4690  cJSON_AddItemToArray(leg_lists_json, leg_list_json);
4691  }
4692  }
4693 
4694  return SWITCH_STATUS_SUCCESS;
4695 }
static switch_status_t vars_serialize_json_obj(switch_event_t *event, cJSON **json)
static switch_status_t leg_list_serialize_json_obj(switch_dial_leg_list_t *ll, cJSON **json)
switch_event_t * global_vars
switch_dial_leg_list_t * leg_lists[MAX_PEERS]

◆ switch_dial_leg_get_var()

const char* switch_dial_leg_get_var ( switch_dial_leg_t leg,
const char *  key 
)

Definition at line 4620 of file switch_ivr_originate.c.

References switch_dial_leg_s::leg_vars, switch_assert, and switch_event_get_header.

4621 {
4622  switch_assert(leg);
4623 
4624  return switch_event_get_header(leg->leg_vars, key);
4625 }
switch_event_t * leg_vars
#define switch_event_get_header(_e, _h)
Definition: switch_event.h:172
char * key
Definition: switch_msrp.c:64
#define switch_assert(expr)

◆ switch_dial_leg_get_vars()

switch_event_t* switch_dial_leg_get_vars ( switch_dial_leg_t leg)

Definition at line 4613 of file switch_ivr_originate.c.

References switch_dial_leg_s::leg_vars, and switch_assert.

4614 {
4615  switch_assert(leg);
4616 
4617  return leg->leg_vars;
4618 }
switch_event_t * leg_vars
#define switch_assert(expr)

◆ switch_dial_leg_list_add_leg()

void switch_dial_leg_list_add_leg ( switch_dial_leg_list_t parent,
switch_dial_leg_t **  legP,
const char *  dial_string 
)

Definition at line 4491 of file switch_ivr_originate.c.

References switch_dial_leg_s::dial_string, switch_dial_leg_list_s::handle, switch_dial_leg_s::handle, switch_dial_leg_list_s::leg_idx, switch_dial_leg_list_s::legs, switch_dial_handle_s::pool, switch_assert, switch_core_alloc, and switch_core_strdup.

Referenced by switch_dial_handle_create_json_obj(), switch_dial_handle_dup(), and switch_dial_leg_list_add_leg_printf().

4492 {
4493  switch_dial_leg_t *leg;
4494 
4495  switch_assert(parent);
4496 
4497  leg = switch_core_alloc(parent->handle->pool, sizeof(*leg));
4498  leg->handle = parent->handle;
4499  leg->dial_string = switch_core_strdup(parent->handle->pool, dial_string);
4500 
4501  parent->legs[parent->leg_idx++] = leg;
4502 
4503  if (legP) {
4504  *legP = leg;
4505  }
4506 }
switch_memory_pool_t * pool
struct switch_dial_handle_s * handle
#define switch_core_strdup(_pool, _todup)
Copy a string using memory allocation from a given pool.
Definition: switch_core.h:733
#define switch_core_alloc(_pool, _mem)
Allocate memory directly from a memory pool.
Definition: switch_core.h:684
struct switch_dial_handle_s * handle
#define switch_assert(expr)
switch_dial_leg_t * legs[MAX_PEERS]

◆ switch_dial_leg_list_add_leg_printf()

void switch_dial_leg_list_add_leg_printf ( switch_dial_leg_list_t parent,
switch_dial_leg_t **  legP,
const char *  fmt,
  ... 
)

Definition at line 4473 of file switch_ivr_originate.c.

References switch_dial_leg_list_add_leg(), and switch_vasprintf().

4474 {
4475  int ret = 0;
4476  char *data = NULL;
4477  va_list ap;
4478 
4479  va_start(ap, fmt);
4480  ret = switch_vasprintf(&data, fmt, ap);
4481  va_end(ap);
4482 
4483  if (ret == -1) {
4484  abort();
4485  }
4486 
4487  switch_dial_leg_list_add_leg(parent, legP, data);
4488  free(data);
4489 }
int cJSON_bool fmt
Definition: switch_cJSON.h:150
void switch_dial_leg_list_add_leg(switch_dial_leg_list_t *parent, switch_dial_leg_t **legP, const char *dial_string)
int switch_vasprintf(_Out_opt_ char **buf, _In_z_ _Printf_format_string_ const char *format, _In_ va_list ap)

◆ switch_ivr_bind_dtmf_meta_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 
)

Definition at line 4731 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, switch_ivr_dmachine_binding::key, 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.

4733 {
4736  const char *meta_var = switch_channel_get_variable(channel, "bind_meta_key");
4737  char meta = '*';
4738  char str[2] = "";
4739 
4740  if (meta_var) {
4741  char t_meta = *meta_var;
4742  if (is_dtmf(t_meta)) {
4743  meta = t_meta;
4744  } else {
4745  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Invalid META KEY %c\n", t_meta);
4746  }
4747  }
4748 
4749  if (meta != '*' && meta != '#') {
4750  str[0] = meta;
4751 
4752  if (switch_dtmftoi(str) == (char)key) {
4753  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid key %u, same as META CHAR\n", key);
4754  return SWITCH_STATUS_FALSE;
4755  }
4756  }
4757 
4758 
4759  if (key > 13) {
4760  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid key %u\n", key);
4761  return SWITCH_STATUS_FALSE;
4762  }
4763 
4764  if (!md) {
4765  md = switch_core_session_alloc(session, sizeof(*md));
4767  switch_core_event_hook_add_send_dtmf(session, meta_on_dtmf);
4768  switch_core_event_hook_add_recv_dtmf(session, meta_on_dtmf);
4769  }
4770 
4771  if (!zstr(app)) {
4772  if ((bind_flags & SBF_DIAL_ALEG)) {
4773  md->sr[SWITCH_DTMF_RECV].meta = meta;
4774  md->sr[SWITCH_DTMF_RECV].up = 1;
4775  md->sr[SWITCH_DTMF_RECV].map[key].app = switch_core_session_strdup(session, app);
4777  md->sr[SWITCH_DTMF_RECV].map[key].bind_flags = bind_flags;
4778 
4779  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Bound A-Leg: %c%c %s\n", meta, switch_itodtmf((char)key), app);
4780  }
4781  if ((bind_flags & SBF_DIAL_BLEG)) {
4782  md->sr[SWITCH_DTMF_SEND].meta = meta;
4783  md->sr[SWITCH_DTMF_SEND].up = 1;
4784  md->sr[SWITCH_DTMF_SEND].map[key].app = switch_core_session_strdup(session, app);
4786  md->sr[SWITCH_DTMF_SEND].map[key].bind_flags = bind_flags;
4787  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Bound B-Leg: %c%c %s\n", meta, switch_itodtmf((char)key), app);
4788  }
4789 
4790  } else {
4791  if ((bind_flags & SBF_DIAL_ALEG)) {
4792  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "UnBound A-Leg: %c%c\n", meta, switch_itodtmf((char)key));
4793  md->sr[SWITCH_DTMF_SEND].map[key].app = NULL;
4794  } else {
4795  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "UnBound: B-Leg %c%d\n", meta, key);
4796  md->sr[SWITCH_DTMF_SEND].map[key].app = NULL;
4797  }
4798  }
4799 
4800  return SWITCH_STATUS_SUCCESS;
4801 }
#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:314
#define is_dtmf(key)
determine if a character is a valid DTMF key
Definition: switch_utils.h:683
_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:450
void * switch_channel_get_private(switch_channel_t *channel, const char *key)
Retrieve private from a given channel.
switch_bind_flag_t bind_flags
char * key
Definition: switch_msrp.c:64
#define switch_core_session_alloc(_session, _memory)
Allocate memory from a session&#39;s pool.
Definition: switch_core.h:696
static int switch_dtmftoi(char *s)
Definition: switch_utils.h:463
#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&#39;s pool.
Definition: switch_core.h:719
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_ivr_blind_transfer_ack()

switch_status_t switch_ivr_blind_transfer_ack ( switch_core_session_t session,
switch_bool_t  success 
)

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

4419 {
4422 
4424  switch_core_session_t *other_session;
4425  const char *uuid = switch_channel_get_variable(channel, "blind_transfer_uuid");
4426 
4428 
4429  if (!zstr(uuid) && (other_session = switch_core_session_locate(uuid))) {
4430  switch_core_session_message_t msg = { 0 };
4432  msg.from = __FILE__;
4433  msg.numeric_arg = success;
4434  switch_core_session_receive_message(other_session, &msg);
4435  switch_core_session_rwunlock(other_session);
4436  status = SWITCH_STATUS_SUCCESS;
4437  }
4438  }
4439 
4440  return status;
4441 
4442 }
switch_core_session_message_types_t message_id
Definition: switch_core.h:183
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:179
#define zstr(x)
Definition: switch_utils.h:314
_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:1247
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&#39;s uuid.
Definition: switch_core.h:932
void switch_channel_clear_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Clear given flag(s) from a channel.

◆ switch_ivr_block_dtmf_session()

switch_status_t switch_ivr_block_dtmf_session ( switch_core_session_t session)

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

4718 {
4720  uint8_t enabled = (uint8_t)(intptr_t)switch_channel_get_private(channel, SWITCH_BLOCK_DTMF_KEY);
4721 
4722  if (!enabled) {
4723  switch_channel_set_private(channel, SWITCH_BLOCK_DTMF_KEY, (void *)(intptr_t)1);
4724  switch_core_event_hook_add_send_dtmf(session, block_on_dtmf);
4725  switch_core_event_hook_add_recv_dtmf(session, block_on_dtmf);
4726  }
4727 
4728  return SWITCH_STATUS_SUCCESS;
4729 }
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.

◆ switch_ivr_capture_text()

switch_status_t switch_ivr_capture_text ( switch_core_session_t session,
switch_bool_t  on 
)

Definition at line 1847 of file switch_ivr_async.c.

References record_helper::bug, SMBF_READ_TEXT_STREAM, switch_channel_get_private(), SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_private(), switch_core_media_bug_add(), switch_core_media_bug_remove(), switch_core_session_get_channel(), switch_core_session_get_uuid(), SWITCH_LOG_ERROR, switch_log_printf(), SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, and text_callback().

1848 {
1851 
1852  bug = (switch_media_bug_t *) switch_channel_get_private(channel, "capture_text");
1853 
1854  if (on) {
1855 
1856  if (bug) {
1857  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "text bug already attached\n");
1858  return SWITCH_STATUS_FALSE;
1859  }
1860 
1861 
1862  if (switch_core_media_bug_add(session, "capture_text", switch_core_session_get_uuid(session),
1863  text_callback, NULL, 0,
1865  &bug) != SWITCH_STATUS_SUCCESS) {
1866  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot attach bug\n");
1867  return SWITCH_STATUS_FALSE;
1868  }
1869 
1870  switch_channel_set_private(channel, "capture_text", bug);
1871  return SWITCH_STATUS_SUCCESS;
1872 
1873  } else {
1874 
1875  if (bug) {
1876  switch_channel_set_private(channel, "capture_text", NULL);
1877  switch_core_media_bug_remove(session, &bug);
1878  return SWITCH_STATUS_SUCCESS;
1879  } else {
1880  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "text bug not attached\n");
1881  return SWITCH_STATUS_FALSE;
1882  }
1883 
1884  }
1885 }
#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.
switch_status_t switch_core_media_bug_add(_In_ switch_core_session_t *session, _In_ const char *function, _In_ const char *target, _In_ switch_media_bug_callback_t callback, _In_opt_ void *user_data, _In_ time_t stop_time, _In_ switch_media_bug_flag_t flags, _Out_ switch_media_bug_t **new_bug)
Add a media bug to the 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_media_bug_remove(_In_ switch_core_session_t *session, _Inout_ switch_media_bug_t **bug)
Remove a media bug from the session.
char * switch_core_session_get_uuid(_In_ switch_core_session_t *session)
Retrieve the unique identifier from a session.
void * switch_channel_get_private(switch_channel_t *channel, const char *key)
Retrieve private from a given channel.
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
static switch_bool_t text_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type)
switch_media_bug_t * bug

◆ switch_ivr_check_presence_mapping()

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

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

4341 {
4342  char *cf = "presence_map.conf";
4343  switch_xml_t cfg, xml, x_domains, x_domain, x_exten;
4344  char *r = NULL;
4345  switch_event_t *params = NULL;
4346  switch_regex_t *re = NULL;
4347  int proceed = 0, ovector[100];
4348 
4350  switch_assert(params);
4351 
4352  if ( !zstr(domain_name) ) {
4353  switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "domain", domain_name);
4354  }
4355 
4356  if ( !zstr(exten_name) ) {
4357  switch_event_add_header_string(params, SWITCH_STACK_BOTTOM, "exten", exten_name);
4358  }
4359 
4360  if (!(xml = switch_xml_open_cfg(cf, &cfg, params))) {
4361  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", cf);
4362  goto end;
4363  }
4364 
4365  if (!(x_domains = switch_xml_child(cfg, "domains"))) {
4366  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't find any domains!\n");
4367  goto end;
4368  }
4369 
4370  for (x_domain = switch_xml_child(x_domains, "domain"); x_domain; x_domain = x_domain->next) {
4371  const char *dname = switch_xml_attr(x_domain, "name");
4372  if (!dname || (strcasecmp(dname, "*") && strcasecmp(domain_name, dname))) continue;
4373 
4374  for (x_exten = switch_xml_child(x_domain, "exten"); x_exten; x_exten = x_exten->next) {
4375  const char *regex = switch_xml_attr(x_exten, "regex");
4376  const char *proto = switch_xml_attr(x_exten, "proto");
4377 
4378  if (!zstr(regex) && !zstr(proto)) {
4379  proceed = switch_regex_perform(exten_name, regex, &re, ovector, sizeof(ovector) / sizeof(ovector[0]));
4381 
4382  if (proceed) {
4383  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Mapping %s@%s to proto %s matching expression [%s]\n",
4384  exten_name, domain_name, proto, regex);
4385  r = strdup(proto);
4386  goto end;
4387  }
4388 
4389  }
4390  }
4391  }
4392 
4393  end:
4394  switch_event_destroy(&params);
4395 
4396  if (xml) {
4397  switch_xml_free(xml);
4398  }
4399 
4400  return r;
4401 
4402 }
#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:79
struct real_pcre switch_regex_t
Definition: switch_regex.h:43
#define zstr(x)
Definition: switch_utils.h:314
switch_xml_t next
Definition: switch_xml.h:91
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:384
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_ivr_create_message_reply()

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

Definition at line 4327 of file switch_ivr.c.

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

4328 {
4330 
4331  if ((status = switch_event_dup_reply(reply, message) != SWITCH_STATUS_SUCCESS)) {
4332  abort();
4333  }
4334 
4335  switch_event_add_header_string(*reply, SWITCH_STACK_BOTTOM, "proto", new_proto);
4336 
4337  return status;
4338 }
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)

◆ switch_ivr_delay_echo()

void switch_ivr_delay_echo ( switch_core_session_t session,
uint32_t  delay_ms 
)

Definition at line 3579 of file switch_ivr.c.

References switch_rtp_packet_t::body, switch_frame::buflen, switch_frame::codec, switch_frame::data, switch_frame::datalen, debug, 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.

3580 {
3581  switch_jb_t *jb;
3582  int qlen = 0;
3583  switch_frame_t *read_frame, write_frame = { 0 };
3584  switch_status_t status;
3586  uint32_t interval;
3587  uint32_t ts = 0;
3588  uint16_t seq = 0;
3589  switch_codec_implementation_t read_impl = { 0 };
3590  int is_rtp = 0;
3591  int debug = 0;
3592  const char *var;
3593 
3594 
3595  switch_core_session_get_read_impl(session, &read_impl);
3596 
3597  if (delay_ms < 1 || delay_ms > 10000) {
3598  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid delay [%d] must be between 1 and 10000\n", delay_ms);
3599  return;
3600  }
3601 
3602  interval = read_impl.microseconds_per_packet / 1000;
3603 
3604  if (delay_ms < interval * 2) {
3605  delay_ms = interval * 2;
3606  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Minimum possible delay for this codec (%d) has been chosen\n", delay_ms);
3607  }
3608 
3609  qlen = delay_ms / (interval);
3610  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Setting delay to %dms (%d frames)\n", delay_ms, qlen);
3611 
3612  switch_jb_create(&jb, SJB_AUDIO, qlen, qlen, switch_core_session_get_pool(session));
3613 
3614  if ((var = switch_channel_get_variable(channel, "delay_echo_debug_level"))) {
3615  debug = atoi(var);
3616  }
3617 
3618  if (debug) {
3619  switch_jb_debug_level(jb, debug);
3620  }
3621 
3622  write_frame.codec = switch_core_session_get_read_codec(session);
3623 
3624  while (switch_channel_ready(channel)) {
3625  switch_rtp_packet_t packet = { {0} };
3626  switch_size_t plen = sizeof(packet);
3627 
3628  status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
3629 
3630  if (!SWITCH_READ_ACCEPTABLE(status)) {
3631  break;
3632  }
3633 
3634  if (switch_test_flag(read_frame, SFF_CNG)) {
3635  continue;
3636  }
3637 
3638  if (read_frame->packet) {
3639  is_rtp = 1;
3640  switch_jb_put_packet(jb, (switch_rtp_packet_t *) read_frame->packet, read_frame->packetlen);
3641  } else if (is_rtp) {
3642  continue;
3643  } else {
3644  ts += read_impl.samples_per_packet;
3645  memcpy(packet.body, read_frame->data, read_frame->datalen);
3646  packet.header.ts = htonl(ts);
3647  packet.header.seq = htons(++seq);
3648  packet.header.version = 2;
3649  }
3650 
3651  if (switch_jb_get_packet(jb, (switch_rtp_packet_t *) &packet, &plen) == SWITCH_STATUS_SUCCESS) {
3652  write_frame.data = packet.body;
3653  write_frame.datalen = (uint32_t) plen - 12;
3654  write_frame.buflen = (uint32_t) plen;
3655 
3656  status = switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0);
3657 
3658  if (!SWITCH_READ_ACCEPTABLE(status)) {
3659  break;
3660  }
3661  }
3662  }
3663 
3664  switch_jb_destroy(&jb);
3665 }
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:56
#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:56
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:70
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:68
uint32_t packetlen
Definition: switch_frame.h:62
#define switch_channel_get_variable(_c, _v)
An abstraction of a data frame.
Definition: switch_frame.h:54
uintptr_t switch_size_t
void switch_jb_debug_level(switch_jb_t *jb, uint8_t level)
void * packet
Definition: switch_frame.h:60
switch_status_t
Common return values.
char body[SWITCH_RTP_MAX_BUF_LEN+4+sizeof(char *)]
Definition: switch_rtp.h:57
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:693
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.
int debug
Definition: switch_msrp.c:57
#define SWITCH_READ_ACCEPTABLE(status)
switch_memory_pool_t * switch_core_session_get_pool(_In_ switch_core_session_t *session)
Retrieve the memory pool from a session.

◆ switch_ivr_dmachine_bind()

switch_status_t switch_ivr_dmachine_bind ( switch_ivr_dmachine_t dmachine,
const char *  realm,
const char *  digits,
switch_byte_t  is_priority,
int32_t  key,
switch_ivr_dmachine_callback_t  callback,
void *  user_data 
)

Definition at line 255 of file switch_ivr_async.c.

References switch_ivr_dmachine::binding_hash, dm_binding_head_t::binding_list, switch_ivr_dmachine_binding::callback, switch_ivr_dmachine_binding::digits, DMACHINE_MAX_DIGIT_LEN, switch_ivr_dmachine_binding::first_match, switch_ivr_dmachine_binding::is_priority, switch_ivr_dmachine_binding::is_regex, switch_ivr_dmachine_binding::key, switch_ivr_dmachine::max_digit_len, dm_binding_head_t::name, switch_ivr_dmachine::name, switch_ivr_dmachine_binding::next, switch_ivr_dmachine::pool, switch_ivr_dmachine::realm, switch_ivr_dmachine_binding::repl, 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.

262 {
263  switch_ivr_dmachine_binding_t *binding = NULL, *ptr;
264  switch_size_t len;
265  dm_binding_head_t *headp;
266  const char *msg = "";
267  char *repl = NULL;
268  char *digits_;
269 
270  if (strlen(digits) > DMACHINE_MAX_DIGIT_LEN -1) {
271  return SWITCH_STATUS_FALSE;
272  }
273 
274  if (zstr(realm)) {
275  realm = "default";
276  }
277 
278  if (!(headp = switch_core_hash_find(dmachine->binding_hash, realm))) {
279  headp = switch_core_alloc(dmachine->pool, sizeof(*headp));
280  headp->name = switch_core_strdup(dmachine->pool, realm);
281  switch_core_hash_insert(dmachine->binding_hash, realm, headp);
282  }
283 
284  for(ptr = headp->binding_list; ptr; ptr = ptr->next) {
285  if ((ptr->is_regex && !strcmp(ptr->digits, digits+1)) || !strcmp(ptr->digits, digits)) {
286  msg = "Reuse Existing ";
287  binding = ptr;
288  binding->callback = callback;
289  binding->user_data = user_data;
290  goto done;
291  }
292  }
293 
294 
295  binding = switch_core_alloc(dmachine->pool, sizeof(*binding));
296 
297  digits_ = switch_core_strdup(dmachine->pool, digits);
298 
299  if (*digits_ == '=') {
300  binding->first_match = 1;
301  digits_++;
302  }
303 
304  if (*digits_ == '~') {
305  binding->is_regex = 1;
306  digits_++;
307  if ((repl = strchr(digits_, '~')) && *(repl+1) == '~') {
308  *repl++ = '\0';
309  *repl++ = '\0';
310  }
311  }
312 
313  binding->key = key;
314  binding->digits = digits_;
315  binding->is_priority = is_priority;
316  binding->callback = callback;
317  binding->user_data = user_data;
318  binding->repl = repl;
319 
320  if (headp->tail) {
321  headp->tail->next = binding;
322  } else {
323  headp->binding_list = binding;
324  }
325 
326  headp->tail = binding;
327 
328  len = strlen(digits);
329 
330  if (dmachine->realm != headp) {
331  switch_ivr_dmachine_set_realm(dmachine, realm);
332  }
333 
334  if (binding->is_regex && dmachine->max_digit_len != DMACHINE_MAX_DIGIT_LEN -1) {
335  dmachine->max_digit_len = DMACHINE_MAX_DIGIT_LEN -1;
336  } else if (len > dmachine->max_digit_len) {
337  dmachine->max_digit_len = (uint32_t) len;
338  }
339 
340  done:
341 
342  if (binding->is_regex) {
343  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%sDigit parser %s: binding %s/%s/%d callback: %p data: %p\n",
344  msg, dmachine->name, digits, realm, key, (void *)(intptr_t) callback, user_data);
345  } else {
346  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%sDigit parser %s: binding %s/%s/%d callback: %p data: %p\n",
347  msg, dmachine->name, digits, realm, key, (void *)(intptr_t) callback, user_data);
348  }
349 
350  return SWITCH_STATUS_SUCCESS;
351 }
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:733
dm_binding_head_t * realm
switch_ivr_dmachine_binding_t * binding_list
#define zstr(x)
Definition: switch_utils.h:314
switch_ivr_dmachine_binding_t * tail
#define switch_core_alloc(_pool, _mem)
Allocate memory directly from a memory pool.
Definition: switch_core.h:684
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:1479
switch_memory_pool_t * pool
char * key
Definition: switch_msrp.c:64
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_ivr_dmachine_clear()

switch_status_t switch_ivr_dmachine_clear ( switch_ivr_dmachine_t dmachine)

Definition at line 692 of file switch_ivr_async.c.

References switch_ivr_dmachine::cur_digit_len, switch_ivr_dmachine::digits, switch_ivr_dmachine::last_digit_time, memset(), and SWITCH_STATUS_SUCCESS.

Referenced by switch_ivr_dmachine_ping().

693 {
694 
695  memset(dmachine->digits, 0, sizeof(dmachine->digits));
696  dmachine->cur_digit_len = 0;
697  dmachine->last_digit_time = 0;
698  return SWITCH_STATUS_SUCCESS;
699 }
char digits[DMACHINE_MAX_DIGIT_LEN]
switch_time_t last_digit_time
memset(buf, 0, buflen)

◆ switch_ivr_dmachine_clear_realm()

switch_status_t switch_ivr_dmachine_clear_realm ( switch_ivr_dmachine_t dmachine,
const char *  realm 
)

Definition at line 231 of file switch_ivr_async.c.

References switch_ivr_dmachine::binding_hash, switch_ivr_dmachine::name, switch_ivr_dmachine::realm, 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.

232 {
233  dm_binding_head_t *headp;
234 
235  if (zstr(realm)) {
236  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Digit parser %s: Error unknown realm: '%s'\n", dmachine->name, realm);
237  return SWITCH_STATUS_FALSE;
238  }
239 
240  headp = switch_core_hash_find(dmachine->binding_hash, realm);
241 
242  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Digit parser %s: Clearing realm '%s'\n", dmachine->name, realm);
243 
244  if (headp == dmachine->realm) {
246  "Digit parser %s: '%s' was the active realm, no realm currently selected.\n", dmachine->name, realm);
247  dmachine->realm = NULL;
248  }
249 
250  /* pool alloc'd just ditch it and it will give back the memory when we destroy ourselves */
251  switch_core_hash_delete(dmachine->binding_hash, realm);
252  return SWITCH_STATUS_SUCCESS;
253 }
#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:314
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_ivr_dmachine_create()

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 132 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, switch_ivr_dmachine_binding::user_data, and switch_ivr_dmachine::user_data.

140 {
141  switch_byte_t my_pool = 0;
142  switch_ivr_dmachine_t *dmachine;
143 
144  if (!pool) {
146  my_pool = 1;
147  }
148 
149  dmachine = switch_core_alloc(pool, sizeof(*dmachine));
150  dmachine->pool = pool;
151  dmachine->my_pool = my_pool;
152  dmachine->digit_timeout_ms = digit_timeout_ms;
153  dmachine->input_timeout_ms = input_timeout_ms;
154  dmachine->match.dmachine = dmachine;
155  dmachine->name = switch_core_strdup(dmachine->pool, name);
156  switch_mutex_init(&dmachine->mutex, SWITCH_MUTEX_NESTED, dmachine->pool);
157 
159 
160  if (match_callback) {
161  dmachine->match_callback = match_callback;
162  }
163 
164  if (nonmatch_callback) {
165  dmachine->nonmatch_callback = nonmatch_callback;
166  }
167 
168  dmachine->user_data = user_data;
169 
170  *dmachine_p = dmachine;
171 
172  return SWITCH_STATUS_SUCCESS;
173 }
#define switch_core_new_memory_pool(p)
Create a new sub memory pool from the core&#39;s master pool.
Definition: switch_core.h:633
switch_ivr_dmachine_callback_t nonmatch_callback
switch_hash_t * binding_hash
#define switch_core_hash_init(_hash)
Definition: switch_core.h:1431
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:733
switch_memory_pool_t * pool
uint8_t switch_byte_t
Definition: switch_types.h:256
#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:684
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:293
switch_memory_pool_t * pool
switch_byte_t my_pool
const char *const name
Definition: switch_cJSON.h:250
switch_mutex_t * mutex

◆ switch_ivr_dmachine_destroy()

void switch_ivr_dmachine_destroy ( switch_ivr_dmachine_t **  dmachine)

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

187 {
189 
190  if (!(dmachine && *dmachine)) return;
191 
192  pool = (*dmachine)->pool;
193 
194  switch_core_hash_destroy(&(*dmachine)->binding_hash);
195 
196  if ((*dmachine)->my_pool) {
198  }
199 }
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:642
switch_memory_pool_t * pool
struct fspr_pool_t switch_memory_pool_t

◆ switch_ivr_dmachine_feed()

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

Definition at line 654 of file switch_ivr_async.c.

References switch_ivr_dmachine::cur_digit_len, switch_ivr_dmachine::digits, switch_ivr_dmachine::last_digit_time, switch_ivr_dmachine::max_digit_len, switch_ivr_dmachine::mutex, 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_event(), switch_ivr_sleep(), and switch_ivr_speak_text_handle().

655 {
656  const char *p;
658 
659  if (!zstr(digits)) {
660  status = SWITCH_STATUS_SUCCESS;
661  }
662 
663  for (p = digits; p && *p; p++) {
664  switch_mutex_lock(dmachine->mutex);
665  if (dmachine->cur_digit_len < dmachine->max_digit_len) {
666  switch_status_t istatus;
667  char *e = dmachine->digits + strlen(dmachine->digits);
668 
669  *e++ = *p;
670  *e = '\0';
671  dmachine->cur_digit_len++;
672  switch_mutex_unlock(dmachine->mutex);
673  dmachine->last_digit_time = switch_time_now();
674  if (status == SWITCH_STATUS_SUCCESS && (istatus = switch_ivr_dmachine_ping(dmachine, match)) != SWITCH_STATUS_SUCCESS) {
675  status = istatus;
676  }
677  } else {
678  switch_mutex_unlock(dmachine->mutex);
679  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "dmachine overflow error!\n");
680  status = SWITCH_STATUS_FALSE;
681  }
682  }
683 
684  return status;
685 }
#define SWITCH_CHANNEL_LOG
#define zstr(x)
Definition: switch_utils.h:314
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:313
char digits[DMACHINE_MAX_DIGIT_LEN]
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:308
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:325

◆ switch_ivr_dmachine_get_failed_digits()

const char* switch_ivr_dmachine_get_failed_digits ( switch_ivr_dmachine_t dmachine)

Definition at line 527 of file switch_ivr_async.c.

References switch_ivr_dmachine::last_failed_digits.

528 {
529 
530  return dmachine->last_failed_digits;
531 }
char last_failed_digits[DMACHINE_MAX_DIGIT_LEN]

◆ switch_ivr_dmachine_get_match()

switch_ivr_dmachine_match_t* switch_ivr_dmachine_get_match ( switch_ivr_dmachine_t dmachine)

Definition at line 517 of file switch_ivr_async.c.

References switch_ivr_dmachine::is_match, and switch_ivr_dmachine::match.

518 {
519  if (dmachine->is_match) {
520  dmachine->is_match = 0;
521  return &dmachine->match;
522  }
523 
524  return NULL;
525 }
switch_ivr_dmachine_match_t match
switch_byte_t is_match

◆ switch_ivr_dmachine_get_name()

const char* switch_ivr_dmachine_get_name ( switch_ivr_dmachine_t dmachine)

Definition at line 127 of file switch_ivr_async.c.

References switch_ivr_dmachine::name.

128 {
129  return (const char *) dmachine->name;
130 }

◆ switch_ivr_dmachine_is_parsing()

switch_bool_t switch_ivr_dmachine_is_parsing ( switch_ivr_dmachine_t dmachine)

Definition at line 687 of file switch_ivr_async.c.

References switch_ivr_dmachine::cur_digit_len.

Referenced by switch_ivr_play_file().

688 {
689  return !!dmachine->cur_digit_len;
690 }

◆ switch_ivr_dmachine_last_ping()

switch_status_t switch_ivr_dmachine_last_ping ( switch_ivr_dmachine_t dmachine)

Definition at line 93 of file switch_ivr_async.c.

References switch_ivr_dmachine::last_return.

Referenced by switch_ivr_play_and_collect_input(), and switch_ivr_play_and_detect_speech().

94 {
95  return dmachine->last_return;
96 }
switch_status_t last_return

◆ switch_ivr_dmachine_ping()

switch_status_t switch_ivr_dmachine_ping ( switch_ivr_dmachine_t dmachine,
switch_ivr_dmachine_match_t **  match_p 
)

Definition at line 533 of file switch_ivr_async.c.

References switch_ivr_dmachine_binding::callback, switch_ivr_dmachine::cur_digit_len, switch_ivr_dmachine::digits, DM_MATCH_BOTH, DM_MATCH_EXACT, DM_MATCH_NEGATIVE, DM_MATCH_NEVER, DM_MATCH_NONE, DM_MATCH_POSITIVE, switch_ivr_dmachine::is_match, switch_ivr_dmachine_binding::key, switch_ivr_dmachine::last_failed_digits, switch_ivr_dmachine::last_matching_binding, switch_ivr_dmachine::last_matching_digits, switch_ivr_dmachine::last_return, switch_ivr_dmachine::match, switch_ivr_dmachine::match_callback, switch_ivr_dmachine_match::match_digits, switch_ivr_dmachine_match::match_key, switch_ivr_dmachine::max_digit_len, switch_ivr_dmachine::mutex, switch_ivr_dmachine::nonmatch_callback, switch_ivr_dmachine::pinging, 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, switch_ivr_dmachine_match::type, switch_ivr_dmachine_binding::user_data, switch_ivr_dmachine::user_data, switch_ivr_dmachine_match::user_data, 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_event(), switch_ivr_sleep(), and switch_ivr_speak_text_handle().

534 {
535  switch_bool_t is_timeout = switch_ivr_dmachine_check_timeout(dmachine);
536  dm_match_t is_match = switch_ivr_dmachine_check_match(dmachine, is_timeout);
537  switch_status_t r, s;
538  int clear = 0;
539 
540  if (is_match == DM_MATCH_NEVER) {
541  is_timeout++;
542  }
543 
545  return SWITCH_STATUS_SUCCESS;
546  }
547 
548  if (dmachine->pinging) {
549  switch_mutex_unlock(dmachine->mutex);
550  return SWITCH_STATUS_BREAK;
551  }
552 
553  dmachine->pinging = 1;
554 
555  if (zstr(dmachine->digits) && !is_timeout) {
557  } else if (dmachine->cur_digit_len > dmachine->max_digit_len) {
559  } else if (is_match == DM_MATCH_EXACT || (is_match == DM_MATCH_BOTH && is_timeout)) {
561 
562  dmachine->match.match_digits = dmachine->last_matching_digits;
563  dmachine->match.match_key = dmachine->last_matching_binding->key;
564  dmachine->match.user_data = dmachine->last_matching_binding->user_data;
565 
566  if (match_p) {
567  *match_p = &dmachine->match;
568  }
569 
570  dmachine->is_match = 1;
571 
572  dmachine->match.type = DM_MATCH_POSITIVE;
573 
574  if (dmachine->last_matching_binding->callback) {
575  s = dmachine->last_matching_binding->callback(&dmachine->match);
576 
577  switch(s) {
580  break;
582  break;
583  default:
585  break;
586  }
587  }
588 
589  if (dmachine->match_callback) {
590  dmachine->match.user_data = dmachine->user_data;
591  s = dmachine->match_callback(&dmachine->match);
592 
593  switch(s) {
596  break;
598  break;
599  default:
601  break;
602  }
603 
604  }
605 
606  clear++;
607  } else if (is_timeout) {
609  } else if (is_match == DM_MATCH_NONE && dmachine->cur_digit_len == dmachine->max_digit_len) {
611  } else {
613  }
614 
616  switch_set_string(dmachine->last_failed_digits, dmachine->digits);
617  dmachine->match.match_digits = dmachine->last_failed_digits;
618 
619  dmachine->match.type = DM_MATCH_NEGATIVE;
620 
621  if (dmachine->nonmatch_callback) {
622  dmachine->match.user_data = dmachine->user_data;
623  s = dmachine->nonmatch_callback(&dmachine->match);
624 
625  switch(s) {
628  break;
630  break;
631  default:
633  break;
634  }
635 
636  }
637 
638  clear++;
639  }
640 
641  if (clear) {
642  switch_ivr_dmachine_clear(dmachine);
643  }
644 
645  dmachine->last_return = r;
646 
647  dmachine->pinging = 0;
648 
649  switch_mutex_unlock(dmachine->mutex);
650 
651  return r;
652 }
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:318
static switch_bool_t switch_ivr_dmachine_check_timeout(switch_ivr_dmachine_t *dmachine)
switch_bool_t
Definition: switch_types.h:437
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:314
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:313
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:734
switch_mutex_t * mutex
switch_status_t last_return

◆ switch_ivr_dmachine_set_digit_timeout_ms()

void switch_ivr_dmachine_set_digit_timeout_ms ( switch_ivr_dmachine_t dmachine,
uint32_t  digit_timeout_ms 
)

Definition at line 176 of file switch_ivr_async.c.

References switch_ivr_dmachine::digit_timeout_ms.

177 {
178  dmachine->digit_timeout_ms = digit_timeout_ms;
179 }

◆ switch_ivr_dmachine_set_input_timeout_ms()

void switch_ivr_dmachine_set_input_timeout_ms ( switch_ivr_dmachine_t dmachine,
uint32_t  input_timeout_ms 
)

Definition at line 181 of file switch_ivr_async.c.

References switch_ivr_dmachine::input_timeout_ms.

182 {
183  dmachine->input_timeout_ms = input_timeout_ms;
184 }

◆ switch_ivr_dmachine_set_match_callback()

void switch_ivr_dmachine_set_match_callback ( switch_ivr_dmachine_t dmachine,
switch_ivr_dmachine_callback_t  match_callback 
)

Definition at line 111 of file switch_ivr_async.c.

References switch_ivr_dmachine::match_callback, and switch_assert.

112 {
113 
114  switch_assert(dmachine);
115  dmachine->match_callback = match_callback;
116 
117 }
switch_ivr_dmachine_callback_t match_callback
#define switch_assert(expr)

◆ switch_ivr_dmachine_set_nonmatch_callback()

void switch_ivr_dmachine_set_nonmatch_callback ( switch_ivr_dmachine_t dmachine,
switch_ivr_dmachine_callback_t  nonmatch_callback 
)

Definition at line 119 of file switch_ivr_async.c.

References switch_ivr_dmachine::nonmatch_callback, and switch_assert.

120 {
121 
122  switch_assert(dmachine);
123  dmachine->nonmatch_callback = nonmatch_callback;
124 
125 }
switch_ivr_dmachine_callback_t nonmatch_callback
#define switch_assert(expr)

◆ switch_ivr_dmachine_set_realm()

switch_status_t switch_ivr_dmachine_set_realm ( switch_ivr_dmachine_t dmachine,
const char *  realm 
)

Definition at line 216 of file switch_ivr_async.c.

References switch_ivr_dmachine::binding_hash, switch_ivr_dmachine::name, switch_ivr_dmachine::realm, 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().

217 {
218  dm_binding_head_t *headp = switch_core_hash_find(dmachine->binding_hash, realm);
219 
220  if (headp) {
221  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Digit parser %s: Setting realm to '%s'\n", dmachine->name, realm);
222  dmachine->realm = headp;
223  return SWITCH_STATUS_SUCCESS;
224  }
225 
226  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Digit parser %s: Error Setting realm to '%s'\n", dmachine->name, realm);
227 
228  return SWITCH_STATUS_FALSE;
229 }
#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_ivr_enterprise_orig_and_bridge()

switch_status_t switch_ivr_enterprise_orig_and_bridge ( switch_core_session_t session,
const char *  data,
switch_dial_handle_list_t hl,
switch_call_cause_t cause 
)

Definition at line 4912 of file switch_ivr_originate.c.

References CF_BYPASS_MEDIA_AFTER_BRIDGE, CF_PROXY_MODE, fail, o_bridge_on_dtmf(), SOF_NONE, SWITCH_BYPASS_MEDIA_AFTER_BRIDGE_VARIABLE, switch_channel_cause2str(), switch_channel_get_variable, switch_channel_handle_cause(), SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_flag, switch_channel_set_variable, switch_channel_test_flag(), switch_core_session_get_channel(), switch_core_session_rwunlock(), switch_core_session_strdup, switch_ivr_enterprise_originate(), switch_ivr_multi_threaded_bridge(), switch_ivr_signal_bridge(), SWITCH_LOG_INFO, switch_log_printf(), SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, and switch_true().

4913 {
4914  switch_channel_t *caller_channel = switch_core_session_get_channel(session);
4915  switch_core_session_t *peer_session = NULL;
4917  int fail = 0;
4918 
4919  if ((status = switch_ivr_enterprise_originate(session,
4920  &peer_session,
4921  cause, data, 0, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, hl)) != SWITCH_STATUS_SUCCESS) {
4922  fail = 1;
4923  }
4924 
4925 
4926  if (fail) {
4927  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Originate Failed. Cause: %s\n", switch_channel_cause2str(*cause));
4928 
4929  switch_channel_set_variable(caller_channel, "originate_failed_cause", switch_channel_cause2str(*cause));
4930 
4931  switch_channel_handle_cause(caller_channel, *cause);
4932 
4933  return status;
4934  } else {
4935  switch_channel_t *peer_channel = switch_core_session_get_channel(peer_session);
4936 
4940  }
4941 
4942  if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE)) {
4943  switch_ivr_signal_bridge(session, peer_session);
4944  } else {
4945  char *a_key = (char *) switch_channel_get_variable(caller_channel, "bridge_terminate_key");
4946  char *b_key = (char *) switch_channel_get_variable(peer_channel, "bridge_terminate_key");
4947  int ok = 0;
4949 
4950  if (a_key) {
4951  a_key = switch_core_session_strdup(session, a_key);
4952  ok++;
4953  }
4954  if (b_key) {
4955  b_key = switch_core_session_strdup(session, b_key);
4956  ok++;
4957  }
4958  if (ok) {
4959  func = o_bridge_on_dtmf;
4960  } else {
4961  a_key = NULL;
4962  b_key = NULL;
4963  }
4964 
4965  switch_ivr_multi_threaded_bridge(session, peer_session, func, a_key, b_key);
4966  }
4967 
4968  switch_core_session_rwunlock(peer_session);
4969  }
4970 
4971  return status;
4972 }
static switch_bool_t switch_true(const char *expr)
Evaluate the truthfullness of a string expression.
Definition: switch_utils.h:519
#define SWITCH_CHANNEL_SESSION_LOG(x)
const char * switch_channel_cause2str(_In_ switch_call_cause_t cause)
return a cause string for a given cause
switch_status_t switch_ivr_enterprise_originate(switch_core_session_t *session, switch_core_session_t **bleg, switch_call_cause_t *cause, const char *bridgeto, uint32_t timelimit_sec, const switch_state_handler_table_t *table, const char *cid_name_override, const char *cid_num_override, switch_caller_profile_t *caller_profile_override, switch_event_t *ovars, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause, switch_dial_handle_list_t *hl)
#define fail()
Definition: tone2wav.c:70
uint32_t switch_channel_test_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Test for presence of given flag on a given channel.
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
switch_status_t switch_ivr_multi_threaded_bridge(_In_ switch_core_session_t *session, _In_ switch_core_session_t *peer_session, switch_input_callback_function_t dtmf_callback, void *session_data, void *peer_session_data)
Bridge Audio from one session to another.
#define SWITCH_BYPASS_MEDIA_AFTER_BRIDGE_VARIABLE
Definition: switch_types.h:137
#define switch_channel_get_variable(_c, _v)
static switch_status_t o_bridge_on_dtmf(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen)
switch_status_t(* switch_input_callback_function_t)(switch_core_session_t *session, void *input, switch_input_type_t input_type, void *buf, unsigned int buflen)
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_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&#39;s pool.
Definition: switch_core.h:719
switch_status_t switch_ivr_signal_bridge(switch_core_session_t *session, switch_core_session_t *peer_session)
Bridge Signalling from one session to another.
#define switch_channel_set_variable(_channel, _var, _val)
void switch_channel_handle_cause(switch_channel_t *channel, switch_call_cause_t cause)

◆ switch_ivr_find_bridged_uuid()

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

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

2235 {
2236  switch_core_session_t *rsession;
2238 
2239  switch_assert(uuid);
2240 
2241  if ((rsession = switch_core_session_locate(uuid))) {
2242  switch_channel_t *rchannel = switch_core_session_get_channel(rsession);
2243  const char *brto;
2244 
2246  (brto = switch_channel_get_partner_uuid(rchannel))) {
2247  switch_copy_string(b_uuid, brto, blen);
2248  status = SWITCH_STATUS_SUCCESS;
2249  }
2250  switch_core_session_rwunlock(rsession);
2251  }
2252 
2253  return status;
2254 
2255 }
const char * switch_channel_get_partner_uuid(switch_channel_t *channel)
#define SWITCH_ORIGINATE_SIGNAL_BOND_VARIABLE
Definition: switch_types.h:204
_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&#39;s uuid.
Definition: switch_core.h:932
#define switch_assert(expr)

◆ switch_ivr_get_file_handle()

switch_status_t switch_ivr_get_file_handle ( switch_core_session_t session,
switch_file_handle_t **  fh 
)

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

1215 {
1216  switch_file_handle_t *fhp;
1218 
1219  *fh = NULL;
1221 
1222  if ((fhp = switch_channel_get_private(channel, "__fh"))) {
1223  *fh = fhp;
1224  return SWITCH_STATUS_SUCCESS;
1225  }
1226 
1228 
1229  return SWITCH_STATUS_FALSE;
1230 }
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_ivr_get_say_gender_by_name()

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:474
const char *const name
Definition: switch_cJSON.h:250

◆ switch_ivr_get_say_method_by_name()

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:443
const char *const name
Definition: switch_cJSON.h:250

◆ switch_ivr_get_say_type_by_name()

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:452
const char *const name
Definition: switch_cJSON.h:250
static char * SAY_TYPE_NAMES[]

◆ switch_ivr_insert_file()

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

4174 {
4175  switch_file_handle_t orig_fh = { 0 };
4176  switch_file_handle_t new_fh = { 0 };
4177  switch_codec_implementation_t read_impl = { 0 };
4178  char *tmp_file;
4179  switch_uuid_t uuid;
4180  char uuid_str[SWITCH_UUID_FORMATTED_LENGTH + 1];
4181  int16_t *abuf = NULL;
4182  switch_size_t olen = 0;
4183  int asis = 0;
4185  switch_size_t sample_count = 0;
4186  uint32_t pos = 0;
4187  char *ext;
4188 
4189  switch_uuid_get(&uuid);
4190  switch_uuid_format(uuid_str, &uuid);
4191 
4192  if ((ext = strrchr(file, '.'))) {
4193  ext++;
4194  } else {
4195  ext = "wav";
4196  }
4197 
4198  tmp_file = switch_core_session_sprintf(session, "%s%smsg_%s.%s",
4200 
4201  switch_core_session_get_read_impl(session, &read_impl);
4202 
4203  new_fh.channels = read_impl.number_of_channels;
4204  new_fh.native_rate = read_impl.actual_samples_per_second;
4205 
4206 
4207  if (switch_core_file_open(&new_fh,
4208  tmp_file,
4209  new_fh.channels,
4211  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Failed to open file %s\n", tmp_file);
4212  goto end;
4213  }
4214 
4215 
4216  if (switch_core_file_open(&orig_fh,
4217  file,
4218  new_fh.channels,
4220  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Failed to open file %s\n", file);
4221  goto end;
4222  }
4223 
4224 
4225  switch_zmalloc(abuf, START_SAMPLES * sizeof(*abuf));
4226 
4227  if (switch_test_flag((&orig_fh), SWITCH_FILE_NATIVE)) {
4228  asis = 1;
4229  }
4230 
4231  while (switch_channel_ready(channel)) {
4232  olen = START_SAMPLES;
4233 
4234  if (!asis) {
4235  olen /= 2;
4236  }
4237 
4238  if ((sample_count + olen) > sample_point) {
4239  olen = sample_point - sample_count;
4240  }
4241 
4242  if (!olen || switch_core_file_read(&orig_fh, abuf, &olen) != SWITCH_STATUS_SUCCESS || !olen) {
4243  break;
4244  }
4245 
4246  sample_count += olen;
4247 
4248  switch_core_file_write(&new_fh, abuf, &olen);
4249  }
4250 
4251  switch_core_file_close(&orig_fh);
4252 
4253 
4254  if (switch_core_file_open(&orig_fh,
4255  insert_file,
4256  new_fh.channels,
4258  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Failed to open file %s\n", file);
4259  goto end;
4260  }
4261 
4262 
4263  while (switch_channel_ready(channel)) {
4264  olen = START_SAMPLES;
4265 
4266  if (!asis) {
4267  olen /= 2;
4268  }
4269 
4270  if (switch_core_file_read(&orig_fh, abuf, &olen) != SWITCH_STATUS_SUCCESS || !olen) {
4271  break;
4272  }
4273 
4274  sample_count += olen;
4275 
4276  switch_core_file_write(&new_fh, abuf, &olen);
4277  }
4278 
4279  switch_core_file_close(&orig_fh);
4280 
4281  if (switch_core_file_open(&orig_fh,
4282  file,
4283  new_fh.channels,
4285  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Failed to open file %s\n", file);
4286  goto end;
4287  }
4288 
4289  pos = 0;
4290  switch_core_file_seek(&orig_fh, &pos, sample_point, SEEK_SET);
4291 
4292  while (switch_channel_ready(channel)) {
4293  olen = START_SAMPLES;
4294 
4295  if (!asis) {
4296  olen /= 2;
4297  }
4298 
4299  if (switch_core_file_read(&orig_fh, abuf, &olen) != SWITCH_STATUS_SUCCESS || !olen) {
4300  break;
4301  }
4302 
4303  sample_count += olen;
4304 
4305  switch_core_file_write(&new_fh, abuf, &olen);
4306  }
4307 
4308  end:
4309 
4310  if (switch_test_flag((&orig_fh), SWITCH_FILE_OPEN)) {
4311  switch_core_file_close(&orig_fh);
4312  }
4313 
4314  if (switch_test_flag((&new_fh), SWITCH_FILE_OPEN)) {
4315  switch_core_file_close(&new_fh);
4316  }
4317 
4318  switch_file_rename(tmp_file, file, switch_core_session_get_pool(session));
4319  unlink(tmp_file);
4320 
4321  switch_safe_free(abuf);
4322 
4323  return SWITCH_STATUS_SUCCESS;
4324 }
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:1963
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:4171
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:447
#define SWITCH_PATH_SEPARATOR
Definition: switch_types.h:124
#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:885
uintptr_t switch_size_t
switch_directories SWITCH_GLOBAL_dirs
Definition: switch_core.c:82
void switch_uuid_format(char *buffer, const switch_uuid_t *uuid)
Definition: switch_apr.c:1140
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:1152
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:693
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

◆ switch_ivr_intercept_session()

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

Definition at line 2257 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_set_variable_partner, switch_channel_test_flag(), switch_core_session_get_channel(), switch_core_session_get_uuid(), switch_core_session_locate, switch_core_session_rwunlock(), switch_core_session_strdup, SWITCH_FALSE, switch_ivr_find_bridged_uuid(), switch_ivr_uuid_bridge(), SWITCH_LOG_DEBUG, switch_log_printf(), SWITCH_SIGNAL_BOND_VARIABLE, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_true(), SWITCH_UUID_FORMATTED_LENGTH, and zstr.

2258 {
2259  switch_core_session_t *rsession, *bsession = NULL;
2260  switch_channel_t *channel, *rchannel, *bchannel = NULL;
2261  const char *buuid, *var;
2262  char brto[SWITCH_UUID_FORMATTED_LENGTH + 1] = "";
2264 
2265  if (bleg) {
2266  if (switch_ivr_find_bridged_uuid(uuid, brto, sizeof(brto)) == SWITCH_STATUS_SUCCESS) {
2267  uuid = switch_core_session_strdup(session, brto);
2268  } else {
2269  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "no uuid bridged to %s\n", uuid);
2270  return status;
2271  }
2272  }
2273 
2274  if (zstr(uuid) || !(rsession = switch_core_session_locate(uuid))) {
2275  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "no uuid %s\n", uuid);
2276  return status;
2277  }
2278 
2279  channel = switch_core_session_get_channel(session);
2280  rchannel = switch_core_session_get_channel(rsession);
2281  buuid = switch_channel_get_partner_uuid(rchannel);
2282 
2283  if (zstr(buuid) || !strcasecmp(buuid, switch_core_session_get_uuid(session))) {
2284  buuid = NULL;
2285  }
2286 
2287  if ((var = switch_channel_get_variable(channel, "intercept_unbridged_only")) && switch_true(var)) {
2288  if ((switch_channel_test_flag(rchannel, CF_BRIDGED))) {
2289  switch_core_session_rwunlock(rsession);
2290  return status;
2291  }
2292  }
2293 
2294  if ((var = switch_channel_get_variable(channel, "intercept_unanswered_only")) && switch_true(var)) {
2295  if ((switch_channel_test_flag(rchannel, CF_ANSWERED))) {
2296  switch_core_session_rwunlock(rsession);
2297  return status;
2298  }
2299  }
2300 
2301  switch_channel_answer(channel);
2302 
2303  if (!zstr(buuid)) {
2304  if ((bsession = switch_core_session_locate(buuid))) {
2305  bchannel = switch_core_session_get_channel(bsession);
2307  }
2308  }
2309 
2310  if (!switch_channel_test_flag(rchannel, CF_ANSWERED)) {
2311  switch_channel_answer(rchannel);
2312  }
2313 
2315 
2317  switch_channel_set_state(rchannel, CS_PARK);
2318 
2319  if (bchannel) {
2320  switch_channel_set_variable(bchannel, "park_after_bridge", "true");
2321  }
2322 
2323  if ((var = switch_channel_get_variable(channel, "intercept_pre_bond")) && switch_true(var)) {
2326  }
2327 
2329  status = switch_ivr_uuid_bridge(switch_core_session_get_uuid(session), uuid);
2330  switch_core_session_rwunlock(rsession);
2331 
2332  if (bsession) {
2334  switch_core_session_rwunlock(bsession);
2335  }
2336 
2337  return status;
2338 
2339 }
#define switch_channel_hangup(channel, hangup_cause)
Hangup a channel flagging it&#39;s state machine to end.
#define switch_channel_answer(channel)
Answer a channel (initiate/acknowledge a successful connection)
static switch_bool_t switch_true(const char *expr)
Evaluate the truthfullness of a string expression.
Definition: switch_utils.h:519
#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.
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:314
_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)
#define switch_channel_set_variable_partner(_channel, _var, _val)
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.
switch_status_t
Common return values.
#define SWITCH_SIGNAL_BOND_VARIABLE
Definition: switch_types.h:203
#define switch_core_session_locate(uuid_str)
Locate a session based on it&#39;s uuid.
Definition: switch_core.h:932
#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&#39;s pool.
Definition: switch_core.h:719
#define switch_channel_set_variable(_channel, _var, _val)
#define SWITCH_UUID_FORMATTED_LENGTH
Definition: switch_apr.h:545

◆ switch_ivr_kill_uuid()

switch_status_t switch_ivr_kill_uuid ( const char *  uuid,
switch_call_cause_t  cause 
)

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

4405 {
4407 
4408  if (zstr(uuid) || !(session = switch_core_session_locate(uuid))) {
4409  return SWITCH_STATUS_FALSE;
4410  } else {
4412  switch_channel_hangup(channel, cause);
4414  return SWITCH_STATUS_SUCCESS;
4415  }
4416 }
#define switch_channel_hangup(channel, hangup_cause)
Hangup a channel flagging it&#39;s state machine to end.
switch_core_session_t * session
#define zstr(x)
Definition: switch_utils.h:314
_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&#39;s uuid.
Definition: switch_core.h:932

◆ switch_ivr_menu_bind_action()

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 245 of file switch_ivr_menu.c.

References actions, switch_ivr_menu_action::arg, switch_ivr_menu_action::bind, inlen, switch_ivr_menu_action::ivr_action, switch_ivr_menu_action::next, pool, 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().

246 {
247  switch_ivr_menu_action_t *action, *ap;
248  uint32_t len;
249 
250  if ((action = switch_core_alloc(menu->pool, sizeof(*action)))) {
251  action->bind = switch_core_strdup(menu->pool, bind);
252  action->arg = switch_core_strdup(menu->pool, arg);
253  if (*action->bind == '/') {
254  action->re = 1;
255  } else {
256  len = (uint32_t) strlen(action->bind);
257  if (len > menu->inlen) {
258  menu->inlen = len;
259  }
260  }
261  action->ivr_action = ivr_action;
262 
263  if (menu->actions) {
264  for(ap = menu->actions; ap && ap->next; ap = ap->next);
265  ap->next = action;
266  } else {
267  menu->actions = action;
268  }
269 
270  return SWITCH_STATUS_SUCCESS;
271  }
272 
273  return SWITCH_STATUS_MEMERR;
274 }
#define switch_core_strdup(_pool, _todup)
Copy a string using memory allocation from a given pool.
Definition: switch_core.h:733
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:684
switch_ivr_action_t ivr_action
switch_memory_pool_t * pool
struct switch_ivr_menu_action * next

◆ switch_ivr_menu_bind_function()

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 276 of file switch_ivr_menu.c.

References actions, switch_ivr_menu_action::arg, switch_ivr_menu_action::bind, switch_ivr_menu_action::function, inlen, switch_ivr_menu_action::next, pool, 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().

278 {
279  switch_ivr_menu_action_t *action, *ap;
280  uint32_t len;
281 
282  if ((action = switch_core_alloc(menu->pool, sizeof(*action)))) {
283  action->bind = switch_core_strdup(menu->pool, bind);
284  action->arg = switch_core_strdup(menu->pool, arg);
285 
286  if (*action->bind == '/') {
287  action->re = 1;
288  } else {
289  len = (uint32_t) strlen(action->bind);
290  if (len > menu->inlen) {
291  menu->inlen = len;
292  }
293  }
294 
295  action->function = function;
296 
297  if (menu->actions) {
298  for(ap = menu->actions; ap && ap->next; ap = ap->next);
299  ap->next = action;
300  } else {
301  menu->actions = action;
302  }
303 
304  return SWITCH_STATUS_SUCCESS;
305  }
306 
307  return SWITCH_STATUS_MEMERR;
308 }
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:733
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:684
switch_memory_pool_t * pool
struct switch_ivr_menu_action * next

◆ switch_ivr_menu_execute()

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 451 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, stack_count, switch_assert, 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().

452 {
453  int reps = 0, errs = 0, timeouts = 0, match = 0, running = 1;
454  char *greeting_sound = NULL, *aptr = NULL;
455  char arg[512];
458  switch_ivr_menu_t *menu = NULL;
459  switch_channel_t *channel;
461 
462  switch_assert(stack);
463 
464  if (++stack->stack_count > 12) {
465  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Too many levels of recursion.\n");
467  }
468 
469  if (!session || zstr(name)) {
470  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid menu context\n");
472  }
473 
474  channel = switch_core_session_get_channel(session);
475 
476  if (!(menu = switch_ivr_menu_find(stack, name))) {
477  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid Menu!\n");
479  }
480 
481  if (!zstr(menu->tts_engine) && !zstr(menu->tts_voice)) {
482  switch_channel_set_variable(channel, "tts_engine", menu->tts_engine);
483  switch_channel_set_variable(channel, "tts_voice", menu->tts_voice);
484  }
485 
486  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Executing IVR menu %s\n", menu->name);
487  switch_channel_set_variable(channel, "ivr_menu_status", "success");
488 
489  ivr_send_event(session, MENU_EVENT_ENTER, menu);
490 
491  if (!zstr(menu->pin)) {
492  char digit_buffer[128] = "";
493  char *digits_regex = switch_core_session_sprintf(session, "^%s$", menu->pin);
494 
495  if (switch_play_and_get_digits(session, (uint32_t)strlen(menu->pin), (uint32_t)strlen(menu->pin), 3, 3000, "#",
496  menu->prompt_pin_file, menu->bad_pin_file, NULL, digit_buffer, sizeof(digit_buffer),
497  digits_regex, 10000, NULL) != SWITCH_STATUS_SUCCESS) {
499  }
500  }
501 
502 
503  for (reps = 0; running && status == SWITCH_STATUS_SUCCESS; reps++) {
504  if (!switch_channel_ready(channel)) {
505  break;
506  }
507  if (errs == menu->max_failures) {
508  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Maximum failures\n");
509  switch_channel_set_variable(channel, "ivr_menu_status", "failure");
510  if (!zstr(menu->exec_on_max_fail)) {
511  exec_app(session, menu->exec_on_max_fail);
512  }
513  break;
514  }
515  if (timeouts == menu->max_timeouts) {
516  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Maximum timeouts\n");
517  switch_channel_set_variable(channel, "ivr_menu_status", "timeout");
518  if (!zstr(menu->exec_on_max_timeout)) {
519  exec_app(session, menu->exec_on_max_timeout);
520  }
521  break;
522  }
523 
524  if (reps > 0 && menu->short_greeting_sound) {
525  greeting_sound = menu->short_greeting_sound;
526  } else {
527  greeting_sound = menu->greeting_sound;
528  }
529 
530  match = 0;
531  aptr = NULL;
532 
533  memset(arg, 0, sizeof(arg));
534 
535  memset(menu->buf, 0, menu->inlen + 1);
536 
537  if (play_and_collect(session, menu, greeting_sound, menu->inlen) == SWITCH_STATUS_TIMEOUT && *menu->buf == '\0') {
538  timeouts++;
539  continue;
540  }
541 
542  if (*menu->buf != '\0') {
543 
544  for (ap = menu->actions; ap; ap = ap->next) {
545  int ok = 0;
546  char substituted[1024];
547  char *use_arg = ap->arg;
548 
549  if (!zstr(menu->tts_engine) && !zstr(menu->tts_voice)) {
550  switch_channel_set_variable(channel, "tts_engine", menu->tts_engine);
551  switch_channel_set_variable(channel, "tts_voice", menu->tts_voice);
552  }
553 
554  if (ap->re) {
555  switch_regex_t *re = NULL;
556  int ovector[30];
557 
558  if ((ok = switch_regex_perform(menu->buf, ap->bind, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
559  switch_perform_substitution(re, ok, ap->arg, menu->buf, substituted, sizeof(substituted), ovector);
560  use_arg = substituted;
561  }
562  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "action regex [%s] [%s] [%d]\n", menu->buf, ap->bind, ok);
563 
565  } else {
566  ok = !strcmp(menu->buf, ap->bind);
567  }
568 
569  if (ok) {
570  match++;
571  errs = 0;
572  if (ap->function) {
574  "IVR function on menu '%s' matched '%s' param '%s'\n", menu->name, menu->buf, use_arg);
575  todo = ap->function(menu, use_arg, arg, sizeof(arg), obj);
576  aptr = arg;
577  } else {
578  todo = ap->ivr_action;
579  aptr = use_arg;
581  "IVR action on menu '%s' matched '%s' param '%s'\n", menu->name, menu->buf, aptr);
582  }
583 
584  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "switch_ivr_menu_execute todo=[%d]\n", todo);
585 
586  switch (todo) {
588  status = SWITCH_STATUS_FALSE;
589  break;
591  status = switch_ivr_play_file(session, NULL, aptr, NULL);
592  break;
594  if (!strcmp(aptr, menu->name)) {
595  status = SWITCH_STATUS_SUCCESS;
596  } else {
597  reps = -1;
598  ivr_send_event(session, MENU_EVENT_EXIT, menu);
599  status = switch_ivr_menu_execute(session, stack, aptr, obj);
600  ivr_send_event(session, MENU_EVENT_ENTER, menu);
601  }
602  break;
604  {
605  switch_application_interface_t *application_interface;
606  char *app_name;
607  char *app_arg = NULL;
608 
609  status = SWITCH_STATUS_FALSE;
610 
611  if (!zstr(aptr)) {
612  app_name = switch_core_session_strdup(session, aptr);
613  if ((app_arg = strchr(app_name, ' '))) {
614  *app_arg++ = '\0';
615  }
616 
617  if ((application_interface = switch_loadable_module_get_application_interface(app_name))) {
618  if (!zstr(menu->transfer_sound) && !strcmp(app_name, "transfer")) {
619  play_and_collect(session, menu, menu->transfer_sound, 0);
620  }
621 
622  switch_core_session_exec(session, application_interface, app_arg);
623  UNPROTECT_INTERFACE(application_interface);
624  status = SWITCH_STATUS_SUCCESS;
625  }
626  }
627  }
628  break;
630  running = 0;
631  status = SWITCH_STATUS_SUCCESS;
632  break;
635  status = SWITCH_STATUS_BREAK;
636  break;
638  status = SWITCH_STATUS_SUCCESS;
639  break;
640  default:
642  break;
643  }
644  }
645  }
646 
647  if (switch_test_flag(menu, SWITCH_IVR_MENU_FLAG_STACK)) { /* top level */
648  if (switch_test_flag(stack, SWITCH_IVR_MENU_FLAG_FALLTOMAIN)) { /* catch the fallback and recover */
650  status = SWITCH_STATUS_SUCCESS;
651  running = 1;
652  continue;
653  }
654  }
655  }
656  if (!match) {
657  if (*menu->buf) {
658  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "IVR menu '%s' caught invalid input '%s'\n", menu->name,
659  menu->buf);
660  if (menu->invalid_sound) {
661  play_and_collect(session, menu, menu->invalid_sound, 0);
662  }
663  } else {
664  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "IVR menu '%s' no input detected\n", menu->name);
665  }
666  errs++;
667 
668  /* breaks are ok too */
669  if (SWITCH_STATUS_IS_BREAK(status)) {
670  status = SWITCH_STATUS_SUCCESS;
671  }
672  }
673  }
674 
675  if (stack->stack_count == 1) {
676  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "exit-sound '%s'\n", menu->exit_sound);
677  if (!zstr(menu->exit_sound)) {
678  status = play_and_collect(session, menu, menu->exit_sound, 0);
679  }
680  }
681 
682  end:
683 
684  stack->stack_count--;
685 
686  if (menu) {
687  ivr_send_event(session, MENU_EVENT_EXIT, menu);
688  }
689 
690  return status;
691 }
#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:700
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&#39;t give digits i...
#define SWITCH_STATUS_IS_BREAK(x)
Definition: switch_utils.h:633
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:314
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:724
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&#39;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:287
char * exec_on_max_timeout
switch_ivr_action_t
Definition: switch_ivr.h:806
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:693
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
const char *const name
Definition: switch_cJSON.h:250
#define switch_core_session_strdup(_session, _todup)
Copy a string using memory allocation from a session&#39;s pool.
Definition: switch_core.h:719
struct switch_ivr_menu_action * next
#define switch_assert(expr)
#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_ivr_menu_init()

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, digit_len, exit_sound, greeting_sound, inlen, inter_timeout, invalid_sound, max_failures, max_timeouts, name, 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) {
146  }
147 
149  return SWITCH_STATUS_MEMERR;
150  }
151 
152  menu->pool = pool;
153 
154  if (!confirm_attempts) {
155  confirm_attempts = 3;
156  }
157 
158  if (!inter_timeout) {
159  inter_timeout = timeout / 2;
160  }
161 
162  if (!zstr(name)) {
163  menu->name = switch_core_strdup(menu->pool, name);
164  }
165 
166  if (!zstr(greeting_sound)) {
167  menu->greeting_sound = switch_core_strdup(menu->pool, greeting_sound);
168  }
169 
170  if (!zstr(short_greeting_sound)) {
171  menu->short_greeting_sound = switch_core_strdup(menu->pool, short_greeting_sound);
172  }
173 
174  if (!zstr(invalid_sound)) {
175  menu->invalid_sound = switch_core_strdup(menu->pool, invalid_sound);
176  }
177 
178  if (!zstr(transfer_sound)) {
179  menu->transfer_sound = switch_core_strdup(menu->pool, transfer_sound);
180  }
181 
182  if (!zstr(exit_sound)) {
183  menu->exit_sound = switch_core_strdup(menu->pool, exit_sound);
184  }
185 
186  if (!zstr(confirm_key)) {
187  menu->confirm_key = switch_core_strdup(menu->pool, confirm_key);
188  }
189 
190  if (!zstr(confirm_macro)) {
191  menu->confirm_macro = switch_core_strdup(menu->pool, confirm_macro);
192  }
193 
194  if (!zstr(tts_engine)) {
195  menu->tts_engine = switch_core_strdup(menu->pool, tts_engine);
196  }
197 
198  if (!zstr(tts_voice)) {
199  menu->tts_voice = switch_core_strdup(menu->pool, tts_voice);
200  }
201 
202  menu->confirm_attempts = confirm_attempts;
203 
204  menu->inlen = digit_len;
205 
206  if (max_failures > 0) {
207  menu->max_failures = max_failures;
208  } else {
209  menu->max_failures = 3;
210  }
211 
212  if (max_timeouts > 0) {
213  menu->max_timeouts = max_timeouts;
214  } else {
215  menu->max_timeouts = 3;
216  }
217 
218  menu->timeout = timeout;
219 
220  menu->inter_timeout = inter_timeout;
221 
222  menu->actions = NULL;
223 
224  if (newpool) {
226  }
227 
228  if (menu->timeout <= 0) {
229  menu->timeout = 10000;
230  }
231 
232  if (main) {
233  switch_ivr_menu_stack_add(&main, menu);
234  } else {
236  }
237 
238  menu->buf = switch_core_alloc(menu->pool, 1024);
239 
240  *new_menu = menu;
241 
242  return SWITCH_STATUS_SUCCESS;
243 }
#define switch_core_new_memory_pool(p)
Create a new sub memory pool from the core&#39;s master pool.
Definition: switch_core.h:633
#define switch_set_flag(obj, flag)
Set a flag on an arbitrary object.
Definition: switch_utils.h:700
#define SWITCH_CHANNEL_LOG
#define switch_core_strdup(_pool, _todup)
Copy a string using memory allocation from a given pool.
Definition: switch_core.h:733
#define switch_core_destroy_memory_pool(p)
Returns a subpool back to the main pool.
Definition: switch_core.h:642
switch_memory_pool_t * pool
struct switch_ivr_menu_action * actions
#define zstr(x)
Definition: switch_utils.h:314
switch_size_t inlen
#define switch_core_alloc(_pool, _mem)
Allocate memory directly from a memory pool.
Definition: switch_core.h:684
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)
const char *const name
Definition: switch_cJSON.h:250
char * short_greeting_sound

◆ switch_ivr_menu_stack_free()

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

311 {
313 
314  if (stack != NULL && stack->pool != NULL) {
317  switch_memory_pool_t *pool = stack->pool;
318  status = switch_core_destroy_memory_pool(&pool);
319  } else {
320  status = SWITCH_STATUS_SUCCESS;
321  }
322  }
323 
324  return status;
325 }
#define switch_core_destroy_memory_pool(p)
Returns a subpool back to the main pool.
Definition: switch_core.h:642
switch_memory_pool_t * pool
switch_status_t
Common return values.
switch_memory_pool_t * pool
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:693
struct fspr_pool_t switch_memory_pool_t

◆ switch_ivr_menu_stack_xml_add_custom()

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 843 of file switch_ivr_menu.c.

References switch_ivr_menu_stack_xml_add().

845 {
846  return switch_ivr_menu_stack_xml_add(xml_menu_ctx, name, -1, function);
847 }
const char *const name
Definition: switch_cJSON.h:250
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_ivr_menu_stack_xml_build()

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 849 of file switch_ivr_menu.c.

References switch_ivr_menu_xml_map::action, switch_ivr_menu_xml_ctx::autocreated, bad_pin_file, confirm_attempts, confirm_key, confirm_macro, digit_len, exec_on_max_fail, exec_on_max_timeout, exit_sound, switch_ivr_menu_xml_map::function, inter_timeout, invalid_sound, is_valid_action(), switch_ivr_menu_xml_ctx::map, max_failures, max_timeouts, switch_ivr_menu_xml_map::name, switch_xml::next, switch_ivr_menu_xml_map::next, pin, pool, switch_ivr_menu_xml_ctx::pool, prompt_pin_file, switch_assert, 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(), timeout, transfer_sound, tts_engine, tts_voice, and zstr.

851 {
853 
854  if (xml_menu_ctx != NULL && menu_stack != NULL && xml_menu != NULL) {
855  const char *menu_name = switch_xml_attr_soft(xml_menu, "name"); /* if the attr doesn't exist, return "" */
856  const char *greet_long = switch_xml_attr(xml_menu, "greet-long"); /* if the attr doesn't exist, return NULL */
857  const char *greet_short = switch_xml_attr(xml_menu, "greet-short"); /* if the attr doesn't exist, return NULL */
858  const char *invalid_sound = switch_xml_attr(xml_menu, "invalid-sound"); /* if the attr doesn't exist, return NULL */
859  const char *exit_sound = switch_xml_attr(xml_menu, "exit-sound"); /* if the attr doesn't exist, return NULL */
860  const char *transfer_sound = switch_xml_attr(xml_menu, "transfer-sound"); /* if the attr doesn't exist, return NULL */
861  const char *timeout = switch_xml_attr_soft(xml_menu, "timeout"); /* if the attr doesn't exist, return "" */
862  const char *max_failures = switch_xml_attr_soft(xml_menu, "max-failures"); /* if the attr doesn't exist, return "" */
863  const char *max_timeouts = switch_xml_attr_soft(xml_menu, "max-timeouts");
864  const char *exec_on_max_fail = switch_xml_attr(xml_menu, "exec-on-max-failures");
865  const char *exec_on_max_timeout = switch_xml_attr(xml_menu, "exec-on-max-timeouts");
866  const char *confirm_macro = switch_xml_attr(xml_menu, "confirm-macro");
867  const char *confirm_key = switch_xml_attr(xml_menu, "confirm-key");
868  const char *tts_engine = switch_xml_attr(xml_menu, "tts-engine");
869  const char *tts_voice = switch_xml_attr(xml_menu, "tts-voice");
870  const char *confirm_attempts = switch_xml_attr_soft(xml_menu, "confirm-attempts");
871  const char *digit_len = switch_xml_attr_soft(xml_menu, "digit-len");
872  const char *inter_timeout = switch_xml_attr_soft(xml_menu, "inter-digit-timeout");
873  const char *pin = switch_xml_attr_soft(xml_menu, "pin");
874  const char *prompt_pin_file = switch_xml_attr_soft(xml_menu, "pin-file");
875  const char *bad_pin_file = switch_xml_attr_soft(xml_menu, "bad-pin-file");
876 
877  switch_ivr_menu_t *menu = NULL;
878 
879  if (zstr(max_timeouts)) {
880  max_timeouts = max_failures;
881  }
882 
883  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "building menu '%s'\n", menu_name);
884 
885  status = switch_ivr_menu_init(&menu,
886  *menu_stack,
887  menu_name,
888  greet_long,
889  greet_short,
890  invalid_sound,
891  exit_sound,
892  transfer_sound,
893  confirm_macro,
894  confirm_key,
895  tts_engine,
896  tts_voice,
897  atoi(confirm_attempts),
898  atoi(inter_timeout),
899  atoi(digit_len),
900  atoi(timeout),
901  strlen(max_failures) ? atoi(max_failures) : 0, strlen(max_timeouts) ? atoi(max_timeouts) : 0, xml_menu_ctx->pool);
902 
903  switch_assert(menu);
904 
905  if (!zstr(exec_on_max_fail)) {
906  menu->exec_on_max_fail = switch_core_strdup(menu->pool, exec_on_max_fail);
907  }
908 
909  if (!zstr(exec_on_max_timeout)) {
910  menu->exec_on_max_timeout = switch_core_strdup(menu->pool, exec_on_max_timeout);
911  }
912 
913  if (!zstr(pin)) {
914  if (zstr(prompt_pin_file)) {
915  prompt_pin_file = "ivr/ivr-please_enter_pin_followed_by_pound.wav";
916  }
917  if (zstr(bad_pin_file)) {
918  bad_pin_file = "conference/conf-bad-pin.wav";
919  }
920  menu->pin = switch_core_strdup(menu->pool, pin);
921  menu->prompt_pin_file = switch_core_strdup(menu->pool, prompt_pin_file);
922  menu->bad_pin_file = switch_core_strdup(menu->pool, bad_pin_file);
923  }
924 
925  /* set the menu_stack for the caller */
926  if (status == SWITCH_STATUS_SUCCESS && *menu_stack == NULL) {
927  *menu_stack = menu;
928 
929  if (xml_menu_ctx->autocreated) {
931  }
932  }
933 
934  if (status == SWITCH_STATUS_SUCCESS) {
935  switch_xml_t xml_kvp;
936 
937  /* build menu entries */
938  for (xml_kvp = switch_xml_child(xml_menu, "entry"); xml_kvp != NULL && status == SWITCH_STATUS_SUCCESS; xml_kvp = xml_kvp->next) {
939  const char *action = switch_xml_attr(xml_kvp, "action");
940  const char *digits = switch_xml_attr(xml_kvp, "digits");
941  const char *param = switch_xml_attr_soft(xml_kvp, "param");
942 
943  if (is_valid_action(action) && !zstr(digits)) {
944  switch_ivr_menu_xml_map_t *xml_map = xml_menu_ctx->map;
945  int found = 0;
946 
947  /* find and appropriate xml handler */
948  while (xml_map != NULL && !found) {
949  if (!(found = (strcasecmp(xml_map->name, action) == 0))) {
950  xml_map = xml_map->next;
951  }
952  }
953 
954  if (found && xml_map != NULL) {
955  /* do we need to build a new sub-menu ? */
956  if (xml_map->action == SWITCH_IVR_ACTION_EXECMENU && switch_ivr_menu_find(*menu_stack, param) == NULL) {
957  if ((xml_menu = switch_xml_find_child(xml_menus, "menu", "name", param)) != NULL) {
958  status = switch_ivr_menu_stack_xml_build(xml_menu_ctx, menu_stack, xml_menus, xml_menu);
959  }
960  }
961  /* finally bind the menu entry */
962  if (status == SWITCH_STATUS_SUCCESS) {
963  if (xml_map->function != NULL) {
965  "binding menu caller control '%s'/'%s' to '%s'\n", xml_map->name, param, digits);
966  status = switch_ivr_menu_bind_function(menu, xml_map->function, param, digits);
967  } else {
968  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "binding menu action '%s' to '%s'\n", xml_map->name, digits);
969  status = switch_ivr_menu_bind_action(menu, xml_map->action, param, digits);
970  }
971  }
972  }
973  } else {
974  status = SWITCH_STATUS_FALSE;
975  }
976  }
977  }
978  }
979 
980  if (status != SWITCH_STATUS_SUCCESS) {
981  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to build xml menu\n");
982  }
983 
984  return status;
985 }
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:700
#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 &#39;childname&#39; with an attribute &#39;attrname&#39; which equals &#39;value&#39; ...
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:733
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:79
#define zstr(x)
Definition: switch_utils.h:314
switch_xml_t next
Definition: switch_xml.h:91
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.
#define switch_assert(expr)
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_ivr_menu_stack_xml_init()

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 808 of file switch_ivr_menu.c.

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

809 {
811  int autocreated = 0;
812 
813  /* build a memory pool ? */
814  if (pool == NULL) {
816  autocreated = 1;
817  }
818  /* allocate the xml context */
819  if (xml_menu_ctx != NULL && pool != NULL) {
820  *xml_menu_ctx = switch_core_alloc(pool, sizeof(switch_ivr_menu_xml_ctx_t));
821  if (*xml_menu_ctx != NULL) {
822  (*xml_menu_ctx)->pool = pool;
823  (*xml_menu_ctx)->autocreated = autocreated;
824  (*xml_menu_ctx)->map = NULL;
825  status = SWITCH_STATUS_SUCCESS;
826  } else {
827  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unable to alloc xml_ctx\n");
828  status = SWITCH_STATUS_FALSE;
829  }
830  }
831  /* build the standard/default xml menu handler mappings */
832  if (status == SWITCH_STATUS_SUCCESS && xml_menu_ctx != NULL && *xml_menu_ctx != NULL) {
833  int i;
834 
835  for (i = 0; iam[i].name && status == SWITCH_STATUS_SUCCESS; i++) {
836  status = switch_ivr_menu_stack_xml_add(*xml_menu_ctx, iam[i].name, iam[i].action, NULL);
837  }
838  }
839 
840  return status;
841 }
#define switch_core_new_memory_pool(p)
Create a new sub memory pool from the core&#39;s master pool.
Definition: switch_core.h:633
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:684
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.
const char *const name
Definition: switch_cJSON.h:250
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_ivr_menu_str2action()

switch_status_t switch_ivr_menu_str2action ( const char *  action_name,
switch_ivr_action_t action 
)

Definition at line 768 of file switch_ivr_menu.c.

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

Referenced by IVRMenu::bindAction().

769 {
770  int i;
771 
772  if (!zstr(action_name)) {
773  for (i = 0;; i++) {
774  if (!iam[i].name) {
775  break;
776  }
777 
778  if (!strcasecmp(iam[i].name, action_name)) {
779  *action = iam[i].action;
780  return SWITCH_STATUS_SUCCESS;
781  }
782  }
783  }
784 
785  return SWITCH_STATUS_FALSE;
786 }
#define zstr(x)
Definition: switch_utils.h:314
switch_ivr_action_t action
static struct iam_s iam[]
const char *const name
Definition: switch_cJSON.h:250

◆ switch_ivr_orig_and_bridge()

switch_status_t switch_ivr_orig_and_bridge ( switch_core_session_t session,
const char *  data,
switch_dial_handle_t dh,
switch_call_cause_t cause 
)

Definition at line 4975 of file switch_ivr_originate.c.

References CF_BYPASS_MEDIA_AFTER_BRIDGE, CF_PROXY_MODE, fail, o_bridge_on_dtmf(), SOF_NONE, SWITCH_BYPASS_MEDIA_AFTER_BRIDGE_VARIABLE, switch_channel_cause2str(), switch_channel_get_variable, switch_channel_handle_cause(), SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_flag, switch_channel_set_variable, switch_channel_test_flag(), switch_core_session_get_channel(), switch_core_session_rwunlock(), switch_core_session_strdup, switch_ivr_multi_threaded_bridge(), switch_ivr_originate(), switch_ivr_signal_bridge(), SWITCH_LOG_INFO, switch_log_printf(), SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, and switch_true().

4976 {
4977  switch_channel_t *caller_channel = switch_core_session_get_channel(session);
4978  switch_core_session_t *peer_session = NULL;
4980  int fail = 0;
4981 
4982  if ((status = switch_ivr_originate(session,
4983  &peer_session,
4984  cause, data, 0, NULL, NULL, NULL, NULL, NULL, SOF_NONE, NULL, dh)) != SWITCH_STATUS_SUCCESS) {
4985  fail = 1;
4986  }
4987 
4988 
4989  if (fail) {
4990  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Originate Failed. Cause: %s\n", switch_channel_cause2str(*cause));
4991 
4992  switch_channel_set_variable(caller_channel, "originate_failed_cause", switch_channel_cause2str(*cause));
4993 
4994  switch_channel_handle_cause(caller_channel, *cause);
4995 
4996  return status;
4997  } else {
4998  switch_channel_t *peer_channel = switch_core_session_get_channel(peer_session);
4999 
5003  }
5004 
5005  if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE)) {
5006  switch_ivr_signal_bridge(session, peer_session);
5007  } else {
5008  char *a_key = (char *) switch_channel_get_variable(caller_channel, "bridge_terminate_key");
5009  char *b_key = (char *) switch_channel_get_variable(peer_channel, "bridge_terminate_key");
5010  int ok = 0;
5012 
5013  if (a_key) {
5014  a_key = switch_core_session_strdup(session, a_key);
5015  ok++;
5016  }
5017  if (b_key) {
5018  b_key = switch_core_session_strdup(session, b_key);
5019  ok++;
5020  }
5021  if (ok) {
5022  func = o_bridge_on_dtmf;
5023  } else {
5024  a_key = NULL;
5025  b_key = NULL;
5026  }
5027 
5028  switch_ivr_multi_threaded_bridge(session, peer_session, func, a_key, b_key);
5029  }
5030 
5031  switch_core_session_rwunlock(peer_session);
5032  }
5033 
5034  return status;
5035 }
static switch_bool_t switch_true(const char *expr)
Evaluate the truthfullness of a string expression.
Definition: switch_utils.h:519
#define SWITCH_CHANNEL_SESSION_LOG(x)
const char * switch_channel_cause2str(_In_ switch_call_cause_t cause)
return a cause string for a given cause
#define fail()
Definition: tone2wav.c:70
uint32_t switch_channel_test_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Test for presence of given flag on a given channel.
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
switch_status_t switch_ivr_multi_threaded_bridge(_In_ switch_core_session_t *session, _In_ switch_core_session_t *peer_session, switch_input_callback_function_t dtmf_callback, void *session_data, void *peer_session_data)
Bridge Audio from one session to another.
#define SWITCH_BYPASS_MEDIA_AFTER_BRIDGE_VARIABLE
Definition: switch_types.h:137
#define switch_channel_get_variable(_c, _v)
static switch_status_t o_bridge_on_dtmf(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen)
switch_status_t(* switch_input_callback_function_t)(switch_core_session_t *session, void *input, switch_input_type_t input_type, void *buf, unsigned int buflen)
void switch_core_session_rwunlock(_In_ switch_core_session_t *session)
Unlock a read or write lock on as given session.
switch_status_t switch_ivr_originate(switch_core_session_t *session, switch_core_session_t **bleg, switch_call_cause_t *cause, const char *bridgeto, uint32_t timelimit_sec, const switch_state_handler_table_t *table, const char *cid_name_override, const char *cid_num_override, switch_caller_profile_t *caller_profile_override, switch_event_t *ovars, switch_originate_flag_t flags, switch_call_cause_t *cancel_cause, switch_dial_handle_t *dh)
Make an outgoing call.
switch_status_t
Common return values.
#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&#39;s pool.
Definition: switch_core.h:719
switch_status_t switch_ivr_signal_bridge(switch_core_session_t *session, switch_core_session_t *peer_session)
Bridge Signalling from one session to another.
#define switch_channel_set_variable(_channel, _var, _val)
void switch_channel_handle_cause(switch_channel_t *channel, switch_call_cause_t cause)

◆ switch_ivr_park_session()

void switch_ivr_park_session ( switch_core_session_t session)

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

3572 {
3576 
3577 }
#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_ivr_phrase_macro_event()

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, name, 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_is_number(), 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_normalize_volume_granular, 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, switch_file_handle::volgranular, 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  char *volume_str = (char *) switch_xml_attr_soft(action, "volume");
255  switch_file_handle_t pfh = { 0 };
256  if (volume_str && switch_is_number(volume_str)) {
257  int32_t volume = atoi(volume_str);
258 
260  pfh.volgranular = volume;
261 
262  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Setting playback volume to %d\n", pfh.volgranular);
263  }
264  status = switch_ivr_play_file(session, &pfh, odata, args);
265  } else if (!strcasecmp(func, "phrase")) {
266  char *name = (char *) switch_xml_attr_soft(action, "phrase");
267  status = switch_ivr_phrase_macro(session, name, odata, chan_lang, args);
268  } else if (!strcasecmp(func, "break")) {
269  done = 1; /* don't break or we leak memory */
270  } else if (!strcasecmp(func, "execute")) {
272  char *cmd, *cmd_args;
273  status = SWITCH_STATUS_FALSE;
274 
275  cmd = switch_core_session_strdup(session, odata);
276  cmd_args = switch_separate_paren_args(cmd);
277 
278  if (!cmd_args) {
279  cmd_args = "";
280  }
281 
282  if ((app = switch_loadable_module_get_application_interface(cmd)) != NULL) {
283  status = switch_core_session_exec(session, app, cmd_args);
284  UNPROTECT_INTERFACE(app);
285  } else {
286  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid Application %s\n", cmd);
287  }
288  } else if (!strcasecmp(func, "say")) {
290  if ((si = switch_loadable_module_get_say_interface(module_name))) {
291  char *say_type = (char *) switch_xml_attr_soft(action, "type");
292  char *say_method = (char *) switch_xml_attr_soft(action, "method");
293  char *say_gender = (char *) switch_xml_attr_soft(action, "gender");
294  switch_say_args_t say_args = {0};
295 
296  say_args.type = switch_ivr_get_say_type_by_name(say_type);
297  say_args.method = switch_ivr_get_say_method_by_name(say_method);
298  say_args.gender = switch_ivr_get_say_gender_by_name(say_gender);
299 
300  status = si->say_function(session, odata, &say_args, args);
301  } else {
302  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid SAY Interface [%s]!\n", module_name);
303  }
304  } else if (!strcasecmp(func, "speak-text")) {
305  const char *my_tts_engine = switch_xml_attr(action, "tts-engine");
306  const char *my_tts_voice = switch_xml_attr(action, "tts-voice");
307 
308  if (!my_tts_engine) {
309  my_tts_engine = tts_engine;
310  }
311 
312  if (!my_tts_voice) {
313  my_tts_voice = tts_voice;
314  }
315  if (zstr(tts_engine) || zstr(tts_voice)) {
316  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "TTS is not configured\n");
317  } else {
318  status = switch_ivr_speak_text(session, my_tts_engine, my_tts_voice, odata, args);
319  }
320  }
321 
322  switch_ivr_sleep(session, pause, SWITCH_FALSE, NULL);
323  switch_safe_free(expanded);
324  switch_safe_free(substituted);
325  if (done || status != SWITCH_STATUS_SUCCESS) break;
326  }
327  }
328 
330  switch_safe_free(field_expanded_alloc);
331 
332  if (done || status != SWITCH_STATUS_SUCCESS
333  || (match && do_break && switch_true(do_break))) {
334  break;
335  }
336 
337  input = input->next;
338  }
339 
340  done:
341 
343 
344  if (hint_data) {
345  switch_event_destroy(&hint_data);
346  }
347 
348  if (searched && !matches) {
349  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Macro [%s]: '%s' did not match any patterns\n", macro_name, data);
350  }
351 
352  if (old_sound_prefix) {
353  switch_channel_set_variable(channel, "sound_prefix", old_sound_prefix);
354  }
355  if (local_sound_prefix_enforced == SWITCH_TRUE) {
356  switch_channel_set_variable(channel, "sound_prefix_enforced", NULL);
357  }
358 
359  if (xml) {
360  switch_xml_free(xml);
361  }
362 
363  return status;
364 }
#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
static switch_bool_t switch_true(const char *expr)
Evaluate the truthfullness of a string expression.
Definition: switch_utils.h:519
#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:355
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 &#39;childname&#39; with an attribute &#39;attrname&#39; which equals &#39;value&#39; ...
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:3356
switch_bool_t
Definition: switch_types.h:437
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_bool_t switch_is_number(const char *str)
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:79
struct real_pcre switch_regex_t
Definition: switch_regex.h:43
switch_status_t switch_ivr_speak_text(switch_core_session_t *session, const char *tts_name, const char *voice_name, const char *text, switch_input_args_t *args)
Speak given text with given tts engine.
#define zstr(x)
Definition: switch_utils.h:314
_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_normalize_volume_granular(x)
switch_xml_t next
Definition: switch_xml.h:91
switch_application_interface_t * switch_loadable_module_get_application_interface(const char *name)
Retrieve the application interface by it&#39;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:885
#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:993
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&#39;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:384
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:936
const char *const name
Definition: switch_cJSON.h:250
#define switch_core_session_strdup(_session, _todup)
Copy a string using memory allocation from a session&#39;s pool.
Definition: switch_core.h:719
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_ivr_play_and_collect_input()

switch_status_t switch_ivr_play_and_collect_input ( switch_core_session_t session,
const char *  prompt,
const char *  recognizer_mod_name,
const char *  recognizer_grammar,
int  min_digits,
int  max_digits,
const char *  terminators,
uint32_t  digit_timeout,
cJSON **  recognition_result,
char **  digits_collected,
char *  terminator_collected,
switch_input_args_t args 
)

Play prompt and collect input.

Returns collect status

Parameters
[in]sessionthe current session
Returns
Returns status SWITCH_STATUS_SUCCESS when success SWITCH_STATUS_FALSE when error SWITCH_STATUS_GENERR when error

Definition at line 3411 of file switch_ivr_play_say.c.

References arg_recursion_check_start, arg_recursion_check_stop, switch_input_args_t::buf, switch_input_args_t::buflen, switch_collect_input_state_t::digits, switch_input_args_t::dmachine, switch_input_args_t::input_callback, switch_collect_input_state_t::is_speech, switch_collect_input_state_t::last_digit_time, switch_collect_input_state_t::max_digits, switch_collect_input_state_t::min_digits, switch_collect_input_state_t::original_args, switch_input_args_t::read_frame_callback, switch_collect_input_state_t::recognition_result, switch_channel_get_name(), switch_channel_ready, SWITCH_CHANNEL_SESSION_LOG, switch_clear_flag, switch_collect_input_callback(), SWITCH_COLLECT_INPUT_DIGITS, SWITCH_COLLECT_INPUT_DIGITS_DONE, SWITCH_COLLECT_INPUT_PROMPT, SWITCH_COLLECT_INPUT_SPEECH, SWITCH_COLLECT_INPUT_SPEECH_DONE, switch_core_session_alloc, switch_core_session_get_channel(), SWITCH_FALSE, SWITCH_INT64_T_FMT, switch_ivr_detect_speech(), switch_ivr_detect_speech_start_input_timers(), switch_ivr_dmachine_last_ping(), switch_ivr_pause_detect_speech(), switch_ivr_play_file(), switch_ivr_sleep(), SWITCH_LOG_DEBUG, SWITCH_LOG_INFO, switch_log_printf(), switch_micro_time_now(), switch_set_flag, SWITCH_STATUS_BREAK, SWITCH_STATUS_FALSE, SWITCH_STATUS_GENERR, SWITCH_STATUS_SUCCESS, switch_test_flag, switch_collect_input_state_t::terminator, switch_collect_input_state_t::terminators, switch_input_args_t::user_data, and zstr.

3423 {
3425  switch_input_args_t myargs = { 0 };
3428 
3430 
3431  /* configure digit collection */
3432  if (digit_timeout <= 0) digit_timeout = 5000;
3433  if (min_digits < 0) {
3434  min_digits = 0;
3435  }
3436 
3437  /* check if digit collection is enabled */
3438  if (min_digits > 0) {
3439  if (max_digits < min_digits) {
3440  max_digits = min_digits;
3441  }
3442  if (max_digits > 100) {
3443  max_digits = 100;
3444  }
3445  state.digits = switch_core_session_alloc(session, sizeof(char) * (max_digits + 1));
3447  } else {
3449  }
3450 
3451  state.min_digits = min_digits;
3452  state.max_digits = max_digits;
3453  if (!zstr(terminators)) {
3454  if (!strcasecmp(terminators, "any")) {
3455  state.terminators = "1234567890*#";
3456  } else if (!strcasecmp(terminators, "none")) {
3457  state.terminators = NULL;
3458  } else {
3459  state.terminators = terminators;
3460  }
3461  }
3462 
3463  /* start speech recognition, if enabled */
3464  if (recognizer_grammar && recognizer_mod_name) {
3465  if ((status = switch_ivr_detect_speech(session, recognizer_mod_name, recognizer_grammar, "", NULL, NULL)) != SWITCH_STATUS_SUCCESS) {
3466  /* map SWITCH_STATUS_FALSE to SWITCH_STATUS_GENERR to indicate grammar load failed
3467  SWITCH_STATUS_NOT_INITALIZED will be passed back to indicate ASR resource problem */
3468  if (status == SWITCH_STATUS_FALSE) {
3469  status = SWITCH_STATUS_GENERR;
3470  }
3471  goto done;
3472  }
3474  } else {
3476  }
3477 
3478  /* play the prompt, looking for input result */
3479 
3480  if (args) {
3481  state.original_args = args;
3482  myargs.dmachine = args->dmachine;
3484  myargs.user_data = args->user_data;
3485  }
3486 
3488  myargs.buf = &state;
3489  myargs.buflen = sizeof(state);
3490 
3492  status = switch_ivr_play_file(session, NULL, prompt, &myargs);
3494 
3495  if (args && args->dmachine && switch_ivr_dmachine_last_ping(args->dmachine) != SWITCH_STATUS_SUCCESS) {
3498  status = SWITCH_STATUS_SUCCESS;
3499  }
3500 
3501  if (status != SWITCH_STATUS_BREAK && status != SWITCH_STATUS_SUCCESS) {
3502  status = SWITCH_STATUS_FALSE;
3503  goto done;
3504  }
3505 
3506  // wait for final result if not done
3508  int sleep_time = digit_timeout;
3509 
3512  }
3514 
3515  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "(%s) WAITING FOR RESULT\n", switch_channel_get_name(channel));
3516 
3518  && switch_channel_ready(channel)) {
3519 
3520  status = switch_ivr_sleep(session, sleep_time, SWITCH_FALSE, &myargs);
3521 
3522  if (args && args->dmachine && switch_ivr_dmachine_last_ping(args->dmachine) != SWITCH_STATUS_SUCCESS) {
3523  // dmachine done
3524  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "(%s) DMACHINE DONE\n", switch_channel_get_name(channel));
3527  status = SWITCH_STATUS_SUCCESS;
3528  goto done;
3529  }
3530 
3531  if (state.terminator != 0) {
3533  status = SWITCH_STATUS_SUCCESS;
3534  sleep_time = digit_timeout;
3535  continue;
3536  }
3537 
3538  if (state.is_speech == SWITCH_FALSE) {
3539 
3540  // calculating how much time has elapsed since the last digit was collected
3541  sleep_time = (switch_micro_time_now() - state.last_digit_time) / 1000;
3542 
3543  if (sleep_time >= digit_timeout) {
3544  // too much time since last digit
3546  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, " (%s) INTER-DIGIT TIMEOUT is_speech = false; sleep_time >= digit_timeout; sleep_time=%i; last_digit_time=%" SWITCH_INT64_T_FMT "; digit_timeout=%lu \n", switch_channel_get_name(channel), sleep_time, state.last_digit_time, (unsigned long)digit_timeout);
3548  } else {
3549  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "\nis_speech = false; sleep_time >= digit_timeout; sleep_time=%i; last_digit_time=%" SWITCH_INT64_T_FMT "; digit_timeout=%lu \n", sleep_time, state.last_digit_time, (unsigned long)digit_timeout);
3550  }
3551  status = SWITCH_STATUS_SUCCESS;
3552  sleep_time = digit_timeout;
3553  } else {
3554  // woke up early, sleep for remaining digit timeout
3555  sleep_time = digit_timeout - sleep_time;
3556  }
3557  } else {
3558  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "\nis_speech = true; sleep_time < digit_timeout; sleep_time=%i; last_digit_time=%" SWITCH_INT64_T_FMT "; digit_timeout=%lu \n", sleep_time, state.last_digit_time, (unsigned long)digit_timeout);
3559  }
3560 
3561  if (status != SWITCH_STATUS_BREAK && status != SWITCH_STATUS_SUCCESS) {
3562  // error of some sort
3563  status = SWITCH_STATUS_FALSE;
3564  goto done;
3565  }
3566 
3567  }
3568  }
3569 
3570 done:
3571 
3572  if (status == SWITCH_STATUS_BREAK) {
3573  status = SWITCH_STATUS_SUCCESS;
3574  }
3575 
3578  }
3579 
3580  if (!zstr(state.digits) && strlen(state.digits) >= state.min_digits) {
3581  /* got DTMF result */
3582  if (digits_collected) {
3583  *digits_collected = state.digits;
3584  }
3585 
3586  if (state.recognition_result) {
3587  cJSON_Delete(state.recognition_result);
3588  }
3589  } else if (state.recognition_result) {
3590  /* have some kind of recognition result or error */
3591  if (recognition_result) {
3592  *recognition_result = state.recognition_result;
3593  } else {
3594  cJSON_Delete(state.recognition_result);
3595  }
3596  }
3597 
3598  if (terminator_collected && state.terminator != 0) {
3599  *terminator_collected = state.terminator;
3600  }
3601 
3603 
3604  return status;
3605 }
switch_time_t switch_micro_time_now(void)
Get the current epoch time in microseconds.
Definition: switch_time.c:311
#define SWITCH_CHANNEL_SESSION_LOG(x)
#define switch_set_flag(obj, flag)
Set a flag on an arbitrary object.
Definition: switch_utils.h:700
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
#define switch_channel_ready(_channel)
#define arg_recursion_check_stop(_args)
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
#define zstr(x)
Definition: switch_utils.h:314
switch_status_t switch_ivr_dmachine_last_ping(switch_ivr_dmachine_t *dmachine)
_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_clear_flag(obj, flag)
Clear a flag on an arbitrary object while locked.
Definition: switch_utils.h:724
switch_status_t switch_ivr_pause_detect_speech(switch_core_session_t *session)
Pause background Speech detection on a session.
switch_input_callback_function_t input_callback
#define arg_recursion_check_start(_args)
switch_status_t switch_ivr_detect_speech(switch_core_session_t *session, const char *mod_name, const char *grammar, const char *name, const char *dest, switch_asr_handle_t *ah)
Engage background Speech detection on a session.
switch_read_frame_callback_function_t read_frame_callback
static switch_status_t switch_collect_input_callback(switch_core_session_t *session, void *input, switch_input_type_t input_type, void *data, unsigned int len)
switch_input_args_t * original_args
switch_status_t
Common return values.
#define SWITCH_INT64_T_FMT
#define switch_core_session_alloc(_session, _memory)
Allocate memory from a session&#39;s pool.
Definition: switch_core.h:696
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:693
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
char * switch_channel_get_name(switch_channel_t *channel)
Retrieve the name of a given channel.
switch_status_t switch_ivr_detect_speech_start_input_timers(switch_core_session_t *session)
Start input timers on a background speech detection handle.
switch_ivr_dmachine_t * dmachine

◆ switch_ivr_process_fh()

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

Definition at line 4052 of file switch_ivr.c.

References if(), switch_file_handle::native_rate, switch_file_handle::offset_pos, SCFC_PAUSE_READ, switch_file_handle::speed, 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, target, switch_file_handle::vol, and zstr.

Referenced by CoreSession::process_callback_result().

4053 {
4054  if (zstr(cmd)) {
4055  return SWITCH_STATUS_SUCCESS;
4056  }
4057 
4058  if (fhp) {
4059  if (!switch_test_flag(fhp, SWITCH_FILE_OPEN)) {
4060  return SWITCH_STATUS_FALSE;
4061  }
4062 
4063  if (!strncasecmp(cmd, "speed", 5)) {
4064  char *p;
4065 
4066  if ((p = strchr(cmd, ':'))) {
4067  p++;
4068  if (*p == '+' || *p == '-') {
4069  int step;
4070  if (!(step = atoi(p))) {
4071  step = 1;
4072  }
4073  fhp->speed += step;
4074  } else {
4075  int speed = atoi(p);
4076  fhp->speed = speed;
4077  }
4078  return SWITCH_STATUS_SUCCESS;
4079  }
4080 
4081  return SWITCH_STATUS_FALSE;
4082 
4083  } else if (!strncasecmp(cmd, "volume", 6)) {
4084  char *p;
4085 
4086  if ((p = strchr(cmd, ':'))) {
4087  p++;
4088  if (*p == '+' || *p == '-') {
4089  int step;
4090  if (!(step = atoi(p))) {
4091  step = 1;
4092  }
4093  fhp->vol += step;
4094  } else {
4095  int vol = atoi(p);
4096  fhp->vol = vol;
4097  }
4098  return SWITCH_STATUS_SUCCESS;
4099  }
4100 
4101  if (fhp->vol) {
4103  }
4104 
4105  return SWITCH_STATUS_FALSE;
4106  } else if (!strcasecmp(cmd, "pause")) {
4107  if (switch_test_flag(fhp, SWITCH_FILE_PAUSE)) {
4109  } else {
4111  }
4112 
4114 
4115  return SWITCH_STATUS_SUCCESS;
4116  } else if (!strcasecmp(cmd, "stop")) {
4118  return SWITCH_STATUS_FALSE;
4119  } else if (!strcasecmp(cmd, "truncate")) {
4120  switch_core_file_truncate(fhp, 0);
4121  } else if (!strcasecmp(cmd, "restart")) {
4122  unsigned int pos = 0;
4123  fhp->speed = 0;
4124  switch_core_file_seek(fhp, &pos, 0, SEEK_SET);
4125  return SWITCH_STATUS_SUCCESS;
4126  } else if (!strncasecmp(cmd, "seek", 4)) {
4127  //switch_codec_t *codec;
4128  unsigned int samps = 0;
4129  unsigned int pos = 0;
4130  char *p;
4131  //codec = switch_core_session_get_read_codec(session);
4132 
4133  if ((p = strchr(cmd, ':'))) {
4134  p++;
4135  if (*p == '+' || *p == '-') {
4136  int step;
4137  int32_t target;
4138  if (!(step = atoi(p))) {
4139  step = 1000;
4140  }
4141 
4142  samps = step * (fhp->native_rate / 1000);
4143  target = (int32_t)fhp->offset_pos + samps;
4144 
4145  if (target < 0) {
4146  target = 0;
4147  }
4148 
4149  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "seek to position %d\n", target);
4150  switch_core_file_seek(fhp, &pos, target, SEEK_SET);
4151 
4152  } else {
4153  samps = switch_atoui(p) * (fhp->native_rate / 1000);
4154  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "seek to position %d\n", samps);
4155  switch_core_file_seek(fhp, &pos, samps, SEEK_SET);
4156  }
4157  }
4158 
4159  return SWITCH_STATUS_SUCCESS;
4160  }
4161  }
4162 
4163  if (!strcmp(cmd, "true") || !strcmp(cmd, "undefined")) {
4164  return SWITCH_STATUS_SUCCESS;
4165  }
4166 
4167  return SWITCH_STATUS_FALSE;
4168 
4169 }
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:314
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:707
#define switch_clear_flag_locked(obj, flag)
Clear a flag on an arbitrary object.
Definition: switch_utils.h:717
const cJSON *const target
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:693
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_ivr_read()

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

2513 {
2514  switch_channel_t *channel;
2515  switch_input_args_t args = { 0 };
2517  size_t len = 0;
2518  char tb[2] = "";
2519  int term_required = 0;
2520 
2521 
2522  if (valid_terminators && *valid_terminators == '=') {
2523  term_required = 1;
2524  }
2525 
2526  switch_assert(session);
2527 
2528  if (!digit_timeout) {
2529  digit_timeout = timeout;
2530  }
2531 
2532  if (max_digits < min_digits) {
2534  "Max digits %u is less than Min %u, forcing Max to %u\n", max_digits, min_digits, min_digits);
2535  max_digits = min_digits;
2536  }
2537 
2538  channel = switch_core_session_get_channel(session);
2540 
2541  if (var_name) {
2542  switch_channel_set_variable(channel, var_name, NULL);
2543  }
2544 
2545  if ((min_digits && digit_buffer_length < min_digits) || digit_buffer_length < max_digits) {
2546  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Buffer too small!\n");
2547  return SWITCH_STATUS_FALSE;
2548  }
2549 
2551  return SWITCH_STATUS_FALSE;
2552  }
2553 
2554  memset(digit_buffer, 0, digit_buffer_length);
2555  args.buf = digit_buffer;
2556  args.buflen = (uint32_t) digit_buffer_length;
2557 
2558  if (!zstr(prompt_audio_file) && strcasecmp(prompt_audio_file, "silence")) {
2559  if ((status = switch_ivr_play_file(session, NULL, prompt_audio_file, &args)) == SWITCH_STATUS_BREAK) {
2560  status = SWITCH_STATUS_SUCCESS;
2561  }
2562  }
2563 
2564  if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) {
2565  goto end;
2566  }
2567 
2568  len = strlen(digit_buffer);
2569 
2570  if ((min_digits && len < min_digits) || len < max_digits) {
2571  args.buf = digit_buffer + len;
2572  args.buflen = (uint32_t) (digit_buffer_length - len);
2573  status = switch_ivr_collect_digits_count(session, digit_buffer, digit_buffer_length, max_digits, valid_terminators, &tb[0],
2574  len ? digit_timeout : timeout, digit_timeout, 0);
2575  }
2576 
2577 
2578  if (tb[0]) {
2579  char *p;
2580 
2582 
2583  if (!zstr(valid_terminators) && (p = strchr(valid_terminators, tb[0]))) {
2584  if (p >= (valid_terminators + 1) && (*(p - 1) == '+' || *(p - 1) == 'x')) {
2585  switch_snprintf(digit_buffer + strlen(digit_buffer), digit_buffer_length - strlen(digit_buffer), "%s", tb);
2586  if (*(p - 1) == 'x') {
2587  status = SWITCH_STATUS_RESTART;
2588  }
2589  }
2590  }
2591  } else if (term_required) {
2592  status = SWITCH_STATUS_TOO_SMALL;
2593  }
2594 
2595  len = strlen(digit_buffer);
2596  if ((min_digits && len < min_digits)) {
2597  status = SWITCH_STATUS_TOO_SMALL;
2598  }
2599 
2600  switch (status) {
2601  case SWITCH_STATUS_SUCCESS:
2603  break;
2604  case SWITCH_STATUS_TIMEOUT:
2606  break;
2607  default:
2609  break;
2610 
2611  }
2612 
2613  end:
2614 
2615  if (status != SWITCH_STATUS_RESTART && max_digits == 1 && len == 1 && valid_terminators && strchr(valid_terminators, *digit_buffer)) {
2616  *digit_buffer = '\0';
2617  }
2618 
2619  if (var_name && !zstr(digit_buffer)) {
2620  switch_channel_set_variable(channel, var_name, digit_buffer);
2621  }
2622 
2623  return status;
2624 
2625 }
#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:314
_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:1342
#define SWITCH_READ_RESULT_VARIABLE
Definition: switch_types.h:138
#define SWITCH_READ_TERMINATOR_USED_VARIABLE
Definition: switch_types.h:130
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_ivr_record_session_mask()

switch_status_t switch_ivr_record_session_mask ( switch_core_session_t session,
const char *  file,
switch_bool_t  on 
)

Definition at line 1888 of file switch_ivr_async.c.

References record_helper::bug, 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.

1889 {
1892 
1893  if ((bug = switch_channel_get_private(channel, file))) {
1894  if (on) {
1896  } else {
1898  }
1899  return SWITCH_STATUS_SUCCESS;
1900  }
1901  return SWITCH_STATUS_FALSE;
1902 }
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_ivr_record_session_pause()

switch_status_t switch_ivr_record_session_pause ( switch_core_session_t session,
const char *  file,
switch_bool_t  on 
)

Definition at line 1904 of file switch_ivr_async.c.

References record_helper::bug, SMBF_PAUSE, 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.

1905 {
1908 
1909  if ((bug = switch_channel_get_private(channel, file))) {
1910  if (on) {
1912  } else {
1914  }
1915  return SWITCH_STATUS_SUCCESS;
1916  }
1917  return SWITCH_STATUS_FALSE;
1918 }
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_ivr_release_file_handle()

switch_status_t switch_ivr_release_file_handle ( switch_core_session_t session,
switch_file_handle_t **  fh 
)

Definition at line 1232 of file switch_ivr_play_say.c.

References switch_core_session_io_rwunlock(), and SWITCH_STATUS_SUCCESS.

1233 {
1234  *fh = NULL;
1236 
1237  return SWITCH_STATUS_SUCCESS;
1238 }
switch_status_t switch_core_session_io_rwunlock(switch_core_session_t *session)

◆ switch_ivr_say()

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

3674 {
3676  switch_channel_t *channel;
3678  const char *save_path = NULL, *chan_lang = NULL, *lang = NULL, *sound_path = NULL;
3679  switch_event_t *hint_data;
3680  switch_xml_t cfg, xml = NULL, language = NULL, macros = NULL, phrases = NULL;
3681  char *p;
3682 
3683  switch_assert(session);
3684  channel = switch_core_session_get_channel(session);
3685  switch_assert(channel);
3686 
3688 
3689 
3690  if (zstr(module_name)) {
3691  module_name = "en";
3692  }
3693 
3694  if (module_name) {
3695  char *p;
3696  p = switch_core_session_strdup(session, module_name);
3697  module_name = p;
3698 
3699  if ((p = strchr(module_name, ':'))) {
3700  *p++ = '\0';
3701  chan_lang = p;
3702  }
3703  }
3704 
3705  if (!chan_lang) {
3706  lang = switch_channel_get_variable(channel, "language");
3707 
3708  if (!lang) {
3709  chan_lang = switch_channel_get_variable(channel, "default_language");
3710  if (!chan_lang) {
3711  chan_lang = module_name;
3712  }
3713  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "No language specified - Using [%s]\n", chan_lang);
3714  } else {
3715  chan_lang = lang;
3716  }
3717  }
3718 
3720  switch_assert(hint_data);
3721 
3722  switch_event_add_header_string(hint_data, SWITCH_STACK_BOTTOM, "macro_name", "say_app");
3723  switch_event_add_header_string(hint_data, SWITCH_STACK_BOTTOM, "lang", chan_lang);
3724  switch_channel_event_set_data(channel, hint_data);
3725 
3726  if (switch_xml_locate_language(&xml, &cfg, hint_data, &language, &phrases, &macros, chan_lang) != SWITCH_STATUS_SUCCESS) {
3727  goto done;
3728  }
3729 
3730  if ((p = (char *) switch_xml_attr(language, "say-module"))) {
3731  module_name = switch_core_session_strdup(session, p);
3732  } else if ((p = (char *) switch_xml_attr(language, "module"))) {
3733  module_name = switch_core_session_strdup(session, p);
3734  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Deprecated usage of module attribute\n");
3735  } else {
3736  module_name = chan_lang;
3737  }
3738 
3739  if (!(sound_path = (char *) switch_xml_attr(language, "sound-prefix"))) {
3740  if (!(sound_path = (char *) switch_xml_attr(language, "sound-path"))) {
3741  sound_path = (char *) switch_xml_attr(language, "sound_path");
3742  }
3743  }
3744 
3745  if (channel) {
3746  const char *p = switch_channel_get_variable(channel, "sound_prefix_enforced");
3747  if (!switch_true(p)) {
3748  save_path = switch_channel_get_variable(channel, "sound_prefix");
3749  if (sound_path) {
3750  switch_channel_set_variable(channel, "sound_prefix", sound_path);
3751  }
3752  }
3753  }
3754 
3755  if ((si = switch_loadable_module_get_say_interface(module_name))) {
3756  /* should go back and proto all the say mods to const.... */
3757  switch_say_args_t say_args = {0};
3758 
3759  say_args.type = switch_ivr_get_say_type_by_name(say_type);
3760  say_args.method = switch_ivr_get_say_method_by_name(say_method);
3761  say_args.gender = switch_ivr_get_say_gender_by_name(say_gender);
3762 
3763  status = si->say_function(session, (char *) tosay, &say_args, args);
3764  } else {
3765  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid SAY Interface [%s]!\n", module_name);
3766  status = SWITCH_STATUS_FALSE;
3767  }
3768 
3769  done:
3770 
3772 
3773 
3774  if (hint_data) {
3775  switch_event_destroy(&hint_data);
3776  }
3777 
3778  if (save_path) {
3779  switch_channel_set_variable(channel, "sound_prefix", save_path);
3780  }
3781 
3782  if (xml) {
3783  switch_xml_free(xml);
3784  }
3785 
3786  return status;
3787 }
void switch_xml_free(_In_opt_ switch_xml_t xml)
frees the memory allocated for an switch_xml structure
static switch_bool_t switch_true(const char *expr)
Evaluate the truthfullness of a string expression.
Definition: switch_utils.h:519
#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:3356
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:79
#define zstr(x)
Definition: switch_utils.h:314
_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&#39;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:384
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&#39;s pool.
Definition: switch_core.h:719
void switch_event_destroy(switch_event_t **event)
Destroy an event.
#define switch_assert(expr)
#define switch_channel_set_variable(_channel, _var, _val)

◆ switch_ivr_say_ip()

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, b, switch_say_args_t::method, 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 }
const cJSON *const b
Definition: switch_cJSON.h:243
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:287
#define switch_core_session_strdup(_session, _todup)
Copy a string using memory allocation from a session&#39;s pool.
Definition: switch_core.h:719

◆ switch_ivr_say_spell()

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, SWITCH_STATUS_SUCCESS, and switch_say_args_t::type.

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_ivr_say_string()

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

3798 {
3800  switch_channel_t *channel = NULL;
3802  const char *save_path = NULL, *chan_lang = NULL, *sound_path = NULL;
3803  switch_event_t *hint_data;
3804  switch_xml_t cfg, xml = NULL, language = NULL, macros = NULL, phrases = NULL;
3805 
3806  if (session) {
3807  channel = switch_core_session_get_channel(session);
3808 
3809  if (!lang) {
3810  lang = switch_channel_get_variable(channel, "language");
3811 
3812  if (!lang) {
3813  chan_lang = switch_channel_get_variable(channel, "default_language");
3814  if (!chan_lang) {
3815  chan_lang = "en";
3816  }
3817  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "No language specified - Using [%s]\n", chan_lang);
3818  } else {
3819  chan_lang = lang;
3820  }
3821  }
3822  }
3823 
3824  if (!lang) lang = "en";
3825  if (!chan_lang) chan_lang = lang;
3826 
3828  switch_assert(hint_data);
3829 
3830  switch_event_add_header_string(hint_data, SWITCH_STACK_BOTTOM, "macro_name", "say_app");
3831  switch_event_add_header_string(hint_data, SWITCH_STACK_BOTTOM, "lang", chan_lang);
3832 
3833  if (channel) {
3834  switch_channel_event_set_data(channel, hint_data);
3835  }
3836 
3837  if (switch_xml_locate_language(&xml, &cfg, hint_data, &language, &phrases, &macros, chan_lang) != SWITCH_STATUS_SUCCESS) {
3838  goto done;
3839  }
3840 
3841  if ((module_name = switch_xml_attr(language, "say-module"))) {
3842  } else if ((module_name = switch_xml_attr(language, "module"))) {
3843  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Deprecated usage of module attribute\n");
3844  } else {
3845  module_name = chan_lang;
3846  }
3847 
3848  if (!(sound_path = (char *) switch_xml_attr(language, "sound-prefix"))) {
3849  if (!(sound_path = (char *) switch_xml_attr(language, "sound-path"))) {
3850  sound_path = (char *) switch_xml_attr(language, "sound_path");
3851  }
3852  }
3853 
3854  if (channel) {
3855  const char *p = switch_channel_get_variable(channel, "sound_prefix_enforced");
3856  if (!switch_true(p)) {
3857  save_path = switch_channel_get_variable(channel, "sound_prefix");
3858  if (sound_path) {
3859  switch_channel_set_variable(channel, "sound_prefix", sound_path);
3860  }
3861  }
3862  }
3863 
3864  if ((si = switch_loadable_module_get_say_interface(module_name)) && si->say_string_function) {
3865  /* should go back and proto all the say mods to const.... */
3866  switch_say_args_t say_args = {0};
3867 
3868  say_args.type = switch_ivr_get_say_type_by_name(say_type);
3869  say_args.method = switch_ivr_get_say_method_by_name(say_method);
3870  say_args.gender = switch_ivr_get_say_gender_by_name(say_gender);
3871  say_args.ext = ext;
3872  status = si->say_string_function(session, (char *) tosay, &say_args, rstr);
3873  } else {
3874  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid SAY Interface [%s]!\n", module_name);
3875  status = SWITCH_STATUS_FALSE;
3876  }
3877 
3878  done:
3879 
3880  if (hint_data) {
3881  switch_event_destroy(&hint_data);
3882  }
3883 
3884  if (save_path && channel) {
3885  switch_channel_set_variable(channel, "sound_prefix", save_path);
3886  }
3887 
3888  if (xml) {
3889  switch_xml_free(xml);
3890  }
3891 
3892  return status;
3893 }
void switch_xml_free(_In_opt_ switch_xml_t xml)
frees the memory allocated for an switch_xml structure
static switch_bool_t switch_true(const char *expr)
Evaluate the truthfullness of a string expression.
Definition: switch_utils.h:519
#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:3356
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:79
_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&#39;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:384
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_ivr_send_prompt()

switch_status_t switch_ivr_send_prompt ( switch_core_session_t session,
const char *  type,
const char *  text,
const char *  regex 
)

Definition at line 1510 of file switch_ivr.c.

References switch_core_session_message::from, switch_core_session_message::message_id, switch_core_session_message::string_array_arg, switch_core_session_receive_message, SWITCH_MESSAGE_INDICATE_PROMPT, and SWITCH_STATUS_SUCCESS.

1511 {
1512  switch_core_session_message_t msg = { 0 };
1513 
1515  msg.string_array_arg[0] = type;
1516  msg.string_array_arg[1] = text;
1517  msg.string_array_arg[2] = regex;
1518  msg.from = __FILE__;
1519 
1520  switch_core_session_receive_message(session, &msg);
1521 
1522  return SWITCH_STATUS_SUCCESS;
1523 }
switch_core_session_message_types_t message_id
Definition: switch_core.h:183
const char * string_array_arg[MESSAGE_STRING_ARG_MAX]
Definition: switch_core.h:211
A message object designed to allow unlike technologies to exchange data.
Definition: switch_core.h:179
#define switch_core_session_receive_message(_session, _message)
Definition: switch_core.h:1247

◆ switch_ivr_set_user()

switch_status_t switch_ivr_set_user ( switch_core_session_t session,
const char *  data 
)

Definition at line 3976 of file switch_ivr.c.

References switch_ivr_set_user_extended().

3977 {
3978  return switch_ivr_set_user_extended(session, data, NULL);
3979 }
switch_status_t switch_ivr_set_user_extended(switch_core_session_t *session, const char *data, switch_event_t *params)
Definition: switch_ivr.c:3981

◆ switch_ivr_set_user_extended()

switch_status_t switch_ivr_set_user_extended ( switch_core_session_t session,
const char *  data,
switch_event_t params 
)

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

Referenced by switch_ivr_set_user().

3982 {
3983  switch_xml_t x_user = 0;
3984  char *user, *domain;
3986 
3987  char *prefix;
3988 
3989  if (zstr(data)) {
3990  goto error;
3991  }
3992 
3993  user = switch_core_session_strdup(session, data);
3994 
3995  if ((prefix = strchr(user, ' '))) {
3996  *prefix++ = 0;
3997  }
3998 
3999  if (!(domain = strchr(user, '@'))) {
4000  goto error;
4001  }
4002 
4003  *domain++ = '\0';
4004 
4005  if (switch_xml_locate_user_merged("id", user, domain, NULL, &x_user, params) != SWITCH_STATUS_SUCCESS) {
4006  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "can't find user [%s@%s]\n", user, domain);
4007  goto done;
4008  }
4009 
4010  status = switch_ivr_set_user_xml(session, prefix, user, domain, x_user);
4011 
4012  goto done;
4013 
4014  error:
4015  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No user@domain specified.\n");
4016 
4017  done:
4018 
4019  if (x_user) {
4020  switch_xml_free(x_user);
4021  }
4022 
4023  return status;
4024 }
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:2145
A representation of an XML tree.
Definition: switch_xml.h:79
#define zstr(x)
Definition: switch_utils.h:314
Definition: cJSON.c:68
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&#39;s pool.
Definition: switch_core.h:719
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:3921

◆ switch_ivr_set_user_xml()

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 3921 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_extended().

3923 {
3924  switch_xml_t x_params, x_param;
3925  char *number_alias;
3928 
3929  char *prefix_buffer = NULL;
3930  size_t buffer_size = 0;
3931  size_t prefix_size = 0;
3932 
3933 
3934  status = SWITCH_STATUS_SUCCESS;
3935 
3936  if (!zstr(prefix)) {
3937  prefix_size = strlen(prefix);
3938  buffer_size = 1024 + prefix_size + 1;
3939  prefix_buffer = switch_core_session_alloc(session, buffer_size);
3940  }
3941 
3942  if ((number_alias = (char *) switch_xml_attr(x_user, "number-alias"))) {
3943  switch_channel_set_variable(channel, get_prefixed_str(prefix_buffer, buffer_size, prefix, prefix_size, "number_alias"), number_alias);
3944  }
3945 
3946  if ((x_params = switch_xml_child(x_user, "variables"))) {
3947  for (x_param = switch_xml_child(x_params, "variable"); x_param; x_param = x_param->next) {
3948  const char *var = switch_xml_attr(x_param, "name");
3949  const char *val = switch_xml_attr(x_param, "value");
3950 
3951  if (var && val) {
3952  switch_channel_set_variable(channel, get_prefixed_str(prefix_buffer, buffer_size, prefix, prefix_size, var), val);
3953  }
3954  }
3955  }
3956 
3957  if (switch_channel_get_caller_profile(channel) && (x_params = switch_xml_child(x_user, "profile-variables"))) {
3958  for (x_param = switch_xml_child(x_params, "variable"); x_param; x_param = x_param->next) {
3959  const char *var = switch_xml_attr(x_param, "name");
3960  const char *val = switch_xml_attr(x_param, "value");
3961 
3962  if (var && val) {
3963  switch_channel_set_profile_var(channel, get_prefixed_str(prefix_buffer, buffer_size, prefix, prefix_size, var), val);
3964  }
3965  }
3966  }
3967 
3968  if (user && domain) {
3969  switch_channel_set_variable(channel, get_prefixed_str(prefix_buffer, buffer_size, prefix, prefix_size, "user_name"), user);
3970  switch_channel_set_variable(channel, get_prefixed_str(prefix_buffer, buffer_size, prefix, prefix_size, "domain_name"), domain);
3971  }
3972 
3973  return status;
3974 }
switch_status_t switch_channel_set_profile_var(switch_channel_t *channel, const char *name, const char *val)
Set a variable on a given channel.
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
A representation of an XML tree.
Definition: switch_xml.h:79
static const char * get_prefixed_str(char *buffer, size_t buffer_size, const char *prefix, size_t prefix_size, const char *str)
Definition: switch_ivr.c:3896
#define zstr(x)
Definition: switch_utils.h:314
_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_xml_t next
Definition: switch_xml.h:91
switch_status_t
Common return values.
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 ...
#define switch_core_session_alloc(_session, _memory)
Allocate memory from a session&#39;s pool.
Definition: switch_core.h:696
#define switch_channel_set_variable(_channel, _var, _val)
switch_caller_profile_t * switch_channel_get_caller_profile(switch_channel_t *channel)
Retrieve the given channel&#39;s caller profile.

◆ switch_ivr_soft_hold()

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

Definition at line 3198 of file switch_ivr_play_say.c.

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

3199 {
3200  switch_channel_t *channel, *other_channel;
3201  switch_core_session_t *other_session;
3202  const char *other_uuid, *moh = NULL;
3203  int moh_br = 0;
3204  switch_input_args_t args = { 0 };
3205  switch_status_t res;
3206 
3208  args.buf = (void *) unhold_key;
3209  args.buflen = (uint32_t) strlen(unhold_key);
3210 
3211  switch_assert(session != NULL);
3212  channel = switch_core_session_get_channel(session);
3213  switch_assert(channel != NULL);
3214 
3215  if ((other_uuid = switch_channel_get_partner_uuid(channel))) {
3216  if ((other_session = switch_core_session_locate(other_uuid))) {
3217  other_channel = switch_core_session_get_channel(other_session);
3218 
3219  if (moh_b) {
3220  moh = moh_b;
3221  } else {
3222  moh = switch_channel_get_hold_music(other_channel);
3223  }
3224 
3225  if (!zstr(moh) && strcasecmp(moh, "silence") && !switch_channel_test_flag(other_channel, CF_BROADCAST)) {
3226  switch_ivr_broadcast(other_uuid, moh, SMF_ECHO_ALEG | SMF_LOOP);
3227  moh_br++;
3228  }
3229 
3230  if (moh_a) {
3231  moh = moh_a;
3232  } else {
3233  moh = switch_channel_get_hold_music(channel);
3234  }
3235 
3236  if (!zstr(moh) && strcasecmp(moh, "silence")) {
3237  res = switch_ivr_play_file(session, NULL, moh, &args);
3238  } else {
3239  res = switch_ivr_collect_digits_callback(session, &args, 0, 0);
3240  }
3241 
3242  (void)res;
3243 
3244  if (moh_br) {
3245  switch_channel_stop_broadcast(other_channel);
3246  }
3247 
3248  switch_core_session_rwunlock(other_session);
3249 
3250 
3251  return SWITCH_STATUS_SUCCESS;
3252  }
3253  }
3254 
3255  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Channel %s is not in a bridge\n", switch_channel_get_name(channel));
3256 
3257  return SWITCH_STATUS_FALSE;
3258 
3259 }
#define SWITCH_CHANNEL_SESSION_LOG(x)
static switch_status_t hold_on_dtmf(switch_core_session_t *session, void *input, switch_input_type_t itype, void *buf, unsigned int buflen)
const char * switch_channel_get_partner_uuid(switch_channel_t *channel)
#define switch_channel_stop_broadcast(_channel)
switch_status_t switch_ivr_collect_digits_callback(switch_core_session_t *session, switch_input_args_t *args, uint32_t digit_timeout, uint32_t abs_timeout)
Wait for DTMF digits calling a pluggable callback function when digits are collected.
Definition: switch_ivr.c:1225
switch_status_t switch_ivr_broadcast(const char *uuid, const char *path, switch_media_flag_t flags)
Signal the session to broadcast audio.
switch_status_t switch_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
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:314
_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.
const char * switch_channel_get_hold_music(switch_channel_t *channel)
switch_input_callback_function_t input_callback
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&#39;s uuid.
Definition: switch_core.h:932
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)
char * switch_channel_get_name(switch_channel_t *channel)
Retrieve the name of a given channel.

◆ switch_ivr_sound_test()

switch_status_t switch_ivr_sound_test ( switch_core_session_t session)

Definition at line 41 of file switch_ivr.c.

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

42 {
43 
45  switch_codec_t codec = { 0 };
46  int16_t peak = 0;
47  int16_t *data;
48  switch_frame_t *read_frame = NULL;
49  uint32_t i;
52  int64_t global_total = 0, global_sum = 0, period_sum = 0;
53  int period_total = 0;
54  int period_avg = 0, global_avg = 0;
55  int avg = 0;
56  int period_len;
57 
58  switch_core_session_get_read_impl(session, &imp);
59 
60  period_len = imp.actual_samples_per_second / imp.samples_per_packet;
61 
62  if (switch_core_codec_init(&codec,
63  "L16",
64  NULL,
65  NULL,
67  imp.microseconds_per_packet / 1000,
71  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec Error L16@%uhz %u channels %dms\n",
73  return SWITCH_STATUS_FALSE;
74  }
75 
76  while (switch_channel_ready(channel)) {
77  status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
78 
79  if (!SWITCH_READ_ACCEPTABLE(status)) {
80  break;
81  }
82 
83  if (switch_test_flag(read_frame, SFF_CNG) || !read_frame->samples) {
84  continue;
85  }
86 
87 
88  data = (int16_t *) read_frame->data;
89  peak = 0;
90  avg = 0;
91  for (i = 0; i < read_frame->samples; i++) {
92  const int16_t s = (int16_t) abs(data[i]);
93  if (s > peak) {
94  peak = s;
95  }
96  avg += s;
97  }
98 
99  avg /= read_frame->samples;
100 
101  period_sum += peak;
102  global_sum += peak;
103 
104  global_total++;
105  period_total++;
106 
107  period_avg = (int) (period_sum / period_total);
108 
110  "\npacket_avg=%d packet_peak=%d period_avg=%d global_avg=%d\n\n", avg, peak, period_avg, global_avg);
111 
112  if (period_total >= period_len) {
113  global_avg = (int) (global_sum / global_total);
114  period_total = 0;
115  period_sum = 0;
116  }
117 
118  }
119 
120 
122 
123  return SWITCH_STATUS_SUCCESS;
124 
125 }
#define SWITCH_CHANNEL_SESSION_LOG(x)
#define switch_channel_ready(_channel)
switch_status_t switch_core_codec_destroy(switch_codec_t *codec)
Destroy an initalized codec handle.
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_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.
An abstraction of a data frame.
Definition: switch_frame.h:54
#define switch_core_codec_init(_codec, _codec_name, _modname, _fmtp, _rate, _ms, _channels, _flags, _codec_settings, _pool)
Initialize a codec handle.
Definition: switch_core.h:1693
switch_status_t
Common return values.
uint32_t samples
Definition: switch_frame.h:72
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:693
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)
switch_memory_pool_t * switch_core_session_get_pool(_In_ switch_core_session_t *session)
Retrieve the memory pool from a session.

◆ switch_ivr_stop_video_write_overlay_session()

switch_status_t switch_ivr_stop_video_write_overlay_session ( switch_core_session_t session)

Definition at line 5821 of file switch_ivr_async.c.

References switch_channel_get_private(), switch_channel_set_private(), switch_core_media_bug_remove(), switch_core_session_get_channel(), SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.

5822 {
5824  switch_media_bug_t *bug = switch_channel_get_private(channel, "_video_write_overlay_bug_");
5825 
5826  if (bug) {
5827  switch_channel_set_private(channel, "_video_write_overlay_bug_", NULL);
5828  switch_core_media_bug_remove(session, &bug);
5829  return SWITCH_STATUS_SUCCESS;
5830  }
5831 
5832  return SWITCH_STATUS_FALSE;
5833 }
switch_status_t switch_channel_set_private(switch_channel_t *channel, const char *key, const void *private_info)
Set private data on 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.
switch_status_t switch_core_media_bug_remove(_In_ switch_core_session_t *session, _Inout_ switch_media_bug_t **bug)
Remove a media bug from the session.
void * switch_channel_get_private(switch_channel_t *channel, const char *key)
Retrieve private from a given channel.
switch_media_bug_t * bug

◆ switch_ivr_unbind_dtmf_meta_session()

switch_status_t switch_ivr_unbind_dtmf_meta_session ( switch_core_session_t session,
uint32_t  key 
)

Definition at line 4669 of file switch_ivr_async.c.

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

4670 {
4672 
4673  if (key) {
4675 
4676  if (!md || key > 9) {
4677  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid key %u\n", key);
4678  return SWITCH_STATUS_FALSE;
4679  }
4680 
4681  memset(&md->sr[SWITCH_DTMF_RECV].map[key], 0, sizeof(md->sr[SWITCH_DTMF_RECV].map[key]));
4682  memset(&md->sr[SWITCH_DTMF_SEND].map[key], 0, sizeof(md->sr[SWITCH_DTMF_SEND].map[key]));
4683  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "UnBound A-Leg: %d\n", key);
4684 
4685  } else {
4686  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "UnBound A-Leg: ALL\n");
4688  }
4689 
4690  return SWITCH_STATUS_SUCCESS;
4691 }
#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.
_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 * key
Definition: switch_msrp.c:64
#define SWITCH_META_VAR_KEY
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
dtmf_meta_settings_t sr[3]
dtmf_meta_app_t map[14]
memset(buf, 0, buflen)

◆ switch_ivr_unblock_dtmf_session()

switch_status_t switch_ivr_unblock_dtmf_session ( switch_core_session_t session)

Definition at line 4705 of file switch_ivr_async.c.

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

4706 {
4708  uint8_t enabled = (uint8_t)(intptr_t)switch_channel_get_private(channel, SWITCH_BLOCK_DTMF_KEY);
4709 
4710  if (enabled) {
4712  }
4713 
4714  return SWITCH_STATUS_SUCCESS;
4715 }
switch_status_t switch_channel_set_private(switch_channel_t *channel, const char *key, const void *private_info)
Set private data on channel.
#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.

◆ switch_ivr_uuid_exists()

switch_bool_t switch_ivr_uuid_exists ( const char *  uuid)

Definition at line 4026 of file switch_ivr.c.

References switch_core_session_locate, switch_core_session_rwunlock(), and SWITCH_FALSE.

Referenced by core_event_handler().

4027 {
4028  switch_bool_t exists = SWITCH_FALSE;
4029  switch_core_session_t *psession = NULL;
4030 
4031  if ((psession = switch_core_session_locate(uuid))) {
4032  switch_core_session_rwunlock(psession);
4033  exists = 1;
4034  }
4035 
4036  return exists;
4037 }
switch_bool_t
Definition: switch_types.h:437
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&#39;s uuid.
Definition: switch_core.h:932

◆ switch_ivr_uuid_force_exists()

switch_bool_t switch_ivr_uuid_force_exists ( const char *  uuid)

Definition at line 4039 of file switch_ivr.c.

References switch_core_session_force_locate, switch_core_session_rwunlock(), and SWITCH_FALSE.

4040 {
4041  switch_bool_t exists = SWITCH_FALSE;
4042  switch_core_session_t *psession = NULL;
4043 
4044  if ((psession = switch_core_session_force_locate(uuid))) {
4045  switch_core_session_rwunlock(psession);
4046  exists = 1;
4047  }
4048 
4049  return exists;
4050 }
#define switch_core_session_force_locate(uuid_str)
Locate a session based on it&#39;s uuid even if the channel is not ready.
Definition: switch_core.h:941
switch_bool_t
Definition: switch_types.h:437
void switch_core_session_rwunlock(_In_ switch_core_session_t *session)
Unlock a read or write lock on as given session.

◆ switch_ivr_video_write_overlay_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 
)

Definition at line 5835 of file switch_ivr_async.c.

References oht_s::alpha, oht_s::img, oht_s::pos, SMBF_NO_PAUSE, SMBF_WRITE_VIDEO_PING, switch_channel_get_private(), SWITCH_CHANNEL_LOG, switch_channel_set_private(), switch_core_media_bug_add(), switch_core_session_alloc, switch_core_session_get_channel(), SWITCH_IMG_FMT_ARGB, switch_img_free(), switch_img_read_png(), SWITCH_LOG_ERROR, switch_log_printf(), SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, and video_write_overlay_callback().

5837 {
5839  switch_status_t status;
5842  overly_helper_t *oht;
5843  switch_image_t *img;
5844 
5845  bflags |= SMBF_NO_PAUSE;
5846 
5847  if (switch_channel_get_private(channel, "_video_write_overlay_bug_")) {
5848  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Only one of this type of bug per channel\n");
5849  return SWITCH_STATUS_FALSE;
5850  }
5851 
5852  if (!(img = switch_img_read_png(img_path, SWITCH_IMG_FMT_ARGB))) {
5853  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error opening file: %s\n", img_path);
5854  return SWITCH_STATUS_FALSE;
5855  }
5856 
5857  oht = switch_core_session_alloc(session, sizeof(*oht));
5858  oht->img = img;
5859  oht->pos = pos;
5860  oht->alpha = alpha;
5861 
5862  if ((status = switch_core_media_bug_add(session, "video_write_overlay", NULL,
5863  video_write_overlay_callback, oht, 0, bflags, &bug)) != SWITCH_STATUS_SUCCESS) {
5864 
5865  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error creating bug, file: %s\n", img_path);
5866  switch_img_free(&oht->img);
5867  return status;
5868  }
5869 
5870  switch_channel_set_private(channel, "_video_write_overlay_bug_", bug);
5871 
5872  return SWITCH_STATUS_SUCCESS;
5873 }
Image Descriptor.
Definition: switch_image.h:88
#define SWITCH_CHANNEL_LOG
void switch_img_free(switch_image_t **img)
Close an image descriptor.
switch_status_t switch_channel_set_private(switch_channel_t *channel, const char *key, const void *private_info)
Set private data on channel.
uint8_t alpha
#define SWITCH_IMG_FMT_ARGB
Definition: switch_vpx.h:72
switch_status_t switch_core_media_bug_add(_In_ switch_core_session_t *session, _In_ const char *function, _In_ const char *target, _In_ switch_media_bug_callback_t callback, _In_opt_ void *user_data, _In_ time_t stop_time, _In_ switch_media_bug_flag_t flags, _Out_ switch_media_bug_t **new_bug)
Add a media bug to the session.
switch_image_t * img
_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_image_t * switch_img_read_png(const char *file_name, switch_img_fmt_t img_fmt)
switch_img_position_t pos
static switch_bool_t video_write_overlay_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type)
switch_status_t
Common return values.
void * switch_channel_get_private(switch_channel_t *channel, const char *key)
Retrieve private from a given channel.
#define switch_core_session_alloc(_session, _memory)
Allocate memory from a session&#39;s pool.
Definition: switch_core.h:696
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
uint32_t switch_media_bug_flag_t
switch_media_bug_t * bug

◆ switch_ivr_wait_for_answer()

switch_status_t switch_ivr_wait_for_answer ( switch_core_session_t session,
switch_core_session_t peer_session 
)

Definition at line 943 of file switch_ivr_originate.c.

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

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

944 {
945  switch_channel_t *caller_channel = NULL;
946  switch_channel_t *peer_channel = switch_core_session_get_channel(peer_session);
947  const char *ringback_data = NULL;
948  switch_frame_t write_frame = { 0 };
949  switch_codec_t write_codec = { 0 };
950  switch_codec_t *read_codec = switch_core_session_get_read_codec(session);
951  uint8_t pass = 0;
952  ringback_t ringback = { 0 };
953  switch_frame_t *read_frame = NULL;
955  int timelimit = SWITCH_DEFAULT_TIMEOUT;
956  const char *var;
957  switch_time_t start = 0;
958  const char *cancel_key = NULL;
959  switch_channel_state_t wait_state = 0;
960 
961  switch_assert(peer_channel);
962 
963  if (switch_channel_get_state(peer_channel) == CS_RESET) {
965  }
966 
967  if (session) {
968  caller_channel = switch_core_session_get_channel(session);
969  }
970 
971  if ((switch_channel_test_flag(peer_channel, CF_ANSWERED) || switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA))) {
972  goto end;
973  }
974 
977 
978  if (caller_channel && (var = switch_channel_get_variable(caller_channel, SWITCH_CALL_TIMEOUT_VARIABLE))) {
979  timelimit = atoi(var);
980  if (timelimit < 0) {
981  timelimit = SWITCH_DEFAULT_TIMEOUT;
982  }
983  }
984 
985  timelimit *= 1000000;
986  start = switch_micro_time_now();
987 
988  if (caller_channel) {
989  cancel_key = switch_channel_get_variable(caller_channel, "origination_cancel_key");
990 
991  if (switch_channel_test_flag(caller_channel, CF_ANSWERED)) {
992  ringback_data = switch_channel_get_variable(caller_channel, "transfer_ringback");
993  }
994 
995  if (!ringback_data) {
996  ringback_data = switch_channel_get_variable(caller_channel, "ringback");
997  }
998 
999  if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE) || switch_channel_test_flag(caller_channel, CF_PROXY_MEDIA)) {
1000  ringback_data = NULL;
1001  } else if (zstr(ringback_data)) {
1003  int sval = atoi(var);
1004 
1005  if (sval) {
1006  ringback_data = switch_core_session_sprintf(session, "silence:%d", sval);
1007  }
1008  }
1009  }
1010  }
1011 
1012 
1013  if (read_codec && ringback_data) {
1014  if (switch_is_file_path(ringback_data)) {
1015  if (!(strrchr(ringback_data, '.') || strstr(ringback_data, SWITCH_URL_SEPARATOR))) {
1016  ringback.asis++;
1017  }
1018  }
1019 
1020 
1021 
1022  if (!ringback.asis) {
1023  if ((pass = (uint8_t) switch_test_flag(read_codec, SWITCH_CODEC_FLAG_PASSTHROUGH))) {
1024  goto no_ringback;
1025  }
1026 
1027  if (switch_core_codec_init(&write_codec,
1028  "L16",
1029  NULL,
1030  NULL,
1032  read_codec->implementation->microseconds_per_packet / 1000,
1035  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec Error!\n");
1036  if (caller_channel) {
1038  }
1039  read_codec = NULL;
1040  goto done;
1041  } else {
1043  "Raw Codec Activation Success L16@%uhz 1 channel %dms\n",
1045 
1046  write_frame.codec = &write_codec;
1047  write_frame.datalen = read_codec->implementation->decoded_bytes_per_packet;
1048  write_frame.samples = write_frame.datalen / 2;
1049  memset(write_frame.data, 255, write_frame.datalen);
1050  switch_core_session_set_read_codec(session, &write_codec);
1051  }
1052  }
1053 
1054  if (switch_channel_test_flag(caller_channel, CF_DISABLE_RINGBACK)) {
1055  ringback_data = NULL;
1056  }
1057 
1058  if (ringback_data) {
1059  char *tmp_data = NULL;
1060 
1061  if (switch_is_file_path(ringback_data)) {
1062  char *ext;
1063 
1064  if (ringback.asis) {
1065  write_frame.codec = read_codec;
1066  ext = read_codec->implementation->iananame;
1067  tmp_data = switch_mprintf("%s.%s", ringback_data, ext);
1068  ringback_data = tmp_data;
1069  }
1070 
1071  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Play Ringback File [%s]\n", ringback_data);
1072 
1073  ringback.fhb.channels = read_codec->implementation->number_of_channels;
1074  ringback.fhb.samplerate = read_codec->implementation->actual_samples_per_second;
1075  if (switch_core_file_open(&ringback.fhb,
1076  ringback_data,
1077  read_codec->implementation->number_of_channels,
1080  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error Playing File\n");
1081  switch_safe_free(tmp_data);
1082  goto done;
1083  }
1084  ringback.fh = &ringback.fhb;
1085  } else {
1086  if (!strncasecmp(ringback_data, "silence", 7)) {
1087  const char *p = ringback_data + 7;
1088  if (*p == ':') {
1089  p++;
1090  if (p) {
1091  ringback.silence = atoi(p);
1092  }
1093  }
1095  } else {
1096  switch_buffer_create_dynamic(&ringback.audio_buffer, 512, 1024, 0);
1097  switch_buffer_set_loops(ringback.audio_buffer, -1);
1098 
1099  teletone_init_session(&ringback.ts, 0, teletone_handler, &ringback);
1100  ringback.ts.rate = read_codec->implementation->actual_samples_per_second;
1101  ringback.channels = read_codec->implementation->number_of_channels;
1102  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Play Ringback Tone [%s]\n", ringback_data);
1103  if (teletone_run(&ringback.ts, ringback_data)) {
1104  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error Playing Tone\n");
1105  teletone_destroy_session(&ringback.ts);
1107  ringback_data = NULL;
1108  }
1109  }
1110  }
1111  switch_safe_free(tmp_data);
1112  }
1113  }
1114 
1115  no_ringback:
1116 
1117  if (caller_channel) {
1118  wait_state = switch_channel_get_state(caller_channel);
1119  }
1120 
1121  while (switch_channel_ready(peer_channel) && !switch_channel_media_ready(peer_channel)) {
1122  int diff = (int) (switch_micro_time_now() - start);
1123 
1125 
1126  if (caller_channel && cancel_key) {
1127  if (switch_channel_has_dtmf(caller_channel)) {
1128  switch_dtmf_t dtmf = { 0, 0 };
1129  if (switch_channel_dequeue_dtmf(caller_channel, &dtmf) == SWITCH_STATUS_SUCCESS) {
1130  if (dtmf.digit == *cancel_key) {
1131  status = SWITCH_STATUS_FALSE;
1132  goto done;
1133  }
1134  }
1135  }
1136  }
1137 
1138  if (caller_channel && switch_channel_get_state(caller_channel) != wait_state) {
1139  goto done;
1140  }
1141 
1142  if (diff > timelimit) {
1143  status = SWITCH_STATUS_TIMEOUT;
1144  goto done;
1145  }
1146 
1147  if (switch_channel_media_ready(caller_channel)) {
1148  status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
1149  if (!SWITCH_READ_ACCEPTABLE(status)) {
1150  break;
1151  }
1152  } else {
1153  read_frame = NULL;
1154  }
1155 
1156  if (read_frame && !pass) {
1157 
1158  if (!write_frame.codec) {
1159  status = SWITCH_STATUS_FALSE;
1160  break;
1161  }
1162 
1163  if (ringback.fh) {
1164  switch_size_t mlen, olen;
1165  unsigned int pos = 0;
1166 
1167  if (ringback.asis) {
1168  mlen = write_frame.codec->implementation->encoded_bytes_per_packet;
1169  } else {
1170  mlen = write_frame.codec->implementation->samples_per_packet;
1171  }
1172 
1173  olen = mlen;
1174  //if (ringback.fh->resampler && ringback.fh->resampler->rfactor > 1) {
1175  //olen = (switch_size_t) (olen * ringback.fh->resampler->rfactor);
1176  //}
1177  switch_core_file_read(ringback.fh, write_frame.data, &olen);
1178 
1179  if (olen == 0) {
1180  olen = mlen;
1181  ringback.fh->speed = 0;
1182  switch_core_file_seek(ringback.fh, &pos, 0, SEEK_SET);
1183  switch_core_file_read(ringback.fh, write_frame.data, &olen);
1184  if (olen == 0) {
1186  "Failure to read or re-read after seeking to beginning on file [%s]\n", ringback.fh->file_path);
1187  break;
1188  }
1189  }
1190  write_frame.datalen = (uint32_t) (ringback.asis ? olen : olen * 2 * ringback.fh->channels);
1191  } else if (ringback.audio_buffer) {
1192  if ((write_frame.datalen = (uint32_t) switch_buffer_read_loop(ringback.audio_buffer,
1193  write_frame.data,
1194  write_frame.codec->implementation->decoded_bytes_per_packet)) <= 0) {
1195  break;
1196  }
1197  } else if (ringback.silence) {
1198  write_frame.datalen = write_frame.codec->implementation->decoded_bytes_per_packet;
1199  switch_generate_sln_silence((int16_t *) write_frame.data, write_frame.datalen / 2,
1200  write_frame.codec->implementation->number_of_channels, ringback.silence);
1201  }
1202 
1203  if ((ringback.fh || ringback.silence || ringback.audio_buffer) && write_frame.codec && write_frame.datalen) {
1205  break;
1206  }
1207  }
1208  } else {
1209  switch_cond_next();
1210  }
1211  }
1212 
1213  done:
1214 
1215  if (ringback.fh) {
1216  switch_core_file_close(ringback.fh);
1217  ringback.fh = NULL;
1218  } else if (ringback.audio_buffer) {
1219  teletone_destroy_session(&ringback.ts);
1220  switch_safe_free(ringback.mux_buf);
1222  }
1223 
1224 
1225  switch_ivr_parse_all_events(session);
1226 
1228 
1229  if (switch_core_codec_ready(&write_codec)) {
1230  switch_core_codec_destroy(&write_codec);
1231  }
1232 
1233  switch_safe_free(write_frame.data);
1234 
1235  end:
1236 
1237  if (!switch_channel_media_ready(peer_channel)) {
1238  if (switch_channel_up_nosig(peer_channel)) {
1240  }
1241  status = SWITCH_STATUS_FALSE;
1242  }
1243 
1244  if (switch_channel_test_flag(caller_channel, CF_XFER_ZOMBIE)) {
1245  switch_channel_state_t peer_state = switch_channel_get_state(peer_channel);
1246 
1247  while (switch_channel_ready(peer_channel) && switch_channel_get_state(peer_channel) == peer_state) {
1249  switch_channel_ready(caller_channel);
1250  switch_yield(20000);
1251  }
1252  }
1253 
1254  if (caller_channel && !switch_channel_up_nosig(caller_channel)) {
1255  status = SWITCH_STATUS_FALSE;
1256  }
1257 
1258  return status;
1259 }
switch_time_t switch_micro_time_now(void)
Get the current epoch time in microseconds.
Definition: switch_time.c:311
switch_channel_state_t switch_channel_get_state(switch_channel_t *channel)
Get the current state of a channel in the state engine.
#define switch_channel_hangup(channel, hangup_cause)
Hangup a channel flagging it&#39;s state machine to end.
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)
void switch_core_session_reset(_In_ switch_core_session_t *session, switch_bool_t flush_dtmf, switch_bool_t reset_read_codec)
Reset the buffers and resampler on a session.
#define switch_channel_set_state(channel, state)
Set the current state of a channel.
#define switch_core_file_open(_fh, _file_path, _channels, _rate, _flags, _pool)
Open a media file using file format modules.
Definition: switch_core.h:1963
switch_status_t switch_buffer_create_dynamic(_Out_ switch_buffer_t **buffer, _In_ switch_size_t blocksize, _In_ switch_size_t start_len, _In_ switch_size_t max_len)
Allocate a new dynamic switch_buffer.
teletone_generation_session_t ts
#define SWITCH_RECOMMENDED_BUFFER_SIZE
Definition: switch_types.h:590
switch_status_t switch_core_session_set_read_codec(_In_ switch_core_session_t *session, switch_codec_t *codec)
Assign the read codec to a given session.
#define SWITCH_URL_SEPARATOR
Definition: switch_types.h:126
switch_file_handle_t fhb
#define SWITCH_CALL_TIMEOUT_VARIABLE
Definition: switch_types.h:171
switch_status_t switch_core_file_close(_In_ switch_file_handle_t *fh)
Close an open file handle.
#define switch_channel_ready(_channel)
void switch_generate_sln_silence(int16_t *data, uint32_t samples, uint32_t channels, uint32_t divisor)
Generate static noise.
#define switch_channel_media_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.
int teletone_destroy_session(teletone_generation_session_t *ts)
Free the buffer allocated by a tone generation session.
switch_status_t switch_core_codec_destroy(switch_codec_t *codec)
Destroy an initalized codec handle.
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_ivr_parse_all_events(switch_core_session_t *session)
Parse all commands from an event.
Definition: switch_ivr.c:913
uint32_t switch_channel_test_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Test for presence of given flag on a given channel.
switch_status_t switch_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:56
#define zstr(x)
Definition: switch_utils.h:314
switch_codec_t * switch_core_session_get_read_codec(_In_ switch_core_session_t *session)
Retrieve the read codec from a given session.
#define SWITCH_SEND_SILENCE_WHEN_IDLE_VARIABLE
Definition: switch_types.h:131
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.
int teletone_run(teletone_generation_session_t *ts, const char *cmd)
Execute a tone generation script and call callbacks after each instruction.
_Ret_ switch_channel_t * switch_core_session_get_channel(_In_ switch_core_session_t *session)
Retrieve a pointer to the channel object associated with a given session.
int teletone_init_session(teletone_generation_session_t *ts, int buflen, tone_handler handler, void *user_data)
Initilize a tone generation session.
int64_t switch_time_t
Definition: switch_apr.h:188
const switch_codec_implementation_t * implementation
uint32_t buflen
Definition: switch_frame.h:70
#define switch_yield(ms)
Wait a desired number of microseconds and yield the CPU.
Definition: switch_utils.h:998
uint32_t datalen
Definition: switch_frame.h:68
#define SWITCH_DEFAULT_TIMEOUT
Definition: switch_types.h:117
void switch_buffer_set_loops(_In_ switch_buffer_t *buffer, _In_ int32_t loops)
Assign a number of loops to read.
#define switch_channel_get_variable(_c, _v)
switch_status_t switch_channel_dequeue_dtmf(_In_ switch_channel_t *channel, _In_ switch_dtmf_t *dtmf)
Retrieve DTMF digits from a given channel.
#define switch_zmalloc(ptr, len)
switch_size_t switch_buffer_read_loop(_In_ switch_buffer_t *buffer, _In_ void *data, _In_ switch_size_t datalen)
Read data endlessly from a switch_buffer_t.
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:885
#define SWITCH_IVR_VERIFY_SILENCE_DIVISOR(divisor)
Definition: switch_ivr.h:68
An abstraction of a data frame.
Definition: switch_frame.h:54
uintptr_t switch_size_t
#define switch_core_codec_init(_codec, _codec_name, _modname, _fmtp, _rate, _ms, _channels, _flags, _codec_settings, _pool)
Initialize a codec handle.
Definition: switch_core.h:1693
void switch_cond_next(void)
Definition: switch_time.c:658
switch_channel_state_t
Channel States (these are the defaults, CS_SOFT_EXECUTE, CS_EXCHANGE_MEDIA, and CS_CONSUME_MEDIA are ...
switch_status_t
Common return values.
switch_size_t switch_channel_has_dtmf(_In_ switch_channel_t *channel)
Test for presence of DTMF on a given channel.
switch_buffer_t * audio_buffer
static switch_bool_t switch_is_file_path(const char *file)
uint32_t samples
Definition: switch_frame.h:72
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:693
static switch_bool_t switch_core_codec_ready(switch_codec_t *codec)
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_channel_up_nosig(_channel)
#define switch_assert(expr)
switch_file_handle_t * fh
void switch_buffer_destroy(switch_buffer_t **buffer)
Destroy the buffer.
SWITCH_BEGIN_EXTERN_C char * switch_mprintf(const char *zFormat,...)
#define SWITCH_READ_ACCEPTABLE(status)
memset(buf, 0, buflen)
#define SWITCH_CHANNEL_CHANNEL_LOG(x)
switch_memory_pool_t * switch_core_session_get_pool(_In_ switch_core_session_t *session)
Retrieve the memory pool from a session.
static int teletone_handler(teletone_generation_session_t *ts, teletone_tone_map_t *map)
switch_status_t switch_ivr_parse_all_messages(switch_core_session_t *session)
Definition: switch_ivr.c:847

◆ switch_process_import()

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

Definition at line 1261 of file switch_ivr_originate.c.

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

Referenced by switch_ivr_originate().

1262 {
1263  const char *import, *val;
1264  switch_channel_t *caller_channel;
1265 
1266  switch_assert(session && peer_channel);
1267  caller_channel = switch_core_session_get_channel(session);
1268 
1269  if ((import = switch_channel_get_variable(caller_channel, varname))) {
1270  char *mydata = switch_core_session_strdup(session, import);
1271  int i, argc;
1272  char *argv[64] = { 0 };
1273 
1274  if ((argc = switch_separate_string(mydata, ',', argv, (sizeof(argv) / sizeof(argv[0]))))) {
1275  for (i = 0; i < argc; i++) {
1276  if ((val = switch_channel_get_variable(peer_channel, argv[i]))) {
1277  if (prefix) {
1278  char *var = switch_mprintf("%s%s", prefix, argv[i]);
1279  switch_channel_set_variable(caller_channel, var, val);
1280  free(var);
1281  } else {
1282  switch_channel_set_variable(caller_channel, argv[i], val);
1283  }
1284  }
1285  }
1286  }
1287  }
1288 }
_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.
unsigned int switch_separate_string(_In_ char *buf, char delim, _Post_count_(return) char **array, unsigned int arraylen)
Separate a string into an array based on a character delimiter.
#define switch_channel_get_variable(_c, _v)
#define switch_core_session_strdup(_session, _todup)
Copy a string using memory allocation from a session&#39;s pool.
Definition: switch_core.h:719
#define switch_assert(expr)
#define switch_channel_set_variable(_channel, _var, _val)
SWITCH_BEGIN_EXTERN_C char * switch_mprintf(const char *zFormat,...)