Wed Jan 8 2020 09:50:19

Asterisk developer's documentation


res_mutestream.c File Reference

MUTESTREAM audiohooks. More...

#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"

Go to the source code of this file.

Data Structures

struct  mute_information
 

Macros

#define FALSE   0
 
#define TRUE   1
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
static void destroy_callback (void *data)
 
static int func_mute_write (struct ast_channel *chan, const char *cmd, char *data, const char *value)
 Mute dialplan function. More...
 
static struct ast_datastoreinitialize_mutehook (struct ast_channel *chan)
 Initialize mute hook on channel, but don't activate it. More...
 
static int load_module (void)
 
static int manager_mutestream (struct mansession *s, const struct message *m)
 
static int mute_add_audiohook (struct ast_channel *chan, struct mute_information *mute, struct ast_datastore *datastore)
 Add or activate mute audiohook on channel Assumes channel is locked. More...
 
static int mute_callback (struct ast_audiohook *audiohook, struct ast_channel *chan, struct ast_frame *frame, enum ast_audiohook_direction direction)
 The callback from the audiohook subsystem. We basically get a frame to have fun with. More...
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Mute audio stream resources" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, }
 
static struct ast_module_infoast_module_info = &__mod_info
 
static const char mandescr_mutestream []
 
static struct ast_datastore_info mute_datastore
 Static structure for datastore information. More...
 
static struct ast_custom_function mute_function
 

Detailed Description

MUTESTREAM audiohooks.

Author
Olle E. Johansson oej@e.nosp@m.dvin.nosp@m.a.net
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.

Definition in file res_mutestream.c.

Macro Definition Documentation

#define FALSE   0

Definition at line 102 of file res_mutestream.c.

#define TRUE   1

Definition at line 101 of file res_mutestream.c.

Referenced by manager_mutestream().

Function Documentation

static void __reg_module ( void  )
static

Definition at line 356 of file res_mutestream.c.

static void __unreg_module ( void  )
static

Definition at line 356 of file res_mutestream.c.

static void destroy_callback ( void *  data)
static

Datastore destroy audiohook callback

Definition at line 105 of file res_mutestream.c.

References ast_audiohook_destroy(), ast_free, ast_module_unref(), mute_information::audiohook, mute, and ast_module_info::self.

106 {
107  struct mute_information *mute = data;
108 
109  /* Destroy the audiohook, and destroy ourselves */
111  ast_free(mute);
113 
114  return;
115 }
struct ast_audiohook audiohook
void ast_module_unref(struct ast_module *)
Definition: loader.c:1312
int ast_audiohook_destroy(struct ast_audiohook *audiohook)
Destroys an audiohook structure.
Definition: audiohook.c:96
static int mute
Definition: chan_alsa.c:135
struct ast_module * self
Definition: module.h:227
#define ast_free(a)
Definition: astmm.h:97
static int func_mute_write ( struct ast_channel chan,
const char *  cmd,
char *  data,
const char *  value 
)
static

Mute dialplan function.

Definition at line 203 of file res_mutestream.c.

References ast_channel_datastore_find(), ast_channel_lock, ast_channel_unlock, ast_datastore_free(), ast_debug, ast_free, ast_log(), ast_true(), ast_datastore::data, initialize_mutehook(), LOG_WARNING, mute, mute_add_audiohook(), mute_information::mute_read, and mute_information::mute_write.

