Fri Jun 19 12:09:59 2009

Asterisk developer's documentation


app_mixmonitor.c File Reference

MixMonitor() - Record a call and mix the audio during the recording. More...

#include "asterisk.h"
#include "asterisk/paths.h"
#include "asterisk/file.h"
#include "asterisk/audiohook.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/cli.h"
#include "asterisk/app.h"
#include "asterisk/channel.h"

Go to the source code of this file.

Data Structures

struct  mixmonitor
struct  mixmonitor_ds

Defines

#define get_volfactor(x)   x ? ((x > 0) ? (1 << x) : ((1 << abs(x)) * -1)) : 0
#define SAMPLES_PER_FRAME   160

Enumerations

enum  {
  MUXFLAG_APPEND = (1 << 1), MUXFLAG_BRIDGED = (1 << 2), MUXFLAG_VOLUME = (1 << 3), MUXFLAG_READVOLUME = (1 << 4),
  MUXFLAG_WRITEVOLUME = (1 << 5)
}
enum  { OPT_ARG_READVOLUME = 0, OPT_ARG_WRITEVOLUME, OPT_ARG_VOLUME, OPT_ARG_ARRAY_SIZE }

Functions

static void __reg_module (void)
static void __unreg_module (void)
static char * handle_cli_mixmonitor (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
static void launch_monitor_thread (struct ast_channel *chan, const char *filename, unsigned int flags, int readvol, int writevol, const char *post_process)
static int load_module (void)
static void mixmonitor_ds_chan_fixup (void *data, struct ast_channel *old_chan, struct ast_channel *new_chan)
static void mixmonitor_ds_destroy (void *data)
static int mixmonitor_exec (struct ast_channel *chan, void *data)
static void * mixmonitor_thread (void *obj)
static int setup_mixmonitor_ds (struct mixmonitor *mixmonitor, struct ast_channel *chan)
static int startmon (struct ast_channel *chan, struct ast_audiohook *audiohook)
static int stop_mixmonitor_exec (struct ast_channel *chan, void *data)
static int unload_module (void)

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Mixed Audio Monitoring Application" , .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 = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, }
static const char * app = "MixMonitor"
static struct ast_module_infoast_module_info = &__mod_info
static struct ast_cli_entry cli_mixmonitor []
static const char * desc
module_symbols * me
enum { ... }  mixmonitor_args
static struct ast_datastore_info mixmonitor_ds_info
enum { ... }  mixmonitor_flags
static struct ast_app_option mixmonitor_opts [128] = { [ 'a' ] = { .flag = MUXFLAG_APPEND }, [ 'b' ] = { .flag = MUXFLAG_BRIDGED }, [ 'v' ] = { .flag = MUXFLAG_READVOLUME , .arg_index = OPT_ARG_READVOLUME + 1 }, [ 'V' ] = { .flag = MUXFLAG_WRITEVOLUME , .arg_index = OPT_ARG_WRITEVOLUME + 1 }, [ 'W' ] = { .flag = MUXFLAG_VOLUME , .arg_index = OPT_ARG_VOLUME + 1 },}
static const char * mixmonitor_spy_type = "MixMonitor"
static const char * stop_app = "StopMixMonitor"
static const char * stop_desc
static const char * stop_synopsis = "Stop recording a call through MixMonitor"
static const char * synopsis = "Record a call and mix the audio during the recording"


Detailed Description

MixMonitor() - Record a call and mix the audio during the recording.

Author:
Mark Spencer <markster@digium.com>

Kevin P. Fleming <kpfleming@digium.com>

Note:
Based on app_muxmon.c provided by Anthony Minessale II <anthmct@yahoo.com>

Definition in file app_mixmonitor.c.


Define Documentation

#define get_volfactor (  )     x ? ((x > 0) ? (1 << x) : ((1 << abs(x)) * -1)) : 0

Definition at line 49 of file app_mixmonitor.c.

Referenced by mixmonitor_exec().

#define SAMPLES_PER_FRAME   160

Definition at line 178 of file app_mixmonitor.c.

Referenced by mixmonitor_thread().


Enumeration Type Documentation

anonymous enum

Enumerator:
MUXFLAG_APPEND 
MUXFLAG_BRIDGED 
MUXFLAG_VOLUME 
MUXFLAG_READVOLUME 
MUXFLAG_WRITEVOLUME 

Definition at line 95 of file app_mixmonitor.c.

00095      {
00096    MUXFLAG_APPEND = (1 << 1),
00097    MUXFLAG_BRIDGED = (1 << 2),
00098    MUXFLAG_VOLUME = (1 << 3),
00099    MUXFLAG_READVOLUME = (1 << 4),
00100    MUXFLAG_WRITEVOLUME = (1 << 5),
00101 } mixmonitor_flags;

anonymous enum

Enumerator:
OPT_ARG_READVOLUME 
OPT_ARG_WRITEVOLUME 
OPT_ARG_VOLUME 
OPT_ARG_ARRAY_SIZE 

Definition at line 103 of file app_mixmonitor.c.


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 509 of file app_mixmonitor.c.

static void __unreg_module ( void   )  [static]

Definition at line 509 of file app_mixmonitor.c.

static char* handle_cli_mixmonitor ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
) [static]

