Mon Oct 8 12:39:28 2012

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

Defines

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


Define 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.


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 351 of file res_mutestream.c.

static void __unreg_module ( void   )  [static]

Definition at line 351 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(), and mute.

00106 {
00107    struct mute_information *mute = data;
00108 
00109    /* Destroy the audiohook, and destroy ourselves */
00110    ast_audiohook_destroy(&mute->audiohook);
00111    ast_free(mute);
00112    ast_module_unref(ast_module_info->self);
00113 
00114    return;
00115 }

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_true(), ast_datastore::data, initialize_mutehook(), mute, mute_add_audiohook(), and mute_datastore.

00204 {
00205    struct ast_datastore *datastore = NULL;
00206    struct mute_information *mute = NULL;
00207    int is_new = 0;
00208 
00209    ast_channel_lock(chan);
00210    if (!(datastore = ast_channel_datastore_find(chan, &mute_datastore, NULL))) {
00211       if (!(datastore = initialize_mutehook(chan))) {
00212          ast_channel_unlock(chan);
00213          return 0;
00214       }
00215       is_new = 1;
00216    }
00217 
00218    mute = datastore->data;
00219 
00220    if (!strcasecmp(data, "out")) {
00221       mute->mute_write = ast_true(value);
00222       ast_debug(1, "%s channel - outbound \n", ast_true(value) ? "Muting" : "Unmuting");
00223    } else if (!strcasecmp(data, "in")) {
00224       mute->mute_read = ast_true(value);
00225       ast_debug(1, "%s channel - inbound  \n", ast_true(value) ? "Muting" : "Unmuting");
00226    } else if (!strcasecmp(data,"all")) {
00227       mute->mute_write = mute->mute_read = ast_true(value);
00228    }
00229 
00230    if (is_new) {
00231       if (mute_add_audiohook(chan, mute, datastore)) {
00232          /* Can't add audiohook - already printed error message */
00233          ast_datastore_free(datastore);
00234          ast_free(mute);
00235       }
00236    }
00237    ast_channel_unlock(chan);
00238 
00239    return 0;
00240 }

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, ast_datastore::data, mute, mute_callback(), and mute_datastore.

Referenced by func_mute_write(), and manager_mutestream().

00165 {
00166    struct ast_datastore *datastore = NULL;
00167    struct mute_information *mute = NULL;
00168 
00169    ast_debug(2, "Initializing new Mute Audiohook \n");
00170 
00171    /* Allocate a new datastore to hold the reference to this mute_datastore and audiohook information */
00172    if (!(datastore = ast_datastore_alloc(&mute_datastore, NULL))) {
00173       return NULL;
00174    }
00175 
00176    if (!(mute = ast_calloc(1, sizeof(*mute)))) {
00177       ast_datastore_free(datastore);
00178       return NULL;
00179    }
00180    ast_audiohook_init(&mute->audiohook, AST_AUDIOHOOK_TYPE_MANIPULATE, "Mute");
00181    mute->audiohook.manipulate_callback = mute_callback;
00182    datastore->data = mute;
00183    return datastore;
00184 }

static int load_module ( void   )  [static]

Definition at line 331 of file res_mutestream.c.

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

00332 {
00333    int res;
00334    res = ast_custom_function_register(&mute_function);
00335 
00336    res |= ast_manager_register2("MuteAudio", EVENT_FLAG_SYSTEM, manager_mutestream,
00337                         "Mute an audio stream", mandescr_mutestream);
00338 
00339    return (res ? AST_MODULE_LOAD_DECLINE : AST_MODULE_LOAD_SUCCESS);
00340 }

static int manager_mutestream ( struct mansession s,
const struct message m 
) [static]

Definition at line 248 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_datastore, and TRUE.

Referenced by load_module().

