Sat Apr 26 2014 22:03:11

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"
Include dependency graph for res_mutestream.c:

Go to the source code of this file.

Data Structures

struct  mute_information

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.
static struct ast_datastoreinitialize_mutehook (struct ast_channel *chan)
 Initialize mute hook on channel, but don't activate it.
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.
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.
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 = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, }
static struct ast_module_infoast_module_info = &__mod_info
static struct ast_datastore_info mute_datastore
 Static structure for datastore information.
static struct ast_custom_function mute_function

Detailed Description

MUTESTREAM audiohooks.

Author:
Olle E. Johansson <oej@edvina.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.


Function Documentation

static void __reg_module ( void  ) [static]

Definition at line 382 of file res_mutestream.c.

static void __unreg_module ( void  ) [static]

Definition at line 382 of file res_mutestream.c.

static void destroy_callback ( void *  data) [static]

Datastore destroy audiohook callback

Definition at line 135 of file res_mutestream.c.

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

{
   struct mute_information *mute = data;

   /* Destroy the audiohook, and destroy ourselves */
   ast_audiohook_destroy(&mute->audiohook);
   ast_free(mute);
   ast_module_unref(ast_module_info->self);
}
static int func_mute_write ( struct ast_channel chan,
const char *  cmd,
char *  data,
const char *  value 
) [static]

Mute dialplan function.

Definition at line 231 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.

{
   struct ast_datastore *datastore = NULL;
   struct mute_information *mute = NULL;
   int is_new = 0;
   int turnon;

   if (!chan) {
      ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
      return -1;
   }

   ast_channel_lock(chan);
   if (!(datastore = ast_channel_datastore_find(chan, &mute_datastore, NULL))) {
      if (!(datastore = initialize_mutehook(chan))) {
         ast_channel_unlock(chan);
         return 0;
      }
      is_new = 1;
   }
   mute = datastore->data;

   turnon = ast_true(value);
   if (!strcasecmp(data, "out")) {
      mute->mute_write = turnon;
      ast_debug(1, "%s channel - outbound \n", turnon ? "Muting" : "Unmuting");
   } else if (!strcasecmp(data, "in")) {
      mute->mute_read = turnon;
      ast_debug(1, "%s channel - inbound  \n", turnon ? "Muting" : "Unmuting");
   } else if (!strcasecmp(data,"all")) {
      mute->mute_write = mute->mute_read = turnon;
   }

   if (is_new) {
      if (mute_add_audiohook(chan, mute, datastore)) {
         /* Can't add audiohook - already printed error message */
         ast_datastore_free(datastore);
         ast_free(mute);
      }
   }
   ast_channel_unlock(chan);

   return 0;
}
static struct ast_datastore* initialize_mutehook ( struct ast_channel chan) [static, read]

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

Precondition:
Assumes that the channel is locked

Definition at line 192 of file res_mutestream.c.

References ast_audiohook_init(), AST_AUDIOHOOK_MANIPULATE_ALL_RATES, 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().

{
   struct ast_datastore *datastore = NULL;
   struct mute_information *mute = NULL;

   ast_debug(2, "Initializing new Mute Audiohook \n");

   /* Allocate a new datastore to hold the reference to this mute_datastore and audiohook information */
   if (!(datastore = ast_datastore_alloc(&mute_datastore, NULL))) {
      return NULL;
   }

   if (!(mute = ast_calloc(1, sizeof(*mute)))) {
      ast_datastore_free(datastore);
      return NULL;
   }
   ast_audiohook_init(&mute->audiohook, AST_AUDIOHOOK_TYPE_MANIPULATE, "Mute", AST_AUDIOHOOK_MANIPULATE_ALL_RATES);
   mute->audiohook.manipulate_callback = mute_callback;
   datastore->data = mute;
   return datastore;
}
static int manager_mutestream ( struct mansession s,
const struct message m 
) [static]

Definition at line 282 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, and mute_information::mute_write.