Definition at line 447 of file app_mixmonitor.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_audiohook_detach_source(), ast_channel_unlock, ast_cli(), ast_complete_channels(), ast_get_channel_by_name_prefix_locked(), chan, CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, ast_cli_args::line, mixmonitor_exec(), ast_cli_args::n, ast_cli_args::pos, ast_cli_entry::usage, and ast_cli_args::word.

00448 {
00449    struct ast_channel *chan;
00450 
00451    switch (cmd) {
00452    case CLI_INIT:
00453       e->command = "mixmonitor [start|stop]";
00454       e->usage =
00455          "Usage: mixmonitor <start|stop> <chan_name> [args]\n"
00456          "       The optional arguments are passed to the MixMonitor\n"
00457          "       application when the 'start' command is used.\n";
00458       return NULL;
00459    case CLI_GENERATE:
00460       return ast_complete_channels(a->line, a->word, a->pos, a->n, 2);
00461    }
00462 
00463    if (a->argc < 3)
00464       return CLI_SHOWUSAGE;
00465 
00466    if (!(chan = ast_get_channel_by_name_prefix_locked(a->argv[2], strlen(a->argv[2])))) {
00467       ast_cli(a->fd, "No channel matching '%s' found.\n", a->argv[2]);
00468       /* Technically this is a failure, but we don't want 2 errors printing out */
00469       return CLI_SUCCESS;
00470    }
00471 
00472    if (!strcasecmp(a->argv[1], "start")) {
00473       mixmonitor_exec(chan, a->argv[3]);
00474       ast_channel_unlock(chan);
00475    } else {
00476       ast_channel_unlock(chan);
00477       ast_audiohook_detach_source(chan, mixmonitor_spy_type);
00478    }
00479 
00480    return CLI_SUCCESS;
00481 }

static void launch_monitor_thread ( struct ast_channel chan,
const char *  filename,
unsigned int  flags,
int  readvol,
int  writevol,
const char *  post_process 
) [static]

Definition at line 290 of file app_mixmonitor.c.

References ast_audiohook_destroy(), ast_audiohook_init(), AST_AUDIOHOOK_TRIGGER_SYNC, AST_AUDIOHOOK_TYPE_SPY, ast_calloc, ast_free, ast_log(), ast_pthread_create_detached_background, ast_set_flag, ast_strdupa, ast_strlen_zero(), chan, mixmonitor::flags, len(), LOG_WARNING, mixmonitor_thread(), mixmonitor::name, ast_channel::name, pbx_substitute_variables_helper(), setup_mixmonitor_ds(), startmon(), and thread.

Referenced by mixmonitor_exec().

