FreeSWITCH API Documentation  1.7.0
Modules | Typedefs | Functions
IVR Library
+ Collaboration diagram for IVR Library:

Modules

 IVR Menu Library
 

Typedefs

typedef struct
switch_ivr_digit_stream_parser 
switch_ivr_digit_stream_parser_t
 
typedef struct
switch_ivr_digit_stream 
switch_ivr_digit_stream_t
 

Functions

switch_status_t switch_ivr_deactivate_unicast (switch_core_session_t *session)
 
switch_status_t switch_ivr_activate_unicast (switch_core_session_t *session, char *local_ip, switch_port_t local_port, char *remote_ip, switch_port_t remote_port, char *transport, char *flags)
 
switch_status_t switch_ivr_generate_json_cdr (switch_core_session_t *session, cJSON **json_cdr, switch_bool_t urlencode)
 Generate an JSON CDR report. More...
 
switch_status_t switch_ivr_generate_xml_cdr (switch_core_session_t *session, switch_xml_t *xml_cdr)
 Generate an XML CDR report. More...
 
int switch_ivr_set_xml_profile_data (switch_xml_t xml, switch_caller_profile_t *caller_profile, int off)
 
int switch_ivr_set_xml_chan_vars (switch_xml_t xml, switch_channel_t *channel, int off)
 
switch_status_t switch_ivr_parse_event (_In_ switch_core_session_t *session, _In_ switch_event_t *event)
 Parse command from an event. More...
 
switch_status_t switch_ivr_parse_all_events (switch_core_session_t *session)
 Parse all commands from an event. More...
 
switch_status_t switch_ivr_parse_next_event (switch_core_session_t *session)
 
switch_status_t switch_ivr_parse_all_messages (switch_core_session_t *session)
 
switch_status_t switch_ivr_parse_all_signal_data (switch_core_session_t *session)
 
switch_status_t switch_ivr_parse_signal_data (switch_core_session_t *session, switch_bool_t all, switch_bool_t only_session_thread)
 
switch_status_t switch_ivr_parse_next_signal_data (switch_core_session_t *session)
 
switch_status_t switch_ivr_process_indications (switch_core_session_t *session, switch_core_session_message_t *message)
 
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. More...
 
switch_status_t switch_ivr_park (switch_core_session_t *session, switch_input_args_t *args)
 
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. More...
 
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. More...
 
switch_status_t switch_ivr_play_and_detect_speech (switch_core_session_t *session, const char *file, const char *mod_name, const char *grammar, char **result, uint32_t input_timeout, switch_input_args_t *args)
 play a file to the session while doing speech recognition. More...
 
switch_status_t switch_ivr_detect_speech_init (switch_core_session_t *session, const char *mod_name, const char *dest, switch_asr_handle_t *ah)
 Initialize background Speech detection on a session, so that parameters can be set, and grammars loaded. After calling this function, it is possible to call switch_ivr_set_param_detect_speech() to set recognition parameters. Calling switch_ivr_detect_speech_load_grammar() starts the speech recognition. More...
 
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. More...
 
switch_status_t switch_ivr_stop_detect_speech (switch_core_session_t *session)
 Stop background Speech detection on a session. More...
 
switch_status_t switch_ivr_pause_detect_speech (switch_core_session_t *session)
 Pause background Speech detection on a session. More...
 
switch_status_t switch_ivr_resume_detect_speech (switch_core_session_t *session)
 Resume background Speech detection on a session. More...
 
switch_status_t switch_ivr_detect_speech_load_grammar (switch_core_session_t *session, const char *grammar, const char *name)
 Load a grammar on a background speech detection handle. More...
 
switch_status_t switch_ivr_detect_speech_unload_grammar (switch_core_session_t *session, const char *name)
 Unload a grammar on a background speech detection handle. More...
 
switch_status_t switch_ivr_detect_speech_enable_grammar (switch_core_session_t *session, const char *name)
 Enable a grammar on a background speech detection handle. More...
 
switch_status_t switch_ivr_detect_speech_disable_grammar (switch_core_session_t *session, const char *name)
 Disable a grammar on a background speech detection handle. More...
 
switch_status_t switch_ivr_detect_speech_disable_all_grammars (switch_core_session_t *session)
 Disable all grammars on a background speech detection handle. More...
 
switch_status_t switch_ivr_set_param_detect_speech (switch_core_session_t *session, const char *name, const char *val)
 
switch_status_t switch_ivr_detect_speech_start_input_timers (switch_core_session_t *session)
 Start input timers on a background speech detection handle. More...
 
switch_status_t switch_ivr_record_session (switch_core_session_t *session, char *file, uint32_t limit, switch_file_handle_t *fh)
 Record a session to disk. More...
 
switch_status_t switch_ivr_transfer_recordings (switch_core_session_t *orig_session, switch_core_session_t *new_session)
 
switch_status_t switch_ivr_eavesdrop_pop_eavesdropper (switch_core_session_t *session, switch_core_session_t **sessionp)
 
switch_status_t switch_ivr_eavesdrop_exec_all (switch_core_session_t *session, const char *app, const char *arg)
 
switch_status_t switch_ivr_eavesdrop_update_display (switch_core_session_t *session, const char *name, const char *number)
 
switch_status_t switch_ivr_eavesdrop_session (switch_core_session_t *session, const char *uuid, const char *require_group, switch_eavesdrop_flag_t flags)
 Eavesdrop on a another session. More...
 
switch_status_t switch_ivr_displace_session (switch_core_session_t *session, const char *file, uint32_t limit, const char *flags)
 displace the media for a session with the audio from a file More...
 
switch_status_t switch_ivr_stop_displace_session (switch_core_session_t *session, const char *file)
 Stop displacing a session. More...
 
switch_status_t switch_ivr_stop_record_session (switch_core_session_t *session, const char *file)
 Stop Recording a session. More...
 
switch_status_t switch_ivr_session_audio (switch_core_session_t *session, const char *cmd, const char *direction, int level)
 
switch_status_t switch_ivr_stop_session_audio (switch_core_session_t *session)
 
switch_status_t switch_ivr_inband_dtmf_session (switch_core_session_t *session)
 Start looking for DTMF inband. More...
 
switch_status_t switch_ivr_stop_inband_dtmf_session (switch_core_session_t *session)
 Stop looking for DTMF inband. More...
 
switch_status_t switch_ivr_inband_dtmf_generate_session (switch_core_session_t *session, switch_bool_t read_stream)
 Start generating DTMF inband. More...
 
switch_status_t switch_ivr_stop_inband_dtmf_generate_session (switch_core_session_t *session)
 Stop generating DTMF inband. More...
 
switch_status_t switch_ivr_session_echo (switch_core_session_t *session, switch_input_args_t *args)
 
  • NEEDDESC -
More...
 
switch_status_t switch_ivr_stop_tone_detect_session (switch_core_session_t *session)
 Stop looking for TONES. More...
 
switch_status_t switch_ivr_tone_detect_session (switch_core_session_t *session, const char *key, const char *tone_spec, const char *flags, time_t timeout, int hits, const char *app, const char *data, switch_tone_detect_callback_t callback)
 Start looking for TONES. More...
 
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 More...
 
switch_status_t switch_ivr_wait_for_silence (switch_core_session_t *session, uint32_t thresh, uint32_t silence_hits, uint32_t listen_hits, uint32_t timeout_ms, const char *file)
 
switch_status_t switch_ivr_gentones (switch_core_session_t *session, const char *script, int32_t loops, switch_input_args_t *args)
 
switch_status_t switch_ivr_record_file (_In_ switch_core_session_t *session, _In_ switch_file_handle_t *fh, _In_z_ const char *file, _In_opt_ switch_input_args_t *args, _In_ uint32_t limit)
 record a file from the session to a file More...
 
switch_status_t switch_play_and_get_digits (switch_core_session_t *session, uint32_t min_digits, uint32_t max_digits, uint32_t max_tries, uint32_t timeout, const char *valid_terminators, const char *audio_file, const char *bad_input_audio_file, const char *var_name, char *digit_buffer, uint32_t digit_buffer_length, const char *digits_regex, uint32_t digit_timeout, const char *transfer_on_failure)
 Play a sound and gather digits with the number of retries specified if the user doesn't give digits in the set time. More...
 
switch_status_t switch_ivr_speak_text_handle (switch_core_session_t *session, switch_speech_handle_t *sh, switch_codec_t *codec, switch_timer_t *timer, char *text, switch_input_args_t *args)
 
void switch_ivr_clear_speech_cache (switch_core_session_t *session)
 
switch_status_t switch_ivr_speak_text (switch_core_session_t *session, const char *tts_name, const char *voice_name, char *text, switch_input_args_t *args)
 Speak given text with given tts engine. More...
 
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)
 Make an outgoing call. More...
 
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)
 
void switch_ivr_bridge_display (switch_core_session_t *session, switch_core_session_t *peer_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. More...
 
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. More...
 
switch_status_t switch_ivr_session_transfer (_In_ switch_core_session_t *session, const char *extension, const char *dialplan, const char *context)
 Transfer an existing session to another location. More...
 
uint32_t switch_ivr_schedule_transfer (time_t runtime, const char *uuid, char *extension, char *dialplan, char *context)
 Transfer an existing session to another location in the future. More...
 
uint32_t switch_ivr_schedule_hangup (time_t runtime, const char *uuid, switch_call_cause_t cause, switch_bool_t bleg)
 Hangup an existing session in the future. More...
 
switch_status_t switch_ivr_uuid_bridge (const char *originator_uuid, const char *originatee_uuid)
 Bridge two existing sessions. More...
 
switch_status_t switch_ivr_media (const char *uuid, switch_media_flag_t flags)
 Signal a session to request direct media access to it's remote end. More...
 
switch_status_t switch_ivr_3p_media (const char *uuid, switch_media_flag_t flags)
 
switch_status_t switch_ivr_nomedia (const char *uuid, switch_media_flag_t flags)
 Signal a session to request indirect media allowing it to exchange media directly with another device. More...
 
switch_status_t switch_ivr_3p_nomedia (const char *uuid, switch_media_flag_t flags)
 
void switch_ivr_bg_media (const char *uuid, switch_media_flag_t flags, switch_bool_t on, switch_bool_t is3p, uint32_t delay)
 
switch_status_t switch_ivr_hold_uuid (const char *uuid, const char *message, switch_bool_t moh)
 Signal the session with a protocol specific hold message. More...
 
switch_status_t switch_ivr_hold_toggle_uuid (const char *uuid, const char *message, switch_bool_t moh)
 Toggles channel hold state of session. More...
 
switch_status_t switch_ivr_unhold_uuid (const char *uuid)
 Signal the session with a protocol specific unhold message. More...
 
switch_status_t switch_ivr_hold (switch_core_session_t *session, const char *message, switch_bool_t moh)
 Signal the session with a protocol specific hold message. More...
 
switch_status_t switch_ivr_unhold (switch_core_session_t *session)
 Signal the session with a protocol specific unhold message. More...
 
uint32_t switch_ivr_schedule_broadcast (time_t runtime, const char *uuid, const char *path, switch_media_flag_t flags)
 Signal the session to broadcast audio in the future. More...
 
switch_status_t switch_ivr_broadcast (const char *uuid, const char *path, switch_media_flag_t flags)
 Signal the session to broadcast audio. More...
 
void switch_ivr_broadcast_in_thread (switch_core_session_t *session, const char *app, int flags)
 
switch_status_t switch_ivr_transfer_variable (switch_core_session_t *sessa, switch_core_session_t *sessb, char *var)
 Transfer variables from one session to another. More...
 
switch_status_t switch_ivr_digit_stream_parser_new (switch_memory_pool_t *pool, switch_ivr_digit_stream_parser_t **parser)
 Create a digit stream parser object. More...
 
switch_status_t switch_ivr_digit_stream_parser_destroy (switch_ivr_digit_stream_parser_t *parser)
 Destroy a digit stream parser object. More...
 
switch_status_t switch_ivr_digit_stream_new (switch_ivr_digit_stream_parser_t *parser, switch_ivr_digit_stream_t **stream)
 Create a new digit stream object. More...
 
switch_status_t switch_ivr_digit_stream_destroy (switch_ivr_digit_stream_t **stream)
 Destroys a digit stream object. More...
 
switch_status_t switch_ivr_digit_stream_parser_set_event (switch_ivr_digit_stream_parser_t *parser, char *digits, void *data)
 Set a digit string to action mapping. More...
 
switch_status_t switch_ivr_digit_stream_parser_del_event (switch_ivr_digit_stream_parser_t *parser, char *digits)
 Delete a string to action mapping. More...
 
void * switch_ivr_digit_stream_parser_feed (switch_ivr_digit_stream_parser_t *parser, switch_ivr_digit_stream_t *stream, char digit)
 Feed digits collected into the stream for event match testing. More...
 
switch_status_t switch_ivr_digit_stream_reset (switch_ivr_digit_stream_t *stream)
 Reset the collected digit stream to nothing. More...
 
switch_status_t switch_ivr_digit_stream_parser_set_terminator (switch_ivr_digit_stream_parser_t *parser, char digit)
 Set a digit string terminator. More...
 

Detailed Description

A group of core functions to do IVR related functions designed to be building blocks for a higher level IVR interface.

Typedef Documentation

Definition at line 679 of file switch_ivr.h.

Definition at line 681 of file switch_ivr.h.

Function Documentation

switch_status_t switch_ivr_3p_media ( const char *  uuid,
switch_media_flag_t  flags 
)

Definition at line 1564 of file switch_ivr.c.

References CF_3P_MEDIA_REQUESTED, CF_BRIDGE_ORIGINATOR, CF_BRIDGED, CF_EARLY_MEDIA, CF_MEDIA_ACK, CF_MEDIA_SET, CF_MEDIA_TRANS, CF_PROXY_MODE, CF_REQ_MEDIA, switch_core_session_message::from, switch_core_session_message::message_id, switch_core_session_message::numeric_arg, SMF_IMMEDIATE, SMF_REBRIDGE, SMF_REPLYONLY_A, SMF_REPLYONLY_B, switch_assert, switch_channel_clear_flag(), switch_channel_clear_state_handler(), switch_channel_get_name(), switch_channel_get_variable, SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_flag, switch_channel_set_variable, switch_channel_test_flag(), switch_channel_wait_for_flag(), switch_core_session_get_channel(), switch_core_session_locate, switch_core_session_receive_message, switch_core_session_rwunlock(), SWITCH_FALSE, switch_ivr_uuid_bridge(), SWITCH_LOG_ERROR, switch_log_printf(), SWITCH_MESSAGE_INDICATE_3P_MEDIA, SWITCH_MESSAGE_INDICATE_CLEAR_PROGRESS, SWITCH_SIGNAL_BRIDGE_VARIABLE, SWITCH_STATUS_GENERR, SWITCH_STATUS_INUSE, SWITCH_STATUS_SUCCESS, SWITCH_TRUE, and switch_yield.

Referenced by media_thread_run().

1565 {
1566  const char *other_uuid = NULL;
1567  switch_channel_t *channel, *other_channel = NULL;
1568  switch_core_session_t *session, *other_session;
1569  switch_core_session_message_t msg = { 0 };
1571  uint8_t swap = 0;
1572  //switch_frame_t *read_frame = NULL;
1573 
1575  msg.from = __FILE__;
1576 
1577  if ((session = switch_core_session_locate(uuid))) {
1578  channel = switch_core_session_get_channel(session);
1579 
1581  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Operation is invalid\n");
1583  return SWITCH_STATUS_INUSE;
1584  }
1585 
1587 
1588  if ((flags & SMF_REBRIDGE) && !switch_channel_test_flag(channel, CF_BRIDGE_ORIGINATOR)) {
1589  swap = 1;
1590  }
1591 
1592 
1593  status = SWITCH_STATUS_SUCCESS;
1594 
1595  /* If we had early media in bypass mode before, it is no longer relevant */
1596  if (switch_channel_test_flag(channel, CF_EARLY_MEDIA)) {
1597  switch_core_session_message_t msg2 = { 0 };
1598 
1600  msg2.from = __FILE__;
1601  switch_core_session_receive_message(session, &msg2);
1602  }
1603 
1604  if ((flags & SMF_REPLYONLY_A)) {
1605  msg.numeric_arg = 1;
1606  }
1607 
1609 
1611  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't re-establsh media on %s\n", switch_channel_get_name(channel));
1614  return SWITCH_STATUS_GENERR;
1615  }
1616 
1617  if ((flags & SMF_REPLYONLY_B)) {
1618  msg.numeric_arg = 1;
1619  } else {
1620  msg.numeric_arg = 0;
1621  }
1622 
1623  if ((flags & SMF_IMMEDIATE)) {
1625  switch_yield(250000);
1626  } else {
1627  switch_channel_wait_for_flag(channel, CF_REQ_MEDIA, SWITCH_FALSE, 10000, NULL);
1628  switch_channel_wait_for_flag(channel, CF_MEDIA_ACK, SWITCH_TRUE, 10000, NULL);
1629  switch_channel_wait_for_flag(channel, CF_MEDIA_SET, SWITCH_TRUE, 10000, NULL);
1631  //switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
1632  }
1633 
1634  if ((flags & SMF_REBRIDGE)
1636  && (other_session = switch_core_session_locate(other_uuid))) {
1637 
1638  other_channel = switch_core_session_get_channel(other_session);
1639  switch_assert(other_channel != NULL);
1640 
1642  switch_channel_set_variable(other_channel, "rtp_secure_media", "optional");
1643 
1644  switch_core_session_receive_message(other_session, &msg);
1645  switch_channel_wait_for_flag(other_channel, CF_REQ_MEDIA, SWITCH_FALSE, 10000, NULL);
1646  switch_channel_wait_for_flag(other_channel, CF_MEDIA_ACK, SWITCH_TRUE, 10000, NULL);
1647  switch_channel_wait_for_flag(other_channel, CF_MEDIA_SET, SWITCH_TRUE, 10000, NULL);
1648  switch_channel_wait_for_flag(other_channel, CF_3P_MEDIA_REQUESTED, SWITCH_FALSE, 10000, NULL);
1649  //switch_core_session_read_frame(other_session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
1650  switch_channel_clear_state_handler(other_channel, NULL);
1651  switch_core_session_rwunlock(other_session);
1652  }
1653  if (other_channel) {
1654  switch_channel_clear_state_handler(channel, NULL);
1655  }
1656 
1659 
1660  if (other_channel) {
1661  if (swap) {
1662  switch_ivr_uuid_bridge(other_uuid, uuid);
1663  } else {
1664  switch_ivr_uuid_bridge(uuid, other_uuid);
1665  }
1666  switch_channel_wait_for_flag(channel, CF_BRIDGED, SWITCH_TRUE, 1000, NULL);
1667  switch_channel_wait_for_flag(other_channel, CF_BRIDGED, SWITCH_TRUE, 1000, NULL);
1668  }
1669  }
1670 
1671  return status;
1672 }
#define SWITCH_SIGNAL_BRIDGE_VARIABLE
Definition: switch_types.h:201
#define SWITCH_CHANNEL_SESSION_LOG(x)
switch_core_session_message_types_t message_id
Definition: switch_core.h:181
uint32_t switch_channel_test_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Test for presence of given flag on a given channel.
A message object designed to allow unlike technologies to exchange data.
Definition: switch_core.h:177
_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_yield(ms)
Wait a desired number of microseconds and yield the CPU.
Definition: switch_utils.h:908
void switch_channel_clear_state_handler(switch_channel_t *channel, const switch_state_handler_table_t *state_handler)
clear a state handler table from a given channel
#define switch_channel_get_variable(_c, _v)
switch_status_t switch_ivr_uuid_bridge(const char *originator_uuid, const char *originatee_uuid)
Bridge two existing sessions.
#define switch_core_session_receive_message(_session, _message)
Definition: switch_core.h:1217
void switch_core_session_rwunlock(_In_ switch_core_session_t *session)
Unlock a read or write lock on as given session.
switch_status_t
Common return values.
#define switch_core_session_locate(uuid_str)
Locate a session based on it's uuid.
Definition: switch_core.h:916
#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.
switch_status_t switch_channel_wait_for_flag(switch_channel_t *channel, switch_channel_flag_t want_flag, switch_bool_t pres, uint32_t to, switch_channel_t *super_channel)
void switch_channel_clear_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Clear given flag(s) from a channel.
#define switch_assert(expr)
#define switch_channel_set_variable(_channel, _var, _val)
char * switch_channel_get_name(switch_channel_t *channel)
Retrieve the name of a given channel.
switch_status_t switch_ivr_3p_nomedia ( const char *  uuid,
switch_media_flag_t  flags 
)