Referenced by load_module().

{
   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;
   struct ast_datastore *datastore = NULL;
   struct mute_information *mute = NULL;
   int is_new = 0;
   int turnon;

   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;
   }

   ast_channel_lock(c);

   if (!(datastore = ast_channel_datastore_find(c, &mute_datastore, NULL))) {
      if (!(datastore = initialize_mutehook(c))) {
         ast_channel_unlock(c);
         ast_channel_unref(c);
         astman_send_error(s, m, "Memory allocation failure");
         return 0;
      }
      is_new = 1;
   }
   mute = datastore->data;

   turnon = ast_true(state);
   if (!strcasecmp(direction, "in")) {
      mute->mute_read = turnon;
   } else if (!strcasecmp(direction, "out")) {
      mute->mute_write = turnon;
   } else if (!strcasecmp(direction, "all")) {
      mute->mute_read = mute->mute_write = turnon;
   }

   if (is_new) {
      if (mute_add_audiohook(c, mute, datastore)) {
         /* Can't add audiohook */
         ast_datastore_free(datastore);
         ast_free(mute);
         ast_channel_unlock(c);
         ast_channel_unref(c);
         astman_send_error(s, m, "Couldn't add mute audiohook");
         return 0;
      }
   }
   ast_channel_unlock(c);
   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 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 217 of file res_mutestream.c.

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

Referenced by func_mute_write(), and manager_mutestream().

{
   /* Activate the settings */
   ast_channel_datastore_add(chan, datastore);
   if (ast_audiohook_attach(chan, &mute->audiohook)) {
      ast_log(LOG_ERROR, "Failed to attach audiohook for muting channel %s\n", ast_channel_name(chan));
      return -1;
   }
   ast_module_ref(ast_module_info->self);
   ast_debug(2, "Initialized audiohook on channel %s\n", ast_channel_name(chan));
   return 0;
}
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 152 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().

{
   struct ast_datastore *datastore = NULL;
   struct mute_information *mute = NULL;


   /* If the audiohook is stopping it means the channel is shutting down.... but we let the datastore destroy take care of it */
   if (audiohook->status == AST_AUDIOHOOK_STATUS_DONE) {
      return 0;
   }

   ast_channel_lock(chan);
   /* Grab datastore which contains our mute information */
   if (!(datastore = ast_channel_datastore_find(chan, &mute_datastore, NULL))) {
      ast_channel_unlock(chan);
      ast_debug(2, "Can't find any datastore to use. Bad. \n");
      return 0;
   }

   mute = datastore->data;


   /* If this is audio then allow them to increase/decrease the gains */
   if (frame->frametype == AST_FRAME_VOICE) {
      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");

      /* Based on direction of frame grab the gain, and confirm it is applicable */
      if ((direction == AST_AUDIOHOOK_DIRECTION_READ && mute->mute_read) || (direction == AST_AUDIOHOOK_DIRECTION_WRITE && mute->mute_write)) {
         /* Ok, we just want to reset all audio in this frame. Keep NOTHING, thanks. */
         ast_frame_clear(frame);
      }
   }
   ast_channel_unlock(chan);

   return 0;
}
static int unload_module ( void  ) [static]

Definition at line 373 of file res_mutestream.c.

References ast_custom_function_unregister(), and ast_manager_unregister().

{
   ast_custom_function_unregister(&mute_function);
   /* Unregister AMI actions */
   ast_manager_unregister("MuteAudio");

   return 0;
}

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 = AST_BUILDOPT_SUM, .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, } [static]

Definition at line 382 of file res_mutestream.c.

Definition at line 382 of file res_mutestream.c.

Initial value:
 {
   .type = "mute",
   .destroy = destroy_callback
}

Static structure for datastore information.

Definition at line 146 of file res_mutestream.c.

Initial value:
 {
   .name = "MUTEAUDIO",
   .write = func_mute_write,
}

Definition at line 277 of file res_mutestream.c.