00292 {
00293    pthread_t thread;
00294    struct mixmonitor *mixmonitor;
00295    char postprocess2[1024] = "";
00296    size_t len;
00297 
00298    len = sizeof(*mixmonitor) + strlen(chan->name) + strlen(filename) + 2;
00299 
00300    postprocess2[0] = 0;
00301    /* If a post process system command is given attach it to the structure */
00302    if (!ast_strlen_zero(post_process)) {
00303       char *p1, *p2;
00304 
00305       p1 = ast_strdupa(post_process);
00306       for (p2 = p1; *p2 ; p2++) {
00307          if (*p2 == '^' && *(p2+1) == '{') {
00308             *p2 = '$';
00309          }
00310       }
00311       pbx_substitute_variables_helper(chan, p1, postprocess2, sizeof(postprocess2) - 1);
00312       if (!ast_strlen_zero(postprocess2))
00313          len += strlen(postprocess2) + 1;
00314    }
00315 
00316    /* Pre-allocate mixmonitor structure and spy */
00317    if (!(mixmonitor = ast_calloc(1, len))) {
00318       return;
00319    }
00320 
00321    /* Copy over flags and channel name */
00322    mixmonitor->flags = flags;
00323    if (setup_mixmonitor_ds(mixmonitor, chan)) {
00324       return;
00325    }
00326    mixmonitor->name = (char *) mixmonitor + sizeof(*mixmonitor);
00327    strcpy(mixmonitor->name, chan->name);
00328    if (!ast_strlen_zero(postprocess2)) {
00329       mixmonitor->post_process = mixmonitor->name + strlen(mixmonitor->name) + strlen(filename) + 2;
00330       strcpy(mixmonitor->post_process, postprocess2);
00331    }
00332 
00333    mixmonitor->filename = (char *) mixmonitor + sizeof(*mixmonitor) + strlen(chan->name) + 1;
00334    strcpy(mixmonitor->filename, filename);
00335 
00336    /* Setup the actual spy before creating our thread */
00337    if (ast_audiohook_init(&mixmonitor->audiohook, AST_AUDIOHOOK_TYPE_SPY, mixmonitor_spy_type)) {
00338       ast_free(mixmonitor);
00339       return;
00340    }
00341 
00342    ast_set_flag(&mixmonitor->audiohook, AST_AUDIOHOOK_TRIGGER_SYNC);
00343 
00344    if (readvol)
00345       mixmonitor->audiohook.options.read_volume = readvol;
00346    if (writevol)
00347       mixmonitor->audiohook.options.write_volume = writevol;
00348 
00349    if (startmon(chan, &mixmonitor->audiohook)) {
00350       ast_log(LOG_WARNING, "Unable to add '%s' spy to channel '%s'\n",
00351          mixmonitor_spy_type, chan->name);
00352       ast_audiohook_destroy(&mixmonitor->audiohook);
00353       ast_free(mixmonitor);
00354       return;
00355    }
00356 
00357    ast_pthread_create_detached_background(&thread, NULL, mixmonitor_thread, mixmonitor);
00358 }

static int load_module ( void   )  [static]

Definition at line 498 of file app_mixmonitor.c.

References ast_cli_register_multiple(), ast_register_application, cli_mixmonitor, mixmonitor_exec(), and stop_mixmonitor_exec().

00499 {
00500    int res;
00501 
00502    ast_cli_register_multiple(cli_mixmonitor, sizeof(cli_mixmonitor) / sizeof(struct ast_cli_entry));
00503    res = ast_register_application(app, mixmonitor_exec, synopsis, desc);
00504    res |= ast_register_application(stop_app, stop_mixmonitor_exec, stop_synopsis, stop_desc);
00505 
00506    return res;
00507 }

static void mixmonitor_ds_chan_fixup ( void *  data,
struct ast_channel old_chan,
struct ast_channel new_chan 
) [static]

Definition at line 147 of file app_mixmonitor.c.

References ast_mutex_lock(), ast_mutex_unlock(), mixmonitor_ds::chan, and mixmonitor_ds::lock.

00148 {
00149    struct mixmonitor_ds *mixmonitor_ds = data;
00150 
00151    ast_mutex_lock(&mixmonitor_ds->lock);
00152    mixmonitor_ds->chan = new_chan;
00153    ast_mutex_unlock(&mixmonitor_ds->lock);
00154 }

static void mixmonitor_ds_destroy ( void *  data  )  [static]

Definition at line 136 of file app_mixmonitor.c.

References ast_cond_signal(), ast_mutex_lock(), ast_mutex_unlock(), mixmonitor_ds::chan, mixmonitor_ds::destruction_condition, mixmonitor_ds::destruction_ok, and mixmonitor_ds::lock.