Definition at line 1774 of file switch_ivr.c.

References CF_3P_NOMEDIA_REQUESTED, CF_3P_NOMEDIA_REQUESTED_BLEG, CF_BRIDGE_ORIGINATOR, CF_MEDIA_ACK, CF_MEDIA_TRANS, CF_PROXY_MODE, CF_REDIRECT, CF_REQ_MEDIA, CF_RESET, CS_HIBERNATE, CS_PARK, switch_core_session_message::from, switch_core_session_message::message_id, SMF_FORCE, SMF_REBRIDGE, switch_core_session_message::string_arg, SWITCH_BRIDGE_VARIABLE, switch_channel_clear_flag(), switch_channel_get_variable, SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_flag, switch_channel_set_state, switch_channel_set_variable, switch_channel_test_flag(), switch_channel_wait_for_flag(), switch_channel_wait_for_state(), switch_core_session_get_channel(), switch_core_session_in_thread(), switch_core_session_locate, switch_core_session_receive_message, switch_core_session_rwunlock(), SWITCH_FALSE, switch_ivr_signal_bridge(), SWITCH_LOG_ERROR, switch_log_printf(), SWITCH_MESSAGE_INDICATE_3P_NOMEDIA, SWITCH_R_SDP_VARIABLE, SWITCH_STATUS_GENERR, SWITCH_STATUS_INUSE, SWITCH_STATUS_SUCCESS, SWITCH_TRUE, and switch_yield.

Referenced by audio_bridge_thread(), and media_thread_run().

1775 {
1776  const char *other_uuid;
1777  switch_channel_t *channel, *other_channel = NULL;
1778  switch_core_session_t *session, *other_session = NULL;
1779  switch_core_session_message_t msg = { 0 };
1781  uint8_t swap = 0;
1782 
1784  msg.from = __FILE__;
1785 
1786  if ((session = switch_core_session_locate(uuid))) {
1787  status = SWITCH_STATUS_SUCCESS;
1788  channel = switch_core_session_get_channel(session);
1789 
1790  if (switch_channel_test_flag(channel, CF_MEDIA_TRANS) || (!(flags & SMF_FORCE) && switch_channel_test_flag(channel, CF_PROXY_MODE))) {
1791  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Operation is invalid\n");
1793  return SWITCH_STATUS_INUSE;
1794  }
1795 
1797 
1798  if ((flags & SMF_REBRIDGE) && !switch_channel_test_flag(channel, CF_BRIDGE_ORIGINATOR)) {
1799  swap = 1;
1800  }
1801 
1802  if ((flags & SMF_FORCE) || !switch_channel_test_flag(channel, CF_PROXY_MODE)) {
1803  if ((flags & SMF_REBRIDGE) && (other_uuid = switch_channel_get_variable(channel, SWITCH_BRIDGE_VARIABLE)) &&
1804  (other_session = switch_core_session_locate(other_uuid))) {
1805  other_channel = switch_core_session_get_channel(other_session);
1806 
1809 
1810  switch_channel_set_flag(other_channel, CF_RESET);
1811  switch_channel_set_flag(other_channel, CF_REDIRECT);
1812 
1815  switch_core_session_receive_message(session, &msg);
1816 
1817  if (!switch_core_session_in_thread(session)) {
1819  }
1820 
1821  switch_channel_set_state(other_channel, CS_PARK);
1822 
1823  if (switch_core_session_in_thread(session)) {
1824  switch_yield(100000);
1825  } else {
1826  switch_channel_wait_for_state(other_channel, channel, CS_PARK);
1827  }
1828 
1829 
1830  if (!switch_core_session_in_thread(session)) {
1831  switch_channel_wait_for_state(channel, NULL, CS_PARK);
1832  }
1833 
1834  switch_channel_wait_for_flag(channel, CF_REQ_MEDIA, SWITCH_FALSE, 10000, NULL);
1835  switch_channel_wait_for_flag(channel, CF_MEDIA_ACK, SWITCH_TRUE, 10000, NULL);
1837 
1841 
1842 
1843  switch_core_session_receive_message(other_session, &msg);
1844  switch_channel_wait_for_flag(other_channel, CF_REQ_MEDIA, SWITCH_FALSE, 10000, NULL);
1845  switch_channel_wait_for_flag(other_channel, CF_MEDIA_ACK, SWITCH_TRUE, 10000, NULL);
1847  }
1848 
1849  if (other_channel) {
1850  if (swap) {
1851  switch_ivr_signal_bridge(other_session, session);
1852  } else {
1853  switch_ivr_signal_bridge(session, other_session);
1854  }
1855 
1856  if (switch_core_session_in_thread(session)) {
1857  switch_yield(100000);
1858  } else {
1859  switch_channel_wait_for_state(other_channel, channel, CS_HIBERNATE);
1860  }
1861 
1862  if (!switch_core_session_in_thread(session)) {
1863  switch_channel_wait_for_state(channel, other_channel, CS_HIBERNATE);
1864  }
1865  switch_core_session_rwunlock(other_session);
1866  }
1867  }
1868 
1871  }
1872 
1873 
1874 
1875  return status;
1876 }
#define SWITCH_CHANNEL_SESSION_LOG(x)
switch_core_session_message_types_t message_id
Definition: switch_core.h:181
#define switch_channel_set_state(channel, state)
Set the current state of a channel.
uint32_t switch_channel_test_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Test for presence of given flag on a given channel.
A message object designed to allow unlike technologies to exchange data.
Definition: switch_core.h:177
_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_wait_for_state(switch_channel_t *channel, switch_channel_t *other_channel, switch_channel_state_t want_state)
#define switch_yield(ms)
Wait a desired number of microseconds and yield the CPU.
Definition: switch_utils.h:908
#define switch_channel_get_variable(_c, _v)
#define SWITCH_BRIDGE_VARIABLE
Definition: switch_types.h:199
#define switch_core_session_receive_message(_session, _message)
Definition: switch_core.h:1217
void switch_core_session_rwunlock(_In_ switch_core_session_t *session)
Unlock a read or write lock on as given session.
#define SWITCH_R_SDP_VARIABLE
Definition: switch_types.h:196
switch_status_t
Common return values.
#define switch_core_session_locate(uuid_str)
Locate a session based on it's uuid.
Definition: switch_core.h:916
#define switch_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.
switch_status_t switch_channel_wait_for_flag(switch_channel_t *channel, switch_channel_flag_t want_flag, switch_bool_t pres, uint32_t to, switch_channel_t *super_channel)
void switch_channel_clear_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Clear given flag(s) from a channel.
switch_status_t switch_ivr_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)
switch_bool_t switch_core_session_in_thread(switch_core_session_t *session)
switch_status_t switch_ivr_activate_unicast ( switch_core_session_t session,
char *  local_ip,
switch_port_t  local_port,
char *  remote_ip,
switch_port_t  remote_port,
char *  transport,
char *  flags 
)

Definition at line 398 of file switch_ivr.c.

References switch_codec_implementation::actual_samples_per_second, switch_frame::buflen, CF_UNICAST, switch_frame::codec, switch_frame::data, fail, switch_unicast_conninfo::flag_mutex, switch_codec::implementation, switch_unicast_conninfo::local_addr, switch_unicast_conninfo::local_ip, switch_unicast_conninfo::local_port, switch_codec_implementation::microseconds_per_packet, switch_unicast_conninfo::read_codec, switch_unicast_conninfo::remote_addr, switch_unicast_conninfo::remote_ip, switch_unicast_conninfo::remote_port, switch_unicast_conninfo::session, switch_unicast_conninfo::socket, SUF_NATIVE, SUF_READY, switch_assert, SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_flag, switch_channel_set_private(), SWITCH_CODEC_FLAG_DECODE, SWITCH_CODEC_FLAG_ENCODE, switch_core_codec_init, switch_core_session_alloc, switch_core_session_get_channel(), switch_core_session_get_pool(), switch_core_session_get_read_codec(), switch_core_session_strdup, SWITCH_LOG_CRIT, SWITCH_LOG_DEBUG, SWITCH_LOG_ERROR, SWITCH_LOG_INFO, switch_log_printf(), switch_mutex_init(), SWITCH_MUTEX_NESTED, switch_set_flag, switch_set_flag_locked, switch_sockaddr_info_get(), switch_socket_bind(), switch_socket_create(), SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_test_flag, SWITCH_UNSPEC, switch_unicast_conninfo::transport, switch_unicast_conninfo::type, switch_unicast_conninfo::write_frame, and switch_unicast_conninfo::write_frame_data.

Referenced by switch_ivr_parse_event().

