From a5f83ef69163437b41f49b4d6fa6a8ddc0bf7897 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 17 Dec 2009 20:46:49 +0000 Subject: [PATCH] add uuid_audio cli cmd git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@15989 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- src/include/switch_core.h | 2 + src/include/switch_ivr.h | 4 + .../applications/mod_commands/mod_commands.c | 69 +++++++++ src/switch_core_media_bug.c | 10 ++ src/switch_ivr_async.c | 140 ++++++++++++++++++ 5 files changed, 225 insertions(+) diff --git a/src/include/switch_core.h b/src/include/switch_core.h index 655c0b005f..19194f9062 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -202,6 +202,8 @@ SWITCH_DECLARE(switch_core_session_t *) switch_core_media_bug_get_session(_In_ s \return true value if the object has the flags defined */ SWITCH_DECLARE(uint32_t) switch_core_media_bug_test_flag(_In_ switch_media_bug_t *bug, _In_ uint32_t flag); +SWITCH_DECLARE(uint32_t) switch_core_media_bug_set_flag(_In_ switch_media_bug_t *bug, _In_ uint32_t flag); +SWITCH_DECLARE(uint32_t) switch_core_media_bug_clear_flag(_In_ switch_media_bug_t *bug, _In_ uint32_t flag); /*! \brief Set a return replace frame diff --git a/src/include/switch_ivr.h b/src/include/switch_ivr.h index 2a99ed7559..506a118934 100644 --- a/src/include/switch_ivr.h +++ b/src/include/switch_ivr.h @@ -244,6 +244,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_stop_displace_session(switch_core_ses */ SWITCH_DECLARE(switch_status_t) switch_ivr_stop_record_session(switch_core_session_t *session, const char *file); + +SWITCH_DECLARE(switch_status_t) switch_ivr_session_audio(switch_core_session_t *session, const char *cmd, const char *direction, int level); +SWITCH_DECLARE(switch_status_t) switch_ivr_stop_session_audio(switch_core_session_t *session); + /*! \brief Start looking for DTMF inband \param session the session to start looking diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 4eb6fee8e1..5c0c3df38e 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -2405,6 +2405,69 @@ SWITCH_STANDARD_API(session_displace_function) return SWITCH_STATUS_SUCCESS; } + +#define AUDIO_SYNTAX " [start [read|write] [mute|level ]|stop]" +SWITCH_STANDARD_API(session_audio_function) +{ + switch_core_session_t *u_session = NULL; + char *mycmd = NULL; + int fail = 0; + int argc = 0; + char *argv[5] = { 0 }; + int level; + + if (zstr(cmd)) { + fail++; goto done; + } + + mycmd = strdup(cmd); + argc = switch_split(mycmd, ' ', argv); + + if (argc < 2) { + fail++; goto done; + } + + if (!(u_session = switch_core_session_locate(argv[0]))) { + stream->write_function(stream, "-ERR No Such Channel!\n"); + goto done; + } + + if (!strcasecmp(argv[1], "stop")) { + switch_ivr_stop_session_audio(u_session); + goto done; + } + + if (strcasecmp(argv[1], "start") || argc < 5 || (strcasecmp(argv[2], "read") && strcasecmp(argv[2], "write"))) { + fail++; goto done; + } + + level = atoi(argv[4]); + + if (!strcasecmp(argv[3], "mute")) { + switch_ivr_session_audio(u_session, "mute", argv[2], level); + } else if (!strcasecmp(argv[3], "level")) { + switch_ivr_session_audio(u_session, "level", argv[2], level); + } else { + fail++; + } + + done: + + if (u_session) { + switch_core_session_rwunlock(u_session); + } + + switch_safe_free(mycmd); + + if (fail) { + stream->write_function(stream, "-USAGE: %s\n", AUDIO_SYNTAX); + } else { + stream->write_function(stream, "+OK\n"); + } + + return SWITCH_STATUS_SUCCESS; +} + #define BREAK_SYNTAX " [all]" SWITCH_STANDARD_API(break_function) { @@ -3895,6 +3958,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) SWITCH_ADD_API(commands_api_interface, "url_encode", "url encode a string", url_encode_function, ""); SWITCH_ADD_API(commands_api_interface, "user_data", "find user data", user_data_function, "@ [var|param|attr] "); SWITCH_ADD_API(commands_api_interface, "user_exists", "find a user", user_exists_function, " "); + SWITCH_ADD_API(commands_api_interface, "uuid_audio", "uuid_audio", session_audio_function, AUDIO_SYNTAX); SWITCH_ADD_API(commands_api_interface, "uuid_bridge", "uuid_bridge", uuid_bridge_function, ""); SWITCH_ADD_API(commands_api_interface, "uuid_broadcast", "broadcast", uuid_broadcast_function, BROADCAST_SYNTAX); SWITCH_ADD_API(commands_api_interface, "uuid_chat", "Send a chat message", uuid_chat, UUID_CHAT_SYNTAX); @@ -3973,6 +4037,11 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) switch_console_set_complete("add show nat_map"); switch_console_set_complete("add show say"); switch_console_set_complete("add show timer"); + switch_console_set_complete("add uuid_audio ::console::list_uuid start read mute"); + switch_console_set_complete("add uuid_audio ::console::list_uuid start read level"); + switch_console_set_complete("add uuid_audio ::console::list_uuid start write mute"); + switch_console_set_complete("add uuid_audio ::console::list_uuid start write level"); + switch_console_set_complete("add uuid_audio ::console::list_uuid stop"); switch_console_set_complete("add uuid_bridge ::console::list_uuid ::console::list_uuid"); switch_console_set_complete("add uuid_broadcast ::console::list_uuid"); switch_console_set_complete("add uuid_chat ::console::list_uuid"); diff --git a/src/switch_core_media_bug.c b/src/switch_core_media_bug.c index bac2eeda52..3171e71458 100644 --- a/src/switch_core_media_bug.c +++ b/src/switch_core_media_bug.c @@ -61,6 +61,16 @@ SWITCH_DECLARE(uint32_t) switch_core_media_bug_test_flag(switch_media_bug_t *bug return switch_test_flag(bug, flag); } +SWITCH_DECLARE(uint32_t) switch_core_media_bug_set_flag(switch_media_bug_t *bug, uint32_t flag) +{ + return switch_set_flag(bug, flag); +} + +SWITCH_DECLARE(uint32_t) switch_core_media_bug_clear_flag(switch_media_bug_t *bug, uint32_t flag) +{ + return switch_clear_flag(bug, flag); +} + SWITCH_DECLARE(switch_core_session_t *) switch_core_media_bug_get_session(switch_media_bug_t *bug) { return bug->session; diff --git a/src/switch_ivr_async.c b/src/switch_ivr_async.c index 955cd1193e..bc8bc53c9e 100644 --- a/src/switch_ivr_async.c +++ b/src/switch_ivr_async.c @@ -1355,6 +1355,146 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_preprocess_session(switch_core_sessio return SWITCH_STATUS_SUCCESS; } + +typedef struct { + switch_core_session_t *session; + int mute; + int read_level; + int write_level; + int read_mute; + int write_mute; +} switch_session_audio_t; + +static switch_bool_t session_audio_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type) +{ + switch_session_audio_t *pvt = (switch_session_audio_t *) user_data; + switch_frame_t *frame = NULL; + int level = 0, mute = 0; + + + if (type == SWITCH_ABC_TYPE_READ_REPLACE || type == SWITCH_ABC_TYPE_WRITE_REPLACE) { + if (!(pvt->read_level || pvt->write_level || pvt->read_mute || pvt->write_mute)) { + switch_channel_set_private(switch_core_session_get_channel(pvt->session), "__audio", NULL); + return SWITCH_FALSE; + } + } + + if (type == SWITCH_ABC_TYPE_READ_REPLACE) { + level = pvt->read_level; + mute = pvt->read_mute; + frame = switch_core_media_bug_get_read_replace_frame(bug); + } else if (type == SWITCH_ABC_TYPE_WRITE_REPLACE) { + level = pvt->write_level; + mute = pvt->write_mute; + frame = switch_core_media_bug_get_write_replace_frame(bug); + } + + if (frame) { + if (mute) { + switch_generate_sln_silence(frame->data, frame->datalen / 2, 400); + } else if (level) { + switch_change_sln_volume(frame->data, frame->datalen / 2, level); + } + + if (type == SWITCH_ABC_TYPE_READ_REPLACE) { + switch_core_media_bug_set_read_replace_frame(bug, frame); + } else if (type == SWITCH_ABC_TYPE_WRITE_REPLACE) { + switch_core_media_bug_set_write_replace_frame(bug, frame); + } + } + + return SWITCH_TRUE; +} + +SWITCH_DECLARE(switch_status_t) switch_ivr_stop_session_audio(switch_core_session_t *session) +{ + switch_media_bug_t *bug; + switch_channel_t *channel = switch_core_session_get_channel(session); + + if ((bug = switch_channel_get_private(channel, "__audio"))) { + switch_channel_set_private(channel, "__audio", NULL); + switch_core_media_bug_remove(session, &bug); + return SWITCH_STATUS_SUCCESS; + } + return SWITCH_STATUS_FALSE; +} + +SWITCH_DECLARE(switch_status_t) switch_ivr_session_audio(switch_core_session_t *session, const char *cmd, const char *direction, int level) +{ + switch_channel_t *channel = switch_core_session_get_channel(session); + switch_media_bug_t *bug; + switch_status_t status; + switch_session_audio_t *pvt; + switch_codec_implementation_t read_impl = {0}; + int existing = 0, c_read = 0, c_write = 0, flags = 0; + + if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) { + return SWITCH_STATUS_FALSE; + } + + switch_core_session_get_read_impl(session, &read_impl); + + + if ((bug = switch_channel_get_private(channel, "__audio"))) { + pvt = switch_core_media_bug_get_user_data(bug); + existing = 1; + } else { + if (!(pvt = switch_core_session_alloc(session, sizeof(*pvt)))) { + return SWITCH_STATUS_MEMERR; + } + + pvt->session = session; + } + + + if (!strcasecmp(direction, "write")) { + flags = SMBF_WRITE_REPLACE; + c_write = 1; + } else if (!strcasecmp(direction, "read")){ + flags = SMBF_READ_REPLACE; + c_read = 1; + } else if (!strcasecmp(direction, "both")){ + flags = SMBF_READ_REPLACE | SMBF_WRITE_REPLACE; + c_read = c_write = 1; + } + + + if (!strcasecmp(cmd, "mute")) { + if (c_read) { + pvt->read_mute = level; + } + if (c_write) { + pvt->write_mute = level; + } + } else if (!strcasecmp(cmd, "level")) { + if (level < 5 && level > -5) { + if (c_read) { + pvt->read_level = level; + } + if (c_write) { + pvt->write_level = level; + } + } + } + + if (existing) { + switch_core_media_bug_clear_flag(bug, SMBF_READ_REPLACE); + switch_core_media_bug_clear_flag(bug, SMBF_WRITE_REPLACE); + switch_core_media_bug_set_flag(bug, flags); + + } else { + if ((status = switch_core_media_bug_add(session, session_audio_callback, pvt, 0, flags, &bug)) != SWITCH_STATUS_SUCCESS) { + return status; + } + + switch_channel_set_private(channel, "__audio", bug); + } + + + return SWITCH_STATUS_SUCCESS; +} + + typedef struct { switch_core_session_t *session; teletone_dtmf_detect_state_t dtmf_detect;