00137 {
00138    struct mixmonitor_ds *mixmonitor_ds = data;
00139 
00140    ast_mutex_lock(&mixmonitor_ds->lock);
00141    mixmonitor_ds->chan = NULL;
00142    mixmonitor_ds->destruction_ok = 1;
00143    ast_cond_signal(&mixmonitor_ds->destruction_condition);
00144    ast_mutex_unlock(&mixmonitor_ds->lock);
00145 }

static int mixmonitor_exec ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 360 of file app_mixmonitor.c.

References AST_APP_ARG, ast_app_parse_options(), ast_config_AST_MONITOR_DIR, AST_DECLARE_APP_ARGS, ast_log(), ast_mkdir(), AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ast_test_flag, chan, ast_flags::flags, get_volfactor, launch_monitor_thread(), LOG_NOTICE, LOG_WARNING, mixmonitor_opts, MUXFLAG_READVOLUME, MUXFLAG_VOLUME, MUXFLAG_WRITEVOLUME, OPT_ARG_ARRAY_SIZE, OPT_ARG_READVOLUME, OPT_ARG_VOLUME, OPT_ARG_WRITEVOLUME, parse(), and pbx_builtin_setvar_helper().

Referenced by handle_cli_mixmonitor(), and load_module().

00361 {
00362    int x, readvol = 0, writevol = 0;
00363    struct ast_flags flags = {0};
00364    char *parse, *tmp, *slash;
00365    AST_DECLARE_APP_ARGS(args,
00366       AST_APP_ARG(filename);
00367       AST_APP_ARG(options);
00368       AST_APP_ARG(post_process);
00369    );
00370    
00371    if (ast_strlen_zero(data)) {
00372       ast_log(LOG_WARNING, "MixMonitor requires an argument (filename)\n");
00373       return -1;
00374    }
00375 
00376    parse = ast_strdupa(data);
00377 
00378    AST_STANDARD_APP_ARGS(args, parse);
00379    
00380    if (ast_strlen_zero(args.filename)) {
00381       ast_log(LOG_WARNING, "MixMonitor requires an argument (filename)\n");
00382       return -1;
00383    }
00384 
00385    if (args.options) {
00386       char *opts[OPT_ARG_ARRAY_SIZE] = { NULL, };
00387 
00388       ast_app_parse_options(mixmonitor_opts, &flags, opts, args.options);
00389 
00390       if (ast_test_flag(&flags, MUXFLAG_READVOLUME)) {
00391          if (ast_strlen_zero(opts[OPT_ARG_READVOLUME])) {
00392             ast_log(LOG_WARNING, "No volume level was provided for the heard volume ('v') option.\n");
00393          } else if ((sscanf(opts[OPT_ARG_READVOLUME], "%d", &x) != 1) || (x < -4) || (x > 4)) {
00394             ast_log(LOG_NOTICE, "Heard volume must be a number between -4 and 4, not '%s'\n", opts[OPT_ARG_READVOLUME]);
00395          } else {
00396             readvol = get_volfactor(x);
00397          }
00398       }
00399       
00400       if (ast_test_flag(&flags, MUXFLAG_WRITEVOLUME)) {
00401          if (ast_strlen_zero(opts[OPT_ARG_WRITEVOLUME])) {
00402             ast_log(LOG_WARNING, "No volume level was provided for the spoken volume ('V') option.\n");
00403          } else if ((sscanf(opts[OPT_ARG_WRITEVOLUME], "%d", &x) != 1) || (x < -4) || (x > 4)) {
00404             ast_log(LOG_NOTICE, "Spoken volume must be a number between -4 and 4, not '%s'\n", opts[OPT_ARG_WRITEVOLUME]);
00405          } else {
00406             writevol = get_volfactor(x);
00407          }
00408       }
00409       
00410       if (ast_test_flag(&flags, MUXFLAG_VOLUME)) {
00411          if (ast_strlen_zero(opts[OPT_ARG_VOLUME])) {
00412             ast_log(LOG_WARNING, "No volume level was provided for the combined volume ('W') option.\n");
00413          } else if ((sscanf(opts[OPT_ARG_VOLUME], "%d", &x) != 1) || (x < -4) || (x > 4)) {
00414             ast_log(LOG_NOTICE, "Combined volume must be a number between -4 and 4, not '%s'\n", opts[OPT_ARG_VOLUME]);
00415          } else {
00416             readvol = writevol = get_volfactor(x);
00417          }
00418       }
00419    }
00420 
00421    /* if not provided an absolute path, use the system-configured monitoring directory */
00422    if (args.filename[0] != '/') {
00423       char *build;
00424 
00425       build = alloca(strlen(ast_config_AST_MONITOR_DIR) + strlen(args.filename) + 3);
00426       sprintf(build, "%s/%s", ast_config_AST_MONITOR_DIR, args.filename);
00427       args.filename = build;
00428    }
00429 
00430    tmp = ast_strdupa(args.filename);
00431    if ((slash = strrchr(tmp, '/')))
00432       *slash = '\0';
00433    ast_mkdir(tmp, 0777);
00434 
00435    pbx_builtin_setvar_helper(chan, "MIXMONITOR_FILENAME", args.filename);
00436    launch_monitor_thread(chan, args.filename, flags.flags, readvol, writevol, args.post_process);
00437 
00438    return 0;
00439 }