402 {
404  switch_unicast_conninfo_t *conninfo = switch_core_session_alloc(session, sizeof(*conninfo));
405  switch_codec_t *read_codec;
406 
407  switch_assert(conninfo != NULL);
408 
409  conninfo->local_ip = switch_core_session_strdup(session, local_ip);
410  conninfo->local_port = local_port;
411 
412  conninfo->remote_ip = switch_core_session_strdup(session, remote_ip);
413  conninfo->remote_port = remote_port;
414  conninfo->session = session;
415 
416  if (!strcasecmp(transport, "udp")) {
417  conninfo->type = AF_INET;
418  conninfo->transport = SOCK_DGRAM;
419  } else if (!strcasecmp(transport, "tcp")) {
420  conninfo->type = AF_INET;
421  conninfo->transport = SOCK_STREAM;
422  } else {
423  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid transport %s\n", transport);
424  goto fail;
425  }
426 
427  if (flags) {
428  if (strstr(flags, "native")) {
429  switch_set_flag(conninfo, SUF_NATIVE);
430  }
431  }
432 
434 
435  read_codec = switch_core_session_get_read_codec(session);
436 
437  if (!switch_test_flag(conninfo, SUF_NATIVE)) {
438  if (switch_core_codec_init(&conninfo->read_codec,
439  "L16",
440  NULL,
441  NULL,
443  read_codec->implementation->microseconds_per_packet / 1000,
447  "Raw Codec Activation Success L16@%uhz 1 channel %dms\n",
449  } else {
450  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Raw Codec Activation Failed L16@%uhz 1 channel %dms\n",
452  goto fail;
453  }
454  }
455 
456  conninfo->write_frame.data = conninfo->write_frame_data;
457  conninfo->write_frame.buflen = sizeof(conninfo->write_frame_data);
458  conninfo->write_frame.codec = switch_test_flag(conninfo, SUF_NATIVE) ? read_codec : &conninfo->read_codec;
459 
460  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "connect %s:%d->%s:%d\n",
461  conninfo->local_ip, conninfo->local_port, conninfo->remote_ip, conninfo->remote_port);
462 
463  if (switch_sockaddr_info_get(&conninfo->local_addr,
464  conninfo->local_ip, SWITCH_UNSPEC, conninfo->local_port, 0,
466  goto fail;
467  }
468 
469  if (switch_sockaddr_info_get(&conninfo->remote_addr,
470  conninfo->remote_ip, SWITCH_UNSPEC, conninfo->remote_port, 0,
472  goto fail;
473  }
474 
475  if (switch_socket_create(&conninfo->socket, AF_INET, SOCK_DGRAM, 0, switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) {
476  if (switch_socket_bind(conninfo->socket, conninfo->local_addr) != SWITCH_STATUS_SUCCESS) {
477  goto fail;
478  }
479  } else {
480  goto fail;
481  }
482 
483  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Created unicast connection %s:%d->%s:%d\n",
484  conninfo->local_ip, conninfo->local_port, conninfo->remote_ip, conninfo->remote_port);
485  switch_channel_set_private(channel, "unicast", conninfo);
488  return SWITCH_STATUS_SUCCESS;
489 
490  fail:
491 
492  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Failure creating unicast connection %s:%d->%s:%d\n",
493  conninfo->local_ip, conninfo->local_port, conninfo->remote_ip, conninfo->remote_port);
494  return SWITCH_STATUS_FALSE;
495 }
switch_sockaddr_t * local_addr
Definition: switch_ivr.h:57
switch_socket_t * socket
Definition: switch_ivr.h:52
#define SWITCH_CHANNEL_SESSION_LOG(x)
#define switch_set_flag(obj, flag)
Set a flag on an arbitrary object.
Definition: switch_utils.h:631
switch_status_t switch_socket_bind(switch_socket_t *sock, switch_sockaddr_t *sa)
Definition: switch_apr.c:719
switch_status_t switch_channel_set_private(switch_channel_t *channel, const char *key, const void *private_info)
Set private data on channel.
#define fail()
Definition: tone2wav.c:70
switch_sockaddr_t * remote_addr
Definition: switch_ivr.h:58
switch_codec_t * codec
Definition: switch_frame.h:45
switch_codec_t * switch_core_session_get_read_codec(_In_ switch_core_session_t *session)
Retrieve the read codec from a given session.
_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_MUTEX_NESTED
Definition: switch_apr.h:318
const switch_codec_implementation_t * implementation
uint32_t buflen
Definition: switch_frame.h:59
switch_port_t remote_port
Definition: switch_ivr.h:56
switch_codec_t read_codec
Definition: switch_ivr.h:49
switch_status_t switch_mutex_init(switch_mutex_t **lock, unsigned int flags, switch_memory_pool_t *pool)
Definition: switch_apr.c:270
#define switch_set_flag_locked(obj, flag)
Set a flag on an arbitrary object while locked.
Definition: switch_utils.h:638
#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:1602
switch_mutex_t * flag_mutex
Definition: switch_ivr.h:59
switch_frame_t write_frame
Definition: switch_ivr.h:50
switch_status_t switch_socket_create(switch_socket_t **new_sock, int family, int type, int protocol, switch_memory_pool_t *pool)
Definition: switch_apr.c:704
#define SWITCH_UNSPEC
Definition: switch_apr.h:1022
#define switch_channel_set_flag(_c, _f)
switch_core_session_t * session
Definition: switch_ivr.h:48
switch_port_t local_port
Definition: switch_ivr.h:54
#define switch_core_session_alloc(_session, _memory)
Allocate memory from a session's pool.
Definition: switch_core.h:694
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:624
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
#define switch_core_session_strdup(_session, _todup)
Copy a string using memory allocation from a session's pool.
Definition: switch_core.h:717
#define switch_assert(expr)
switch_status_t switch_sockaddr_info_get(switch_sockaddr_t **sa, const char *hostname, int32_t family, switch_port_t port, int32_t flags, switch_memory_pool_t *pool)
Definition: switch_apr.c:817
switch_byte_t write_frame_data[SWITCH_RECOMMENDED_BUFFER_SIZE]
Definition: switch_ivr.h:51
switch_memory_pool_t * switch_core_session_get_pool(_In_ switch_core_session_t *session)
Retrieve the memory pool from a session.
void switch_ivr_bg_media ( const char *  uuid,
switch_media_flag_t  flags,
switch_bool_t  on,
switch_bool_t  is3p,
uint32_t  delay 
)

Definition at line 2014 of file switch_ivr.c.

References media_job_t::delay, media_job_t::flags, switch_thread_data_s::func, media_job_t::is3p, media_thread_run(), switch_thread_data_s::obj, media_job_t::on, pool, switch_thread_data_s::pool, media_job_t::pool, switch_core_alloc, switch_core_new_memory_pool, switch_core_strdup, switch_thread_pool_launch_thread(), and media_job_t::uuid.

Referenced by switch_core_media_toggle_hold().

2015 {
2018  media_job_t *job;
2019 
2021  td = switch_core_alloc(pool, sizeof(*td));
2022  job = switch_core_alloc(pool, sizeof(*job));
2023  td->func = media_thread_run;
2024  job->pool = pool;
2025  job->uuid = switch_core_strdup(pool, uuid);
2026  job->flags = flags;
2027  job->on = on;
2028  job->is3p = is3p;
2029  job->delay = delay;
2030  td->obj = job;
2031  td->pool = pool;
2033 
2034 }
const char * uuid
Definition: switch_ivr.c:1981
#define switch_core_new_memory_pool(p)
Create a new sub memory pool from the core's master pool.
Definition: switch_core.h:631
#define switch_core_strdup(_pool, _todup)
Copy a string using memory allocation from a given pool.
Definition: switch_core.h:729
switch_memory_pool_t * pool
switch_memory_pool_t * pool
Definition: switch_core.h:69
switch_memory_pool_t * pool
Definition: switch_ivr.c:1980
switch_bool_t on
Definition: switch_ivr.c:1983
uint32_t delay
Definition: switch_ivr.c:1985
#define switch_core_alloc(_pool, _mem)
Allocate memory directly from a memory pool.
Definition: switch_core.h:682
switch_thread_start_t func
Definition: switch_core.h:66
static void *SWITCH_THREAD_FUNC media_thread_run(switch_thread_t *thread, void *obj)
Definition: switch_ivr.c:1988
struct apr_pool_t switch_memory_pool_t
switch_media_flag_t flags
Definition: switch_ivr.c:1982
switch_bool_t is3p
Definition: switch_ivr.c:1984
switch_status_t switch_thread_pool_launch_thread(switch_thread_data_t **tdp)
void switch_ivr_bridge_display ( switch_core_session_t session,
switch_core_session_t peer_session 
)

Definition at line 293 of file switch_ivr_bridge.c.

References send_display().

Referenced by audio_bridge_thread(), and switch_ivr_signal_bridge().

294 {
295 
296  send_display(session, peer_session);
297  send_display(peer_session, session);
298 
299 }
static void send_display(switch_core_session_t *session, switch_core_session_t *peer_session)
switch_status_t switch_ivr_broadcast ( const char *  uuid,
const char *  path,
switch_media_flag_t  flags 
)

Signal the session to broadcast audio.

Parameters
uuidthe uuid of the session to broadcast on
paththe path data of the broadcast "/path/to/file.wav [<timer name>]" or "speak:<engine>|<voice>|<Text to say>"
flagsflags to send to the request (SMF_ECHO_BRIDGED to send the broadcast to both sides of the call)
Returns
SWITCH_STATUS_SUCCESS if all is well

Definition at line 4963 of file switch_ivr_async.c.

References CF_BROADCAST_DROP_MEDIA, CF_PROXY_MODE, SAF_MEDIA_TAP, SMF_ECHO_ALEG, SMF_ECHO_BLEG, SMF_EXEC_INLINE, SMF_HOLD_BLEG, SMF_LOOP, SMF_PRIORITY, SMF_REBRIDGE, switch_assert, switch_channel_get_partner_uuid(), switch_channel_set_flag, switch_channel_test_flag(), switch_core_session_execute_application, switch_core_session_execute_application_get_flags(), switch_core_session_get_app_flags(), switch_core_session_get_channel(), switch_core_session_locate, switch_core_session_queue_private_event(), switch_core_session_rwunlock(), switch_event_add_header(), switch_event_add_header_string(), SWITCH_EVENT_COMMAND, switch_event_create, switch_ivr_media(), switch_safe_free, SWITCH_STACK_BOTTOM, SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.

Referenced by bcast_thread(), meta_on_dtmf(), switch_core_media_toggle_hold(), switch_core_session_send_dtmf(), switch_ivr_hold(), switch_ivr_parse_event(), switch_ivr_soft_hold(), and SWITCH_STANDARD_SCHED_FUNC().

4964 {
4965  switch_channel_t *channel;
4966  switch_core_session_t *session, *master;
4967  switch_event_t *event;
4968  switch_core_session_t *other_session = NULL;
4969  const char *other_uuid = NULL;
4970  char *app = "playback";
4971  char *cause = NULL;
4972  char *mypath;
4973  char *p;
4974  int app_flags = 0, nomedia = 0;
4975 
4976  switch_assert(path);
4977 
4978  if (!(master = session = switch_core_session_locate(uuid))) {
4979  return SWITCH_STATUS_FALSE;
4980  }
4981 
4982  channel = switch_core_session_get_channel(session);
4983 
4984  mypath = strdup(path);
4985  assert(mypath);
4986 
4987  if ((p = strchr(mypath, ':')) && *(p + 1) == ':') {
4988  app = mypath;
4989  *p++ = '\0';
4990  *p++ = '\0';
4991  path = p;
4992  }
4993 
4994  if (switch_channel_test_flag(channel, CF_PROXY_MODE)) {
4995  nomedia = 1;
4997  }
4998 
4999  if ((cause = strchr(app, '!'))) {
5000  *cause++ = '\0';
5001  if (!cause) {
5002  cause = "normal_clearing";
5003  }
5004  }
5005 
5006  if ((flags & SMF_ECHO_BLEG) && (other_uuid = switch_channel_get_partner_uuid(channel))
5007  && (other_session = switch_core_session_locate(other_uuid))) {
5008  if ((flags & SMF_EXEC_INLINE)) {
5009  switch_core_session_execute_application_get_flags(other_session, app, path, &app_flags);
5010  nomedia = 0;
5011  } else {
5012  switch_core_session_get_app_flags(app, &app_flags);
5014  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-command", "execute");
5015  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "execute-app-name", app);
5016  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "execute-app-arg", path);
5017  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, (flags & SMF_PRIORITY) ? "event-lock-pri" : "event-lock", "true");
5018 
5019  switch_event_add_header(event, SWITCH_STACK_BOTTOM, "lead-frames", "%d", 5);
5020 
5021  if ((flags & SMF_LOOP)) {
5022  switch_event_add_header(event, SWITCH_STACK_BOTTOM, "loops", "%d", -1);
5023  }
5024 
5025  if ((flags & SMF_HOLD_BLEG)) {
5026  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "hold-bleg", "true");
5027  }
5028 
5029  switch_core_session_queue_private_event(other_session, &event, (flags & SMF_PRIORITY));
5030  }
5031  }
5032 
5033  switch_core_session_rwunlock(other_session);
5034  master = other_session;
5035  other_session = NULL;
5036  }
5037 
5038  if ((app_flags & SAF_MEDIA_TAP)) {
5039  nomedia = 0;
5040  }
5041 
5042  if ((flags & SMF_ECHO_ALEG)) {
5043  if ((flags & SMF_EXEC_INLINE)) {
5044  nomedia = 0;
5045  switch_core_session_execute_application(session, app, path);
5046  } else {
5048  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-command", "execute");
5049  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "execute-app-name", app);
5050  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "execute-app-arg", path);
5051  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, (flags & SMF_PRIORITY) ? "event-lock-pri" : "event-lock", "true");
5052  switch_event_add_header(event, SWITCH_STACK_BOTTOM, "lead-frames", "%d", 5);
5053 
5054  if ((flags & SMF_LOOP)) {
5055  switch_event_add_header(event, SWITCH_STACK_BOTTOM, "loops", "%d", -1);
5056  }
5057  if ((flags & SMF_HOLD_BLEG)) {
5058  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "hold-bleg", "true");
5059  }
5060 
5061  switch_core_session_queue_private_event(session, &event, (flags & SMF_PRIORITY));
5062 
5063  if (nomedia)
5065  }
5066  }
5067  master = session;
5068  }
5069 
5070  if (cause) {
5072  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-command", "execute");
5073  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "execute-app-name", "hangup");
5074  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "execute-app-arg", cause);
5075  switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, (flags & SMF_PRIORITY) ? "event-lock-pri" : "event-lock", "true");
5076  switch_core_session_queue_private_event(session, &event, (flags & SMF_PRIORITY));
5077  }
5078  }
5079 
5081  switch_safe_free(mypath);
5082 
5083  return SWITCH_STATUS_SUCCESS;
5084 }
const char * switch_channel_get_partner_uuid(switch_channel_t *channel)
switch_status_t switch_event_add_header(switch_event_t *event, switch_stack_t stack, const char *header_name, const char *fmt,...) PRINTF_FUNCTION(4
Add a header to an event.
Representation of an event.
Definition: switch_event.h:80
switch_status_t switch_ivr_media(const char *uuid, switch_media_flag_t flags)
Signal a session to request direct media access to it's remote end.
Definition: switch_ivr.c:1674
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 switch_core_session_execute_application(_a, _b, _c)
Execute an application on a session.
Definition: switch_core.h:1103
_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_get_app_flags(const char *app, int32_t *flags)
switch_status_t switch_core_session_execute_application_get_flags(_In_ switch_core_session_t *session, _In_ const char *app, _In_opt_z_ const char *arg, _Out_opt_ int32_t *flags)
Execute an application on a session.
switch_status_t switch_event_add_header_string(switch_event_t *event, switch_stack_t stack, const char *header_name, const char *data)
Add a string header to an event.
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:789
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_core_session_queue_private_event(_In_ switch_core_session_t *session, _Inout_ switch_event_t **event, switch_bool_t priority)
Queue a private event on a given session.
#define switch_core_session_locate(uuid_str)
Locate a session based on it's uuid.
Definition: switch_core.h:916
#define switch_event_create(event, id)
Create a new event assuming it will not be custom event and therefore hiding the unused parameters...
Definition: switch_event.h:383
#define switch_channel_set_flag(_c, _f)
#define switch_assert(expr)
void switch_ivr_broadcast_in_thread ( switch_core_session_t session,
const char *  app,
int  flags 
)

Definition at line 3919 of file switch_ivr_async.c.

References bch_t::app, bcast_thread(), bch_t::flags, pool, bch_t::session, switch_assert, switch_core_session_alloc, switch_core_session_get_pool(), switch_thread_create(), SWITCH_THREAD_STACKSIZE, switch_threadattr_create(), switch_threadattr_detach_set(), switch_threadattr_stacksize_set(), and thread.

Referenced by meta_on_dtmf().

3920 {
3922  switch_threadattr_t *thd_attr = NULL;
3924  bch_t *bch;
3925 
3926  switch_assert(session);
3927 
3928  pool = switch_core_session_get_pool(session);
3929 
3930  bch = switch_core_session_alloc(session, sizeof(*bch));
3931  bch->session = session;
3932  bch->app = app;
3933  bch->flags = flags;
3934 
3935 
3936  switch_threadattr_create(&thd_attr, pool);
3937  switch_threadattr_detach_set(thd_attr, 1);
3939  switch_thread_create(&thread, thd_attr, bcast_thread, bch, pool);
3940 }
static void *SWITCH_THREAD_FUNC bcast_thread(switch_thread_t *thread, void *obj)
switch_status_t switch_threadattr_stacksize_set(switch_threadattr_t *attr, switch_size_t stacksize)
Definition: switch_apr.c:660
switch_memory_pool_t * pool
const char * app
static switch_thread_t * thread
Definition: switch_log.c:279
switch_status_t switch_threadattr_detach_set(switch_threadattr_t *attr, int32_t on)
Definition: switch_apr.c:655
#define SWITCH_THREAD_STACKSIZE
Definition: switch_types.h:551
struct apr_thread_t switch_thread_t
Definition: switch_apr.h:941
switch_core_session_t * session
#define switch_core_session_alloc(_session, _memory)
Allocate memory from a session's pool.
Definition: switch_core.h:694
struct apr_pool_t switch_memory_pool_t
switch_status_t switch_threadattr_create(switch_threadattr_t **new_attr, switch_memory_pool_t *pool)
Definition: switch_apr.c:642
switch_status_t switch_thread_create(switch_thread_t **new_thread, switch_threadattr_t *attr, switch_thread_start_t func, void *data, switch_memory_pool_t *cont)
Definition: switch_apr.c:675
#define switch_assert(expr)
switch_memory_pool_t * switch_core_session_get_pool(_In_ switch_core_session_t *session)
Retrieve the memory pool from a session.
void switch_ivr_clear_speech_cache ( switch_core_session_t session)

Definition at line 2629 of file switch_ivr_play_say.c.

References cached_speech_handle::codec, switch_timer::interval, cached_speech_handle::sh, switch_speech_handle::speech_interface, SWITCH_CACHE_SPEECH_HANDLES_OBJ_NAME, switch_channel_get_private(), switch_channel_set_private(), switch_core_codec_destroy(), switch_core_session_get_channel(), switch_core_speech_close(), switch_core_timer_destroy(), SWITCH_SPEECH_FLAG_NONE, and cached_speech_handle::timer.

Referenced by switch_core_session_perform_destroy(), and switch_ivr_speak_text().

2630 {
2631  cached_speech_handle_t *cache_obj = NULL;
2633 
2636  if (cache_obj->timer.interval) {
2637  switch_core_timer_destroy(&cache_obj->timer);
2638  }
2639  if (cache_obj->sh.speech_interface) {
2640  switch_core_speech_close(&cache_obj->sh, &flags);
2641  }
2642  switch_core_codec_destroy(&cache_obj->codec);
2644  }
2645 }
switch_status_t switch_channel_set_private(switch_channel_t *channel, const char *key, const void *private_info)
Set private data on channel.
uint32_t switch_speech_flag_t
switch_status_t switch_core_codec_destroy(switch_codec_t *codec)
Destroy an initalized codec handle.
#define SWITCH_CACHE_SPEECH_HANDLES_OBJ_NAME
Definition: switch_types.h:187
_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_speech_close(switch_speech_handle_t *sh, switch_speech_flag_t *flags)
Close an open speech handle.
switch_speech_interface_t * speech_interface
switch_speech_handle_t sh
switch_status_t switch_core_timer_destroy(switch_timer_t *timer)
Destroy an allocated timer.
void * switch_channel_get_private(switch_channel_t *channel, const char *key)
Retrieve private from a given 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.

Parameters
sessionthe session to read.
argsarguements to pass for callbacks etc
timeouta timeout in milliseconds
Returns
SWITCH_STATUS_SUCCESS to keep the collection moving.

Definition at line 1173 of file switch_ivr.c.

References arg_recursion_check_start, arg_recursion_check_stop, CF_BREAK, CF_SERVICE, switch_dtmf_t::digit, switch_channel_clear_flag(), switch_channel_dequeue_dtmf(), switch_channel_has_dtmf(), switch_channel_ready, switch_channel_test_flag(), switch_cond_next(), switch_core_session_dequeue_event(), switch_core_session_get_channel(), switch_core_session_read_frame(), switch_event_destroy(), SWITCH_FALSE, SWITCH_INPUT_TYPE_DTMF, SWITCH_INPUT_TYPE_EVENT, SWITCH_IO_FLAG_NONE, switch_ivr_dmachine_feed(), switch_ivr_dmachine_ping(), switch_ivr_parse_all_events(), switch_micro_time_now(), SWITCH_READ_ACCEPTABLE, SWITCH_STATUS_BREAK, SWITCH_STATUS_GENERR, SWITCH_STATUS_SUCCESS, SWITCH_STATUS_TIMEOUT, and switch_frame::user_data.

Referenced by CoreSession::collectDigits(), enterprise_originate_ringback_thread(), fs_switch_ivr_collect_digits_callback(), and switch_ivr_soft_hold().

1175 {
1178  switch_time_t abs_started = 0, digit_started = 0;
1179  uint32_t abs_elapsed = 0, digit_elapsed = 0;
1180 
1181  if (!args) {
1182  return SWITCH_STATUS_GENERR;
1183  }
1184 
1186 
1187  if (abs_timeout) {
1188  abs_started = switch_micro_time_now();
1189  }
1190  if (digit_timeout) {
1191  digit_started = switch_micro_time_now();
1192  }
1193 
1194  while (switch_channel_ready(channel)) {
1195  switch_frame_t *read_frame = NULL;
1196  switch_event_t *event;
1197  switch_dtmf_t dtmf = { 0 };
1198 
1199  if (switch_channel_test_flag(channel, CF_BREAK)) {
1201  status = SWITCH_STATUS_BREAK;
1202  break;
1203  }
1204 
1205  if (abs_timeout) {
1206  abs_elapsed = (uint32_t) ((switch_micro_time_now() - abs_started) / 1000);
1207  if (abs_elapsed >= abs_timeout) {
1208  status = SWITCH_STATUS_TIMEOUT;
1209  break;
1210  }
1211  }
1212  if (digit_timeout) {
1213  digit_elapsed = (uint32_t) ((switch_micro_time_now() - digit_started) / 1000);
1214  if (digit_elapsed >= digit_timeout) {
1215  status = SWITCH_STATUS_TIMEOUT;
1216  break;
1217  }
1218  }
1219 
1220 
1221  switch_ivr_parse_all_events(session);
1222 
1223 
1224  if (switch_channel_has_dtmf(channel)) {
1225  if (!args->input_callback && !args->buf && !args->dmachine) {
1226  status = SWITCH_STATUS_BREAK;
1227  break;
1228  }
1229  switch_channel_dequeue_dtmf(channel, &dtmf);
1230 
1231  if (args->dmachine) {
1232  char ds[2] = {dtmf.digit, '\0'};
1233  if ((status = switch_ivr_dmachine_feed(args->dmachine, ds, NULL)) != SWITCH_STATUS_SUCCESS) {
1234  break;
1235  }
1236  }
1237 
1238  if (args->input_callback) {
1239  status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen);
1240  }
1241 
1242  if (digit_timeout) {
1243  digit_started = switch_micro_time_now();
1244  }
1245  }
1246 
1248  switch_status_t ostatus = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen);
1249  if (ostatus != SWITCH_STATUS_SUCCESS) {
1250  status = ostatus;
1251  }
1252  switch_event_destroy(&event);
1253  }
1254 
1255  if (status != SWITCH_STATUS_SUCCESS) {
1256  break;
1257  }
1258 
1259  if (switch_channel_test_flag(channel, CF_SERVICE)) {
1260  switch_cond_next();
1261  } else {
1262  status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
1263  }
1264 
1265  if (!SWITCH_READ_ACCEPTABLE(status)) {
1266  break;
1267  }
1268 
1269  if (args && args->dmachine) {
1270  if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL)) != SWITCH_STATUS_SUCCESS) {
1271  break;
1272  }
1273  }
1274 
1275  if (read_frame && args && (args->read_frame_callback)) {
1276  if ((status = args->read_frame_callback(session, read_frame, args->user_data)) != SWITCH_STATUS_SUCCESS) {
1277  break;
1278  }
1279  }
1280  }
1281 
1283 
1284  return status;
1285 }
switch_time_t switch_micro_time_now(void)
Get the current epoch time in microseconds.
Definition: switch_time.c:310
switch_status_t switch_ivr_dmachine_feed(switch_ivr_dmachine_t *dmachine, const char *digits, switch_ivr_dmachine_match_t **match)
Representation of an event.
Definition: switch_event.h:80
#define switch_channel_ready(_channel)
#define arg_recursion_check_stop(_args)
switch_status_t switch_ivr_parse_all_events(switch_core_session_t *session)
Parse all commands from an event.
Definition: switch_ivr.c:867
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.
_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.
int64_t switch_time_t
Definition: switch_apr.h:188
switch_status_t switch_channel_dequeue_dtmf(_In_ switch_channel_t *channel, _In_ switch_dtmf_t *dtmf)
Retrieve DTMF digits from a given channel.
switch_input_callback_function_t input_callback
An abstraction of a data frame.
Definition: switch_frame.h:43
#define arg_recursion_check_start(_args)
void switch_cond_next(void)
Definition: switch_time.c:638
switch_read_frame_callback_function_t read_frame_callback
switch_status_t
Common return values.
switch_status_t switch_core_session_dequeue_event(_In_ switch_core_session_t *session, _Out_ switch_event_t **event, switch_bool_t force)
DE-Queue an event on a given session.
switch_size_t switch_channel_has_dtmf(_In_ switch_channel_t *channel)
Test for presence of DTMF on a given channel.
switch_status_t switch_ivr_dmachine_ping(switch_ivr_dmachine_t *dmachine, switch_ivr_dmachine_match_t **match_p)
void switch_event_destroy(switch_event_t **event)
Destroy an event.
void switch_channel_clear_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Clear given flag(s) from a channel.
#define SWITCH_READ_ACCEPTABLE(status)
Definition: switch_utils.h:995
switch_ivr_dmachine_t * dmachine
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.

Parameters
sessionthe session to read.
bufstrig to write to
buflenmax size of buf
maxdigitsmax number of digits to read
terminatorsdigits to end the collection
terminatoractual digit that caused the collection to end (if any)
first_timeouttimeout in ms
digit_timeoutdigit timeout in ms
abs_timeoutabs timeout in ms
Returns
SWITCH_STATUS_SUCCESS to keep the collection moving.

Definition at line 1287 of file switch_ivr.c.

References switch_frame::buflen, CF_SERVICE, switch_frame::codec, switch_frame::data, switch_frame::datalen, switch_codec_implementation::decoded_bytes_per_packet, switch_dtmf_t::digit, switch_codec_implementation::microseconds_per_packet, switch_codec_implementation::number_of_channels, switch_frame::samples, switch_codec_implementation::samples_per_second, switch_channel_dequeue_dtmf(), switch_channel_get_variable, switch_channel_has_dtmf(), switch_channel_ready, SWITCH_CHANNEL_SESSION_LOG, switch_channel_test_flag(), SWITCH_CODEC_FLAG_DECODE, SWITCH_CODEC_FLAG_ENCODE, switch_cond_next(), 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_core_session_write_frame(), switch_generate_sln_silence(), SWITCH_IO_FLAG_NONE, switch_ivr_parse_all_events(), SWITCH_LOG_DEBUG, SWITCH_LOG_ERROR, switch_log_printf(), switch_micro_time_now(), 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_zmalloc, and zstr.

Referenced by fs_switch_ivr_collect_digits_count(), CoreSession::getDigits(), play_and_collect(), and switch_ivr_read().

