/* * Asterisk -- An open source telephony toolkit. * * Copyright (C) 2009, Olle E. Johansson * * Olle E. Johansson * * See http://www.asterisk.org for more information about * the Asterisk project. Please do not directly contact * any of the maintainers of this project for assistance; * the project provides a web site, mailing lists and IRC * channels for your use. * * This program is free software, distributed under the terms of * the GNU General Public License Version 2. See the LICENSE file * at the top of the source tree. */ /*! \file * * \brief MUTESTREAM audiohooks * * \author Olle E. Johansson * * \ingroup functions * * \note This module only handles audio streams today, but can easily be appended to also * zero out text streams if there's an application for it. * When we know and understands what happens if we zero out video, we can do that too. */ /*** MODULEINFO core ***/ #include "asterisk.h" #include "asterisk/options.h" #include "asterisk/logger.h" #include "asterisk/channel.h" #include "asterisk/module.h" #include "asterisk/config.h" #include "asterisk/file.h" #include "asterisk/pbx.h" #include "asterisk/frame.h" #include "asterisk/utils.h" #include "asterisk/audiohook.h" #include "asterisk/manager.h" /*** DOCUMENTATION Muting audio streams in the channel Must be one of Inbound stream (to the PBX) Outbound stream (from the PBX) Both streams The MUTEAUDIO function can be used to mute inbound (to the PBX) or outbound audio in a call. Examples: MUTEAUDIO(in)=on MUTEAUDIO(in)=off Mute an audio stream. The channel you want to mute. Set muting on inbound audio stream. (to the PBX) Set muting on outbound audio stream. (from the PBX) Set muting on inbound and outbound audio streams. Turn muting on. Turn muting off. Mute an incoming or outgoing audio stream on a channel. ***/ static int mute_channel(struct ast_channel *chan, const char *direction, int mute) { unsigned int mute_direction = 0; enum ast_frame_type frametype = AST_FRAME_VOICE; int ret = 0; if (!strcmp(direction, "in")) { mute_direction = AST_MUTE_DIRECTION_READ; } else if (!strcmp(direction, "out")) { mute_direction = AST_MUTE_DIRECTION_WRITE; } else if (!strcmp(direction, "all")) { mute_direction = AST_MUTE_DIRECTION_READ | AST_MUTE_DIRECTION_WRITE; } else { return -1; } ast_channel_lock(chan); if (mute) { ret = ast_channel_suppress(chan, mute_direction, frametype); } else { ret = ast_channel_unsuppress(chan, mute_direction, frametype); } ast_channel_unlock(chan); return ret; } /*! \brief Mute dialplan function */ static int func_mute_write(struct ast_channel *chan, const char *cmd, char *data, const char *value) { if (!chan) { ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd); return -1; } return mute_channel(chan, data, ast_true(value)); } /* Function for debugging - might be useful */ static struct ast_custom_function mute_function = { .name = "MUTEAUDIO", .write = func_mute_write, }; static int manager_mutestream(struct mansession *s, const struct message *m) { const char *channel = astman_get_header(m, "Channel"); const char *id = astman_get_header(m,"ActionID"); const char *state = astman_get_header(m,"State"); const char *direction = astman_get_header(m,"Direction"); char id_text[256]; struct ast_channel *c = NULL; if (ast_strlen_zero(channel)) { astman_send_error(s, m, "Channel not specified"); return 0; } if (ast_strlen_zero(state)) { astman_send_error(s, m, "State not specified"); return 0; } if (ast_strlen_zero(direction)) { astman_send_error(s, m, "Direction not specified"); return 0; } /* Ok, we have everything */ c = ast_channel_get_by_name(channel); if (!c) { astman_send_error(s, m, "No such channel"); return 0; } if (mute_channel(c, direction, ast_true(state))) { astman_send_error(s, m, "Failed to mute/unmute stream"); ast_channel_unref(c); return 0; } ast_channel_unref(c); if (!ast_strlen_zero(id)) { snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id); } else { id_text[0] = '\0'; } astman_append(s, "Response: Success\r\n" "%s" "\r\n", id_text); return 0; } static int load_module(void) { int res; res = ast_custom_function_register(&mute_function); res |= ast_manager_register_xml("MuteAudio", EVENT_FLAG_SYSTEM, manager_mutestream); return (res ? AST_MODULE_LOAD_DECLINE : AST_MODULE_LOAD_SUCCESS); } static int unload_module(void) { ast_custom_function_unregister(&mute_function); /* Unregister AMI actions */ ast_manager_unregister("MuteAudio"); return 0; } AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Mute audio stream resources");