return SWITCH_STATUS_SUCCESS;
}
+
+#define AUDIO_SYNTAX "<uuid> [start [read|write] [mute|level <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 "<uuid> [all]"
SWITCH_STANDARD_API(break_function)
{
SWITCH_ADD_API(commands_api_interface, "url_encode", "url encode a string", url_encode_function, "<string>");
SWITCH_ADD_API(commands_api_interface, "user_data", "find user data", user_data_function, "<user>@<domain> [var|param|attr] <name>");
SWITCH_ADD_API(commands_api_interface, "user_exists", "find a user", user_exists_function, "<key> <user> <domain>");
+ 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);
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");
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;