1293 {
1294  switch_size_t i = 0, x = strlen(buf);
1297  switch_time_t started = 0, digit_started = 0;
1298  uint32_t abs_elapsed = 0, digit_elapsed = 0;
1299  uint32_t eff_timeout = 0;
1300  switch_frame_t write_frame = { 0 };
1301  unsigned char *abuf = NULL;
1302  switch_codec_implementation_t imp = { 0 };
1303  switch_codec_t codec = { 0 };
1304  int sval = 0;
1305  const char *var;
1306 
1307  if ((var = switch_channel_get_variable(channel, SWITCH_SEND_SILENCE_WHEN_IDLE_VARIABLE)) && (sval = atoi(var))) {
1308  switch_core_session_get_read_impl(session, &imp);
1309 
1310  if (switch_core_codec_init(&codec,
1311  "L16",
1312  NULL,
1313  NULL,
1314  imp.samples_per_second,
1315  imp.microseconds_per_packet / 1000,
1316  imp.number_of_channels,
1319  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec Error L16@%uhz %u channels %dms\n",
1321  return SWITCH_STATUS_FALSE;
1322  }
1323 
1324 
1325  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Codec Activated L16@%uhz %u channels %dms\n",
1327 
1328  write_frame.codec = &codec;
1330  write_frame.data = abuf;
1331  write_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE;
1332  write_frame.datalen = imp.decoded_bytes_per_packet;
1333  write_frame.samples = write_frame.datalen / sizeof(int16_t);
1334  }
1335 
1336  if (terminator != NULL) {
1337  *terminator = '\0';
1338  }
1339 
1340  if (!zstr(terminators)) {
1341  for (i = 0; i < x; i++) {
1342  if (strchr(terminators, buf[i]) && terminator != NULL) {
1343  *terminator = buf[i];
1344  buf[i] = '\0';
1345  switch_safe_free(abuf);
1346  return SWITCH_STATUS_SUCCESS;
1347  }
1348  }
1349  }
1350 
1351  if (abs_timeout) {
1352  started = switch_micro_time_now();
1353  }
1354 
1355  if (digit_timeout && first_timeout) {
1356  eff_timeout = first_timeout;
1357  } else if (digit_timeout && !first_timeout) {
1358  first_timeout = eff_timeout = digit_timeout;
1359  } else if (first_timeout) {
1360  digit_timeout = eff_timeout = first_timeout;
1361  }
1362 
1363 
1364  if (eff_timeout) {
1365  digit_started = switch_micro_time_now();
1366  }
1367 
1368  while (switch_channel_ready(channel)) {
1369  switch_frame_t *read_frame;
1370 
1371  if (abs_timeout) {
1372  abs_elapsed = (uint32_t) ((switch_micro_time_now() - started) / 1000);
1373  if (abs_elapsed >= abs_timeout) {
1374  status = SWITCH_STATUS_TIMEOUT;
1375  break;
1376  }
1377  }
1378 
1379 
1380  switch_ivr_parse_all_events(session);
1381 
1382 
1383 
1384  if (eff_timeout) {
1385  digit_elapsed = (uint32_t) ((switch_micro_time_now() - digit_started) / 1000);
1386 
1387  if (digit_elapsed >= eff_timeout) {
1388  status = SWITCH_STATUS_TIMEOUT;
1389  break;
1390  }
1391  }
1392 
1393  if (switch_channel_has_dtmf(channel)) {
1394  switch_dtmf_t dtmf = { 0 };
1395  switch_size_t y;
1396 
1397  if (eff_timeout) {
1398  eff_timeout = digit_timeout;
1399  digit_started = switch_micro_time_now();
1400  }
1401 
1402  for (y = 0; y <= maxdigits; y++) {
1403  if (switch_channel_dequeue_dtmf(channel, &dtmf) != SWITCH_STATUS_SUCCESS) {
1404  break;
1405  }
1406 
1407  if (!zstr(terminators) && strchr(terminators, dtmf.digit) && terminator != NULL) {
1408  *terminator = dtmf.digit;
1409  switch_safe_free(abuf);
1410  return SWITCH_STATUS_SUCCESS;
1411  }
1412 
1413 
1414  buf[x++] = dtmf.digit;
1415  buf[x] = '\0';
1416 
1417  if (x >= buflen || x >= maxdigits) {
1418  switch_safe_free(abuf);
1419  return SWITCH_STATUS_SUCCESS;
1420  }
1421  }
1422  }
1423 
1424  if (switch_channel_test_flag(channel, CF_SERVICE)) {
1425  switch_cond_next();
1426  } else {
1427  status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
1428  if (!SWITCH_READ_ACCEPTABLE(status)) {
1429  break;
1430  }
1431 
1432  if (write_frame.data) {
1433  switch_generate_sln_silence((int16_t *) write_frame.data, write_frame.samples, imp.number_of_channels, sval);
1434  switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0);
1435  }
1436 
1437  }
1438  }
1439 
1440  if (write_frame.codec) {
1441  switch_core_codec_destroy(&codec);
1442  }
1443 
1444  switch_safe_free(abuf);
1445 
1446  return status;
1447 }
switch_time_t switch_micro_time_now(void)
Get the current epoch time in microseconds.
Definition: switch_time.c:310
#define SWITCH_CHANNEL_SESSION_LOG(x)
#define SWITCH_RECOMMENDED_BUFFER_SIZE
Definition: switch_types.h:557
#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.
switch_status_t switch_core_codec_destroy(switch_codec_t *codec)
Destroy an initalized codec handle.
switch_status_t switch_ivr_parse_all_events(switch_core_session_t *session)
Parse all commands from an event.
Definition: switch_ivr.c:867
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:45
#define zstr(x)
Definition: switch_utils.h:281
#define SWITCH_SEND_SILENCE_WHEN_IDLE_VARIABLE
Definition: switch_types.h:129
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.
int64_t switch_time_t
Definition: switch_apr.h:188
uint32_t buflen
Definition: switch_frame.h:59
switch_byte_t switch_byte_t * buf
uint32_t datalen
Definition: switch_frame.h:57
#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)
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:789
An abstraction of a data frame.
Definition: switch_frame.h:43
uintptr_t switch_size_t
switch_byte_t switch_byte_t uint32_t buflen
#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:1602
void switch_cond_next(void)
Definition: switch_time.c:638
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.
uint32_t samples
Definition: switch_frame.h:61
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
A table of settings and callbacks that define a paticular implementation of a codec.
#define SWITCH_READ_ACCEPTABLE(status)
Definition: switch_utils.h:995
switch_memory_pool_t * switch_core_session_get_pool(_In_ switch_core_session_t *session)
Retrieve the memory pool from a session.
switch_status_t switch_ivr_deactivate_unicast ( switch_core_session_t session)

Definition at line 365 of file switch_ivr.c.

References CF_UNICAST, switch_unicast_conninfo::read_codec, switch_unicast_conninfo::socket, SUF_READY, SUF_THREAD_RUNNING, switch_channel_clear_flag(), switch_channel_get_private(), SWITCH_CHANNEL_SESSION_LOG, switch_channel_test_flag(), switch_clear_flag_locked, switch_core_codec_destroy(), switch_core_codec_ready(), switch_core_session_get_channel(), SWITCH_LOG_DEBUG, switch_log_printf(), SWITCH_SHUTDOWN_READWRITE, switch_socket_close(), switch_socket_shutdown(), SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_test_flag, switch_thread_join(), switch_yield, and switch_unicast_conninfo::thread.

Referenced by switch_core_session_perform_destroy(), switch_core_session_reset(), and switch_ivr_park().

366 {
368  switch_unicast_conninfo_t *conninfo;
369  int sanity = 0;
370 
371  if (!switch_channel_test_flag(channel, CF_UNICAST)) {
372  return SWITCH_STATUS_FALSE;
373  }
374 
375  if ((conninfo = switch_channel_get_private(channel, "unicast"))) {
376  switch_status_t st;
377 
378  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Shutting down unicast connection\n");
381  switch_thread_join(&st, conninfo->thread);
382 
383  while (switch_test_flag(conninfo, SUF_THREAD_RUNNING)) {
384  switch_yield(10000);
385  if (++sanity >= 10000) {
386  break;
387  }
388  }
389  if (switch_core_codec_ready(&conninfo->read_codec)) {
391  }
392  switch_socket_close(conninfo->socket);
393  }
395  return SWITCH_STATUS_SUCCESS;
396 }
switch_socket_t * socket
Definition: switch_ivr.h:52
#define SWITCH_CHANNEL_SESSION_LOG(x)
switch_status_t switch_core_codec_destroy(switch_codec_t *codec)
Destroy an initalized codec handle.
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_thread_join(switch_status_t *retval, switch_thread_t *thd)
Definition: switch_apr.c:1255
_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_yield(ms)
Wait a desired number of microseconds and yield the CPU.
Definition: switch_utils.h:908
switch_codec_t read_codec
Definition: switch_ivr.h:49
switch_thread_t * thread
Definition: switch_ivr.h:64
#define switch_clear_flag_locked(obj, flag)
Clear a flag on an arbitrary object.
Definition: switch_utils.h:648
switch_status_t
Common return values.
void * switch_channel_get_private(switch_channel_t *channel, const char *key)
Retrieve private from a given channel.
switch_status_t switch_socket_close(switch_socket_t *sock)
Definition: switch_apr.c:714
switch_status_t switch_socket_shutdown(switch_socket_t *sock, switch_shutdown_how_e how)
Definition: switch_apr.c:709
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:624
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.
void switch_channel_clear_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Clear given flag(s) from a channel.
switch_status_t switch_ivr_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.

Parameters
sessionthe session to attach
mod_namethe module name of the ASR library
grammarthe grammar text, URI, or local file name
namethe grammar name
destthe destination address
ahan ASR handle to use (NULL to create one)
Returns
SWITCH_STATUS_SUCCESS if all is well

Definition at line 4778 of file switch_ivr_async.c.

References speech_thread_handle::ah, SWITCH_ASR_FLAG_FIRE_EVENTS, switch_channel_get_private(), switch_channel_get_variable, SWITCH_CHANNEL_SESSION_LOG, switch_core_asr_load_grammar(), switch_core_session_get_channel(), switch_ivr_detect_speech_init(), switch_ivr_stop_detect_speech(), SWITCH_LOG_DEBUG, switch_log_printf(), switch_set_flag, SWITCH_SPEECH_KEY, SWITCH_STATUS_FALSE, SWITCH_STATUS_NOT_INITALIZED, SWITCH_STATUS_SUCCESS, and switch_true().

Referenced by switch_ivr_play_and_detect_speech().

4781 {
4783  switch_status_t status;
4785  const char *p;
4786 
4787  if (!sth) {
4788  /* No speech thread handle available yet, init speech detection first. */
4789  if ((status = switch_ivr_detect_speech_init(session, mod_name, dest, ah)) != SWITCH_STATUS_SUCCESS) {
4791  }
4792 
4793  /* Fetch the new speech thread handle */
4794  if (!(sth = switch_channel_get_private(channel, SWITCH_SPEECH_KEY))) {
4796  }
4797  }
4798 
4799  if (switch_core_asr_load_grammar(sth->ah, grammar, name) != SWITCH_STATUS_SUCCESS) {
4800  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Error loading Grammar\n");
4802  return SWITCH_STATUS_FALSE;
4803  }
4804 
4805  if ((p = switch_channel_get_variable(channel, "fire_asr_events")) && switch_true(p)) {
4807  }
4808 
4809  return SWITCH_STATUS_SUCCESS;
4810 }
#define SWITCH_CHANNEL_SESSION_LOG(x)
#define switch_set_flag(obj, flag)
Set a flag on an arbitrary object.
Definition: switch_utils.h:631
switch_asr_handle_t * ah
static int switch_true(const char *expr)
Evaluate the truthfullness of a string expression.
Definition: switch_utils.h:450
switch_status_t switch_core_asr_load_grammar(switch_asr_handle_t *ah, const char *grammar, const char *name)
Load a grammar to an asr handle.
#define SWITCH_SPEECH_KEY
Definition: switch_types.h:226
_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_stop_detect_speech(switch_core_session_t *session)
Stop background Speech detection on a session.
#define switch_channel_get_variable(_c, _v)
switch_status_t
Common return values.
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.
switch_status_t switch_ivr_detect_speech_init(switch_core_session_t *session, const char *mod_name, const char *dest, switch_asr_handle_t *ah)
Initialize background Speech detection on a session, so that parameters can be set, and grammars loaded. After calling this function, it is possible to call switch_ivr_set_param_detect_speech() to set recognition parameters. Calling switch_ivr_detect_speech_load_grammar() starts the speech recognition.
switch_status_t switch_ivr_detect_speech_disable_all_grammars ( switch_core_session_t session)

Disable all grammars on a background speech detection handle.

Parameters
sessionThe session to change the grammar on
Returns
SWITCH_STATUS_SUCCESS if all is well

Definition at line 4703 of file switch_ivr_async.c.

References speech_thread_handle::ah, switch_channel_get_private(), SWITCH_CHANNEL_SESSION_LOG, switch_core_asr_disable_all_grammars(), switch_core_session_get_channel(), switch_ivr_stop_detect_speech(), SWITCH_LOG_DEBUG, switch_log_printf(), SWITCH_SPEECH_KEY, SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.

4704 {
4707  switch_status_t status;
4708 
4709  if (sth) {
4711  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Error disabling all Grammars\n");
4713  }
4714  return status;
4715  }
4716  return SWITCH_STATUS_FALSE;
4717 }
#define SWITCH_CHANNEL_SESSION_LOG(x)
switch_asr_handle_t * ah
switch_status_t switch_core_asr_disable_all_grammars(switch_asr_handle_t *ah)
Disable all grammars from an asr handle.
#define SWITCH_SPEECH_KEY
Definition: switch_types.h:226
_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_stop_detect_speech(switch_core_session_t *session)
Stop background Speech detection on a session.
switch_status_t
Common return values.
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.
switch_status_t switch_ivr_detect_speech_disable_grammar ( switch_core_session_t session,
const char *  name 
)

Disable a grammar on a background speech detection handle.

Parameters
sessionThe session to change the grammar on
namethe grammar name
Returns
SWITCH_STATUS_SUCCESS if all is well

Definition at line 4687 of file switch_ivr_async.c.

References speech_thread_handle::ah, switch_channel_get_private(), SWITCH_CHANNEL_SESSION_LOG, switch_core_asr_disable_grammar(), switch_core_session_get_channel(), switch_ivr_stop_detect_speech(), SWITCH_LOG_DEBUG, switch_log_printf(), SWITCH_SPEECH_KEY, SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.

4688 {
4691  switch_status_t status;
4692 
4693  if (sth) {
4694  if ((status = switch_core_asr_disable_grammar(sth->ah, name)) != SWITCH_STATUS_SUCCESS) {
4695  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Error disabling Grammar\n");
4697  }
4698  return status;
4699  }
4700  return SWITCH_STATUS_FALSE;
4701 }
#define SWITCH_CHANNEL_SESSION_LOG(x)
switch_asr_handle_t * ah
#define SWITCH_SPEECH_KEY
Definition: switch_types.h:226
_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_stop_detect_speech(switch_core_session_t *session)
Stop background Speech detection on a session.
switch_status_t switch_core_asr_disable_grammar(switch_asr_handle_t *ah, const char *name)
Disable a grammar from an asr handle.
switch_status_t
Common return values.
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.
switch_status_t switch_ivr_detect_speech_enable_grammar ( switch_core_session_t session,
const char *  name 
)

Enable a grammar on a background speech detection handle.

Parameters
sessionThe session to change the grammar on
namethe grammar name
Returns
SWITCH_STATUS_SUCCESS if all is well

Definition at line 4671 of file switch_ivr_async.c.

References speech_thread_handle::ah, switch_channel_get_private(), SWITCH_CHANNEL_SESSION_LOG, switch_core_asr_enable_grammar(), switch_core_session_get_channel(), switch_ivr_stop_detect_speech(), SWITCH_LOG_DEBUG, switch_log_printf(), SWITCH_SPEECH_KEY, SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.

4672 {
4675  switch_status_t status;
4676 
4677  if (sth) {
4678  if ((status = switch_core_asr_enable_grammar(sth->ah, name)) != SWITCH_STATUS_SUCCESS) {
4679  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Error enabling Grammar\n");
4681  }
4682  return status;
4683  }
4684  return SWITCH_STATUS_FALSE;
4685 }
#define SWITCH_CHANNEL_SESSION_LOG(x)
switch_asr_handle_t * ah
#define SWITCH_SPEECH_KEY
Definition: switch_types.h:226
_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_stop_detect_speech(switch_core_session_t *session)
Stop background Speech detection on a session.
switch_status_t
Common return values.
void * switch_channel_get_private(switch_channel_t *channel, const char *key)
Retrieve private from a given channel.
switch_status_t switch_core_asr_enable_grammar(switch_asr_handle_t *ah, const char *name)
Enable a grammar from an asr 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.
switch_status_t switch_ivr_detect_speech_init ( switch_core_session_t session,
const char *  mod_name,
const char *  dest,
switch_asr_handle_t ah 
)

Initialize background Speech detection on a session, so that parameters can be set, and grammars loaded. After calling this function, it is possible to call switch_ivr_set_param_detect_speech() to set recognition parameters. Calling switch_ivr_detect_speech_load_grammar() starts the speech recognition.

Parameters
sessionthe session to attach
mod_namethe module name of the ASR library
destthe destination address
ahan ASR handle to use (NULL to create one)
Returns
SWITCH_STATUS_SUCCESS if all is well

Definition at line 4719 of file switch_ivr_async.c.

References switch_codec_implementation::actual_samples_per_second, speech_thread_handle::ah, speech_thread_handle::bug, speech_thread_handle::pool, speech_thread_handle::session, SMBF_NO_PAUSE, SMBF_READ_STREAM, speech_callback(), speech_on_dtmf(), SWITCH_ASR_FLAG_FIRE_EVENTS, SWITCH_ASR_FLAG_NONE, switch_channel_get_private(), switch_channel_get_variable, switch_channel_set_private(), switch_core_asr_close(), switch_core_asr_open(), switch_core_media_bug_add(), switch_core_session_alloc, switch_core_session_get_channel(), switch_core_session_get_pool(), switch_core_session_get_read_impl(), switch_ivr_stop_detect_speech(), switch_set_flag, switch_snprintf(), SWITCH_SPEECH_KEY, SWITCH_STATUS_MEMERR, SWITCH_STATUS_SUCCESS, and switch_true().

Referenced by switch_ivr_detect_speech().