static void* mixmonitor_thread ( void *  obj  )  [static]

Definition at line 180 of file app_mixmonitor.c.

References ast_audiohook_destroy(), ast_audiohook_detach(), AST_AUDIOHOOK_DIRECTION_BOTH, ast_audiohook_lock, ast_audiohook_read_frame(), AST_AUDIOHOOK_STATUS_RUNNING, ast_audiohook_trigger_wait(), ast_audiohook_unlock, ast_bridged_channel(), ast_closestream(), ast_cond_destroy(), ast_cond_wait(), AST_FORMAT_SLINEAR, ast_frame_free(), ast_free, ast_log(), ast_mutex_destroy(), ast_mutex_lock(), ast_mutex_unlock(), ast_safe_system(), ast_test_flag, ast_verb, ast_writefile(), ast_writestream(), mixmonitor::audiohook, mixmonitor_ds::chan, mixmonitor_ds::destruction_condition, mixmonitor_ds::destruction_ok, ext, mixmonitor::filename, mixmonitor_ds::lock, LOG_ERROR, mixmonitor::mixmonitor_ds, MUXFLAG_APPEND, MUXFLAG_BRIDGED, mixmonitor::name, mixmonitor::post_process, SAMPLES_PER_FRAME, and ast_audiohook::status.

Referenced by launch_monitor_thread().

