#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_info * | ast_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" |
Kevin P. Fleming <kpfleming@digium.com>
Definition in file app_mixmonitor.c.
#define get_volfactor | ( | x | ) | x ? ((x > 0) ? (1 << x) : ((1 << abs(x)) * -1)) : 0 |
#define SAMPLES_PER_FRAME 160 |
anonymous enum |
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 |
Definition at line 103 of file app_mixmonitor.c.
00103 { 00104 OPT_ARG_READVOLUME = 0, 00105 OPT_ARG_WRITEVOLUME, 00106 OPT_ARG_VOLUME, 00107 OPT_ARG_ARRAY_SIZE, 00108 } mixmonitor_args;
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 }
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] |
const char* mixmonitor_spy_type = "MixMonitor" [static] |
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.