4721 {
4723  switch_status_t status;
4726  switch_codec_implementation_t read_impl = { 0 };
4727  const char *p;
4728  char key[512] = "";
4729 
4730  if (sth) {
4731  /* Already initialized */
4732  return SWITCH_STATUS_SUCCESS;
4733  }
4734 
4735  if (!ah) {
4736  if (!(ah = switch_core_session_alloc(session, sizeof(*ah)))) {
4737  return SWITCH_STATUS_MEMERR;
4738  }
4739  }
4740 
4741  switch_core_session_get_read_impl(session, &read_impl);
4742 
4743  if ((status = switch_core_asr_open(ah,
4744  mod_name,
4745  "L16",
4746  read_impl.actual_samples_per_second, dest, &flags,
4748  return status;
4749  }
4750 
4751  sth = switch_core_session_alloc(session, sizeof(*sth));
4752  sth->pool = switch_core_session_get_pool(session);
4753  sth->session = session;
4754  sth->ah = ah;
4755 
4756  if ((p = switch_channel_get_variable(channel, "fire_asr_events")) && switch_true(p)) {
4758  }
4759 
4760  switch_snprintf(key, sizeof(key), "%s/%s/%s/%s", mod_name, NULL, NULL, dest);
4761 
4762  if ((status = switch_core_media_bug_add(session, "detect_speech", key,
4764  switch_core_asr_close(ah, &flags);
4765  return status;
4766  }
4767 
4768  if ((status = switch_core_event_hook_add_recv_dtmf(session, speech_on_dtmf)) != SWITCH_STATUS_SUCCESS) {
4770  return status;
4771  }
4772 
4774 
4775  return SWITCH_STATUS_SUCCESS;
4776 }
#define switch_set_flag(obj, flag)
Set a flag on an arbitrary object.
Definition: switch_utils.h:631
switch_asr_handle_t * ah
switch_core_session_t * session
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_asr_open(switch_asr_handle_t *ah, const char *module_name, const char *codec, int rate, const char *dest, switch_asr_flag_t *flags, switch_memory_pool_t *pool)
Open an asr handle.
static switch_status_t speech_on_dtmf(switch_core_session_t *session, const switch_dtmf_t *dtmf, switch_dtmf_direction_t direction)
int switch_snprintf(_Out_z_cap_(len) char *buf, _In_ switch_size_t len, _In_z_ _Printf_format_string_ const char *format,...)
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.
static int switch_true(const char *expr)
Evaluate the truthfullness of a string expression.
Definition: switch_utils.h:450
#define SWITCH_SPEECH_KEY
Definition: switch_types.h:226
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_core_asr_close(switch_asr_handle_t *ah, switch_asr_flag_t *flags)
Close an asr handle.
switch_status_t switch_ivr_stop_detect_speech(switch_core_session_t *session)
Stop background Speech detection on a session.
static switch_bool_t speech_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type)
switch_memory_pool_t * pool
#define switch_channel_get_variable(_c, _v)
uint32_t switch_asr_flag_t
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's pool.
Definition: switch_core.h:694
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.
switch_media_bug_t * bug
switch_status_t switch_ivr_detect_speech_load_grammar ( switch_core_session_t session,
const char *  grammar,
const char *  name 
)

Load a grammar on a background speech detection handle.

Parameters
sessionThe session to change the grammar on
grammarthe grammar text, URI, or local file name
namethe grammar name
Returns
SWITCH_STATUS_SUCCESS if all is well

Definition at line 4614 of file switch_ivr_async.c.

References speech_thread_handle::ah, switch_channel_get_private(), SWITCH_CHANNEL_SESSION_LOG, switch_core_asr_load_grammar(), switch_core_session_get_channel(), switch_ivr_stop_detect_speech(), SWITCH_LOG_DEBUG, switch_log_printf(), SWITCH_SPEECH_KEY, SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.

4615 {
4618  switch_status_t status;
4619 
4620  if (sth) {
4621  if ((status = switch_core_asr_load_grammar(sth->ah, grammar, name)) != SWITCH_STATUS_SUCCESS) {
4622  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Error loading Grammar\n");
4624  }
4625  return status;
4626  }
4627  return SWITCH_STATUS_FALSE;
4628 }
#define SWITCH_CHANNEL_SESSION_LOG(x)
switch_asr_handle_t * ah
switch_status_t switch_core_asr_load_grammar(switch_asr_handle_t *ah, const char *grammar, const char *name)
Load a grammar to an asr handle.
#define SWITCH_SPEECH_KEY
Definition: switch_types.h:226
_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_stop_detect_speech(switch_core_session_t *session)
Stop background Speech detection on a session.
switch_status_t
Common return values.
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.
switch_status_t switch_ivr_detect_speech_start_input_timers ( switch_core_session_t session)

Start input timers on a background speech detection handle.

Parameters
sessionThe session to start the timers on
Returns
SWITCH_STATUS_SUCCESS if all is well

Definition at line 4643 of file switch_ivr_async.c.

References speech_thread_handle::ah, switch_channel_get_private(), switch_core_asr_start_input_timers(), switch_core_session_get_channel(), SWITCH_SPEECH_KEY, SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.

Referenced by switch_ivr_play_and_detect_speech().

4644 {
4647 
4648  if (sth) {
4650  return SWITCH_STATUS_SUCCESS;
4651  }
4652  return SWITCH_STATUS_FALSE;
4653 }
switch_status_t switch_core_asr_start_input_timers(switch_asr_handle_t *ah)
Start input timers on an asr handle.
switch_asr_handle_t * ah
#define SWITCH_SPEECH_KEY
Definition: switch_types.h:226
_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_status_t switch_ivr_detect_speech_unload_grammar ( switch_core_session_t session,
const char *  name 
)

Unload a grammar on a background speech detection handle.

Parameters
sessionThe session to change the grammar on
namethe grammar name
Returns
SWITCH_STATUS_SUCCESS if all is well

Definition at line 4655 of file switch_ivr_async.c.

References speech_thread_handle::ah, switch_channel_get_private(), SWITCH_CHANNEL_SESSION_LOG, switch_core_asr_unload_grammar(), switch_core_session_get_channel(), switch_ivr_stop_detect_speech(), SWITCH_LOG_DEBUG, switch_log_printf(), SWITCH_SPEECH_KEY, SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.

4656 {
4659  switch_status_t status;
4660 
4661  if (sth) {
4662  if ((status = switch_core_asr_unload_grammar(sth->ah, name)) != SWITCH_STATUS_SUCCESS) {
4663  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Error unloading Grammar\n");
4665  }
4666  return status;
4667  }
4668  return SWITCH_STATUS_FALSE;
4669 }
#define SWITCH_CHANNEL_SESSION_LOG(x)
switch_asr_handle_t * ah
#define SWITCH_SPEECH_KEY
Definition: switch_types.h:226
_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_stop_detect_speech(switch_core_session_t *session)
Stop background Speech detection on a session.
switch_status_t
Common return values.
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.
switch_status_t switch_core_asr_unload_grammar(switch_asr_handle_t *ah, const char *name)
Unload a grammar from an asr handle.
switch_status_t switch_ivr_digit_stream_destroy ( switch_ivr_digit_stream_t **  stream)

Destroys a digit stream object.

Parameters
streama pointer to the stream object
Returns
NULL if no match found or consumer data that was associated with a given digit string when matched

Definition at line 2311 of file switch_ivr.c.

References switch_safe_free, SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.

2312 {
2314 
2315  if (*stream) {
2316  switch_safe_free((*stream)->digits);
2317  free(*stream);
2318  *stream = NULL;
2319  status = SWITCH_STATUS_SUCCESS;
2320  }
2321 
2322  return status;
2323 }
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:789
switch_status_t
Common return values.
switch_status_t switch_ivr_digit_stream_new ( switch_ivr_digit_stream_parser_t parser,
switch_ivr_digit_stream_t **  stream 
)

Create a new digit stream object.

Parameters
parsera pointer to the parser object created by switch_ivr_digit_stream_parser_new
streama pointer to the stream object pointer
Returns
NULL if no match found or consumer data that was associated with a given digit string when matched

Definition at line 2295 of file switch_ivr.c.

References memset(), switch_assert, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, and switch_zmalloc.

2296 {
2298 
2299  /* if we have a parser object memory pool and a stream object pointer that is null */
2300  if (parser && stream && *stream == NULL) {
2301  *stream = (switch_ivr_digit_stream_t *) malloc(sizeof(**stream));
2302  switch_assert(*stream);
2303  memset(*stream, 0, sizeof(**stream));
2304  switch_zmalloc((*stream)->digits, parser->buflen + 1);
2305  status = SWITCH_STATUS_SUCCESS;
2306  }
2307 
2308  return status;
2309 }
#define switch_zmalloc(ptr, len)
switch_status_t
Common return values.
#define switch_assert(expr)
memset(buf, 0, buflen)
switch_status_t switch_ivr_digit_stream_parser_del_event ( switch_ivr_digit_stream_parser_t parser,
char *  digits 
)

Delete a string to action mapping.

Parameters
parsera pointer to the parser object created by switch_ivr_digit_stream_parser_new
digitsthe digit string to be removed from the map
Returns
SWITCH_STATUS_SUCCESS if all is well

Definition at line 2367 of file switch_ivr.c.

References SWITCH_CHANNEL_LOG, switch_core_hash_delete(), SWITCH_LOG_DEBUG, switch_log_printf(), SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.

2368 {
2370 
2371  if (parser != NULL && digits != NULL && *digits) {
2373  }
2374 
2375  if (status != SWITCH_STATUS_SUCCESS) {
2376  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "unable to del hash for '%s'\n", digits);
2377  }
2378 
2379  return status;
2380 }
#define SWITCH_CHANNEL_LOG
void * switch_core_hash_delete(_In_ switch_hash_t *hash, _In_z_ const char *key)
Delete data from a hash based on desired key.
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.
switch_status_t switch_ivr_digit_stream_parser_destroy ( switch_ivr_digit_stream_parser_t parser)

Destroy a digit stream parser object.

Parameters
parsera pointer to the parser object
Returns
SWITCH_STATUS_SUCCESS if all is well

Definition at line 2277 of file switch_ivr.c.

References switch_core_destroy_memory_pool, switch_core_hash_destroy(), and SWITCH_STATUS_FALSE.

2278 {
2280 
2281  if (parser != NULL) {
2282  if (parser->hash != NULL) {
2283  switch_core_hash_destroy(&parser->hash);
2284  parser->hash = NULL;
2285  }
2286  /* free the memory pool if we created it */
2287  if (parser->pool_auto_created && parser->pool != NULL) {
2288  status = switch_core_destroy_memory_pool(&parser->pool);
2289  }
2290  }
2291 
2292  return status;
2293 }
switch_status_t switch_core_hash_destroy(_Inout_ switch_hash_t **hash)
Destroy an existing hash table.
#define switch_core_destroy_memory_pool(p)
Returns a subpool back to the main pool.
Definition: switch_core.h:640
switch_status_t
Common return values.
switch_memory_pool_t * pool
Definition: switch_ivr.c:2223
void* switch_ivr_digit_stream_parser_feed ( switch_ivr_digit_stream_parser_t parser,
switch_ivr_digit_stream_t stream,
char  digit 
)

Feed digits collected into the stream for event match testing.

Parameters
parsera pointer to the parser object created by switch_ivr_digit_stream_parser_new
streama stream to write data to
digita digit to collect and test against the map of digit strings
Returns
NULL if no match found or consumer data that was associated with a given digit string when matched

Definition at line 2382 of file switch_ivr.c.

References switch_assert, switch_core_hash_find(), and switch_micro_time_now().

2383 {
2384  void *result = NULL;
2385  switch_size_t len;
2386 
2387  switch_assert(parser);
2388  switch_assert(stream);
2389  switch_assert(stream->digits);
2390 
2391  len = strlen(stream->digits);
2392 
2393  /* handle new digit arrivals */
2394  if (digit) {
2395  /* if it's not a terminator digit, add it to the collected digits */
2396  if (digit != parser->terminator) {
2397  /* if collected digits length >= the max length of the keys
2398  * in the hash table, then left shift the digit string
2399  */
2400  if (len > 0 && parser->maxlen != 0 && len >= parser->maxlen) {
2401  char *src = stream->digits + 1;
2402  char *dst = stream->digits;
2403 
2404  while (*src) {
2405  *(dst++) = *(src++);
2406  }
2407  *dst = digit;
2408  } else {
2409  *(stream->digits + (len++)) = digit;
2410  *(stream->digits + len) = '\0';
2411  stream->last_digit_time = switch_micro_time_now() / 1000;
2412  }
2413  }
2414  }
2415 
2416  /* don't allow collected digit string testing if there are varying sized keys until timeout */
2417  if (parser->maxlen - parser->minlen > 0 && (switch_micro_time_now() / 1000) - stream->last_digit_time < parser->digit_timeout_ms) {
2418  len = 0;
2419  }
2420  /* if we have digits to test */
2421  if (len) {
2422  result = switch_core_hash_find(parser->hash, stream->digits);
2423  /* if we matched the digit string, or this digit is the terminator
2424  * reset the collected digits for next digit string
2425  */
2426  if (result != NULL || parser->terminator == digit) {
2427  *stream->digits = '\0';
2428  }
2429  }
2430 
2431 
2432  return result;
2433 }
switch_time_t switch_micro_time_now(void)
Get the current epoch time in microseconds.
Definition: switch_time.c:310
void * switch_core_hash_find(_In_ switch_hash_t *hash, _In_z_ const char *key)
Retrieve data from a given hash.
switch_time_t last_digit_time
Definition: switch_ivr.c:2234
uintptr_t switch_size_t
#define switch_assert(expr)
switch_status_t switch_ivr_digit_stream_parser_new ( switch_memory_pool_t pool,
switch_ivr_digit_stream_parser_t **  parser 
)

Create a digit stream parser object.

Parameters
poolthe pool to use for the new hash
parsera pointer to the object pointer
Returns
SWITCH_STATUS_SUCCESS if all is well

Definition at line 2237 of file switch_ivr.c.

References memset(), pool, SWITCH_CHANNEL_LOG, switch_core_alloc, switch_core_destroy_memory_pool, switch_core_hash_init, switch_core_new_memory_pool, SWITCH_LOG_DEBUG, switch_log_printf(), SWITCH_STATUS_FALSE, SWITCH_STATUS_MEMERR, and SWITCH_STATUS_SUCCESS.

2238 {
2240 
2241  if (parser != NULL) {
2242  int pool_auto_created = 0;
2243 
2244  /* if the caller didn't provide a pool, make one */
2245  if (pool == NULL) {
2247  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "created a memory pool\n");
2248  if (pool != NULL) {
2249  pool_auto_created = 1;
2250  }
2251  }
2252  /* if we have a pool, make a parser object */
2253  if (pool != NULL) {
2255  }
2256  /* if we have parser object, initialize it for the caller */
2257  if (pool && *parser != NULL) {
2258  memset(*parser, 0, sizeof(switch_ivr_digit_stream_parser_t));
2259  (*parser)->pool_auto_created = pool_auto_created;
2260  (*parser)->pool = pool;
2261  (*parser)->digit_timeout_ms = 1000;
2262  switch_core_hash_init(&(*parser)->hash);
2263 
2264  status = SWITCH_STATUS_SUCCESS;
2265  } else {
2266  status = SWITCH_STATUS_MEMERR;
2267  /* if we can't create a parser object,clean up the pool if we created it */
2268  if (pool != NULL && pool_auto_created) {
2270  }
2271  }
2272  }
2273 
2274  return status;
2275 }
#define switch_core_new_memory_pool(p)
Create a new sub memory pool from the core's master pool.
Definition: switch_core.h:631
#define SWITCH_CHANNEL_LOG
#define switch_core_hash_init(_hash)
Definition: switch_core.h:1390
#define switch_core_destroy_memory_pool(p)
Returns a subpool back to the main pool.
Definition: switch_core.h:640
switch_memory_pool_t * pool
#define switch_core_alloc(_pool, _mem)
Allocate memory directly from a memory pool.
Definition: switch_core.h:682
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.
memset(buf, 0, buflen)
switch_status_t switch_ivr_digit_stream_parser_set_event ( switch_ivr_digit_stream_parser_t parser,
char *  digits,
void *  data 
)

Set a digit string to action mapping.

Parameters
parsera pointer to the parser object created by switch_ivr_digit_stream_parser_new
digitsa string of digits to associate with an action
dataconsumer data attached to this digit string
Returns
SWITCH_STATUS_SUCCESS if all is well

Definition at line 2325 of file switch_ivr.c.

References SWITCH_CHANNEL_LOG, switch_core_hash_insert, SWITCH_LOG_DEBUG, switch_log_printf(), SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.

2326 {
2328 
2329  if (parser != NULL && digits != NULL && *digits && parser->hash != NULL) {
2330 
2331  status = switch_core_hash_insert(parser->hash, digits, data);
2332  if (status == SWITCH_STATUS_SUCCESS) {
2333  switch_size_t len = strlen(digits);
2334 
2335  /* if we don't have a terminator, then we have to try and
2336  * figure out when a digit set is completed, therefore we
2337  * keep track of the min and max digit lengths
2338  */
2339 
2340  if (len > parser->buflen) {
2341  parser->buflen = len;
2342  }
2343 
2344  if (parser->terminator == '\0') {
2345  if (len > parser->maxlen) {
2346  parser->maxlen = len;
2347  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "max len %u\n", (uint32_t) parser->maxlen);
2348  }
2349  if (parser->minlen == 0 || len < parser->minlen) {
2350  parser->minlen = len;
2351  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "min len %u\n", (uint32_t) parser->minlen);
2352  }
2353  } else {
2354  /* since we have a terminator, reset min and max */
2355  parser->minlen = 0;
2356  parser->maxlen = 0;
2357  }
2358  }
2359  }
2360  if (status != SWITCH_STATUS_SUCCESS) {
2361  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "unable to add hash for '%s'\n", digits);
2362  }
2363 
2364  return status;
2365 }
#define SWITCH_CHANNEL_LOG
uintptr_t switch_size_t
switch_status_t
Common return values.
#define switch_core_hash_insert(_h, _k, _d)
Definition: switch_core.h:1410
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
switch_status_t switch_ivr_digit_stream_parser_set_terminator ( switch_ivr_digit_stream_parser_t parser,
char  digit 
)

Set a digit string terminator.

Parameters
parsera pointer to the parser object created by switch_ivr_digit_stream_parser_new
digitthe terminator digit
Returns
SWITCH_STATUS_SUCCESS if all is well

Definition at line 2448 of file switch_ivr.c.

References SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.

2449 {
2451 
2452  if (parser != NULL) {
2453  parser->terminator = digit;
2454  /* since we have a terminator, reset min and max */
2455  parser->minlen = 0;
2456  parser->maxlen = 0;
2457  status = SWITCH_STATUS_SUCCESS;
2458  }
2459 
2460  return status;
2461 }
switch_status_t
Common return values.
switch_status_t switch_ivr_digit_stream_reset ( switch_ivr_digit_stream_t stream)

Reset the collected digit stream to nothing.

Parameters
streama pointer to the parser stream object created by switch_ivr_digit_stream_new
Returns
SWITCH_STATUS_SUCCESS if all is well

Definition at line 2435 of file switch_ivr.c.

References switch_assert, SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.

2436 {
2438  switch_assert(stream);
2439  switch_assert(stream->digits);
2440 
2441  *stream->digits = '\0';
2442  stream->last_digit_time = 0;
2443  status = SWITCH_STATUS_SUCCESS;
2444 
2445  return status;
2446 }
switch_time_t last_digit_time
Definition: switch_ivr.c:2234
switch_status_t
Common return values.
#define switch_assert(expr)
switch_status_t switch_ivr_displace_session ( switch_core_session_t session,
const char *  file,
uint32_t  limit,
const char *  flags 
)

displace the media for a session with the audio from a file

Parameters
sessionthe session to displace
filefilename
limittime limit in ms
flagsm (mux) l (loop) or r(read session instead of write session)
Returns
SWITCH_STATUS_SUCCESS if all is well

Definition at line 912 of file switch_ivr_async.c.

References switch_codec_implementation::actual_samples_per_second, switch_directories::base_dir, switch_file_handle::channels, displace_helper_t::fh, displace_helper_t::file, switch_codec_implementation::iananame, displace_helper_t::loop, displace_helper_t::mux, switch_codec_implementation::number_of_channels, read_displace_callback(), switch_file_handle::samplerate, SMBF_NO_PAUSE, SMBF_READ_REPLACE, SMBF_WRITE_REPLACE, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER, switch_channel_get_private(), switch_channel_get_variable, switch_channel_hangup, switch_channel_media_up, switch_channel_pre_answer, SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_private(), switch_core_file_close(), switch_core_file_open, switch_core_media_bug_add(), switch_core_session_alloc, switch_core_session_get_channel(), switch_core_session_get_read_codec(), switch_core_session_get_read_impl(), switch_core_session_reset(), switch_core_session_sprintf(), switch_core_session_strdup, switch_epoch_time_now(), SWITCH_FALSE, SWITCH_FILE_DATA_SHORT, SWITCH_FILE_FLAG_READ, switch_find_end_paren(), SWITCH_GLOBAL_dirs, switch_is_file_path(), SWITCH_LOG_ERROR, switch_log_printf(), SWITCH_PATH_SEPARATOR, SWITCH_STATUS_FALSE, SWITCH_STATUS_GENERR, SWITCH_STATUS_MEMERR, SWITCH_STATUS_SUCCESS, switch_str_nil, SWITCH_TRUE, switch_true(), SWITCH_URL_SEPARATOR, write_displace_callback(), and zstr.

