Asterisk - The Open Source Telephony Project  21.4.1
res_mutestream.c
Go to the documentation of this file.
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 
19 /*! \file
20  *
21  * \brief MUTESTREAM audiohooks
22  *
23  * \author Olle E. Johansson <oej@edvina.net>
24  *
25  * \ingroup functions
26  *
27  * \note This module only handles audio streams today, but can easily be appended to also
28  * zero out text streams if there's an application for it.
29  * When we know and understand what happens if we zero out video, we can do that too.
30  */
31 
32 /*** MODULEINFO
33  <support_level>core</support_level>
34  ***/
35 
36 #include "asterisk.h"
37 
38 #include "asterisk/options.h"
39 #include "asterisk/logger.h"
40 #include "asterisk/channel.h"
41 #include "asterisk/module.h"
42 #include "asterisk/config.h"
43 #include "asterisk/file.h"
44 #include "asterisk/pbx.h"
45 #include "asterisk/frame.h"
46 #include "asterisk/utils.h"
47 #include "asterisk/audiohook.h"
48 #include "asterisk/manager.h"
49 
50 /*** DOCUMENTATION
51  <function name="MUTEAUDIO" language="en_US">
52  <synopsis>
53  Muting audio streams in the channel
54  </synopsis>
55  <syntax>
56  <parameter name="direction" required="true">
57  <para>Must be one of </para>
58  <enumlist>
59  <enum name="in">
60  <para>Inbound stream (to the PBX)</para>
61  </enum>
62  <enum name="out">
63  <para>Outbound stream (from the PBX)</para>
64  </enum>
65  <enum name="all">
66  <para>Both streams</para>
67  </enum>
68  </enumlist>
69  </parameter>
70  </syntax>
71  <description>
72  <para>The MUTEAUDIO function can be used to mute inbound (to the PBX) or outbound audio in a call.</para>
73  <example title="Mute incoming audio">
74  exten => s,1,Set(MUTEAUDIO(in)=on)
75  </example>
76  <example title="Do not mute incoming audio">
77  exten => s,1,Set(MUTEAUDIO(in)=off)
78  </example>
79  </description>
80  </function>
81  <manager name="MuteAudio" language="en_US">
82  <synopsis>
83  Mute an audio stream.
84  </synopsis>
85  <syntax>
86  <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
87  <parameter name="Channel" required="true">
88  <para>The channel you want to mute.</para>
89  </parameter>
90  <parameter name="Direction" required="true">
91  <enumlist>
92  <enum name="in">
93  <para>Set muting on inbound audio stream. (to the PBX)</para>
94  </enum>
95  <enum name="out">
96  <para>Set muting on outbound audio stream. (from the PBX)</para>
97  </enum>
98  <enum name="all">
99  <para>Set muting on inbound and outbound audio streams.</para>
100  </enum>
101  </enumlist>
102  </parameter>
103  <parameter name="State" required="true">
104  <enumlist>
105  <enum name="on">
106  <para>Turn muting on.</para>
107  </enum>
108  <enum name="off">
109  <para>Turn muting off.</para>
110  </enum>
111  </enumlist>
112  </parameter>
113  </syntax>
114  <description>
115  <para>Mute an incoming or outgoing audio stream on a channel.</para>
116  </description>
117  </manager>
118  ***/
119 
120 
121 static int mute_channel(struct ast_channel *chan, const char *direction, int mute)
122 {
123  unsigned int mute_direction = 0;
124  enum ast_frame_type frametype = AST_FRAME_VOICE;
125  int ret = 0;
126 
127  if (!strcmp(direction, "in")) {
128  mute_direction = AST_MUTE_DIRECTION_READ;
129  } else if (!strcmp(direction, "out")) {
130  mute_direction = AST_MUTE_DIRECTION_WRITE;
131  } else if (!strcmp(direction, "all")) {
132  mute_direction = AST_MUTE_DIRECTION_READ | AST_MUTE_DIRECTION_WRITE;
133  } else {
134  return -1;
135  }
136 
137  ast_channel_lock(chan);
138 
139  if (mute) {
140  ret = ast_channel_suppress(chan, mute_direction, frametype);
141  } else {
142  ret = ast_channel_unsuppress(chan, mute_direction, frametype);
143  }
144 
145  ast_channel_unlock(chan);
146 
147  return ret;
148 }
149 
150 /*! \brief Mute dialplan function */
151 static int func_mute_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
152 {
153  if (!chan) {
154  ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
155  return -1;
156  }
157 
158  return mute_channel(chan, data, ast_true(value));
159 }
160 
161 /* Function for debugging - might be useful */
162 static struct ast_custom_function mute_function = {
163  .name = "MUTEAUDIO",
164  .write = func_mute_write,
165 };
166 
167 static int manager_mutestream(struct mansession *s, const struct message *m)
168 {
169  const char *channel = astman_get_header(m, "Channel");
170  const char *id = astman_get_header(m,"ActionID");
171  const char *state = astman_get_header(m,"State");
172  const char *direction = astman_get_header(m,"Direction");
173  char id_text[256];
174  struct ast_channel *c = NULL;
175 
176  if (ast_strlen_zero(channel)) {
177  astman_send_error(s, m, "Channel not specified");
178  return 0;
179  }
180  if (ast_strlen_zero(state)) {
181  astman_send_error(s, m, "State not specified");
182  return 0;
183  }
184  if (ast_strlen_zero(direction)) {
185  astman_send_error(s, m, "Direction not specified");
186  return 0;
187  }
188  /* Ok, we have everything */
189 
190  c = ast_channel_get_by_name(channel);
191  if (!c) {
192  astman_send_error(s, m, "No such channel");
193  return 0;
194  }
195 
196  if (mute_channel(c, direction, ast_true(state))) {
197  astman_send_error(s, m, "Failed to mute/unmute stream");
199  return 0;
200  }
201 
203 
204  if (!ast_strlen_zero(id)) {
205  snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id);
206  } else {
207  id_text[0] = '\0';
208  }
209  astman_append(s, "Response: Success\r\n"
210  "%s"
211  "\r\n", id_text);
212  return 0;
213 }
214 
215 
216 static int load_module(void)
217 {
218  int res;
219 
220  res = ast_custom_function_register(&mute_function);
221  res |= ast_manager_register_xml("MuteAudio", EVENT_FLAG_SYSTEM, manager_mutestream);
222 
224 }
225 
226 static int unload_module(void)
227 {
228  ast_custom_function_unregister(&mute_function);
229  /* Unregister AMI actions */
230  ast_manager_unregister("MuteAudio");
231 
232  return 0;
233 }
234 
235 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Mute audio stream resources");
const char * name
Definition: pbx.h:119
Main Channel structure associated with a channel.
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:3310
Asterisk main include file. File version handling, generic pbx functions.
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2958
Audiohooks Architecture.
Generic File Format Support. Should be included by clients of the file handling routines. File service providers should instead include mod_format.h.
int ast_channel_suppress(struct ast_channel *chan, unsigned int direction, enum ast_frame_type frametype)
Suppress passing of a frame type on a channel.
Definition: channel.c:10777
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
Utility functions.
const char * astman_get_header(const struct message *m, char *var)
Get header from manager transaction.
Definition: manager.c:3050
Configuration File Parser.
General Asterisk PBX channel definitions.
Data structure associated with a custom dialplan function.
Definition: pbx.h:118
Asterisk internal frame definitions.
In case you didn't read that giant block of text above the mansession_session struct, the mansession is named this solely to keep the API the same in Asterisk. This structure really represents data that is different from Manager action to Manager action. The mansession_session pointer contained within points to session-specific data.
Definition: manager.c:1785
Core PBX routines and definitions.
ast_frame_type
Frame types.
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
Definition: manager.c:8057
The AMI - Asterisk Manager Interface - is a TCP protocol created to manage Asterisk with third-party ...
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
Definition: utils.c:2199
Support for logging to various files, console and syslog Configuration in file logger.conf.
Module has failed to load, may be in an inconsistent state.
Definition: module.h:78
int ast_channel_unsuppress(struct ast_channel *chan, unsigned int direction, enum ast_frame_type frametype)
Stop suppressing of a frame type on a channel.
Definition: channel.c:10839
static int func_mute_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
Mute dialplan function.
Options provided by main asterisk program.
#define ast_manager_register_xml(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:191
#define ASTERISK_GPL_KEY
The text the key() function should return.
Definition: module.h:46
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1454
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:3389
Asterisk module definitions.
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1558