Wed Apr 6 11:30:09 2011

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 = "8586c2a7d357cb591cc3a6607a8f62d1" , .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 98 of file res_mutestream.c.

#define TRUE   1

Definition at line 97 of file res_mutestream.c.


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 347 of file res_mutestream.c.

static void __unreg_module ( void   )  [static]

Definition at line 347 of file res_mutestream.c.

static void destroy_callback ( void *  data  )  [static]

Datastore destroy audiohook callback

Definition at line 101 of file res_mutestream.c.

References ast_audiohook_destroy(), ast_free, ast_module_unref(), and mute.

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

static int func_mute_write ( struct ast_channel chan,
const char *  cmd,
char *  data,
const char *  value 
) [static]

Mute dialplan function.

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

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

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 160 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().

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

static int load_module ( void   )  [static]

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

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

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

Definition at line 244 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().

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

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 185 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().

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

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 120 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().

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

static int unload_module ( void   )  [static]

Definition at line 338 of file res_mutestream.c.

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

00339 {
00340    ast_custom_function_unregister(&mute_function);
00341    /* Unregister AMI actions */
00342         ast_manager_unregister("MuteAudio");
00343 
00344    return 0;
00345 }


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

Definition at line 347 of file res_mutestream.c.

struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 347 of file res_mutestream.c.

const char mandescr_mutestream[] [static]

Definition at line 318 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 114 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 239 of file res_mutestream.c.

Referenced by load_module(), and unload_module().


Generated on Wed Apr 6 11:30:09 2011 for Asterisk - The Open Source Telephony Project by  doxygen 1.4.7