913 {
916  switch_status_t status;
917  time_t to = 0;
918  char *ext;
919  const char *prefix;
920  displace_helper_t *dh;
921  const char *p;
922  switch_bool_t hangup_on_error = SWITCH_FALSE;
923  switch_codec_implementation_t read_impl = { 0 };
924  switch_core_session_get_read_impl(session, &read_impl);
925 
926  if ((p = switch_channel_get_variable(channel, "DISPLACE_HANGUP_ON_ERROR"))) {
927  hangup_on_error = switch_true(p);
928  }
929 
930  if (zstr(file)) {
931  return SWITCH_STATUS_FALSE;
932  }
933 
934  if ((status = switch_channel_pre_answer(channel)) != SWITCH_STATUS_SUCCESS) {
935  return SWITCH_STATUS_FALSE;
936  }
937 
938  if (!switch_channel_media_up(channel) || !switch_core_session_get_read_codec(session)) {
939  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can not displace session. Media not enabled on channel\n");
940  return SWITCH_STATUS_FALSE;
941  }
942 
943  if ((bug = switch_channel_get_private(channel, file))) {
944  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Only 1 of the same file per channel please!\n");
945  return SWITCH_STATUS_FALSE;
946  }
947 
948  if (!(dh = switch_core_session_alloc(session, sizeof(*dh)))) {
949  return SWITCH_STATUS_MEMERR;
950  }
951 
952  if (!(prefix = switch_channel_get_variable(channel, "sound_prefix"))) {
953  prefix = SWITCH_GLOBAL_dirs.base_dir;
954  }
955 
956  if (!strstr(file, SWITCH_URL_SEPARATOR)) {
957  if (!switch_is_file_path(file)) {
958  char *tfile = NULL;
959  char *e;
960 
961  if (*file == '[') {
962  tfile = switch_core_session_strdup(session, file);
963  if ((e = switch_find_end_paren(tfile, '[', ']'))) {
964  *e = '\0';
965  file = e + 1;
966  } else {
967  tfile = NULL;
968  }
969  }
970 
971  file = switch_core_session_sprintf(session, "%s%s%s%s%s", switch_str_nil(tfile), tfile ? "]" : "", prefix, SWITCH_PATH_SEPARATOR, file);
972  }
973  if ((ext = strrchr(file, '.'))) {
974  ext++;
975  } else {
976  ext = read_impl.iananame;
977  file = switch_core_session_sprintf(session, "%s.%s", file, ext);
978  }
979  }
980 
981  dh->fh.channels = read_impl.number_of_channels;
982  dh->fh.samplerate = read_impl.actual_samples_per_second;
983  dh->file = switch_core_session_strdup(session, file);
984 
985  if (switch_core_file_open(&dh->fh,
986  file,
987  read_impl.number_of_channels,
989  if (hangup_on_error) {
992  }
993  return SWITCH_STATUS_GENERR;
994  }
995 
996  if (limit) {
997  to = switch_epoch_time_now(NULL) + limit;
998  }
999 
1000  if (flags && strchr(flags, 'm')) {
1001  dh->mux++;
1002  }
1003 
1004  if (flags && strchr(flags, 'l')) {
1005  dh->loop++;
1006  }
1007 
1008  if (flags && strchr(flags, 'r')) {
1009  status = switch_core_media_bug_add(session, "displace", file,
1011  } else {
1012  status = switch_core_media_bug_add(session, "displace", file,
1014  }
1015 
1016  if (status != SWITCH_STATUS_SUCCESS) {
1017  switch_core_file_close(&dh->fh);
1018  return status;
1019  }
1020 
1021  switch_channel_set_private(channel, file, bug);
1022 
1023  return SWITCH_STATUS_SUCCESS;
1024 }
#define switch_channel_hangup(channel, hangup_cause)
Hangup a channel flagging it'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.
char * switch_find_end_paren(const char *s, char open, char close)
Definition: switch_utils.c:661
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_core_file_open(_fh, _file_path, _channels, _rate, _flags, _pool)
Open a media file using file format modules.
Definition: switch_core.h:1865
switch_bool_t
Definition: switch_types.h:405
#define SWITCH_URL_SEPARATOR
Definition: switch_types.h:124
switch_status_t switch_core_file_close(_In_ switch_file_handle_t *fh)
Close an open file handle.
static switch_bool_t read_displace_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type)
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.
static int switch_true(const char *expr)
Evaluate the truthfullness of a string expression.
Definition: switch_utils.h:450
#define zstr(x)
Definition: switch_utils.h:281
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_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.
#define SWITCH_PATH_SEPARATOR
Definition: switch_types.h:122
switch_file_handle_t fh
#define switch_channel_get_variable(_c, _v)
switch_directories SWITCH_GLOBAL_dirs
Definition: switch_core.c:60
#define switch_str_nil(s)
Make a null string a blank string instead.
Definition: switch_utils.h:903
switch_status_t
Common return values.
void * switch_channel_get_private(switch_channel_t *channel, const char *key)
Retrieve private from a given channel.
static switch_bool_t switch_is_file_path(const char *file)
time_t switch_epoch_time_now(time_t *t)
Get the current epoch time.
Definition: switch_time.c:321
#define switch_core_session_alloc(_session, _memory)
Allocate memory from a session's pool.
Definition: switch_core.h:694
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_core_session_strdup(_session, _todup)
Copy a string using memory allocation from a session's pool.
Definition: switch_core.h:717
static switch_bool_t write_displace_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type)
#define switch_channel_pre_answer(channel)
Indicate progress on a channel to attempt early media.
#define switch_channel_media_up(_channel)
switch_media_bug_t * bug
switch_status_t switch_ivr_eavesdrop_exec_all ( switch_core_session_t session,
const char *  app,
const char *  arg 
)

Definition at line 1832 of file switch_ivr_async.c.

References exec_cb_data::caller, exec_cb(), switch_core_media_bug_exec_all(), switch_core_session_alloc, switch_core_session_strdup, exec_cb_data::val, and exec_cb_data::var.

1833 {
1834  struct exec_cb_data *data = NULL;
1835 
1836  data = switch_core_session_alloc(session, sizeof(*data));
1837  data->var = switch_core_session_strdup(session, app);
1838  data->val = switch_core_session_strdup(session, arg);
1839  data->caller = session;
1840 
1841  return switch_core_media_bug_exec_all(session, "eavesdrop", exec_cb, data);
1842 }
switch_core_session_t * caller
static void exec_cb(switch_media_bug_t *bug, void *user_data)
#define switch_core_session_alloc(_session, _memory)
Allocate memory from a session's pool.
Definition: switch_core.h:694
#define switch_core_session_strdup(_session, _todup)
Copy a string using memory allocation from a session's pool.
Definition: switch_core.h:717
switch_status_t switch_core_media_bug_exec_all(switch_core_session_t *orig_session, const char *function, switch_media_bug_exec_cb_t cb, void *user_data)
switch_status_t switch_ivr_eavesdrop_pop_eavesdropper ( switch_core_session_t session,
switch_core_session_t **  sessionp 
)

Definition at line 1773 of file switch_ivr_async.c.

References eavesdrop_pvt::eavesdropper, ep, SMBF_PRUNE, switch_core_media_bug_get_user_data(), switch_core_media_bug_pop(), switch_core_media_bug_set_flag(), switch_core_session_read_lock(), SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.

1774 {
1775  switch_media_bug_t *bug;
1777 
1778  if (switch_core_media_bug_pop(session, "eavesdrop", &bug) == SWITCH_STATUS_SUCCESS) {
1780 
1781  if (ep && ep->eavesdropper && ep->eavesdropper != session) {
1783  *sessionp = ep->eavesdropper;
1785  status = SWITCH_STATUS_SUCCESS;
1786  }
1787  }
1788 
1789 
1790  return status;
1791 }
void * switch_core_media_bug_get_user_data(_In_ switch_media_bug_t *bug)
Obtain private data from a media bug.
switch_status_t switch_core_session_read_lock(_In_ switch_core_session_t *session)
Acquire a read lock on the session.
uint32_t switch_core_media_bug_set_flag(_In_ switch_media_bug_t *bug, _In_ uint32_t flag)
switch_core_session_t * eavesdropper
switch_status_t switch_core_media_bug_pop(switch_core_session_t *orig_session, const char *function, switch_media_bug_t **pop)
static const char * ep
Definition: switch_json.c:36
switch_status_t
Common return values.
switch_status_t switch_ivr_eavesdrop_session ( switch_core_session_t session,
const char *  uuid,
const char *  require_group,
switch_eavesdrop_flag_t  flags 
)

Eavesdrop on a another session.

Parameters
sessionour session
uuidthe uuid of the session to spy on
require_groupgroup name to use to limit by group
flagstweak read-mux, write-mux and dtmf
Returns
SWITCH_STATUS_SUCESS if all is well

Definition at line 1866 of file switch_ivr_async.c.

References switch_codec_implementation::actual_samples_per_second, buf, eavesdrop_pvt::buffer, switch_frame::buflen, switch_caller_profile::callee_id_name, switch_caller_profile::callee_id_number, switch_caller_profile::caller_id_name, switch_caller_profile::caller_id_number, CF_BRIDGE_ORIGINATOR, CF_BRIDGED, CF_VIDEO, switch_core_session::channel, switch_frame::codec, switch_frame::data, eavesdrop_pvt::data, switch_frame::datalen, switch_codec_implementation::decoded_bytes_per_packet, switch_dtmf_t::digit, eavesdrop_callback(), eavesdrop_pvt::eavesdropper, ED_BRIDGE_READ, ED_BRIDGE_WRITE, ED_COPY_DISPLAY, ED_DTMF, ED_MUX_READ, ED_MUX_WRITE, ep, eavesdrop_pvt::flags, switch_core_session_message::from, switch_codec::implementation, switch_core_session_message::message_id, switch_codec_implementation::microseconds_per_packet, eavesdrop_pvt::mutex, switch_codec_implementation::number_of_channels, eavesdrop_pvt::r_buffer, eavesdrop_pvt::r_mutex, switch_frame::rate, eavesdrop_pvt::read_impl, switch_frame::samples, SFF_CNG, SMBF_NO_PAUSE, SMBF_READ_PING, SMBF_READ_REPLACE, SMBF_READ_STREAM, SMBF_READ_VIDEO_PING, SMBF_READ_VIDEO_STREAM, SMBF_SPY_VIDEO_STREAM, SMBF_SPY_VIDEO_STREAM_BLEG, SMBF_THREAD_LOCK, SMBF_WRITE_REPLACE, SMBF_WRITE_STREAM, SMBF_WRITE_VIDEO_STREAM, switch_core_session_message::string_arg, switch_buffer_add_mutex(), switch_buffer_create_dynamic(), switch_buffer_destroy(), switch_buffer_inuse(), switch_buffer_lock(), switch_buffer_read(), switch_buffer_unlock(), switch_buffer_zero(), switch_buffer_zwrite(), switch_channel_dequeue_dtmf(), switch_channel_get_caller_profile(), switch_channel_get_variable, switch_channel_has_dtmf(), switch_channel_media_ack, switch_channel_media_up, switch_channel_pre_answer, switch_channel_ready, SWITCH_CHANNEL_SESSION_LOG, switch_channel_state_change_pending(), switch_channel_test_flag(), switch_channel_up, switch_channel_up_nosig, switch_clear_flag, SWITCH_CODEC_FLAG_DECODE, SWITCH_CODEC_FLAG_ENCODE, switch_core_codec_destroy(), switch_core_codec_init, switch_core_media_bug_add(), switch_core_media_bug_clear_flag(), switch_core_media_bug_remove(), switch_core_media_bug_set_flag(), switch_core_media_bug_test_flag(), switch_core_session_alloc, switch_core_session_dequeue_event(), switch_core_session_get_channel(), switch_core_session_get_pool(), switch_core_session_get_read_impl(), switch_core_session_locate, switch_core_session_read_frame(), switch_core_session_receive_message, switch_core_session_request_video_refresh(), switch_core_session_reset(), switch_core_session_rwunlock(), switch_core_session_set_read_codec(), switch_core_session_strdup, switch_core_session_write_frame(), switch_event_destroy(), switch_event_get_header, SWITCH_FALSE, SWITCH_IO_FLAG_NONE, switch_ivr_phrase_macro, SWITCH_LOG_DEBUG, SWITCH_LOG_ERROR, switch_log_printf(), switch_media_bug_parse_spy_fmt(), switch_media_bug_set_spy_fmt(), SWITCH_MESSAGE_INDICATE_BRIDGE, SWITCH_MESSAGE_INDICATE_DISPLAY, SWITCH_MESSAGE_INDICATE_UNBRIDGE, SWITCH_MESSAGE_INDICATE_VIDEO_REFRESH_REQ, switch_mutex_init(), SWITCH_MUTEX_NESTED, switch_mux_channels(), SWITCH_READ_ACCEPTABLE, SWITCH_RECOMMENDED_BUFFER_SIZE, switch_safe_free, switch_separate_string(), switch_set_flag, switch_snprintf(), SWITCH_STATUS_BREAK, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_test_flag, SWITCH_TRUE, switch_true(), switch_yield, eavesdrop_pvt::tread_impl, eavesdrop_pvt::w_buffer, eavesdrop_pvt::w_mutex, and zstr.

1868 {
1869  switch_core_session_t *tsession;
1872  int codec_initialized = 0;
1873  const char *name, *num;
1874 
1875  if ((tsession = switch_core_session_locate(uuid))) {
1876  struct eavesdrop_pvt *ep = NULL;
1877  switch_media_bug_t *bug = NULL;
1878  switch_channel_t *tchannel = switch_core_session_get_channel(tsession);
1879  switch_frame_t *read_frame, write_frame = { 0 };
1880  switch_codec_t codec = { 0 };
1881  int16_t buf[SWITCH_RECOMMENDED_BUFFER_SIZE / 2];
1882  uint32_t tlen;
1883  const char *macro_name = "eavesdrop_announce";
1884  const char *id_name = NULL;
1886  switch_core_session_message_t msg = { 0 };
1887  char cid_buf[1024] = "";
1888  switch_caller_profile_t *cp = NULL;
1889  uint32_t sanity = 600;
1890  switch_media_bug_flag_t read_flags = 0, write_flags = 0;
1891  const char *vval;
1892  int buf_size = 0;
1893 
1894  if (!switch_channel_media_up(channel)) {
1895  goto end;
1896  }
1897 
1898  while(switch_channel_state_change_pending(tchannel) || !switch_channel_media_up(tchannel)) {
1899  switch_yield(10000);
1900  if (!--sanity) break;
1901  }
1902 
1903  if (!switch_channel_media_up(tchannel)) {
1904  goto end;
1905  }
1906 
1907  switch_core_session_get_read_impl(tsession, &tread_impl);
1909 
1910  if ((id_name = switch_channel_get_variable(tchannel, "eavesdrop_announce_id"))) {
1911  const char *tmp = switch_channel_get_variable(tchannel, "eavesdrop_announce_macro");
1912  if (tmp) {
1913  macro_name = tmp;
1914  }
1915 
1916  switch_ivr_phrase_macro(session, macro_name, id_name, NULL, NULL);
1917  }
1918 
1919 
1920  if (!zstr(require_group)) {
1921  int argc, i;
1922  int ok = 0;
1923  char *argv[10] = { 0 };
1924  char *data;
1925 
1926  const char *group_name = switch_channel_get_variable(tchannel, "eavesdrop_group");
1927  /* If we don't have a group, then return */
1928  if (!group_name) {
1929  status = SWITCH_STATUS_BREAK;
1930  goto end;
1931  }
1932  /* Separate the group */
1933  data = strdup(group_name);
1934  if ((argc = switch_separate_string(data, ',', argv, (sizeof(argv) / sizeof(argv[0]))))) {
1935  for (i = 0; i < argc; i++) {
1936  /* If one of the group matches, then ok */
1937  if (argv[i] && !strcmp(argv[i], require_group)) {
1938  ok = 1;
1939  }
1940  }
1941  }
1942  switch_safe_free(data);
1943  /* If we didn't find any match, then end */
1944  if (!ok) {
1945  status = SWITCH_STATUS_BREAK;
1946  goto end;
1947  }
1948  }
1949 
1950 
1951  ep = switch_core_session_alloc(session, sizeof(*ep));
1952 
1953  tlen = tread_impl.decoded_bytes_per_packet;
1954 
1955 
1957  goto end;
1958  }
1959 
1960 
1961  if (switch_core_codec_init(&codec,
1962  "L16",
1963  NULL,
1964  NULL,
1965  tread_impl.actual_samples_per_second,
1966  tread_impl.microseconds_per_packet / 1000,
1967  tread_impl.number_of_channels,
1970  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot init codec\n");
1971  switch_core_session_rwunlock(tsession);
1972  goto end;
1973  }
1974 
1976 
1977  ep->read_impl = read_impl;
1978  ep->tread_impl = tread_impl;
1979 
1980  codec_initialized = 1;
1981 
1982  switch_core_session_set_read_codec(session, &codec);
1983  write_frame.codec = &codec;
1984  write_frame.data = buf;
1985  write_frame.buflen = sizeof(buf);
1986  write_frame.rate = codec.implementation->actual_samples_per_second;
1987 
1988  /* Make sure that at least one leg is bridged, default to both */
1989  if (! (flags & (ED_BRIDGE_READ | ED_BRIDGE_WRITE))) {
1991  }
1992 
1993  buf_size = codec.implementation->decoded_bytes_per_packet * 10;
1994 
1995  ep->eavesdropper = session;
1996  ep->flags = flags;
1998  switch_buffer_create_dynamic(&ep->buffer, buf_size, buf_size, buf_size);
2000 
2002  switch_buffer_create_dynamic(&ep->w_buffer, buf_size, buf_size, buf_size);
2004 
2006  switch_buffer_create_dynamic(&ep->r_buffer, buf_size, buf_size, buf_size);
2008 
2009  if (flags & ED_BRIDGE_READ) {
2010  read_flags = SMBF_READ_STREAM | SMBF_READ_REPLACE;
2011  }
2012 
2013  if (flags & ED_BRIDGE_WRITE) {
2014  write_flags = SMBF_WRITE_STREAM | SMBF_WRITE_REPLACE;
2015  }
2016 
2018  if ((vval = switch_channel_get_variable(session->channel, "eavesdrop_show_listener_video"))) {
2019  if (switch_true(vval) || !strcasecmp(vval, "aleg") || !strcasecmp(vval, "bleg") || !strcasecmp(vval, "both")) {
2020  read_flags |= SMBF_SPY_VIDEO_STREAM;
2021  }
2022  if (switch_true(vval) || !strcasecmp(vval, "bleg") || !strcasecmp(vval, "both")) {
2023  read_flags |= SMBF_SPY_VIDEO_STREAM_BLEG;
2024  }
2025  }
2026 
2027  if ((vval = switch_channel_get_variable(session->channel, "eavesdrop_concat_video")) && switch_true(vval)) {
2028  read_flags |= SMBF_READ_VIDEO_STREAM;
2029  read_flags |= SMBF_WRITE_VIDEO_STREAM;
2030  } else {
2031  read_flags |= SMBF_READ_VIDEO_PING;
2032  }
2033  } else {
2034  read_flags &= ~SMBF_READ_VIDEO_PING;
2035  read_flags &= ~SMBF_READ_VIDEO_STREAM;
2036  read_flags &= ~SMBF_WRITE_VIDEO_STREAM;
2037  read_flags &= ~SMBF_SPY_VIDEO_STREAM;
2038  read_flags &= ~SMBF_SPY_VIDEO_STREAM_BLEG;
2039  }
2040 
2041 
2042  if (switch_core_media_bug_add(tsession, "eavesdrop", uuid,
2043  eavesdrop_callback, ep, 0,
2044  read_flags | write_flags | SMBF_READ_PING | SMBF_THREAD_LOCK | SMBF_NO_PAUSE,
2045  &bug) != SWITCH_STATUS_SUCCESS) {
2046  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot attach bug\n");
2047  goto end;
2048  }
2049 
2050  if ((vval = switch_channel_get_variable(session->channel, "eavesdrop_video_spy_fmt"))) {
2052  }
2053 
2054  msg.from = __FILE__;
2055 
2056  /* Tell the channel we are going to be in a bridge */
2058  switch_core_session_receive_message(session, &msg);
2059  cp = switch_channel_get_caller_profile(tchannel);
2060 
2061  name = cp->caller_id_name;
2062  num = cp->caller_id_number;
2063 
2064  if (flags & ED_COPY_DISPLAY) {
2066  name = cp->callee_id_name;
2067  num = cp->callee_id_number;
2068  } else {
2069  name = cp->caller_id_name;
2070  num = cp->caller_id_number;
2071  }
2072  }
2073 
2074  sanity = 300;
2075  while(switch_channel_up(channel) && !switch_channel_media_ack(channel) && --sanity) {
2076  switch_yield(10000);
2077  }
2078 
2079 
2080  switch_snprintf(cid_buf, sizeof(cid_buf), "%s|%s", name, num);
2081  msg.string_arg = cid_buf;
2083  switch_core_session_receive_message(session, &msg);
2084 
2085  if (switch_channel_test_flag(tchannel, CF_VIDEO)) {
2086 
2088 
2089  switch_core_session_receive_message(tsession, &msg);
2090  }
2091 
2092  while (switch_channel_up_nosig(tchannel) && switch_channel_ready(channel)) {
2093  uint32_t len = sizeof(buf);
2094  switch_event_t *event = NULL;
2095  char *fcommand = NULL;
2096  char db[2] = "";
2097  int vid_bug = 0, vid_dual = 0;
2098 
2099  status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
2100 
2101  if (!SWITCH_READ_ACCEPTABLE(status)) {
2102  goto end_loop;
2103  }
2104 
2106  char *command = switch_event_get_header(event, "eavesdrop-command");
2107  if (command) {
2108  fcommand = switch_core_session_strdup(session, command);
2109  }
2110  switch_event_destroy(&event);
2111  }
2112 
2113  if ((flags & ED_DTMF) && switch_channel_has_dtmf(channel)) {
2114  switch_dtmf_t dtmf = { 0 };
2115  switch_channel_dequeue_dtmf(channel, &dtmf);
2116  db[0] = dtmf.digit;
2117  fcommand = db;
2118  }
2119 
2122  vid_dual = 1;
2123  }
2124 
2125  if (vid_dual || switch_core_media_bug_test_flag(bug, SMBF_READ_VIDEO_PING)) {
2126  vid_bug = 1;
2127  }
2128 
2129  if (fcommand) {
2130  char *d;
2131  for (d = fcommand; *d; d++) {
2132  int z = 1;
2133 
2134  switch (*d) {
2135  case '1':
2138  if (vid_bug) {
2142  }
2143  break;
2144  case '2':
2147  if (vid_bug) {
2151  }
2152  break;
2153  case '3':
2156  if (vid_bug) {
2160  }
2161  break;
2162 
2163  case '4':
2165  break;
2166  case '5':
2168  break;
2169  case '6':
2171  break;
2172  case '0':
2175  if (vid_bug) {
2179  }
2180  break;
2181  case '*':
2182  goto end_loop;
2183  default:
2184  z = 0;
2185  break;
2186 
2187  }
2188 
2189  if (z) {
2190  if (ep->r_buffer) {
2194  }
2195 
2196  if (ep->w_buffer) {
2200  }
2201  }
2202  }
2203  }
2204 
2205  if (!switch_test_flag(read_frame, SFF_CNG)) {
2207  switch_buffer_zwrite(ep->r_buffer, read_frame->data, read_frame->datalen);
2209 
2211  switch_buffer_zwrite(ep->w_buffer, read_frame->data, read_frame->datalen);
2213  }
2214 
2215  if (len > tlen) {
2216  len = tlen;
2217  }
2218 
2219  if (switch_buffer_inuse(ep->buffer) >= len) {
2221  while (switch_buffer_inuse(ep->buffer) >= len) {
2222  int tchanged = 0, changed = 0;
2223 
2224  write_frame.datalen = (uint32_t) switch_buffer_read(ep->buffer, buf, len);
2225  write_frame.samples = write_frame.datalen / 2;
2226 
2227 
2228  switch_core_session_get_read_impl(tsession, &tread_impl);
2230 
2231  if (tread_impl.number_of_channels != ep->tread_impl.number_of_channels ||
2233  tchanged = 1;
2234  }
2235 
2238  changed = 1;
2239  }
2240 
2241  if (changed || tchanged) {
2242 
2243  if (changed) {
2245  "SPYING CHANNEL CODEC CHANGE FROM %dhz@%dc to %dhz@%dc\n",
2250  }
2251 
2252  if (tchanged) {
2254  "SPYED CHANNEL CODEC CHANGE FROM %dhz@%dc to %dhz@%dc\n",
2257  tread_impl.actual_samples_per_second,
2258  tread_impl.number_of_channels);
2259 
2260  tlen = tread_impl.decoded_bytes_per_packet;
2261 
2262  if (len > tlen) {
2263  len = tlen;
2264  }
2265 
2266  switch_core_codec_destroy(&codec);
2267 
2268  if (switch_core_codec_init(&codec,
2269  "L16",
2270  NULL,
2271  NULL,
2272  tread_impl.actual_samples_per_second,
2273  tread_impl.microseconds_per_packet / 1000,
2274  tread_impl.number_of_channels,
2277  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot init codec\n");
2278  switch_core_session_rwunlock(tsession);
2279  goto end;
2280  }
2281  }
2282 
2283  ep->read_impl = read_impl;
2284  ep->tread_impl = tread_impl;
2285  }
2286 
2287 
2289  uint32_t rlen = write_frame.datalen / 2 / ep->tread_impl.number_of_channels;
2290 
2291  switch_mux_channels((int16_t *) write_frame.data, rlen, ep->tread_impl.number_of_channels, ep->read_impl.number_of_channels);
2292  write_frame.datalen = rlen * 2 * ep->read_impl.number_of_channels;
2293  write_frame.samples = write_frame.datalen / 2;
2294  }
2295 
2296  if ((status = switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0)) != SWITCH_STATUS_SUCCESS) {
2297  break;
2298  }
2299  }
2301  }
2302 
2303  }
2304 
2305  end_loop:
2306 
2307  /* Tell the channel we are no longer going to be in a bridge */
2309  switch_core_session_receive_message(session, &msg);
2310 
2311 
2312 
2313  end:
2314 
2315  if (codec_initialized)
2316  switch_core_codec_destroy(&codec);
2317 
2318  if (bug) {
2319  switch_core_media_bug_remove(tsession, &bug);
2320  }
2321 
2322  if (ep) {
2323  if (ep->buffer) {
2325  }
2326 
2327  if (ep->r_buffer) {
2329  }
2330 
2331  if (ep->w_buffer) {
2333  }
2334  }
2335 
2336  switch_core_session_rwunlock(tsession);
2337  status = SWITCH_STATUS_SUCCESS;
2338 
2340  }
2341 
2342  return status;
2343 }
#define SWITCH_CHANNEL_SESSION_LOG(x)
Call Specific Data.
Definition: switch_caller.h:73
#define switch_set_flag(obj, flag)
Set a flag on an arbitrary object.
Definition: switch_utils.h:631
switch_size_t switch_buffer_zwrite(_In_ switch_buffer_t *buffer, _In_bytecount_(datalen) const void *data, _In_ switch_size_t datalen)
switch_core_session_message_types_t message_id
Definition: switch_core.h:181
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.
switch_size_t switch_buffer_read(_In_ switch_buffer_t *buffer, _In_ void *data, _In_ switch_size_t datalen)
Read data from a switch_buffer_t up to the ammount of datalen if it is available. Remove read data fr...
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.
#define switch_channel_up(_channel)
#define SWITCH_RECOMMENDED_BUFFER_SIZE
Definition: switch_types.h:557
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.
switch_buffer_t * r_buffer
Representation of an event.
Definition: switch_event.h:80
#define switch_channel_ready(_channel)
void switch_media_bug_set_spy_fmt(switch_media_bug_t *bug, switch_vid_spy_fmt_t spy_fmt)
uint32_t switch_core_media_bug_set_flag(_In_ switch_media_bug_t *bug, _In_ uint32_t flag)
switch_mutex_t * w_mutex
switch_status_t switch_core_codec_destroy(switch_codec_t *codec)
Destroy an initalized codec handle.
int switch_snprintf(_Out_z_cap_(len) char *buf, _In_ switch_size_t len, _In_z_ _Printf_format_string_ const char *format,...)
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.
static int switch_true(const char *expr)
Evaluate the truthfullness of a string expression.
Definition: switch_utils.h:450
uint32_t switch_channel_test_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Test for presence of given flag on a given channel.
switch_core_session_t * eavesdropper
static switch_bool_t eavesdrop_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type)
switch_status_t switch_core_session_read_frame(_In_ switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id)
Read a frame from a session.
switch_codec_t * codec
Definition: switch_frame.h:45
A message object designed to allow unlike technologies to exchange data.
Definition: switch_core.h:177
#define zstr(x)
Definition: switch_utils.h:281
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.
#define switch_clear_flag(obj, flag)
Clear a flag on an arbitrary object while locked.
Definition: switch_utils.h:655
#define SWITCH_MUTEX_NESTED
Definition: switch_apr.h:318
uint8_t data[SWITCH_RECOMMENDED_BUFFER_SIZE]
const switch_codec_implementation_t * implementation
uint32_t buflen
Definition: switch_frame.h:59
switch_byte_t switch_byte_t * buf
#define switch_yield(ms)
Wait a desired number of microseconds and yield the CPU.
Definition: switch_utils.h:908
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.
switch_channel_t * channel
uint32_t datalen
Definition: switch_frame.h:57
switch_codec_implementation_t tread_impl
const char * callee_id_number
Definition: switch_caller.h:89
void switch_buffer_lock(_In_ switch_buffer_t *buffer)
switch_codec_implementation_t read_impl
uint32_t rate
Definition: switch_frame.h:63
#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.
const char * caller_id_name
Definition: switch_caller.h:79
#define switch_safe_free(it)
Free a pointer and set it to NULL unless it already is NULL.
Definition: switch_utils.h:789
switch_status_t switch_mutex_init(switch_mutex_t **lock, unsigned int flags, switch_memory_pool_t *pool)
Definition: switch_apr.c:270
uint32_t switch_core_media_bug_clear_flag(_In_ switch_media_bug_t *bug, _In_ uint32_t flag)
void switch_buffer_zero(_In_ switch_buffer_t *buffer)
Remove all data from the buffer.
switch_buffer_t * w_buffer
An abstraction of a data frame.
Definition: switch_frame.h:43
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.
switch_vid_spy_fmt_t switch_media_bug_parse_spy_fmt(const char *name)
#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:1602
void switch_buffer_add_mutex(_In_ switch_buffer_t *buffer, _In_ switch_mutex_t *mutex)
#define switch_core_session_receive_message(_session, _message)
Definition: switch_core.h:1217
void switch_core_session_rwunlock(_In_ switch_core_session_t *session)
Unlock a read or write lock on as given session.
void switch_mux_channels(int16_t *data, switch_size_t samples, uint32_t orig_channels, uint32_t channels)
switch_status_t switch_core_session_request_video_refresh(switch_core_session_t *session)
static const char * ep
Definition: switch_json.c:36
switch_status_t
Common return values.
switch_status_t switch_core_session_dequeue_event(_In_ switch_core_session_t *session, _Out_ switch_event_t **event, switch_bool_t force)
DE-Queue an event on a given session.
switch_size_t switch_channel_has_dtmf(_In_ switch_channel_t *channel)
Test for presence of DTMF on a given channel.
void switch_buffer_unlock(_In_ switch_buffer_t *buffer)
#define switch_core_session_locate(uuid_str)
Locate a session based on it's uuid.
Definition: switch_core.h:916
int switch_channel_state_change_pending(switch_channel_t *channel)
uint32_t samples
Definition: switch_frame.h:61
#define switch_event_get_header(_e, _h)
Definition: switch_event.h:172
switch_mutex_t * r_mutex
#define switch_channel_media_ack(_channel)
const char * caller_id_number
Definition: switch_caller.h:81
#define switch_core_session_alloc(_session, _memory)
Allocate memory from a session's pool.
Definition: switch_core.h:694
switch_buffer_t * buffer
#define switch_test_flag(obj, flag)
Test for the existance of a flag on an arbitary object.
Definition: switch_utils.h:624
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
A table of settings and callbacks that define a paticular implementation of a codec.
#define switch_ivr_phrase_macro(session, macro_name, data, lang, args)
Definition: switch_ivr.h:903
uint32_t switch_media_bug_flag_t
uint32_t switch_core_media_bug_test_flag(_In_ switch_media_bug_t *bug, _In_ uint32_t flag)
Test for the existance of a flag on an media bug.
#define switch_channel_up_nosig(_channel)
#define switch_core_session_strdup(_session, _todup)
Copy a string using memory allocation from a session's pool.
Definition: switch_core.h:717
void switch_event_destroy(switch_event_t **event)
Destroy an event.
#define switch_channel_pre_answer(channel)
Indicate progress on a channel to attempt early media.
switch_caller_profile_t * switch_channel_get_caller_profile(switch_channel_t *channel)
Retrieve the given channel's caller profile.
switch_mutex_t * mutex
switch_size_t switch_buffer_inuse(_In_ switch_buffer_t *buffer)
Get the in use amount of a switch_buffer_t.
void switch_buffer_destroy(switch_buffer_t **buffer)
Destroy the buffer.
#define SWITCH_READ_ACCEPTABLE(status)
Definition: switch_utils.h:995
#define switch_channel_media_up(_channel)
const char * callee_id_name
Definition: switch_caller.h:87
switch_memory_pool_t * switch_core_session_get_pool(_In_ switch_core_session_t *session)
Retrieve the memory pool from a session.
switch_status_t switch_ivr_eavesdrop_update_display ( switch_core_session_t session,
const char *  name,
const char *  number 
)

