res_mutestream.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 2009, Olle E. Johansson
  5. *
  6. * Olle E. Johansson <oej@edvina.net>
  7. *
  8. * See http://www.asterisk.org for more information about
  9. * the Asterisk project. Please do not directly contact
  10. * any of the maintainers of this project for assistance;
  11. * the project provides a web site, mailing lists and IRC
  12. * channels for your use.
  13. *
  14. * This program is free software, distributed under the terms of
  15. * the GNU General Public License Version 2. See the LICENSE file
  16. * at the top of the source tree.
  17. */
  18. /*! \file
  19. *
  20. * \brief MUTESTREAM audiohooks
  21. *
  22. * \author Olle E. Johansson <oej@edvina.net>
  23. *
  24. * \ingroup functions
  25. *
  26. * \note This module only handles audio streams today, but can easily be appended to also
  27. * zero out text streams if there's an application for it.
  28. * When we know and understands what happens if we zero out video, we can do that too.
  29. */
  30. /*** MODULEINFO
  31. <support_level>core</support_level>
  32. ***/
  33. #include "asterisk.h"
  34. ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
  35. #include "asterisk/options.h"
  36. #include "asterisk/logger.h"
  37. #include "asterisk/channel.h"
  38. #include "asterisk/module.h"
  39. #include "asterisk/config.h"
  40. #include "asterisk/file.h"
  41. #include "asterisk/pbx.h"
  42. #include "asterisk/frame.h"
  43. #include "asterisk/utils.h"
  44. #include "asterisk/audiohook.h"
  45. #include "asterisk/manager.h"
  46. /*** DOCUMENTATION
  47. <function name="MUTEAUDIO" language="en_US">
  48. <synopsis>
  49. Muting audio streams in the channel
  50. </synopsis>
  51. <syntax>
  52. <parameter name="direction" required="true">
  53. <para>Must be one of </para>
  54. <enumlist>
  55. <enum name="in">
  56. <para>Inbound stream (to the PBX)</para>
  57. </enum>
  58. <enum name="out">
  59. <para>Outbound stream (from the PBX)</para>
  60. </enum>
  61. <enum name="all">
  62. <para>Both streams</para>
  63. </enum>
  64. </enumlist>
  65. </parameter>
  66. </syntax>
  67. <description>
  68. <para>The MUTEAUDIO function can be used to mute inbound (to the PBX) or outbound audio in a call.
  69. </para>
  70. <para>Examples:
  71. </para>
  72. <para>
  73. MUTEAUDIO(in)=on
  74. </para>
  75. <para>
  76. MUTEAUDIO(in)=off
  77. </para>
  78. </description>
  79. </function>
  80. <manager name="MuteAudio" language="en_US">
  81. <synopsis>
  82. Mute an audio stream.
  83. </synopsis>
  84. <syntax>
  85. <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
  86. <parameter name="Channel" required="true">
  87. <para>The channel you want to mute.</para>
  88. </parameter>
  89. <parameter name="Direction" required="true">
  90. <enumlist>
  91. <enum name="in">
  92. <para>Set muting on inbound audio stream. (to the PBX)</para>
  93. </enum>
  94. <enum name="out">
  95. <para>Set muting on outbound audio stream. (from the PBX)</para>
  96. </enum>
  97. <enum name="all">
  98. <para>Set muting on inbound and outbound audio streams.</para>
  99. </enum>
  100. </enumlist>
  101. </parameter>
  102. <parameter name="State" required="true">
  103. <enumlist>
  104. <enum name="on">
  105. <para>Turn muting on.</para>
  106. </enum>
  107. <enum name="off">
  108. <para>Turn muting off.</para>
  109. </enum>
  110. </enumlist>
  111. </parameter>
  112. </syntax>
  113. <description>
  114. <para>Mute an incoming or outgoing audio stream on a channel.</para>
  115. </description>
  116. </manager>
  117. ***/
  118. static int mute_channel(struct ast_channel *chan, const char *direction, int mute)
  119. {
  120. unsigned int mute_direction = 0;
  121. enum ast_frame_type frametype = AST_FRAME_VOICE;
  122. int ret = 0;
  123. if (!strcmp(direction, "in")) {
  124. mute_direction = AST_MUTE_DIRECTION_READ;
  125. } else if (!strcmp(direction, "out")) {
  126. mute_direction = AST_MUTE_DIRECTION_WRITE;
  127. } else if (!strcmp(direction, "all")) {
  128. mute_direction = AST_MUTE_DIRECTION_READ | AST_MUTE_DIRECTION_WRITE;
  129. } else {
  130. return -1;
  131. }
  132. ast_channel_lock(chan);
  133. if (mute) {
  134. ret = ast_channel_suppress(chan, mute_direction, frametype);
  135. } else {
  136. ret = ast_channel_unsuppress(chan, mute_direction, frametype);
  137. }
  138. ast_channel_unlock(chan);
  139. return ret;
  140. }
  141. /*! \brief Mute dialplan function */
  142. static int func_mute_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
  143. {
  144. if (!chan) {
  145. ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
  146. return -1;
  147. }
  148. return mute_channel(chan, data, ast_true(value));
  149. }
  150. /* Function for debugging - might be useful */
  151. static struct ast_custom_function mute_function = {
  152. .name = "MUTEAUDIO",
  153. .write = func_mute_write,
  154. };
  155. static int manager_mutestream(struct mansession *s, const struct message *m)
  156. {
  157. const char *channel = astman_get_header(m, "Channel");
  158. const char *id = astman_get_header(m,"ActionID");
  159. const char *state = astman_get_header(m,"State");
  160. const char *direction = astman_get_header(m,"Direction");
  161. char id_text[256];
  162. struct ast_channel *c = NULL;
  163. if (ast_strlen_zero(channel)) {
  164. astman_send_error(s, m, "Channel not specified");
  165. return 0;
  166. }
  167. if (ast_strlen_zero(state)) {
  168. astman_send_error(s, m, "State not specified");
  169. return 0;
  170. }
  171. if (ast_strlen_zero(direction)) {
  172. astman_send_error(s, m, "Direction not specified");
  173. return 0;
  174. }
  175. /* Ok, we have everything */
  176. c = ast_channel_get_by_name(channel);
  177. if (!c) {
  178. astman_send_error(s, m, "No such channel");
  179. return 0;
  180. }
  181. if (mute_channel(c, direction, ast_true(state))) {
  182. astman_send_error(s, m, "Failed to mute/unmute stream");
  183. ast_channel_unref(c);
  184. return 0;
  185. }
  186. ast_channel_unref(c);
  187. if (!ast_strlen_zero(id)) {
  188. snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id);
  189. } else {
  190. id_text[0] = '\0';
  191. }
  192. astman_append(s, "Response: Success\r\n"
  193. "%s"
  194. "\r\n", id_text);
  195. return 0;
  196. }
  197. static int load_module(void)
  198. {
  199. int res;
  200. res = ast_custom_function_register(&mute_function);
  201. res |= ast_manager_register_xml("MuteAudio", EVENT_FLAG_SYSTEM, manager_mutestream);
  202. return (res ? AST_MODULE_LOAD_DECLINE : AST_MODULE_LOAD_SUCCESS);
  203. }
  204. static int unload_module(void)
  205. {
  206. ast_custom_function_unregister(&mute_function);
  207. /* Unregister AMI actions */
  208. ast_manager_unregister("MuteAudio");
  209. return 0;
  210. }
  211. AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Mute audio stream resources");