00181 {
00182    struct mixmonitor *mixmonitor = obj;
00183    struct ast_filestream *fs = NULL;
00184    unsigned int oflags;
00185    char *ext;
00186    int errflag = 0;
00187 
00188    ast_verb(2, "Begin MixMonitor Recording %s\n", mixmonitor->name);
00189    
00190    ast_audiohook_lock(&mixmonitor->audiohook);
00191 
00192    while (mixmonitor->audiohook.status == AST_AUDIOHOOK_STATUS_RUNNING) {
00193       struct ast_frame *fr = NULL;
00194 
00195       ast_audiohook_trigger_wait(&mixmonitor->audiohook);
00196 
00197       if (mixmonitor->audiohook.status != AST_AUDIOHOOK_STATUS_RUNNING)
00198          break;
00199 
00200       if (!(fr = ast_audiohook_read_frame(&mixmonitor->audiohook, SAMPLES_PER_FRAME, AST_AUDIOHOOK_DIRECTION_BOTH, AST_FORMAT_SLINEAR)))
00201          continue;
00202 
00203       ast_mutex_lock(&mixmonitor->mixmonitor_ds->lock);
00204       if (!ast_test_flag(mixmonitor, MUXFLAG_BRIDGED) || (mixmonitor->mixmonitor_ds->chan && ast_bridged_channel(mixmonitor->mixmonitor_ds->chan))) {
00205          ast_mutex_unlock(&mixmonitor->mixmonitor_ds->lock);
00206          /* Initialize the file if not already done so */
00207          if (!fs && !errflag) {
00208             oflags = O_CREAT | O_WRONLY;
00209             oflags |= ast_test_flag(mixmonitor, MUXFLAG_APPEND) ? O_APPEND : O_TRUNC;
00210             
00211             if ((ext = strrchr(mixmonitor->filename, '.')))
00212                *(ext++) = '\0';
00213             else
00214                ext = "raw";
00215             
00216             if (!(fs = ast_writefile(mixmonitor->filename, ext, NULL, oflags, 0, 0666))) {
00217                ast_log(LOG_ERROR, "Cannot open %s.%s\n", mixmonitor->filename, ext);
00218                errflag = 1;
00219             }
00220          }
00221          
00222          /* Write out frame */
00223          if (fs)
00224             ast_writestream(fs, fr);
00225       } else {
00226          ast_mutex_unlock(&mixmonitor->mixmonitor_ds->lock);
00227       }
00228 
00229       /* All done! free it. */
00230       ast_frame_free(fr, 0);
00231 
00232    }
00233 
00234    ast_audiohook_detach(&mixmonitor->audiohook);
00235    ast_audiohook_unlock(&mixmonitor->audiohook);
00236    ast_audiohook_destroy(&mixmonitor->audiohook);
00237 
00238    ast_verb(2, "End MixMonitor Recording %s\n", mixmonitor->name);
00239 
00240    if (fs)
00241       ast_closestream(fs);
00242 
00243    if (mixmonitor->post_process) {
00244       ast_verb(2, "Executing [%s]\n", mixmonitor->post_process);
00245       ast_safe_system(mixmonitor->post_process);
00246    }
00247 
00248    ast_mutex_lock(&mixmonitor->mixmonitor_ds->lock);
00249    if (!mixmonitor->mixmonitor_ds->destruction_ok) {
00250       ast_cond_wait(&mixmonitor->mixmonitor_ds->destruction_condition, &mixmonitor->mixmonitor_ds->lock);
00251    }
00252    ast_mutex_unlock(&mixmonitor->mixmonitor_ds->lock);
00253    ast_mutex_destroy(&mixmonitor->mixmonitor_ds->lock);
00254    ast_cond_destroy(&mixmonitor->mixmonitor_ds->destruction_condition);
00255    ast_free(mixmonitor->mixmonitor_ds);
00256    ast_free(mixmonitor);
00257 
00258    return NULL;
00259 }

static int setup_mixmonitor_ds ( struct mixmonitor mixmonitor,
struct ast_channel chan 
) [static]

Definition at line 261 of file app_mixmonitor.c.

References ast_calloc, ast_channel_datastore_add(), ast_channel_lock, ast_channel_unlock, ast_cond_init(), ast_datastore_alloc(), ast_free, ast_mutex_init(), chan, ast_datastore::data, mixmonitor::mixmonitor_ds, and mixmonitor_ds_info.

Referenced by launch_monitor_thread().

00262 {
00263    struct ast_datastore *datastore = NULL;
00264    struct mixmonitor_ds *mixmonitor_ds;
00265 
00266    if (!(mixmonitor_ds = ast_calloc(1, sizeof(*mixmonitor_ds)))) {
00267       return -1;
00268    }
00269    
00270    ast_mutex_init(&mixmonitor_ds->lock);
00271    ast_cond_init(&mixmonitor_ds->destruction_condition, NULL);
00272 
00273    if (!(datastore = ast_datastore_alloc(&mixmonitor_ds_info, NULL))) {
00274       ast_free(mixmonitor_ds);
00275       return -1;
00276    }
00277 
00278    /* No need to lock mixmonitor_ds since this is still operating in the channel's thread */
00279    mixmonitor_ds->chan = chan;
00280    datastore->data = mixmonitor_ds;
00281 
00282    ast_channel_lock(chan);
00283    ast_channel_datastore_add(chan, datastore);
00284    ast_channel_unlock(chan);
00285 
00286    mixmonitor->mixmonitor_ds = mixmonitor_ds;
00287    return 0;
00288 }

static int startmon ( struct ast_channel chan,
struct ast_audiohook audiohook 
) [static]

Definition at line 162 of file app_mixmonitor.c.

References ast_audiohook_attach(), ast_bridged_channel(), AST_FLAG_NBRIDGE, ast_softhangup(), AST_SOFTHANGUP_UNBRIDGE, ast_test_flag, and chan.

Referenced by launch_monitor_thread().