Definition at line 1845 of file switch_ivr_async.c.

References exec_cb_data::caller, display_exec_cb(), switch_channel_clear_app_flag_key(), switch_channel_set_app_flag_key(), switch_channel_test_app_flag_key(), switch_core_media_bug_exec_all(), switch_core_session_alloc, switch_core_session_get_channel(), switch_core_session_strdup, SWITCH_STATUS_FALSE, exec_cb_data::val, and exec_cb_data::var.

1846 {
1847  struct exec_cb_data *data = NULL;
1850 
1851  data = switch_core_session_alloc(session, sizeof(*data));
1852  data->var = switch_core_session_strdup(session, name);
1853  data->val = switch_core_session_strdup(session, number);
1854  data->caller = session;
1855 
1856  if (!switch_channel_test_app_flag_key("EAVESDROP", channel, 1)) {
1857  switch_channel_set_app_flag_key("EAVESDROP", channel, 1);
1858  status = switch_core_media_bug_exec_all(session, "eavesdrop", display_exec_cb, data);
1859  switch_channel_clear_app_flag_key("EAVESDROP", channel, 1);
1860  }
1861 
1862  return status;
1863 }
switch_core_session_t * caller
_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_clear_app_flag_key(const char *app, switch_channel_t *channel, uint32_t flags)
static void display_exec_cb(switch_media_bug_t *bug, void *user_data)
void switch_channel_set_app_flag_key(const char *app, switch_channel_t *channel, uint32_t flags)
switch_status_t
Common return values.
#define switch_core_session_alloc(_session, _memory)
Allocate memory from a session's pool.
Definition: switch_core.h:694
#define switch_core_session_strdup(_session, _todup)
Copy a string using memory allocation from a session's pool.
Definition: switch_core.h:717
switch_status_t switch_core_media_bug_exec_all(switch_core_session_t *orig_session, const char *function, switch_media_bug_exec_cb_t cb, void *user_data)
int switch_channel_test_app_flag_key(const char *app, switch_channel_t *channel, uint32_t flags)
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 
)

Definition at line 1454 of file switch_ivr_originate.c.

References enterprise_originate_handle_t::bleg, enterprise_originate_handle_t::cause, CF_ANSWERED, CF_NOT_READY, CF_PROXY_MEDIA, CF_PROXY_MODE, enterprise_originate_handle_t::done, enterprise_originate_ringback_thread(), enterprise_originate_thread(), MAX_PEERS, mutex, enterprise_originate_handle_t::mutex, switch_event_header::name, switch_event_header::next, enterprise_originate_handle_t::ovars, pool, ent_originate_ringback::ringback_data, running, ent_originate_ringback::running, ent_originate_ringback::session, enterprise_originate_handle_t::status, switch_caller_profile_dup(), SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER, SWITCH_CAUSE_LOSE_RACE, SWITCH_CAUSE_NO_ANSWER, SWITCH_CAUSE_NO_PICKUP, SWITCH_CAUSE_SUCCESS, switch_channel_cause2str(), switch_channel_clear_flag(), switch_channel_get_caller_profile(), switch_channel_get_variable, switch_channel_handle_cause(), switch_channel_media_ready, switch_channel_pre_answer, switch_channel_process_export(), switch_channel_ready, SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_flag, switch_channel_set_variable, switch_channel_test_flag(), switch_core_destroy_memory_pool, switch_core_new_memory_pool, switch_core_session_get_channel(), switch_core_session_get_uuid(), switch_core_strdup, SWITCH_ENT_ORIGINATE_DELIM, switch_event_add_header_string(), SWITCH_EVENT_CHANNEL_DATA, switch_event_create_brackets(), switch_event_create_plain(), switch_event_destroy(), switch_event_dup(), SWITCH_EXPORT_VARS_VARIABLE, SWITCH_FALSE, switch_goto_status, SWITCH_LOG_DEBUG, SWITCH_LOG_ERROR, switch_log_printf(), switch_mutex_init(), switch_mutex_lock(), SWITCH_MUTEX_NESTED, switch_mutex_unlock(), switch_separate_string_string(), SWITCH_STACK_BOTTOM, SWITCH_STATUS_FALSE, SWITCH_STATUS_GENERR, SWITCH_STATUS_SUCCESS, switch_thread_create(), switch_thread_join(), SWITCH_THREAD_STACKSIZE, switch_threadattr_create(), switch_threadattr_stacksize_set(), switch_yield, thread, enterprise_originate_handle_t::thread, ent_originate_ringback::thread, switch_event_header::value, and zstr.

Referenced by switch_ivr_originate().