00249 {
00250    const char *channel = astman_get_header(m, "Channel");
00251    const char *id = astman_get_header(m,"ActionID");
00252    const char *state = astman_get_header(m,"State");
00253    const char *direction = astman_get_header(m,"Direction");
00254    char id_text[256] = "";
00255    struct ast_channel *c = NULL;
00256    struct ast_datastore *datastore = NULL;
00257    struct mute_information *mute = NULL;
00258    int is_new = 0;
00259    int turnon = TRUE;
00260 
00261    if (ast_strlen_zero(channel)) {
00262       astman_send_error(s, m, "Channel not specified");
00263       return 0;
00264    }
00265    if (ast_strlen_zero(state)) {
00266       astman_send_error(s, m, "State not specified");
00267       return 0;
00268    }
00269    if (ast_strlen_zero(direction)) {
00270       astman_send_error(s, m, "Direction not specified");
00271       return 0;
00272    }
00273    /* Ok, we have everything */
00274    if (!ast_strlen_zero(id)) {
00275       snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id);
00276    }
00277 
00278    c = ast_channel_get_by_name(channel);
00279    if (!c) {
00280       astman_send_error(s, m, "No such channel");
00281       return 0;
00282    }
00283 
00284    ast_channel_lock(c);
00285 
00286    if (!(datastore = ast_channel_datastore_find(c, &mute_datastore, NULL))) {
00287       if (!(datastore = initialize_mutehook(c))) {
00288          ast_channel_unlock(c);
00289          ast_channel_unref(c);
00290          return 0;
00291       }
00292       is_new = 1;
00293    }
00294    mute = datastore->data;
00295    turnon = ast_true(state);
00296 
00297    if (!strcasecmp(direction, "in")) {
00298       mute->mute_read = turnon;
00299    } else if (!strcasecmp(direction, "out")) {
00300       mute->mute_write = turnon;
00301    } else if (!strcasecmp(direction, "all")) {
00302       mute->mute_read = mute->mute_write = turnon;
00303    }
00304 
00305    if (is_new) {
00306       if (mute_add_audiohook(c, mute, datastore)) {
00307          /* Can't add audiohook - already printed error message */
00308          ast_datastore_free(datastore);
00309          ast_free(mute);
00310       }
00311    }
00312    ast_channel_unlock(c);
00313    ast_channel_unref(c);
00314 
00315    astman_append(s, "Response: Success\r\n"
00316                "%s"
00317                "\r\n\r\n", id_text);
00318    return 0;
00319 }

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(), LOG_ERROR, mute, and ast_channel::name.

Referenced by func_mute_write(), and manager_mutestream().

00190 {
00191    /* Activate the settings */
00192    ast_channel_datastore_add(chan, datastore);
00193    if (ast_audiohook_attach(chan, &mute->audiohook)) {
00194       ast_log(LOG_ERROR, "Failed to attach audiohook for muting channel %s\n", chan->name);
00195       return -1;
00196    }
00197    ast_module_ref(ast_module_info->self);
00198    ast_debug(2, "Initialized audiohook on channel %s\n", chan->name);
00199    return 0;
00200 }

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, mute_information::audiohook, ast_datastore::data, ast_frame::frametype, mute, mute_datastore, and ast_audiohook::status.

Referenced by initialize_mutehook().

00125 {
00126    struct ast_datastore *datastore = NULL;
00127    struct mute_information *mute = NULL;
00128 
00129 
00130    /* If the audiohook is stopping it means the channel is shutting down.... but we let the datastore destroy take care of it */
00131    if (audiohook->status == AST_AUDIOHOOK_STATUS_DONE) {
00132       return 0;
00133    }
00134 
00135    ast_channel_lock(chan);
00136    /* Grab datastore which contains our mute information */
00137    if (!(datastore = ast_channel_datastore_find(chan, &mute_datastore, NULL))) {
00138       ast_channel_unlock(chan);
00139       ast_debug(2, "Can't find any datastore to use. Bad. \n");
00140       return 0;
00141    }
00142 
00143    mute = datastore->data;
00144 
00145 
00146    /* If this is audio then allow them to increase/decrease the gains */
00147    if (frame->frametype == AST_FRAME_VOICE) {
00148       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");
00149 
00150       /* Based on direction of frame grab the gain, and confirm it is applicable */
00151       if ((direction == AST_AUDIOHOOK_DIRECTION_READ && mute->mute_read) || (direction == AST_AUDIOHOOK_DIRECTION_WRITE && mute->mute_write)) {
00152          /* Ok, we just want to reset all audio in this frame. Keep NOTHING, thanks. */
00153          ast_frame_clear(frame);
00154       }
00155    }
00156    ast_channel_unlock(chan);
00157 
00158    return 0;
00159 }

static int unload_module ( void   )  [static]

Definition at line 342 of file res_mutestream.c.

References ast_custom_function_unregister(), ast_manager_unregister(), and mute_function.

00343 {
00344    ast_custom_function_unregister(&mute_function);
00345    /* Unregister AMI actions */
00346         ast_manager_unregister("MuteAudio");
00347 
00348    return 0;
00349 }


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 351 of file res_mutestream.c.

struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 351 of file res_mutestream.c.

const char mandescr_mutestream[] [static]

Definition at line 322 of file res_mutestream.c.

struct ast_datastore_info mute_datastore [static]

Initial value:

 {
   .type = "mute",
   .destroy = destroy_callback
}
Static structure for datastore information.

Definition at line 118 of file res_mutestream.c.

Referenced by func_mute_write(), initialize_mutehook(), manager_mutestream(), and mute_callback().

struct ast_custom_function mute_function [static]

Initial value:

 {
        .name = "MUTEAUDIO",
        .write = func_mute_write,
}

Definition at line 243 of file res_mutestream.c.

Referenced by load_module(), and unload_module().


Generated on Mon Oct 8 12:39:28 2012 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7