204 {
205  struct ast_datastore *datastore = NULL;
206  struct mute_information *mute = NULL;
207  int is_new = 0;
208 
209  if (!chan) {
210  ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
211  return -1;
212  }
213 
214  ast_channel_lock(chan);
215  if (!(datastore = ast_channel_datastore_find(chan, &mute_datastore, NULL))) {
216  if (!(datastore = initialize_mutehook(chan))) {
217  ast_channel_unlock(chan);
218  return 0;
219  }
220  is_new = 1;
221  }
222 
223  mute = datastore->data;
224 
225  if (!strcasecmp(data, "out")) {
226  mute->mute_write = ast_true(value);
227  ast_debug(1, "%s channel - outbound \n", ast_true(value) ? "Muting" : "Unmuting");
228  } else if (!strcasecmp(data, "in")) {
229  mute->mute_read = ast_true(value);
230  ast_debug(1, "%s channel - inbound \n", ast_true(value) ? "Muting" : "Unmuting");
231  } else if (!strcasecmp(data,"all")) {
232  mute->mute_write = mute->mute_read = ast_true(value);
233  }
234 
235  if (is_new) {
236  if (mute_add_audiohook(chan, mute, datastore)) {
237  /* Can't add audiohook - already printed error message */
238  ast_datastore_free(datastore);
239  ast_free(mute);
240  }
241  }
242  ast_channel_unlock(chan);
243 
244  return 0;
245 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
static struct ast_datastore * initialize_mutehook(struct ast_channel *chan)
Initialize mute hook on channel, but don't activate it.
#define LOG_WARNING
Definition: logger.h:144
Structure for a data store object.
Definition: datastore.h:54
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
Definition: channel.c:2604
int value
Definition: syslog.c:39
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:65
static int mute
Definition: chan_alsa.c:135
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static int mute_add_audiohook(struct ast_channel *chan, struct mute_information *mute, struct ast_datastore *datastore)
Add or activate mute audiohook on channel Assumes channel is locked.
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:1533
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static struct ast_datastore_info mute_datastore
Static structure for datastore information.
#define ast_channel_unlock(chan)
Definition: channel.h:2467
#define ast_free(a)
Definition: astmm.h:97
void * data
Definition: datastore.h:56
static struct ast_datastore* initialize_mutehook ( struct ast_channel chan)
static

Initialize mute hook on channel, but don't activate it.

Precondition
Assumes that the channel is locked

Definition at line 164 of file res_mutestream.c.

References ast_audiohook_init(), AST_AUDIOHOOK_TYPE_MANIPULATE, ast_calloc, ast_datastore_alloc(), ast_datastore_free(), ast_debug, mute_information::audiohook, ast_datastore::data, ast_audiohook::manipulate_callback, mute, and mute_callback().

Referenced by func_mute_write(), and manager_mutestream().

165 {
166  struct ast_datastore *datastore = NULL;
167  struct mute_information *mute = NULL;
168 
169  ast_debug(2, "Initializing new Mute Audiohook \n");
170 
171  /* Allocate a new datastore to hold the reference to this mute_datastore and audiohook information */
172  if (!(datastore = ast_datastore_alloc(&mute_datastore, NULL))) {
173  return NULL;
174  }
175 
176  if (!(mute = ast_calloc(1, sizeof(*mute)))) {
177  ast_datastore_free(datastore);
178  return NULL;
179  }
182  datastore->data = mute;
183  return datastore;
184 }
struct ast_audiohook audiohook
static int mute_callback(struct ast_audiohook *audiohook, struct ast_channel *chan, struct ast_frame *frame, enum ast_audiohook_direction direction)
The callback from the audiohook subsystem. We basically get a frame to have fun with.
int ast_audiohook_init(struct ast_audiohook *audiohook, enum ast_audiohook_type type, const char *source)
Initialize an audiohook structure.
Definition: audiohook.c:64
Structure for a data store object.
Definition: datastore.h:54
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:65
static int mute
Definition: chan_alsa.c:135
ast_audiohook_manipulate_callback manipulate_callback
Definition: audiohook.h:116
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static struct ast_datastore_info mute_datastore
Static structure for datastore information.
struct ast_datastore * ast_datastore_alloc(const struct ast_datastore_info *info, const char *uid)
Definition: datastore.c:98
void * data
Definition: datastore.h:56
#define ast_calloc(a, b)
Definition: astmm.h:82
static int load_module ( void  )
static

Definition at line 336 of file res_mutestream.c.

References ast_custom_function_register, ast_manager_register2(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, EVENT_FLAG_SYSTEM, and manager_mutestream().

337 {
338  int res;
340 
342  "Mute an audio stream", mandescr_mutestream);
343 
345 }
#define EVENT_FLAG_SYSTEM
Definition: manager.h:71
static const char mandescr_mutestream[]
int ast_manager_register2(const char *action, int authority, int(*func)(struct mansession *s, const struct message *m), const char *synopsis, const char *description)
Register a manager command with the manager interface.
Definition: manager.c:5469
static struct ast_custom_function mute_function
#define ast_custom_function_register(acf)
Register a custom function.
Definition: pbx.h:1164
static int manager_mutestream(struct mansession *s, const struct message *m)
static int manager_mutestream ( struct mansession s,
const struct message m 
)
static

Definition at line 253 of file res_mutestream.c.

References ast_channel_datastore_find(), ast_channel_get_by_name(), ast_channel_lock, ast_channel_unlock, ast_channel_unref, ast_datastore_free(), ast_free, ast_strlen_zero(), ast_true(), astman_append(), astman_get_header(), astman_send_error(), ast_datastore::data, initialize_mutehook(), mute, mute_add_audiohook(), mute_information::mute_read, mute_information::mute_write, and TRUE.

Referenced by load_module().

254 {
255  const char *channel = astman_get_header(m, "Channel");
256  const char *id = astman_get_header(m,"ActionID");
257  const char *state = astman_get_header(m,"State");
258  const char *direction = astman_get_header(m,"Direction");
259  char id_text[256] = "";
260  struct ast_channel *c = NULL;
261  struct ast_datastore *datastore = NULL;
262  struct mute_information *mute = NULL;
263  int is_new = 0;
264  int turnon = TRUE;
265 
266  if (ast_strlen_zero(channel)) {
267  astman_send_error(s, m, "Channel not specified");
268  return 0;
269  }
270  if (ast_strlen_zero(state)) {
271  astman_send_error(s, m, "State not specified");
272  return 0;
273  }
274  if (ast_strlen_zero(direction)) {
275  astman_send_error(s, m, "Direction not specified");
276  return 0;
277  }
278  /* Ok, we have everything */
279  if (!ast_strlen_zero(id)) {
280  snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id);
281  }
282 
283  c = ast_channel_get_by_name(channel);
284  if (!c) {
285  astman_send_error(s, m, "No such channel");
286  return 0;
287  }
288 
289  ast_channel_lock(c);
290 
291  if (!(datastore = ast_channel_datastore_find(c, &mute_datastore, NULL))) {
292  if (!(datastore = initialize_mutehook(c))) {
295  return 0;
296  }
297  is_new = 1;
298  }
299  mute = datastore->data;
300  turnon = ast_true(state);
301 
302  if (!strcasecmp(direction, "in")) {
303  mute->mute_read = turnon;
304  } else if (!strcasecmp(direction, "out")) {
305  mute->mute_write = turnon;
306  } else if (!strcasecmp(direction, "all")) {
307  mute->mute_read = mute->mute_write = turnon;
308  }
309 
310  if (is_new) {
311  if (mute_add_audiohook(c, mute, datastore)) {
312  /* Can't add audiohook - already printed error message */
313  ast_datastore_free(datastore);
314  ast_free(mute);
315  }
316  }
319 
320  astman_append(s, "Response: Success\r\n"
321  "%s"
322  "\r\n\r\n", id_text);
323  return 0;
324 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
Main Channel structure associated with a channel.
Definition: channel.h:742
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:2068
static struct ast_datastore * initialize_mutehook(struct ast_channel *chan)
Initialize mute hook on channel, but don't activate it.
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2502
Structure for a data store object.
Definition: datastore.h:54
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
Definition: channel.c:2604
#define TRUE
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:65
static int mute
Definition: chan_alsa.c:135
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static int mute_add_audiohook(struct ast_channel *chan, struct mute_information *mute, struct ast_datastore *datastore)
Add or activate mute audiohook on channel Assumes channel is locked.
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:1533
static struct ast_datastore_info mute_datastore
Static structure for datastore information.
#define ast_channel_unlock(chan)
Definition: channel.h:2467
#define ast_free(a)
Definition: astmm.h:97
void * data
Definition: datastore.h:56
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1803
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:2130
static int mute_add_audiohook ( struct ast_channel chan,
struct mute_information mute,
struct ast_datastore datastore 
)
static

Add or activate mute audiohook on channel Assumes channel is locked.

Definition at line 189 of file res_mutestream.c.

References ast_audiohook_attach(), ast_channel_datastore_add(), ast_debug, ast_log(), ast_module_ref(), mute_information::audiohook, LOG_ERROR, ast_channel::name, and ast_module_info::self.

Referenced by func_mute_write(), and manager_mutestream().

190 {
191  /* Activate the settings */
192  ast_channel_datastore_add(chan, datastore);
193  if (ast_audiohook_attach(chan, &mute->audiohook)) {
194  ast_log(LOG_ERROR, "Failed to attach audiohook for muting channel %s\n", chan->name);
195  return -1;
196  }
198  ast_debug(2, "Initialized audiohook on channel %s\n", chan->name);
199  return 0;
200 }
struct ast_audiohook audiohook
int ast_audiohook_attach(struct ast_channel *chan, struct ast_audiohook *audiohook)
Attach audiohook to channel.
Definition: audiohook.c:348
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
struct ast_module * self
Definition: module.h:227
#define LOG_ERROR
Definition: logger.h:155
const ast_string_field name
Definition: channel.h:787
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2590
struct ast_module * ast_module_ref(struct ast_module *)
Definition: loader.c:1300
static int mute_callback ( struct ast_audiohook audiohook,
struct ast_channel chan,
struct ast_frame frame,
enum ast_audiohook_direction  direction 
)
static

The callback from the audiohook subsystem. We basically get a frame to have fun with.

Definition at line 124 of file res_mutestream.c.

References AST_AUDIOHOOK_DIRECTION_READ, AST_AUDIOHOOK_DIRECTION_WRITE, AST_AUDIOHOOK_STATUS_DONE, ast_channel_datastore_find(), ast_channel_lock, ast_channel_unlock, ast_debug, ast_frame_clear(), AST_FRAME_VOICE, ast_datastore::data, ast_frame::frametype, mute, mute_information::mute_read, mute_information::mute_write, and ast_audiohook::status.

Referenced by initialize_mutehook().

125 {
126  struct ast_datastore *datastore = NULL;
127  struct mute_information *mute = NULL;
128 
129 
130  /* If the audiohook is stopping it means the channel is shutting down.... but we let the datastore destroy take care of it */
131  if (audiohook->status == AST_AUDIOHOOK_STATUS_DONE) {
132  return 0;
133  }
134 
135  ast_channel_lock(chan);
136  /* Grab datastore which contains our mute information */
137  if (!(datastore = ast_channel_datastore_find(chan, &mute_datastore, NULL))) {
138  ast_channel_unlock(chan);
139  ast_debug(2, "Can't find any datastore to use. Bad. \n");
140  return 0;
141  }
142 
143  mute = datastore->data;
144 
145 
146  /* If this is audio then allow them to increase/decrease the gains */
147  if (frame->frametype == AST_FRAME_VOICE) {
148  ast_debug(2, "Audio frame - direction %s mute READ %s WRITE %s\n", direction == AST_AUDIOHOOK_DIRECTION_READ ? "read" : "write", mute->mute_read ? "on" : "off", mute->mute_write ? "on" : "off");
149 
150  /* Based on direction of frame grab the gain, and confirm it is applicable */
151  if ((direction == AST_AUDIOHOOK_DIRECTION_READ && mute->mute_read) || (direction == AST_AUDIOHOOK_DIRECTION_WRITE && mute->mute_write)) {
152  /* Ok, we just want to reset all audio in this frame. Keep NOTHING, thanks. */
153  ast_frame_clear(frame);
154  }
155  }
156  ast_channel_unlock(chan);
157 
158  return 0;
159 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
int ast_frame_clear(struct ast_frame *frame)
Clear all audio samples from an ast_frame. The frame must be AST_FRAME_VOICE and AST_FORMAT_SLINEAR.
Definition: frame.c:1629
Structure for a data store object.
Definition: datastore.h:54
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
Definition: channel.c:2604
static int mute
Definition: chan_alsa.c:135
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static struct ast_datastore_info mute_datastore
Static structure for datastore information.
#define ast_channel_unlock(chan)
Definition: channel.h:2467
void * data
Definition: datastore.h:56
enum ast_audiohook_status status
Definition: audiohook.h:107
enum ast_frame_type frametype
Definition: frame.h:144
static int unload_module ( void  )
static

Definition at line 347 of file res_mutestream.c.

References ast_custom_function_unregister(), and ast_manager_unregister().

348 {
350  /* Unregister AMI actions */
351  ast_manager_unregister("MuteAudio");
352 
353  return 0;
354 }
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
Definition: pbx.c:3814
static struct ast_custom_function mute_function
int ast_manager_unregister(char *action)
Unregister a registered manager command.
Definition: manager.c:5355

Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Mute audio stream resources" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, }
static

Definition at line 356 of file res_mutestream.c.

Definition at line 356 of file res_mutestream.c.

const char mandescr_mutestream[]
static

Definition at line 327 of file res_mutestream.c.

struct ast_datastore_info mute_datastore
static
Initial value:
= {
.type = "mute",
.destroy = destroy_callback
}
static void destroy_callback(void *data)

Static structure for datastore information.

Definition at line 118 of file res_mutestream.c.

struct ast_custom_function mute_function
static
Initial value:
= {
.name = "MUTEAUDIO",
.write = func_mute_write,
}
static int func_mute_write(struct ast_channel *chan, const char *cmd, char *data, const char *value)
Mute dialplan function.

Definition at line 248 of file res_mutestream.c.