00163 {
00164    struct ast_channel *peer = NULL;
00165    int res = 0;
00166 
00167    if (!chan)
00168       return -1;
00169 
00170    ast_audiohook_attach(chan, audiohook);
00171 
00172    if (!res && ast_test_flag(chan, AST_FLAG_NBRIDGE) && (peer = ast_bridged_channel(chan)))
00173       ast_softhangup(peer, AST_SOFTHANGUP_UNBRIDGE);  
00174 
00175    return res;
00176 }

static int stop_mixmonitor_exec ( struct ast_channel chan,
void *  data 
) [static]

Definition at line 441 of file app_mixmonitor.c.

References ast_audiohook_detach_source(), and chan.

Referenced by load_module().

00442 {
00443    ast_audiohook_detach_source(chan, mixmonitor_spy_type);
00444    return 0;
00445 }

static int unload_module ( void   )  [static]

Definition at line 487 of file app_mixmonitor.c.

References ast_cli_unregister_multiple(), ast_unregister_application(), and cli_mixmonitor.

00488 {
00489    int res;
00490 
00491    ast_cli_unregister_multiple(cli_mixmonitor, sizeof(cli_mixmonitor) / sizeof(struct ast_cli_entry));
00492    res = ast_unregister_application(stop_app);
00493    res |= ast_unregister_application(app);
00494    
00495    return res;
00496 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_DEFAULT , .description = "Mixed Audio Monitoring Application" , .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 = "a9c98e5d177805051735cb5b0b16b0a0" , .load = load_module, .unload = unload_module, } [static]

Definition at line 509 of file app_mixmonitor.c.

const char* app = "MixMonitor" [static]

Definition at line 51 of file app_mixmonitor.c.

struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 509 of file app_mixmonitor.c.

struct ast_cli_entry cli_mixmonitor[] [static]

Initial value:

 {
   { .handler =  handle_cli_mixmonitor , .summary =  "Execute a MixMonitor command" ,__VA_ARGS__ }
}

Definition at line 483 of file app_mixmonitor.c.

Referenced by load_module(), and unload_module().

const char* desc [static]

Definition at line 53 of file app_mixmonitor.c.

struct module_symbols* me

Definition at line 82 of file app_mixmonitor.c.

Referenced by _sip_tcp_helper_thread(), handle_mgcp_audit_endpoint(), and handle_mgcp_show_endpoints().

enum { ... } mixmonitor_args

struct ast_datastore_info mixmonitor_ds_info [static]

Initial value:

 {
   .type = "mixmonitor",
   .destroy = mixmonitor_ds_destroy,
   .chan_fixup = mixmonitor_ds_chan_fixup,
}

Definition at line 156 of file app_mixmonitor.c.

Referenced by setup_mixmonitor_ds().

enum { ... } mixmonitor_flags

struct ast_app_option mixmonitor_opts[128] = { [ 'a' ] = { .flag = MUXFLAG_APPEND }, [ 'b' ] = { .flag = MUXFLAG_BRIDGED }, [ 'v' ] = { .flag = MUXFLAG_READVOLUME , .arg_index = OPT_ARG_READVOLUME + 1 }, [ 'V' ] = { .flag = MUXFLAG_WRITEVOLUME , .arg_index = OPT_ARG_WRITEVOLUME + 1 }, [ 'W' ] = { .flag = MUXFLAG_VOLUME , .arg_index = OPT_ARG_VOLUME + 1 },} [static]

Definition at line 116 of file app_mixmonitor.c.

Referenced by mixmonitor_exec().

const char* mixmonitor_spy_type = "MixMonitor" [static]

Definition at line 84 of file app_mixmonitor.c.

Referenced by builtin_automixmonitor().

const char* stop_app = "StopMixMonitor" [static]

Definition at line 74 of file app_mixmonitor.c.

const char* stop_desc [static]

Initial value:

 ""
"  StopMixMonitor():\n"
"Stops the audio recording that was started with a call to MixMonitor()\n"
"on the current channel.\n"
""

Definition at line 76 of file app_mixmonitor.c.

const char* stop_synopsis = "Stop recording a call through MixMonitor" [static]

Definition at line 75 of file app_mixmonitor.c.

const char* synopsis = "Record a call and mix the audio during the recording" [static]

Definition at line 52 of file app_mixmonitor.c.


Generated on Fri Jun 19 12:09:59 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7