1465 {
1466  int x_argc = 0;
1467  char *x_argv[MAX_PEERS] = { 0 };
1468  enterprise_originate_handle_t *hp = NULL, handles[MAX_PEERS] = { {0} };
1469  int i;
1470  switch_caller_profile_t *cp = NULL;
1471  switch_channel_t *channel = NULL;
1472  char *data;
1474  switch_threadattr_t *thd_attr = NULL;
1475  int running = 0, over = 0;
1478  switch_event_header_t *hi = NULL;
1479  struct ent_originate_ringback rb_data = { 0 };
1480  const char *ringback_data = NULL;
1481  switch_event_t *var_event = NULL;
1482  int getcause = 1;
1483 
1484  *cause = SWITCH_CAUSE_SUCCESS;
1485 
1487 
1488  if (zstr(bridgeto)) {
1490  getcause = 0;
1492  }
1493 
1494  data = switch_core_strdup(pool, bridgeto);
1495 
1496  if (session) {
1497  switch_caller_profile_t *cpp = NULL;
1498  channel = switch_core_session_get_channel(session);
1499  if ((cpp = switch_channel_get_caller_profile(channel))) {
1500  cp = switch_caller_profile_dup(pool, cpp);
1501  }
1502  }
1503 
1504  if (ovars) {
1505  var_event = ovars;
1506  } else {
1508  abort();
1509  }
1510  }
1511 
1512  if (session) {
1513  switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "ent_originate_aleg_uuid", switch_core_session_get_uuid(session));
1514  }
1515 
1516  if (channel) {
1517  const char *tmp_var = NULL;
1518 
1520 
1521  if ((tmp_var = switch_channel_get_variable(channel, "effective_ani"))) {
1522  switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "origination_ani", tmp_var);
1523  }
1524 
1525  if ((tmp_var = switch_channel_get_variable(channel, "effective_aniii"))) {
1526  switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "origination_aniii", tmp_var);
1527  }
1528 
1529  if ((tmp_var = switch_channel_get_variable(channel, "effective_caller_id_name"))) {
1530  switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "origination_caller_id_name", tmp_var);
1531  }
1532 
1533  if ((tmp_var = switch_channel_get_variable(channel, "effective_caller_id_number"))) {
1534  switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "origination_caller_id_number", tmp_var);
1535  }
1536  }
1537 
1538  /* strip leading spaces */
1539  while (data && *data && *data == ' ') {
1540  data++;
1541  }
1542 
1543  /* extract channel variables, allowing multiple sets of braces */
1544  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Parsing ultra-global variables\n");
1545  while (*data == '<') {
1546  char *parsed = NULL;
1547 
1548  if (switch_event_create_brackets(data, '<', '>', ',', &var_event, &parsed, SWITCH_FALSE) != SWITCH_STATUS_SUCCESS || !parsed) {
1549  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Parse Error!\n");
1551  }
1552 
1553  data = parsed;
1554  }
1555 
1556  /* strip leading spaces (again) */
1557  while (data && *data && *data == ' ') {
1558  data++;
1559  }
1560 
1561  if (ovars && ovars != var_event) {
1562  for (hi = ovars->headers; hi; hi = hi->next) {
1564  }
1565  }
1566 
1567  switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "ignore_early_media", "true");
1568 
1569  if (!(x_argc = switch_separate_string_string(data, SWITCH_ENT_ORIGINATE_DELIM, x_argv, MAX_PEERS))) {
1571  getcause = 0;
1573  }
1574 
1575  switch_threadattr_create(&thd_attr, pool);
1577 
1578  for (i = 0; i < x_argc; i++) {
1579  handles[i].session = session;
1580  handles[i].bleg = NULL;
1581  handles[i].cause = 0;
1582  handles[i].cancel_cause = 0;
1583  handles[i].bridgeto = x_argv[i];
1584  handles[i].timelimit_sec = timelimit_sec;
1585  handles[i].table = table;
1586  handles[i].cid_name_override = cid_name_override;
1587  handles[i].cid_num_override = cid_num_override;
1588  handles[i].caller_profile_override = cp;
1589  switch_event_dup(&handles[i].ovars, var_event);
1590  handles[i].flags = flags;
1591  switch_mutex_init(&handles[i].mutex, SWITCH_MUTEX_NESTED, pool);
1592  switch_mutex_lock(handles[i].mutex);
1593  switch_thread_create(&handles[i].thread, thd_attr, enterprise_originate_thread, &handles[i], pool);
1594  }
1595 
1596  if (channel && !switch_channel_test_flag(channel, CF_PROXY_MODE) && !switch_channel_test_flag(channel, CF_PROXY_MEDIA)) {
1597  if (switch_channel_test_flag(channel, CF_ANSWERED)) {
1598  ringback_data = switch_channel_get_variable(channel, "transfer_ringback");
1599  }
1600 
1601  if (!ringback_data) {
1602  ringback_data = switch_channel_get_variable(channel, "ringback");
1603  }
1604 
1605  if (ringback_data || switch_channel_media_ready(channel)) {
1606  rb_data.ringback_data = ringback_data;
1607  rb_data.session = session;
1608  rb_data.running = 1;
1609  if (!switch_channel_media_ready(channel)) {
1611  goto done;
1612  }
1613  }
1614  switch_thread_create(&rb_data.thread, thd_attr, enterprise_originate_ringback_thread, &rb_data, pool);
1615  }
1616  }
1617 
1618 
1619  for (;;) {
1620  running = 0;
1621  over = 0;
1622 
1623  if (channel && !switch_channel_ready(channel)) {
1624  break;
1625  }
1626 
1627  if (cancel_cause && *cancel_cause > 0) {
1628  break;
1629  }
1630 
1631  for (i = 0; i < x_argc; i++) {
1632 
1633 
1634  if (handles[i].done == 0) {
1635  running++;
1636  } else if (handles[i].done == 1) {
1637  if (handles[i].status == SWITCH_STATUS_SUCCESS) {
1638  handles[i].done = 2;
1639  hp = &handles[i];
1640  goto done;
1641  } else {
1642  handles[i].done = -1;
1643  }
1644  } else {
1645  over++;
1646  }
1647 
1648  switch_yield(10000);
1649  }
1650 
1651  if (!running || over == x_argc) {
1652  break;
1653  }
1654  }
1655 
1656 
1657  done:
1658 
1659  if (hp) {
1660  *cause = hp->cause;
1661  getcause = 0;
1662  status = hp->status;
1663  *bleg = hp->bleg;
1665  switch_thread_join(&tstatus, hp->thread);
1667  }
1668 
1669  for (i = 0; i < x_argc; i++) {
1670  if (hp == &handles[i]) {
1671  continue;
1672  }
1673 
1674  if (cancel_cause && *cancel_cause > 0) {
1675  handles[i].cancel_cause = *cancel_cause;
1676  } else {
1677  handles[i].cancel_cause = SWITCH_CAUSE_LOSE_RACE;
1678  }
1679  }
1680 
1681  for (i = 0; i < x_argc; i++) {
1682 
1683  if (hp == &handles[i]) {
1684  continue;
1685  }
1686 
1687  if (channel && handles[i].cause && handles[i].cause != SWITCH_CAUSE_SUCCESS) {
1688  switch_channel_handle_cause(channel, handles[i].cause);
1689  }
1690 
1691  switch_mutex_unlock(handles[i].mutex);
1692 
1693  if (getcause && *cause != handles[i].cause && handles[i].cause != SWITCH_CAUSE_LOSE_RACE && handles[i].cause != SWITCH_CAUSE_NO_PICKUP) {
1694  *cause = handles[i].cause;
1695  getcause++;
1696  }
1697 
1698  switch_thread_join(&tstatus, handles[i].thread);
1699  switch_event_destroy(&handles[i].ovars);
1700  }
1701 
1702  if (channel && rb_data.thread) {
1704  switch_thread_join(&tstatus, rb_data.thread);
1706  }
1707 
1708 
1709  end:
1710 
1711  if (getcause == 1 && *cause == SWITCH_CAUSE_SUCCESS) {
1712  *cause = SWITCH_CAUSE_NO_ANSWER;
1713  }
1714 
1715  if (channel) {
1716  if (*cause == SWITCH_CAUSE_SUCCESS) {
1717  switch_channel_set_variable(channel, "originate_disposition", "success");
1718  } else {
1719  switch_channel_set_variable(channel, "originate_disposition", "failure");
1720  switch_channel_set_variable(channel, "hangup_cause", switch_channel_cause2str(*cause));
1721  }
1722  }
1723 
1724 
1725  if (var_event && var_event != ovars) {
1726  switch_event_destroy(&var_event);
1727  }
1728 
1730 
1731  return status;
1732 
1733 }
#define switch_core_new_memory_pool(p)
Create a new sub memory pool from the core's master pool.
Definition: switch_core.h:631
#define SWITCH_CHANNEL_SESSION_LOG(x)
Call Specific Data.
Definition: switch_caller.h:73
const char * switch_channel_cause2str(_In_ switch_call_cause_t cause)
return a cause string for a given cause
unsigned int switch_separate_string_string(char *buf, char *delim, _Post_count_(return) char **array, unsigned int arraylen)
switch_status_t switch_event_create_brackets(char *data, char a, char b, char c, switch_event_t **event, char **new_data, switch_bool_t dup)
#define switch_core_strdup(_pool, _todup)
Copy a string using memory allocation from a given pool.
Definition: switch_core.h:729
switch_status_t switch_threadattr_stacksize_set(switch_threadattr_t *attr, switch_size_t stacksize)
Definition: switch_apr.c:660
#define switch_core_destroy_memory_pool(p)
Returns a subpool back to the main pool.
Definition: switch_core.h:640
switch_memory_pool_t * pool
static void *SWITCH_THREAD_FUNC enterprise_originate_thread(switch_thread_t *thread, void *obj)
Representation of an event.
Definition: switch_event.h:80
#define switch_channel_ready(_channel)
An event Header.
Definition: switch_event.h:65
#define switch_channel_media_ready(_channel)
static void *SWITCH_THREAD_FUNC enterprise_originate_ringback_thread(switch_thread_t *thread, void *obj)
switch_status_t switch_event_dup(switch_event_t **event, switch_event_t *todup)
Duplicate an event.
static switch_thread_t * thread
Definition: switch_log.c:279
uint32_t switch_channel_test_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Test for presence of given flag on a given channel.
#define zstr(x)
Definition: switch_utils.h:281
switch_status_t switch_mutex_unlock(switch_mutex_t *lock)
Definition: switch_apr.c:290
switch_status_t switch_thread_join(switch_status_t *retval, switch_thread_t *thd)
Definition: switch_apr.c:1255
_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_MUTEX_NESTED
Definition: switch_apr.h:318
#define switch_yield(ms)
Wait a desired number of microseconds and yield the CPU.
Definition: switch_utils.h:908
switch_status_t switch_mutex_lock(switch_mutex_t *lock)
Definition: switch_apr.c:285
void switch_channel_process_export(switch_channel_t *channel, switch_channel_t *peer_channel, switch_event_t *var_event, const char *export_varname)
#define switch_channel_get_variable(_c, _v)
#define SWITCH_THREAD_STACKSIZE
Definition: switch_types.h:551
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_core_session_t * session
switch_status_t switch_mutex_init(switch_mutex_t **lock, unsigned int flags, switch_memory_pool_t *pool)
Definition: switch_apr.c:270
#define SWITCH_ENT_ORIGINATE_DELIM
Definition: switch_types.h:46
#define MAX_PEERS
static switch_status_t switch_event_create_plain(switch_event_t **event, switch_event_types_t event_id)
Definition: switch_event.h:385
static int32_t running
char * switch_core_session_get_uuid(_In_ switch_core_session_t *session)
Retrieve the unique identifier from a session.
switch_mutex_t * mutex
switch_status_t
Common return values.
#define switch_goto_status(_status, _label)
Definition: switch_utils.h:256
struct switch_event_header * next
Definition: switch_event.h:76
#define switch_channel_set_flag(_c, _f)
switch_caller_profile_t * switch_caller_profile_dup(_In_ switch_memory_pool_t *pool, _In_ switch_caller_profile_t *tocopy)
Duplicate an existing caller profile object.
struct apr_pool_t switch_memory_pool_t
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
switch_status_t switch_threadattr_create(switch_threadattr_t **new_attr, switch_memory_pool_t *pool)
Definition: switch_apr.c:642
switch_status_t switch_thread_create(switch_thread_t **new_thread, switch_threadattr_t *attr, switch_thread_start_t func, void *data, switch_memory_pool_t *cont)
Definition: switch_apr.c:675
void switch_event_destroy(switch_event_t **event)
Destroy an event.
void switch_channel_clear_flag(switch_channel_t *channel, switch_channel_flag_t flag)
Clear given flag(s) from a channel.
#define switch_channel_set_variable(_channel, _var, _val)
#define switch_channel_pre_answer(channel)
Indicate progress on a channel to attempt early media.
switch_caller_profile_t * switch_channel_get_caller_profile(switch_channel_t *channel)
Retrieve the given channel's caller profile.
switch_event_header_t * headers
Definition: switch_event.h:90
#define SWITCH_EXPORT_VARS_VARIABLE
Definition: switch_types.h:194
void switch_channel_handle_cause(switch_channel_t *channel, switch_call_cause_t cause)
switch_status_t switch_ivr_generate_json_cdr ( switch_core_session_t session,
cJSON **  json_cdr,
switch_bool_t  urlencode 
)

Generate an JSON CDR report.

Parameters
sessionthe session to get the data from.
json_cdrpointer to the json object
Returns
SWITCH_STATUS_SUCCESS if successful
Note
on success the json object must be freed

Definition at line 3177 of file switch_ivr.c.

References switch_channel_timetable::answered, switch_app_log::app, switch_caller_application::application_data, switch_caller_application::application_name, switch_caller_extension::applications, switch_app_log::arg, switch_channel_timetable::bridged, switch_caller_profile::caller_extension, switch_caller_extension::children, cJSON_AddItemToArray(), cJSON_AddItemToObject(), cJSON_CreateArray(), cJSON_CreateObject(), cJSON_CreateString(), switch_channel_timetable::created, switch_caller_extension::current_application, switch_caller_profile::dialplan, switch_caller_extension::extension_name, switch_caller_extension::extension_number, switch_channel_timetable::hold_accum, switch_channel_timetable::hungup, switch_channel_timetable::last_hold, switch_app_log::next, switch_caller_profile::next, switch_caller_application::next, switch_caller_profile::originatee_caller_profile, switch_caller_profile::originator_caller_profile, switch_channel_timetable::profile_created, switch_caller_profile::profile_index, switch_channel_timetable::progress, switch_channel_timetable::progress_media, switch_channel_timetable::resurrected, SWITCH_CALL_DIRECTION_OUTBOUND, switch_channel_direction(), switch_channel_get_caller_profile(), switch_channel_get_cap_string(), switch_channel_get_flag_string(), switch_channel_get_state(), switch_channel_state_name(), switch_core_get_switchname(), switch_core_get_uuid(), switch_core_session_get_app_log(), switch_core_session_get_channel(), switch_ivr_set_json_call_stats(), switch_ivr_set_json_chan_vars(), switch_ivr_set_json_profile_data(), SWITCH_MEDIA_TYPE_AUDIO, SWITCH_MEDIA_TYPE_VIDEO, switch_snprintf(), SWITCH_STATUS_SUCCESS, switch_str_nil, SWITCH_TIME_T_FMT, switch_caller_profile::times, switch_channel_timetable::transferred, and zstr.

Referenced by switch_ivr_multi_threaded_bridge(), and switch_ivr_originate().

3178 {
3179  cJSON *cdr = cJSON_CreateObject();
3181  switch_caller_profile_t *caller_profile;
3182  cJSON *variables, *j_main_cp, *j_caller_profile, *j_caller_extension, *j_caller_extension_apps, *j_times, *j_application,
3183  *j_callflow, *j_profile, *j_inner_extension, *j_app_log, *j_apps, *j_o, *j_o_profiles, *j_channel_data, *callStats;
3184  switch_app_log_t *app_log;
3185  char tmp[512], *f;
3186 
3189  j_channel_data = cJSON_CreateObject();
3190 
3191  cJSON_AddItemToObject(cdr, "channel_data", j_channel_data);
3192 
3194  cJSON_AddItemToObject(j_channel_data, "direction", cJSON_CreateString(switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND ? "outbound" : "inbound"));
3195 
3196  switch_snprintf(tmp, sizeof(tmp), "%d", switch_channel_get_state(channel));
3197  cJSON_AddItemToObject(j_channel_data, "state_number", cJSON_CreateString((char *) tmp));
3198 
3199  if ((f = switch_channel_get_flag_string(channel))) {
3200  cJSON_AddItemToObject(j_channel_data, "flags", cJSON_CreateString((char *) f));
3201  free(f);
3202  }
3203 
3204  if ((f = switch_channel_get_cap_string(channel))) {
3205  cJSON_AddItemToObject(j_channel_data, "caps", cJSON_CreateString((char *) f));
3206  free(f);
3207  }
3208 
3209  callStats = cJSON_CreateObject();
3210  cJSON_AddItemToObject(cdr, "callStats", callStats);
3213 
3214  variables = cJSON_CreateObject();
3215  cJSON_AddItemToObject(cdr, "variables", variables);
3216  switch_ivr_set_json_chan_vars(variables, channel, urlencode);
3217 
3218 
3219  if ((app_log = switch_core_session_get_app_log(session))) {
3220  switch_app_log_t *ap;
3221 
3222  j_app_log = cJSON_CreateObject();
3223  j_apps = cJSON_CreateArray();
3224 
3225  cJSON_AddItemToObject(cdr, "app_log", j_app_log);
3226  cJSON_AddItemToObject(j_app_log, "applications", j_apps);
3227 
3228  for (ap = app_log; ap; ap = ap->next) {
3229  j_application = cJSON_CreateObject();
3230 
3231  cJSON_AddItemToObject(j_application, "app_name", cJSON_CreateString(ap->app));
3232  cJSON_AddItemToObject(j_application, "app_data", cJSON_CreateString(ap->arg));
3233 
3234  cJSON_AddItemToArray(j_apps, j_application);
3235  }
3236  }
3237 
3238 
3239  caller_profile = switch_channel_get_caller_profile(channel);
3240 
3241  j_callflow = cJSON_CreateArray();
3242  cJSON_AddItemToObject(cdr, "callflow", j_callflow);
3243 
3244  while (caller_profile) {
3245 
3246  j_profile = cJSON_CreateObject();
3247 
3248  if (!zstr(caller_profile->dialplan)) {
3249  cJSON_AddItemToObject(j_profile, "dialplan", cJSON_CreateString((char *)caller_profile->dialplan));
3250  }
3251 
3252  if (!zstr(caller_profile->profile_index)) {
3253  cJSON_AddItemToObject(j_profile, "profile_index", cJSON_CreateString((char *)caller_profile->profile_index));
3254  }
3255 
3256  if (caller_profile->caller_extension) {
3258 
3259  j_caller_extension = cJSON_CreateObject();
3260  j_caller_extension_apps = cJSON_CreateArray();
3261 
3262  cJSON_AddItemToObject(j_profile, "extension", j_caller_extension);
3263 
3264  cJSON_AddItemToObject(j_caller_extension, "name", cJSON_CreateString(caller_profile->caller_extension->extension_name));
3265  cJSON_AddItemToObject(j_caller_extension, "number", cJSON_CreateString(caller_profile->caller_extension->extension_number));
3266  cJSON_AddItemToObject(j_caller_extension, "applications", j_caller_extension_apps);
3267 
3268  if (caller_profile->caller_extension->current_application) {
3269  cJSON_AddItemToObject(j_caller_extension, "current_app", cJSON_CreateString(caller_profile->caller_extension->current_application->application_name));
3270  }
3271 
3272  for (ap = caller_profile->caller_extension->applications; ap; ap = ap->next) {
3273  j_application = cJSON_CreateObject();
3274 
3275  cJSON_AddItemToArray(j_caller_extension_apps, j_application);
3276 
3277  if (ap == caller_profile->caller_extension->current_application) {
3278  cJSON_AddItemToObject(j_application, "last_executed", cJSON_CreateString("true"));
3279  }
3280  cJSON_AddItemToObject(j_application, "app_name", cJSON_CreateString(ap->application_name));
3281  cJSON_AddItemToObject(j_application, "app_data", cJSON_CreateString(switch_str_nil(ap->application_data)));