Collaboration diagram for IVR Library:
Modules | |
| IVR Menu Library | |
Typedefs | |
| typedef switch_ivr_digit_stream_parser | switch_ivr_digit_stream_parser_t |
| typedef 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. | |
| switch_status_t | switch_ivr_generate_xml_cdr (switch_core_session_t *session, switch_xml_t *xml_cdr) |
| Generate an XML CDR report. | |
| 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. | |
| switch_status_t | switch_ivr_parse_all_events (switch_core_session_t *session) |
| Parse all commands from an event. | |
| 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_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. | |
| 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. | |
| 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. | |
| 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. | |
| switch_status_t | switch_ivr_detect_speech (switch_core_session_t *session, const char *mod_name, const char *grammar, const char *name, const char *dest, switch_asr_handle_t *ah) |
| Engage background Speech detection on a session. | |
| switch_status_t | switch_ivr_stop_detect_speech (switch_core_session_t *session) |
| Stop background Speech detection on a session. | |
| switch_status_t | switch_ivr_pause_detect_speech (switch_core_session_t *session) |
| Pause background Speech detection on a session. | |
| switch_status_t | switch_ivr_resume_detect_speech (switch_core_session_t *session) |
| Resume background Speech detection on a session. | |
| switch_status_t | switch_ivr_detect_speech_load_grammar (switch_core_session_t *session, char *grammar, char *name) |
| Load a grammar on a background speech detection handle. | |
| 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. | |
| 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. | |
| 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. | |
| switch_status_t | switch_ivr_detect_speech_disable_all_grammars (switch_core_session_t *session) |
| Disable all grammars on a background speech detection handle. | |
| 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. | |
| 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. | |
| 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. | |
| 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 | |
| switch_status_t | switch_ivr_stop_displace_session (switch_core_session_t *session, const char *file) |
| Stop displacing a session. | |
| switch_status_t | switch_ivr_stop_record_session (switch_core_session_t *session, const char *file) |
| Stop Recording a session. | |
| 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. | |
| switch_status_t | switch_ivr_stop_inband_dtmf_session (switch_core_session_t *session) |
| Stop looking for DTMF inband. | |
| switch_status_t | switch_ivr_inband_dtmf_generate_session (switch_core_session_t *session, switch_bool_t read_stream) |
| Start generating DTMF inband. | |
| switch_status_t | switch_ivr_stop_inband_dtmf_generate_session (switch_core_session_t *session) |
| Stop generating DTMF inband. | |
| void | switch_ivr_session_echo (switch_core_session_t *session, switch_input_args_t *args) |
| |
| switch_status_t | switch_ivr_stop_tone_detect_session (switch_core_session_t *session) |
| Stop looking for TONES. | |
| 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. | |
| 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 | |
| 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 | |
| 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. | |
| 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. | |
| 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. | |
| 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. | |
| 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. | |
| 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. | |
| 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. | |
| 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. | |
| switch_status_t | switch_ivr_uuid_bridge (const char *originator_uuid, const char *originatee_uuid) |
| Bridge two existing sessions. | |
| 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. | |
| 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. | |
| 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. | |
| switch_status_t | switch_ivr_unhold_uuid (const char *uuid) |
| Signal the session with a protocol specific unhold message. | |
| 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. | |
| switch_status_t | switch_ivr_unhold (switch_core_session_t *session) |
| Signal the session with a protocol specific unhold message. | |
| 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. | |
| switch_status_t | switch_ivr_broadcast (const char *uuid, const char *path, switch_media_flag_t flags) |
| Signal the session to broadcast audio. | |
| 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. | |
| 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. | |
| switch_status_t | switch_ivr_digit_stream_parser_destroy (switch_ivr_digit_stream_parser_t *parser) |
| Destroy a digit stream parser object. | |
| 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. | |
| switch_status_t | switch_ivr_digit_stream_destroy (switch_ivr_digit_stream_t **stream) |
| Destroys a digit stream object. | |
| 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. | |
| 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. | |
| 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. | |
| switch_status_t | switch_ivr_digit_stream_reset (switch_ivr_digit_stream_t *stream) |
| Reset the collected digit stream to nothing. | |
| switch_status_t | switch_ivr_digit_stream_parser_set_terminator (switch_ivr_digit_stream_parser_t *parser, char digit) |
| Set a digit string terminator. | |
| typedef struct switch_ivr_digit_stream_parser switch_ivr_digit_stream_parser_t |
Definition at line 650 of file switch_ivr.h.
| typedef struct switch_ivr_digit_stream switch_ivr_digit_stream_t |
Definition at line 652 of file switch_ivr.h.
| 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 381 of file switch_ivr.c.
References switch_codec_implementation::actual_samples_per_second, CF_UNICAST, fail, switch_codec::implementation, switch_codec_implementation::microseconds_per_packet, 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, and SWITCH_UNSPEC.
Referenced by switch_ivr_parse_event().
00385 { 00386 switch_channel_t *channel = switch_core_session_get_channel(session); 00387 switch_unicast_conninfo_t *conninfo = switch_core_session_alloc(session, sizeof(*conninfo)); 00388 switch_codec_t *read_codec; 00389 00390 switch_assert(conninfo != NULL); 00391 00392 conninfo->local_ip = switch_core_session_strdup(session, local_ip); 00393 conninfo->local_port = local_port; 00394 00395 conninfo->remote_ip = switch_core_session_strdup(session, remote_ip); 00396 conninfo->remote_port = remote_port; 00397 conninfo->session = session; 00398 00399 if (!strcasecmp(transport, "udp")) { 00400 conninfo->type = AF_INET; 00401 conninfo->transport = SOCK_DGRAM; 00402 } else if (!strcasecmp(transport, "tcp")) { 00403 conninfo->type = AF_INET; 00404 conninfo->transport = SOCK_STREAM; 00405 } else { 00406 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid transport %s\n", transport); 00407 goto fail; 00408 } 00409 00410 if (flags) { 00411 if (strstr(flags, "native")) { 00412 switch_set_flag(conninfo, SUF_NATIVE); 00413 } 00414 } 00415 00416 switch_mutex_init(&conninfo->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); 00417 00418 read_codec = switch_core_session_get_read_codec(session); 00419 00420 if (!switch_test_flag(conninfo, SUF_NATIVE)) { 00421 if (switch_core_codec_init(&conninfo->read_codec, 00422 "L16", 00423 NULL, 00424 read_codec->implementation->actual_samples_per_second, 00425 read_codec->implementation->microseconds_per_packet / 1000, 00426 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, 00427 NULL, switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) { 00428 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, 00429 "Raw Codec Activation Success L16@%uhz 1 channel %dms\n", 00430 read_codec->implementation->actual_samples_per_second, read_codec->implementation->microseconds_per_packet / 1000); 00431 } else { 00432 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Raw Codec Activation Failed L16@%uhz 1 channel %dms\n", 00433 read_codec->implementation->actual_samples_per_second, read_codec->implementation->microseconds_per_packet / 1000); 00434 goto fail; 00435 } 00436 } 00437 00438 conninfo->write_frame.data = conninfo->write_frame_data; 00439 conninfo->write_frame.buflen = sizeof(conninfo->write_frame_data); 00440 conninfo->write_frame.codec = switch_test_flag(conninfo, SUF_NATIVE) ? read_codec : &conninfo->read_codec; 00441 00442 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "connect %s:%d->%s:%d\n", 00443 conninfo->local_ip, conninfo->local_port, conninfo->remote_ip, conninfo->remote_port); 00444 00445 if (switch_sockaddr_info_get(&conninfo->local_addr, 00446 conninfo->local_ip, SWITCH_UNSPEC, conninfo->local_port, 0, 00447 switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { 00448 goto fail; 00449 } 00450 00451 if (switch_sockaddr_info_get(&conninfo->remote_addr, 00452 conninfo->remote_ip, SWITCH_UNSPEC, conninfo->remote_port, 0, 00453 switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { 00454 goto fail; 00455 } 00456 00457 if (switch_socket_create(&conninfo->socket, AF_INET, SOCK_DGRAM, 0, switch_core_session_get_pool(session)) == SWITCH_STATUS_SUCCESS) { 00458 if (switch_socket_bind(conninfo->socket, conninfo->local_addr) != SWITCH_STATUS_SUCCESS) { 00459 goto fail; 00460 } 00461 } else { 00462 goto fail; 00463 } 00464 00465 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Created unicast connection %s:%d->%s:%d\n", 00466 conninfo->local_ip, conninfo->local_port, conninfo->remote_ip, conninfo->remote_port); 00467 switch_channel_set_private(channel, "unicast", conninfo); 00468 switch_channel_set_flag(channel, CF_UNICAST); 00469 switch_set_flag_locked(conninfo, SUF_READY); 00470 return SWITCH_STATUS_SUCCESS; 00471 00472 fail: 00473 00474 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_CRIT, "Failure creating unicast connection %s:%d->%s:%d\n", 00475 conninfo->local_ip, conninfo->local_port, conninfo->remote_ip, conninfo->remote_port); 00476 return SWITCH_STATUS_FALSE; 00477 }
| void switch_ivr_bridge_display | ( | switch_core_session_t * | session, | |
| switch_core_session_t * | peer_session | |||
| ) |
Definition at line 143 of file switch_ivr_bridge.c.
References send_display().
Referenced by audio_bridge_thread(), switch_ivr_signal_bridge(), and switch_ivr_uuid_bridge().
00144 { 00145 00146 send_display(session, peer_session); 00147 send_display(peer_session, session); 00148 00149 }
| switch_status_t switch_ivr_broadcast | ( | const char * | uuid, | |
| const char * | path, | |||
| switch_media_flag_t | flags | |||
| ) |
Signal the session to broadcast audio.
| uuid | the uuid of the session to broadcast on | |
| path | the path data of the broadcast "/path/to/file.wav [<timer name>]" or "speak:<engine>|<voice>|<Text to say>" | |
| flags | flags to send to the request (SMF_ECHO_BRIDGED to send the broadcast to both sides of the call) |
Definition at line 4028 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_variable, 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_SIGNAL_BOND_VARIABLE, SWITCH_STACK_BOTTOM, SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.
Referenced by bcast_thread(), meta_on_dtmf(), switch_ivr_hold(), switch_ivr_parse_event(), switch_ivr_soft_hold(), and SWITCH_STANDARD_SCHED_FUNC().
04029 { 04030 switch_channel_t *channel; 04031 switch_core_session_t *session, *master; 04032 switch_event_t *event; 04033 switch_core_session_t *other_session = NULL; 04034 const char *other_uuid = NULL; 04035 char *app = "playback"; 04036 char *cause = NULL; 04037 char *mypath; 04038 char *p; 04039 int app_flags = 0, nomedia = 0; 04040 04041 switch_assert(path); 04042 04043 if (!(master = session = switch_core_session_locate(uuid))) { 04044 return SWITCH_STATUS_FALSE; 04045 } 04046 04047 channel = switch_core_session_get_channel(session); 04048 04049 mypath = strdup(path); 04050 assert(mypath); 04051 04052 if ((p = strchr(mypath, ':')) && *(p + 1) == ':') { 04053 app = mypath; 04054 *p++ = '\0'; 04055 *p++ = '\0'; 04056 path = p; 04057 } 04058 04059 if (switch_channel_test_flag(channel, CF_PROXY_MODE)) { 04060 nomedia = 1; 04061 switch_ivr_media(uuid, SMF_REBRIDGE); 04062 } 04063 04064 if ((cause = strchr(app, '!'))) { 04065 *cause++ = '\0'; 04066 if (!cause) { 04067 cause = "normal_clearing"; 04068 } 04069 } 04070 04071 if ((flags & SMF_ECHO_BLEG) && (other_uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE)) 04072 && (other_session = switch_core_session_locate(other_uuid))) { 04073 if ((flags & SMF_EXEC_INLINE)) { 04074 switch_core_session_execute_application_get_flags(other_session, app, path, &app_flags); 04075 nomedia = 0; 04076 } else { 04077 switch_core_session_get_app_flags(app, &app_flags); 04078 if (switch_event_create(&event, SWITCH_EVENT_COMMAND) == SWITCH_STATUS_SUCCESS) { 04079 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-command", "execute"); 04080 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "execute-app-name", app); 04081 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "execute-app-arg", path); 04082 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, (flags & SMF_PRIORITY) ? "event-lock-pri" : "event-lock", "true"); 04083 04084 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "lead-frames", "%d", 5); 04085 04086 if ((flags & SMF_LOOP)) { 04087 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "loops", "%d", -1); 04088 } 04089 04090 if ((flags & SMF_HOLD_BLEG)) { 04091 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "hold-bleg", "true"); 04092 } 04093 04094 switch_core_session_queue_private_event(other_session, &event, (flags & SMF_PRIORITY)); 04095 } 04096 } 04097 04098 switch_core_session_rwunlock(other_session); 04099 master = other_session; 04100 other_session = NULL; 04101 } 04102 04103 if ((app_flags & SAF_MEDIA_TAP)) { 04104 nomedia = 0; 04105 } 04106 04107 if ((flags & SMF_ECHO_ALEG)) { 04108 if ((flags & SMF_EXEC_INLINE)) { 04109 nomedia = 0; 04110 switch_core_session_execute_application(session, app, path); 04111 } else { 04112 if (switch_event_create(&event, SWITCH_EVENT_COMMAND) == SWITCH_STATUS_SUCCESS) { 04113 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-command", "execute"); 04114 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "execute-app-name", app); 04115 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "execute-app-arg", path); 04116 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, (flags & SMF_PRIORITY) ? "event-lock-pri" : "event-lock", "true"); 04117 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "lead-frames", "%d", 5); 04118 04119 if ((flags & SMF_LOOP)) { 04120 switch_event_add_header(event, SWITCH_STACK_BOTTOM, "loops", "%d", -1); 04121 } 04122 if ((flags & SMF_HOLD_BLEG)) { 04123 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "hold-bleg", "true"); 04124 } 04125 04126 switch_core_session_queue_private_event(session, &event, (flags & SMF_PRIORITY)); 04127 04128 if (nomedia) 04129 switch_channel_set_flag(channel, CF_BROADCAST_DROP_MEDIA); 04130 } 04131 } 04132 master = session; 04133 } 04134 04135 if (cause) { 04136 if (switch_event_create(&event, SWITCH_EVENT_COMMAND) == SWITCH_STATUS_SUCCESS) { 04137 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "call-command", "execute"); 04138 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "execute-app-name", "hangup"); 04139 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "execute-app-arg", cause); 04140 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, (flags & SMF_PRIORITY) ? "event-lock-pri" : "event-lock", "true"); 04141 switch_core_session_queue_private_event(session, &event, (flags & SMF_PRIORITY)); 04142 } 04143 } 04144 04145 switch_core_session_rwunlock(session); 04146 switch_safe_free(mypath); 04147 04148 return SWITCH_STATUS_SUCCESS; 04149 }
| void switch_ivr_broadcast_in_thread | ( | switch_core_session_t * | session, | |
| const char * | app, | |||
| int | flags | |||
| ) |
Definition at line 3081 of file switch_ivr_async.c.
References bcast_thread(), pool, switch_assert, switch_core_session_alloc, switch_core_session_get_pool(), switch_thread_create(), SWITCH_THREAD_STACKSIZE, switch_threadattr_create(), switch_threadattr_detach_set(), and switch_threadattr_stacksize_set().
Referenced by meta_on_dtmf().
03082 { 03083 switch_thread_t *thread; 03084 switch_threadattr_t *thd_attr = NULL; 03085 switch_memory_pool_t *pool; 03086 bch_t *bch; 03087 03088 switch_assert(session); 03089 03090 pool = switch_core_session_get_pool(session); 03091 03092 bch = switch_core_session_alloc(session, sizeof(*bch)); 03093 bch->session = session; 03094 bch->app = app; 03095 bch->flags = flags; 03096 03097 03098 switch_threadattr_create(&thd_attr, pool); 03099 switch_threadattr_detach_set(thd_attr, 1); 03100 switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); 03101 switch_thread_create(&thread, thd_attr, bcast_thread, bch, pool); 03102 }
| void switch_ivr_clear_speech_cache | ( | switch_core_session_t * | session | ) |
Definition at line 2377 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().
02378 { 02379 cached_speech_handle_t *cache_obj = NULL; 02380 switch_channel_t *channel = switch_core_session_get_channel(session); 02381 02382 if ((cache_obj = switch_channel_get_private(channel, SWITCH_CACHE_SPEECH_HANDLES_OBJ_NAME))) { 02383 switch_speech_flag_t flags = SWITCH_SPEECH_FLAG_NONE; 02384 if (cache_obj->timer.interval) { 02385 switch_core_timer_destroy(&cache_obj->timer); 02386 } 02387 if (&cache_obj->sh && cache_obj->sh.speech_interface) { 02388 switch_core_speech_close(&cache_obj->sh, &flags); 02389 } 02390 if (&cache_obj->codec) { 02391 switch_core_codec_destroy(&cache_obj->codec); 02392 } 02393 switch_channel_set_private(channel, SWITCH_CACHE_SPEECH_HANDLES_OBJ_NAME, NULL); 02394 } 02395 }
| 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.
| session | the session to read. | |
| args | arguements to pass for callbacks etc | |
| timeout | a timeout in milliseconds |
Definition at line 1106 of file switch_ivr.c.
References 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, and SWITCH_STATUS_TIMEOUT.
Referenced by CoreSession::collectDigits(), enterprise_originate_ringback_thread(), fs_switch_ivr_collect_digits_callback(), and switch_ivr_soft_hold().
01108 { 01109 switch_channel_t *channel = switch_core_session_get_channel(session); 01110 switch_status_t status = SWITCH_STATUS_SUCCESS; 01111 switch_time_t abs_started = 0, digit_started = 0; 01112 uint32_t abs_elapsed = 0, digit_elapsed = 0; 01113 01114 if (!args) { 01115 return SWITCH_STATUS_GENERR; 01116 } 01117 01118 if (abs_timeout) { 01119 abs_started = switch_micro_time_now(); 01120 } 01121 if (digit_timeout) { 01122 digit_started = switch_micro_time_now(); 01123 } 01124 while (switch_channel_ready(channel)) { 01125 switch_frame_t *read_frame = NULL; 01126 switch_event_t *event; 01127 switch_dtmf_t dtmf = { 0 }; 01128 01129 if (switch_channel_test_flag(channel, CF_BREAK)) { 01130 switch_channel_clear_flag(channel, CF_BREAK); 01131 status = SWITCH_STATUS_BREAK; 01132 break; 01133 } 01134 01135 if (abs_timeout) { 01136 abs_elapsed = (uint32_t) ((switch_micro_time_now() - abs_started) / 1000); 01137 if (abs_elapsed >= abs_timeout) { 01138 status = SWITCH_STATUS_TIMEOUT; 01139 break; 01140 } 01141 } 01142 if (digit_timeout) { 01143 digit_elapsed = (uint32_t) ((switch_micro_time_now() - digit_started) / 1000); 01144 if (digit_elapsed >= digit_timeout) { 01145 status = SWITCH_STATUS_TIMEOUT; 01146 break; 01147 } 01148 } 01149 01150 01151 switch_ivr_parse_all_events(session); 01152 01153 01154 if (switch_channel_has_dtmf(channel)) { 01155 if (!args->input_callback && !args->buf && !args->dmachine) { 01156 status = SWITCH_STATUS_BREAK; 01157 break; 01158 } 01159 switch_channel_dequeue_dtmf(channel, &dtmf); 01160 01161 if (args->dmachine) { 01162 char ds[2] = {dtmf.digit, '\0'}; 01163 if ((status = switch_ivr_dmachine_feed(args->dmachine, ds, NULL)) != SWITCH_STATUS_SUCCESS) { 01164 break; 01165 } 01166 } 01167 01168 if (args->input_callback) { 01169 status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen); 01170 } 01171 01172 if (digit_timeout) { 01173 digit_started = switch_micro_time_now(); 01174 } 01175 } 01176 01177 if (switch_core_session_dequeue_event(session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) { 01178 status = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen); 01179 switch_event_destroy(&event); 01180 } 01181 01182 if (status != SWITCH_STATUS_SUCCESS) { 01183 break; 01184 } 01185 01186 if (switch_channel_test_flag(channel, CF_SERVICE)) { 01187 switch_cond_next(); 01188 } else { 01189 status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); 01190 } 01191 01192 if (!SWITCH_READ_ACCEPTABLE(status)) { 01193 break; 01194 } 01195 01196 if (args && args->dmachine) { 01197 if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL)) != SWITCH_STATUS_SUCCESS) { 01198 break; 01199 } 01200 } 01201 01202 if (read_frame && args && (args->read_frame_callback)) { 01203 if ((status = args->read_frame_callback(session, read_frame, args->user_data)) != SWITCH_STATUS_SUCCESS) { 01204 break; 01205 } 01206 } 01207 } 01208 01209 return status; 01210 }
| 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.
| session | the session to read. | |
| buf | strig to write to | |
| buflen | max size of buf | |
| maxdigits | max number of digits to read | |
| terminators | digits to end the collection | |
| terminator | actual digit that caused the collection to end (if any) | |
| first_timeout | timeout in ms | |
| digit_timeout | digit timeout in ms | |
| abs_timeout | abs timeout in ms |
Definition at line 1212 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_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_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().
01218 { 01219 switch_size_t i = 0, x = strlen(buf); 01220 switch_channel_t *channel = switch_core_session_get_channel(session); 01221 switch_status_t status = SWITCH_STATUS_FALSE; 01222 switch_time_t started = 0, digit_started = 0; 01223 uint32_t abs_elapsed = 0, digit_elapsed = 0; 01224 uint32_t eff_timeout = 0; 01225 switch_frame_t write_frame = { 0 }; 01226 unsigned char *abuf = NULL; 01227 switch_codec_implementation_t imp = { 0 }; 01228 switch_codec_t codec = { 0 }; 01229 int sval = 0; 01230 const char *var; 01231 01232 if ((var = switch_channel_get_variable(channel, SWITCH_SEND_SILENCE_WHEN_IDLE_VARIABLE)) && (sval = atoi(var))) { 01233 switch_core_session_get_read_impl(session, &imp); 01234 01235 if (switch_core_codec_init(&codec, 01236 "L16", 01237 NULL, 01238 imp.samples_per_second, 01239 imp.microseconds_per_packet / 1000, 01240 imp.number_of_channels, 01241 SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, 01242 switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { 01243 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec Error L16@%uhz %u channels %dms\n", 01244 imp.samples_per_second, imp.number_of_channels, imp.microseconds_per_packet / 1000); 01245 return SWITCH_STATUS_FALSE; 01246 } 01247 01248 01249 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Codec Activated L16@%uhz %u channels %dms\n", 01250 imp.samples_per_second, imp.number_of_channels, imp.microseconds_per_packet / 1000); 01251 01252 write_frame.codec = &codec; 01253 switch_zmalloc(abuf, SWITCH_RECOMMENDED_BUFFER_SIZE); 01254 write_frame.data = abuf; 01255 write_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE; 01256 write_frame.datalen = imp.decoded_bytes_per_packet; 01257 write_frame.samples = write_frame.datalen / sizeof(int16_t); 01258 } 01259 01260 if (terminator != NULL) { 01261 *terminator = '\0'; 01262 } 01263 01264 if (!zstr(terminators)) { 01265 for (i = 0; i < x; i++) { 01266 if (strchr(terminators, buf[i]) && terminator != NULL) { 01267 *terminator = buf[i]; 01268 buf[i] = '\0'; 01269 return SWITCH_STATUS_SUCCESS; 01270 } 01271 } 01272 } 01273 01274 if (abs_timeout) { 01275 started = switch_micro_time_now(); 01276 } 01277 01278 if (digit_timeout && first_timeout) { 01279 eff_timeout = first_timeout; 01280 } else if (digit_timeout && !first_timeout) { 01281 first_timeout = eff_timeout = digit_timeout; 01282 } else if (first_timeout) { 01283 digit_timeout = eff_timeout = first_timeout; 01284 } 01285 01286 01287 if (eff_timeout) { 01288 digit_started = switch_micro_time_now(); 01289 } 01290 01291 while (switch_channel_ready(channel)) { 01292 switch_frame_t *read_frame; 01293 01294 if (abs_timeout) { 01295 abs_elapsed = (uint32_t) ((switch_micro_time_now() - started) / 1000); 01296 if (abs_elapsed >= abs_timeout) { 01297 status = SWITCH_STATUS_TIMEOUT; 01298 break; 01299 } 01300 } 01301 01302 01303 switch_ivr_parse_all_events(session); 01304 01305 01306 01307 if (eff_timeout) { 01308 digit_elapsed = (uint32_t) ((switch_micro_time_now() - digit_started) / 1000); 01309 01310 if (digit_elapsed >= eff_timeout) { 01311 status = SWITCH_STATUS_TIMEOUT; 01312 break; 01313 } 01314 } 01315 01316 if (switch_channel_has_dtmf(channel)) { 01317 switch_dtmf_t dtmf = { 0 }; 01318 switch_size_t y; 01319 01320 if (eff_timeout) { 01321 eff_timeout = digit_timeout; 01322 digit_started = switch_micro_time_now(); 01323 } 01324 01325 for (y = 0; y <= maxdigits; y++) { 01326 if (switch_channel_dequeue_dtmf(channel, &dtmf) != SWITCH_STATUS_SUCCESS) { 01327 break; 01328 } 01329 01330 if (!zstr(terminators) && strchr(terminators, dtmf.digit) && terminator != NULL) { 01331 *terminator = dtmf.digit; 01332 return SWITCH_STATUS_SUCCESS; 01333 } 01334 01335 01336 buf[x++] = dtmf.digit; 01337 buf[x] = '\0'; 01338 01339 if (x >= buflen || x >= maxdigits) { 01340 return SWITCH_STATUS_SUCCESS; 01341 } 01342 } 01343 } 01344 01345 if (switch_channel_test_flag(channel, CF_SERVICE)) { 01346 switch_cond_next(); 01347 } else { 01348 status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); 01349 if (!SWITCH_READ_ACCEPTABLE(status)) { 01350 break; 01351 } 01352 01353 if (write_frame.data) { 01354 switch_generate_sln_silence((int16_t *) write_frame.data, write_frame.samples, sval); 01355 switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0); 01356 } 01357 01358 } 01359 } 01360 01361 if (write_frame.codec) { 01362 switch_core_codec_destroy(&codec); 01363 } 01364 01365 switch_safe_free(abuf); 01366 01367 return status; 01368 }
| switch_status_t switch_ivr_deactivate_unicast | ( | switch_core_session_t * | session | ) |
Definition at line 352 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, and switch_yield.
Referenced by switch_core_session_perform_destroy(), switch_core_session_reset(), and switch_ivr_park().
00353 { 00354 switch_channel_t *channel = switch_core_session_get_channel(session); 00355 switch_unicast_conninfo_t *conninfo; 00356 int sanity = 0; 00357 00358 if (!switch_channel_test_flag(channel, CF_UNICAST)) { 00359 return SWITCH_STATUS_FALSE; 00360 } 00361 00362 if ((conninfo = switch_channel_get_private(channel, "unicast"))) { 00363 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Shutting down unicast connection\n"); 00364 switch_clear_flag_locked(conninfo, SUF_READY); 00365 switch_socket_shutdown(conninfo->socket, SWITCH_SHUTDOWN_READWRITE); 00366 while (switch_test_flag(conninfo, SUF_THREAD_RUNNING)) { 00367 switch_yield(10000); 00368 if (++sanity >= 10000) { 00369 break; 00370 } 00371 } 00372 if (switch_core_codec_ready(&conninfo->read_codec)) { 00373 switch_core_codec_destroy(&conninfo->read_codec); 00374 } 00375 switch_socket_close(conninfo->socket); 00376 } 00377 switch_channel_clear_flag(channel, CF_UNICAST); 00378 return SWITCH_STATUS_SUCCESS; 00379 }
| 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.
| session | the session to attach | |
| mod_name | the module name of the ASR library | |
| grammar | the grammar text, URI, or local file name | |
| name | the grammar name | |
| dest | the destination address | |
| ah | an ASR handle to use (NULL to create one) |
Definition at line 3801 of file switch_ivr_async.c.
References switch_codec_implementation::actual_samples_per_second, speech_thread_handle::ah, 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_SESSION_LOG, switch_channel_set_private(), switch_core_asr_close(), switch_core_asr_load_grammar(), 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_LOG_DEBUG, switch_log_printf(), switch_set_flag, switch_snprintf(), SWITCH_SPEECH_KEY, SWITCH_STATUS_FALSE, SWITCH_STATUS_MEMERR, SWITCH_STATUS_SUCCESS, and switch_true().
Referenced by switch_ivr_play_and_detect_speech().
03804 { 03805 switch_channel_t *channel = switch_core_session_get_channel(session); 03806 switch_status_t status; 03807 switch_asr_flag_t flags = SWITCH_ASR_FLAG_NONE; 03808 struct speech_thread_handle *sth = switch_channel_get_private(channel, SWITCH_SPEECH_KEY); 03809 switch_codec_implementation_t read_impl = { 0 }; 03810 const char *p; 03811 char key[512] = ""; 03812 03813 switch_core_session_get_read_impl(session, &read_impl); 03814 03815 switch_snprintf(key, sizeof(key), "%s/%s/%s/%s", mod_name, grammar, name, dest); 03816 03817 if (!ah) { 03818 if (!(ah = switch_core_session_alloc(session, sizeof(*ah)))) { 03819 return SWITCH_STATUS_MEMERR; 03820 } 03821 } 03822 03823 if (sth) { 03824 if (switch_core_asr_load_grammar(sth->ah, grammar, name) != SWITCH_STATUS_SUCCESS) { 03825 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Error loading Grammar\n"); 03826 switch_ivr_stop_detect_speech(session); 03827 return SWITCH_STATUS_FALSE; 03828 } 03829 03830 if ((p = switch_channel_get_variable(channel, "fire_asr_events")) && switch_true(p)) { 03831 switch_set_flag(sth->ah, SWITCH_ASR_FLAG_FIRE_EVENTS); 03832 } 03833 03834 return SWITCH_STATUS_SUCCESS; 03835 } 03836 03837 if ((status = switch_core_asr_open(ah, 03838 mod_name, 03839 "L16", 03840 read_impl.actual_samples_per_second, dest, &flags, 03841 switch_core_session_get_pool(session))) == SWITCH_STATUS_SUCCESS) { 03842 03843 if (switch_core_asr_load_grammar(ah, grammar, name) != SWITCH_STATUS_SUCCESS) { 03844 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Error loading Grammar\n"); 03845 switch_core_asr_close(ah, &flags); 03846 return SWITCH_STATUS_FALSE; 03847 } 03848 } else { 03849 return status; 03850 } 03851 03852 sth = switch_core_session_alloc(session, sizeof(*sth)); 03853 sth->pool = switch_core_session_get_pool(session); 03854 sth->session = session; 03855 sth->ah = ah; 03856 03857 if ((p = switch_channel_get_variable(channel, "fire_asr_events")) && switch_true(p)) { 03858 switch_set_flag(ah, SWITCH_ASR_FLAG_FIRE_EVENTS); 03859 } 03860 03861 if ((status = switch_core_media_bug_add(session, "detect_speech", key, 03862 speech_callback, sth, 0, SMBF_READ_STREAM | SMBF_NO_PAUSE, &sth->bug)) != SWITCH_STATUS_SUCCESS) { 03863 switch_core_asr_close(ah, &flags); 03864 return status; 03865 } 03866 03867 if ((status = switch_core_event_hook_add_recv_dtmf(session, speech_on_dtmf)) != SWITCH_STATUS_SUCCESS) { 03868 switch_ivr_stop_detect_speech(session); 03869 return status; 03870 } 03871 03872 switch_channel_set_private(channel, SWITCH_SPEECH_KEY, sth); 03873 03874 return SWITCH_STATUS_SUCCESS; 03875 }
| switch_status_t switch_ivr_detect_speech_disable_all_grammars | ( | switch_core_session_t * | session | ) |
Disable all grammars on a background speech detection handle.
| session | The session to change the grammar on |
Definition at line 3785 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.
03786 { 03787 switch_channel_t *channel = switch_core_session_get_channel(session); 03788 struct speech_thread_handle *sth = switch_channel_get_private(channel, SWITCH_SPEECH_KEY); 03789 switch_status_t status; 03790 03791 if (sth) { 03792 if ((status = switch_core_asr_disable_all_grammars(sth->ah)) != SWITCH_STATUS_SUCCESS) { 03793 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Error disabling all Grammars\n"); 03794 switch_ivr_stop_detect_speech(session); 03795 } 03796 return status; 03797 } 03798 return SWITCH_STATUS_FALSE; 03799 }
| 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.
| session | The session to change the grammar on | |
| name | the grammar name |
Definition at line 3769 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.
03770 { 03771 switch_channel_t *channel = switch_core_session_get_channel(session); 03772 struct speech_thread_handle *sth = switch_channel_get_private(channel, SWITCH_SPEECH_KEY); 03773 switch_status_t status; 03774 03775 if (sth) { 03776 if ((status = switch_core_asr_disable_grammar(sth->ah, name)) != SWITCH_STATUS_SUCCESS) { 03777 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Error disabling Grammar\n"); 03778 switch_ivr_stop_detect_speech(session); 03779 } 03780 return status; 03781 } 03782 return SWITCH_STATUS_FALSE; 03783 }
| 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.
| session | The session to change the grammar on | |
| name | the grammar name |
Definition at line 3753 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.
03754 { 03755 switch_channel_t *channel = switch_core_session_get_channel(session); 03756 struct speech_thread_handle *sth = switch_channel_get_private(channel, SWITCH_SPEECH_KEY); 03757 switch_status_t status; 03758 03759 if (sth) { 03760 if ((status = switch_core_asr_enable_grammar(sth->ah, name)) != SWITCH_STATUS_SUCCESS) { 03761 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Error enabling Grammar\n"); 03762 switch_ivr_stop_detect_speech(session); 03763 } 03764 return status; 03765 } 03766 return SWITCH_STATUS_FALSE; 03767 }
| switch_status_t switch_ivr_detect_speech_load_grammar | ( | switch_core_session_t * | session, | |
| char * | grammar, | |||
| char * | name | |||
| ) |
Load a grammar on a background speech detection handle.
| session | The session to change the grammar on | |
| grammar | the grammar text, URI, or local file name | |
| name | the grammar name |
Definition at line 3696 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.
03697 { 03698 switch_channel_t *channel = switch_core_session_get_channel(session); 03699 struct speech_thread_handle *sth = switch_channel_get_private(channel, SWITCH_SPEECH_KEY); 03700 switch_status_t status; 03701 03702 if (sth) { 03703 if ((status = switch_core_asr_load_grammar(sth->ah, grammar, name)) != SWITCH_STATUS_SUCCESS) { 03704 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Error loading Grammar\n"); 03705 switch_ivr_stop_detect_speech(session); 03706 } 03707 return status; 03708 } 03709 return SWITCH_STATUS_FALSE; 03710 }
| switch_status_t switch_ivr_detect_speech_start_input_timers | ( | switch_core_session_t * | session | ) |
Start input timers on a background speech detection handle.
| session | The session to start the timers on |
Definition at line 3725 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().
03726 { 03727 switch_channel_t *channel = switch_core_session_get_channel(session); 03728 struct speech_thread_handle *sth = switch_channel_get_private(channel, SWITCH_SPEECH_KEY); 03729 03730 if (sth) { 03731 switch_core_asr_start_input_timers(sth->ah); 03732 return SWITCH_STATUS_SUCCESS; 03733 } 03734 return SWITCH_STATUS_FALSE; 03735 }
| 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.
| session | The session to change the grammar on | |
| name | the grammar name |
Definition at line 3737 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.
03738 { 03739 switch_channel_t *channel = switch_core_session_get_channel(session); 03740 struct speech_thread_handle *sth = switch_channel_get_private(channel, SWITCH_SPEECH_KEY); 03741 switch_status_t status; 03742 03743 if (sth) { 03744 if ((status = switch_core_asr_unload_grammar(sth->ah, name)) != SWITCH_STATUS_SUCCESS) { 03745 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Error unloading Grammar\n"); 03746 switch_ivr_stop_detect_speech(session); 03747 } 03748 return status; 03749 } 03750 return SWITCH_STATUS_FALSE; 03751 }
| switch_status_t switch_ivr_digit_stream_destroy | ( | switch_ivr_digit_stream_t ** | stream | ) |
Destroys a digit stream object.
| stream | a pointer to the stream object |
Definition at line 1873 of file switch_ivr.c.
References switch_safe_free, SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.
01874 { 01875 switch_status_t status = SWITCH_STATUS_FALSE; 01876 01877 if (*stream) { 01878 switch_safe_free((*stream)->digits); 01879 free(*stream); 01880 *stream = NULL; 01881 status = SWITCH_STATUS_SUCCESS; 01882 } 01883 01884 return status; 01885 }
| 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.
| parser | a pointer to the parser object created by switch_ivr_digit_stream_parser_new | |
| stream | a pointer to the stream object pointer |
Definition at line 1857 of file switch_ivr.c.
References switch_assert, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, and switch_zmalloc.
01858 { 01859 switch_status_t status = SWITCH_STATUS_FALSE; 01860 01861 /* if we have a parser object memory pool and a stream object pointer that is null */ 01862 if (parser && stream && *stream == NULL) { 01863 *stream = (switch_ivr_digit_stream_t *) malloc(sizeof(**stream)); 01864 switch_assert(*stream); 01865 memset(*stream, 0, sizeof(**stream)); 01866 switch_zmalloc((*stream)->digits, parser->buflen + 1); 01867 status = SWITCH_STATUS_SUCCESS; 01868 } 01869 01870 return status; 01871 }
| 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.
| parser | a pointer to the parser object created by switch_ivr_digit_stream_parser_new | |
| digits | the digit string to be removed from the map |
Definition at line 1929 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.
01930 { 01931 switch_status_t status = SWITCH_STATUS_FALSE; 01932 01933 if (parser != NULL && digits != NULL && *digits) { 01934 status = switch_core_hash_delete(parser->hash, digits); 01935 } 01936 01937 if (status != SWITCH_STATUS_SUCCESS) { 01938 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "unable to del hash for '%s'\n", digits); 01939 } 01940 01941 return status; 01942 }
| switch_status_t switch_ivr_digit_stream_parser_destroy | ( | switch_ivr_digit_stream_parser_t * | parser | ) |
Destroy a digit stream parser object.
| parser | a pointer to the parser object |
Definition at line 1839 of file switch_ivr.c.
References switch_core_destroy_memory_pool, switch_core_hash_destroy(), and SWITCH_STATUS_FALSE.
01840 { 01841 switch_status_t status = SWITCH_STATUS_FALSE; 01842 01843 if (parser != NULL) { 01844 if (parser->hash != NULL) { 01845 switch_core_hash_destroy(&parser->hash); 01846 parser->hash = NULL; 01847 } 01848 /* free the memory pool if we created it */ 01849 if (parser->pool_auto_created && parser->pool != NULL) { 01850 status = switch_core_destroy_memory_pool(&parser->pool); 01851 } 01852 } 01853 01854 return status; 01855 }
| 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.
| parser | a pointer to the parser object created by switch_ivr_digit_stream_parser_new | |
| stream | a stream to write data to | |
| digit | a digit to collect and test against the map of digit strings |
Definition at line 1944 of file switch_ivr.c.
References switch_assert, switch_core_hash_find(), and switch_micro_time_now().
01945 { 01946 void *result = NULL; 01947 switch_size_t len; 01948 01949 switch_assert(parser); 01950 switch_assert(stream); 01951 switch_assert(stream->digits); 01952 01953 len = strlen(stream->digits); 01954 01955 /* handle new digit arrivals */ 01956 if (digit) { 01957 /* if it's not a terminator digit, add it to the collected digits */ 01958 if (digit != parser->terminator) { 01959 /* if collected digits length >= the max length of the keys 01960 * in the hash table, then left shift the digit string 01961 */ 01962 if (len > 0 && parser->maxlen != 0 && len >= parser->maxlen) { 01963 char *src = stream->digits + 1; 01964 char *dst = stream->digits; 01965 01966 while (*src) { 01967 *(dst++) = *(src++); 01968 } 01969 *dst = digit; 01970 } else { 01971 *(stream->digits + (len++)) = digit; 01972 *(stream->digits + len) = '\0'; 01973 stream->last_digit_time = switch_micro_time_now() / 1000; 01974 } 01975 } 01976 } 01977 01978 /* don't allow collected digit string testing if there are varying sized keys until timeout */ 01979 if (parser->maxlen - parser->minlen > 0 && (switch_micro_time_now() / 1000) - stream->last_digit_time < parser->digit_timeout_ms) { 01980 len = 0; 01981 } 01982 /* if we have digits to test */ 01983 if (len) { 01984 result = switch_core_hash_find(parser->hash, stream->digits); 01985 /* if we matched the digit string, or this digit is the terminator 01986 * reset the collected digits for next digit string 01987 */ 01988 if (result != NULL || parser->terminator == digit) { 01989 *stream->digits = '\0'; 01990 } 01991 } 01992 01993 01994 return result; 01995 }
| 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.
| pool | the pool to use for the new hash | |
| parser | a pointer to the object pointer |
Definition at line 1799 of file switch_ivr.c.
References 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.
01800 { 01801 switch_status_t status = SWITCH_STATUS_FALSE; 01802 01803 if (parser != NULL) { 01804 int pool_auto_created = 0; 01805 01806 /* if the caller didn't provide a pool, make one */ 01807 if (pool == NULL) { 01808 switch_core_new_memory_pool(&pool); 01809 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "created a memory pool\n"); 01810 if (pool != NULL) { 01811 pool_auto_created = 1; 01812 } 01813 } 01814 /* if we have a pool, make a parser object */ 01815 if (pool != NULL) { 01816 *parser = (switch_ivr_digit_stream_parser_t *) switch_core_alloc(pool, sizeof(switch_ivr_digit_stream_parser_t)); 01817 } 01818 /* if we have parser object, initialize it for the caller */ 01819 if (pool && *parser != NULL) { 01820 memset(*parser, 0, sizeof(switch_ivr_digit_stream_parser_t)); 01821 (*parser)->pool_auto_created = pool_auto_created; 01822 (*parser)->pool = pool; 01823 (*parser)->digit_timeout_ms = 1000; 01824 switch_core_hash_init(&(*parser)->hash, (*parser)->pool); 01825 01826 status = SWITCH_STATUS_SUCCESS; 01827 } else { 01828 status = SWITCH_STATUS_MEMERR; 01829 /* if we can't create a parser object,clean up the pool if we created it */ 01830 if (pool != NULL && pool_auto_created) { 01831 switch_core_destroy_memory_pool(&pool); 01832 } 01833 } 01834 } 01835 01836 return status; 01837 }
| 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.
| parser | a pointer to the parser object created by switch_ivr_digit_stream_parser_new | |
| digits | a string of digits to associate with an action | |
| data | consumer data attached to this digit string |
Definition at line 1887 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.
01888 { 01889 switch_status_t status = SWITCH_STATUS_FALSE; 01890 01891 if (parser != NULL && digits != NULL && *digits && parser->hash != NULL) { 01892 01893 status = switch_core_hash_insert(parser->hash, digits, data); 01894 if (status == SWITCH_STATUS_SUCCESS) { 01895 switch_size_t len = strlen(digits); 01896 01897 /* if we don't have a terminator, then we have to try and 01898 * figure out when a digit set is completed, therefore we 01899 * keep track of the min and max digit lengths 01900 */ 01901 01902 if (len > parser->buflen) { 01903 parser->buflen = len; 01904 } 01905 01906 if (parser->terminator == '\0') { 01907 if (len > parser->maxlen) { 01908 parser->maxlen = len; 01909 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "max len %u\n", (uint32_t) parser->maxlen); 01910 } 01911 if (parser->minlen == 0 || len < parser->minlen) { 01912 parser->minlen = len; 01913 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "min len %u\n", (uint32_t) parser->minlen); 01914 } 01915 } else { 01916 /* since we have a terminator, reset min and max */ 01917 parser->minlen = 0; 01918 parser->maxlen = 0; 01919 } 01920 } 01921 } 01922 if (status != SWITCH_STATUS_SUCCESS) { 01923 switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "unable to add hash for '%s'\n", digits); 01924 } 01925 01926 return status; 01927 }
| switch_status_t switch_ivr_digit_stream_parser_set_terminator | ( | switch_ivr_digit_stream_parser_t * | parser, | |
| char | digit | |||
| ) |
Set a digit string terminator.
| parser | a pointer to the parser object created by switch_ivr_digit_stream_parser_new | |
| digit | the terminator digit |
Definition at line 2010 of file switch_ivr.c.
References SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.
02011 { 02012 switch_status_t status = SWITCH_STATUS_FALSE; 02013 02014 if (parser != NULL) { 02015 parser->terminator = digit; 02016 /* since we have a terminator, reset min and max */ 02017 parser->minlen = 0; 02018 parser->maxlen = 0; 02019 status = SWITCH_STATUS_SUCCESS; 02020 } 02021 02022 return status; 02023 }
| switch_status_t switch_ivr_digit_stream_reset | ( | switch_ivr_digit_stream_t * | stream | ) |
Reset the collected digit stream to nothing.
| stream | a pointer to the parser stream object created by switch_ivr_digit_stream_new |
Definition at line 1997 of file switch_ivr.c.
References switch_assert, SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.
01998 { 01999 switch_status_t status = SWITCH_STATUS_FALSE; 02000 switch_assert(stream); 02001 switch_assert(stream->digits); 02002 02003 *stream->digits = '\0'; 02004 stream->last_digit_time = 0; 02005 status = SWITCH_STATUS_SUCCESS; 02006 02007 return status; 02008 }
| 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
| session | the session to displace | |
| file | filename | |
| limit | time limit in ms | |
| flags | m (mux) l (loop) or r(read session instead of write session) |
Definition at line 881 of file switch_ivr_async.c.
References switch_codec_implementation::actual_samples_per_second, switch_directories::base_dir, switch_codec_implementation::iananame, switch_codec_implementation::number_of_channels, read_displace_callback(), 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_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_URL_SEPARATOR, write_displace_callback(), and zstr.
00882 { 00883 switch_channel_t *channel = switch_core_session_get_channel(session); 00884 switch_media_bug_t *bug; 00885 switch_status_t status; 00886 time_t to = 0; 00887 char *ext; 00888 const char *prefix; 00889 displace_helper_t *dh; 00890 switch_codec_implementation_t read_impl = { 0 }; 00891 switch_core_session_get_read_impl(session, &read_impl); 00892 00893 if (zstr(file)) { 00894 return SWITCH_STATUS_FALSE; 00895 } 00896 00897 if ((status = switch_channel_pre_answer(channel)) != SWITCH_STATUS_SUCCESS) { 00898 return SWITCH_STATUS_FALSE; 00899 } 00900 00901 if (!switch_channel_media_up(channel) || !switch_core_session_get_read_codec(session)) { 00902 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can not displace session. Media not enabled on channel\n"); 00903 return SWITCH_STATUS_FALSE; 00904 } 00905 00906 if ((bug = switch_channel_get_private(channel, file))) { 00907 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Only 1 of the same file per channel please!\n"); 00908 return SWITCH_STATUS_FALSE; 00909 } 00910 00911 if (!(dh = switch_core_session_alloc(session, sizeof(*dh)))) { 00912 return SWITCH_STATUS_MEMERR; 00913 } 00914 00915 if (!(prefix = switch_channel_get_variable(channel, "sound_prefix"))) { 00916 prefix = SWITCH_GLOBAL_dirs.base_dir; 00917 } 00918 00919 if (!strstr(file, SWITCH_URL_SEPARATOR)) { 00920 if (!switch_is_file_path(file)) { 00921 char *tfile = NULL; 00922 char *e; 00923 00924 if (*file == '[') { 00925 tfile = switch_core_session_strdup(session, file); 00926 if ((e = switch_find_end_paren(tfile, '[', ']'))) { 00927 *e = '\0'; 00928 file = e + 1; 00929 } else { 00930 tfile = NULL; 00931 } 00932 } 00933 00934 file = switch_core_session_sprintf(session, "%s%s%s%s%s", switch_str_nil(tfile), tfile ? "]" : "", prefix, SWITCH_PATH_SEPARATOR, file); 00935 } 00936 if ((ext = strrchr(file, '.'))) { 00937 ext++; 00938 } else { 00939 ext = read_impl.iananame; 00940 file = switch_core_session_sprintf(session, "%s.%s", file, ext); 00941 } 00942 } 00943 00944 dh->fh.channels = read_impl.number_of_channels; 00945 dh->fh.samplerate = read_impl.actual_samples_per_second; 00946 dh->file = switch_core_session_strdup(session, file); 00947 00948 if (switch_core_file_open(&dh->fh, 00949 file, 00950 read_impl.number_of_channels, 00951 read_impl.actual_samples_per_second, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) { 00952 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); 00953 switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE); 00954 return SWITCH_STATUS_GENERR; 00955 } 00956 00957 if (limit) { 00958 to = switch_epoch_time_now(NULL) + limit; 00959 } 00960 00961 if (flags && strchr(flags, 'm')) { 00962 dh->mux++; 00963 } 00964 00965 if (flags && strchr(flags, 'l')) { 00966 dh->loop++; 00967 } 00968 00969 if (flags && strchr(flags, 'r')) { 00970 status = switch_core_media_bug_add(session, "displace", file, 00971 read_displace_callback, dh, to, SMBF_WRITE_REPLACE | SMBF_READ_REPLACE | SMBF_NO_PAUSE, &bug); 00972 } else { 00973 status = switch_core_media_bug_add(session, "displace", file, 00974 write_displace_callback, dh, to, SMBF_WRITE_REPLACE | SMBF_READ_REPLACE | SMBF_NO_PAUSE, &bug); 00975 } 00976 00977 if (status != SWITCH_STATUS_SUCCESS) { 00978 switch_core_file_close(&dh->fh); 00979 return status; 00980 } 00981 00982 switch_channel_set_private(channel, file, bug); 00983 00984 return SWITCH_STATUS_SUCCESS; 00985 }
| switch_status_t switch_ivr_eavesdrop_exec_all | ( | switch_core_session_t * | session, | |
| const char * | app, | |||
| const char * | arg | |||
| ) |
Definition at line 1301 of file switch_ivr_async.c.
References exec_cb(), switch_core_media_bug_exec_all(), switch_core_session_alloc, and switch_core_session_strdup.
01302 { 01303 struct exec_cb_data *data = NULL; 01304 01305 data = switch_core_session_alloc(session, sizeof(*data)); 01306 data->var = switch_core_session_strdup(session, app); 01307 data->val = switch_core_session_strdup(session, arg); 01308 data->caller = session; 01309 01310 return switch_core_media_bug_exec_all(session, "eavesdrop", exec_cb, data); 01311 }
| switch_status_t switch_ivr_eavesdrop_pop_eavesdropper | ( | switch_core_session_t * | session, | |
| switch_core_session_t ** | sessionp | |||
| ) |
Definition at line 1242 of file switch_ivr_async.c.
References eavesdrop_pvt::eavesdropper, 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.
01243 { 01244 switch_media_bug_t *bug; 01245 switch_status_t status = SWITCH_STATUS_FALSE; 01246 01247 if (switch_core_media_bug_pop(session, "eavesdrop", &bug) == SWITCH_STATUS_SUCCESS) { 01248 struct eavesdrop_pvt *ep = (struct eavesdrop_pvt *) switch_core_media_bug_get_user_data(bug); 01249 01250 if (ep && ep->eavesdropper && ep->eavesdropper != session) { 01251 switch_core_session_read_lock(ep->eavesdropper); 01252 *sessionp = ep->eavesdropper; 01253 switch_core_media_bug_set_flag(bug, SMBF_PRUNE); 01254 status = SWITCH_STATUS_SUCCESS; 01255 } 01256 } 01257 01258 01259 return status; 01260 }
| 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.
| session | our session | |
| uuid | the uuid of the session to spy on | |
| require_group | group name to use to limit by group | |
| flags | tweak read-mux, write-mux and dtmf |
Definition at line 1335 of file switch_ivr_async.c.
References switch_codec_implementation::actual_samples_per_second, buf, 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, switch_frame::codec, eavesdrop_pvt::data, switch_frame::data, switch_frame::datalen, switch_codec_implementation::decoded_bytes_per_packet, switch_dtmf_t::digit, eavesdrop_callback(), ED_COPY_DISPLAY, ED_DTMF, ED_MUX_READ, ED_MUX_WRITE, switch_core_session_message::from, switch_codec::implementation, switch_core_session_message::message_id, switch_codec_implementation::microseconds_per_packet, switch_codec_implementation::number_of_channels, switch_frame::rate, switch_frame::samples, SFF_CNG, SMBF_NO_PAUSE, SMBF_READ_PING, SMBF_READ_REPLACE, SMBF_READ_STREAM, SMBF_THREAD_LOCK, SMBF_WRITE_REPLACE, SMBF_WRITE_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_up, switch_channel_pre_answer, switch_channel_ready, SWITCH_CHANNEL_SESSION_LOG, switch_channel_state_change_pending(), 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_remove(), 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_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_ERROR, switch_log_printf(), SWITCH_MESSAGE_INDICATE_BRIDGE, SWITCH_MESSAGE_INDICATE_DISPLAY, SWITCH_MESSAGE_INDICATE_UNBRIDGE, switch_mutex_init(), SWITCH_MUTEX_NESTED, 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_yield, and zstr.
01337 { 01338 switch_core_session_t *tsession; 01339 switch_status_t status = SWITCH_STATUS_FALSE; 01340 switch_channel_t *channel = switch_core_session_get_channel(session); 01341 int codec_initialized = 0; 01342 const char *name, *num; 01343 01344 if ((tsession = switch_core_session_locate(uuid))) { 01345 struct eavesdrop_pvt *ep = NULL; 01346 switch_media_bug_t *bug = NULL; 01347 switch_channel_t *tchannel = switch_core_session_get_channel(tsession); 01348 switch_frame_t *read_frame, write_frame = { 0 }; 01349 switch_codec_t codec = { 0 }; 01350 int16_t buf[SWITCH_RECOMMENDED_BUFFER_SIZE / 2]; 01351 uint32_t tlen; 01352 const char *macro_name = "eavesdrop_announce"; 01353 const char *id_name = NULL; 01354 switch_codec_implementation_t tread_impl = { 0 }, read_impl = { 0 }; 01355 switch_core_session_message_t msg = { 0 }; 01356 char cid_buf[1024] = ""; 01357 switch_caller_profile_t *cp = NULL; 01358 uint32_t sanity = 600; 01359 01360 if (!switch_channel_media_up(channel)) { 01361 goto end; 01362 } 01363 01364 while(switch_channel_state_change_pending(tchannel) || !switch_channel_media_up(tchannel)) { 01365 switch_yield(10000); 01366 if (!--sanity) break; 01367 } 01368 01369 if (!switch_channel_media_up(tchannel)) { 01370 goto end; 01371 } 01372 01373 switch_core_session_get_read_impl(tsession, &tread_impl); 01374 switch_core_session_get_read_impl(session, &read_impl); 01375 01376 if ((id_name = switch_channel_get_variable(tchannel, "eavesdrop_announce_id"))) { 01377 const char *tmp = switch_channel_get_variable(tchannel, "eavesdrop_annnounce_macro"); 01378 if (tmp) { 01379 macro_name = tmp; 01380 } 01381 01382 switch_ivr_phrase_macro(session, macro_name, id_name, NULL, NULL); 01383 } 01384 01385 01386 if (!zstr(require_group)) { 01387 int argc, i; 01388 int ok = 0; 01389 char *argv[10] = { 0 }; 01390 char *data; 01391 01392 const char *group_name = switch_channel_get_variable(tchannel, "eavesdrop_group"); 01393 /* If we don't have a group, then return */ 01394 if (!group_name) { 01395 status = SWITCH_STATUS_BREAK; 01396 goto end; 01397 } 01398 /* Separate the group */ 01399 data = strdup(group_name); 01400 if ((argc = switch_separate_string(data, ',', argv, (sizeof(argv) / sizeof(argv[0]))))) { 01401 for (i = 0; i < argc; i++) { 01402 /* If one of the group matches, then ok */ 01403 if (argv[i] && !strcmp(argv[i], require_group)) { 01404 ok = 1; 01405 } 01406 } 01407 } 01408 switch_safe_free(data); 01409 /* If we didn't find any match, then end */ 01410 if (!ok) { 01411 status = SWITCH_STATUS_BREAK; 01412 goto end; 01413 } 01414 } 01415 01416 01417 ep = switch_core_session_alloc(session, sizeof(*ep)); 01418 01419 tlen = tread_impl.decoded_bytes_per_packet; 01420 01421 01422 if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) { 01423 goto end; 01424 } 01425 01426 01427 if (switch_core_codec_init(&codec, 01428 "L16", 01429 NULL, 01430 tread_impl.actual_samples_per_second, 01431 tread_impl.microseconds_per_packet / 1000, 01432 tread_impl.number_of_channels, 01433 SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, 01434 NULL, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { 01435 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot init codec\n"); 01436 switch_core_session_rwunlock(tsession); 01437 goto end; 01438 } 01439 01440 codec_initialized = 1; 01441 01442 switch_core_session_set_read_codec(session, &codec); 01443 write_frame.codec = &codec; 01444 write_frame.data = buf; 01445 write_frame.buflen = sizeof(buf); 01446 write_frame.rate = codec.implementation->actual_samples_per_second; 01447 01448 ep->eavesdropper = session; 01449 ep->flags = flags; 01450 switch_mutex_init(&ep->mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(tsession)); 01451 switch_buffer_create_dynamic(&ep->buffer, 2048, 2048, 8192); 01452 switch_buffer_add_mutex(ep->buffer, ep->mutex); 01453 01454 switch_mutex_init(&ep->w_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(tsession)); 01455 switch_buffer_create_dynamic(&ep->w_buffer, 2048, 2048, 8192); 01456 switch_buffer_add_mutex(ep->w_buffer, ep->w_mutex); 01457 01458 switch_mutex_init(&ep->r_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(tsession)); 01459 switch_buffer_create_dynamic(&ep->r_buffer, 2048, 2048, 8192); 01460 switch_buffer_add_mutex(ep->r_buffer, ep->r_mutex); 01461 01462 01463 if (switch_core_media_bug_add(tsession, "eavesdrop", uuid, 01464 eavesdrop_callback, ep, 0, 01465 SMBF_READ_STREAM | SMBF_WRITE_STREAM | SMBF_READ_REPLACE | SMBF_WRITE_REPLACE | 01466 SMBF_READ_PING | SMBF_THREAD_LOCK | SMBF_NO_PAUSE, 01467 &bug) != SWITCH_STATUS_SUCCESS) { 01468 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot attach bug\n"); 01469 goto end; 01470 } 01471 01472 01473 msg.from = __FILE__; 01474 01475 /* Tell the channel we are going to be in a bridge */ 01476 msg.message_id = SWITCH_MESSAGE_INDICATE_BRIDGE; 01477 switch_core_session_receive_message(session, &msg); 01478 cp = switch_channel_get_caller_profile(tchannel); 01479 name = cp->caller_id_name; 01480 num = cp->caller_id_number; 01481 01482 if (flags & ED_COPY_DISPLAY) { 01483 const char *tmp_name = NULL, *tmp_num = NULL; 01484 name = cp->callee_id_name; 01485 num = cp->callee_id_number; 01486 01487 if (!((tmp_name = switch_channel_get_variable(tchannel, "last_sent_callee_id_name")) 01488 && (tmp_num = switch_channel_get_variable(tchannel, "last_sent_callee_id_number")))) { 01489 01490 tmp_name = switch_channel_get_variable(tchannel, "callee_id_name"); 01491 tmp_num = switch_channel_get_variable(tchannel, "callee_id_number"); 01492 } 01493 01494 if (tmp_name) name = tmp_name; 01495 if (tmp_num) num = tmp_num; 01496 01497 } 01498 01499 switch_snprintf(cid_buf, sizeof(cid_buf), "%s|%s", name, num); 01500 msg.string_arg = cid_buf; 01501 msg.message_id = SWITCH_MESSAGE_INDICATE_DISPLAY; 01502 switch_core_session_receive_message(session, &msg); 01503 01504 while (switch_channel_up_nosig(tchannel) && switch_channel_ready(channel)) { 01505 uint32_t len = sizeof(buf); 01506 switch_event_t *event = NULL; 01507 char *fcommand = NULL; 01508 char db[2] = ""; 01509 01510 status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); 01511 01512 if (!SWITCH_READ_ACCEPTABLE(status)) { 01513 goto end_loop; 01514 } 01515 01516 if (switch_core_session_dequeue_event(session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) { 01517 char *command = switch_event_get_header(event, "eavesdrop-command"); 01518 if (command) { 01519 fcommand = switch_core_session_strdup(session, command); 01520 } 01521 switch_event_destroy(&event); 01522 } 01523 01524 if ((flags & ED_DTMF) && switch_channel_has_dtmf(channel)) { 01525 switch_dtmf_t dtmf = { 0 }; 01526 switch_channel_dequeue_dtmf(channel, &dtmf); 01527 db[0] = dtmf.digit; 01528 fcommand = db; 01529 } 01530 01531 if (fcommand) { 01532 char *d; 01533 for (d = fcommand; *d; d++) { 01534 int z = 1; 01535 01536 switch (*d) { 01537 case '1': 01538 switch_set_flag(ep, ED_MUX_READ); 01539 switch_clear_flag(ep, ED_MUX_WRITE); 01540 break; 01541 case '2': 01542 switch_set_flag(ep, ED_MUX_WRITE); 01543 switch_clear_flag(ep, ED_MUX_READ); 01544 break; 01545 case '3': 01546 switch_set_flag(ep, ED_MUX_READ); 01547 switch_set_flag(ep, ED_MUX_WRITE); 01548 break; 01549 case '0': 01550 switch_clear_flag(ep, ED_MUX_READ); 01551 switch_clear_flag(ep, ED_MUX_WRITE); 01552 break; 01553 case '*': 01554 goto end_loop; 01555 default: 01556 z = 0; 01557 break; 01558 01559 } 01560 01561 if (z) { 01562 if (ep->r_buffer) { 01563 switch_buffer_lock(ep->r_buffer); 01564 switch_buffer_zero(ep->r_buffer); 01565 switch_buffer_unlock(ep->r_buffer); 01566 } 01567 01568 if (ep->w_buffer) { 01569 switch_buffer_lock(ep->w_buffer); 01570 switch_buffer_zero(ep->w_buffer); 01571 switch_buffer_unlock(ep->w_buffer); 01572 } 01573 } 01574 } 01575 } 01576 01577 if (!switch_test_flag(read_frame, SFF_CNG)) { 01578 switch_buffer_lock(ep->r_buffer); 01579 switch_buffer_zwrite(ep->r_buffer, read_frame->data, read_frame->datalen); 01580 switch_buffer_unlock(ep->r_buffer); 01581 01582 switch_buffer_lock(ep->w_buffer); 01583 switch_buffer_zwrite(ep->w_buffer, read_frame->data, read_frame->datalen); 01584 switch_buffer_unlock(ep->w_buffer); 01585 } 01586 01587 if (len > tlen) { 01588 len = tlen; 01589 } 01590 01591 if (switch_buffer_inuse(ep->buffer) >= len) { 01592 switch_buffer_lock(ep->buffer); 01593 while (switch_buffer_inuse(ep->buffer) >= len) { 01594 write_frame.datalen = (uint32_t) switch_buffer_read(ep->buffer, buf, len); 01595 write_frame.samples = write_frame.datalen / 2; 01596 01597 if ((status = switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0)) != SWITCH_STATUS_SUCCESS) { 01598 break; 01599 } 01600 } 01601 switch_buffer_unlock(ep->buffer); 01602 } 01603 01604 } 01605 01606 end_loop: 01607 01608 /* Tell the channel we are no longer going to be in a bridge */ 01609 msg.message_id = SWITCH_MESSAGE_INDICATE_UNBRIDGE; 01610 switch_core_session_receive_message(session, &msg); 01611 01612 01613 01614 end: 01615 01616 if (codec_initialized) 01617 switch_core_codec_destroy(&codec); 01618 01619 if (bug) { 01620 switch_core_media_bug_remove(tsession, &bug); 01621 } 01622 01623 if (ep) { 01624 if (ep->buffer) { 01625 switch_buffer_destroy(&ep->buffer); 01626 } 01627 01628 if (ep->r_buffer) { 01629 switch_buffer_destroy(&ep->r_buffer); 01630 } 01631 01632 if (ep->w_buffer) { 01633 switch_buffer_destroy(&ep->w_buffer); 01634 } 01635 } 01636 01637 switch_core_session_rwunlock(tsession); 01638 status = SWITCH_STATUS_SUCCESS; 01639 01640 switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE); 01641 } 01642 01643 return status; 01644 }
| switch_status_t switch_ivr_eavesdrop_update_display | ( | switch_core_session_t * | session, | |
| const char * | name, | |||
| const char * | number | |||
| ) |
Definition at line 1314 of file switch_ivr_async.c.
References 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, and SWITCH_STATUS_FALSE.
01315 { 01316 struct exec_cb_data *data = NULL; 01317 switch_channel_t *channel = switch_core_session_get_channel(session); 01318 switch_status_t status = SWITCH_STATUS_FALSE; 01319 01320 data = switch_core_session_alloc(session, sizeof(*data)); 01321 data->var = switch_core_session_strdup(session, name); 01322 data->val = switch_core_session_strdup(session, number); 01323 data->caller = session; 01324 01325 if (!switch_channel_test_app_flag_key("EAVESDROP", channel, 1)) { 01326 switch_channel_set_app_flag_key("EAVESDROP", channel, 1); 01327 status = switch_core_media_bug_exec_all(session, "eavesdrop", display_exec_cb, data); 01328 switch_channel_clear_app_flag_key("EAVESDROP", channel, 1); 01329 } 01330 01331 return status; 01332 }
| 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 1375 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_channel_clear_flag(), switch_channel_get_caller_profile(), switch_channel_get_variable, 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_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, ent_originate_ringback::thread, enterprise_originate_handle_t::thread, switch_event_header::value, and zstr.
Referenced by switch_ivr_originate().
01386 { 01387 int x_argc = 0; 01388 char *x_argv[MAX_PEERS] = { 0 }; 01389 enterprise_originate_handle_t *hp = NULL, handles[MAX_PEERS] = { {0} }; 01390 int i; 01391 switch_caller_profile_t *cp = NULL; 01392 switch_channel_t *channel = NULL; 01393 char *data; 01394 switch_status_t status = SWITCH_STATUS_FALSE; 01395 switch_threadattr_t *thd_attr = NULL; 01396 int running = 0, over = 0; 01397 switch_status_t tstatus = SWITCH_STATUS_FALSE; 01398 switch_memory_pool_t *pool; 01399 switch_event_header_t *hi = NULL; 01400 struct ent_originate_ringback rb_data = { 0 }; 01401 const char *ringback_data = NULL; 01402 switch_event_t *var_event = NULL; 01403 01404 switch_core_new_memory_pool(&pool); 01405 01406 if (zstr(bridgeto)) { 01407 *cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; 01408 switch_goto_status(SWITCH_STATUS_FALSE, end); 01409 } 01410 01411 data = switch_core_strdup(pool, bridgeto); 01412 01413 if (session) { 01414 switch_caller_profile_t *cpp = NULL; 01415 channel = switch_core_session_get_channel(session); 01416 if ((cpp = switch_channel_get_caller_profile(channel))) { 01417 cp = switch_caller_profile_dup(pool, cpp); 01418 } 01419 } 01420 01421 if (ovars) { 01422 var_event = ovars; 01423 } else { 01424 if (switch_event_create_plain(&var_event, SWITCH_EVENT_CHANNEL_DATA) != SWITCH_STATUS_SUCCESS) { 01425 abort(); 01426 } 01427 } 01428 01429 if (session) { 01430 switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "ent_originate_aleg_uuid", switch_core_session_get_uuid(session)); 01431 } 01432 01433 if (channel) { 01434 const char *cid; 01435 01436 switch_channel_process_export(channel, NULL, var_event, SWITCH_EXPORT_VARS_VARIABLE); 01437 01438 if ((cid = switch_channel_get_variable(channel, "effective_caller_id_name"))) { 01439 switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "origination_caller_id_name", cid); 01440 } 01441 01442 if ((cid = switch_channel_get_variable(channel, "effective_caller_id_number"))) { 01443 switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "origination_caller_id_number", cid); 01444 } 01445 } 01446 01447 /* strip leading spaces */ 01448 while (data && *data && *data == ' ') { 01449 data++; 01450 } 01451 01452 /* extract channel variables, allowing multiple sets of braces */ 01453 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Parsing ultra-global variables\n"); 01454 while (*data == '<') { 01455 char *parsed = NULL; 01456 01457 if (switch_event_create_brackets(data, '<', '>', ',', &var_event, &parsed, SWITCH_FALSE) != SWITCH_STATUS_SUCCESS || !parsed) { 01458 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Parse Error!\n"); 01459 switch_goto_status(SWITCH_STATUS_GENERR, done); 01460 } 01461 01462 data = parsed; 01463 } 01464 01465 /* strip leading spaces (again) */ 01466 while (data && *data && *data == ' ') { 01467 data++; 01468 } 01469 01470 if (ovars && ovars != var_event) { 01471 for (hi = ovars->headers; hi; hi = hi->next) { 01472 switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, hi->name, hi->value); 01473 } 01474 } 01475 01476 switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "ignore_early_media", "true"); 01477 01478 if (!(x_argc = switch_separate_string_string(data, SWITCH_ENT_ORIGINATE_DELIM, x_argv, MAX_PEERS))) { 01479 *cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; 01480 switch_goto_status(SWITCH_STATUS_FALSE, end); 01481 } 01482 01483 switch_threadattr_create(&thd_attr, pool); 01484 switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); 01485 01486 for (i = 0; i < x_argc; i++) { 01487 handles[i].session = session; 01488 handles[i].bleg = NULL; 01489 handles[i].cause = 0; 01490 handles[i].cancel_cause = 0; 01491 handles[i].bridgeto = x_argv[i]; 01492 handles[i].timelimit_sec = timelimit_sec; 01493 handles[i].table = table; 01494 handles[i].cid_name_override = cid_name_override; 01495 handles[i].cid_num_override = cid_num_override; 01496 handles[i].caller_profile_override = cp; 01497 switch_event_dup(&handles[i].ovars, var_event); 01498 handles[i].flags = flags; 01499 switch_mutex_init(&handles[i].mutex, SWITCH_MUTEX_NESTED, pool); 01500 switch_mutex_lock(handles[i].mutex); 01501 switch_thread_create(&handles[i].thread, thd_attr, enterprise_originate_thread, &handles[i], pool); 01502 } 01503 01504 if (channel && !switch_channel_test_flag(channel, CF_PROXY_MODE) && !switch_channel_test_flag(channel, CF_PROXY_MEDIA)) { 01505 if (switch_channel_test_flag(channel, CF_ANSWERED)) { 01506 ringback_data = switch_channel_get_variable(channel, "transfer_ringback"); 01507 } 01508 01509 if (!ringback_data) { 01510 ringback_data = switch_channel_get_variable(channel, "ringback"); 01511 } 01512 01513 if (ringback_data || switch_channel_media_ready(channel)) { 01514 rb_data.ringback_data = ringback_data; 01515 rb_data.session = session; 01516 rb_data.running = 1; 01517 if (!switch_channel_media_ready(channel)) { 01518 if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) { 01519 goto done; 01520 } 01521 } 01522 switch_thread_create(&rb_data.thread, thd_attr, enterprise_originate_ringback_thread, &rb_data, pool); 01523 } 01524 } 01525 01526 01527 for (;;) { 01528 running = 0; 01529 over = 0; 01530 01531 if (channel && !switch_channel_ready(channel)) { 01532 break; 01533 } 01534 01535 if (cancel_cause && *cancel_cause > 0) { 01536 break; 01537 } 01538 01539 for (i = 0; i < x_argc; i++) { 01540 01541 01542 if (handles[i].done == 0) { 01543 running++; 01544 } else if (handles[i].done == 1) { 01545 if (handles[i].status == SWITCH_STATUS_SUCCESS) { 01546 handles[i].done = 2; 01547 hp = &handles[i]; 01548 goto done; 01549 } else { 01550 handles[i].done = -1; 01551 } 01552 } else { 01553 over++; 01554 } 01555 01556 switch_yield(10000); 01557 } 01558 01559 if (!running || over == x_argc) { 01560 break; 01561 } 01562 } 01563 01564 01565 done: 01566 01567 if (hp) { 01568 *cause = hp->cause; 01569 status = hp->status; 01570 *bleg = hp->bleg; 01571 switch_mutex_unlock(hp->mutex); 01572 switch_thread_join(&tstatus, hp->thread); 01573 switch_event_destroy(&hp->ovars); 01574 } 01575 01576 for (i = 0; i < x_argc; i++) { 01577 if (hp == &handles[i]) { 01578 continue; 01579 } 01580 01581 if (cancel_cause && *cancel_cause > 0) { 01582 handles[i].cancel_cause = *cancel_cause; 01583 } else { 01584 handles[i].cancel_cause = SWITCH_CAUSE_LOSE_RACE; 01585 } 01586 } 01587 01588 for (i = 0; i < x_argc; i++) { 01589 if (hp == &handles[i]) { 01590 continue; 01591 } 01592 switch_mutex_unlock(handles[i].mutex); 01593 switch_thread_join(&tstatus, handles[i].thread); 01594 switch_event_destroy(&handles[i].ovars); 01595 } 01596 01597 01598 if (channel && rb_data.thread) { 01599 switch_channel_set_flag(channel, CF_NOT_READY); 01600 switch_thread_join(&tstatus, rb_data.thread); 01601 switch_channel_clear_flag(channel, CF_NOT_READY); 01602 } 01603 01604 01605 end: 01606 01607 if (var_event && var_event != ovars) { 01608 switch_event_destroy(&var_event); 01609 } 01610 01611 switch_core_destroy_memory_pool(&pool); 01612 01613 return status; 01614 01615 }
| 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.
| session | the session to get the data from. | |
| json_cdr | pointer to the json object |
Definition at line 2523 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_caller_profile::caller_extension, switch_caller_extension::children, cJSON_AddItemToObject(), 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::hungup, switch_app_log::next, switch_caller_application::next, switch_caller_profile::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_session_get_app_log(), switch_core_session_get_channel(), switch_ivr_set_json_chan_vars(), switch_ivr_set_json_profile_data(), 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().
02524 { 02525 cJSON *cdr = cJSON_CreateObject(); 02526 switch_channel_t *channel = switch_core_session_get_channel(session); 02527 switch_caller_profile_t *caller_profile; 02528 cJSON *variables, *j_main_cp, *j_caller_profile, *j_caller_extension, *j_times, 02529 *j_application, *j_callflow, *j_inner_extension, *j_apps, *j_o, *j_channel_data; 02530 switch_app_log_t *app_log; 02531 char tmp[512], *f; 02532 02533 j_channel_data = cJSON_CreateObject(); 02534 02535 cJSON_AddItemToObject(cdr, "channel_data", j_channel_data); 02536 02537 cJSON_AddItemToObject(j_channel_data, "state", cJSON_CreateString((char *) switch_channel_state_name(switch_channel_get_state(channel)))); 02538 cJSON_AddItemToObject(j_channel_data, "direction", cJSON_CreateString(switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND ? "outbound" : "inbound")); 02539 02540 switch_snprintf(tmp, sizeof(tmp), "%d", switch_channel_get_state(channel)); 02541 cJSON_AddItemToObject(j_channel_data, "state_number", cJSON_CreateString((char *) tmp)); 02542 02543 if ((f = switch_channel_get_flag_string(channel))) { 02544 cJSON_AddItemToObject(j_channel_data, "flags", cJSON_CreateString((char *) f)); 02545 free(f); 02546 } 02547 02548 if ((f = switch_channel_get_cap_string(channel))) { 02549 cJSON_AddItemToObject(j_channel_data, "caps", cJSON_CreateString((char *) f)); 02550 free(f); 02551 } 02552 02553 variables = cJSON_CreateObject(); 02554 cJSON_AddItemToObject(cdr, "variables", variables); 02555 02556 switch_ivr_set_json_chan_vars(variables, channel, urlencode); 02557 02558 02559 if ((app_log = switch_core_session_get_app_log(session))) { 02560 switch_app_log_t *ap; 02561 02562 j_apps = cJSON_CreateObject(); 02563 02564 cJSON_AddItemToObject(cdr, "app_log", j_apps); 02565 02566 for (ap = app_log; ap; ap = ap->next) { 02567 j_application = cJSON_CreateObject(); 02568 02569 cJSON_AddItemToObject(j_application, "app_name", cJSON_CreateString(ap->app)); 02570 cJSON_AddItemToObject(j_application, "app_data", cJSON_CreateString(ap->arg)); 02571 02572 cJSON_AddItemToObject(j_apps, "application", j_application); 02573 } 02574 } 02575 02576 02577 caller_profile = switch_channel_get_caller_profile(channel); 02578 02579 while (caller_profile) { 02580 02581 j_callflow = cJSON_CreateObject(); 02582 02583 cJSON_AddItemToObject(cdr, "callflow", j_callflow); 02584 02585 if (!zstr(caller_profile->dialplan)) { 02586 cJSON_AddItemToObject(j_callflow, "dialplan", cJSON_CreateString((char *)caller_profile->dialplan)); 02587 } 02588 02589 if (!zstr(caller_profile->profile_index)) { 02590 cJSON_AddItemToObject(j_callflow, "profile_index", cJSON_CreateString((char *)caller_profile->profile_index)); 02591 } 02592 02593 if (caller_profile->caller_extension) { 02594 switch_caller_application_t *ap; 02595 02596 j_caller_extension = cJSON_CreateObject(); 02597 02598 cJSON_AddItemToObject(j_callflow, "extension", j_caller_extension); 02599 02600 cJSON_AddItemToObject(j_caller_extension, "name", cJSON_CreateString(caller_profile->caller_extension->extension_name)); 02601 cJSON_AddItemToObject(j_caller_extension, "number", cJSON_CreateString(caller_profile->caller_extension->extension_number)); 02602 02603 if (caller_profile->caller_extension->current_application) { 02604 cJSON_AddItemToObject(j_caller_extension, "current_app", cJSON_CreateString(caller_profile->caller_extension->current_application->application_name)); 02605 } 02606 02607 for (ap = caller_profile->caller_extension->applications; ap; ap = ap->next) { 02608 j_application = cJSON_CreateObject(); 02609 02610 cJSON_AddItemToObject(j_caller_extension, "application", j_application); 02611 02612 if (ap == caller_profile->caller_extension->current_application) { 02613 cJSON_AddItemToObject(j_application, "last_executed", cJSON_CreateString("true")); 02614 } 02615 cJSON_AddItemToObject(j_application, "app_name", cJSON_CreateString(ap->application_name)); 02616 cJSON_AddItemToObject(j_application, "app_data", cJSON_CreateString(switch_str_nil(ap->application_data))); 02617 } 02618 02619 if (caller_profile->caller_extension->children) { 02620 switch_caller_profile_t *cp = NULL; 02621 for (cp = caller_profile->caller_extension->children; cp; cp = cp->next) { 02622 02623 if (!cp->caller_extension) { 02624 continue; 02625 } 02626 02627 j_inner_extension = cJSON_CreateObject(); 02628 cJSON_AddItemToObject(j_caller_extension, "sub_extensions", j_inner_extension); 02629 02630 j_caller_extension = cJSON_CreateObject(); 02631 cJSON_AddItemToObject(j_inner_extension, "extension", j_caller_extension); 02632 02633 cJSON_AddItemToObject(j_caller_extension, "name", cJSON_CreateString(cp->caller_extension->extension_name)); 02634 cJSON_AddItemToObject(j_caller_extension, "number", cJSON_CreateString(cp->caller_extension->extension_number)); 02635 02636 cJSON_AddItemToObject(j_caller_extension, "dialplan", cJSON_CreateString((char *)cp->dialplan)); 02637 02638 if (cp->caller_extension->current_application) { 02639 cJSON_AddItemToObject(j_caller_extension, "current_app", cJSON_CreateString(cp->caller_extension->current_application->application_name)); 02640 } 02641 02642 for (ap = cp->caller_extension->applications; ap; ap = ap->next) { 02643 j_application = cJSON_CreateObject(); 02644 cJSON_AddItemToObject(j_caller_extension, "application", j_application); 02645 02646 if (ap == cp->caller_extension->current_application) { 02647 cJSON_AddItemToObject(j_application, "last_executed", cJSON_CreateString("true")); 02648 } 02649 cJSON_AddItemToObject(j_application, "app_name", cJSON_CreateString(ap->application_name)); 02650 cJSON_AddItemToObject(j_application, "app_data", cJSON_CreateString(switch_str_nil(ap->application_data))); 02651 } 02652 } 02653 } 02654 } 02655 02656 j_main_cp = cJSON_CreateObject(); 02657 cJSON_AddItemToObject(j_callflow, "caller_profile", j_main_cp); 02658 02659 switch_ivr_set_json_profile_data(j_main_cp, caller_profile); 02660 02661 if (caller_profile->originator_caller_profile) { 02662 switch_caller_profile_t *cp = NULL; 02663 02664 j_o = cJSON_CreateObject(); 02665 cJSON_AddItemToObject(j_main_cp, "originator", j_o); 02666 02667 for (cp = caller_profile->originator_caller_profile; cp; cp = cp->next) { 02668 j_caller_profile = cJSON_CreateObject(); 02669 cJSON_AddItemToObject(j_o, "originator_caller_profile", j_caller_profile); 02670 02671 switch_ivr_set_json_profile_data(j_caller_profile, cp); 02672 } 02673 } 02674 02675 if (caller_profile->originatee_caller_profile) { 02676 switch_caller_profile_t *cp = NULL; 02677 02678 j_o = cJSON_CreateObject(); 02679 cJSON_AddItemToObject(j_main_cp, "originatee", j_o); 02680 02681 for (cp = caller_profile->originatee_caller_profile; cp; cp = cp->next) { 02682 j_caller_profile = cJSON_CreateObject(); 02683 cJSON_AddItemToObject(j_o, "originatee_caller_profile", j_caller_profile); 02684 switch_ivr_set_json_profile_data(j_caller_profile, cp); 02685 } 02686 } 02687 02688 if (caller_profile->times) { 02689 02690 j_times = cJSON_CreateObject(); 02691 cJSON_AddItemToObject(j_callflow, "times", j_times); 02692 02693 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->created); 02694 cJSON_AddItemToObject(j_times, "created_time", cJSON_CreateString(tmp)); 02695 02696 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->profile_created); 02697 cJSON_AddItemToObject(j_times, "profile_created_time", cJSON_CreateString(tmp)); 02698 02699 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->progress); 02700 cJSON_AddItemToObject(j_times, "progress_time", cJSON_CreateString(tmp)); 02701 02702 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->progress_media); 02703 cJSON_AddItemToObject(j_times, "progress_media_time", cJSON_CreateString(tmp)); 02704 02705 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->answered); 02706 cJSON_AddItemToObject(j_times, "answered_time", cJSON_CreateString(tmp)); 02707 02708 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->hungup); 02709 cJSON_AddItemToObject(j_times, "hangup_time", cJSON_CreateString(tmp)); 02710 02711 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->resurrected); 02712 cJSON_AddItemToObject(j_times, "resurrect_time", cJSON_CreateString(tmp)); 02713 02714 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->transferred); 02715 cJSON_AddItemToObject(j_times, "transfer_time", cJSON_CreateString(tmp)); 02716 02717 } 02718 02719 caller_profile = caller_profile->next; 02720 } 02721 02722 *json_cdr = cdr; 02723 02724 return SWITCH_STATUS_SUCCESS; 02725 02726 }
| switch_status_t switch_ivr_generate_xml_cdr | ( | switch_core_session_t * | session, | |
| switch_xml_t * | xml_cdr | |||
| ) |
Generate an XML CDR report.
| session | the session to get the data from. | |
| xml_cdr | pointer to the xml_record |
Definition at line 2174 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, switch_caller_profile::clone_of, 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_application::next, switch_caller_profile::next, switch_caller_profile::originatee_caller_profile, switch_caller_profile::origination_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_app_log::stamp, 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_session_get_app_log(), switch_core_session_get_channel(), switch_ivr_set_xml_chan_vars(), switch_ivr_set_xml_profile_data(), switch_snprintf(), SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, SWITCH_TIME_T_FMT, switch_xml_add_child_d, switch_xml_free(), switch_xml_new(), switch_xml_set_attr_d, switch_xml_set_attr_d_buf, switch_xml_set_txt_d, switch_caller_profile::times, switch_channel_timetable::transferred, switch_caller_profile::uuid_str, and zstr.
Referenced by CoreSession::getXMLCDR(), switch_core_session_reporting_state(), and switch_ivr_multi_threaded_bridge().
02175 { 02176 switch_channel_t *channel = switch_core_session_get_channel(session); 02177 switch_caller_profile_t *caller_profile; 02178 switch_xml_t variables, cdr, x_main_cp, x_caller_profile, x_caller_extension, x_times, time_tag, 02179 x_application, x_callflow, x_inner_extension, x_apps, x_o, x_channel_data, x_field; 02180 switch_app_log_t *app_log; 02181 char tmp[512], *f; 02182 int cdr_off = 0, v_off = 0, cd_off = 0; 02183 02184 if (*xml_cdr) { 02185 cdr = *xml_cdr; 02186 } else { 02187 if (!(cdr = switch_xml_new("cdr"))) { 02188 return SWITCH_STATUS_SUCCESS; 02189 } 02190 } 02191 02192 if (!(x_channel_data = switch_xml_add_child_d(cdr, "channel_data", cdr_off++))) { 02193 goto error; 02194 } 02195 02196 x_field = switch_xml_add_child_d(x_channel_data, "state", cd_off++); 02197 switch_xml_set_txt_d(x_field, switch_channel_state_name(switch_channel_get_state(channel))); 02198 02199 x_field = switch_xml_add_child_d(x_channel_data, "direction", cd_off++); 02200 switch_xml_set_txt_d(x_field, switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND ? "outbound" : "inbound"); 02201 02202 x_field = switch_xml_add_child_d(x_channel_data, "state_number", cd_off++); 02203 switch_snprintf(tmp, sizeof(tmp), "%d", switch_channel_get_state(channel)); 02204 switch_xml_set_txt_d(x_field, tmp); 02205 02206 if ((f = switch_channel_get_flag_string(channel))) { 02207 x_field = switch_xml_add_child_d(x_channel_data, "flags", cd_off++); 02208 switch_xml_set_txt_d(x_field, f); 02209 free(f); 02210 } 02211 02212 if ((f = switch_channel_get_cap_string(channel))) { 02213 x_field = switch_xml_add_child_d(x_channel_data, "caps", cd_off++); 02214 switch_xml_set_txt_d(x_field, f); 02215 free(f); 02216 } 02217 02218 02219 if (!(variables = switch_xml_add_child_d(cdr, "variables", cdr_off++))) { 02220 goto error; 02221 } 02222 02223 switch_ivr_set_xml_chan_vars(variables, channel, v_off); 02224 02225 02226 if ((app_log = switch_core_session_get_app_log(session))) { 02227 int app_off = 0; 02228 switch_app_log_t *ap; 02229 02230 if (!(x_apps = switch_xml_add_child_d(cdr, "app_log", cdr_off++))) { 02231 goto error; 02232 } 02233 for (ap = app_log; ap; ap = ap->next) { 02234 char tmp[128]; 02235 02236 if (!(x_application = switch_xml_add_child_d(x_apps, "application", app_off++))) { 02237 goto error; 02238 } 02239 02240 switch_xml_set_attr_d(x_application, "app_name", ap->app); 02241 switch_xml_set_attr_d(x_application, "app_data", ap->arg); 02242 02243 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, ap->stamp); 02244 switch_xml_set_attr_d_buf(x_application, "app_stamp", tmp); 02245 } 02246 } 02247 02248 02249 caller_profile = switch_channel_get_caller_profile(channel); 02250 02251 while (caller_profile) { 02252 int cf_off = 0; 02253 int cp_off = 0; 02254 02255 if (!(x_callflow = switch_xml_add_child_d(cdr, "callflow", cdr_off++))) { 02256 goto error; 02257 } 02258 02259 if (!zstr(caller_profile->dialplan)) { 02260 switch_xml_set_attr_d(x_callflow, "dialplan", caller_profile->dialplan); 02261 } 02262 02263 if (!zstr(caller_profile->uuid_str)) { 02264 switch_xml_set_attr_d(x_callflow, "unique-id", caller_profile->uuid_str); 02265 } 02266 02267 if (!zstr(caller_profile->clone_of)) { 02268 switch_xml_set_attr_d(x_callflow, "clone-of", caller_profile->clone_of); 02269 } 02270 02271 if (!zstr(caller_profile->profile_index)) { 02272 switch_xml_set_attr_d(x_callflow, "profile_index", caller_profile->profile_index); 02273 } 02274 02275 if (caller_profile->caller_extension) { 02276 switch_caller_application_t *ap; 02277 int app_off = 0; 02278 02279 if (!(x_caller_extension = switch_xml_add_child_d(x_callflow, "extension", cf_off++))) { 02280 goto error; 02281 } 02282 02283 switch_xml_set_attr_d(x_caller_extension, "name", caller_profile->caller_extension->extension_name); 02284 switch_xml_set_attr_d(x_caller_extension, "number", caller_profile->caller_extension->extension_number); 02285 if (caller_profile->caller_extension->current_application) { 02286 switch_xml_set_attr_d(x_caller_extension, "current_app", caller_profile->caller_extension->current_application->application_name); 02287 } 02288 02289 for (ap = caller_profile->caller_extension->applications; ap; ap = ap->next) { 02290 if (!(x_application = switch_xml_add_child_d(x_caller_extension, "application", app_off++))) { 02291 goto error; 02292 } 02293 if (ap == caller_profile->caller_extension->current_application) { 02294 switch_xml_set_attr_d(x_application, "last_executed", "true"); 02295 } 02296 switch_xml_set_attr_d(x_application, "app_name", ap->application_name); 02297 switch_xml_set_attr_d(x_application, "app_data", ap->application_data); 02298 } 02299 02300 if (caller_profile->caller_extension->children) { 02301 switch_caller_profile_t *cp = NULL; 02302 int i_off = 0, i_app_off = 0; 02303 for (cp = caller_profile->caller_extension->children; cp; cp = cp->next) { 02304 02305 if (!cp->caller_extension) { 02306 continue; 02307 } 02308 if (!(x_inner_extension = switch_xml_add_child_d(x_caller_extension, "sub_extensions", app_off++))) { 02309 goto error; 02310 } 02311 02312 if (!(x_caller_extension = switch_xml_add_child_d(x_inner_extension, "extension", i_off++))) { 02313 goto error; 02314 } 02315 switch_xml_set_attr_d(x_caller_extension, "name", cp->caller_extension->extension_name); 02316 switch_xml_set_attr_d(x_caller_extension, "number", cp->caller_extension->extension_number); 02317 switch_xml_set_attr_d(x_caller_extension, "dialplan", cp->dialplan); 02318 if (cp->caller_extension->current_application) { 02319 switch_xml_set_attr_d(x_caller_extension, "current_app", cp->caller_extension->current_application->application_name); 02320 } 02321 02322 for (ap = cp->caller_extension->applications; ap; ap = ap->next) { 02323 if (!(x_application = switch_xml_add_child_d(x_caller_extension, "application", i_app_off++))) { 02324 goto error; 02325 } 02326 if (ap == cp->caller_extension->current_application) { 02327 switch_xml_set_attr_d(x_application, "last_executed", "true"); 02328 } 02329 switch_xml_set_attr_d(x_application, "app_name", ap->application_name); 02330 switch_xml_set_attr_d(x_application, "app_data", ap->application_data); 02331 } 02332 } 02333 } 02334 } 02335 02336 if (!(x_main_cp = switch_xml_add_child_d(x_callflow, "caller_profile", cf_off++))) { 02337 goto error; 02338 } 02339 02340 cp_off += switch_ivr_set_xml_profile_data(x_main_cp, caller_profile, 0); 02341 02342 if (caller_profile->origination_caller_profile) { 02343 switch_caller_profile_t *cp = NULL; 02344 int off = 0; 02345 if (!(x_o = switch_xml_add_child_d(x_main_cp, "origination", cp_off++))) { 02346 goto error; 02347 } 02348 02349 for (cp = caller_profile->origination_caller_profile; cp; cp = cp->next) { 02350 if (!(x_caller_profile = switch_xml_add_child_d(x_o, "origination_caller_profile", off++))) { 02351 goto error; 02352 } 02353 switch_ivr_set_xml_profile_data(x_caller_profile, cp, 0); 02354 } 02355 } 02356 02357 if (caller_profile->originator_caller_profile) { 02358 switch_caller_profile_t *cp = NULL; 02359 int off = 0; 02360 if (!(x_o = switch_xml_add_child_d(x_main_cp, "originator", cp_off++))) { 02361 goto error; 02362 } 02363 02364 for (cp = caller_profile->originator_caller_profile; cp; cp = cp->next) { 02365 if (!(x_caller_profile = switch_xml_add_child_d(x_o, "originator_caller_profile", off++))) { 02366 goto error; 02367 } 02368 switch_ivr_set_xml_profile_data(x_caller_profile, cp, 0); 02369 } 02370 } 02371 02372 if (caller_profile->originatee_caller_profile) { 02373 switch_caller_profile_t *cp = NULL; 02374 int off = 0; 02375 if (!(x_o = switch_xml_add_child_d(x_main_cp, "originatee", cp_off++))) { 02376 goto error; 02377 } 02378 for (cp = caller_profile->originatee_caller_profile; cp; cp = cp->next) { 02379 if (!(x_caller_profile = switch_xml_add_child_d(x_o, "originatee_caller_profile", off++))) { 02380 goto error; 02381 } 02382 switch_ivr_set_xml_profile_data(x_caller_profile, cp, 0); 02383 } 02384 } 02385 02386 if (caller_profile->times) { 02387 int t_off = 0; 02388 if (!(x_times = switch_xml_add_child_d(x_callflow, "times", cf_off++))) { 02389 goto error; 02390 } 02391 if (!(time_tag = switch_xml_add_child_d(x_times, "created_time", t_off++))) { 02392 goto error; 02393 } 02394 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->created); 02395 switch_xml_set_txt_d(time_tag, tmp); 02396 02397 if (!(time_tag = switch_xml_add_child_d(x_times, "profile_created_time", t_off++))) { 02398 goto error; 02399 } 02400 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->profile_created); 02401 switch_xml_set_txt_d(time_tag, tmp); 02402 02403 if (!(time_tag = switch_xml_add_child_d(x_times, "progress_time", t_off++))) { 02404 goto error; 02405 } 02406 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->progress); 02407 switch_xml_set_txt_d(time_tag, tmp); 02408 02409 02410 if (!(time_tag = switch_xml_add_child_d(x_times, "progress_media_time", t_off++))) { 02411 goto error; 02412 } 02413 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->progress_media); 02414 switch_xml_set_txt_d(time_tag, tmp); 02415 02416 if (!(time_tag = switch_xml_add_child_d(x_times, "answered_time", t_off++))) { 02417 goto error; 02418 } 02419 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->answered); 02420 switch_xml_set_txt_d(time_tag, tmp); 02421 02422 if (!(time_tag = switch_xml_add_child_d(x_times, "bridged_time", t_off++))) { 02423 goto error; 02424 } 02425 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->bridged); 02426 switch_xml_set_txt_d(time_tag, tmp); 02427 02428 if (!(time_tag = switch_xml_add_child_d(x_times, "last_hold_time", t_off++))) { 02429 goto error; 02430 } 02431 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->last_hold); 02432 switch_xml_set_txt_d(time_tag, tmp); 02433 02434 if (!(time_tag = switch_xml_add_child_d(x_times, "hold_accum_time", t_off++))) { 02435 goto error; 02436 } 02437 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->hold_accum); 02438 switch_xml_set_txt_d(time_tag, tmp); 02439 02440 if (!(time_tag = switch_xml_add_child_d(x_times, "hangup_time", t_off++))) { 02441 goto error; 02442 } 02443 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->hungup); 02444 switch_xml_set_txt_d(time_tag, tmp); 02445 02446 if (!(time_tag = switch_xml_add_child_d(x_times, "resurrect_time", t_off++))) { 02447 goto error; 02448 } 02449 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->resurrected); 02450 switch_xml_set_txt_d(time_tag, tmp); 02451 02452 if (!(time_tag = switch_xml_add_child_d(x_times, "transfer_time", t_off++))) { 02453 goto error; 02454 } 02455 switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, caller_profile->times->transferred); 02456 switch_xml_set_txt_d(time_tag, tmp); 02457 } 02458 02459 caller_profile = caller_profile->next; 02460 } 02461 02462 *xml_cdr = cdr; 02463 02464 return SWITCH_STATUS_SUCCESS; 02465 02466 error: 02467 02468 if (cdr) { 02469 switch_xml_free(cdr); 02470 } 02471 02472 return SWITCH_STATUS_FALSE; 02473 }
| switch_status_t switch_ivr_gentones | ( | switch_core_session_t * | session, | |
| const char * | script, | |||
| int32_t | loops, | |||
| switch_input_args_t * | args | |||
| ) |
Definition at line 817 of file switch_ivr_play_say.c.
References switch_codec_implementation::actual_samples_per_second, switch_frame::buflen, CF_BREAK, 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_frame::samples, switch_buffer_create_dynamic(), switch_buffer_destroy(), switch_buffer_read_loop(), switch_buffer_set_loops(), switch_channel_clear_flag(), switch_channel_dequeue_dtmf(), switch_channel_has_dtmf(), switch_channel_pre_answer, switch_channel_ready, switch_channel_test_flag(), SWITCH_CODEC_FLAG_DECODE, SWITCH_CODEC_FLAG_ENCODE, switch_core_codec_destroy(), switch_core_codec_init, switch_core_session_dequeue_event(), 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_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_READ_ACCEPTABLE, SWITCH_RECOMMENDED_BUFFER_SIZE, SWITCH_STATUS_BREAK, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, teletone_destroy_session(), teletone_handler(), teletone_init_session(), and teletone_run().
Referenced by enterprise_originate_ringback_thread().
00818 { 00819 teletone_generation_session_t ts; 00820 switch_dtmf_t dtmf = { 0 }; 00821 switch_buffer_t *audio_buffer; 00822 switch_frame_t *read_frame = NULL; 00823 switch_codec_t write_codec = { 0 }; 00824 switch_frame_t write_frame = { 0 }; 00825 switch_byte_t data[SWITCH_RECOMMENDED_BUFFER_SIZE]; 00826 switch_channel_t *channel = switch_core_session_get_channel(session); 00827 switch_codec_implementation_t read_impl = { 0 }; 00828 switch_core_session_get_read_impl(session, &read_impl); 00829 00830 if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) { 00831 return SWITCH_STATUS_FALSE; 00832 } 00833 00834 if (switch_core_codec_init(&write_codec, 00835 "L16", 00836 NULL, 00837 read_impl.actual_samples_per_second, 00838 read_impl.microseconds_per_packet / 1000, 00839 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, 00840 NULL, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { 00841 00842 return SWITCH_STATUS_FALSE; 00843 } 00844 memset(&ts, 0, sizeof(ts)); 00845 write_frame.codec = &write_codec; 00846 write_frame.data = data; 00847 write_frame.buflen = sizeof(data); 00848 00849 switch_buffer_create_dynamic(&audio_buffer, 512, 1024, 0); 00850 teletone_init_session(&ts, 0, teletone_handler, audio_buffer); 00851 ts.rate = read_impl.actual_samples_per_second; 00852 ts.channels = 1; 00853 teletone_run(&ts, script); 00854 00855 if (loops) { 00856 switch_buffer_set_loops(audio_buffer, loops); 00857 } 00858 00859 for (;;) { 00860 switch_status_t status; 00861 00862 if (!switch_channel_ready(channel)) { 00863 status = SWITCH_STATUS_FALSE; 00864 break; 00865 } 00866 00867 if (switch_channel_test_flag(channel, CF_BREAK)) { 00868 switch_channel_clear_flag(channel, CF_BREAK); 00869 status = SWITCH_STATUS_BREAK; 00870 break; 00871 } 00872 00873 status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); 00874 00875 if (!SWITCH_READ_ACCEPTABLE(status)) { 00876 break; 00877 } 00878 00879 if (args && args->dmachine) { 00880 if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL)) != SWITCH_STATUS_SUCCESS) { 00881 break; 00882 } 00883 } 00884 00885 if (args && (args->read_frame_callback)) { 00886 if ((status = args->read_frame_callback(session, read_frame, args->user_data)) != SWITCH_STATUS_SUCCESS) { 00887 break; 00888 } 00889 } 00890 00891 switch_ivr_parse_all_events(session); 00892 00893 if (args) { 00894 /* 00895 dtmf handler function you can hook up to be executed when a digit is dialed during gentones 00896 if you return anything but SWITCH_STATUS_SUCCESS the playback will stop. 00897 */ 00898 if (switch_channel_has_dtmf(channel)) { 00899 if (!args->input_callback && !args->buf && !args->dmachine) { 00900 status = SWITCH_STATUS_BREAK; 00901 break; 00902 } 00903 switch_channel_dequeue_dtmf(channel, &dtmf); 00904 00905 if (args->dmachine) { 00906 char ds[2] = {dtmf.digit, '\0'}; 00907 if ((status = switch_ivr_dmachine_feed(args->dmachine, ds, NULL)) != SWITCH_STATUS_SUCCESS) { 00908 break; 00909 } 00910 } 00911 00912 if (args->input_callback) { 00913 status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen); 00914 } else if (args->buf) { 00915 *((char *) args->buf) = dtmf.digit; 00916 status = SWITCH_STATUS_BREAK; 00917 } 00918 } 00919 00920 if (args->input_callback) { 00921 switch_event_t *event; 00922 00923 if (switch_core_session_dequeue_event(session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) { 00924 status = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen); 00925 switch_event_destroy(&event); 00926 } 00927 } 00928 00929 if (status != SWITCH_STATUS_SUCCESS) { 00930 break; 00931 } 00932 } 00933 00934 if ((write_frame.datalen = (uint32_t) switch_buffer_read_loop(audio_buffer, write_frame.data, read_impl.decoded_bytes_per_packet)) <= 0) { 00935 break; 00936 } 00937 00938 write_frame.samples = write_frame.datalen / 2; 00939 00940 if (switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) { 00941 break; 00942 } 00943 } 00944 00945 switch_core_codec_destroy(&write_codec); 00946 switch_buffer_destroy(&audio_buffer); 00947 teletone_destroy_session(&ts); 00948 00949 return SWITCH_STATUS_SUCCESS; 00950 }
| 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.
| session | the session to hold | |
| message | optional message | |
| moh | play music-on-hold |
Definition at line 1370 of file switch_ivr.c.
References CF_HOLD, CF_SUSPEND, switch_core_session_message::from, switch_core_session_message::message_id, SMF_ECHO_ALEG, SMF_LOOP, switch_core_session_message::string_arg, switch_channel_get_hold_music(), switch_channel_get_variable, switch_channel_set_flag, switch_core_session_get_channel(), switch_core_session_receive_message, switch_ivr_broadcast(), SWITCH_MESSAGE_INDICATE_HOLD, SWITCH_SIGNAL_BOND_VARIABLE, and SWITCH_STATUS_SUCCESS.
Referenced by switch_ivr_hold_uuid().
01371 { 01372 switch_core_session_message_t msg = { 0 }; 01373 switch_channel_t *channel = switch_core_session_get_channel(session); 01374 const char *stream; 01375 const char *other_uuid; 01376 01377 msg.message_id = SWITCH_MESSAGE_INDICATE_HOLD; 01378 msg.string_arg = message; 01379 msg.from = __FILE__; 01380 01381 switch_channel_set_flag(channel, CF_HOLD); 01382 switch_channel_set_flag(channel, CF_SUSPEND); 01383 01384 switch_core_session_receive_message(session, &msg); 01385 01386 if (moh && (stream = switch_channel_get_hold_music(channel))) { 01387 if ((other_uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE))) { 01388 switch_ivr_broadcast(other_uuid, stream, SMF_ECHO_ALEG | SMF_LOOP); 01389 } 01390 } 01391 01392 01393 return SWITCH_STATUS_SUCCESS; 01394 }
| 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.
| uuid | the uuid of the session to hold | |
| message | optional message | |
| moh | play music-on-hold |
Definition at line 1396 of file switch_ivr.c.
References switch_core_session_locate(), switch_core_session_rwunlock(), switch_ivr_hold(), and SWITCH_STATUS_SUCCESS.
01397 { 01398 switch_core_session_t *session; 01399 01400 if ((session = switch_core_session_locate(uuid))) { 01401 switch_ivr_hold(session, message, moh); 01402 switch_core_session_rwunlock(session); 01403 } 01404 01405 return SWITCH_STATUS_SUCCESS; 01406 }
| switch_status_t switch_ivr_inband_dtmf_generate_session | ( | switch_core_session_t * | session, | |
| switch_bool_t | read_stream | |||
| ) |
Start generating DTMF inband.
| session | the session to generate on | |
| read_stream | true to use the session we are reading from, false for the session we are writing to. |
Definition at line 2641 of file switch_ivr_async.c.
References inband_dtmf_generate_callback(), SMBF_NO_PAUSE, SMBF_READ_REPLACE, SMBF_WRITE_REPLACE, switch_channel_media_up, switch_channel_pre_answer, SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_private(), switch_core_media_bug_add(), switch_core_session_alloc, switch_core_session_get_channel(), switch_core_session_get_read_codec(), SWITCH_LOG_ERROR, switch_log_printf(), SWITCH_STATUS_FALSE, SWITCH_STATUS_MEMERR, and SWITCH_STATUS_SUCCESS.
02642 { 02643 switch_channel_t *channel = switch_core_session_get_channel(session); 02644 switch_media_bug_t *bug; 02645 switch_status_t status; 02646 switch_inband_dtmf_generate_t *pvt; 02647 02648 if ((status = switch_channel_pre_answer(channel)) != SWITCH_STATUS_SUCCESS) { 02649 return SWITCH_STATUS_FALSE; 02650 } 02651 02652 if (!switch_channel_media_up(channel) || !switch_core_session_get_read_codec(session)) { 02653 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can not install inband dtmf generate. Media not enabled on channel\n"); 02654 return status; 02655 } 02656 02657 if (!(pvt = switch_core_session_alloc(session, sizeof(*pvt)))) { 02658 return SWITCH_STATUS_MEMERR; 02659 } 02660 02661 pvt->session = session; 02662 pvt->read = !!read_stream; 02663 02664 if ((status = switch_core_media_bug_add(session, "inband_dtmf_generate", NULL, 02665 inband_dtmf_generate_callback, pvt, 0, 02666 SMBF_NO_PAUSE | (pvt->read ? SMBF_READ_REPLACE : SMBF_WRITE_REPLACE) , &bug)) != SWITCH_STATUS_SUCCESS) { 02667 return status; 02668 } 02669 02670 switch_channel_set_private(channel, "dtmf_generate", bug); 02671 02672 return SWITCH_STATUS_SUCCESS; 02673 }
| switch_status_t switch_ivr_inband_dtmf_session | ( | switch_core_session_t * | session | ) |
Start looking for DTMF inband.
| session | the session to start looking |
Definition at line 2406 of file switch_ivr_async.c.
References switch_codec_implementation::actual_samples_per_second, inband_dtmf_callback(), SMBF_NO_PAUSE, SMBF_READ_REPLACE, switch_channel_pre_answer, switch_channel_set_private(), switch_core_media_bug_add(), switch_core_session_alloc, switch_core_session_get_channel(), switch_core_session_get_read_impl(), SWITCH_STATUS_FALSE, SWITCH_STATUS_MEMERR, SWITCH_STATUS_SUCCESS, and teletone_dtmf_detect_init().
02407 { 02408 switch_channel_t *channel = switch_core_session_get_channel(session); 02409 switch_media_bug_t *bug; 02410 switch_status_t status; 02411 switch_inband_dtmf_t *pvt; 02412 switch_codec_implementation_t read_impl = { 0 }; 02413 02414 switch_core_session_get_read_impl(session, &read_impl); 02415 02416 if (!(pvt = switch_core_session_alloc(session, sizeof(*pvt)))) { 02417 return SWITCH_STATUS_MEMERR; 02418 } 02419 02420 teletone_dtmf_detect_init(&pvt->dtmf_detect, read_impl.actual_samples_per_second); 02421 02422 pvt->session = session; 02423 02424 02425 if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) { 02426 return SWITCH_STATUS_FALSE; 02427 } 02428 02429 if ((status = switch_core_media_bug_add(session, "inband_dtmf", NULL, 02430 inband_dtmf_callback, pvt, 0, SMBF_READ_REPLACE | SMBF_NO_PAUSE, &bug)) != SWITCH_STATUS_SUCCESS) { 02431 return status; 02432 } 02433 02434 switch_channel_set_private(channel, "dtmf", bug); 02435 02436 return SWITCH_STATUS_SUCCESS; 02437 }
| 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.
| uuid | the uuid of the session to request | |
| flags | flags to influence behaviour (SMF_REBRIDGE to rebridge the call in media mode) |
Definition at line 1447 of file switch_ivr.c.
References CF_BRIDGE_ORIGINATOR, CF_BRIDGED, CF_EARLY_MEDIA, CF_MEDIA_ACK, CF_MEDIA_SET, CF_PROXY_MODE, CF_REQ_MEDIA, switch_core_session_message::from, switch_core_session_message::message_id, SMF_IMMEDIATE, SMF_REBRIDGE, switch_assert, switch_channel_clear_state_handler(), switch_channel_get_name(), switch_channel_get_variable, SWITCH_CHANNEL_SESSION_LOG, switch_channel_test_flag(), switch_channel_wait_for_flag(), switch_core_session_get_channel(), switch_core_session_locate(), switch_core_session_read_frame(), switch_core_session_receive_message, switch_core_session_rwunlock(), SWITCH_FALSE, SWITCH_IO_FLAG_NONE, switch_ivr_uuid_bridge(), SWITCH_LOG_ERROR, switch_log_printf(), SWITCH_MESSAGE_INDICATE_CLEAR_PROGRESS, SWITCH_MESSAGE_INDICATE_MEDIA, SWITCH_SIGNAL_BRIDGE_VARIABLE, SWITCH_STATUS_GENERR, SWITCH_STATUS_SUCCESS, SWITCH_TRUE, and switch_yield.
Referenced by cleanup_proxy_mode_b(), switch_core_session_execute_application_get_flags(), switch_core_standard_on_routing(), switch_ivr_broadcast(), switch_ivr_originate(), and switch_ivr_session_transfer().
01448 { 01449 const char *other_uuid = NULL; 01450 switch_channel_t *channel, *other_channel = NULL; 01451 switch_core_session_t *session, *other_session; 01452 switch_core_session_message_t msg = { 0 }; 01453 switch_status_t status = SWITCH_STATUS_GENERR; 01454 uint8_t swap = 0; 01455 switch_frame_t *read_frame = NULL; 01456 01457 msg.message_id = SWITCH_MESSAGE_INDICATE_MEDIA; 01458 msg.from = __FILE__; 01459 01460 if ((session = switch_core_session_locate(uuid))) { 01461 channel = switch_core_session_get_channel(session); 01462 01463 if ((flags & SMF_REBRIDGE) && !switch_channel_test_flag(channel, CF_BRIDGE_ORIGINATOR)) { 01464 swap = 1; 01465 } 01466 01467 if (switch_channel_test_flag(channel, CF_PROXY_MODE)) { 01468 status = SWITCH_STATUS_SUCCESS; 01469 01470 /* If we had early media in bypass mode before, it is no longer relevant */ 01471 if (switch_channel_test_flag(channel, CF_EARLY_MEDIA)) { 01472 switch_core_session_message_t msg2 = { 0 }; 01473 01474 msg2.message_id = SWITCH_MESSAGE_INDICATE_CLEAR_PROGRESS; 01475 msg2.from = __FILE__; 01476 switch_core_session_receive_message(session, &msg2); 01477 } 01478 01479 if (switch_core_session_receive_message(session, &msg) != SWITCH_STATUS_SUCCESS) { 01480 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't re-establsh media on %s\n", switch_channel_get_name(channel)); 01481 switch_core_session_rwunlock(session); 01482 return SWITCH_STATUS_GENERR; 01483 } 01484 01485 if ((flags & SMF_IMMEDIATE)) { 01486 switch_channel_wait_for_flag(channel, CF_REQ_MEDIA, SWITCH_FALSE, 250, NULL); 01487 switch_yield(250000); 01488 } else { 01489 switch_channel_wait_for_flag(channel, CF_REQ_MEDIA, SWITCH_FALSE, 10000, NULL); 01490 switch_channel_wait_for_flag(channel, CF_MEDIA_ACK, SWITCH_TRUE, 10000, NULL); 01491 switch_channel_wait_for_flag(channel, CF_MEDIA_SET, SWITCH_TRUE, 10000, NULL); 01492 switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); 01493 } 01494 01495 if ((flags & SMF_REBRIDGE) 01496 && (other_uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BRIDGE_VARIABLE)) 01497 && (other_session = switch_core_session_locate(other_uuid))) { 01498 other_channel = switch_core_session_get_channel(other_session); 01499 switch_assert(other_channel != NULL); 01500 switch_core_session_receive_message(other_session, &msg); 01501 switch_channel_wait_for_flag(other_channel, CF_REQ_MEDIA, SWITCH_FALSE, 10000, NULL); 01502 switch_channel_wait_for_flag(other_channel, CF_MEDIA_ACK, SWITCH_TRUE, 10000, NULL); 01503 switch_channel_wait_for_flag(other_channel, CF_MEDIA_SET, SWITCH_TRUE, 10000, NULL); 01504 switch_core_session_read_frame(other_session, &read_frame, SWITCH_IO_FLAG_NONE, 0); 01505 switch_channel_clear_state_handler(other_channel, NULL); 01506 switch_core_session_rwunlock(other_session); 01507 } 01508 if (other_channel) { 01509 switch_channel_clear_state_handler(channel, NULL); 01510 } 01511 } 01512 01513 switch_core_session_rwunlock(session); 01514 01515 if (other_channel) { 01516 if (swap) { 01517 switch_ivr_uuid_bridge(other_uuid, uuid); 01518 } else { 01519 switch_ivr_uuid_bridge(uuid, other_uuid); 01520 } 01521 switch_channel_wait_for_flag(channel, CF_BRIDGED, SWITCH_TRUE, 1000, NULL); 01522 switch_channel_wait_for_flag(other_channel, CF_BRIDGED, SWITCH_TRUE, 1000, NULL); 01523 } 01524 } 01525 01526 return status; 01527 }
| 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.
| session | one session | |
| peer_session | the other session | |
| dtmf_callback | a callback for messages and dtmf | |
| session_data | data to pass to the DTMF callback for session | |
| peer_session_data | data to pass to the DTMF callback for peer_session |
Referenced by bridge(), fs_switch_ivr_originate(), and uuid_bridge_on_soft_execute().
| 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.
| uuid | the uuid of the session to request | |
| flags | flags to influence behaviour (SMF_REBRIDGE to rebridge the call in no_media mode) |
Definition at line 1529 of file switch_ivr.c.
References CF_BRIDGE_ORIGINATOR, CF_MEDIA_ACK, CF_MEDIA_SET, 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_BRIDGE_VARIABLE, switch_channel_get_variable, switch_channel_set_flag, switch_channel_set_state, 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_MESSAGE_INDICATE_NOMEDIA, SWITCH_STATUS_GENERR, SWITCH_STATUS_SUCCESS, SWITCH_TRUE, and switch_yield.
Referenced by audio_bridge_thread(), and switch_ivr_parse_event().
01530 { 01531 const char *other_uuid; 01532 switch_channel_t *channel, *other_channel = NULL; 01533 switch_core_session_t *session, *other_session = NULL; 01534 switch_core_session_message_t msg = { 0 }; 01535 switch_status_t status = SWITCH_STATUS_GENERR; 01536 uint8_t swap = 0; 01537 01538 msg.message_id = SWITCH_MESSAGE_INDICATE_NOMEDIA; 01539 msg.from = __FILE__; 01540 01541 if ((session = switch_core_session_locate(uuid))) { 01542 status = SWITCH_STATUS_SUCCESS; 01543 channel = switch_core_session_get_channel(session); 01544 01545 if ((flags & SMF_REBRIDGE) && !switch_channel_test_flag(channel, CF_BRIDGE_ORIGINATOR)) { 01546 swap = 1; 01547 } 01548 01549 switch_channel_set_flag(channel, CF_REDIRECT); 01550 switch_channel_set_flag(channel, CF_RESET); 01551 01552 if ((flags & SMF_FORCE) || !switch_channel_test_flag(channel, CF_PROXY_MODE)) { 01553 if ((flags & SMF_REBRIDGE) && (other_uuid = switch_channel_get_variable(channel, SWITCH_BRIDGE_VARIABLE)) && 01554 (other_session = switch_core_session_locate(other_uuid))) { 01555 other_channel = switch_core_session_get_channel(other_session); 01556 01557 switch_channel_set_flag(other_channel, CF_RESET); 01558 switch_channel_set_flag(other_channel, CF_REDIRECT); 01559 01560 if (!switch_core_session_in_thread(session)) { 01561 switch_channel_set_state(channel, CS_PARK); 01562 } 01563 switch_channel_set_state(other_channel, CS_PARK); 01564 if (switch_core_session_in_thread(session)) { 01565 switch_yield(100000); 01566 } else { 01567 switch_channel_wait_for_state(other_channel, channel, CS_PARK); 01568 } 01569 switch_core_session_receive_message(other_session, &msg); 01570 switch_channel_wait_for_flag(other_channel, CF_REQ_MEDIA, SWITCH_FALSE, 10000, NULL); 01571 //switch_channel_wait_for_flag(other_channel, CF_MEDIA_ACK, SWITCH_TRUE, 10000, NULL); 01572 switch_channel_wait_for_flag(other_channel, CF_MEDIA_SET, SWITCH_TRUE, 10000, NULL); 01573 } 01574 01575 switch_core_session_receive_message(session, &msg); 01576 01577 if (other_channel) { 01578 if (!switch_core_session_in_thread(session)) { 01579 switch_channel_wait_for_state(channel, NULL, CS_PARK); 01580 switch_channel_wait_for_flag(channel, CF_REQ_MEDIA, SWITCH_FALSE, 10000, NULL); 01581 switch_channel_wait_for_flag(channel, CF_MEDIA_ACK, SWITCH_TRUE, 10000, NULL); 01582 switch_channel_wait_for_flag(channel, CF_MEDIA_SET, SWITCH_TRUE, 10000, NULL); 01583 } 01584 01585 if (swap) { 01586 switch_ivr_signal_bridge(other_session, session); 01587 } else { 01588 switch_ivr_signal_bridge(session, other_session); 01589 } 01590 01591 if (switch_core_session_in_thread(session)) { 01592 switch_yield(100000); 01593 } else { 01594 switch_channel_wait_for_state(other_channel, channel, CS_HIBERNATE); 01595 } 01596 01597 if (!switch_core_session_in_thread(session)) { 01598 switch_channel_wait_for_state(channel, other_channel, CS_HIBERNATE); 01599 } 01600 switch_core_session_rwunlock(other_session); 01601 } 01602 } 01603 switch_core_session_rwunlock(session); 01604 } 01605 01606 return status; 01607 }
| 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.
| session | originating session | |
| bleg | B leg session | |
| cause | a pointer to hold call cause | |
| bridgeto | the desired remote callstring | |
| timelimit_sec | timeout in seconds for outgoing call | |
| table | optional state handler table to install on the channel | |
| cid_name_override | override the caller id name | |
| cid_num_override | override the caller id number | |
| caller_profile_override | override the entire calling caller profile | |
| ovars | variables to be set on the outgoing channel | |
| flags | flags to pass |
Definition at line 1748 of file switch_ivr_originate.c.
References originate_global_t::bridge_early_media, buf, switch_frame::buflen, originate_global_t::caller_profile_override, CF_ANSWERED, CF_EARLY_MEDIA, CF_ORIGINATOR, CF_PROXY_MEDIA, CF_PROXY_MODE, originate_global_t::check_vars, switch_frame::data, originate_global_t::early_ok, originate_global_t::error_file, originate_global_t::file, switch_core_session_message::from, originate_global_t::idx, IDX_NADA, MAX_PEERS, switch_core_session_message::message_id, switch_event_header::name, switch_event_header::next, early_state::oglobals, early_state::originate_status, originate_global_t::pool, originate_global_t::ringback_ok, originate_global_t::session, SMF_NONE, SOF_NONE, SWITCH_B_SDP_VARIABLE, SWITCH_BYPASS_MEDIA_VARIABLE, SWITCH_CALL_TIMEOUT_VARIABLE, switch_caller_profile_dup(), SWITCH_CAUSE_NONE, switch_channel_answer, switch_channel_clear_flag(), switch_channel_get_caller_profile(), switch_channel_get_name(), switch_channel_get_variable, switch_channel_process_export(), SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_flag, switch_channel_set_variable, switch_channel_test_flag(), switch_channel_variable_first(), switch_core_get_variable(), switch_core_new_memory_pool, switch_core_session_get_channel(), switch_core_session_get_read_impl(), switch_core_session_get_uuid(), switch_core_session_receive_message, SWITCH_ENT_ORIGINATE_DELIM, SWITCH_EVENT_CHANNEL_DATA, switch_event_create_brackets(), switch_event_create_plain(), switch_event_get_header, SWITCH_EXPORT_VARS_VARIABLE, SWITCH_FALSE, switch_goto_status, switch_ivr_enterprise_originate(), switch_ivr_media(), SWITCH_LOG_DEBUG, SWITCH_LOG_ERROR, switch_log_printf(), SWITCH_LOG_WARNING, SWITCH_MESSAGE_INDICATE_CLEAR_PROGRESS, SWITCH_PROXY_MEDIA_VARIABLE, SWITCH_RECOMMENDED_BUFFER_SIZE, switch_snprintf(), SWITCH_STATUS_GENERR, SWITCH_STATUS_MEMERR, SWITCH_STATUS_SUCCESS, switch_stristr(), SWITCH_TRUE, switch_true(), switch_zmalloc, and zstr.
Referenced by CoreSession::CoreSession(), enterprise_originate_thread(), fs_switch_ivr_originate(), and CoreSession::originate().
01758 { 01759 originate_status_t originate_status[MAX_PEERS] = { {0} }; 01760 switch_originate_flag_t dftflags = SOF_NONE, myflags = dftflags; 01761 char *pipe_names[MAX_PEERS] = { 0 }; 01762 char *data = NULL; 01763 switch_status_t status = SWITCH_STATUS_SUCCESS; 01764 switch_channel_t *caller_channel = NULL; 01765 char *peer_names[MAX_PEERS] = { 0 }; 01766 switch_core_session_t *new_session = NULL, *peer_session; 01767 switch_caller_profile_t *new_profile = NULL, *caller_caller_profile; 01768 char *chan_type = NULL, *chan_data; 01769 switch_channel_t *peer_channel = NULL; 01770 ringback_t ringback = { 0 }; 01771 time_t start; 01772 switch_frame_t *read_frame = NULL; 01773 int r = 0, i, and_argc = 0, or_argc = 0; 01774 int32_t sleep_ms = 1000, try = 0, retries = 1; 01775 switch_codec_t write_codec = { 0 }; 01776 switch_frame_t write_frame = { 0 }; 01777 char *odata, *var; 01778 switch_call_cause_t reason = SWITCH_CAUSE_NONE; 01779 switch_call_cause_t force_reason = SWITCH_CAUSE_NONE; 01780 uint8_t to = 0; 01781 char *var_val; 01782 const char *ringback_data = NULL; 01783 switch_event_t *var_event = NULL; 01784 int8_t fail_on_single_reject = 0; 01785 char *fail_on_single_reject_var = NULL; 01786 char *loop_data = NULL; 01787 uint32_t progress_timelimit_sec = 0; 01788 const char *cid_tmp, *lc; 01789 originate_global_t oglobals = { 0 }; 01790 int cdr_total = 0; 01791 int local_clobber = 0; 01792 const char *cancel_key = NULL; 01793 const char *holding = NULL; 01794 const char *soft_holding = NULL; 01795 early_state_t early_state = { 0 }; 01796 int read_packet = 0; 01797 int check_reject = 1; 01798 switch_codec_implementation_t read_impl = { 0 }; 01799 01800 if (strstr(bridgeto, SWITCH_ENT_ORIGINATE_DELIM)) { 01801 return switch_ivr_enterprise_originate(session, bleg, cause, bridgeto, timelimit_sec, table, cid_name_override, cid_num_override, 01802 caller_profile_override, ovars, flags, cancel_cause); 01803 } 01804 01805 oglobals.check_vars = SWITCH_TRUE; 01806 oglobals.ringback_ok = 1; 01807 oglobals.bridge_early_media = -1; 01808 oglobals.file = NULL; 01809 oglobals.error_file = NULL; 01810 switch_core_new_memory_pool(&oglobals.pool); 01811 01812 if (caller_profile_override) { 01813 oglobals.caller_profile_override = switch_caller_profile_dup(oglobals.pool, caller_profile_override); 01814 } else if (session) { 01815 switch_caller_profile_t *cp = switch_channel_get_caller_profile(switch_core_session_get_channel(session)); 01816 01817 if (cp) { 01818 oglobals.caller_profile_override = switch_caller_profile_dup(oglobals.pool, cp); 01819 } 01820 } 01821 01822 if (session) { 01823 const char *to_var, *bypass_media = NULL, *proxy_media = NULL; 01824 caller_channel = switch_core_session_get_channel(session); 01825 switch_channel_set_flag(caller_channel, CF_ORIGINATOR); 01826 oglobals.session = session; 01827 01828 switch_core_session_get_read_impl(session, &read_impl); 01829 01830 if ((to_var = switch_channel_get_variable(caller_channel, SWITCH_CALL_TIMEOUT_VARIABLE))) { 01831 timelimit_sec = atoi(to_var); 01832 } 01833 01834 proxy_media = switch_channel_get_variable(caller_channel, SWITCH_PROXY_MEDIA_VARIABLE); 01835 bypass_media = switch_channel_get_variable(caller_channel, SWITCH_BYPASS_MEDIA_VARIABLE); 01836 01837 if (!zstr(proxy_media)) { 01838 if (switch_true(proxy_media)) { 01839 switch_channel_set_flag(caller_channel, CF_PROXY_MEDIA); 01840 } else if (switch_channel_test_flag(caller_channel, CF_PROXY_MEDIA)) { 01841 switch_channel_clear_flag(caller_channel, CF_PROXY_MEDIA); 01842 } 01843 } 01844 01845 if (bypass_media && switch_channel_test_flag(caller_channel, CF_EARLY_MEDIA) && !switch_channel_test_flag(caller_channel, CF_ANSWERED)) { 01846 switch_core_session_message_t msg = { 0 }; 01847 01848 msg.message_id = SWITCH_MESSAGE_INDICATE_CLEAR_PROGRESS; 01849 msg.from = __FILE__; 01850 switch_core_session_receive_message(session, &msg); 01851 } 01852 01853 01854 if (!zstr(bypass_media) && !switch_channel_test_flag(caller_channel, CF_PROXY_MEDIA)) { 01855 if (switch_true(bypass_media)) { 01856 switch_channel_set_flag(caller_channel, CF_PROXY_MODE); 01857 } else if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE)) { 01858 if (!switch_channel_test_flag(caller_channel, CF_ANSWERED) && switch_channel_test_flag(caller_channel, CF_EARLY_MEDIA)) { 01859 switch_channel_set_variable(caller_channel, SWITCH_B_SDP_VARIABLE, NULL); 01860 switch_channel_answer(caller_channel); 01861 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, 01862 "Must answer channel %s due to SIP PARADOX\n", switch_channel_get_name(caller_channel)); 01863 } 01864 switch_channel_set_variable(caller_channel, SWITCH_B_SDP_VARIABLE, NULL); 01865 switch_ivr_media(switch_core_session_get_uuid(session), SMF_NONE); 01866 } 01867 } 01868 01869 if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE) && switch_channel_test_flag(caller_channel, CF_ANSWERED)) { 01870 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, 01871 "Channel is already up, delaying proxy mode 'till both legs are answered.\n"); 01872 switch_channel_set_variable(caller_channel, "bypass_media_after_bridge", "true"); 01873 switch_channel_set_variable(caller_channel, SWITCH_BYPASS_MEDIA_VARIABLE, NULL); 01874 switch_channel_clear_flag(caller_channel, CF_PROXY_MODE); 01875 } 01876 } 01877 01878 if (timelimit_sec <= 0) { 01879 timelimit_sec = 60; 01880 } 01881 01882 01883 oglobals.idx = IDX_NADA; 01884 oglobals.early_ok = 1; 01885 01886 *bleg = NULL; 01887 01888 switch_zmalloc(write_frame.data, SWITCH_RECOMMENDED_BUFFER_SIZE); 01889 write_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE; 01890 01891 odata = strdup(bridgeto); 01892 01893 if (!odata) { 01894 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Memory Error!\n"); 01895 status = SWITCH_STATUS_MEMERR; 01896 goto done; 01897 } 01898 01899 data = odata; 01900 01901 01902 /* Some channel are created from an originating channel and some aren't so not all outgoing calls have a way to get params 01903 so we will normalize dialstring params and channel variables (when there is an originator) into an event that we 01904 will use as a pseudo hash to consult for params as needed. 01905 */ 01906 01907 if (ovars) { 01908 var_event = ovars; 01909 } else { 01910 if (switch_event_create_plain(&var_event, SWITCH_EVENT_CHANNEL_DATA) != SWITCH_STATUS_SUCCESS) { 01911 abort(); 01912 } 01913 } 01914 01915 if (caller_channel) { 01916 switch_channel_process_export(caller_channel, NULL, var_event, SWITCH_EXPORT_VARS_VARIABLE); 01917 } 01918 01919 /* strip leading spaces */ 01920 while (data && *data && *data == ' ') { 01921 data++; 01922 } 01923 01924 if ((ovars && switch_true(switch_event_get_header(ovars,"origination_nested_vars"))) || 01925 (caller_channel && switch_true(switch_channel_get_variable(caller_channel, "origination_nested_vars"))) 01926 || switch_true(switch_core_get_variable("origination_nested_vars")) || switch_stristr("origination_nested_vars=true", data)) { 01927 oglobals.check_vars = SWITCH_FALSE; 01928 } 01929 01930 01931 /* extract channel variables, allowing multiple sets of braces */ 01932 if (*data == '<') { 01933 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Parsing ultra-global variables\n"); 01934 while (*data == '<') { 01935 char *parsed = NULL; 01936 01937 if (switch_event_create_brackets(data, '<', '>', ',', &var_event, &parsed, SWITCH_FALSE) != SWITCH_STATUS_SUCCESS || !parsed) { 01938 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Parse Error!\n"); 01939 switch_goto_status(SWITCH_STATUS_GENERR, done); 01940 } 01941 01942 data = parsed; 01943 } 01944 } 01945 01946 /* extract channel variables, allowing multiple sets of braces */ 01947 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Parsing global variables\n"); 01948 while (*data == '{') { 01949 char *parsed = NULL; 01950 01951 if (switch_event_create_brackets(data, '{', '}', ',', &var_event, &parsed, SWITCH_FALSE) != SWITCH_STATUS_SUCCESS || !parsed) { 01952 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Parse Error!\n"); 01953 switch_goto_status(SWITCH_STATUS_GENERR, done); 01954 } 01955 01956 data = parsed; 01957 } 01958 01959 01960 /* strip leading spaces (again) */ 01961 while (data && *data && *data == ' ') { 01962 data++; 01963 } 01964 01965 if (zstr(data)) { 01966 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "No origination URL specified!\n"); 01967 status = SWITCH_STATUS_GENERR; 01968 goto done; 01969 } 01970 01971 01972 if (oglobals.session) { 01973 switch_event_header_t *hi; 01974 const char *cdr_total_var; 01975 const char *cdr_var; 01976 01977 if ((cdr_var = switch_channel_get_variable(caller_channel, "failed_xml_cdr_prefix"))) { 01978 char buf[128] = ""; 01979 switch_snprintf(buf, sizeof(buf), "%s_total", cdr_var); 01980 if ((cdr_total_var = switch_channel_get_variable(caller_channel, buf))) { 01981 int tmp = atoi(cdr_total_var); 01982 if (tmp > 0) { 01983 cdr_total = tmp; 01984 } 01985 } 01986 } 01987 01988 01989 /* Copy all the missing applicable channel variables from A-leg into the event */ 01990 if ((hi = switch_channel_variable_first(caller_channel))) { 01991 for (; hi; hi = hi->next) { 01992 int ok = 0; 01993 if (!strcasecmp((char *) hi->name, "group_confirm_key")) { 01994 ok = 1; 01995 } else if (!strcasecmp((char *) hi->name, "group_confirm_file")) { 01996 ok = 1; 01997 } else if (!strcasecmp((char *) hi->name, "group_confirm_read_timeout")) { 01998 ok = 1; 01999 } else if (!strcasecmp((char *) hi->name, "group_confirm_cancel_timeout")) { 02000 ok = 1; 02001 } else if (!strcasecmp((char *) hi->name, "forked_dial")) { 02002 ok = 1; 02003 } else if (!strcasecmp((char *) hi->name, "fail_on_single_reject")) { 02004 ok = 1; 02005 } else if (!strcasecmp((char *) hi->name, "ignore_early_media")) { 02006 ok = 1; 02007 } else if (!strcasecmp((char *) hi->name, "bridge_early_media")) { 02008 ok = 1; 02009 } else if (!strcasecmp((char *) hi->name, "originate_continue_on_timeout")) { 02010 ok = 1; 02011 } else if (!strcasecmp((char *) hi->name, "ignore_ring_ready")) { 02012 ok = 1; 02013 } else if (!strcasecmp((char *) hi->name, "monitor_early_media_ring")) { 02014 ok = 1; 02015 } else if (!strcasecmp((char *) hi->name, "monitor_early_media_ring_total")) { 02016 ok = 1; 02017 } else if (!strcasecmp((char *) hi->name, "monitor_early_media_fail")) { 02018 ok = 1; 02019 } else if (!strcasecmp((char *) hi->name, "return_ring_ready")) { 02020 ok = 1; 02021 } else if (!strcasecmp((char *) hi->name, "ring_ready")) { 02022 ok = 1; 02023 } else if (!strcasecmp((char *) hi->name, "instant_ringback")) { 02024 ok = 1; 02025 } else if (!strcasecmp((char *) hi->name, "progress_timeout")) { 02026 ok = 1; 02027 } else if (!strcasecmp((char *) hi->name, "language")) { 02028 ok = 1; 02029 } 02030 02031 if (ok && !switch_event_get_header(var_event, hi->name)) { 02032 switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, (char *) hi->name, (char *) hi->value); 02033 } 02034 } 02035 switch_channel_variable_last(caller_channel); 02036 } 02037 /* 02038 if ((hi = switch_channel_variable_first(caller_channel))) { 02039 for (; hi; hi = switch_hash_next(hi)) { 02040 switch_hash_this(hi, &vvar, NULL, &vval); 02041 if (vvar && vval) { 02042 switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, (void *) vvar, (char *) vval); 02043 } 02044 } 02045 switch_channel_variable_last(caller_channel); 02046 } 02047 */ 02048 } 02049 02050 if (caller_channel) { /* ringback is only useful when there is an originator */ 02051 ringback_data = NULL; 02052 cancel_key = switch_channel_get_variable(caller_channel, "origination_cancel_key"); 02053 02054 if (switch_channel_test_flag(caller_channel, CF_ANSWERED)) { 02055 ringback_data = switch_channel_get_variable(caller_channel, "transfer_ringback"); 02056 } 02057 02058 if (!ringback_data) { 02059 ringback_data = switch_channel_get_variable(caller_channel, "ringback"); 02060 } 02061 02062 switch_channel_set_variable(caller_channel, "originate_disposition", "failure"); 02063 switch_channel_set_variable(caller_channel, "DIALSTATUS", "INVALIDARGS"); 02064 02065 if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE) || switch_channel_test_flag(caller_channel, CF_PROXY_MEDIA)) { 02066 ringback_data = NULL; 02067 } else if (zstr(ringback_data)) { 02068 const char *vvar; 02069 02070 if ((vvar = switch_channel_get_variable(caller_channel, SWITCH_SEND_SILENCE_WHEN_IDLE_VARIABLE))) { 02071 int sval = atoi(vvar); 02072 02073 if (sval) { 02074 ringback_data = switch_core_session_sprintf(oglobals.session, "silence:%d", sval); 02075 } 02076 02077 } 02078 } 02079 } 02080 #if 0 02081 /* changing behaviour ignore_early_media=true must also be explicitly set for previous behaviour */ 02082 if (ringback_data) { 02083 oglobals.early_ok = 0; 02084 } 02085 #endif 02086 02087 if (switch_true(switch_event_get_header(var_event, "group_confirm_cancel_timeout"))) { 02088 oglobals.cancel_timeout = -1; 02089 } 02090 02091 if ((var = switch_event_get_header(var_event, "group_confirm_key"))) { 02092 switch_copy_string(oglobals.key, var, sizeof(oglobals.key)); 02093 if ((var = switch_event_get_header(var_event, "group_confirm_file"))) { 02094 oglobals.file = strdup(var); 02095 } 02096 if ((var = switch_event_get_header(var_event, "group_confirm_error_file"))) { 02097 oglobals.error_file = strdup(var); 02098 } 02099 if ((var = switch_event_get_header(var_event, "group_confirm_read_timeout"))) { 02100 int tmp = atoi(var); 02101 02102 if (tmp >= 0) { 02103 oglobals.confirm_timeout = tmp; 02104 } 02105 02106 } 02107 } 02108 /* When using the AND operator, the fail_on_single_reject flag may be set in order to indicate that a single 02109 rejections should terminate the attempt rather than a timeout, answer, or rejection by all. 02110 If the value is set to 'true' any fail cause will end the attempt otherwise it can contain a comma (,) separated 02111 list of cause names which should be considered fatal 02112 */ 02113 if ((var = switch_event_get_header(var_event, "fail_on_single_reject"))) { 02114 fail_on_single_reject_var = strdup(var); 02115 if (switch_true(var)) { 02116 fail_on_single_reject = 1; 02117 } else { 02118 fail_on_single_reject = -1; 02119 } 02120 } 02121 02122 if ((!zstr(oglobals.file)) && (!strcmp(oglobals.file, "undef"))) { 02123 switch_safe_free(oglobals.file); 02124 oglobals.file = NULL; 02125 } 02126 if ((!zstr(oglobals.error_file)) && (!strcmp(oglobals.error_file, "undef"))) { 02127 switch_safe_free(oglobals.error_file); 02128 oglobals.error_file = NULL; 02129 } 02130 02131 if ((var_val = switch_event_get_header(var_event, "bridge_early_media"))) { 02132 if (switch_true(var_val)) { 02133 oglobals.early_ok = 0; 02134 oglobals.ignore_early_media = 3; 02135 } 02136 } 02137 02138 if ((var_val = switch_event_get_header(var_event, "ignore_early_media"))) { 02139 if (switch_true(var_val)) { 02140 oglobals.early_ok = 0; 02141 oglobals.ignore_early_media = 1; 02142 } else if (!strcmp(var_val, "ring_ready")) { 02143 oglobals.early_ok = 0; 02144 oglobals.ignore_early_media = 2; 02145 } 02146 } 02147 02148 if ((var_val = switch_event_get_header(var_event, "originate_continue_on_timeout")) && switch_true(var_val)) { 02149 oglobals.continue_on_timeout = 1; 02150 } 02151 02152 if ((var_val = switch_event_get_header(var_event, "ignore_ring_ready")) && switch_true(var_val)) { 02153 oglobals.ignore_ring_ready = 1; 02154 } 02155 02156 if ((var_val = switch_event_get_header(var_event, "monitor_early_media_ring"))) { 02157 oglobals.early_ok = 0; 02158 oglobals.monitor_early_media_ring = 1; 02159 } 02160 02161 if ((var_val = switch_event_get_header(var_event, "monitor_early_media_fail"))) { 02162 oglobals.early_ok = 0; 02163 oglobals.monitor_early_media_fail = 1; 02164 } 02165 02166 if ((var_val = switch_event_get_header(var_event, "return_ring_ready")) && switch_true(var_val)) { 02167 oglobals.return_ring_ready = 1; 02168 } 02169 02170 if ((var_val = switch_event_get_header(var_event, "ring_ready")) && switch_true(var_val)) { 02171 oglobals.ring_ready = 1; 02172 } 02173 02174 if ((var_val = switch_event_get_header(var_event, "instant_ringback")) && switch_true(var_val)) { 02175 oglobals.instant_ringback = 1; 02176 } 02177 02178 if ((var_val = switch_event_get_header(var_event, "originate_timeout"))) { 02179 int tmp = atoi(var_val); 02180 if (tmp > 0) { 02181 timelimit_sec = (uint32_t) tmp; 02182 } 02183 } 02184 02185 if ((var_val = switch_event_get_header(var_event, "progress_timeout"))) { 02186 int tmp = atoi(var_val); 02187 if (tmp > 0) { 02188 progress_timelimit_sec = (uint32_t) tmp; 02189 } 02190 } 02191 02192 if ((var_val = switch_event_get_header(var_event, "originate_retries")) && switch_true(var_val)) { 02193 int32_t tmp; 02194 tmp = atoi(var_val); 02195 if (tmp > 0 && tmp < 101) { 02196 retries = tmp; 02197 } else { 02198 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, 02199 "Invalid originate_retries setting of %d ignored, value must be between 1 and 100\n", tmp); 02200 } 02201 } 02202 02203 if ((var_val = switch_event_get_header(var_event, "originate_retry_sleep_ms")) && switch_true(var_val)) { 02204 int32_t tmp; 02205 tmp = atoi(var_val); 02206 if (tmp >= 500 && tmp <= 60000) { 02207 sleep_ms = tmp; 02208 } else { 02209 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, 02210 "Invalid originate_retry_sleep_ms setting of %d ignored, value must be between 500 and 60000\n", tmp); 02211 } 02212 } 02213 02214 if ((cid_tmp = switch_event_get_header(var_event, "origination_caller_id_name"))) { 02215 cid_name_override = cid_tmp; 02216 } 02217 02218 if (cid_name_override) { 02219 if (!cid_tmp) { 02220 switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "origination_caller_id_name", cid_name_override); 02221 } 02222 } else { 02223 cid_name_override = switch_event_get_header(var_event, "origination_caller_id_name"); 02224 } 02225 02226 if ((cid_tmp = switch_event_get_header(var_event, "origination_caller_id_number"))) { 02227 cid_num_override = cid_tmp; 02228 } 02229 02230 if (cid_num_override) { 02231 if (!cid_tmp) { 02232 switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "origination_caller_id_number", cid_num_override); 02233 } 02234 } else { 02235 cid_num_override = switch_event_get_header(var_event, "origination_caller_id_number"); 02236 } 02237 02238 if (flags & SOF_NO_LIMITS) { 02239 dftflags |= SOF_NO_LIMITS; 02240 } 02241 02242 if (cid_num_override) { 02243 dftflags |= SOF_NO_EFFECTIVE_CID_NUM; 02244 } 02245 02246 if (cid_name_override) { 02247 dftflags |= SOF_NO_EFFECTIVE_CID_NAME; 02248 } 02249 02250 if (!progress_timelimit_sec) { 02251 progress_timelimit_sec = timelimit_sec; 02252 } 02253 02254 for (try = 0; try < retries; try++) { 02255 switch_safe_free(loop_data); 02256 loop_data = strdup(data); 02257 switch_assert(loop_data); 02258 or_argc = switch_separate_string(loop_data, '|', pipe_names, (sizeof(pipe_names) / sizeof(pipe_names[0]))); 02259 02260 if ((flags & SOF_NOBLOCK) && or_argc > 1) { 02261 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Only calling the first element in the list in this mode.\n"); 02262 or_argc = 1; 02263 } 02264 02265 for (r = 0; r < or_argc; r++) { 02266 char *p, *end = NULL; 02267 int q = 0, alt = 0; 02268 02269 check_reject = 1; 02270 02271 oglobals.hups = 0; 02272 02273 reason = SWITCH_CAUSE_NONE; 02274 memset(peer_names, 0, sizeof(peer_names)); 02275 peer_session = NULL; 02276 memset(originate_status, 0, sizeof(originate_status)); 02277 new_profile = NULL; 02278 new_session = NULL; 02279 chan_type = NULL; 02280 chan_data = NULL; 02281 peer_channel = NULL; 02282 start = 0; 02283 read_frame = NULL; 02284 oglobals.ringback_ok = 1; 02285 var = NULL; 02286 to = 0; 02287 oglobals.sent_ring = 0; 02288 oglobals.progress = 0; 02289 myflags = dftflags; 02290 02291 02292 if (try > 0) { 02293 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Originate attempt %d/%d in %d ms\n", try + 1, retries, 02294 sleep_ms); 02295 if (caller_channel) { 02296 switch_ivr_sleep(oglobals.session, sleep_ms, SWITCH_TRUE, NULL); 02297 if (!switch_channel_ready(caller_channel)) { 02298 status = SWITCH_STATUS_FALSE; 02299 goto done; 02300 } 02301 } else { 02302 switch_yield(sleep_ms * 1000); 02303 } 02304 } 02305 02306 p = pipe_names[r]; 02307 02308 while (p && *p) { 02309 if (*p == '[') { 02310 end = switch_find_end_paren(p, '[', ']'); 02311 if (*(p+1) == '^' && *(p + 2) == '^') { 02312 alt = 1; 02313 } else { 02314 alt = 0; 02315 } 02316 q = 0; 02317 } 02318 02319 if (*p == '\'') { 02320 q = !q; 02321 } 02322 02323 if (end && p < end && *p == ',') { 02324 02325 if (q || alt) { 02326 *p = QUOTED_ESC_COMMA; 02327 } else { 02328 *p = UNQUOTED_ESC_COMMA; 02329 } 02330 } 02331 02332 if (p == end) { 02333 end = switch_strchr_strict(p, '[', " "); 02334 } 02335 02336 p++; 02337 } 02338 02339 and_argc = switch_separate_string(pipe_names[r], ',', peer_names, (sizeof(peer_names) / sizeof(peer_names[0]))); 02340 02341 if ((flags & SOF_NOBLOCK) && and_argc > 1) { 02342 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Only calling the first element in the list in this mode.\n"); 02343 and_argc = 1; 02344 } 02345 02346 for (i = 0; i < and_argc; i++) { 02347 const char *current_variable; 02348 switch_event_t *local_var_event = NULL, *originate_var_event = NULL, *event = NULL; 02349 02350 end = NULL; 02351 02352 chan_type = peer_names[i]; 02353 02354 02355 /* strip leading spaces */ 02356 while (chan_type && *chan_type && *chan_type == ' ') { 02357 chan_type++; 02358 } 02359 02360 /* extract channel variables, allowing multiple sets of braces */ 02361 02362 if (*chan_type == '[') { 02363 switch_event_create_plain(&local_var_event, SWITCH_EVENT_CHANNEL_DATA); 02364 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Parsing session specific variables\n"); 02365 } 02366 02367 while (*chan_type == '[') { 02368 char *parsed = NULL; 02369 02370 for (p = chan_type; p && *p && *p != ']'; p++) { 02371 if (*p == QUOTED_ESC_COMMA) { 02372 *p = ','; 02373 } 02374 } 02375 02376 if (switch_event_create_brackets(chan_type, '[', ']', UNQUOTED_ESC_COMMA, 02377 &local_var_event, &parsed, SWITCH_FALSE) != SWITCH_STATUS_SUCCESS || !parsed) { 02378 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Parse Error!\n"); 02379 switch_goto_status(SWITCH_STATUS_GENERR, done); 02380 } 02381 02382 chan_type = parsed; 02383 } 02384 02385 02386 /* strip leading spaces (again) */ 02387 while (chan_type && *chan_type && *chan_type == ' ') { 02388 chan_type++; 02389 } 02390 02391 if ((chan_data = strchr(chan_type, '/')) != 0) { 02392 *chan_data = '\0'; 02393 chan_data++; 02394 } 02395 02396 if (oglobals.session) { 02397 if (!switch_channel_ready(caller_channel)) { 02398 status = SWITCH_STATUS_FALSE; 02399 goto done; 02400 } 02401 02402 if ((caller_caller_profile = oglobals.caller_profile_override)) { 02403 new_profile = switch_caller_profile_dup(oglobals.pool, caller_caller_profile); 02404 } else { 02405 new_profile = switch_caller_profile_new(oglobals.pool, 02406 NULL, 02407 NULL, 02408 cid_name_override, cid_num_override, NULL, NULL, NULL, NULL, __FILE__, NULL, chan_data); 02409 } 02410 02411 new_profile->uuid = SWITCH_BLANK_STRING; 02412 new_profile->chan_name = SWITCH_BLANK_STRING; 02413 new_profile->destination_number = switch_core_strdup(new_profile->pool, chan_data); 02414 02415 if (cid_name_override) { 02416 new_profile->caller_id_name = switch_core_strdup(new_profile->pool, cid_name_override); 02417 } 02418 if (cid_num_override) { 02419 new_profile->caller_id_number = switch_core_strdup(new_profile->pool, cid_num_override); 02420 } 02421 } else { 02422 if (oglobals.caller_profile_override) { 02423 new_profile = switch_caller_profile_dup(oglobals.pool, oglobals.caller_profile_override); 02424 new_profile->destination_number = switch_core_strdup(new_profile->pool, switch_str_nil(chan_data)); 02425 new_profile->uuid = SWITCH_BLANK_STRING; 02426 new_profile->chan_name = SWITCH_BLANK_STRING; 02427 } else { 02428 if (!cid_name_override) { 02429 cid_name_override = SWITCH_DEFAULT_CLID_NAME; 02430 } 02431 if (!cid_num_override) { 02432 cid_num_override = "0000000000"; 02433 } 02434 02435 new_profile = switch_caller_profile_new(oglobals.pool, 02436 NULL, 02437 NULL, 02438 cid_name_override, cid_num_override, NULL, NULL, NULL, NULL, __FILE__, NULL, chan_data); 02439 } 02440 } 02441 02442 if (zstr(new_profile->destination_number)) { 02443 new_profile->destination_number = switch_core_strdup(new_profile->pool, "service"); 02444 } 02445 02446 new_profile->callee_id_name = switch_core_strdup(new_profile->pool, "Outbound Call"); 02447 new_profile->callee_id_number = switch_sanitize_number(switch_core_strdup(new_profile->pool, new_profile->destination_number)); 02448 02449 originate_status[i].caller_profile = NULL; 02450 originate_status[i].peer_channel = NULL; 02451 originate_status[i].peer_session = NULL; 02452 new_session = NULL; 02453 02454 if (and_argc > 1 || or_argc > 1) { 02455 myflags |= SOF_FORKED_DIAL; 02456 } 02457 02458 if (var_event) { 02459 const char *vvar; 02460 if ((vvar = switch_event_get_header(var_event, "forked_dial")) && switch_true(vvar)) { 02461 myflags |= SOF_FORKED_DIAL; 02462 } 02463 if ((vvar = switch_event_get_header(var_event, "no_throttle_limits")) && switch_true(vvar)) { 02464 myflags |= SOF_NO_LIMITS; 02465 } 02466 } 02467 02468 02469 /* Valid in both {} and [] with [] taking precedence */ 02470 02471 /* make a special var event with mixture of the {} and the [] vars to pass down as global vars to the outgoing channel 02472 so if something like the user channel does another originate our options will be passed down properly 02473 */ 02474 02475 switch_event_dup(&originate_var_event, var_event); 02476 02477 if (local_var_event) { 02478 switch_event_merge(originate_var_event, local_var_event); 02479 } 02480 02481 if ((current_variable = switch_event_get_header(originate_var_event, "origination_caller_id_number"))) { 02482 new_profile->caller_id_number = switch_core_strdup(new_profile->pool, current_variable); 02483 myflags |= SOF_NO_EFFECTIVE_CID_NUM; 02484 } 02485 02486 if ((current_variable = switch_event_get_header(originate_var_event, "origination_caller_id_name"))) { 02487 new_profile->caller_id_name = switch_core_strdup(new_profile->pool, current_variable); 02488 myflags |= SOF_NO_EFFECTIVE_CID_NAME; 02489 } 02490 02491 if ((current_variable = switch_event_get_header(originate_var_event, "origination_privacy"))) { 02492 new_profile->flags = SWITCH_CPF_NONE; 02493 02494 if (switch_stristr("screen", current_variable)) { 02495 switch_set_flag(new_profile, SWITCH_CPF_SCREEN); 02496 } 02497 02498 if (switch_stristr("hide_name", current_variable)) { 02499 switch_set_flag(new_profile, SWITCH_CPF_HIDE_NAME); 02500 } 02501 02502 if (switch_stristr("hide_number", current_variable)) { 02503 switch_set_flag(new_profile, SWITCH_CPF_HIDE_NUMBER); 02504 } 02505 } 02506 02507 switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "originate_early_media", oglobals.early_ok ? "true" : "false"); 02508 02509 02510 if (caller_channel && switch_true(switch_channel_get_variable(caller_channel, "push_channel_name"))) { 02511 char *new_name = switch_core_session_sprintf(session, "%s__B", switch_channel_get_name(caller_channel)); 02512 switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "origination_channel_name", new_name); 02513 new_name = switch_core_session_sprintf(session, "_%s", switch_channel_get_name(caller_channel)); 02514 switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "sip_h_X-FS-Channel-Name", new_name); 02515 } 02516 02517 02518 reason = switch_core_session_outgoing_channel(oglobals.session, originate_var_event, chan_type, 02519 new_profile, &new_session, NULL, myflags, cancel_cause); 02520 02521 switch_event_destroy(&originate_var_event); 02522 02523 if (reason != SWITCH_CAUSE_SUCCESS) { 02524 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Cannot create outgoing channel of type [%s] cause: [%s]\n", 02525 chan_type, switch_channel_cause2str(reason)); 02526 if (local_var_event) switch_event_destroy(&local_var_event); 02527 02528 if (fail_on_single_reject_var) { 02529 const char *cause_str = switch_channel_cause2str(reason); 02530 int neg = *fail_on_single_reject_var == '!'; 02531 int pos = !!switch_stristr(cause_str, fail_on_single_reject_var); 02532 02533 if (neg) { 02534 pos = !pos; 02535 } 02536 02537 check_reject = 0; 02538 02539 if (fail_on_single_reject == 1 || pos) { 02540 force_reason = reason; 02541 status = SWITCH_STATUS_FALSE; 02542 goto outer_for; 02543 } 02544 } 02545 continue; 02546 } 02547 02548 if (switch_core_session_read_lock(new_session) != SWITCH_STATUS_SUCCESS) { 02549 status = SWITCH_STATUS_FALSE; 02550 if (local_var_event) switch_event_destroy(&local_var_event); 02551 goto done; 02552 } 02553 02554 originate_status[i].peer_channel = switch_core_session_get_channel(new_session); 02555 originate_status[i].caller_profile = switch_channel_get_caller_profile(originate_status[i].peer_channel); 02556 originate_status[i].peer_session = new_session; 02557 02558 switch_channel_set_flag(originate_status[i].peer_channel, CF_ORIGINATING); 02559 02560 if (caller_channel) { 02561 switch_channel_set_variable(originate_status[i].peer_channel, "call_uuid", switch_channel_get_variable(caller_channel, "call_uuid")); 02562 } 02563 02564 02565 if ((lc = switch_event_get_header(var_event, "local_var_clobber"))) { 02566 local_clobber = switch_true(lc); 02567 } 02568 02569 if (local_clobber) { 02570 if (var_event) { 02571 switch_event_header_t *header; 02572 /* install the vars from the {} params */ 02573 for (header = var_event->headers; header; header = header->next) { 02574 switch_channel_set_variable_var_check(originate_status[i].peer_channel, header->name, header->value, oglobals.check_vars); 02575 } 02576 } 02577 } 02578 02579 /* copy local originate vars to the channel */ 02580 if (local_var_event) { 02581 switch_event_header_t *header; 02582 for (header = local_var_event->headers; header; header = header->next) { 02583 switch_channel_set_variable_var_check(originate_status[i].peer_channel, header->name, header->value, oglobals.check_vars); 02584 } 02585 switch_event_destroy(&local_var_event); 02586 } 02587 02588 if (!local_clobber) { 02589 if (var_event) { 02590 switch_event_header_t *header; 02591 /* install the vars from the {} params */ 02592 for (header = var_event->headers; header; header = header->next) { 02593 switch_channel_set_variable_var_check(originate_status[i].peer_channel, header->name, header->value, oglobals.check_vars); 02594 } 02595 } 02596 } 02597 02598 switch_event_create(&event, SWITCH_EVENT_CHANNEL_ORIGINATE); 02599 switch_assert(event); 02600 switch_channel_event_set_data(originate_status[i].peer_channel, event); 02601 switch_event_fire(&event); 02602 02603 if (originate_status[i].peer_channel) { 02604 const char *vvar; 02605 02606 if (switch_true(switch_channel_get_variable(originate_status[i].peer_channel, "leg_required"))) { 02607 originate_status[i].tagged = 1; 02608 } 02609 02610 if ((vvar = switch_channel_get_variable(originate_status[i].peer_channel, "origination_channel_name"))) { 02611 switch_channel_set_name(originate_status[i].peer_channel, vvar); 02612 } 02613 02614 if ((vvar = switch_channel_get_variable(originate_status[i].peer_channel, "origination_callee_id_name"))) { 02615 switch_channel_set_profile_var(originate_status[i].peer_channel, "callee_id_name", vvar); 02616 } 02617 02618 if ((vvar = switch_channel_get_variable(originate_status[i].peer_channel, "origination_callee_id_number"))) { 02619 switch_channel_set_profile_var(originate_status[i].peer_channel, "callee_id_number", vvar); 02620 } 02621 02622 if ((vvar = switch_channel_get_variable(originate_status[i].peer_channel, "leg_timeout"))) { 02623 int val = atoi(vvar); 02624 02625 if (val > 0) { 02626 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Setting leg timeout to %d\n", 02627 switch_channel_get_name(originate_status[i].peer_channel), val); 02628 originate_status[i].per_channel_timelimit_sec = (uint32_t) val; 02629 } 02630 } 02631 02632 if ((vvar = switch_channel_get_variable(originate_status[i].peer_channel, "leg_progress_timeout"))) { 02633 int val = atoi(vvar); 02634 if (val > 0) { 02635 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Setting leg progress timeout to %d\n", 02636 switch_channel_get_name(originate_status[i].peer_channel), val); 02637 originate_status[i].per_channel_progress_timelimit_sec = (uint32_t) val; 02638 } 02639 } 02640 02641 if ((vvar = switch_channel_get_variable(originate_status[i].peer_channel, "leg_delay_start"))) { 02642 int val = atoi(vvar); 02643 if (val > 0) { 02644 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Setting leg delay start to %d\n", 02645 switch_channel_get_name(originate_status[i].peer_channel), val); 02646 originate_status[i].per_channel_delay_start = (uint32_t) val; 02647 02648 if (originate_status[i].per_channel_progress_timelimit_sec != 0) { 02649 originate_status[i].per_channel_progress_timelimit_sec += originate_status[i].per_channel_delay_start; 02650 } 02651 02652 if (originate_status[i].per_channel_timelimit_sec != 0) { 02653 originate_status[i].per_channel_timelimit_sec += originate_status[i].per_channel_delay_start; 02654 } 02655 } 02656 } 02657 02658 if (session) { 02659 switch_channel_set_variable(originate_status[i].peer_channel, "originating_leg_uuid", switch_core_session_get_uuid(session)); 02660 } 02661 02662 switch_channel_execute_on(originate_status[i].peer_channel, SWITCH_CHANNEL_EXECUTE_ON_ORIGINATE_VARIABLE); 02663 switch_channel_api_on(originate_status[i].peer_channel, SWITCH_CHANNEL_API_ON_ORIGINATE_VARIABLE); 02664 } 02665 02666 if (table) { 02667 switch_channel_add_state_handler(originate_status[i].peer_channel, table); 02668 } 02669 02670 if (oglobals.monitor_early_media_ring || oglobals.monitor_early_media_fail) { 02671 switch_channel_set_flag(originate_status[i].peer_channel, CF_CONSUME_ON_ORIGINATE); 02672 } 02673 02674 switch_channel_add_state_handler(originate_status[i].peer_channel, &originate_state_handlers); 02675 02676 if ((flags & SOF_NOBLOCK) && originate_status[i].peer_session) { 02677 status = SWITCH_STATUS_SUCCESS; 02678 *bleg = originate_status[i].peer_session; 02679 *cause = SWITCH_CAUSE_SUCCESS; 02680 goto outer_for; 02681 } 02682 02683 if (!switch_core_session_running(originate_status[i].peer_session)) { 02684 if (originate_status[i].per_channel_delay_start) { 02685 switch_channel_set_flag(originate_status[i].peer_channel, CF_BLOCK_STATE); 02686 } 02687 switch_core_session_thread_launch(originate_status[i].peer_session); 02688 } 02689 } 02690 02691 switch_epoch_time_now(&start); 02692 02693 for (;;) { 02694 uint32_t valid_channels = 0; 02695 for (i = 0; i < and_argc; i++) { 02696 int state; 02697 time_t elapsed; 02698 02699 if (!originate_status[i].peer_channel) { 02700 continue; 02701 } 02702 02703 state = switch_channel_get_state(originate_status[i].peer_channel); 02704 02705 if (state < CS_HANGUP) { 02706 valid_channels++; 02707 } else { 02708 continue; 02709 } 02710 02711 if (state >= CS_ROUTING) { 02712 goto endfor1; 02713 } 02714 02715 if (caller_channel && !switch_channel_ready(caller_channel)) { 02716 goto notready; 02717 } 02718 02719 elapsed = switch_epoch_time_now(NULL) - start; 02720 02721 if (elapsed > (time_t) timelimit_sec) { 02722 to++; 02723 oglobals.idx = IDX_TIMEOUT; 02724 goto notready; 02725 } 02726 02727 if (!oglobals.sent_ring && !oglobals.ignore_ring_ready && 02728 !oglobals.progress && (progress_timelimit_sec && elapsed > (time_t) progress_timelimit_sec)) { 02729 to++; 02730 oglobals.idx = IDX_TIMEOUT; 02731 if (force_reason == SWITCH_CAUSE_NONE) { 02732 force_reason = SWITCH_CAUSE_PROGRESS_TIMEOUT; 02733 } 02734 goto notready; 02735 } 02736 02737 switch_cond_next(); 02738 } 02739 02740 check_per_channel_timeouts(&oglobals, originate_status, and_argc, start, &force_reason); 02741 02742 02743 if (valid_channels == 0) { 02744 status = SWITCH_STATUS_GENERR; 02745 goto done; 02746 } 02747 02748 } 02749 02750 endfor1: 02751 02752 if (caller_channel) { 02753 if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE) || 02754 switch_channel_test_flag(caller_channel, CF_PROXY_MEDIA) || switch_channel_test_flag(caller_channel, CF_DISABLE_RINGBACK)) { 02755 ringback_data = NULL; 02756 } 02757 } 02758 02759 02760 #if 0 02761 /* changing behaviour ignore_early_media=true must also be explicitly set for previous behaviour */ 02762 if (ringback_data) { 02763 oglobals.early_ok = 0; 02764 } 02765 #endif 02766 02767 if (ringback_data) { 02768 oglobals.sending_ringback = 1; 02769 } else { 02770 oglobals.ringback_ok = 0; 02771 } 02772 02773 if (caller_channel) { 02774 soft_holding = switch_channel_get_variable(caller_channel, SWITCH_SOFT_HOLDING_UUID_VARIABLE); 02775 } 02776 02777 while ((!caller_channel || switch_channel_ready(caller_channel) || switch_channel_test_flag(caller_channel, CF_XFER_ZOMBIE)) && 02778 check_channel_status(&oglobals, originate_status, and_argc)) { 02779 time_t elapsed = switch_epoch_time_now(NULL) - start; 02780 02781 read_packet = 0; 02782 02783 if (cancel_cause && *cancel_cause > 0) { 02784 if (force_reason == SWITCH_CAUSE_NONE) { 02785 force_reason = *cancel_cause; 02786 } 02787 oglobals.idx = IDX_CANCEL; 02788 goto notready; 02789 } 02790 02791 check_per_channel_timeouts(&oglobals, originate_status, and_argc, start, &force_reason); 02792 02793 if (oglobals.session) { 02794 switch_ivr_parse_all_events(oglobals.session); 02795 } 02796 02797 if (!oglobals.sent_ring && !oglobals.progress && (progress_timelimit_sec && elapsed > (time_t) progress_timelimit_sec)) { 02798 oglobals.idx = IDX_TIMEOUT; 02799 if (force_reason == SWITCH_CAUSE_NONE) { 02800 force_reason = SWITCH_CAUSE_PROGRESS_TIMEOUT; 02801 } 02802 goto notready; 02803 } 02804 02805 if ((to = (uint8_t) (elapsed >= (time_t) timelimit_sec)) || (fail_on_single_reject && oglobals.hups)) { 02806 int ok = 0; 02807 02808 if (fail_on_single_reject_var) { 02809 if (!switch_true(fail_on_single_reject_var)) { 02810 ok = 1; 02811 02812 for (i = 0; i < and_argc; i++) { 02813 switch_channel_t *pchannel; 02814 const char *cause_str; 02815 02816 if (!originate_status[i].peer_session) { 02817 continue; 02818 } 02819 pchannel = switch_core_session_get_channel(originate_status[i].peer_session); 02820 02821 if (switch_channel_down_nosig(pchannel)) { 02822 int neg, pos; 02823 cause_str = switch_channel_cause2str(switch_channel_get_cause(pchannel)); 02824 neg = *fail_on_single_reject_var == '!'; 02825 pos = !!switch_stristr(cause_str, fail_on_single_reject_var); 02826 02827 if (neg) { 02828 pos = !pos; 02829 } 02830 02831 if (pos) { 02832 ok = 0; 02833 break; 02834 } 02835 } 02836 } 02837 } 02838 } 02839 if (!ok) { 02840 oglobals.idx = IDX_TIMEOUT; 02841 goto notready; 02842 } 02843 } 02844 02845 /* read from the channel while we wait if the audio is up on it */ 02846 if (oglobals.session && 02847 !switch_channel_test_flag(caller_channel, CF_PROXY_MODE) && 02848 !switch_channel_test_flag(caller_channel, CF_PROXY_MEDIA) && 02849 !switch_channel_test_flag(caller_channel, CF_XFER_ZOMBIE) && 02850 (oglobals.ringback_ok 02851 || (switch_channel_test_flag(caller_channel, CF_ANSWERED) || switch_channel_test_flag(caller_channel, CF_EARLY_MEDIA)))) { 02852 02853 switch_status_t tstatus = SWITCH_STATUS_SUCCESS; 02854 int silence = 0; 02855 02856 if (caller_channel && cancel_key) { 02857 if (switch_channel_has_dtmf(caller_channel)) { 02858 switch_dtmf_t dtmf = { 0, 0 }; 02859 if (switch_channel_dequeue_dtmf(caller_channel, &dtmf) == SWITCH_STATUS_SUCCESS) { 02860 if (dtmf.digit == *cancel_key) { 02861 oglobals.idx = IDX_KEY_CANCEL; 02862 goto notready; 02863 } 02864 } 02865 } 02866 } 02867 02868 if (switch_channel_media_ready(caller_channel)) { 02869 tstatus = switch_core_session_read_frame(oglobals.session, &read_frame, SWITCH_IO_FLAG_NONE, 0); 02870 if (!SWITCH_READ_ACCEPTABLE(tstatus)) { 02871 if (soft_holding) { 02872 switch_channel_set_flag(caller_channel, CF_XFER_ZOMBIE); 02873 } 02874 02875 if (switch_channel_test_flag(caller_channel, CF_XFER_ZOMBIE)) { 02876 goto do_continue; 02877 } 02878 break; 02879 } 02880 02881 read_packet++; 02882 } else { 02883 read_frame = NULL; 02884 } 02885 02886 02887 if (oglobals.ringback_ok && (oglobals.ring_ready || oglobals.instant_ringback || 02888 oglobals.sending_ringback > 1 || oglobals.bridge_early_media > -1)) { 02889 if (oglobals.ringback_ok == 1) { 02890 switch_status_t rst; 02891 02892 rst = setup_ringback(&oglobals, originate_status, and_argc, ringback_data, &ringback, &write_frame, &write_codec); 02893 02894 if (oglobals.bridge_early_media > -1) { 02895 switch_threadattr_t *thd_attr = NULL; 02896 switch_threadattr_create(&thd_attr, switch_core_session_get_pool(session)); 02897 switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); 02898 early_state.oglobals = &oglobals; 02899 early_state.originate_status = originate_status; 02900 early_state.ready = 1; 02901 early_state.ringback = &ringback; 02902 switch_mutex_init(&early_state.mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); 02903 switch_buffer_create_dynamic(&early_state.buffer, 1024, 1024, 0); 02904 switch_thread_create(&oglobals.ethread, thd_attr, early_thread_run, &early_state, switch_core_session_get_pool(session)); 02905 } 02906 02907 02908 switch (rst) { 02909 case SWITCH_STATUS_SUCCESS: 02910 oglobals.ringback_ok++; 02911 break; 02912 case SWITCH_STATUS_FALSE: 02913 goto notready; 02914 break; 02915 case SWITCH_STATUS_BREAK: 02916 goto done; 02917 break; 02918 default: 02919 ringback_data = NULL; 02920 oglobals.ringback_ok = 0; 02921 oglobals.sending_ringback = 0; 02922 break; 02923 } 02924 02925 goto do_continue; 02926 } 02927 02928 if (oglobals.bridge_early_media > -1) { 02929 write_frame.datalen = 0; 02930 switch_mutex_lock(early_state.mutex); 02931 if (ringback.asis) { 02932 uint16_t mlen; 02933 switch_size_t buflen = switch_buffer_inuse(early_state.buffer); 02934 if (buflen > sizeof(uint16_t)) { 02935 switch_buffer_peek(early_state.buffer, &mlen, sizeof(uint16_t)); 02936 if (buflen >= (mlen + sizeof(uint16_t))) { 02937 switch_buffer_toss(early_state.buffer, sizeof(uint16_t)); 02938 write_frame.datalen = switch_buffer_read(early_state.buffer, write_frame.data, mlen); 02939 } 02940 } 02941 } else { 02942 if (switch_buffer_inuse(early_state.buffer) >= write_frame.codec->implementation->decoded_bytes_per_packet) { 02943 write_frame.datalen = switch_buffer_read(early_state.buffer, write_frame.data, 02944 write_frame.codec->implementation->decoded_bytes_per_packet); 02945 } 02946 } 02947 switch_mutex_unlock(early_state.mutex); 02948 } else if (ringback.fh) { 02949 switch_size_t mlen, olen; 02950 unsigned int pos = 0; 02951 02952 if (ringback.asis) { 02953 mlen = write_frame.codec->implementation->encoded_bytes_per_packet; 02954 } else { 02955 mlen = write_frame.codec->implementation->samples_per_packet; 02956 } 02957 02958 olen = mlen; 02959 02960 //if (ringback.fh->resampler && ringback.fh->resampler->rfactor > 1) { 02961 //olen = (switch_size_t) (olen * ringback.fh->resampler->rfactor); 02962 //} 02963 02964 switch_core_file_read(ringback.fh, write_frame.data, &olen); 02965 02966 if (olen == 0) { 02967 olen = mlen; 02968 ringback.fh->speed = 0; 02969 switch_core_file_seek(ringback.fh, &pos, 0, SEEK_SET); 02970 switch_core_file_read(ringback.fh, write_frame.data, &olen); 02971 if (olen == 0) { 02972 break; 02973 } 02974 } 02975 write_frame.datalen = (uint32_t) (ringback.asis ? olen : olen * 2); 02976 } else if (ringback.audio_buffer) { 02977 if ((write_frame.datalen = (uint32_t) switch_buffer_read_loop(ringback.audio_buffer, 02978 write_frame.data, 02979 write_frame.codec->implementation->decoded_bytes_per_packet)) <= 02980 0) { 02981 02982 if (soft_holding) { 02983 switch_channel_set_flag(caller_channel, CF_XFER_ZOMBIE); 02984 goto do_continue; 02985 } 02986 02987 break; 02988 } 02989 } else if (ringback.silence) { 02990 silence = ringback.silence; 02991 } 02992 } else { 02993 silence = 600; 02994 } 02995 02996 if ((ringback.fh || silence || ringback.audio_buffer || oglobals.bridge_early_media > -1) && write_frame.codec && write_frame.datalen) { 02997 if (silence) { 02998 write_frame.datalen = read_impl.decoded_bytes_per_packet; 02999 switch_generate_sln_silence((int16_t *) write_frame.data, write_frame.datalen / 2, silence); 03000 } 03001 03002 if (switch_core_session_write_frame(oglobals.session, &write_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) { 03003 if (soft_holding) { 03004 switch_channel_set_flag(caller_channel, CF_XFER_ZOMBIE); 03005 } 03006 if (switch_channel_test_flag(caller_channel, CF_XFER_ZOMBIE)) { 03007 goto do_continue; 03008 } 03009 break; 03010 } 03011 } 03012 03013 } 03014 03015 do_continue: 03016 03017 if (!read_packet) { 03018 switch_cond_next(); 03019 } 03020 } 03021 03022 notready: 03023 03024 if (caller_channel) { 03025 holding = switch_channel_get_variable(caller_channel, SWITCH_HOLDING_UUID_VARIABLE); 03026 switch_channel_set_variable(caller_channel, SWITCH_HOLDING_UUID_VARIABLE, NULL); 03027 03028 if (soft_holding && switch_channel_test_flag(caller_channel, CF_XFER_ZOMBIE)) { 03029 holding = soft_holding; 03030 soft_holding = NULL; 03031 switch_channel_set_variable(caller_channel, SWITCH_SOFT_HOLDING_UUID_VARIABLE, NULL); 03032 } 03033 } 03034 03035 if (caller_channel && !switch_channel_ready(caller_channel) && !switch_channel_test_flag(caller_channel, CF_XFER_ZOMBIE)) { 03036 oglobals.idx = IDX_CANCEL; 03037 } 03038 03039 if (oglobals.session && (ringback_data || !(switch_channel_test_flag(caller_channel, CF_PROXY_MODE) || 03040 switch_channel_test_flag(caller_channel, CF_PROXY_MEDIA)))) { 03041 switch_core_session_reset(oglobals.session, SWITCH_FALSE, SWITCH_TRUE); 03042 } 03043 03044 if (holding) { 03045 if (oglobals.idx > IDX_NADA) { 03046 peer_session = originate_status[oglobals.idx].peer_session; 03047 peer_channel = originate_status[oglobals.idx].peer_channel; 03048 originate_status[oglobals.idx].peer_channel = NULL; 03049 } else if (and_argc == 1) { 03050 peer_session = originate_status[0].peer_session; 03051 peer_channel = originate_status[0].peer_channel; 03052 originate_status[0].peer_channel = NULL; 03053 } else { 03054 for (i = 0; i < and_argc; i++) { 03055 if (!peer_eligible(originate_status[i].peer_channel)) { 03056 continue; 03057 } 03058 if (switch_channel_media_ready(originate_status[i].peer_channel)) { 03059 peer_session = originate_status[i].peer_session; 03060 peer_channel = originate_status[i].peer_channel; 03061 originate_status[i].peer_channel = NULL; 03062 goto end_search; 03063 } 03064 } 03065 for (i = 0; i < and_argc; i++) { 03066 if (!peer_eligible(originate_status[i].peer_channel)) { 03067 continue; 03068 } 03069 if (switch_channel_up_nosig(originate_status[i].peer_channel)) { 03070 peer_session = originate_status[i].peer_session; 03071 peer_channel = originate_status[i].peer_channel; 03072 originate_status[i].peer_channel = NULL; 03073 break; 03074 } 03075 } 03076 } 03077 03078 end_search: 03079 03080 if (peer_channel && switch_channel_down_nosig(peer_channel)) { 03081 switch_core_session_rwunlock(peer_session); 03082 peer_session = NULL; 03083 peer_channel = NULL; 03084 03085 } 03086 03087 if (oglobals.idx == IDX_TIMEOUT || to || oglobals.idx == IDX_KEY_CANCEL || oglobals.idx == IDX_CANCEL || 03088 (!peer_session && oglobals.idx == IDX_NADA)) { 03089 const char *dest = NULL; 03090 const char *context = NULL; 03091 const char *dialplan = NULL; 03092 switch_core_session_t *holding_session; 03093 03094 if (caller_channel) { 03095 if (zstr(context)) { 03096 context = switch_channel_get_variable(caller_channel, "context"); 03097 } 03098 if (zstr(dialplan)) { 03099 dialplan = switch_channel_get_variable(caller_channel, "dialplan"); 03100 } 03101 } 03102 03103 if (zstr(context)) { 03104 context = "default"; 03105 } 03106 03107 if (zstr(context)) { 03108 dialplan = "XML"; 03109 } 03110 03111 if ((holding_session = switch_core_session_locate(holding))) { 03112 switch_channel_t *holding_channel = switch_core_session_get_channel(holding_session); 03113 switch_status_t mstatus = SWITCH_STATUS_FALSE; 03114 03115 if (caller_channel) { 03116 if ((mstatus = switch_channel_caller_extension_masquerade(caller_channel, holding_channel, 0)) == SWITCH_STATUS_SUCCESS) { 03117 switch_channel_restart(holding_channel); 03118 } 03119 } 03120 03121 if (mstatus != SWITCH_STATUS_SUCCESS) { 03122 if (peer_channel) { 03123 dest = switch_channel_get_variable(peer_channel, "destination_number"); 03124 context = switch_channel_get_variable(peer_channel, "context"); 03125 dialplan = switch_channel_get_variable(peer_channel, "dialplan"); 03126 } else if (caller_channel) { 03127 dest = switch_channel_get_variable(caller_channel, "destination_number"); 03128 } 03129 if (dest) { 03130 switch_ivr_session_transfer(holding_session, dest, dialplan, context); 03131 } 03132 } 03133 03134 switch_core_session_rwunlock(holding_session); 03135 holding = NULL; 03136 holding_session = NULL; 03137 } 03138 03139 if (peer_channel) { 03140 switch_channel_hangup(peer_channel, SWITCH_CAUSE_ATTENDED_TRANSFER); 03141 switch_core_session_rwunlock(peer_session); 03142 } 03143 if (force_reason == SWITCH_CAUSE_NONE) { 03144 force_reason = SWITCH_CAUSE_ATTENDED_TRANSFER; 03145 } 03146 } else if (zstr(soft_holding)) { 03147 03148 if (peer_channel && switch_channel_ready(peer_channel)) { 03149 switch_core_session_t *holding_session; 03150 03151 if (force_reason == SWITCH_CAUSE_NONE) { 03152 force_reason = SWITCH_CAUSE_ATTENDED_TRANSFER; 03153 } 03154 03155 if ((holding_session = switch_core_session_locate(holding))) { 03156 switch_channel_set_variable(switch_core_session_get_channel(holding_session), SWITCH_HANGUP_AFTER_BRIDGE_VARIABLE, "true"); 03157 switch_core_session_rwunlock(holding_session); 03158 } 03159 switch_channel_set_flag(peer_channel, CF_LAZY_ATTENDED_TRANSFER); 03160 switch_ivr_uuid_bridge(holding, switch_core_session_get_uuid(peer_session)); 03161 holding = NULL; 03162 oglobals.idx = IDX_NADA; 03163 if (caller_channel && switch_channel_up_nosig(caller_channel) && !switch_channel_test_flag(caller_channel, CF_INTERCEPTED)) { 03164 switch_channel_hangup(caller_channel, SWITCH_CAUSE_ATTENDED_TRANSFER); 03165 } 03166 caller_channel = NULL; 03167 oglobals.session = NULL; 03168 session = NULL; 03169 switch_core_session_rwunlock(peer_session); 03170 } else { 03171 switch_core_session_t *holding_session; 03172 03173 if ((holding_session = switch_core_session_locate(holding))) { 03174 switch_channel_t *holding_channel = switch_core_session_get_channel(holding_session); 03175 03176 if (caller_channel && switch_channel_ready(caller_channel)) { 03177 switch_channel_set_variable(holding_channel, SWITCH_HANGUP_AFTER_BRIDGE_VARIABLE, "true"); 03178 switch_ivr_uuid_bridge(holding, switch_core_session_get_uuid(session)); 03179 holding = NULL; 03180 } else { 03181 switch_channel_hangup(holding_channel, SWITCH_CAUSE_NORMAL_UNSPECIFIED); 03182 } 03183 switch_core_session_rwunlock(holding_session); 03184 } 03185 } 03186 } 03187 03188 peer_session = NULL; 03189 peer_channel = NULL; 03190 } 03191 03192 for (i = 0; i < and_argc; i++) { 03193 if (!peer_eligible(originate_status[i].peer_channel)) { 03194 continue; 03195 } 03196 03197 if (i != oglobals.idx) { 03198 holding = NULL; 03199 03200 if (oglobals.idx == IDX_TIMEOUT || to) { 03201 reason = SWITCH_CAUSE_NO_ANSWER; 03202 } else { 03203 if (oglobals.idx == IDX_CANCEL) { 03204 reason = SWITCH_CAUSE_ORIGINATOR_CANCEL; 03205 } else { 03206 if (and_argc > 1) { 03207 reason = SWITCH_CAUSE_LOSE_RACE; 03208 } else if (!switch_channel_ready(originate_status[i].peer_channel)) { 03209 wait_for_cause(originate_status[i].peer_channel); 03210 if (switch_channel_down_nosig(originate_status[i].peer_channel)) { 03211 reason = switch_channel_get_cause(originate_status[i].peer_channel); 03212 } 03213 } else { 03214 reason = SWITCH_CAUSE_NO_ANSWER; 03215 } 03216 } 03217 } 03218 if (switch_channel_up_nosig(originate_status[i].peer_channel)) { 03219 if (caller_channel && i == 0) { 03220 holding = switch_channel_get_variable(caller_channel, SWITCH_SOFT_HOLDING_UUID_VARIABLE); 03221 switch_channel_set_variable(caller_channel, SWITCH_SOFT_HOLDING_UUID_VARIABLE, NULL); 03222 } 03223 03224 if (holding && oglobals.idx != IDX_TIMEOUT && oglobals.idx != IDX_KEY_CANCEL && oglobals.idx < 0) { 03225 switch_core_session_t *holding_session; 03226 03227 if ((holding_session = switch_core_session_locate(holding))) { 03228 switch_channel_t *holding_channel = switch_core_session_get_channel(holding_session); 03229 03230 switch_channel_set_variable(holding_channel, SWITCH_HANGUP_AFTER_BRIDGE_VARIABLE, "true"); 03231 03232 if (caller_channel && switch_true(switch_channel_get_variable(caller_channel, "recording_follow_transfer"))) { 03233 switch_core_media_bug_transfer_recordings(session, originate_status[i].peer_session); 03234 } 03235 03236 if (switch_true(switch_channel_get_variable(holding_channel, "recording_follow_transfer"))) { 03237 switch_core_media_bug_transfer_recordings(holding_session, originate_status[i].peer_session); 03238 } 03239 03240 switch_core_session_rwunlock(holding_session); 03241 } 03242 switch_channel_set_flag(originate_status[i].peer_channel, CF_LAZY_ATTENDED_TRANSFER); 03243 switch_ivr_uuid_bridge(holding, switch_core_session_get_uuid(originate_status[i].peer_session)); 03244 holding = NULL; 03245 } else { 03246 switch_channel_hangup(originate_status[i].peer_channel, force_reason ? force_reason : reason); 03247 } 03248 } 03249 } 03250 } 03251 03252 03253 03254 if (oglobals.idx > IDX_NADA) { 03255 if ((peer_session = originate_status[oglobals.idx].peer_session)) { 03256 peer_channel = switch_core_session_get_channel(originate_status[oglobals.idx].peer_session); 03257 } 03258 } else { 03259 status = SWITCH_STATUS_FALSE; 03260 if (caller_channel && peer_channel) { 03261 switch_process_import(oglobals.session, peer_channel, "import", NULL); 03262 } 03263 peer_channel = NULL; 03264 goto done; 03265 } 03266 03267 if (caller_channel) { 03268 if (switch_channel_test_flag(peer_channel, CF_ANSWERED)) { 03269 switch_channel_pass_callee_id(peer_channel, caller_channel); 03270 if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE)) { 03271 status = SWITCH_STATUS_SUCCESS; 03272 } else { 03273 status = switch_channel_answer(caller_channel); 03274 } 03275 } else if (switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA)) { 03276 if (switch_channel_test_flag(caller_channel, CF_PROXY_MODE)) { 03277 status = SWITCH_STATUS_SUCCESS; 03278 } else { 03279 status = switch_channel_pre_answer(caller_channel); 03280 } 03281 } else { 03282 status = SWITCH_STATUS_SUCCESS; 03283 } 03284 03285 if (status != SWITCH_STATUS_SUCCESS) { 03286 switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(peer_channel), SWITCH_LOG_DEBUG, "%s Media Establishment Failed.\n", 03287 switch_channel_get_name(caller_channel)); 03288 switch_channel_hangup(peer_channel, SWITCH_CAUSE_INCOMPATIBLE_DESTINATION); 03289 } 03290 } 03291 03292 if (switch_channel_test_flag(peer_channel, CF_ANSWERED) || 03293 (oglobals.early_ok && switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA)) || 03294 (oglobals.return_ring_ready && switch_channel_test_flag(peer_channel, CF_RING_READY)) 03295 ) { 03296 *bleg = peer_session; 03297 03298 if (oglobals.monitor_early_media_ring || oglobals.monitor_early_media_fail) { 03299 switch_ivr_stop_tone_detect_session(peer_session); 03300 switch_channel_set_private(peer_channel, "_oglobals_", NULL); 03301 } 03302 03303 status = SWITCH_STATUS_SUCCESS; 03304 } else { 03305 status = SWITCH_STATUS_FALSE; 03306 } 03307 03308 done: 03309 03310 *cause = SWITCH_CAUSE_NONE; 03311 03312 if (caller_channel && !switch_channel_ready(caller_channel)) { 03313 status = SWITCH_STATUS_FALSE; 03314 } 03315 03316 if (status == SWITCH_STATUS_SUCCESS) { 03317 if (caller_channel) { 03318 switch_channel_set_variable(caller_channel, "originate_disposition", "call accepted"); 03319 if (peer_channel) { 03320 switch_process_import(oglobals.session, peer_channel, "import", NULL); 03321 03322 if (switch_channel_test_flag(peer_channel, CF_ANSWERED)) { 03323 switch_channel_set_variable(caller_channel, "DIALSTATUS", "EARLY"); 03324 } else { 03325 switch_channel_set_variable(caller_channel, "DIALSTATUS", "ANSWER"); 03326 } 03327 03328 } 03329 } 03330 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(oglobals.session), SWITCH_LOG_DEBUG, "Originate Resulted in Success: [%s]\n", 03331 switch_channel_get_name(peer_channel)); 03332 *cause = SWITCH_CAUSE_SUCCESS; 03333 03334 } else { 03335 const char *cdr_var = NULL; 03336 switch_xml_t cdr = NULL; 03337 char *xml_text; 03338 char buf[128] = "", buf2[128] = ""; 03339 03340 if (caller_channel) { 03341 cdr_var = switch_channel_get_variable(caller_channel, "failed_xml_cdr_prefix"); 03342 } 03343 03344 if (peer_channel) { 03345 wait_for_cause(peer_channel); 03346 *cause = switch_channel_get_cause(peer_channel); 03347 } else { 03348 for (i = 0; i < and_argc; i++) { 03349 if (!originate_status[i].peer_channel) { 03350 continue; 03351 } 03352 *cause = switch_channel_get_cause(originate_status[i].peer_channel); 03353 break; 03354 } 03355 } 03356 03357 if (cdr_var) { 03358 for (i = 0; i < and_argc; i++) { 03359 switch_channel_t *channel; 03360 03361 if (!originate_status[i].peer_session) { 03362 continue; 03363 } 03364 03365 channel = switch_core_session_get_channel(originate_status[i].peer_session); 03366 03367 switch_channel_wait_for_state_timeout(channel, CS_REPORTING, 5000); 03368 03369 if (!switch_channel_test_flag(channel, CF_TIMESTAMP_SET)) { 03370 switch_channel_set_timestamps(channel); 03371 } 03372 03373 if (switch_ivr_generate_xml_cdr(originate_status[i].peer_session, &cdr) == SWITCH_STATUS_SUCCESS) { 03374 if ((xml_text = switch_xml_toxml(cdr, SWITCH_FALSE))) { 03375 switch_snprintf(buf, sizeof(buf), "%s_%d", cdr_var, ++cdr_total); 03376 switch_channel_set_variable(caller_channel, buf, xml_text); 03377 switch_safe_free(xml_text); 03378 } 03379 switch_xml_free(cdr); 03380 cdr = NULL; 03381 } 03382 03383 } 03384 switch_snprintf(buf, sizeof(buf), "%s_total", cdr_var); 03385 switch_snprintf(buf2, sizeof(buf2), "%d", cdr_total ? cdr_total : 0); 03386 switch_channel_set_variable(caller_channel, buf, buf2); 03387 } 03388 03389 if (caller_channel && switch_channel_test_flag(caller_channel, CF_INTERCEPTED)) { 03390 *cause = SWITCH_CAUSE_PICKED_OFF; 03391 } 03392 03393 if (!*cause) { 03394 if (reason) { 03395 *cause = reason; 03396 } else if (caller_channel) { 03397 *cause = switch_channel_get_cause(caller_channel); 03398 } else { 03399 *cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER; 03400 for (i = 0; i < and_argc; i++) { 03401 if (!peer_eligible(originate_status[i].peer_channel)) { 03402 continue; 03403 } 03404 03405 wait_for_cause(originate_status[i].peer_channel); 03406 03407 if (switch_channel_down_nosig(originate_status[i].peer_channel)) { 03408 *cause = switch_channel_get_cause(originate_status[i].peer_channel); 03409 break; 03410 } 03411 03412 } 03413 } 03414 } 03415 03416 if (*cause == SWITCH_CAUSE_SUCCESS || *cause == SWITCH_CAUSE_NONE) { 03417 *cause = SWITCH_CAUSE_ORIGINATOR_CANCEL; 03418 } 03419 03420 if (oglobals.idx == IDX_CANCEL) { 03421 *cause = SWITCH_CAUSE_ORIGINATOR_CANCEL; 03422 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(oglobals.session), SWITCH_LOG_DEBUG, 03423 "Originate Cancelled by originator termination Cause: %d [%s]\n", *cause, switch_channel_cause2str(*cause)); 03424 03425 } else if (oglobals.idx == IDX_TIMEOUT) { 03426 *cause = SWITCH_CAUSE_NO_ANSWER; 03427 } else { 03428 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(oglobals.session), SWITCH_LOG_DEBUG, 03429 "Originate Resulted in Error Cause: %d [%s]\n", *cause, switch_channel_cause2str(*cause)); 03430 } 03431 } 03432 03433 if (caller_channel) { 03434 switch_channel_set_variable(caller_channel, "originate_disposition", switch_channel_cause2str(*cause)); 03435 03436 switch (*cause) { 03437 case SWITCH_CAUSE_ORIGINATOR_CANCEL: 03438 switch_channel_set_variable(caller_channel, "DIALSTATUS", "CANCEL"); 03439 break; 03440 case SWITCH_CAUSE_USER_BUSY: 03441 switch_channel_set_variable(caller_channel, "DIALSTATUS", "BUSY"); 03442 break; 03443 case SWITCH_CAUSE_NO_ANSWER: 03444 switch_channel_set_variable(caller_channel, "DIALSTATUS", "NOANSWER"); 03445 break; 03446 case SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER: 03447 case SWITCH_CAUSE_INVALID_PROFILE: 03448 switch_channel_set_variable(caller_channel, "DIALSTATUS", "INVALIDARGS"); 03449 break; 03450 case SWITCH_CAUSE_CALL_REJECTED: 03451 switch_channel_set_variable(caller_channel, "DIALSTATUS", "DONTCALL"); 03452 break; 03453 default: 03454 switch_channel_set_variable(caller_channel, "DIALSTATUS", switch_channel_cause2str(*cause)); 03455 break; 03456 } 03457 } 03458 03459 early_state.ready = 0; 03460 03461 if (oglobals.ethread) { 03462 switch_status_t st; 03463 switch_thread_join(&st, oglobals.ethread); 03464 } 03465 03466 if (early_state.buffer) { 03467 switch_buffer_destroy(&early_state.buffer); 03468 } 03469 03470 if (ringback.fh) { 03471 switch_core_file_close(ringback.fh); 03472 ringback.fh = NULL; 03473 } else if (ringback.audio_buffer) { 03474 teletone_destroy_session(&ringback.ts); 03475 switch_buffer_destroy(&ringback.audio_buffer); 03476 } 03477 03478 if (oglobals.session) { 03479 switch_core_session_reset(oglobals.session, SWITCH_FALSE, SWITCH_TRUE); 03480 } 03481 03482 if (switch_core_codec_ready(&write_codec)) { 03483 switch_core_codec_destroy(&write_codec); 03484 } 03485 03486 for (i = 0; i < and_argc; i++) { 03487 switch_channel_state_t state; 03488 03489 if (!originate_status[i].peer_channel) { 03490 continue; 03491 } 03492 03493 if (status == SWITCH_STATUS_SUCCESS) { 03494 switch_channel_clear_flag(originate_status[i].peer_channel, CF_ORIGINATING); 03495 if (bleg && *bleg && *bleg == originate_status[i].peer_session) { 03496 continue; 03497 } 03498 } else if ((state = switch_channel_get_state(originate_status[i].peer_channel)) < CS_HANGUP && 03499 switch_channel_test_flag(originate_status[i].peer_channel, CF_ORIGINATING)) { 03500 if (!(state == CS_RESET || switch_channel_test_flag(originate_status[i].peer_channel, CF_TRANSFER) || 03501 switch_channel_test_flag(originate_status[i].peer_channel, CF_REDIRECT) || 03502 switch_channel_test_flag(originate_status[i].peer_channel, CF_BRIDGED))) { 03503 if (caller_channel && switch_channel_test_flag(caller_channel, CF_INTERCEPTED)) { 03504 switch_channel_set_flag(originate_status[i].peer_channel, CF_INTERCEPT); 03505 } 03506 switch_channel_hangup(originate_status[i].peer_channel, *cause); 03507 } 03508 } 03509 switch_channel_clear_flag(originate_status[i].peer_channel, CF_ORIGINATING); 03510 03511 switch_core_session_rwunlock(originate_status[i].peer_session); 03512 } 03513 03514 if (status == SWITCH_STATUS_SUCCESS) { 03515 goto outer_for; 03516 } else { 03517 int ok = 1; 03518 03519 if (fail_on_single_reject && check_reject && !switch_true(fail_on_single_reject_var)) { 03520 for (i = 0; i < and_argc; i++) { 03521 switch_channel_t *pchannel; 03522 const char *cause_str; 03523 03524 if (!originate_status[i].peer_session) { 03525 continue; 03526 } 03527 03528 pchannel = switch_core_session_get_channel(originate_status[i].peer_session); 03529 wait_for_cause(pchannel); 03530 03531 if (switch_channel_down_nosig(pchannel)) { 03532 int neg, pos; 03533 03534 cause_str = switch_channel_cause2str(switch_channel_get_cause(pchannel)); 03535 03536 neg = *fail_on_single_reject_var == '!'; 03537 pos = !!switch_stristr(cause_str, fail_on_single_reject_var); 03538 03539 if (neg) { 03540 pos = !pos; 03541 } 03542 03543 03544 if (pos) { 03545 ok = 0; 03546 break; 03547 } 03548 } 03549 } 03550 } 03551 03552 if (!ok) { 03553 goto outer_for; 03554 } 03555 03556 if (to && !oglobals.continue_on_timeout) { 03557 goto outer_for; 03558 } 03559 } 03560 } 03561 } 03562 outer_for: 03563 switch_safe_free(loop_data); 03564 switch_safe_free(odata); 03565 switch_safe_free(oglobals.file); 03566 switch_safe_free(oglobals.error_file); 03567 03568 if (bleg && status != SWITCH_STATUS_SUCCESS) { 03569 *bleg = NULL; 03570 } 03571 03572 if (*bleg) { 03573 switch_channel_t *bchan = switch_core_session_get_channel(*bleg); 03574 03575 if (session && caller_channel) { 03576 switch_caller_profile_t *cloned_profile, *peer_profile = switch_channel_get_caller_profile(switch_core_session_get_channel(*bleg)); 03577 03578 if (peer_profile) { 03579 if ((cloned_profile = switch_caller_profile_clone(session, peer_profile)) != 0) { 03580 switch_channel_set_originatee_caller_profile(caller_channel, cloned_profile); 03581 } 03582 } 03583 03584 switch_channel_set_variable(caller_channel, SWITCH_SIGNAL_BOND_VARIABLE, switch_core_session_get_uuid(*bleg)); 03585 // Now main SWITCH_SIGNAL_BOND_VARIABLE is populated, don't need this one anymore... 03586 switch_channel_set_variable(caller_channel, "originate_signal_bond", NULL); 03587 } 03588 03589 03590 while(switch_channel_state_change_pending(bchan)) { 03591 switch_cond_next(); 03592 } 03593 03594 switch_channel_audio_sync(bchan); 03595 03596 if (caller_channel) { 03597 switch_channel_audio_sync(caller_channel); 03598 } 03599 } 03600 03601 if (oglobals.session) { 03602 switch_ivr_parse_all_events(oglobals.session); 03603 } 03604 03605 if (oglobals.session && status == SWITCH_STATUS_SUCCESS) { 03606 switch_ivr_sleep(oglobals.session, 0, SWITCH_TRUE, NULL); 03607 } 03608 03609 if (var_event && var_event != ovars) { 03610 switch_event_destroy(&var_event); 03611 } 03612 03613 switch_safe_free(write_frame.data); 03614 switch_safe_free(fail_on_single_reject_var); 03615 03616 if (caller_channel) { 03617 switch_channel_clear_flag(caller_channel, CF_ORIGINATOR); 03618 switch_channel_clear_flag(caller_channel, CF_XFER_ZOMBIE); 03619 } 03620 03621 if (force_reason != SWITCH_CAUSE_NONE) { 03622 *cause = force_reason; 03623 } 03624 03625 switch_core_destroy_memory_pool(&oglobals.pool); 03626 03627 return status; 03628 }
| switch_status_t switch_ivr_park | ( | switch_core_session_t * | session, | |
| switch_input_args_t * | args | |||
| ) |
Definition at line 837 of file switch_ivr.c.
References switch_codec_implementation::actual_samples_per_second, switch_frame::buflen, CF_CONTROLLED, CF_PARK, CF_RECOVERED, CF_SERVICE, CF_UNICAST, switch_frame::codec, CS_RESET, 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_unicast_conninfo::read_codec, switch_unicast_conninfo::remote_addr, switch_frame::samples, switch_codec_implementation::samples_per_second, SFF_CNG, switch_unicast_conninfo::socket, SUF_NATIVE, switch_assert, SWITCH_CAUSE_NORMAL_CLEARING, switch_channel_clear_flag(), switch_channel_dequeue_dtmf(), switch_channel_event_set_data(), switch_channel_get_private(), switch_channel_get_state(), switch_channel_get_variable, switch_channel_hangup, switch_channel_has_dtmf(), switch_channel_media_ready, switch_channel_pre_answer, switch_channel_ready, SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_flag, switch_channel_set_variable, switch_channel_str2cause(), switch_channel_test_flag(), SWITCH_CODEC_FLAG_DECODE, SWITCH_CODEC_FLAG_ENCODE, switch_cond_next(), switch_core_codec_decode(), switch_core_codec_destroy(), switch_core_codec_init, switch_core_session_dequeue_event(), switch_core_session_dequeue_private_event(), switch_core_session_get_channel(), switch_core_session_get_pool(), switch_core_session_get_read_codec(), switch_core_session_get_read_impl(), switch_core_session_read_frame(), switch_core_session_write_frame(), switch_epoch_time_now(), SWITCH_EVENT_CHANNEL_PARK, SWITCH_EVENT_CHANNEL_UNPARK, switch_event_create, switch_event_destroy(), switch_event_fire, SWITCH_FALSE, switch_generate_sln_silence(), SWITCH_INPUT_TYPE_DTMF, SWITCH_INPUT_TYPE_EVENT, SWITCH_IO_FLAG_NONE, switch_ivr_deactivate_unicast(), switch_ivr_dmachine_feed(), switch_ivr_dmachine_ping(), switch_ivr_parse_all_events(), switch_ivr_parse_event(), SWITCH_LOG_DEBUG, SWITCH_LOG_ERROR, SWITCH_LOG_NOTICE, switch_log_printf(), SWITCH_PARK_AFTER_BRIDGE_VARIABLE, SWITCH_READ_ACCEPTABLE, SWITCH_RECOMMENDED_BUFFER_SIZE, switch_safe_free, SWITCH_SEND_SILENCE_WHEN_IDLE_VARIABLE, switch_socket_sendto(), SWITCH_STATUS_BREAK, SWITCH_STATUS_FALSE, SWITCH_STATUS_NOOP, SWITCH_STATUS_SUCCESS, switch_test_flag, switch_yield, switch_zmalloc, and unicast_thread_launch().
Referenced by switch_core_standard_on_park().
00838 { 00839 switch_status_t status = SWITCH_STATUS_SUCCESS; 00840 switch_channel_t *channel = switch_core_session_get_channel(session); 00841 switch_frame_t *read_frame = NULL; 00842 int stream_id = 0; 00843 switch_event_t *event; 00844 switch_unicast_conninfo_t *conninfo = NULL; 00845 uint32_t rate = 0; 00846 uint32_t bpf = 0; 00847 const char *to; 00848 int timeout = 0; 00849 time_t expires = 0; 00850 switch_codec_implementation_t read_impl = { 0 }; 00851 switch_call_cause_t timeout_cause = SWITCH_CAUSE_NORMAL_CLEARING; 00852 switch_codec_t codec = { 0 }; 00853 int sval = 0; 00854 const char *var; 00855 switch_frame_t write_frame = { 0 }; 00856 unsigned char *abuf = NULL; 00857 switch_codec_implementation_t imp = { 0 }; 00858 00859 if (switch_channel_test_flag(channel, CF_RECOVERED) && switch_channel_test_flag(channel, CF_CONTROLLED)) { 00860 switch_channel_clear_flag(channel, CF_CONTROLLED); 00861 } 00862 00863 if (switch_channel_test_flag(channel, CF_CONTROLLED)) { 00864 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot park channels that are under control already.\n"); 00865 return SWITCH_STATUS_FALSE; 00866 } 00867 00868 if (switch_channel_get_state(channel) == CS_RESET) { 00869 return SWITCH_STATUS_FALSE; 00870 } 00871 00872 if ((to = switch_channel_get_variable(channel, "park_timeout"))) { 00873 char *cause_str; 00874 00875 if ((cause_str = strchr(to, ':'))) { 00876 timeout_cause = switch_channel_str2cause(cause_str + 1); 00877 } 00878 00879 if ((timeout = atoi(to)) < 0) { 00880 timeout = 0; 00881 } else { 00882 expires = switch_epoch_time_now(NULL) + timeout; 00883 } 00884 switch_channel_set_variable(channel, "park_timeout", NULL); 00885 switch_channel_set_variable(channel, SWITCH_PARK_AFTER_BRIDGE_VARIABLE, NULL); 00886 } 00887 00888 switch_channel_set_flag(channel, CF_CONTROLLED); 00889 switch_channel_set_flag(channel, CF_PARK); 00890 00891 if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_PARK) == SWITCH_STATUS_SUCCESS) { 00892 switch_channel_event_set_data(channel, event); 00893 switch_event_fire(&event); 00894 } 00895 00896 while (switch_channel_ready(channel) && switch_channel_test_flag(channel, CF_CONTROLLED) && switch_channel_test_flag(channel, CF_PARK)) { 00897 00898 if (!rate && switch_channel_media_ready(channel)) { 00899 switch_core_session_get_read_impl(session, &read_impl); 00900 rate = read_impl.actual_samples_per_second; 00901 bpf = read_impl.decoded_bytes_per_packet; 00902 00903 if ((var = switch_channel_get_variable(channel, SWITCH_SEND_SILENCE_WHEN_IDLE_VARIABLE)) && (sval = atoi(var))) { 00904 switch_core_session_get_read_impl(session, &imp); 00905 00906 if (switch_core_codec_init(&codec, 00907 "L16", 00908 NULL, 00909 imp.samples_per_second, 00910 imp.microseconds_per_packet / 1000, 00911 imp.number_of_channels, 00912 SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, 00913 switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { 00914 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec Error L16@%uhz %u channels %dms\n", 00915 imp.samples_per_second, imp.number_of_channels, imp.microseconds_per_packet / 1000); 00916 return SWITCH_STATUS_FALSE; 00917 } 00918 00919 00920 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Codec Activated L16@%uhz %u channels %dms\n", 00921 imp.samples_per_second, imp.number_of_channels, imp.microseconds_per_packet / 1000); 00922 00923 write_frame.codec = &codec; 00924 switch_zmalloc(abuf, SWITCH_RECOMMENDED_BUFFER_SIZE); 00925 write_frame.data = abuf; 00926 write_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE; 00927 write_frame.datalen = imp.decoded_bytes_per_packet; 00928 write_frame.samples = write_frame.datalen / sizeof(int16_t); 00929 } 00930 } 00931 00932 if (rate) { 00933 if (switch_channel_test_flag(channel, CF_SERVICE)) { 00934 switch_cond_next(); 00935 status = SWITCH_STATUS_SUCCESS; 00936 } else { 00937 status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, stream_id); 00938 } 00939 } else { 00940 switch_yield(20000); 00941 00942 if (switch_core_session_dequeue_private_event(session, &event) == SWITCH_STATUS_SUCCESS) { 00943 switch_ivr_parse_event(session, event); 00944 switch_event_destroy(&event); 00945 } 00946 00947 status = SWITCH_STATUS_SUCCESS; 00948 } 00949 00950 if (!SWITCH_READ_ACCEPTABLE(status)) { 00951 break; 00952 } 00953 00954 if (rate && write_frame.data && sval) { 00955 switch_generate_sln_silence((int16_t *) write_frame.data, write_frame.samples, sval); 00956 switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0); 00957 } 00958 00959 if (expires && switch_epoch_time_now(NULL) >= expires) { 00960 switch_channel_hangup(channel, timeout_cause); 00961 break; 00962 } 00963 00964 if (switch_channel_test_flag(channel, CF_UNICAST)) { 00965 if (!switch_channel_media_ready(channel)) { 00966 if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) { 00967 return SWITCH_STATUS_FALSE; 00968 } 00969 } 00970 00971 if (!conninfo) { 00972 if (!(conninfo = switch_channel_get_private(channel, "unicast"))) { 00973 switch_channel_clear_flag(channel, CF_UNICAST); 00974 } 00975 00976 if (conninfo) { 00977 unicast_thread_launch(conninfo); 00978 } 00979 } 00980 00981 if (conninfo) { 00982 switch_size_t len = 0; 00983 uint32_t flags = 0; 00984 switch_byte_t decoded[SWITCH_RECOMMENDED_BUFFER_SIZE]; 00985 uint32_t dlen = sizeof(decoded); 00986 switch_status_t tstatus; 00987 switch_byte_t *sendbuf = NULL; 00988 uint32_t sendlen = 0; 00989 00990 switch_assert(read_frame); 00991 00992 if (switch_test_flag(read_frame, SFF_CNG)) { 00993 sendlen = bpf; 00994 switch_assert(sendlen <= SWITCH_RECOMMENDED_BUFFER_SIZE); 00995 memset(decoded, 255, sendlen); 00996 sendbuf = decoded; 00997 tstatus = SWITCH_STATUS_SUCCESS; 00998 } else { 00999 if (switch_test_flag(conninfo, SUF_NATIVE)) { 01000 tstatus = SWITCH_STATUS_NOOP; 01001 } else { 01002 switch_codec_t *read_codec = switch_core_session_get_read_codec(session); 01003 tstatus = switch_core_codec_decode(read_codec, 01004 &conninfo->read_codec, 01005 read_frame->data, 01006 read_frame->datalen, read_impl.actual_samples_per_second, decoded, &dlen, &rate, &flags); 01007 } 01008 switch (tstatus) { 01009 case SWITCH_STATUS_NOOP: 01010 case SWITCH_STATUS_BREAK: 01011 sendbuf = read_frame->data; 01012 sendlen = read_frame->datalen; 01013 tstatus = SWITCH_STATUS_SUCCESS; 01014 break; 01015 case SWITCH_STATUS_SUCCESS: 01016 sendbuf = decoded; 01017 sendlen = dlen; 01018 tstatus = SWITCH_STATUS_SUCCESS; 01019 break; 01020 default: 01021 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Codec Error\n"); 01022 switch_ivr_deactivate_unicast(session); 01023 break; 01024 } 01025 } 01026 01027 if (tstatus == SWITCH_STATUS_SUCCESS) { 01028 len = sendlen; 01029 if (switch_socket_sendto(conninfo->socket, conninfo->remote_addr, 0, (void *) sendbuf, &len) != SWITCH_STATUS_SUCCESS) { 01030 switch_ivr_deactivate_unicast(session); 01031 } 01032 } 01033 } 01034 } 01035 01036 switch_ivr_parse_all_events(session); 01037 01038 01039 if (switch_channel_has_dtmf(channel)) { 01040 switch_dtmf_t dtmf = { 0 }; 01041 01042 if (args && !args->input_callback && !args->buf && !args->dmachine) { 01043 status = SWITCH_STATUS_BREAK; 01044 break; 01045 } 01046 01047 switch_channel_dequeue_dtmf(channel, &dtmf); 01048 01049 if (args) { 01050 if (args->dmachine) { 01051 char ds[2] = {dtmf.digit, '\0'}; 01052 if ((status = switch_ivr_dmachine_feed(args->dmachine, ds, NULL)) != SWITCH_STATUS_SUCCESS) { 01053 break; 01054 } 01055 } 01056 01057 if (args->input_callback) { 01058 if ((status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen)) != SWITCH_STATUS_SUCCESS) { 01059 break; 01060 } 01061 } 01062 } 01063 } 01064 01065 if (switch_core_session_dequeue_event(session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) { 01066 if (args && args->input_callback) { 01067 if ((status = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen)) != SWITCH_STATUS_SUCCESS) { 01068 break; 01069 } 01070 } else { 01071 switch_channel_event_set_data(channel, event); 01072 switch_event_fire(&event); 01073 } 01074 } 01075 01076 if (args && args->dmachine) { 01077 if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL)) != SWITCH_STATUS_SUCCESS) { 01078 break; 01079 } 01080 } 01081 01082 01083 } 01084 01085 if (write_frame.codec) { 01086 switch_core_codec_destroy(&codec); 01087 } 01088 01089 switch_safe_free(abuf); 01090 01091 switch_channel_clear_flag(channel, CF_CONTROLLED); 01092 switch_channel_clear_flag(channel, CF_PARK); 01093 01094 if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_UNPARK) == SWITCH_STATUS_SUCCESS) { 01095 switch_channel_event_set_data(channel, event); 01096 switch_event_fire(&event); 01097 } 01098 01099 if (switch_channel_test_flag(channel, CF_UNICAST)) { 01100 switch_ivr_deactivate_unicast(session); 01101 } 01102 01103 return status; 01104 }
| switch_status_t switch_ivr_parse_all_events | ( | switch_core_session_t * | session | ) |
Parse all commands from an event.
| session | the session on which to parse the events |
Definition at line 808 of file switch_ivr.c.
References CF_BLOCK_BROADCAST_UNTIL_MEDIA, CF_PROXY_MODE, switch_channel_clear_flag(), switch_channel_media_up, switch_channel_test_flag(), switch_core_session_get_channel(), switch_ivr_parse_all_messages(), switch_ivr_parse_next_event(), switch_ivr_sleep(), SWITCH_STATUS_SUCCESS, and SWITCH_TRUE.
Referenced by check_channel_status(), switch_core_session_run(), switch_ivr_collect_digits_callback(), switch_ivr_collect_digits_count(), switch_ivr_gentones(), switch_ivr_multi_threaded_bridge(), switch_ivr_park(), switch_ivr_play_file(), switch_ivr_record_file(), switch_ivr_session_echo(), switch_ivr_sleep(), and switch_ivr_wait_for_answer().
00809 { 00810 int x = 0; 00811 switch_channel_t *channel; 00812 00813 switch_ivr_parse_all_messages(session); 00814 00815 channel = switch_core_session_get_channel(session); 00816 00817 if (!switch_channel_test_flag(channel, CF_PROXY_MODE) && switch_channel_test_flag(channel, CF_BLOCK_BROADCAST_UNTIL_MEDIA)) { 00818 if (switch_channel_media_up(channel)) { 00819 switch_channel_clear_flag(channel, CF_BLOCK_BROADCAST_UNTIL_MEDIA); 00820 } else { 00821 return SWITCH_STATUS_SUCCESS; 00822 } 00823 } 00824 00825 while (switch_ivr_parse_next_event(session) == SWITCH_STATUS_SUCCESS) { 00826 x++; 00827 } 00828 00829 if (x) { 00830 switch_ivr_sleep(session, 0, SWITCH_TRUE, NULL); 00831 } 00832 00833 return SWITCH_STATUS_SUCCESS; 00834 }
| switch_status_t switch_ivr_parse_all_messages | ( | switch_core_session_t * | session | ) |
Definition at line 754 of file switch_ivr.c.
References switch_core_session_dequeue_message(), switch_core_session_free_message(), switch_core_session_receive_message, switch_ivr_parse_all_signal_data(), switch_ivr_process_indications(), SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.
Referenced by audio_bridge_thread(), enterprise_originate_ringback_thread(), originate_on_consume_media_transmit(), signal_bridge_on_hibernate(), switch_ivr_multi_threaded_bridge(), switch_ivr_parse_all_events(), switch_ivr_play_file(), switch_ivr_speak_text_handle(), and switch_ivr_wait_for_answer().
00755 { 00756 switch_core_session_message_t *message; 00757 int i = 0; 00758 00759 switch_ivr_parse_all_signal_data(session); 00760 00761 while (switch_core_session_dequeue_message(session, &message) == SWITCH_STATUS_SUCCESS) { 00762 i++; 00763 00764 if (switch_ivr_process_indications(session, message) == SWITCH_STATUS_SUCCESS) { 00765 switch_core_session_free_message(&message); 00766 } else { 00767 switch_core_session_receive_message(session, message); 00768 message = NULL; 00769 } 00770 } 00771 00772 return i ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE; 00773 }
| switch_status_t switch_ivr_parse_all_signal_data | ( | switch_core_session_t * | session | ) |
Definition at line 776 of file switch_ivr.c.
References CF_SIGNAL_DATA, switch_core_session_message::from, switch_core_session_message::message_id, switch_core_session_message::pointer_arg, switch_channel_clear_flag(), switch_channel_set_flag, switch_channel_test_flag(), switch_core_session_dequeue_signal_data(), switch_core_session_get_channel(), switch_core_session_receive_message, SWITCH_MESSAGE_INDICATE_SIGNAL_DATA, SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.
Referenced by switch_channel_check_signal(), and switch_ivr_parse_all_messages().
00777 { 00778 void *data; 00779 switch_core_session_message_t msg = { 0 }; 00780 int i = 0; 00781 switch_channel_t *channel = switch_core_session_get_channel(session); 00782 00783 00784 if (switch_channel_test_flag(channel, CF_SIGNAL_DATA)) { 00785 return SWITCH_STATUS_FALSE; 00786 } 00787 00788 switch_channel_set_flag(channel, CF_SIGNAL_DATA); 00789 00790 msg.message_id = SWITCH_MESSAGE_INDICATE_SIGNAL_DATA; 00791 msg.from = __FILE__; 00792 00793 while (switch_core_session_dequeue_signal_data(session, &data) == SWITCH_STATUS_SUCCESS) { 00794 i++; 00795 00796 msg.pointer_arg = data; 00797 switch_core_session_receive_message(session, &msg); 00798 00799 data = NULL; 00800 00801 } 00802 00803 switch_channel_clear_flag(channel, CF_SIGNAL_DATA); 00804 00805 return i ? SWITCH_STATUS_SUCCESS : SWITCH_STATUS_FALSE; 00806 }
| switch_status_t switch_ivr_parse_event | ( | _In_ switch_core_session_t * | session, | |
| _In_ switch_event_t * | event | |||
| ) |
Parse command from an event.
| session | the session on which to parse the event | |
| event | the event to parse |
Referenced by switch_ivr_park(), switch_ivr_parse_next_event(), and switch_ivr_speak_text_handle().
| switch_status_t switch_ivr_parse_next_event | ( | switch_core_session_t * | session | ) |
Definition at line 711 of file switch_ivr.c.
References switch_core_session_dequeue_private_event(), switch_event_fire, switch_ivr_parse_event(), SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.
Referenced by audio_bridge_thread(), and switch_ivr_parse_all_events().
00712 { 00713 switch_event_t *event; 00714 switch_status_t status = SWITCH_STATUS_FALSE; 00715 00716 if (switch_core_session_dequeue_private_event(session, &event) == SWITCH_STATUS_SUCCESS) { 00717 status = switch_ivr_parse_event(session, event); 00718 switch_event_fire(&event); 00719 } 00720 00721 return status; 00722 00723 }
| switch_status_t switch_ivr_pause_detect_speech | ( | switch_core_session_t * | session | ) |
Pause background Speech detection on a session.
| session | The session to pause detection on |
Definition at line 3672 of file switch_ivr_async.c.
References speech_thread_handle::ah, switch_channel_get_private(), switch_core_asr_pause(), switch_core_session_get_channel(), SWITCH_SPEECH_KEY, SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.
Referenced by switch_ivr_play_and_detect_speech().
03673 { 03674 switch_channel_t *channel = switch_core_session_get_channel(session); 03675 struct speech_thread_handle *sth = switch_channel_get_private(channel, SWITCH_SPEECH_KEY); 03676 03677 if (sth) { 03678 switch_core_asr_pause(sth->ah); 03679 return SWITCH_STATUS_SUCCESS; 03680 } 03681 return SWITCH_STATUS_FALSE; 03682 }
| 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.
| session | the session to play and detect on | |
| file | the path to the file | |
| mod_name | the module name of the ASR library | |
| grammar | the grammar text, URI, or local file name | |
| result | of speech recognition, allocated from the session pool | |
| input_timeout | time to wait for input | |
| args | arguements to pass for callbacks etc |
Definition at line 3380 of file switch_ivr_async.c.
References play_and_detect_speech_state_t::done, switch_input_args_t::input_callback, play_and_detect_input_callback(), play_and_detect_speech_state_t::result, switch_channel_get_name(), switch_channel_ready, SWITCH_CHANNEL_SESSION_LOG, switch_core_session_get_channel(), SWITCH_FALSE, switch_ivr_detect_speech(), switch_ivr_detect_speech_start_input_timers(), switch_ivr_dmachine_last_ping(), switch_ivr_pause_detect_speech(), switch_ivr_play_file(), switch_ivr_sleep(), SWITCH_LOG_INFO, switch_log_printf(), SWITCH_STATUS_BREAK, SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.
03387 { 03388 switch_status_t status = SWITCH_STATUS_SUCCESS; 03389 int recognizing = 0; 03390 switch_input_args_t myargs = { 0 }; 03391 play_and_detect_speech_state_t state = { 0, "" }; 03392 switch_channel_t *channel = switch_core_session_get_channel(session); 03393 03394 if (result == NULL) { 03395 goto done; 03396 } 03397 03398 if (!input_timeout) input_timeout = 5000; 03399 03400 if (!args) { 03401 args = &myargs; 03402 } 03403 03404 /* start speech detection */ 03405 if (switch_ivr_detect_speech(session, mod_name, grammar, grammar, NULL, NULL) != SWITCH_STATUS_SUCCESS) { 03406 goto done; 03407 } 03408 recognizing = 1; 03409 03410 /* play the prompt, looking for detection result */ 03411 args->input_callback = play_and_detect_input_callback; 03412 args->buf = &state; 03413 args->buflen = sizeof(state); 03414 status = switch_ivr_play_file(session, NULL, file, args); 03415 03416 if (args->dmachine && switch_ivr_dmachine_last_ping(args->dmachine) != SWITCH_STATUS_SUCCESS) { 03417 state.done = 1; 03418 goto done; 03419 } 03420 03421 if (status != SWITCH_STATUS_BREAK && status != SWITCH_STATUS_SUCCESS) { 03422 goto done; 03423 } 03424 03425 /* wait for result if not done */ 03426 if (!state.done) { 03427 switch_ivr_detect_speech_start_input_timers(session); 03428 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "(%s) WAITING FOR RESULT\n", switch_channel_get_name(channel)); 03429 while (!state.done && switch_channel_ready(channel)) { 03430 status = switch_ivr_sleep(session, input_timeout, SWITCH_FALSE, args); 03431 03432 if (args->dmachine && switch_ivr_dmachine_last_ping(args->dmachine) != SWITCH_STATUS_SUCCESS) { 03433 state.done = 1; 03434 goto done; 03435 } 03436 03437 if (status != SWITCH_STATUS_BREAK && status != SWITCH_STATUS_SUCCESS) { 03438 goto done; 03439 } 03440 } 03441 } 03442 recognizing = !state.done; 03443 03444 done: 03445 if (recognizing) { 03446 switch_ivr_pause_detect_speech(session); 03447 } 03448 03449 *result = state.result; 03450 03451 if (!state.done) { 03452 status = SWITCH_STATUS_FALSE; 03453 } 03454 03455 return status;; 03456 }
| 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
| session | the session to play the file too | |
| fh | file handle to use (NULL for builtin one) | |
| file | the path to the file | |
| args | arguements to pass for callbacks etc |
Definition at line 1014 of file switch_ivr_play_say.c.
References switch_codec_implementation::actual_samples_per_second, add_playback_vars_to_event(), switch_directories::base_dir, switch_frame::buflen, CF_BREAK, CF_HOLD, switch_frame::codec, switch_frame::data, switch_frame::datalen, switch_codec_implementation::decoded_bytes_per_packet, switch_dtmf_t::digit, switch_codec_implementation::encoded_bytes_per_packet, FILE_BLOCKSIZE, FILE_BUFSIZE, FILE_STARTSAMPLES, switch_codec_implementation::iananame, switch_codec::implementation, switch_codec_implementation::microseconds_per_packet, switch_codec_implementation::number_of_channels, pool, switch_frame::rate, switch_timer::samplecount, switch_frame::samples, switch_codec_implementation::samples_per_packet, switch_codec_implementation::samples_per_second, switch_assert, SWITCH_AUDIO_COL_STR_ARTIST, SWITCH_AUDIO_COL_STR_COMMENT, SWITCH_AUDIO_COL_STR_COPYRIGHT, SWITCH_AUDIO_COL_STR_DATE, SWITCH_AUDIO_COL_STR_SOFTWARE, SWITCH_AUDIO_COL_STR_TITLE, switch_buffer_create_dynamic(), switch_buffer_destroy(), switch_buffer_inuse(), switch_buffer_read(), switch_buffer_write(), switch_buffer_zero(), switch_change_sln_volume(), switch_channel_clear_flag(), switch_channel_dequeue_dtmf(), switch_channel_event_set_data(), switch_channel_get_variable, switch_channel_has_dtmf(), switch_channel_media_ready, switch_channel_pre_answer, switch_channel_ready, SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_private(), switch_channel_set_variable, switch_channel_set_variable_printf(), switch_channel_test_flag(), switch_clear_flag, SWITCH_CODEC_FLAG_DECODE, SWITCH_CODEC_FLAG_ENCODE, switch_core_codec_destroy(), switch_core_codec_init, switch_core_codec_ready(), switch_core_file_close(), switch_core_file_get_string(), switch_core_file_open, switch_core_file_read(), switch_core_file_seek(), switch_core_service_session, switch_core_session_dequeue_event(), switch_core_session_get_channel(), switch_core_session_get_pool(), switch_core_session_get_read_codec(), switch_core_session_get_read_impl(), switch_core_session_io_rwunlock(), switch_core_session_io_write_lock(), switch_core_session_read_frame(), switch_core_session_reset(), switch_core_session_sprintf(), switch_core_session_strdup, switch_core_session_write_frame(), switch_core_thread_session_end(), switch_core_timer_destroy(), switch_core_timer_init(), switch_core_timer_next(), switch_core_timer_sync(), switch_event_add_header_string(), switch_event_create, switch_event_destroy(), switch_event_fire, SWITCH_EVENT_PLAYBACK_START, SWITCH_EVENT_PLAYBACK_STOP, SWITCH_FALSE, SWITCH_FILE_CALLBACK, SWITCH_FILE_DATA_SHORT, SWITCH_FILE_FLAG_READ, SWITCH_FILE_NATIVE, SWITCH_FILE_PAUSE, SWITCH_FILE_SEEK, switch_find_end_paren(), SWITCH_GLOBAL_dirs, SWITCH_INPUT_TYPE_DTMF, SWITCH_INPUT_TYPE_EVENT, SWITCH_IO_FLAG_NONE, SWITCH_IO_FLAG_SINGLE_READ, switch_is_file_path(), switch_ivr_dmachine_feed(), switch_ivr_dmachine_ping(), switch_ivr_parse_all_events(), switch_ivr_parse_all_messages(), switch_ivr_phrase_macro, switch_ivr_sleep(), switch_ivr_speak_text(), SWITCH_LOG_DEBUG, SWITCH_LOG_ERROR, switch_log_printf(), SWITCH_PATH_SEPARATOR, SWITCH_READ_ACCEPTABLE, switch_safe_free, switch_separate_string(), switch_set_flag, SWITCH_STACK_BOTTOM, SWITCH_STATUS_BREAK, SWITCH_STATUS_FALSE, SWITCH_STATUS_GENERR, SWITCH_STATUS_MORE_DATA, SWITCH_STATUS_NOTFOUND, SWITCH_STATUS_SUCCESS, SWITCH_STATUS_TIMEOUT, switch_str_nil, switch_swap_linear(), switch_test_flag, SWITCH_TRUE, SWITCH_URL_SEPARATOR, switch_yield, switch_zmalloc, switch_frame::timestamp, and zstr.
Referenced by collect_thread_run(), enterprise_originate_ringback_thread(), fs_ivr_play_file(), fs_ivr_play_file2(), play_and_collect(), CoreSession::streamFile(), switch_ivr_menu_execute(), switch_ivr_phrase_macro_event(), switch_ivr_play_and_detect_speech(), switch_ivr_read(), switch_ivr_soft_hold(), and switch_play_and_get_digits().
01015 { 01016 switch_channel_t *channel = switch_core_session_get_channel(session); 01017 int16_t *abuf = NULL; 01018 switch_dtmf_t dtmf = { 0 }; 01019 uint32_t interval = 0, samples = 0, framelen, sample_start = 0; 01020 uint32_t ilen = 0; 01021 switch_size_t olen = 0, llen = 0; 01022 switch_frame_t write_frame = { 0 }; 01023 switch_timer_t timer = { 0 }; 01024 switch_codec_t codec = { 0 }; 01025 switch_memory_pool_t *pool = switch_core_session_get_pool(session); 01026 char *codec_name; 01027 switch_status_t status = SWITCH_STATUS_SUCCESS; 01028 switch_file_handle_t lfh; 01029 const char *p; 01030 //char *title = "", *copyright = "", *software = "", *artist = "", *comment = "", *date = ""; 01031 char *ext; 01032 const char *prefix; 01033 const char *timer_name; 01034 const char *prebuf; 01035 const char *alt = NULL; 01036 const char *sleep_val; 01037 const char *play_delimiter_val; 01038 char play_delimiter = 0; 01039 int sleep_val_i = 250; 01040 int eof = 0; 01041 switch_size_t bread = 0; 01042 int l16 = 0; 01043 switch_codec_implementation_t read_impl = { 0 }; 01044 char *file_dup; 01045 char *argv[128] = { 0 }; 01046 int argc; 01047 int cur; 01048 int done = 0; 01049 int timeout_samples = 0; 01050 const char *var; 01051 int more_data = 0; 01052 char *playback_vars, *tmp; 01053 switch_event_t *event; 01054 uint32_t test_native = 0, last_native = 0; 01055 01056 if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) { 01057 return SWITCH_STATUS_FALSE; 01058 } 01059 01060 switch_core_session_get_read_impl(session, &read_impl); 01061 01062 if ((var = switch_channel_get_variable(channel, "playback_timeout_sec"))) { 01063 int tmp = atoi(var); 01064 if (tmp > 1) { 01065 timeout_samples = read_impl.actual_samples_per_second * tmp; 01066 } 01067 } 01068 01069 if ((play_delimiter_val = switch_channel_get_variable(channel, "playback_delimiter"))) { 01070 play_delimiter = *play_delimiter_val; 01071 01072 if ((sleep_val = switch_channel_get_variable(channel, "playback_sleep_val"))) { 01073 int tmp = atoi(sleep_val); 01074 if (tmp >= 0) { 01075 sleep_val_i = tmp; 01076 } 01077 } 01078 } 01079 01080 prefix = switch_channel_get_variable(channel, "sound_prefix"); 01081 timer_name = switch_channel_get_variable(channel, "timer_name"); 01082 01083 if (zstr(file) || !switch_channel_media_ready(channel)) { 01084 return SWITCH_STATUS_FALSE; 01085 } 01086 01087 if (!strcasecmp(read_impl.iananame, "l16")) { 01088 l16++; 01089 } 01090 01091 if (play_delimiter) { 01092 file_dup = switch_core_session_strdup(session, file); 01093 argc = switch_separate_string(file_dup, play_delimiter, argv, (sizeof(argv) / sizeof(argv[0]))); 01094 } else { 01095 argc = 1; 01096 argv[0] = (char *) file; 01097 } 01098 01099 if (!fh) { 01100 fh = &lfh; 01101 memset(fh, 0, sizeof(lfh)); 01102 } 01103 01104 if (fh->samples > 0) { 01105 sample_start = fh->samples; 01106 fh->samples = 0; 01107 } 01108 01109 for (cur = 0; switch_channel_ready(channel) && !done && cur < argc; cur++) { 01110 file = argv[cur]; 01111 eof = 0; 01112 01113 if (cur) { 01114 fh->samples = sample_start = 0; 01115 if (sleep_val_i) { 01116 status = switch_ivr_sleep(session, sleep_val_i, SWITCH_FALSE, args); 01117 if(status != SWITCH_STATUS_SUCCESS) { 01118 break; 01119 } 01120 } 01121 } 01122 01123 status = SWITCH_STATUS_SUCCESS; 01124 01125 if ((alt = strchr(file, ':'))) { 01126 char *dup; 01127 01128 if (!strncasecmp(file, "phrase:", 7)) { 01129 char *arg = NULL; 01130 const char *lang = switch_channel_get_variable(channel, "language"); 01131 alt = file + 7; 01132 dup = switch_core_session_strdup(session, alt); 01133 01134 if (dup) { 01135 if ((arg = strchr(dup, ':'))) { 01136 *arg++ = '\0'; 01137 } 01138 if ((status = switch_ivr_phrase_macro(session, dup, arg, lang, args)) != SWITCH_STATUS_SUCCESS) { 01139 return status; 01140 } 01141 continue; 01142 } else { 01143 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid Args\n"); 01144 continue; 01145 } 01146 } else if (!strncasecmp(file, "say:", 4)) { 01147 char *engine = NULL, *voice = NULL, *text = NULL; 01148 alt = file + 4; 01149 dup = switch_core_session_strdup(session, alt); 01150 engine = dup; 01151 01152 if (!zstr(engine)) { 01153 if ((voice = strchr(engine, ':'))) { 01154 *voice++ = '\0'; 01155 if (!zstr(voice) && (text = strchr(voice, ':'))) { 01156 *text++ = '\0'; 01157 } 01158 } 01159 } 01160 01161 if (!zstr(engine) && !zstr(voice) && !zstr(text)) { 01162 if ((status = switch_ivr_speak_text(session, engine, voice, text, args)) != SWITCH_STATUS_SUCCESS) { 01163 return status; 01164 } 01165 } else { 01166 text = engine; 01167 engine = (char *) switch_channel_get_variable(channel, "tts_engine"); 01168 voice = (char *) switch_channel_get_variable(channel, "tts_voice"); 01169 if (engine && text) { 01170 if ((status = switch_ivr_speak_text(session, engine, voice, text, args)) != SWITCH_STATUS_SUCCESS) { 01171 return status; 01172 } 01173 } else { 01174 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid Args\n"); 01175 } 01176 } 01177 continue; 01178 } 01179 01180 } 01181 01182 if (!prefix) { 01183 prefix = SWITCH_GLOBAL_dirs.base_dir; 01184 } 01185 01186 if (!strstr(file, SWITCH_URL_SEPARATOR)) { 01187 if (!switch_is_file_path(file)) { 01188 char *tfile = NULL; 01189 char *e; 01190 01191 if (*file == '[') { 01192 tfile = switch_core_session_strdup(session, file); 01193 if ((e = switch_find_end_paren(tfile, '[', ']'))) { 01194 *e = '\0'; 01195 file = e + 1; 01196 } else { 01197 tfile = NULL; 01198 } 01199 } 01200 01201 file = switch_core_session_sprintf(session, "%s%s%s%s%s", switch_str_nil(tfile), tfile ? "]" : "", prefix, SWITCH_PATH_SEPARATOR, file); 01202 } 01203 if ((ext = strrchr(file, '.'))) { 01204 ext++; 01205 } else { 01206 ext = read_impl.iananame; 01207 file = switch_core_session_sprintf(session, "%s.%s", file, ext); 01208 } 01209 } 01210 01211 /* Try to parse extra parameters for this playback (parameters within {} at the end of the filename */ 01212 playback_vars = NULL; 01213 if ((tmp = strchr(file, '{'))) { 01214 char *tfile, *e; 01215 01216 if ((tfile = switch_core_session_strdup(session, tmp))) { 01217 if ((e = switch_find_end_paren(tfile, '{', '}')) && *(e + 1) == '\0') { 01218 *tmp = '\0'; 01219 *e = '\0'; 01220 playback_vars = tfile+1; 01221 } 01222 } 01223 } 01224 01225 if ((prebuf = switch_channel_get_variable(channel, "stream_prebuffer"))) { 01226 int maybe = atoi(prebuf); 01227 if (maybe > 0) { 01228 fh->prebuf = maybe; 01229 } 01230 } 01231 01232 01233 if (!fh->prefix) { 01234 fh->prefix = prefix; 01235 } 01236 01237 if (switch_core_file_open(fh, 01238 file, 01239 read_impl.number_of_channels, 01240 read_impl.actual_samples_per_second, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) { 01241 switch_core_session_reset(session, SWITCH_TRUE, SWITCH_FALSE); 01242 status = SWITCH_STATUS_NOTFOUND; 01243 continue; 01244 } 01245 01246 switch_core_session_io_write_lock(session); 01247 switch_channel_set_private(channel, "__fh", fh); 01248 switch_core_session_io_rwunlock(session); 01249 01250 01251 if (!abuf) { 01252 switch_zmalloc(abuf, FILE_STARTSAMPLES * sizeof(*abuf)); 01253 write_frame.data = abuf; 01254 write_frame.buflen = FILE_STARTSAMPLES; 01255 } 01256 01257 if (sample_start > 0) { 01258 uint32_t pos = 0; 01259 switch_core_file_seek(fh, &pos, 0, SEEK_SET); 01260 switch_core_file_seek(fh, &pos, sample_start, SEEK_CUR); 01261 switch_clear_flag(fh, SWITCH_FILE_SEEK); 01262 } 01263 01264 if (switch_core_file_get_string(fh, SWITCH_AUDIO_COL_STR_TITLE, &p) == SWITCH_STATUS_SUCCESS) { 01265 //title = switch_core_session_strdup(session, p); 01266 switch_channel_set_variable(channel, "RECORD_TITLE", p); 01267 } 01268 01269 if (switch_core_file_get_string(fh, SWITCH_AUDIO_COL_STR_COPYRIGHT, &p) == SWITCH_STATUS_SUCCESS) { 01270 //copyright = switch_core_session_strdup(session, p); 01271 switch_channel_set_variable(channel, "RECORD_COPYRIGHT", p); 01272 } 01273 01274 if (switch_core_file_get_string(fh, SWITCH_AUDIO_COL_STR_SOFTWARE, &p) == SWITCH_STATUS_SUCCESS) { 01275 //software = switch_core_session_strdup(session, p); 01276 switch_channel_set_variable(channel, "RECORD_SOFTWARE", p); 01277 } 01278 01279 if (switch_core_file_get_string(fh, SWITCH_AUDIO_COL_STR_ARTIST, &p) == SWITCH_STATUS_SUCCESS) { 01280 //artist = switch_core_session_strdup(session, p); 01281 switch_channel_set_variable(channel, "RECORD_ARTIST", p); 01282 } 01283 01284 if (switch_core_file_get_string(fh, SWITCH_AUDIO_COL_STR_COMMENT, &p) == SWITCH_STATUS_SUCCESS) { 01285 //comment = switch_core_session_strdup(session, p); 01286 switch_channel_set_variable(channel, "RECORD_COMMENT", p); 01287 } 01288 01289 if (switch_core_file_get_string(fh, SWITCH_AUDIO_COL_STR_DATE, &p) == SWITCH_STATUS_SUCCESS) { 01290 //date = switch_core_session_strdup(session, p); 01291 switch_channel_set_variable(channel, "RECORD_DATE", p); 01292 } 01293 01294 interval = read_impl.microseconds_per_packet / 1000; 01295 01296 if (!fh->audio_buffer) { 01297 switch_buffer_create_dynamic(&fh->audio_buffer, FILE_BLOCKSIZE, FILE_BUFSIZE, 0); 01298 switch_assert(fh->audio_buffer); 01299 } 01300 01301 codec_name = "L16"; 01302 01303 if (!switch_core_codec_ready((&codec))) { 01304 if (switch_core_codec_init(&codec, 01305 codec_name, 01306 NULL, 01307 fh->samplerate, 01308 interval, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, pool) == SWITCH_STATUS_SUCCESS) { 01309 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), 01310 SWITCH_LOG_DEBUG, "Codec Activated %s@%uhz %u channels %dms\n", codec_name, fh->samplerate, fh->channels, interval); 01311 01312 01313 } else { 01314 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, 01315 "Raw Codec Activation Failed %s@%uhz %u channels %dms\n", codec_name, fh->samplerate, fh->channels, interval); 01316 switch_core_session_io_write_lock(session); 01317 switch_channel_set_private(channel, "__fh", NULL); 01318 switch_core_session_io_rwunlock(session); 01319 01320 switch_core_file_close(fh); 01321 01322 switch_core_session_reset(session, SWITCH_TRUE, SWITCH_FALSE); 01323 status = SWITCH_STATUS_GENERR; 01324 continue; 01325 } 01326 } 01327 01328 test_native = switch_test_flag(fh, SWITCH_FILE_NATIVE); 01329 01330 if (test_native) { 01331 write_frame.codec = switch_core_session_get_read_codec(session); 01332 samples = read_impl.samples_per_packet; 01333 framelen = read_impl.encoded_bytes_per_packet; 01334 } else { 01335 write_frame.codec = &codec; 01336 samples = codec.implementation->samples_per_packet; 01337 framelen = codec.implementation->decoded_bytes_per_packet; 01338 } 01339 01340 last_native = test_native; 01341 01342 if (timer_name && !timer.samplecount) { 01343 uint32_t len; 01344 01345 len = samples * 2; 01346 if (switch_core_timer_init(&timer, timer_name, interval, samples, pool) != SWITCH_STATUS_SUCCESS) { 01347 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Setup timer failed!\n"); 01348 switch_core_codec_destroy(&codec); 01349 switch_core_session_io_write_lock(session); 01350 switch_channel_set_private(channel, "__fh", NULL); 01351 switch_core_session_io_rwunlock(session); 01352 switch_core_file_close(fh); 01353 switch_core_session_reset(session, SWITCH_TRUE, SWITCH_FALSE); 01354 status = SWITCH_STATUS_GENERR; 01355 continue; 01356 } 01357 switch_core_timer_sync(&timer); // Sync timer 01358 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Setup timer success %u bytes per %d ms!\n", len, interval); 01359 } 01360 write_frame.rate = fh->samplerate; 01361 01362 if (timer_name) { 01363 /* start a thread to absorb incoming audio */ 01364 switch_core_service_session(session); 01365 } 01366 01367 ilen = samples; 01368 01369 if (switch_event_create(&event, SWITCH_EVENT_PLAYBACK_START) == SWITCH_STATUS_SUCCESS) { 01370 switch_channel_event_set_data(channel, event); 01371 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Playback-File-Path", file); 01372 add_playback_vars_to_event(session, event, playback_vars); 01373 switch_event_fire(&event); 01374 } 01375 01376 for (;;) { 01377 int do_speed = 1; 01378 int last_speed = -1; 01379 int f; 01380 01381 if (!switch_channel_ready(channel)) { 01382 status = SWITCH_STATUS_FALSE; 01383 break; 01384 } 01385 01386 if ((f = switch_channel_test_flag(channel, CF_BREAK))) { 01387 switch_channel_clear_flag(channel, CF_BREAK); 01388 if (f == 2) { 01389 done = 1; 01390 } 01391 status = SWITCH_STATUS_BREAK; 01392 break; 01393 } 01394 01395 switch_ivr_parse_all_events(session); 01396 01397 if (args) { 01398 /* 01399 dtmf handler function you can hook up to be executed when a digit is dialed during playback 01400 if you return anything but SWITCH_STATUS_SUCCESS the playback will stop. 01401 */ 01402 if (switch_channel_has_dtmf(channel)) { 01403 if (!args->input_callback && !args->buf && !args->dmachine) { 01404 status = SWITCH_STATUS_BREAK; 01405 done = 1; 01406 break; 01407 } 01408 switch_channel_dequeue_dtmf(channel, &dtmf); 01409 01410 if (args->dmachine) { 01411 char ds[2] = {dtmf.digit, '\0'}; 01412 if ((status = switch_ivr_dmachine_feed(args->dmachine, ds, NULL)) != SWITCH_STATUS_SUCCESS) { 01413 break; 01414 } 01415 } 01416 01417 if (args->input_callback) { 01418 status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen); 01419 } else if (args->buf) { 01420 *((char *) args->buf) = dtmf.digit; 01421 status = SWITCH_STATUS_BREAK; 01422 } 01423 } 01424 01425 if (args->input_callback) { 01426 switch_event_t *event; 01427 01428 if (switch_core_session_dequeue_event(session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) { 01429 status = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen); 01430 switch_event_destroy(&event); 01431 } 01432 } 01433 01434 if (status != SWITCH_STATUS_SUCCESS) { 01435 done = 1; 01436 break; 01437 } 01438 } 01439 01440 if (switch_test_flag(fh, SWITCH_FILE_PAUSE)) { 01441 if (framelen > FILE_STARTSAMPLES) { 01442 framelen = FILE_STARTSAMPLES; 01443 } 01444 memset(abuf, 255, framelen); 01445 olen = ilen; 01446 do_speed = 0; 01447 } else if (fh->sp_audio_buffer && (eof || (switch_buffer_inuse(fh->sp_audio_buffer) > (switch_size_t) (framelen)))) { 01448 if (!(bread = switch_buffer_read(fh->sp_audio_buffer, abuf, framelen))) { 01449 if (eof) { 01450 continue; 01451 } else { 01452 break; 01453 } 01454 } 01455 01456 if (bread < framelen) { 01457 memset(abuf + bread, 255, framelen - bread); 01458 } 01459 01460 olen = switch_test_flag(fh, SWITCH_FILE_NATIVE) ? framelen : ilen; 01461 do_speed = 0; 01462 } else if (fh->audio_buffer && (eof || (switch_buffer_inuse(fh->audio_buffer) > (switch_size_t) (framelen)))) { 01463 if (!(bread = switch_buffer_read(fh->audio_buffer, abuf, framelen))) { 01464 if (eof) { 01465 break; 01466 } else { 01467 continue; 01468 } 01469 } 01470 01471 fh->offset_pos += switch_test_flag(fh, SWITCH_FILE_NATIVE) ? bread : bread / 2; 01472 01473 if (bread < framelen) { 01474 memset(abuf + bread, 255, framelen - bread); 01475 } 01476 01477 olen = switch_test_flag(fh, SWITCH_FILE_NATIVE) ? framelen : ilen; 01478 } else { 01479 if (eof) { 01480 break; 01481 } 01482 olen = FILE_STARTSAMPLES; 01483 if (!switch_test_flag(fh, SWITCH_FILE_NATIVE)) { 01484 olen /= 2; 01485 } 01486 if (switch_core_file_read(fh, abuf, &olen) != SWITCH_STATUS_SUCCESS) { 01487 eof++; 01488 continue; 01489 } 01490 01491 test_native = switch_test_flag(fh, SWITCH_FILE_NATIVE); 01492 01493 if (test_native != last_native) { 01494 if (test_native) { 01495 write_frame.codec = switch_core_session_get_read_codec(session); 01496 samples = read_impl.samples_per_packet; 01497 framelen = read_impl.encoded_bytes_per_packet; 01498 } else { 01499 write_frame.codec = &codec; 01500 samples = codec.implementation->samples_per_packet; 01501 framelen = codec.implementation->decoded_bytes_per_packet; 01502 } 01503 switch_buffer_zero(fh->audio_buffer); 01504 } 01505 01506 last_native = test_native; 01507 01508 switch_buffer_write(fh->audio_buffer, abuf, switch_test_flag(fh, SWITCH_FILE_NATIVE) ? olen : olen * 2); 01509 olen = switch_buffer_read(fh->audio_buffer, abuf, framelen); 01510 fh->offset_pos += olen / 2; 01511 01512 if (!switch_test_flag(fh, SWITCH_FILE_NATIVE)) { 01513 olen /= 2; 01514 } 01515 01516 } 01517 01518 if (done || olen <= 0) { 01519 break; 01520 } 01521 01522 if (!switch_test_flag(fh, SWITCH_FILE_NATIVE)) { 01523 if (fh->speed > 2) { 01524 fh->speed = 2; 01525 } else if (fh->speed < -2) { 01526 fh->speed = -2; 01527 } 01528 } 01529 01530 if (!switch_test_flag(fh, SWITCH_FILE_NATIVE) && fh->audio_buffer && last_speed > -1 && last_speed != fh->speed) { 01531 switch_buffer_zero(fh->sp_audio_buffer); 01532 } 01533 01534 if (switch_test_flag(fh, SWITCH_FILE_SEEK)) { 01535 /* file position has changed flush the buffer */ 01536 switch_buffer_zero(fh->audio_buffer); 01537 switch_clear_flag(fh, SWITCH_FILE_SEEK); 01538 } 01539 01540 01541 if (!switch_test_flag(fh, SWITCH_FILE_NATIVE) && fh->speed && do_speed) { 01542 float factor = 0.25f * abs(fh->speed); 01543 switch_size_t newlen, supplement, step; 01544 short *bp = write_frame.data; 01545 switch_size_t wrote = 0; 01546 01547 supplement = (int) (factor * olen); 01548 if (!supplement) { 01549 supplement = 1; 01550 } 01551 newlen = (fh->speed > 0) ? olen - supplement : olen + supplement; 01552 01553 step = (fh->speed > 0) ? (newlen / supplement) : (olen / supplement); 01554 01555 if (!fh->sp_audio_buffer) { 01556 switch_buffer_create_dynamic(&fh->sp_audio_buffer, 1024, 1024, 0); 01557 } 01558 01559 while ((wrote + step) < newlen) { 01560 switch_buffer_write(fh->sp_audio_buffer, bp, step * 2); 01561 wrote += step; 01562 bp += step; 01563 if (fh->speed > 0) { 01564 bp++; 01565 } else { 01566 float f; 01567 short s; 01568 f = (float) (*bp + *(bp + 1) + *(bp - 1)); 01569 f /= 3; 01570 s = (short) f; 01571 switch_buffer_write(fh->sp_audio_buffer, &s, 2); 01572 wrote++; 01573 } 01574 } 01575 if (wrote < newlen) { 01576 switch_size_t r = newlen - wrote; 01577 switch_buffer_write(fh->sp_audio_buffer, bp, r * 2); 01578 wrote += r; 01579 } 01580 last_speed = fh->speed; 01581 continue; 01582 } 01583 01584 if (olen < llen) { 01585 uint8_t *dp = (uint8_t *) write_frame.data; 01586 memset(dp + (int) olen, 255, (int) (llen - olen)); 01587 olen = llen; 01588 } 01589 01590 if (!more_data) { 01591 if (timer_name) { 01592 if (switch_core_timer_next(&timer) != SWITCH_STATUS_SUCCESS) { 01593 break; 01594 } 01595 } else { /* time off the channel (if you must) */ 01596 switch_frame_t *read_frame; 01597 switch_status_t tstatus; 01598 01599 while (switch_channel_ready(channel) && switch_channel_test_flag(channel, CF_HOLD)) { 01600 switch_ivr_parse_all_messages(session); 01601 switch_yield(10000); 01602 } 01603 01604 tstatus = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_SINGLE_READ, 0); 01605 01606 if (!SWITCH_READ_ACCEPTABLE(tstatus)) { 01607 break; 01608 } 01609 01610 if (args && args->dmachine) { 01611 if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL)) != SWITCH_STATUS_SUCCESS) { 01612 break; 01613 } 01614 } 01615 01616 if (args && (args->read_frame_callback)) { 01617 int ok = 1; 01618 switch_set_flag(fh, SWITCH_FILE_CALLBACK); 01619 if ((status = args->read_frame_callback(session, read_frame, args->user_data)) != SWITCH_STATUS_SUCCESS) { 01620 ok = 0; 01621 } 01622 switch_clear_flag(fh, SWITCH_FILE_CALLBACK); 01623 if (!ok) { 01624 break; 01625 } 01626 } 01627 } 01628 } 01629 01630 more_data = 0; 01631 write_frame.samples = (uint32_t) olen; 01632 01633 if (switch_test_flag(fh, SWITCH_FILE_NATIVE)) { 01634 write_frame.datalen = (uint32_t) olen; 01635 } else { 01636 write_frame.datalen = write_frame.samples * 2; 01637 } 01638 01639 llen = olen; 01640 01641 if (timer_name) { 01642 write_frame.timestamp = timer.samplecount; 01643 } 01644 #ifndef WIN32 01645 #if SWITCH_BYTE_ORDER == __BIG_ENDIAN 01646 if (!switch_test_flag(fh, SWITCH_FILE_NATIVE) && l16) { 01647 switch_swap_linear(write_frame.data, (int) write_frame.datalen / 2); 01648 } 01649 #endif 01650 #endif 01651 if (!switch_test_flag(fh, SWITCH_FILE_NATIVE) && fh->vol) { 01652 switch_change_sln_volume(write_frame.data, write_frame.datalen / 2, fh->vol); 01653 } 01654 01655 status = switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0); 01656 01657 if (timeout_samples) { 01658 timeout_samples -= write_frame.samples; 01659 if (timeout_samples <= 0) { 01660 timeout_samples = 0; 01661 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "timeout reached playing file\n"); 01662 status = SWITCH_STATUS_TIMEOUT; 01663 break; 01664 } 01665 } 01666 01667 01668 if (status == SWITCH_STATUS_MORE_DATA) { 01669 status = SWITCH_STATUS_SUCCESS; 01670 more_data = 1; 01671 continue; 01672 } else if (status != SWITCH_STATUS_SUCCESS) { 01673 done = 1; 01674 break; 01675 } 01676 01677 if (done) { 01678 break; 01679 } 01680 } 01681 01682 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "done playing file %s\n", file); 01683 01684 if (read_impl.samples_per_second) { 01685 switch_channel_set_variable_printf(channel, "playback_seconds", "%d", fh->samples_in / read_impl.samples_per_second); 01686 switch_channel_set_variable_printf(channel, "playback_ms", "%d", fh->samples_in / (read_impl.samples_per_second / 1000)); 01687 } 01688 switch_channel_set_variable_printf(channel, "playback_samples", "%d", fh->samples_in); 01689 01690 if (switch_event_create(&event, SWITCH_EVENT_PLAYBACK_STOP) == SWITCH_STATUS_SUCCESS) { 01691 switch_channel_event_set_data(channel, event); 01692 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Playback-File-Path", file); 01693 if (status == SWITCH_STATUS_BREAK) { 01694 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Playback-Status", "break"); 01695 } else { 01696 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Playback-Status", "done"); 01697 } 01698 add_playback_vars_to_event(session, event, playback_vars); 01699 switch_event_fire(&event); 01700 } 01701 01702 switch_core_session_io_write_lock(session); 01703 switch_channel_set_private(channel, "__fh", NULL); 01704 switch_core_session_io_rwunlock(session); 01705 01706 switch_core_file_close(fh); 01707 01708 if (fh->audio_buffer) { 01709 switch_buffer_destroy(&fh->audio_buffer); 01710 } 01711 01712 if (fh->sp_audio_buffer) { 01713 switch_buffer_destroy(&fh->sp_audio_buffer); 01714 } 01715 } 01716 01717 if (switch_core_codec_ready((&codec))) { 01718 switch_core_codec_destroy(&codec); 01719 } 01720 01721 if (timer.samplecount) { 01722 /* End the audio absorbing thread */ 01723 switch_core_thread_session_end(session); 01724 switch_core_timer_destroy(&timer); 01725 } 01726 01727 switch_safe_free(abuf); 01728 01729 switch_core_session_reset(session, SWITCH_FALSE, SWITCH_FALSE); 01730 return status; 01731 }
| switch_status_t switch_ivr_process_indications | ( | switch_core_session_t * | session, | |
| switch_core_session_message_t * | message | |||
| ) |
Definition at line 725 of file switch_ivr.c.
References SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER, switch_channel_answer, switch_channel_hangup, switch_channel_pre_answer, switch_channel_ring_ready, switch_core_session_get_channel(), SWITCH_MESSAGE_INDICATE_ANSWER, SWITCH_MESSAGE_INDICATE_PROGRESS, SWITCH_MESSAGE_INDICATE_RINGING, SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.
Referenced by switch_core_session_flush_message(), and switch_ivr_parse_all_messages().
00726 { 00727 switch_status_t status = SWITCH_STATUS_SUCCESS; 00728 switch_channel_t *channel = switch_core_session_get_channel(session); 00729 00730 switch(message->message_id) { 00731 case SWITCH_MESSAGE_INDICATE_ANSWER: 00732 if (switch_channel_answer(channel) != SWITCH_STATUS_SUCCESS) { 00733 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); 00734 } 00735 break; 00736 case SWITCH_MESSAGE_INDICATE_PROGRESS: 00737 if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) { 00738 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); 00739 } 00740 break; 00741 case SWITCH_MESSAGE_INDICATE_RINGING: 00742 if (switch_channel_ring_ready(channel) != SWITCH_STATUS_SUCCESS) { 00743 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); 00744 } 00745 break; 00746 default: 00747 status = SWITCH_STATUS_FALSE; 00748 break; 00749 } 00750 00751 return status; 00752 }
| 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
| session | the session to record from | |
| fh | file handle to use | |
| file | the path to the file | |
| args | arguements to pass for callbacks etc | |
| limit | max limit to record for (0 for infinite) |
Referenced by fs_switch_ivr_record_file(), and CoreSession::recordFile().
| 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.
| session | the session to record | |
| file | the path to the file | |
| limit | stop recording after this amount of time (in ms, 0 = never stop) | |
| fh | file handle to use (NULL for builtin one) |
Definition at line 1646 of file switch_ivr_async.c.
References switch_codec_implementation::actual_samples_per_second, switch_directories::base_dir, switch_codec_implementation::decoded_bytes_per_packet, eavesdrop_pvt::flags, record_helper::hangup_on_error, switch_codec_implementation::number_of_channels, record_callback(), SMBF_ANSWER_REQ, SMBF_READ_PING, SMBF_READ_STREAM, SMBF_STEREO, SMBF_STEREO_SWAP, SMBF_WRITE_STREAM, SWITCH_AUDIO_COL_STR_ARTIST, SWITCH_AUDIO_COL_STR_COMMENT, SWITCH_AUDIO_COL_STR_COPYRIGHT, SWITCH_AUDIO_COL_STR_DATE, SWITCH_AUDIO_COL_STR_SOFTWARE, SWITCH_AUDIO_COL_STR_TITLE, 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_channel_set_variable, switch_core_file_close(), switch_core_file_open, switch_core_file_set_string(), switch_core_media_bug_add(), switch_core_media_bug_set_pre_buffer_framecount(), switch_core_session_alloc, switch_core_session_get_channel(), switch_core_session_get_partner(), switch_core_session_get_pool(), switch_core_session_get_read_codec(), switch_core_session_get_read_impl(), switch_core_session_reset(), switch_core_session_rwunlock(), switch_core_session_sprintf(), switch_core_session_strdup, SWITCH_DEFAULT_DIR_PERMS, SWITCH_DEFAULT_FILE_BUFFER_LEN, switch_dir_make_recursive(), switch_epoch_time_now(), SWITCH_FALSE, SWITCH_FILE_DATA_SHORT, SWITCH_FILE_FLAG_WRITE, SWITCH_FILE_WRITE_APPEND, switch_find_end_paren(), SWITCH_GLOBAL_dirs, switch_is_file_path(), switch_is_valid_rate, switch_ivr_stop_record_session(), SWITCH_LOG_ERROR, switch_log_printf(), SWITCH_LOG_WARNING, SWITCH_PATH_SEPARATOR, SWITCH_STATUS_FALSE, SWITCH_STATUS_GENERR, SWITCH_STATUS_MEMERR, SWITCH_STATUS_SUCCESS, switch_str_nil, switch_true(), and SWITCH_TRUE.
Referenced by switch_core_media_bug_transfer_recordings().
01647 { 01648 switch_channel_t *channel = switch_core_session_get_channel(session); 01649 const char *p; 01650 const char *vval; 01651 switch_media_bug_t *bug; 01652 switch_status_t status; 01653 time_t to = 0; 01654 switch_media_bug_flag_t flags = SMBF_READ_STREAM | SMBF_WRITE_STREAM | SMBF_READ_PING; 01655 uint8_t channels; 01656 switch_codec_implementation_t read_impl = { 0 }; 01657 struct record_helper *rh = NULL; 01658 int file_flags = SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_DATA_SHORT; 01659 switch_bool_t hangup_on_error = SWITCH_FALSE; 01660 char *file_path = NULL; 01661 01662 if ((p = switch_channel_get_variable(channel, "RECORD_HANGUP_ON_ERROR"))) { 01663 hangup_on_error = switch_true(p); 01664 } 01665 01666 switch_core_session_get_read_impl(session, &read_impl); 01667 01668 if ((status = switch_channel_pre_answer(channel)) != SWITCH_STATUS_SUCCESS) { 01669 return SWITCH_STATUS_FALSE; 01670 } 01671 01672 if (!switch_channel_media_up(channel) || !switch_core_session_get_read_codec(session)) { 01673 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can not record session. Media not enabled on channel\n"); 01674 return SWITCH_STATUS_FALSE; 01675 } 01676 01677 channels = read_impl.number_of_channels; 01678 01679 if ((bug = switch_channel_get_private(channel, file))) { 01680 if (switch_true(switch_channel_get_variable(channel, "RECORD_TOGGLE_ON_REPEAT"))) { 01681 return switch_ivr_stop_record_session(session, file); 01682 } 01683 01684 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Already recording [%s]\n", file); 01685 return SWITCH_STATUS_SUCCESS; 01686 } 01687 01688 01689 if ((p = switch_channel_get_variable(channel, "RECORD_CHECK_BRIDGE")) && switch_true(p)) { 01690 switch_core_session_t *other_session; 01691 int exist = 0; 01692 switch_status_t rstatus = SWITCH_STATUS_SUCCESS; 01693 01694 if (switch_core_session_get_partner(session, &other_session) == SWITCH_STATUS_SUCCESS) { 01695 switch_channel_t *other_channel = switch_core_session_get_channel(other_session); 01696 if ((bug = switch_channel_get_private(other_channel, file))) { 01697 if (switch_true(switch_channel_get_variable(other_channel, "RECORD_TOGGLE_ON_REPEAT"))) { 01698 rstatus = switch_ivr_stop_record_session(other_session, file); 01699 } else { 01700 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(other_session), SWITCH_LOG_WARNING, "Already recording [%s]\n", file); 01701 } 01702 exist = 1; 01703 } 01704 switch_core_session_rwunlock(other_session); 01705 } 01706 01707 if (exist) { 01708 return rstatus; 01709 } 01710 } 01711 01712 if (!fh) { 01713 if (!(fh = switch_core_session_alloc(session, sizeof(*fh)))) { 01714 return SWITCH_STATUS_MEMERR; 01715 } 01716 } 01717 01718 if ((p = switch_channel_get_variable(channel, "RECORD_WRITE_ONLY")) && switch_true(p)) { 01719 flags &= ~SMBF_READ_STREAM; 01720 flags |= SMBF_WRITE_STREAM; 01721 } 01722 01723 if ((p = switch_channel_get_variable(channel, "RECORD_READ_ONLY")) && switch_true(p)) { 01724 flags &= ~SMBF_WRITE_STREAM; 01725 flags |= SMBF_READ_STREAM; 01726 } 01727 01728 if ((p = switch_channel_get_variable(channel, "RECORD_STEREO")) && switch_true(p)) { 01729 flags |= SMBF_STEREO; 01730 flags &= ~SMBF_STEREO_SWAP; 01731 channels = 2; 01732 } 01733 01734 if ((p = switch_channel_get_variable(channel, "RECORD_STEREO_SWAP")) && switch_true(p)) { 01735 flags |= SMBF_STEREO; 01736 flags |= SMBF_STEREO_SWAP; 01737 channels = 2; 01738 } 01739 01740 if ((p = switch_channel_get_variable(channel, "RECORD_ANSWER_REQ")) && switch_true(p)) { 01741 flags |= SMBF_ANSWER_REQ; 01742 } 01743 01744 if ((p = switch_channel_get_variable(channel, "RECORD_APPEND")) && switch_true(p)) { 01745 file_flags |= SWITCH_FILE_WRITE_APPEND; 01746 } 01747 01748 01749 fh->samplerate = 0; 01750 if ((vval = switch_channel_get_variable(channel, "record_sample_rate"))) { 01751 int tmp = 0; 01752 01753 tmp = atoi(vval); 01754 01755 if (switch_is_valid_rate(tmp)) { 01756 fh->samplerate = tmp; 01757 } 01758 } 01759 01760 if (!fh->samplerate) { 01761 fh->samplerate = read_impl.actual_samples_per_second; 01762 } 01763 01764 fh->channels = channels; 01765 01766 if ((vval = switch_channel_get_variable(channel, "enable_file_write_buffering"))) { 01767 int tmp = atoi(vval); 01768 01769 if (tmp > 0) { 01770 fh->pre_buffer_datalen = tmp; 01771 } else if (switch_true(vval)) { 01772 fh->pre_buffer_datalen = SWITCH_DEFAULT_FILE_BUFFER_LEN; 01773 } 01774 01775 } else { 01776 fh->pre_buffer_datalen = SWITCH_DEFAULT_FILE_BUFFER_LEN; 01777 } 01778 01779 01780 if (!switch_is_file_path(file)) { 01781 char *tfile = NULL; 01782 char *e; 01783 const char *prefix; 01784 01785 prefix = switch_channel_get_variable(channel, "sound_prefix"); 01786 01787 if (!prefix) { 01788 prefix = SWITCH_GLOBAL_dirs.base_dir; 01789 } 01790 01791 if (*file == '[') { 01792 tfile = switch_core_session_strdup(session, file); 01793 if ((e = switch_find_end_paren(tfile, '[', ']'))) { 01794 *e = '\0'; 01795 file = e + 1; 01796 } else { 01797 tfile = NULL; 01798 } 01799 } else { 01800 file_path = switch_core_session_sprintf(session, "%s%s%s", prefix, SWITCH_PATH_SEPARATOR, file); 01801 } 01802 01803 file = switch_core_session_sprintf(session, "%s%s%s%s%s", switch_str_nil(tfile), tfile ? "]" : "", prefix, SWITCH_PATH_SEPARATOR, file); 01804 } else { 01805 file_path = switch_core_session_strdup(session, file); 01806 } 01807 01808 if (file_path) { 01809 char *p; 01810 char *path = switch_core_session_strdup(session, file_path); 01811 01812 if ((p = strrchr(path, *SWITCH_PATH_SEPARATOR))) { 01813 *p = '\0'; 01814 if (switch_dir_make_recursive(path, SWITCH_DEFAULT_DIR_PERMS, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { 01815 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error creating %s\n", path); 01816 return SWITCH_STATUS_GENERR; 01817 } 01818 01819 } else { 01820 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error finding the folder path section in '%s'\n", path); 01821 path = NULL; 01822 } 01823 } 01824 01825 if (switch_core_file_open(fh, file, channels, read_impl.actual_samples_per_second, file_flags, NULL) != SWITCH_STATUS_SUCCESS) { 01826 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error opening %s\n", file); 01827 if (hangup_on_error) { 01828 switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); 01829 switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE); 01830 } 01831 return SWITCH_STATUS_GENERR; 01832 } 01833 01834 if ((p = switch_channel_get_variable(channel, "RECORD_TITLE"))) { 01835 vval = (const char *) switch_core_session_strdup(session, p); 01836 switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_TITLE, vval); 01837 switch_channel_set_variable(channel, "RECORD_TITLE", NULL); 01838 } 01839 01840 if ((p = switch_channel_get_variable(channel, "RECORD_COPYRIGHT"))) { 01841 vval = (const char *) switch_core_session_strdup(session, p); 01842 switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_COPYRIGHT, vval); 01843 switch_channel_set_variable(channel, "RECORD_COPYRIGHT", NULL); 01844 } 01845 01846 if ((p = switch_channel_get_variable(channel, "RECORD_SOFTWARE"))) { 01847 vval = (const char *) switch_core_session_strdup(session, p); 01848 switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_SOFTWARE, vval); 01849 switch_channel_set_variable(channel, "RECORD_SOFTWARE", NULL); 01850 } 01851 01852 if ((p = switch_channel_get_variable(channel, "RECORD_ARTIST"))) { 01853 vval = (const char *) switch_core_session_strdup(session, p); 01854 switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_ARTIST, vval); 01855 switch_channel_set_variable(channel, "RECORD_ARTIST", NULL); 01856 } 01857 01858 if ((p = switch_channel_get_variable(channel, "RECORD_COMMENT"))) { 01859 vval = (const char *) switch_core_session_strdup(session, p); 01860 switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_COMMENT, vval); 01861 switch_channel_set_variable(channel, "RECORD_COMMENT", NULL); 01862 } 01863 01864 if ((p = switch_channel_get_variable(channel, "RECORD_DATE"))) { 01865 vval = (const char *) switch_core_session_strdup(session, p); 01866 switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_DATE, vval); 01867 switch_channel_set_variable(channel, "RECORD_DATE", NULL); 01868 } 01869 01870 if (limit) { 01871 to = switch_epoch_time_now(NULL) + limit; 01872 } 01873 01874 rh = switch_core_session_alloc(session, sizeof(*rh)); 01875 rh->fh = fh; 01876 rh->file = switch_core_session_strdup(session, file); 01877 rh->packet_len = read_impl.decoded_bytes_per_packet; 01878 01879 if (file_flags & SWITCH_FILE_WRITE_APPEND) { 01880 rh->min_sec = 3; 01881 } 01882 01883 if ((p = switch_channel_get_variable(channel, "RECORD_MIN_SEC"))) { 01884 int tmp = atoi(p); 01885 if (tmp >= 0) { 01886 rh->min_sec = tmp; 01887 } 01888 } 01889 01890 rh->hangup_on_error = hangup_on_error; 01891 01892 if ((status = switch_core_media_bug_add(session, "session_record", file, 01893 record_callback, rh, to, flags, &bug)) != SWITCH_STATUS_SUCCESS) { 01894 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error adding media bug for file %s\n", file); 01895 switch_core_file_close(fh); 01896 return status; 01897 } 01898 01899 if ((p = switch_channel_get_variable(channel, "RECORD_PRE_BUFFER_FRAMES"))) { 01900 int tmp = atoi(p); 01901 01902 if (tmp > 0) { 01903 switch_core_media_bug_set_pre_buffer_framecount(bug, tmp); 01904 } 01905 } else { 01906 switch_core_media_bug_set_pre_buffer_framecount(bug, 25); 01907 } 01908 01909 switch_channel_set_private(channel, file, bug); 01910 01911 return SWITCH_STATUS_SUCCESS; 01912 }
| switch_status_t switch_ivr_resume_detect_speech | ( | switch_core_session_t * | session | ) |
Resume background Speech detection on a session.
| session | The session to resume detection on |
Definition at line 3684 of file switch_ivr_async.c.
References speech_thread_handle::ah, switch_channel_get_private(), switch_core_asr_resume(), switch_core_session_get_channel(), SWITCH_SPEECH_KEY, SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.
Referenced by speech_thread().
03685 { 03686 switch_channel_t *channel = switch_core_session_get_channel(session); 03687 struct speech_thread_handle *sth = switch_channel_get_private(channel, SWITCH_SPEECH_KEY); 03688 03689 if (sth) { 03690 switch_core_asr_resume(sth->ah); 03691 return SWITCH_STATUS_SUCCESS; 03692 } 03693 return SWITCH_STATUS_FALSE; 03694 }
| 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.
| runtime | when (in epoch time) to run the broadcast | |
| uuid | the uuid of the session to broadcast on | |
| path | the path data of the broadcast "/path/to/file.wav [<timer name>]" or "speak:<engine>|<voice>|<Text to say>" | |
| flags | flags to send to the request (SMF_ECHO_BRIDGED to send the broadcast to both sides of the call) |
Definition at line 4009 of file switch_ivr_async.c.
References __SWITCH_FUNC__, broadcast_helper::flags, SSHF_FREE_ARG, switch_copy_string(), switch_scheduler_add_task(), switch_zmalloc, and broadcast_helper::uuid_str.
04010 { 04011 struct broadcast_helper *helper; 04012 size_t len = sizeof(*helper) + strlen(path) + 1; 04013 char *cur = NULL; 04014 04015 switch_zmalloc(cur, len); 04016 helper = (struct broadcast_helper *) cur; 04017 04018 cur += sizeof(*helper); 04019 switch_copy_string(helper->uuid_str, uuid, sizeof(helper->uuid_str)); 04020 helper->flags = flags; 04021 04022 switch_copy_string(cur, path, len - sizeof(helper)); 04023 helper->path = cur; 04024 04025 return switch_scheduler_add_task(runtime, sch_broadcast_callback, (char *) __SWITCH_FUNC__, uuid, 0, helper, SSHF_FREE_ARG); 04026 }
| 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.
| runtime | the time (int epoch seconds) to transfer the call | |
| uuid | the uuid of the session to hangup | |
| cause | the hanup cause code | |
| bleg | hangup up the B-Leg if possible |
Definition at line 3912 of file switch_ivr_async.c.
References __SWITCH_FUNC__, hangup_helper::bleg, hangup_helper::cause, SSHF_FREE_ARG, switch_copy_string(), switch_scheduler_add_task(), switch_zmalloc, and hangup_helper::uuid_str.
03913 { 03914 struct hangup_helper *helper; 03915 size_t len = sizeof(*helper); 03916 03917 switch_zmalloc(helper, len); 03918 03919 switch_copy_string(helper->uuid_str, uuid, sizeof(helper->uuid_str)); 03920 helper->cause = cause; 03921 helper->bleg = bleg; 03922 03923 return switch_scheduler_add_task(runtime, sch_hangup_callback, (char *) __SWITCH_FUNC__, uuid, 0, helper, SSHF_FREE_ARG); 03924 }
| 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.
| runtime | the time (int epoch seconds) to transfer the call | |
| uuid | the uuid of the session to transfer | |
| extension | the new extension | |
| dialplan | the new dialplan (OPTIONAL, may be NULL) | |
| context | the new context (OPTIONAL, may be NULL) |
Definition at line 3949 of file switch_ivr_async.c.
References __SWITCH_FUNC__, transfer_helper::context, transfer_helper::dialplan, transfer_helper::extension, SSHF_FREE_ARG, switch_copy_string(), switch_scheduler_add_task(), switch_zmalloc, and transfer_helper::uuid_str.
03950 { 03951 struct transfer_helper *helper; 03952 size_t len = sizeof(*helper); 03953 char *cur = NULL; 03954 03955 if (extension) { 03956 len += strlen(extension) + 1; 03957 } 03958 03959 if (dialplan) { 03960 len += strlen(dialplan) + 1; 03961 } 03962 03963 if (context) { 03964 len += strlen(context) + 1; 03965 } 03966 03967 switch_zmalloc(cur, len); 03968 helper = (struct transfer_helper *) cur; 03969 03970 switch_copy_string(helper->uuid_str, uuid, sizeof(helper->uuid_str)); 03971 03972 cur += sizeof(*helper); 03973 03974 if (extension) { 03975 switch_copy_string(cur, extension, strlen(extension) + 1); 03976 helper->extension = cur; 03977 cur += strlen(helper->extension) + 1; 03978 } 03979 03980 if (dialplan) { 03981 switch_copy_string(cur, dialplan, strlen(dialplan) + 1); 03982 helper->dialplan = cur; 03983 cur += strlen(helper->dialplan) + 1; 03984 } 03985 03986 if (context) { 03987 switch_copy_string(cur, context, strlen(context) + 1); 03988 helper->context = cur; 03989 } 03990 03991 return switch_scheduler_add_task(runtime, sch_transfer_callback, (char *) __SWITCH_FUNC__, uuid, 0, helper, SSHF_FREE_ARG); 03992 }
| switch_status_t switch_ivr_session_audio | ( | switch_core_session_t * | session, | |
| const char * | cmd, | |||
| const char * | direction, | |||
| int | level | |||
| ) |
Definition at line 2278 of file switch_ivr_async.c.
References switch_session_audio_t::read_level, switch_session_audio_t::read_mute, session_audio_callback(), SMBF_NO_PAUSE, SMBF_READ_REPLACE, SMBF_WRITE_REPLACE, switch_channel_get_private(), switch_channel_pre_answer, switch_channel_set_private(), switch_core_media_bug_add(), switch_core_media_bug_get_user_data(), switch_core_media_bug_set_flag(), switch_core_session_alloc, switch_core_session_get_channel(), switch_core_session_get_read_impl(), SWITCH_STATUS_FALSE, SWITCH_STATUS_MEMERR, SWITCH_STATUS_SUCCESS, switch_session_audio_t::write_level, and switch_session_audio_t::write_mute.
02279 { 02280 switch_channel_t *channel = switch_core_session_get_channel(session); 02281 switch_media_bug_t *bug; 02282 switch_status_t status; 02283 switch_session_audio_t *pvt; 02284 switch_codec_implementation_t read_impl = { 0 }; 02285 int existing = 0, c_read = 0, c_write = 0, flags = SMBF_NO_PAUSE; 02286 02287 if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) { 02288 return SWITCH_STATUS_FALSE; 02289 } 02290 02291 switch_core_session_get_read_impl(session, &read_impl); 02292 02293 02294 if ((bug = switch_channel_get_private(channel, "__audio"))) { 02295 pvt = switch_core_media_bug_get_user_data(bug); 02296 existing = 1; 02297 } else { 02298 if (!(pvt = switch_core_session_alloc(session, sizeof(*pvt)))) { 02299 return SWITCH_STATUS_MEMERR; 02300 } 02301 02302 pvt->session = session; 02303 } 02304 02305 02306 if (!strcasecmp(direction, "write")) { 02307 flags = SMBF_WRITE_REPLACE; 02308 c_write = 1; 02309 } else if (!strcasecmp(direction, "read")) { 02310 flags = SMBF_READ_REPLACE; 02311 c_read = 1; 02312 } else if (!strcasecmp(direction, "both")) { 02313 flags = SMBF_READ_REPLACE | SMBF_WRITE_REPLACE; 02314 c_read = c_write = 1; 02315 } 02316 02317 02318 if (!strcasecmp(cmd, "mute")) { 02319 if (c_read) { 02320 pvt->read_mute = level; 02321 pvt->read_level = 0; 02322 } 02323 if (c_write) { 02324 pvt->write_mute = level; 02325 pvt->write_level = 0; 02326 } 02327 } else if (!strcasecmp(cmd, "level")) { 02328 if (level < 5 && level > -5) { 02329 if (c_read) { 02330 pvt->read_level = level; 02331 } 02332 if (c_write) { 02333 pvt->write_level = level; 02334 } 02335 } 02336 } 02337 02338 if (existing) { 02339 switch_core_media_bug_set_flag(bug, flags); 02340 } else { 02341 if ((status = switch_core_media_bug_add(session, "audio", cmd, 02342 session_audio_callback, pvt, 0, flags, &bug)) != SWITCH_STATUS_SUCCESS) { 02343 return status; 02344 } 02345 02346 switch_channel_set_private(channel, "__audio", bug); 02347 } 02348 02349 02350 return SWITCH_STATUS_SUCCESS; 02351 }
| void switch_ivr_session_echo | ( | switch_core_session_t * | session, | |
| switch_input_args_t * | args | |||
| ) |
| session | the session to act on |
Definition at line 599 of file switch_ivr_async.c.
References CF_BREAK, CF_VIDEO, switch_dtmf_t::digit, SFF_CNG, switch_channel_clear_flag(), switch_channel_dequeue_dtmf(), switch_channel_has_dtmf(), switch_channel_pre_answer, switch_channel_ready, switch_channel_test_flag(), switch_cond_next(), switch_core_session_dequeue_event(), switch_core_session_get_channel(), switch_core_session_get_pool(), switch_core_session_read_frame(), switch_core_session_read_video_frame(), switch_core_session_write_frame(), switch_core_session_write_video_frame(), switch_event_destroy(), SWITCH_FALSE, SWITCH_INPUT_TYPE_DTMF, SWITCH_INPUT_TYPE_EVENT, SWITCH_IO_FLAG_NONE, switch_ivr_parse_all_events(), SWITCH_READ_ACCEPTABLE, SWITCH_STATUS_BREAK, SWITCH_STATUS_SUCCESS, switch_test_flag, switch_thread_create(), SWITCH_THREAD_STACKSIZE, switch_threadattr_create(), switch_threadattr_detach_set(), and switch_threadattr_stacksize_set().
00600 { 00601 switch_status_t status; 00602 switch_frame_t *read_frame; 00603 switch_channel_t *channel = switch_core_session_get_channel(session); 00604 #ifdef SWITCH_VIDEO_IN_THREADS 00605 struct echo_helper eh = { 0 }; 00606 switch_thread_t *thread; 00607 switch_threadattr_t *thd_attr = NULL; 00608 #endif 00609 00610 if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) { 00611 return; 00612 } 00613 #ifdef SWITCH_VIDEO_IN_THREADS 00614 if (switch_channel_test_flag(channel, CF_VIDEO)) { 00615 eh.session = session; 00616 switch_threadattr_create(&thd_attr, switch_core_session_get_pool(session)); 00617 switch_threadattr_detach_set(thd_attr, 1); 00618 switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); 00619 switch_thread_create(&thread, thd_attr, echo_video_thread, &eh, switch_core_session_get_pool(session)); 00620 } 00621 #endif 00622 00623 while (switch_channel_ready(channel)) { 00624 status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); 00625 if (!SWITCH_READ_ACCEPTABLE(status)) { 00626 break; 00627 } 00628 00629 switch_ivr_parse_all_events(session); 00630 00631 if (args && (args->input_callback || args->buf || args->buflen)) { 00632 switch_dtmf_t dtmf = {0}; 00633 00634 /* 00635 dtmf handler function you can hook up to be executed when a digit is dialed during playback 00636 if you return anything but SWITCH_STATUS_SUCCESS the playback will stop. 00637 */ 00638 if (switch_channel_has_dtmf(channel)) { 00639 if (!args->input_callback && !args->buf) { 00640 status = SWITCH_STATUS_BREAK; 00641 break; 00642 } 00643 switch_channel_dequeue_dtmf(channel, &dtmf); 00644 if (args->input_callback) { 00645 status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen); 00646 } else { 00647 *((char *) args->buf) = dtmf.digit; 00648 status = SWITCH_STATUS_BREAK; 00649 } 00650 } 00651 00652 if (args->input_callback) { 00653 switch_event_t *event = NULL; 00654 00655 if (switch_core_session_dequeue_event(session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) { 00656 status = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen); 00657 switch_event_destroy(&event); 00658 } 00659 } 00660 00661 if (status != SWITCH_STATUS_SUCCESS) { 00662 break; 00663 } 00664 } 00665 00666 00667 switch_core_session_write_frame(session, read_frame, SWITCH_IO_FLAG_NONE, 0); 00668 00669 #ifndef SWITCH_VIDEO_IN_THREADS 00670 status = switch_core_session_read_video_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); 00671 00672 if (!SWITCH_READ_ACCEPTABLE(status)) { 00673 break; 00674 } 00675 00676 if (switch_test_flag(read_frame, SFF_CNG)) { 00677 continue; 00678 } 00679 00680 switch_core_session_write_video_frame(session, read_frame, SWITCH_IO_FLAG_NONE, 0); 00681 #endif 00682 00683 if (switch_channel_test_flag(channel, CF_BREAK)) { 00684 switch_channel_clear_flag(channel, CF_BREAK); 00685 break; 00686 } 00687 } 00688 00689 #ifdef SWITCH_VIDEO_IN_THREADS 00690 if (eh.up) { 00691 while (eh.up) { 00692 switch_cond_next(); 00693 } 00694 } 00695 #endif 00696 00697 }
| 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.
| session | the session to transfer | |
| extension | the new extension | |
| dialplan | the new dialplan (OPTIONAL, may be NULL) | |
| context | the new context (OPTIONAL, may be NULL) |
Referenced by fs_switch_ivr_session_transfer(), switch_ivr_multi_threaded_bridge(), switch_play_and_get_digits(), SWITCH_STANDARD_SCHED_FUNC(), CoreSession::transfer(), transfer_after_bridge(), and uuid_bridge_on_soft_execute().
| switch_status_t switch_ivr_set_param_detect_speech | ( | switch_core_session_t * | session, | |
| const char * | name, | |||
| const char * | val | |||
| ) |
Definition at line 3712 of file switch_ivr_async.c.
References speech_thread_handle::ah, switch_channel_get_private(), switch_core_asr_text_param(), switch_core_session_get_channel(), SWITCH_SPEECH_KEY, SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.
03713 { 03714 struct speech_thread_handle *sth = switch_channel_get_private(switch_core_session_get_channel(session), SWITCH_SPEECH_KEY); 03715 switch_status_t status = SWITCH_STATUS_FALSE; 03716 03717 if (sth && sth->ah && name && val) { 03718 switch_core_asr_text_param(sth->ah, (char *) name, val); 03719 status = SWITCH_STATUS_SUCCESS; 03720 } 03721 03722 return status; 03723 }
| int switch_ivr_set_xml_chan_vars | ( | switch_xml_t | xml, | |
| switch_channel_t * | channel, | |||
| int | off | |||
| ) |
Definition at line 2150 of file switch_ivr.c.
References switch_event_header::array, switch_event_header::idx, switch_event_header::name, switch_event_header::next, switch_channel_variable_first(), switch_ivr_set_xml_chan_var(), and switch_event_header::value.
Referenced by switch_ivr_generate_xml_cdr().
02151 { 02152 02153 switch_event_header_t *hi = switch_channel_variable_first(channel); 02154 02155 if (!hi) 02156 return off; 02157 02158 for (; hi; hi = hi->next) { 02159 if (hi->idx) { 02160 int i; 02161 02162 for (i = 0; i < hi->idx; i++) { 02163 off = switch_ivr_set_xml_chan_var(xml, hi->name, hi->array[i], off); 02164 } 02165 } else { 02166 off = switch_ivr_set_xml_chan_var(xml, hi->name, hi->value, off); 02167 } 02168 } 02169 switch_channel_variable_last(channel); 02170 02171 return off; 02172 }
| int switch_ivr_set_xml_profile_data | ( | switch_xml_t | xml, | |
| switch_caller_profile_t * | caller_profile, | |||
| int | off | |||
| ) |
Definition at line 2025 of file switch_ivr.c.
References switch_xml_add_child_d, and switch_xml_set_txt_d.
Referenced by switch_ivr_generate_xml_cdr().
02026 { 02027 switch_xml_t param; 02028 02029 if (!(param = switch_xml_add_child_d(xml, "username", off++))) { 02030 return -1; 02031 } 02032 switch_xml_set_txt_d(param, caller_profile->username); 02033 02034 if (!(param = switch_xml_add_child_d(xml, "dialplan", off++))) { 02035 return -1; 02036 } 02037 switch_xml_set_txt_d(param, caller_profile->dialplan); 02038 02039 if (!(param = switch_xml_add_child_d(xml, "caller_id_name", off++))) { 02040 return -1; 02041 } 02042 switch_xml_set_txt_d(param, caller_profile->caller_id_name); 02043 02044 if (!(param = switch_xml_add_child_d(xml, "caller_id_number", off++))) { 02045 return -1; 02046 } 02047 switch_xml_set_txt_d(param, caller_profile->caller_id_number); 02048 02049 if (!(param = switch_xml_add_child_d(xml, "callee_id_name", off++))) { 02050 return -1; 02051 } 02052 switch_xml_set_txt_d(param, caller_profile->callee_id_name); 02053 02054 if (!(param = switch_xml_add_child_d(xml, "callee_id_number", off++))) { 02055 return -1; 02056 } 02057 switch_xml_set_txt_d(param, caller_profile->callee_id_number); 02058 02059 if (!(param = switch_xml_add_child_d(xml, "ani", off++))) { 02060 return -1; 02061 } 02062 switch_xml_set_txt_d(param, caller_profile->ani); 02063 02064 if (!(param = switch_xml_add_child_d(xml, "aniii", off++))) { 02065 return -1; 02066 } 02067 switch_xml_set_txt_d(param, caller_profile->aniii); 02068 02069 02070 if (!(param = switch_xml_add_child_d(xml, "network_addr", off++))) { 02071 return -1; 02072 } 02073 switch_xml_set_txt_d(param, caller_profile->network_addr); 02074 02075 if (!(param = switch_xml_add_child_d(xml, "rdnis", off++))) { 02076 return -1; 02077 } 02078 switch_xml_set_txt_d(param, caller_profile->rdnis); 02079 02080 if (!(param = switch_xml_add_child_d(xml, "destination_number", off++))) { 02081 return -1; 02082 } 02083 switch_xml_set_txt_d(param, caller_profile->destination_number); 02084 02085 if (!(param = switch_xml_add_child_d(xml, "uuid", off++))) { 02086 return -1; 02087 } 02088 switch_xml_set_txt_d(param, caller_profile->uuid); 02089 02090 if (!(param = switch_xml_add_child_d(xml, "source", off++))) { 02091 return -1; 02092 } 02093 switch_xml_set_txt_d(param, caller_profile->source); 02094 02095 if (caller_profile->transfer_source) { 02096 if (!(param = switch_xml_add_child_d(xml, "transfer_source", off++))) { 02097 return -1; 02098 } 02099 switch_xml_set_txt_d(param, caller_profile->transfer_source); 02100 } 02101 02102 if (!(param = switch_xml_add_child_d(xml, "context", off++))) { 02103 return -1; 02104 } 02105 switch_xml_set_txt_d(param, caller_profile->context); 02106 02107 if (!(param = switch_xml_add_child_d(xml, "chan_name", off++))) { 02108 return -1; 02109 } 02110 switch_xml_set_txt_d(param, caller_profile->chan_name); 02111 02112 02113 if (caller_profile->soft) { 02114 profile_node_t *pn; 02115 02116 for (pn = caller_profile->soft; pn; pn = pn->next) { 02117 02118 if (!(param = switch_xml_add_child_d(xml, pn->var, off++))) { 02119 return -1; 02120 } 02121 switch_xml_set_txt_d(param, pn->val); 02122 } 02123 02124 } 02125 02126 02127 return off; 02128 }
| 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.
| session | one session | |
| peer_session | the other session |
Definition at line 1108 of file switch_ivr_bridge.c.
References CF_BRIDGE_ORIGINATOR, CF_BRIDGED, CF_RESET, CF_SIGNAL_BRIDGE_TTL, CF_TRANSFER, check_bridge_export(), CS_HIBERNATE, signal_bridge_state_handlers, SWITCH_CAUSE_ORIGINATOR_CANCEL, switch_channel_add_state_handler(), switch_channel_clear_flag(), switch_channel_clear_state_handler(), switch_channel_down_nosig, switch_channel_event_set_data(), switch_channel_get_cause(), switch_channel_hangup, switch_channel_set_bridge_time(), switch_channel_set_flag, switch_channel_set_flag_recursive(), switch_channel_set_state, switch_channel_set_state_flag(), switch_channel_set_variable, switch_channel_test_flag(), switch_channel_up_nosig, switch_core_session_get_channel(), switch_core_session_get_uuid(), switch_event_add_header_string(), SWITCH_EVENT_CHANNEL_EXECUTE, switch_event_create, switch_event_fire, switch_ivr_bridge_display(), SWITCH_SIGNAL_BRIDGE_VARIABLE, SWITCH_STACK_BOTTOM, SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.
Referenced by switch_ivr_multi_threaded_bridge(), and switch_ivr_nomedia().
01109 { 01110 switch_channel_t *caller_channel = switch_core_session_get_channel(session); 01111 switch_channel_t *peer_channel = switch_core_session_get_channel(peer_session); 01112 switch_event_t *event; 01113 01114 if (switch_channel_down_nosig(peer_channel)) { 01115 switch_channel_hangup(caller_channel, switch_channel_get_cause(peer_channel)); 01116 return SWITCH_STATUS_FALSE; 01117 } 01118 01119 if (!switch_channel_up_nosig(caller_channel)) { 01120 switch_channel_hangup(peer_channel, SWITCH_CAUSE_ORIGINATOR_CANCEL); 01121 return SWITCH_STATUS_FALSE; 01122 } 01123 01124 check_bridge_export(caller_channel, peer_channel); 01125 01126 switch_channel_set_flag_recursive(caller_channel, CF_SIGNAL_BRIDGE_TTL); 01127 switch_channel_set_flag_recursive(peer_channel, CF_SIGNAL_BRIDGE_TTL); 01128 01129 switch_channel_set_variable(caller_channel, SWITCH_SIGNAL_BRIDGE_VARIABLE, switch_core_session_get_uuid(peer_session)); 01130 switch_channel_set_variable(peer_channel, SWITCH_SIGNAL_BRIDGE_VARIABLE, switch_core_session_get_uuid(session)); 01131 switch_channel_set_variable(peer_channel, "call_uuid", switch_core_session_get_uuid(session)); 01132 01133 switch_channel_set_flag_recursive(caller_channel, CF_BRIDGE_ORIGINATOR); 01134 switch_channel_clear_flag(peer_channel, CF_BRIDGE_ORIGINATOR); 01135 01136 switch_channel_clear_state_handler(caller_channel, NULL); 01137 switch_channel_clear_state_handler(peer_channel, NULL); 01138 01139 switch_channel_add_state_handler(caller_channel, &signal_bridge_state_handlers); 01140 switch_channel_add_state_handler(peer_channel, &signal_bridge_state_handlers); 01141 01142 switch_channel_set_variable(caller_channel, "signal_bridge", "true"); 01143 switch_channel_set_variable(peer_channel, "signal_bridge", "true"); 01144 01145 /* fire events that will change the data table from "show channels" */ 01146 if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_EXECUTE) == SWITCH_STATUS_SUCCESS) { 01147 switch_channel_event_set_data(caller_channel, event); 01148 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application", "signal_bridge"); 01149 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application-Data", switch_core_session_get_uuid(peer_session)); 01150 switch_event_fire(&event); 01151 } 01152 01153 if (switch_event_create(&event, SWITCH_EVENT_CHANNEL_EXECUTE) == SWITCH_STATUS_SUCCESS) { 01154 switch_channel_event_set_data(peer_channel, event); 01155 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application", "signal_bridge"); 01156 switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Application-Data", switch_core_session_get_uuid(session)); 01157 switch_event_fire(&event); 01158 } 01159 01160 switch_channel_set_bridge_time(caller_channel); 01161 switch_channel_set_bridge_time(peer_channel); 01162 01163 switch_channel_set_state_flag(caller_channel, CF_RESET); 01164 switch_channel_set_state_flag(peer_channel, CF_RESET); 01165 01166 switch_channel_set_state(caller_channel, CS_HIBERNATE); 01167 switch_channel_set_state(peer_channel, CS_HIBERNATE); 01168 01169 #if 0 01170 if (switch_channel_test_flag(caller_channel, CF_BRIDGED)) { 01171 switch_channel_set_flag(caller_channel, CF_TRANSFER); 01172 switch_channel_set_flag(peer_channel, CF_TRANSFER); 01173 } 01174 #endif 01175 01176 switch_ivr_bridge_display(session, peer_session); 01177 01178 return SWITCH_STATUS_SUCCESS; 01179 }
| 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.
| session | the session to wait for. | |
| ms | the number of milliseconds | |
| sync | synchronize the channel's audio before waiting | |
| args | arguements to pass for callbacks etc |
Definition at line 127 of file switch_ivr.c.
References switch_frame::buflen, CF_BREAK, 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, SFF_CNG, switch_channel_audio_sync, switch_channel_clear_flag(), switch_channel_dequeue_dtmf(), switch_channel_get_variable, switch_channel_has_dtmf(), switch_channel_media_ready, switch_channel_ready, SWITCH_CHANNEL_SESSION_LOG, switch_channel_test_flag(), SWITCH_CODEC_FLAG_DECODE, SWITCH_CODEC_FLAG_ENCODE, switch_core_codec_destroy(), switch_core_codec_init, switch_core_session_dequeue_event(), 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_event_destroy(), SWITCH_FALSE, switch_generate_sln_silence(), 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_IVR_VERIFY_SILENCE_DIVISOR, 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_set_flag, SWITCH_STATUS_BREAK, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_yield, and switch_zmalloc.
Referenced by collect_thread_run(), fs_switch_ivr_sleep(), originate_on_consume_media_transmit(), CoreSession::sleep(), switch_ivr_menu_execute(), switch_ivr_parse_all_events(), switch_ivr_phrase_macro_event(), switch_ivr_play_and_detect_speech(), and switch_ivr_play_file().
00128 { 00129 switch_channel_t *channel = switch_core_session_get_channel(session); 00130 switch_status_t status = SWITCH_STATUS_SUCCESS; 00131 switch_time_t start = switch_micro_time_now(), now, done = switch_micro_time_now() + (ms * 1000); 00132 switch_frame_t *read_frame, cng_frame = { 0 }; 00133 int32_t left; 00134 uint32_t elapsed; 00135 char data[2] = ""; 00136 00137 switch_frame_t write_frame = { 0 }; 00138 unsigned char *abuf = NULL; 00139 switch_codec_implementation_t imp = { 0 }; 00140 switch_codec_t codec = { 0 }; 00141 int sval = 0; 00142 const char *var; 00143 00144 /* 00145 if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_INBOUND && !switch_channel_test_flag(channel, CF_PROXY_MODE) && 00146 !switch_channel_media_ready(channel) && !switch_channel_test_flag(channel, CF_SERVICE)) { 00147 if ((status = switch_channel_pre_answer(channel)) != SWITCH_STATUS_SUCCESS) { 00148 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot establish media.\n"); 00149 return SWITCH_STATUS_FALSE; 00150 } 00151 } 00152 */ 00153 00154 if (!switch_channel_media_ready(channel)) { 00155 00156 for (elapsed=0; elapsed<(ms/20); elapsed++) { 00157 if (switch_channel_test_flag(channel, CF_BREAK)) { 00158 switch_channel_clear_flag(channel, CF_BREAK); 00159 return SWITCH_STATUS_BREAK; 00160 } 00161 00162 switch_yield(20 * 1000); 00163 } 00164 return SWITCH_STATUS_SUCCESS; 00165 } 00166 00167 var = switch_channel_get_variable(channel, SWITCH_SEND_SILENCE_WHEN_IDLE_VARIABLE); 00168 if (var) { 00169 sval = atoi(var); 00170 SWITCH_IVR_VERIFY_SILENCE_DIVISOR(sval); 00171 } 00172 00173 if (ms > 10 && sval) { 00174 switch_core_session_get_read_impl(session, &imp); 00175 00176 if (switch_core_codec_init(&codec, 00177 "L16", 00178 NULL, 00179 imp.samples_per_second, 00180 imp.microseconds_per_packet / 1000, 00181 imp.number_of_channels, 00182 SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, 00183 switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { 00184 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Codec Error L16@%uhz %u channels %dms\n", 00185 imp.samples_per_second, imp.number_of_channels, imp.microseconds_per_packet / 1000); 00186 return SWITCH_STATUS_FALSE; 00187 } 00188 00189 00190 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Codec Activated L16@%uhz %u channels %dms\n", 00191 imp.samples_per_second, imp.number_of_channels, imp.microseconds_per_packet / 1000); 00192 00193 write_frame.codec = &codec; 00194 switch_zmalloc(abuf, SWITCH_RECOMMENDED_BUFFER_SIZE); 00195 write_frame.data = abuf; 00196 write_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE; 00197 write_frame.datalen = imp.decoded_bytes_per_packet; 00198 write_frame.samples = write_frame.datalen / sizeof(int16_t); 00199 00200 } 00201 00202 if (!write_frame.datalen) { 00203 sval = 0; 00204 } 00205 00206 cng_frame.data = data; 00207 cng_frame.datalen = 2; 00208 cng_frame.buflen = 2; 00209 switch_set_flag((&cng_frame), SFF_CNG); 00210 00211 if (sync) { 00212 switch_channel_audio_sync(channel); 00213 } 00214 00215 if (!ms) { 00216 return SWITCH_STATUS_SUCCESS; 00217 } 00218 00219 for (;;) { 00220 now = switch_micro_time_now(); 00221 elapsed = (int32_t) ((now - start) / 1000); 00222 left = ms - elapsed; 00223 00224 if (!switch_channel_ready(channel)) { 00225 status = SWITCH_STATUS_FALSE; 00226 break; 00227 } 00228 00229 if (switch_channel_test_flag(channel, CF_BREAK)) { 00230 switch_channel_clear_flag(channel, CF_BREAK); 00231 status = SWITCH_STATUS_BREAK; 00232 break; 00233 } 00234 00235 if (now > done || left <= 0) { 00236 break; 00237 } 00238 00239 00240 switch_ivr_parse_all_events(session); 00241 00242 00243 if (args) { 00244 switch_dtmf_t dtmf = {0}; 00245 00246 /* 00247 dtmf handler function you can hook up to be executed when a digit is dialed during playback 00248 if you return anything but SWITCH_STATUS_SUCCESS the playback will stop. 00249 */ 00250 if (switch_channel_has_dtmf(channel)) { 00251 if (!args->input_callback && !args->buf && !args->dmachine) { 00252 status = SWITCH_STATUS_BREAK; 00253 break; 00254 } 00255 switch_channel_dequeue_dtmf(channel, &dtmf); 00256 00257 if (args->dmachine) { 00258 char ds[2] = {dtmf.digit, '\0'}; 00259 if ((status = switch_ivr_dmachine_feed(args->dmachine, ds, NULL)) != SWITCH_STATUS_SUCCESS) { 00260 break; 00261 } 00262 } 00263 00264 if (args->input_callback) { 00265 status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen); 00266 } else if (args->buf) { 00267 *((char *) args->buf) = dtmf.digit; 00268 status = SWITCH_STATUS_BREAK; 00269 } 00270 } 00271 00272 if (args->input_callback) { 00273 switch_event_t *event = NULL; 00274 00275 if (switch_core_session_dequeue_event(session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) { 00276 status = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen); 00277 switch_event_destroy(&event); 00278 } 00279 } 00280 00281 if (status != SWITCH_STATUS_SUCCESS) { 00282 break; 00283 } 00284 } 00285 00286 status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); 00287 00288 if (!SWITCH_READ_ACCEPTABLE(status)) { 00289 break; 00290 } 00291 00292 if (args && args->dmachine) { 00293 if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL)) != SWITCH_STATUS_SUCCESS) { 00294 break; 00295 } 00296 } 00297 00298 if (sval && write_frame.datalen) { 00299 switch_generate_sln_silence((int16_t *) write_frame.data, write_frame.samples, sval); 00300 switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0); 00301 } else { 00302 switch_core_session_write_frame(session, &cng_frame, SWITCH_IO_FLAG_NONE, 0); 00303 } 00304 } 00305 00306 if (write_frame.codec) { 00307 switch_core_codec_destroy(&codec); 00308 } 00309 00310 switch_safe_free(abuf); 00311 00312 return status; 00313 }
| 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.
| session | the session to speak on | |
| tts_name | the desired tts module | |
| voice_name | the desired voice | |
| text | the text to speak | |
| args | arguements to pass for callbacks etc |
Definition at line 2397 of file switch_ivr_play_say.c.
References switch_codec_implementation::actual_samples_per_second, cached_speech_handle::codec, switch_frame::codec, switch_codec_implementation::microseconds_per_packet, pool, switch_speech_handle::samples, cached_speech_handle::sh, SWITCH_CACHE_SPEECH_HANDLES_OBJ_NAME, SWITCH_CACHE_SPEECH_HANDLES_VARIABLE, switch_channel_get_private(), switch_channel_get_variable, switch_channel_pre_answer, SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_private(), SWITCH_CODEC_FLAG_DECODE, SWITCH_CODEC_FLAG_ENCODE, switch_copy_string(), switch_core_codec_destroy(), switch_core_codec_init, switch_core_service_session, switch_core_session_alloc, switch_core_session_get_channel(), switch_core_session_get_pool(), switch_core_session_get_read_impl(), switch_core_session_reset(), switch_core_speech_close(), switch_core_speech_open(), switch_core_speech_text_param_tts(), switch_core_thread_session_end(), switch_core_timer_destroy(), switch_core_timer_init(), switch_core_timer_sync(), SWITCH_FALSE, switch_ivr_clear_speech_cache(), switch_ivr_speak_text_handle(), SWITCH_LOG_DEBUG, SWITCH_LOG_ERROR, switch_log_printf(), SWITCH_SPEECH_FLAG_NONE, SWITCH_STATUS_FALSE, SWITCH_STATUS_GENERR, SWITCH_STATUS_SUCCESS, switch_true(), SWITCH_TRUE, cached_speech_handle::timer, cached_speech_handle::tts_name, and cached_speech_handle::voice_name.
Referenced by fs_switch_ivr_speak_text(), CoreSession::speak(), switch_ivr_phrase_macro_event(), and switch_ivr_play_file().
02399 { 02400 switch_channel_t *channel = switch_core_session_get_channel(session); 02401 uint32_t rate = 0; 02402 int interval = 0; 02403 switch_frame_t write_frame = { 0 }; 02404 switch_timer_t ltimer, *timer; 02405 switch_codec_t lcodec, *codec; 02406 switch_memory_pool_t *pool = switch_core_session_get_pool(session); 02407 char *codec_name; 02408 switch_status_t status = SWITCH_STATUS_SUCCESS; 02409 switch_speech_handle_t lsh, *sh; 02410 switch_speech_flag_t flags = SWITCH_SPEECH_FLAG_NONE; 02411 const char *timer_name, *var; 02412 cached_speech_handle_t *cache_obj = NULL; 02413 int need_create = 1, need_alloc = 1; 02414 switch_codec_implementation_t read_impl = { 0 }; 02415 switch_core_session_get_read_impl(session, &read_impl); 02416 02417 if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) { 02418 return SWITCH_STATUS_FALSE; 02419 } 02420 02421 sh = ↰ 02422 codec = &lcodec; 02423 timer = <imer; 02424 02425 if ((var = switch_channel_get_variable(channel, SWITCH_CACHE_SPEECH_HANDLES_VARIABLE)) && switch_true(var)) { 02426 if ((cache_obj = (cached_speech_handle_t *) switch_channel_get_private(channel, SWITCH_CACHE_SPEECH_HANDLES_OBJ_NAME))) { 02427 need_create = 0; 02428 if (!strcasecmp(cache_obj->tts_name, tts_name)) { 02429 need_alloc = 0; 02430 } else { 02431 switch_ivr_clear_speech_cache(session); 02432 } 02433 } 02434 02435 if (!cache_obj) { 02436 cache_obj = (cached_speech_handle_t *) switch_core_session_alloc(session, sizeof(*cache_obj)); 02437 } 02438 if (need_alloc) { 02439 switch_copy_string(cache_obj->tts_name, tts_name, sizeof(cache_obj->tts_name)); 02440 switch_copy_string(cache_obj->voice_name, voice_name, sizeof(cache_obj->voice_name)); 02441 switch_channel_set_private(channel, SWITCH_CACHE_SPEECH_HANDLES_OBJ_NAME, cache_obj); 02442 } 02443 sh = &cache_obj->sh; 02444 codec = &cache_obj->codec; 02445 timer = &cache_obj->timer; 02446 } 02447 02448 timer_name = switch_channel_get_variable(channel, "timer_name"); 02449 02450 switch_core_session_reset(session, SWITCH_FALSE, SWITCH_FALSE); 02451 02452 rate = read_impl.actual_samples_per_second; 02453 interval = read_impl.microseconds_per_packet / 1000; 02454 02455 if (need_create) { 02456 memset(sh, 0, sizeof(*sh)); 02457 if ((status = switch_core_speech_open(sh, tts_name, voice_name, (uint32_t) rate, interval, &flags, NULL)) != SWITCH_STATUS_SUCCESS) { 02458 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid TTS module!\n"); 02459 switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE); 02460 switch_ivr_clear_speech_cache(session); 02461 return status; 02462 } 02463 } else if (cache_obj && strcasecmp(cache_obj->voice_name, voice_name)) { 02464 switch_copy_string(cache_obj->voice_name, voice_name, sizeof(cache_obj->voice_name)); 02465 switch_core_speech_text_param_tts(sh, "voice", voice_name); 02466 } 02467 02468 if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) { 02469 flags = 0; 02470 switch_core_speech_close(sh, &flags); 02471 return SWITCH_STATUS_FALSE; 02472 } 02473 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "OPEN TTS %s\n", tts_name); 02474 02475 codec_name = "L16"; 02476 02477 if (need_create) { 02478 if (switch_core_codec_init(codec, 02479 codec_name, 02480 NULL, (int) rate, interval, 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, NULL, 02481 pool) == SWITCH_STATUS_SUCCESS) { 02482 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Raw Codec Activated\n"); 02483 } else { 02484 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Raw Codec Activation Failed %s@%uhz 1 channel %dms\n", codec_name, 02485 rate, interval); 02486 flags = 0; 02487 switch_core_speech_close(sh, &flags); 02488 switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE); 02489 switch_ivr_clear_speech_cache(session); 02490 return SWITCH_STATUS_GENERR; 02491 } 02492 } 02493 02494 write_frame.codec = codec; 02495 02496 if (timer_name) { 02497 if (need_create) { 02498 if (switch_core_timer_init(timer, timer_name, interval, (int) sh->samples, pool) != SWITCH_STATUS_SUCCESS) { 02499 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Setup timer failed!\n"); 02500 switch_core_codec_destroy(write_frame.codec); 02501 flags = 0; 02502 switch_core_speech_close(sh, &flags); 02503 switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE); 02504 switch_ivr_clear_speech_cache(session); 02505 return SWITCH_STATUS_GENERR; 02506 } 02507 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Setup timer success %u bytes per %d ms!\n", sh->samples * 2, 02508 interval); 02509 } 02510 switch_core_timer_sync(timer); // Sync timer 02511 02512 /* start a thread to absorb incoming audio */ 02513 switch_core_service_session(session); 02514 02515 } 02516 02517 status = switch_ivr_speak_text_handle(session, sh, write_frame.codec, timer_name ? timer : NULL, text, args); 02518 flags = 0; 02519 02520 if (!cache_obj) { 02521 switch_core_speech_close(sh, &flags); 02522 switch_core_codec_destroy(codec); 02523 } 02524 02525 if (timer_name) { 02526 /* End the audio absorbing thread */ 02527 switch_core_thread_session_end(session); 02528 if (!cache_obj) { 02529 switch_core_timer_destroy(timer); 02530 } 02531 } 02532 02533 switch_core_session_reset(session, SWITCH_FALSE, SWITCH_TRUE); 02534 return status; 02535 }
| 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 | |||
| ) |
Definition at line 2086 of file switch_ivr_play_say.c.
References switch_frame::buflen, CF_BREAK, CF_HOLD, switch_frame::codec, switch_frame::data, switch_frame::datalen, switch_dtmf_t::digit, switch_frame::rate, switch_frame::samples, switch_assert, switch_channel_audio_sync, switch_channel_clear_flag(), switch_channel_dequeue_dtmf(), switch_channel_get_variable, switch_channel_has_dtmf(), switch_channel_pre_answer, switch_channel_ready, SWITCH_CHANNEL_SESSION_LOG, switch_channel_test_flag(), switch_core_session_dequeue_event(), switch_core_session_dequeue_private_event(), switch_core_session_get_channel(), switch_core_session_read_frame(), switch_core_session_write_frame(), switch_core_speech_feed_tts(), switch_core_speech_flush_tts(), switch_core_speech_read_tts(), switch_core_timer_next(), 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_messages(), switch_ivr_parse_event(), SWITCH_LOG_DEBUG, switch_log_printf(), SWITCH_READ_ACCEPTABLE, switch_safe_free, SWITCH_SPEECH_FLAG_BLOCKING, SWITCH_SPEECH_FLAG_NONE, SWITCH_SPEECH_FLAG_PAUSE, SWITCH_STATUS_BREAK, SWITCH_STATUS_FALSE, SWITCH_STATUS_MEMERR, SWITCH_STATUS_SUCCESS, switch_test_flag, switch_yield, and switch_frame::timestamp.
Referenced by switch_ivr_speak_text().
02089 { 02090 switch_channel_t *channel = switch_core_session_get_channel(session); 02091 short abuf[960]; 02092 switch_dtmf_t dtmf = { 0 }; 02093 uint32_t len = 0; 02094 switch_size_t ilen = 0; 02095 switch_frame_t write_frame = { 0 }; 02096 int x; 02097 int done = 0; 02098 int lead_in_out = 10; 02099 switch_status_t status = SWITCH_STATUS_SUCCESS; 02100 switch_speech_flag_t flags = SWITCH_SPEECH_FLAG_NONE; 02101 switch_size_t extra = 0; 02102 char *p, *tmp = NULL; 02103 const char *star, *pound; 02104 switch_size_t starlen, poundlen; 02105 02106 if (!sh) { 02107 return SWITCH_STATUS_FALSE; 02108 } 02109 02110 if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) { 02111 return SWITCH_STATUS_FALSE; 02112 } 02113 02114 write_frame.data = abuf; 02115 write_frame.buflen = sizeof(abuf); 02116 02117 len = sh->samples * 2; 02118 02119 flags = 0; 02120 02121 if (!(star = switch_channel_get_variable(channel, "star_replace"))) { 02122 star = "star"; 02123 } 02124 if (!(pound = switch_channel_get_variable(channel, "pound_replace"))) { 02125 pound = "pound"; 02126 } 02127 starlen = strlen(star); 02128 poundlen = strlen(pound); 02129 02130 02131 for (p = text; p && *p; p++) { 02132 if (*p == '*') { 02133 extra += starlen; 02134 } else if (*p == '#') { 02135 extra += poundlen; 02136 } 02137 } 02138 02139 if (extra) { 02140 char *tp; 02141 switch_size_t mylen = strlen(text) + extra + 1; 02142 tmp = malloc(mylen); 02143 if (!tmp) { 02144 return SWITCH_STATUS_MEMERR; 02145 } 02146 memset(tmp, 0, mylen); 02147 tp = tmp; 02148 for (p = text; p && *p; p++) { 02149 if (*p == '*') { 02150 strncat(tp, star, starlen); 02151 tp += starlen; 02152 } else if (*p == '#') { 02153 strncat(tp, pound, poundlen); 02154 tp += poundlen; 02155 } else { 02156 *tp++ = *p; 02157 } 02158 } 02159 02160 text = tmp; 02161 } 02162 02163 switch_core_speech_feed_tts(sh, text, &flags); 02164 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Speaking text: %s\n", text); 02165 switch_safe_free(tmp); 02166 text = NULL; 02167 02168 write_frame.rate = sh->rate; 02169 02170 memset(write_frame.data, 0, len); 02171 write_frame.datalen = len; 02172 write_frame.samples = len / 2; 02173 write_frame.codec = codec; 02174 02175 switch_assert(codec->implementation != NULL); 02176 02177 for (x = 0; !done && x < lead_in_out; x++) { 02178 switch_yield(codec->implementation->microseconds_per_packet); 02179 if (timer) { 02180 write_frame.timestamp = timer->samplecount; 02181 } 02182 if (switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) { 02183 done = 1; 02184 break; 02185 } 02186 } 02187 02188 switch_channel_audio_sync(channel); 02189 02190 ilen = len; 02191 for (;;) { 02192 switch_event_t *event; 02193 02194 if (!switch_channel_ready(channel)) { 02195 status = SWITCH_STATUS_FALSE; 02196 break; 02197 } 02198 02199 if (switch_channel_test_flag(channel, CF_BREAK)) { 02200 switch_channel_clear_flag(channel, CF_BREAK); 02201 status = SWITCH_STATUS_BREAK; 02202 break; 02203 } 02204 02205 if (switch_core_session_dequeue_private_event(session, &event) == SWITCH_STATUS_SUCCESS) { 02206 switch_ivr_parse_event(session, event); 02207 switch_event_destroy(&event); 02208 } 02209 02210 if (args) { 02211 /* dtmf handler function you can hook up to be executed when a digit is dialed during playback 02212 * if you return anything but SWITCH_STATUS_SUCCESS the playback will stop. 02213 */ 02214 if (switch_channel_has_dtmf(channel)) { 02215 if (!args->input_callback && !args->buf && !args->dmachine) { 02216 status = SWITCH_STATUS_BREAK; 02217 done = 1; 02218 break; 02219 } 02220 if (args->buf && !strcasecmp(args->buf, "_break_")) { 02221 status = SWITCH_STATUS_BREAK; 02222 } else { 02223 switch_channel_dequeue_dtmf(channel, &dtmf); 02224 02225 if (args->dmachine) { 02226 char ds[2] = {dtmf.digit, '\0'}; 02227 if ((status = switch_ivr_dmachine_feed(args->dmachine, ds, NULL)) != SWITCH_STATUS_SUCCESS) { 02228 break; 02229 } 02230 } 02231 02232 if (args->input_callback) { 02233 status = args->input_callback(session, (void *) &dtmf, SWITCH_INPUT_TYPE_DTMF, args->buf, args->buflen); 02234 } else if (args->buf) { 02235 *((char *) args->buf) = dtmf.digit; 02236 status = SWITCH_STATUS_BREAK; 02237 } 02238 } 02239 } 02240 02241 if (args->input_callback) { 02242 if (switch_core_session_dequeue_event(session, &event, SWITCH_FALSE) == SWITCH_STATUS_SUCCESS) { 02243 status = args->input_callback(session, event, SWITCH_INPUT_TYPE_EVENT, args->buf, args->buflen); 02244 switch_event_destroy(&event); 02245 } 02246 } 02247 02248 if (status != SWITCH_STATUS_SUCCESS) { 02249 done = 1; 02250 break; 02251 } 02252 } 02253 02254 if (switch_test_flag(sh, SWITCH_SPEECH_FLAG_PAUSE)) { 02255 if (timer) { 02256 if (switch_core_timer_next(timer) != SWITCH_STATUS_SUCCESS) { 02257 break; 02258 } 02259 } else { 02260 switch_frame_t *read_frame; 02261 switch_status_t tstatus = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); 02262 02263 while (switch_channel_ready(channel) && switch_channel_test_flag(channel, CF_HOLD)) { 02264 switch_ivr_parse_all_messages(session); 02265 switch_yield(10000); 02266 } 02267 02268 if (!SWITCH_READ_ACCEPTABLE(tstatus)) { 02269 break; 02270 } 02271 02272 if (args && args->dmachine) { 02273 if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL)) != SWITCH_STATUS_SUCCESS) { 02274 goto done; 02275 } 02276 } 02277 02278 if (args && (args->read_frame_callback)) { 02279 if ((status = args->read_frame_callback(session, read_frame, args->user_data)) != SWITCH_STATUS_SUCCESS) { 02280 goto done; 02281 } 02282 } 02283 } 02284 continue; 02285 } 02286 02287 flags = SWITCH_SPEECH_FLAG_BLOCKING; 02288 status = switch_core_speech_read_tts(sh, abuf, &ilen, &flags); 02289 02290 if (status != SWITCH_STATUS_SUCCESS) { 02291 write_frame.datalen = (uint32_t) codec->implementation->decoded_bytes_per_packet; 02292 write_frame.samples = (uint32_t) (write_frame.datalen / 2); 02293 memset(write_frame.data, 0, write_frame.datalen); 02294 for (x = 0; !done && x < lead_in_out; x++) { 02295 switch_yield(codec->implementation->microseconds_per_packet); 02296 if (timer) { 02297 write_frame.timestamp = timer->samplecount; 02298 } 02299 if (switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) { 02300 done = 1; 02301 break; 02302 } 02303 } 02304 if (status == SWITCH_STATUS_BREAK) { 02305 status = SWITCH_STATUS_SUCCESS; 02306 } 02307 done = 1; 02308 } 02309 02310 if (done) { 02311 break; 02312 } 02313 02314 write_frame.datalen = (uint32_t) ilen; 02315 write_frame.samples = (uint32_t) (ilen / 2); 02316 if (timer) { 02317 write_frame.timestamp = timer->samplecount; 02318 } 02319 if (switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) { 02320 done = 1; 02321 break; 02322 } 02323 02324 if (done) { 02325 break; 02326 } 02327 02328 if (timer) { 02329 if (switch_core_timer_next(timer) != SWITCH_STATUS_SUCCESS) { 02330 break; 02331 } 02332 } else { /* time off the channel (if you must) */ 02333 switch_frame_t *read_frame; 02334 switch_status_t tstatus = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); 02335 02336 while (switch_channel_ready(channel) && switch_channel_test_flag(channel, CF_HOLD)) { 02337 switch_ivr_parse_all_messages(session); 02338 switch_yield(10000); 02339 } 02340 02341 if (!SWITCH_READ_ACCEPTABLE(tstatus)) { 02342 break; 02343 } 02344 02345 if (args && args->dmachine) { 02346 if ((status = switch_ivr_dmachine_ping(args->dmachine, NULL)) != SWITCH_STATUS_SUCCESS) { 02347 goto done; 02348 } 02349 } 02350 02351 if (args && (args->read_frame_callback)) { 02352 if ((status = args->read_frame_callback(session, read_frame, args->user_data)) != SWITCH_STATUS_SUCCESS) { 02353 goto done; 02354 } 02355 } 02356 } 02357 } 02358 02359 done: 02360 02361 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "done speaking text\n"); 02362 flags = 0; 02363 switch_core_speech_flush_tts(sh); 02364 return status; 02365 }
| switch_status_t switch_ivr_stop_detect_speech | ( | switch_core_session_t * | session | ) |
Stop background Speech detection on a session.
| session | The session to stop detection on |
Definition at line 3656 of file switch_ivr_async.c.
References speech_thread_handle::bug, speech_on_dtmf(), switch_assert, switch_channel_get_private(), switch_channel_set_private(), switch_core_media_bug_remove(), switch_core_session_get_channel(), SWITCH_SPEECH_KEY, SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.
Referenced by switch_ivr_detect_speech(), switch_ivr_detect_speech_disable_all_grammars(), switch_ivr_detect_speech_disable_grammar(), switch_ivr_detect_speech_enable_grammar(), switch_ivr_detect_speech_load_grammar(), and switch_ivr_detect_speech_unload_grammar().
03657 { 03658 switch_channel_t *channel = switch_core_session_get_channel(session); 03659 struct speech_thread_handle *sth; 03660 03661 switch_assert(channel != NULL); 03662 if ((sth = switch_channel_get_private(channel, SWITCH_SPEECH_KEY))) { 03663 switch_channel_set_private(channel, SWITCH_SPEECH_KEY, NULL); 03664 switch_core_event_hook_remove_recv_dtmf(session, speech_on_dtmf); 03665 switch_core_media_bug_remove(session, &sth->bug); 03666 return SWITCH_STATUS_SUCCESS; 03667 } 03668 03669 return SWITCH_STATUS_FALSE; 03670 }
| switch_status_t switch_ivr_stop_displace_session | ( | switch_core_session_t * | session, | |
| const char * | file | |||
| ) |
Stop displacing a session.
| session | the session | |
| file | file name from the switch_ivr_displace_session call |
Definition at line 867 of file switch_ivr_async.c.
References switch_channel_get_private(), switch_channel_set_private(), switch_core_media_bug_remove(), switch_core_session_get_channel(), SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.
00868 { 00869 switch_media_bug_t *bug; 00870 switch_channel_t *channel = switch_core_session_get_channel(session); 00871 00872 if ((bug = switch_channel_get_private(channel, file))) { 00873 switch_channel_set_private(channel, file, NULL); 00874 switch_core_media_bug_remove(session, &bug); 00875 return SWITCH_STATUS_SUCCESS; 00876 } 00877 00878 return SWITCH_STATUS_FALSE; 00879 }
| switch_status_t switch_ivr_stop_inband_dtmf_generate_session | ( | switch_core_session_t * | session | ) |
Stop generating DTMF inband.
| session | the session to stop generating |
Definition at line 2626 of file switch_ivr_async.c.
References switch_channel_get_private(), switch_channel_set_private(), switch_core_media_bug_remove(), switch_core_session_get_channel(), SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.
02627 { 02628 switch_channel_t *channel = switch_core_session_get_channel(session); 02629 switch_media_bug_t *bug = switch_channel_get_private(channel, "dtmf_generate"); 02630 02631 if (bug) { 02632 switch_channel_set_private(channel, "dtmf_generate", NULL); 02633 switch_core_media_bug_remove(session, &bug); 02634 return SWITCH_STATUS_SUCCESS; 02635 } 02636 02637 return SWITCH_STATUS_FALSE; 02638 02639 }
| switch_status_t switch_ivr_stop_inband_dtmf_session | ( | switch_core_session_t * | session | ) |
Stop looking for DTMF inband.
| session | the session to stop looking |
Definition at line 2393 of file switch_ivr_async.c.
References switch_channel_get_private(), switch_channel_set_private(), switch_core_media_bug_remove(), switch_core_session_get_channel(), SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.
02394 { 02395 switch_media_bug_t *bug; 02396 switch_channel_t *channel = switch_core_session_get_channel(session); 02397 02398 if ((bug = switch_channel_get_private(channel, "dtmf"))) { 02399 switch_channel_set_private(channel, "dtmf", NULL); 02400 switch_core_media_bug_remove(session, &bug); 02401 return SWITCH_STATUS_SUCCESS; 02402 } 02403 return SWITCH_STATUS_FALSE; 02404 }
| switch_status_t switch_ivr_stop_record_session | ( | switch_core_session_t * | session, | |
| const char * | file | |||
| ) |
Stop Recording a session.
| session | the session to stop recording | |
| file | the path to the file |
Definition at line 1130 of file switch_ivr_async.c.
References record_callback(), switch_channel_get_private(), switch_core_media_bug_remove(), switch_core_media_bug_remove_callback(), switch_core_session_get_channel(), SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.
Referenced by switch_core_media_bug_transfer_recordings(), and switch_ivr_record_session().
01131 { 01132 switch_media_bug_t *bug; 01133 switch_channel_t *channel = switch_core_session_get_channel(session); 01134 01135 if (!strcasecmp(file, "all")) { 01136 return switch_core_media_bug_remove_callback(session, record_callback); 01137 } else if ((bug = switch_channel_get_private(channel, file))) { 01138 switch_core_media_bug_remove(session, &bug); 01139 return SWITCH_STATUS_SUCCESS; 01140 } 01141 return SWITCH_STATUS_FALSE; 01142 }
| switch_status_t switch_ivr_stop_session_audio | ( | switch_core_session_t * | session | ) |
Definition at line 2265 of file switch_ivr_async.c.
References switch_channel_get_private(), switch_channel_set_private(), switch_core_media_bug_remove(), switch_core_session_get_channel(), SWITCH_STATUS_FALSE, and SWITCH_STATUS_SUCCESS.
02266 { 02267 switch_media_bug_t *bug; 02268 switch_channel_t *channel = switch_core_session_get_channel(session); 02269 02270 if ((bug = switch_channel_get_private(channel, "__audio"))) { 02271 switch_channel_set_private(channel, "__audio", NULL); 02272 switch_core_media_bug_remove(session, &bug); 02273 return SWITCH_STATUS_SUCCESS; 02274 } 02275 return SWITCH_STATUS_FALSE; 02276 }
| switch_status_t switch_ivr_stop_tone_detect_session | ( | switch_core_session_t * | session | ) |
Stop looking for TONES.
| session | the session to stop looking |
Definition at line 2846 of file switch_ivr_async.c.
References switch_tone_container_t::bug, switch_tone_container_t::detect_fax, switch_tone_container_t::index, switch_tone_container_t::list, switch_channel_get_private(), switch_channel_set_private(), switch_core_media_bug_remove(), switch_core_session_get_channel(), SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, and switch_tone_detect_t::up.
02847 { 02848 switch_channel_t *channel = switch_core_session_get_channel(session); 02849 switch_tone_container_t *cont = switch_channel_get_private(channel, "_tone_detect_"); 02850 int i = 0; 02851 02852 if (cont) { 02853 switch_channel_set_private(channel, "_tone_detect_", NULL); 02854 for (i = 0; i < cont->index; i++) { 02855 cont->list[i].up = 0; 02856 } 02857 switch_core_media_bug_remove(session, &cont->bug); 02858 if (cont->detect_fax) { 02859 cont->detect_fax = 0; 02860 } 02861 return SWITCH_STATUS_SUCCESS; 02862 } 02863 return SWITCH_STATUS_FALSE; 02864 }
| 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.
| session | the session to start looking | |
| key | the name of the tone. | |
| tone_spec | comma sep list of tone freqs | |
| flags | one or both of 'r' and 'w' | |
| timeout | timeout | |
| app | optional application to execute when tone is found | |
| data | optional data for appliaction |
Definition at line 2866 of file switch_ivr_async.c.
References switch_tone_detect_t::expires, switch_tone_detect_t::hits, switch_tone_container_t::index, switch_tone_detect_t::key, switch_tone_container_t::list, MAX_TONES, switch_tone_detect_t::sleep, switch_channel_get_private(), SWITCH_CHANNEL_SESSION_LOG, switch_core_session_get_channel(), switch_core_session_get_read_impl(), SWITCH_LOG_DEBUG, SWITCH_LOG_ERROR, switch_log_printf(), SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, switch_tone_detect_t::up, and zstr.
Referenced by check_channel_status().
02870 { 02871 switch_channel_t *channel = switch_core_session_get_channel(session); 02872 switch_status_t status; 02873 switch_tone_container_t *cont = switch_channel_get_private(channel, "_tone_detect_"); 02874 char *p, *next; 02875 int i = 0, ok = 0, detect_fax = 0; 02876 switch_media_bug_flag_t bflags = 0; 02877 const char *var; 02878 switch_codec_implementation_t read_impl = { 0 }; 02879 switch_core_session_get_read_impl(session, &read_impl); 02880 02881 02882 if (zstr(key)) { 02883 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No Key Specified!\n"); 02884 return SWITCH_STATUS_FALSE; 02885 } 02886 02887 if (cont) { 02888 if (cont->index >= MAX_TONES) { 02889 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Max Tones Reached!\n"); 02890 return SWITCH_STATUS_FALSE; 02891 } 02892 02893 for (i = 0; i < cont->index; i++) { 02894 if (!zstr(cont->list[i].key) && !strcasecmp(key, cont->list[i].key)) { 02895 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Re-enabling %s\n", key); 02896 cont->list[i].up = 1; 02897 cont->list[i].hits = 0; 02898 cont->list[i].sleep = 0; 02899 cont->list[i].expires = 0; 02900 return SWITCH_STATUS_SUCCESS; 02901 } 02902 } 02903 } 02904 02905 if (zstr(tone_spec)) { 02906 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No Spec Specified!\n"); 02907 return SWITCH_STATUS_FALSE; 02908 } 02909 02910 if (!cont && !(cont = switch_core_session_alloc(session, sizeof(*cont)))) { 02911 return SWITCH_STATUS_MEMERR; 02912 } 02913 02914 if ((var = switch_channel_get_variable(channel, "tone_detect_hits"))) { 02915 int tmp = atoi(var); 02916 if (tmp > 0) { 02917 hits = tmp; 02918 } 02919 } 02920 02921 if (!hits) hits = 1; 02922 02923 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Adding tone spec %s index %d hits %d\n", tone_spec, cont->index, hits); 02924 02925 i = 0; 02926 p = (char *) tone_spec; 02927 02928 do { 02929 teletone_process_t this; 02930 next = strchr(p, ','); 02931 while (*p == ' ') 02932 p++; 02933 if ((this = (teletone_process_t) atof(p))) { 02934 ok++; 02935 cont->list[cont->index].map.freqs[i++] = this; 02936 } 02937 if (!strncasecmp(p, "1100", 4)) { 02938 detect_fax = cont->index; 02939 } 02940 02941 if (next) { 02942 p = next + 1; 02943 } 02944 } while (next); 02945 cont->list[cont->index].map.freqs[i++] = 0; 02946 02947 if (!ok) { 02948 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Invalid tone spec!\n"); 02949 return SWITCH_STATUS_FALSE; 02950 } 02951 02952 cont->detect_fax = detect_fax; 02953 02954 cont->list[cont->index].key = switch_core_session_strdup(session, key); 02955 02956 if (app) { 02957 cont->list[cont->index].app = switch_core_session_strdup(session, app); 02958 } 02959 02960 if (data) { 02961 cont->list[cont->index].data = switch_core_session_strdup(session, data); 02962 } 02963 02964 cont->list[cont->index].callback = callback; 02965 02966 if (!hits) 02967 hits = 1; 02968 02969 cont->list[cont->index].hits = 0; 02970 cont->list[cont->index].total_hits = hits; 02971 02972 cont->list[cont->index].up = 1; 02973 memset(&cont->list[cont->index].mt, 0, sizeof(cont->list[cont->index].mt)); 02974 cont->list[cont->index].mt.sample_rate = read_impl.actual_samples_per_second; 02975 teletone_multi_tone_init(&cont->list[cont->index].mt, &cont->list[cont->index].map); 02976 cont->session = session; 02977 02978 if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) { 02979 return SWITCH_STATUS_FALSE; 02980 } 02981 02982 cont->list[cont->index].default_sleep = 25; 02983 cont->list[cont->index].default_expires = 250; 02984 02985 if ((var = switch_channel_get_variable(channel, "tone_detect_sleep"))) { 02986 int tmp = atoi(var); 02987 if (tmp > 0) { 02988 cont->list[cont->index].default_sleep = tmp; 02989 } 02990 } 02991 02992 if ((var = switch_channel_get_variable(channel, "tone_detect_expires"))) { 02993 int tmp = atoi(var); 02994 if (tmp > 0) { 02995 cont->list[cont->index].default_expires = tmp; 02996 } 02997 } 02998 02999 03000 if (zstr(flags)) { 03001 bflags = SMBF_READ_REPLACE; 03002 } else { 03003 if (strchr(flags, 'o')) { 03004 cont->list[cont->index].once = 1; 03005 } 03006 03007 if (strchr(flags, 'r')) { 03008 bflags |= SMBF_READ_REPLACE; 03009 } else if (strchr(flags, 'w')) { 03010 bflags |= SMBF_WRITE_REPLACE; 03011 } 03012 } 03013 03014 bflags |= SMBF_NO_PAUSE; 03015 03016 if (cont->bug_running) { 03017 status = SWITCH_STATUS_SUCCESS; 03018 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s bug already running\n", switch_channel_get_name(channel)); 03019 } else { 03020 cont->bug_running = 1; 03021 if (cont->detect_fax) { 03022 switch_core_event_hook_add_send_dtmf(session, tone_on_dtmf); 03023 switch_core_event_hook_add_recv_dtmf(session, tone_on_dtmf); 03024 } 03025 03026 if ((status = switch_core_media_bug_add(session, "tone_detect", key, 03027 tone_detect_callback, cont, timeout, bflags, &cont->bug)) != SWITCH_STATUS_SUCCESS) { 03028 cont->bug_running = 0; 03029 return status; 03030 } 03031 switch_channel_set_private(channel, "_tone_detect_", cont); 03032 } 03033 03034 cont->index++; 03035 03036 return SWITCH_STATUS_SUCCESS; 03037 }
| 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.
| sessa | the original session | |
| sessb | the new session | |
| var | the name of the variable to transfer (NULL for all) |
Definition at line 1744 of file switch_ivr.c.
References switch_event::headers, switch_event_header::name, switch_event_header::next, switch_channel_get_variable, switch_channel_get_variables(), switch_channel_set_variable, switch_core_session_get_channel(), switch_event_destroy(), SWITCH_STATUS_SUCCESS, and switch_event_header::value.
01745 { 01746 switch_channel_t *chana = switch_core_session_get_channel(sessa); 01747 switch_channel_t *chanb = switch_core_session_get_channel(sessb); 01748 switch_event_t *var_event; 01749 01750 const char *val = NULL; 01751 uint8_t prefix = 0; 01752 01753 if (var && *var == '~') { 01754 var++; 01755 prefix = 1; 01756 } 01757 01758 if (var && !prefix) { 01759 if ((val = switch_channel_get_variable(chana, var))) { 01760 switch_channel_set_variable(chanb, var, val); 01761 } 01762 } else { 01763 switch_event_header_t *hi; 01764 01765 switch_channel_get_variables(chana, &var_event); 01766 01767 for (hi = var_event->headers; hi; hi = hi->next) { 01768 char *vvar = hi->name; 01769 char *vval = hi->value; 01770 if (vvar && vval && (!prefix || (var && !strncmp((char *) vvar, var, strlen(var))))) { 01771 switch_channel_set_variable(chanb, (char *) vvar, (char *) vval); 01772 } 01773 } 01774 01775 switch_event_destroy(&var_event); 01776 } 01777 01778 return SWITCH_STATUS_SUCCESS; 01779 }
| switch_status_t switch_ivr_unhold | ( | switch_core_session_t * | session | ) |
Signal the session with a protocol specific unhold message.
| session | the session to unhold |
Definition at line 1408 of file switch_ivr.c.
References CF_BROADCAST, CF_HOLD, CF_SUSPEND, switch_core_session_message::from, switch_core_session_message::message_id, switch_channel_clear_flag(), switch_channel_get_variable, switch_channel_stop_broadcast, 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_MESSAGE_INDICATE_UNHOLD, SWITCH_SIGNAL_BOND_VARIABLE, and SWITCH_STATUS_SUCCESS.
Referenced by switch_ivr_unhold_uuid().
01409 { 01410 switch_core_session_message_t msg = { 0 }; 01411 switch_channel_t *channel = switch_core_session_get_channel(session); 01412 const char *other_uuid; 01413 switch_core_session_t *b_session; 01414 01415 msg.message_id = SWITCH_MESSAGE_INDICATE_UNHOLD; 01416 msg.from = __FILE__; 01417 01418 switch_channel_clear_flag(channel, CF_HOLD); 01419 switch_channel_clear_flag(channel, CF_SUSPEND); 01420 01421 switch_core_session_receive_message(session, &msg); 01422 01423 01424 if ((other_uuid = switch_channel_get_variable(channel, SWITCH_SIGNAL_BOND_VARIABLE)) && (b_session = switch_core_session_locate(other_uuid))) { 01425 switch_channel_t *b_channel = switch_core_session_get_channel(b_session); 01426 switch_channel_stop_broadcast(b_channel); 01427 switch_channel_wait_for_flag(b_channel, CF_BROADCAST, SWITCH_FALSE, 5000, NULL); 01428 switch_core_session_rwunlock(b_session); 01429 } 01430 01431 01432 return SWITCH_STATUS_SUCCESS; 01433 }
| switch_status_t switch_ivr_unhold_uuid | ( | const char * | uuid | ) |
Signal the session with a protocol specific unhold message.
| uuid | the uuid of the session to hold |
Definition at line 1435 of file switch_ivr.c.
References switch_core_session_locate(), switch_core_session_rwunlock(), switch_ivr_unhold(), and SWITCH_STATUS_SUCCESS.
01436 { 01437 switch_core_session_t *session; 01438 01439 if ((session = switch_core_session_locate(uuid))) { 01440 switch_ivr_unhold(session); 01441 switch_core_session_rwunlock(session); 01442 } 01443 01444 return SWITCH_STATUS_SUCCESS; 01445 }
| switch_status_t switch_ivr_uuid_bridge | ( | const char * | originator_uuid, | |
| const char * | originatee_uuid | |||
| ) |
Bridge two existing sessions.
| originator_uuid | the uuid of the originator | |
| originatee_uuid | the uuid of the originator |
Definition at line 1543 of file switch_ivr_bridge.c.
References switch_caller_profile::caller_id_name, switch_caller_profile::caller_id_number, CF_BRIDGE_ORIGINATOR, CF_DIALPLAN, CF_ORIGINATING, CF_REDIRECT, CF_TRANSFER, cleanup_proxy_mode_a(), CS_CONSUME_MEDIA, CS_HIBERNATE, switch_caller_profile::destination_number, switch_caller_profile::pool, SWITCH_BRIDGE_CHANNEL_VARIABLE, SWITCH_BRIDGE_UUID_VARIABLE, SWITCH_CALL_DIRECTION_OUTBOUND, switch_caller_profile_clone(), switch_channel_add_state_handler(), switch_channel_add_variable_var_check(), switch_channel_clear_flag(), switch_channel_clear_flag_recursive(), switch_channel_clear_state_flag(), switch_channel_clear_state_handler(), switch_channel_direction(), switch_channel_down_nosig, switch_channel_flip_cid(), switch_channel_get_caller_profile(), switch_channel_get_name(), switch_channel_get_state(), switch_channel_media_up, SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_flag, switch_channel_set_originatee_caller_profile(), switch_channel_set_originator_caller_profile(), switch_channel_set_state, switch_channel_set_state_flag(), switch_channel_set_variable, switch_channel_stop_broadcast, switch_channel_test_flag(), switch_core_session_get_channel(), switch_core_session_get_uuid(), switch_core_session_locate(), switch_core_session_rwunlock(), switch_core_sprintf(), switch_epoch_time_now(), SWITCH_FALSE, switch_ivr_bridge_display(), SWITCH_LOG_CRIT, SWITCH_LOG_DEBUG, switch_log_printf(), SWITCH_LOG_WARNING, SWITCH_SIGNAL_BOND_VARIABLE, SWITCH_STACK_PUSH, SWITCH_STATUS_FALSE, SWITCH_STATUS_SUCCESS, SWITCH_TRANSFER_HISTORY_VARIABLE, SWITCH_TRANSFER_SOURCE_VARIABLE, SWITCH_UUID_BRIDGE, switch_caller_profile::transfer_source, uuid_bridge_state_handlers, and switch_caller_profile::uuid_str.
Referenced by switch_ivr_intercept_session(), and switch_ivr_media().
01544 { 01545 switch_core_session_t *originator_session, *originatee_session, *swap_session; 01546 switch_channel_t *originator_channel, *originatee_channel, *swap_channel; 01547 switch_status_t status = SWITCH_STATUS_FALSE; 01548 switch_caller_profile_t *originator_cp, *originatee_cp; 01549 switch_channel_state_t state; 01550 01551 if ((originator_session = switch_core_session_locate(originator_uuid))) { 01552 if ((originatee_session = switch_core_session_locate(originatee_uuid))) { 01553 originator_channel = switch_core_session_get_channel(originator_session); 01554 originatee_channel = switch_core_session_get_channel(originatee_session); 01555 01556 01557 if (switch_channel_direction(originatee_channel) == SWITCH_CALL_DIRECTION_OUTBOUND && !switch_channel_test_flag(originatee_channel, CF_DIALPLAN)) { 01558 switch_channel_flip_cid(originatee_channel); 01559 switch_channel_set_flag(originatee_channel, CF_DIALPLAN); 01560 } 01561 01562 if (switch_channel_direction(originator_channel) == SWITCH_CALL_DIRECTION_OUTBOUND && !switch_channel_test_flag(originator_channel, CF_DIALPLAN)) { 01563 switch_channel_flip_cid(originator_channel); 01564 switch_channel_set_flag(originator_channel, CF_DIALPLAN); 01565 } 01566 01567 01568 if (switch_channel_down_nosig(originator_channel)) { 01569 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(originator_session), SWITCH_LOG_DEBUG, "%s is hungup refusing to bridge.\n", switch_channel_get_name(originatee_channel)); 01570 switch_core_session_rwunlock(originator_session); 01571 switch_core_session_rwunlock(originatee_session); 01572 return SWITCH_STATUS_FALSE; 01573 } 01574 01575 if (!switch_channel_media_up(originator_channel)) { 01576 if (switch_channel_media_up(originatee_channel)) { 01577 swap_session = originator_session; 01578 originator_session = originatee_session; 01579 originatee_session = swap_session; 01580 01581 swap_channel = originator_channel; 01582 originator_channel = originatee_channel; 01583 originatee_channel = swap_channel; 01584 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(originatee_session), SWITCH_LOG_WARNING, "reversing order of channels so this will work!\n"); 01585 } else { 01586 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(originator_session), SWITCH_LOG_CRIT, "Neither channel is answered, cannot bridge them.\n"); 01587 switch_core_session_rwunlock(originator_session); 01588 switch_core_session_rwunlock(originatee_session); 01589 return SWITCH_STATUS_FALSE; 01590 } 01591 } 01592 01593 cleanup_proxy_mode_a(originator_session); 01594 cleanup_proxy_mode_a(originatee_session); 01595 01596 /* override transmit state for originator_channel to bridge to originatee_channel 01597 * install pointer to originatee_session into originator_channel 01598 * set CF_TRANSFER on both channels and change state to CS_SOFT_EXECUTE to 01599 * interrupt anything they are already doing. 01600 * originatee_session will fall asleep and originator_session will bridge to it 01601 */ 01602 01603 switch_channel_set_flag(originator_channel, CF_REDIRECT); 01604 switch_channel_set_flag(originatee_channel, CF_REDIRECT); 01605 01606 01607 switch_channel_set_variable(originator_channel, SWITCH_UUID_BRIDGE, switch_core_session_get_uuid(originatee_session)); 01608 switch_channel_set_variable(originator_channel, SWITCH_BRIDGE_CHANNEL_VARIABLE, switch_channel_get_name(originatee_channel)); 01609 switch_channel_set_variable(originator_channel, SWITCH_BRIDGE_UUID_VARIABLE, switch_core_session_get_uuid(originatee_session)); 01610 switch_channel_set_variable(originator_channel, SWITCH_SIGNAL_BOND_VARIABLE, switch_core_session_get_uuid(originatee_session)); 01611 switch_channel_set_variable(originatee_channel, SWITCH_BRIDGE_CHANNEL_VARIABLE, switch_channel_get_name(originator_channel)); 01612 switch_channel_set_variable(originatee_channel, SWITCH_BRIDGE_UUID_VARIABLE, switch_core_session_get_uuid(originator_session)); 01613 switch_channel_set_variable(originatee_channel, SWITCH_SIGNAL_BOND_VARIABLE, switch_core_session_get_uuid(originator_session)); 01614 01615 01616 originator_cp = switch_channel_get_caller_profile(originator_channel); 01617 originatee_cp = switch_channel_get_caller_profile(originatee_channel); 01618 01619 01620 switch_channel_set_variable(originatee_channel, "original_destination_number", originatee_cp->destination_number); 01621 switch_channel_set_variable(originatee_channel, "original_caller_id_name", originatee_cp->caller_id_name); 01622 switch_channel_set_variable(originatee_channel, "original_caller_id_number", originatee_cp->caller_id_number); 01623 01624 switch_channel_set_variable(originator_channel, "original_destination_number", originator_cp->destination_number); 01625 switch_channel_set_variable(originator_channel, "original_caller_id_name", originator_cp->caller_id_name); 01626 switch_channel_set_variable(originator_channel, "original_caller_id_number", originator_cp->caller_id_number); 01627 01628 01629 switch_channel_set_originator_caller_profile(originatee_channel, switch_caller_profile_clone(originatee_session, originator_cp)); 01630 switch_channel_set_originatee_caller_profile(originator_channel, switch_caller_profile_clone(originator_session, originatee_cp)); 01631 01632 switch_channel_stop_broadcast(originator_channel); 01633 switch_channel_stop_broadcast(originatee_channel); 01634 01635 switch_channel_set_flag(originator_channel, CF_TRANSFER); 01636 switch_channel_set_flag(originatee_channel, CF_TRANSFER); 01637 01638 01639 switch_channel_clear_flag(originator_channel, CF_ORIGINATING); 01640 switch_channel_clear_flag(originatee_channel, CF_ORIGINATING); 01641 01642 01643 originator_cp->transfer_source = switch_core_sprintf(originator_cp->pool, 01644 "%ld:%s:uuid_br:%s", (long)switch_epoch_time_now(NULL), originator_cp->uuid_str, 01645 switch_core_session_get_uuid(originatee_session)); 01646 switch_channel_add_variable_var_check(originator_channel, SWITCH_TRANSFER_HISTORY_VARIABLE, 01647 originator_cp->transfer_source, SWITCH_FALSE, SWITCH_STACK_PUSH); 01648 switch_channel_set_variable(originator_channel, SWITCH_TRANSFER_SOURCE_VARIABLE, originator_cp->transfer_source); 01649 01650 01651 originatee_cp->transfer_source = switch_core_sprintf(originatee_cp->pool, 01652 "%ld:%s:uuid_br:%s", (long)switch_epoch_time_now(NULL), originatee_cp->uuid_str, 01653 switch_core_session_get_uuid(originator_session)); 01654 switch_channel_add_variable_var_check(originatee_channel, SWITCH_TRANSFER_HISTORY_VARIABLE, 01655 originatee_cp->transfer_source, SWITCH_FALSE, SWITCH_STACK_PUSH); 01656 switch_channel_set_variable(originatee_channel, SWITCH_TRANSFER_SOURCE_VARIABLE, originatee_cp->transfer_source); 01657 01658 /* change the states and let the chips fall where they may */ 01659 01660 //switch_channel_set_variable(originator_channel, SWITCH_PARK_AFTER_BRIDGE_VARIABLE, NULL); 01661 //switch_channel_set_variable(originatee_channel, SWITCH_PARK_AFTER_BRIDGE_VARIABLE, NULL); 01662 switch_channel_clear_state_handler(originator_channel, NULL); 01663 switch_channel_clear_state_handler(originatee_channel, NULL); 01664 switch_channel_clear_flag_recursive(originator_channel, CF_BRIDGE_ORIGINATOR); 01665 switch_channel_clear_flag_recursive(originatee_channel, CF_BRIDGE_ORIGINATOR); 01666 switch_channel_set_state_flag(originator_channel, CF_BRIDGE_ORIGINATOR); 01667 switch_channel_clear_state_flag(originatee_channel, CF_BRIDGE_ORIGINATOR); 01668 switch_channel_add_state_handler(originator_channel, &uuid_bridge_state_handlers); 01669 switch_channel_add_state_handler(originatee_channel, &uuid_bridge_state_handlers); 01670 01671 state = switch_channel_get_state(originator_channel); 01672 switch_channel_set_state(originator_channel, state == CS_HIBERNATE ? CS_CONSUME_MEDIA : CS_HIBERNATE); 01673 state = switch_channel_get_state(originatee_channel); 01674 switch_channel_set_state(originatee_channel, state == CS_HIBERNATE ? CS_CONSUME_MEDIA : CS_HIBERNATE); 01675 01676 status = SWITCH_STATUS_SUCCESS; 01677 01678 switch_ivr_bridge_display(originator_session, originatee_session); 01679 01680 /* release the read locks we have on the channels */ 01681 switch_core_session_rwunlock(originator_session); 01682 switch_core_session_rwunlock(originatee_session); 01683 01684 } else { 01685 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(originator_session), SWITCH_LOG_DEBUG, "originatee uuid %s is not present\n", originatee_uuid); 01686 switch_core_session_rwunlock(originator_session); 01687 } 01688 } else { 01689 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(originator_session), SWITCH_LOG_DEBUG, "originator uuid %s is not present\n", originator_uuid); 01690 } 01691 01692 return status; 01693 }
| 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 | |||
| ) |
Definition at line 1733 of file switch_ivr_play_say.c.
References switch_codec_implementation::actual_samples_per_second, switch_frame::buflen, switch_frame::codec, switch_frame::data, switch_frame::datalen, switch_codec::implementation, switch_codec_implementation::microseconds_per_packet, switch_codec_implementation::number_of_channels, switch_frame::samples, switch_codec_implementation::samples_per_packet, switch_channel_ready, SWITCH_CODEC_FLAG_DECODE, SWITCH_CODEC_FLAG_ENCODE, switch_core_codec_destroy(), switch_core_codec_init, switch_core_file_close(), switch_core_file_open, switch_core_file_read(), switch_core_session_get_channel(), switch_core_session_get_pool(), switch_core_session_get_read_impl(), switch_core_session_read_frame(), switch_core_session_reset(), switch_core_session_set_read_codec(), switch_core_session_write_frame(), SWITCH_FALSE, SWITCH_FILE_DATA_SHORT, SWITCH_FILE_FLAG_READ, SWITCH_IO_FLAG_NONE, SWITCH_READ_ACCEPTABLE, SWITCH_RECOMMENDED_BUFFER_SIZE, SWITCH_STATUS_FALSE, SWITCH_STATUS_NOTFOUND, SWITCH_STATUS_SUCCESS, SWITCH_TRUE, and switch_zmalloc.
01735 { 01736 uint32_t score, count = 0, j = 0; 01737 double energy = 0; 01738 switch_channel_t *channel = switch_core_session_get_channel(session); 01739 int divisor = 0; 01740 uint32_t org_silence_hits = silence_hits; 01741 uint32_t channels; 01742 switch_frame_t *read_frame; 01743 switch_status_t status = SWITCH_STATUS_FALSE; 01744 int16_t *data; 01745 uint32_t listening = 0; 01746 int countdown = 0; 01747 switch_codec_t raw_codec = { 0 }; 01748 int16_t *abuf = NULL; 01749 switch_frame_t write_frame = { 0 }; 01750 switch_file_handle_t fh = { 0 }; 01751 int32_t sample_count = 0; 01752 switch_codec_implementation_t read_impl = { 0 }; 01753 switch_core_session_get_read_impl(session, &read_impl); 01754 01755 01756 if (timeout_ms) { 01757 sample_count = (read_impl.actual_samples_per_second / 1000) * timeout_ms; 01758 } 01759 01760 if (file) { 01761 if (switch_core_file_open(&fh, 01762 file, 01763 read_impl.number_of_channels, 01764 read_impl.actual_samples_per_second, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT, NULL) != SWITCH_STATUS_SUCCESS) { 01765 switch_core_session_reset(session, SWITCH_TRUE, SWITCH_FALSE); 01766 return SWITCH_STATUS_NOTFOUND; 01767 } 01768 switch_zmalloc(abuf, SWITCH_RECOMMENDED_BUFFER_SIZE); 01769 write_frame.data = abuf; 01770 write_frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE; 01771 } 01772 01773 01774 if (switch_core_codec_init(&raw_codec, 01775 "L16", 01776 NULL, 01777 read_impl.actual_samples_per_second, 01778 read_impl.microseconds_per_packet / 1000, 01779 1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE, 01780 NULL, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { 01781 01782 status = SWITCH_STATUS_FALSE; 01783 goto end; 01784 } 01785 01786 write_frame.codec = &raw_codec; 01787 01788 divisor = read_impl.actual_samples_per_second / 8000; 01789 channels = read_impl.number_of_channels; 01790 01791 switch_core_session_set_read_codec(session, &raw_codec); 01792 01793 while (switch_channel_ready(channel)) { 01794 01795 status = switch_core_session_read_frame(session, &read_frame, SWITCH_IO_FLAG_NONE, 0); 01796 01797 if (!SWITCH_READ_ACCEPTABLE(status)) { 01798 break; 01799 } 01800 01801 if (sample_count) { 01802 sample_count -= raw_codec.implementation->samples_per_packet; 01803 if (sample_count <= 0) { 01804 break; 01805 } 01806 } 01807 01808 if (abuf) { 01809 switch_size_t olen = raw_codec.implementation->samples_per_packet; 01810 01811 if (switch_core_file_read(&fh, abuf, &olen) != SWITCH_STATUS_SUCCESS) { 01812 break; 01813 } 01814 01815 write_frame.samples = (uint32_t) olen; 01816 write_frame.datalen = (uint32_t) (olen * sizeof(int16_t)); 01817 if ((status = switch_core_session_write_frame(session, &write_frame, SWITCH_IO_FLAG_NONE, 0)) != SWITCH_STATUS_SUCCESS) { 01818 break; 01819 } 01820 } 01821 01822 if (countdown) { 01823 if (!--countdown) { 01824 break; 01825 } else { 01826 continue; 01827 } 01828 } 01829 01830 data = (int16_t *) read_frame->data; 01831 01832 for (energy = 0, j = 0, count = 0; count < read_frame->samples; count++) { 01833 energy += abs(data[j++]); 01834 j += channels; 01835 } 01836 01837 score = (uint32_t) (energy / (read_frame->samples / divisor)); 01838 01839 if (score >= thresh) { 01840 listening++; 01841 } 01842 01843 if (listening > listen_hits && score < thresh) { 01844 if (!--silence_hits) { 01845 countdown = 25; 01846 } 01847 } else { 01848 silence_hits = org_silence_hits; 01849 } 01850 } 01851 01852 switch_core_session_reset(session, SWITCH_FALSE, SWITCH_TRUE); 01853 switch_core_codec_destroy(&raw_codec); 01854 01855 end: 01856 01857 if (abuf) { 01858 switch_core_file_close(&fh); 01859 free(abuf); 01860 } 01861 01862 return status; 01863 }
| 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.
| session | the current session to play sound to and collect digits | |
| min_digits | the fewest digits allowed for the response to be valid | |
| max_digits | the max number of digits to accept | |
| max_tries | number of times to replay the sound and capture digits | |
| timeout | time to wait for input (this is per iteration, so total possible time = max_tries * (timeout + audio playback length) | |
| valid_terminators | for input that can include # or * (useful for variable length prompts) | |
| audio_file | file to play | |
| bad_input_audio_file | file to play if the input from the user was invalid | |
| var_name | variable name to put results in | |
| digit_buffer | variable digits captured will be put back into (empty if capture failed) | |
| digit_buffer_length | length of the buffer for digits (should be the same or larger than max_digits) | |
| digits_regex | the qualifying regex |
Definition at line 1982 of file switch_ivr_play_say.c.
References switch_channel_get_variable, switch_channel_ready, SWITCH_CHANNEL_SESSION_LOG, switch_channel_set_variable, switch_core_session_get_channel(), switch_core_session_strdup, switch_ivr_play_file(), switch_ivr_read(), switch_ivr_session_transfer(), SWITCH_LOG_DEBUG, SWITCH_LOG_ERROR, switch_log_printf(), SWITCH_LOG_WARNING, SWITCH_READ_TERMINATOR_USED_VARIABLE, switch_regex_match(), switch_separate_string(), SWITCH_STATUS_FALSE, SWITCH_STATUS_RESTART, SWITCH_STATUS_SUCCESS, SWITCH_STATUS_TIMEOUT, SWITCH_STATUS_TOO_SMALL, and zstr.
Referenced by CoreSession::playAndGetDigits().
01996 { 01997 switch_channel_t *channel = switch_core_session_get_channel(session); 01998 01999 while (switch_channel_ready(channel) && max_tries) { 02000 switch_status_t status; 02001 02002 memset(digit_buffer, 0, digit_buffer_length); 02003 02004 status = switch_ivr_read(session, min_digits, max_digits, prompt_audio_file, var_name, 02005 digit_buffer, digit_buffer_length, timeout, valid_terminators, digit_timeout); 02006 02007 if (status == SWITCH_STATUS_RESTART) { 02008 return status; 02009 } 02010 02011 if (status == SWITCH_STATUS_TIMEOUT && strlen(digit_buffer) >= min_digits) { 02012 status = SWITCH_STATUS_SUCCESS; 02013 } 02014 02015 if ((min_digits == 0) && (strlen(digit_buffer) == 0) && switch_channel_get_variable(channel, SWITCH_READ_TERMINATOR_USED_VARIABLE) != 0) 02016 { 02017 return SWITCH_STATUS_SUCCESS; 02018 } 02019 02020 if (!(status == SWITCH_STATUS_TOO_SMALL && strlen(digit_buffer) == 0)) { 02021 if (status == SWITCH_STATUS_SUCCESS) { 02022 if (!zstr(digit_buffer)) { 02023 if (zstr(digits_regex)) { 02024 return SWITCH_STATUS_SUCCESS; 02025 } 02026 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Test Regex [%s][%s]\n", digit_buffer, digits_regex); 02027 if (switch_regex_match(digit_buffer, digits_regex) == SWITCH_STATUS_SUCCESS) { 02028 return SWITCH_STATUS_SUCCESS; 02029 } else { 02030 switch_channel_set_variable(channel, var_name, NULL); 02031 } 02032 } 02033 } 02034 } 02035 02036 if (!switch_channel_ready(channel)) { 02037 break; 02038 } 02039 02040 switch_ivr_play_file(session, NULL, bad_input_audio_file, NULL); 02041 max_tries--; 02042 } 02043 02044 memset(digit_buffer, 0, digit_buffer_length); 02045 02046 /* If we get here then check for transfer-on-failure ext/dp/context */ 02047 /* split this arg on spaces to get ext, dp, and context */ 02048 02049 if (!zstr(transfer_on_failure)) { 02050 const char *failure_ext = NULL; 02051 const char *failure_dialplan = NULL; 02052 const char *failure_context = NULL; 02053 char *target[4]; 02054 char *mydata = switch_core_session_strdup(session, transfer_on_failure); 02055 int argc; 02056 02057 argc = switch_separate_string(mydata, ' ', target, (sizeof(target) / sizeof(target[0]))); 02058 02059 if ( argc < 1 ) { 02060 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR,"Bad target for PAGD failure: [%s]\n", transfer_on_failure); 02061 return SWITCH_STATUS_FALSE; 02062 } 02063 02064 if ( argc > 0 ) { 02065 failure_ext = target[0]; 02066 } 02067 02068 if ( argc > 1 ) { 02069 failure_dialplan = target[1]; 02070 } 02071 02072 if ( argc > 2 ) { 02073 failure_context = target[2]; 02074 } 02075 02076 switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, 02077 "PAGD failure! Transfer to: %s / %s / %s\n", failure_ext, failure_dialplan, failure_context); 02078 02079 switch_ivr_session_transfer(session,failure_ext, failure_dialplan, failure_context); 02080 return SWITCH_STATUS_FALSE; 02081 } 02082 02083 return SWITCH_STATUS_FALSE; 02084 }
1.4.7