Wed Jan 8 2020 09:49:54

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"
#include "asterisk/autochan.h"
#include "asterisk/manager.h"
#include "asterisk/test.h"

Go to the source code of this file.

Data Structures

struct  mixmonitor
 
struct  mixmonitor_ds
 

Macros

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

Enumerations

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

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
static void destroy_monitor_audiohook (struct mixmonitor *mixmonitor)
 
static char * handle_cli_mixmonitor (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static int 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 int manager_mute_mixmonitor (struct mansession *s, const struct message *m)
 Mute / unmute a MixMonitor channel. More...
 
static void mixmonitor_ds_close_fs (struct mixmonitor_ds *mixmonitor_ds)
 
static void mixmonitor_ds_destroy (void *data)
 
static int mixmonitor_exec (struct ast_channel *chan, const char *data)
 
static void mixmonitor_free (struct mixmonitor *mixmonitor)
 
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, const char *data)
 
static int unload_module (void)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, }
 
static const char *const app = "MixMonitor"
 
static struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_cli_entry cli_mixmonitor []
 
static struct ast_datastore_info mixmonitor_ds_info
 
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 *const mixmonitor_spy_type = "MixMonitor"
 
static const char *const stop_app = "StopMixMonitor"
 

Detailed Description

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

Author
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m
Kevin P. Fleming kpfle.nosp@m.ming.nosp@m.@digi.nosp@m.um.c.nosp@m.om
Note
Based on app_muxmon.c provided by Anthony Minessale II anthm.nosp@m.ct@y.nosp@m.ahoo..nosp@m.com

Definition in file app_mixmonitor.c.

Macro Definition Documentation

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

Definition at line 164 of file app_mixmonitor.c.

Referenced by mixmonitor_exec().

#define SAMPLES_PER_FRAME   160

Definition at line 277 of file app_mixmonitor.c.

Referenced by mixmonitor_thread().

Enumeration Type Documentation

Enumerator
OPT_ARG_READVOLUME 
OPT_ARG_WRITEVOLUME 
OPT_ARG_VOLUME 
OPT_ARG_ARRAY_SIZE 

Definition at line 190 of file app_mixmonitor.c.

Enumerator
MUXFLAG_APPEND 
MUXFLAG_BRIDGED 
MUXFLAG_VOLUME 
MUXFLAG_READVOLUME 
MUXFLAG_WRITEVOLUME 

Definition at line 182 of file app_mixmonitor.c.

182  {
183  MUXFLAG_APPEND = (1 << 1),
184  MUXFLAG_BRIDGED = (1 << 2),
185  MUXFLAG_VOLUME = (1 << 3),
186  MUXFLAG_READVOLUME = (1 << 4),
187  MUXFLAG_WRITEVOLUME = (1 << 5),
188 };

Function Documentation

static void __reg_module ( void  )
static

Definition at line 754 of file app_mixmonitor.c.

static void __unreg_module ( void  )
static

Definition at line 754 of file app_mixmonitor.c.

static void destroy_monitor_audiohook ( struct mixmonitor mixmonitor)
static

Definition at line 247 of file app_mixmonitor.c.

References ast_audiohook_destroy(), ast_audiohook_detach(), ast_audiohook_lock, ast_audiohook_unlock, ast_mutex_lock, ast_mutex_unlock, mixmonitor_ds::audiohook, mixmonitor::audiohook, mixmonitor_ds::lock, and mixmonitor::mixmonitor_ds.

Referenced by mixmonitor_thread().

248 {
249  if (mixmonitor->mixmonitor_ds) {
250  ast_mutex_lock(&mixmonitor->mixmonitor_ds->lock);
251  mixmonitor->mixmonitor_ds->audiohook = NULL;
252  ast_mutex_unlock(&mixmonitor->mixmonitor_ds->lock);
253  }
254  /* kill the audiohook.*/
255  ast_audiohook_lock(&mixmonitor->audiohook);
256  ast_audiohook_detach(&mixmonitor->audiohook);
257  ast_audiohook_unlock(&mixmonitor->audiohook);
258  ast_audiohook_destroy(&mixmonitor->audiohook);
259 }
#define ast_mutex_lock(a)
Definition: lock.h:155
struct mixmonitor_ds * mixmonitor_ds
int ast_audiohook_destroy(struct ast_audiohook *audiohook)
Destroys an audiohook structure.
Definition: audiohook.c:96
#define ast_audiohook_unlock(ah)
Unlock an audiohook.
Definition: audiohook.h:272
int ast_audiohook_detach(struct ast_audiohook *audiohook)
Detach audiohook from channel.
Definition: audiohook.c:401
ast_mutex_t lock
struct ast_audiohook * audiohook
struct ast_audiohook audiohook
#define ast_audiohook_lock(ah)
Lock an audiohook.
Definition: audiohook.h:267
#define ast_mutex_unlock(a)
Definition: lock.h:156
static char* handle_cli_mixmonitor ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 619 of file app_mixmonitor.c.

References ast_cli_args::argc, ast_cli_args::argv, ast_audiohook_detach_source(), ast_channel_get_by_name_prefix(), ast_channel_lock, ast_channel_unlock, ast_channel_unref, ast_cli(), ast_complete_channels(), 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.

620 {
621  struct ast_channel *chan;
622 
623  switch (cmd) {
624  case CLI_INIT:
625  e->command = "mixmonitor {start|stop}";
626  e->usage =
627  "Usage: mixmonitor <start|stop> <chan_name> [args]\n"
628  " The optional arguments are passed to the MixMonitor\n"
629  " application when the 'start' command is used.\n";
630  return NULL;
631  case CLI_GENERATE:
632  return ast_complete_channels(a->line, a->word, a->pos, a->n, 2);
633  }
634 
635  if (a->argc < 3)
636  return CLI_SHOWUSAGE;
637 
638  if (!(chan = ast_channel_get_by_name_prefix(a->argv[2], strlen(a->argv[2])))) {
639  ast_cli(a->fd, "No channel matching '%s' found.\n", a->argv[2]);
640  /* Technically this is a failure, but we don't want 2 errors printing out */
641  return CLI_SUCCESS;
642  }
643 
644  ast_channel_lock(chan);
645 
646  if (!strcasecmp(a->argv[1], "start")) {
647  mixmonitor_exec(chan, a->argv[3]);
648  ast_channel_unlock(chan);
649  } else {
650  ast_channel_unlock(chan);
652  }
653 
654  chan = ast_channel_unref(chan);
655 
656  return CLI_SUCCESS;
657 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
Main Channel structure associated with a channel.
Definition: channel.h:742
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2502
const int argc
Definition: cli.h:154
Definition: cli.h:146
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
const char * line
Definition: cli.h:156
static int mixmonitor_exec(struct ast_channel *chan, const char *data)
struct ast_channel * ast_channel_get_by_name_prefix(const char *name, size_t name_len)
Find a channel by a name prefix.
Definition: channel.c:1808
static const char *const mixmonitor_spy_type
const int fd
Definition: cli.h:153
const int n
Definition: cli.h:159
int ast_audiohook_detach_source(struct ast_channel *chan, const char *source)
Detach specified source audiohook from channel.
Definition: audiohook.c:509
const char *const * argv
Definition: cli.h:155
#define CLI_SHOWUSAGE
Definition: cli.h:44
#define ast_channel_unlock(chan)
Definition: channel.h:2467
char * command
Definition: cli.h:180
const char * word
Definition: cli.h:157
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
const int pos
Definition: cli.h:158
char * ast_complete_channels(const char *line, const char *word, int pos, int state, int rpos)
Command completion for the list of active channels.
Definition: cli.c:1547
static int 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 419 of file app_mixmonitor.c.

References ast_audiohook_destroy(), ast_audiohook_init(), AST_AUDIOHOOK_TRIGGER_SYNC, AST_AUDIOHOOK_TYPE_SPY, ast_autochan_destroy(), ast_autochan_setup(), ast_calloc, ast_log(), ast_pthread_create_detached_background, ast_set_flag, ast_strdupa, ast_strlen_zero(), mixmonitor::audiohook, mixmonitor::autochan, mixmonitor::filename, mixmonitor::flags, len(), LOG_WARNING, mixmonitor_free(), mixmonitor_thread(), mixmonitor::name, ast_channel::name, ast_audiohook::options, pbx_substitute_variables_helper(), mixmonitor::post_process, ast_audiohook_options::read_volume, setup_mixmonitor_ds(), startmon(), thread, and ast_audiohook_options::write_volume.

Referenced by mixmonitor_exec().

421 {
422  pthread_t thread;
423  struct mixmonitor *mixmonitor;
424  char postprocess2[1024] = "";
425  size_t len;
426 
427  len = sizeof(*mixmonitor) + strlen(chan->name) + strlen(filename) + 2;
428 
429  postprocess2[0] = 0;
430  /* If a post process system command is given attach it to the structure */
432  char *p1, *p2;
433 
435  for (p2 = p1; *p2 ; p2++) {
436  if (*p2 == '^' && *(p2+1) == '{') {
437  *p2 = '$';
438  }
439  }
440  pbx_substitute_variables_helper(chan, p1, postprocess2, sizeof(postprocess2) - 1);
441  if (!ast_strlen_zero(postprocess2))
442  len += strlen(postprocess2) + 1;
443  }
444 
445  /* Pre-allocate mixmonitor structure and spy */
446  if (!(mixmonitor = ast_calloc(1, len))) {
447  return -1;
448  }
449 
450  /* Setup the actual spy before creating our thread */
452  mixmonitor_free(mixmonitor);
453  return -1;
454  }
455 
456  /* Copy over flags and channel name */
457  mixmonitor->flags = flags;
458  if (!(mixmonitor->autochan = ast_autochan_setup(chan))) {
459  mixmonitor_free(mixmonitor);
460  return -1;
461  }
462 
463  if (setup_mixmonitor_ds(mixmonitor, chan)) {
464  ast_autochan_destroy(mixmonitor->autochan);
465  mixmonitor_free(mixmonitor);
466  return -1;
467  }
468  mixmonitor->name = (char *) mixmonitor + sizeof(*mixmonitor);
469  strcpy(mixmonitor->name, chan->name);
470  if (!ast_strlen_zero(postprocess2)) {
471  mixmonitor->post_process = mixmonitor->name + strlen(mixmonitor->name) + strlen(filename) + 2;
472  strcpy(mixmonitor->post_process, postprocess2);
473  }
474 
475  mixmonitor->filename = (char *) mixmonitor + sizeof(*mixmonitor) + strlen(chan->name) + 1;
476  strcpy(mixmonitor->filename, filename);
477 
479 
480  if (readvol)
481  mixmonitor->audiohook.options.read_volume = readvol;
482  if (writevol)
483  mixmonitor->audiohook.options.write_volume = writevol;
484 
485  if (startmon(chan, &mixmonitor->audiohook)) {
486  ast_log(LOG_WARNING, "Unable to add '%s' spy to channel '%s'\n",
487  mixmonitor_spy_type, chan->name);
488  ast_audiohook_destroy(&mixmonitor->audiohook);
489  mixmonitor_free(mixmonitor);
490  return -1;
491  }
492 
493  return ast_pthread_create_detached_background(&thread, NULL, mixmonitor_thread, mixmonitor);
494 }
void pbx_substitute_variables_helper(struct ast_channel *c, const char *cp1, char *cp2, int count)
Definition: pbx.c:4676
pthread_t thread
Definition: app_meetme.c:962
#define ast_set_flag(p, flag)
Definition: utils.h:70
int ast_audiohook_init(struct ast_audiohook *audiohook, enum ast_audiohook_type type, const char *source)
Initialize an audiohook structure.
Definition: audiohook.c:64
#define LOG_WARNING
Definition: logger.h:144
static int startmon(struct ast_channel *chan, struct ast_audiohook *audiohook)
char * post_process
int ast_audiohook_destroy(struct ast_audiohook *audiohook)
Destroys an audiohook structure.
Definition: audiohook.c:96
#define ast_pthread_create_detached_background(a, b, c, d)
Definition: utils.h:431
static void mixmonitor_free(struct mixmonitor *mixmonitor)
static const char *const mixmonitor_spy_type
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static int setup_mixmonitor_ds(struct mixmonitor *mixmonitor, struct ast_channel *chan)
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
const ast_string_field name
Definition: channel.h:787
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
char * filename
void ast_autochan_destroy(struct ast_autochan *autochan)
destroy an ast_autochan structure
Definition: autochan.c:63
struct ast_autochan * ast_autochan_setup(struct ast_channel *chan)
set up a new ast_autochan structure
Definition: autochan.c:40
struct ast_audiohook_options options
Definition: audiohook.h:117
static void * mixmonitor_thread(void *obj)
#define ast_calloc(a, b)
Definition: astmm.h:82
unsigned int flags
struct ast_audiohook audiohook
struct ast_autochan * autochan
static int load_module ( void  )
static

Definition at line 742 of file app_mixmonitor.c.

References ARRAY_LEN, ast_cli_register_multiple(), ast_manager_register_xml, ast_register_application_xml, manager_mute_mixmonitor(), mixmonitor_exec(), and stop_mixmonitor_exec().

743 {
744  int res;
745 
749  res |= ast_manager_register_xml("MixMonitorMute", 0, manager_mute_mixmonitor);
750 
751  return res;
752 }
static int stop_mixmonitor_exec(struct ast_channel *chan, const char *data)
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static int manager_mute_mixmonitor(struct mansession *s, const struct message *m)
Mute / unmute a MixMonitor channel.
static int mixmonitor_exec(struct ast_channel *chan, const char *data)
static const char *const stop_app
#define ast_manager_register_xml(a, b, c)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:172
static const char *const app
int ast_cli_register_multiple(struct ast_cli_entry *e, int len)
Register multiple commands.
Definition: cli.c:2167
static struct ast_cli_entry cli_mixmonitor[]
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:437
static int manager_mute_mixmonitor ( struct mansession s,
const struct message m 
)
static

Mute / unmute a MixMonitor channel.

Definition at line 660 of file app_mixmonitor.c.

References AMI_SUCCESS, AST_AUDIOHOOK_MUTE_READ, AST_AUDIOHOOK_MUTE_WRITE, ast_audiohook_set_mute(), ast_channel_get_by_name(), ast_channel_unref, ast_false(), ast_strlen_zero(), astman_append(), astman_get_header(), astman_send_error(), and name.

Referenced by load_module().

661 {
662  struct ast_channel *c = NULL;
663 
664  const char *name = astman_get_header(m, "Channel");
665  const char *id = astman_get_header(m, "ActionID");
666  const char *state = astman_get_header(m, "State");
667  const char *direction = astman_get_header(m,"Direction");
668 
669  int clearmute = 1;
670 
671  enum ast_audiohook_flags flag;
672 
673  if (ast_strlen_zero(direction)) {
674  astman_send_error(s, m, "No direction specified. Must be read, write or both");
675  return AMI_SUCCESS;
676  }
677 
678  if (!strcasecmp(direction, "read")) {
680  } else if (!strcasecmp(direction, "write")) {
682  } else if (!strcasecmp(direction, "both")) {
684  } else {
685  astman_send_error(s, m, "Invalid direction specified. Must be read, write or both");
686  return AMI_SUCCESS;
687  }
688 
689  if (ast_strlen_zero(name)) {
690  astman_send_error(s, m, "No channel specified");
691  return AMI_SUCCESS;
692  }
693 
694  if (ast_strlen_zero(state)) {
695  astman_send_error(s, m, "No state specified");
696  return AMI_SUCCESS;
697  }
698 
699  clearmute = ast_false(state);
700  c = ast_channel_get_by_name(name);
701 
702  if (!c) {
703  astman_send_error(s, m, "No such channel");
704  return AMI_SUCCESS;
705  }
706 
707  if (ast_audiohook_set_mute(c, mixmonitor_spy_type, flag, clearmute)) {
708  c = ast_channel_unref(c);
709  astman_send_error(s, m, "Cannot set mute flag");
710  return AMI_SUCCESS;
711  }
712 
713  astman_append(s, "Response: Success\r\n");
714 
715  if (!ast_strlen_zero(id)) {
716  astman_append(s, "ActionID: %s\r\n", id);
717  }
718 
719  astman_append(s, "\r\n");
720 
721  c = ast_channel_unref(c);
722 
723  return AMI_SUCCESS;
724 }
Main Channel structure associated with a channel.
Definition: channel.h:742
ast_audiohook_flags
Definition: audiohook.h:60
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:2068
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2502
int ast_audiohook_set_mute(struct ast_channel *chan, const char *source, enum ast_audiohook_flags flag, int clear)
Mute frames read from or written to a channel.
Definition: audiohook.c:1057
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
static const char *const mixmonitor_spy_type
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static const char name[]
int attribute_pure ast_false(const char *val)
Make sure something is false. Determine if a string containing a boolean value is &quot;false&quot;...
Definition: utils.c:1550
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1803
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:2130
#define AMI_SUCCESS
Definition: manager.h:65
static void mixmonitor_ds_close_fs ( struct mixmonitor_ds mixmonitor_ds)
static

Definition at line 221 of file app_mixmonitor.c.

References ast_closestream(), ast_verb, mixmonitor_ds::fs, and mixmonitor_ds::fs_quit.

Referenced by mixmonitor_thread(), and stop_mixmonitor_exec().

222 {
223  if (mixmonitor_ds->fs) {
224  ast_closestream(mixmonitor_ds->fs);
225  mixmonitor_ds->fs = NULL;
226  mixmonitor_ds->fs_quit = 1;
227  ast_verb(2, "MixMonitor close filestream\n");
228  }
229 }
struct ast_filestream * fs
#define ast_verb(level,...)
Definition: logger.h:243
int ast_closestream(struct ast_filestream *f)
Closes a stream.
Definition: file.c:904
static void mixmonitor_ds_destroy ( void *  data)
static

Definition at line 231 of file app_mixmonitor.c.

References ast_cond_signal, ast_mutex_lock, ast_mutex_unlock, mixmonitor_ds::audiohook, mixmonitor_ds::destruction_condition, mixmonitor_ds::destruction_ok, and mixmonitor_ds::lock.

232 {
233  struct mixmonitor_ds *mixmonitor_ds = data;
234 
235  ast_mutex_lock(&mixmonitor_ds->lock);
236  mixmonitor_ds->audiohook = NULL;
237  mixmonitor_ds->destruction_ok = 1;
238  ast_cond_signal(&mixmonitor_ds->destruction_condition);
239  ast_mutex_unlock(&mixmonitor_ds->lock);
240 }
unsigned int destruction_ok
#define ast_mutex_lock(a)
Definition: lock.h:155
#define ast_cond_signal(cond)
Definition: lock.h:169
ast_cond_t destruction_condition
ast_mutex_t lock
struct ast_audiohook * audiohook
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int mixmonitor_exec ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 496 of file app_mixmonitor.c.

References args, ast_alloca, AST_APP_ARG, ast_app_parse_options(), ast_config_AST_MONITOR_DIR, AST_DECLARE_APP_ARGS, ast_log(), ast_mkdir(), ast_module_ref(), ast_module_unref(), AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ast_test_flag, 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(), pbx_builtin_setvar_helper(), and ast_module_info::self.

Referenced by handle_cli_mixmonitor(), and load_module().

497 {
498  int x, readvol = 0, writevol = 0;
499  struct ast_flags flags = {0};
500  char *parse, *tmp, *slash;
502  AST_APP_ARG(filename);
503  AST_APP_ARG(options);
504  AST_APP_ARG(post_process);
505  );
506 
507  if (ast_strlen_zero(data)) {
508  ast_log(LOG_WARNING, "MixMonitor requires an argument (filename)\n");
509  return -1;
510  }
511 
512  parse = ast_strdupa(data);
513 
514  AST_STANDARD_APP_ARGS(args, parse);
515 
516  if (ast_strlen_zero(args.filename)) {
517  ast_log(LOG_WARNING, "MixMonitor requires an argument (filename)\n");
518  return -1;
519  }
520 
521  if (args.options) {
522  char *opts[OPT_ARG_ARRAY_SIZE] = { NULL, };
523 
524  ast_app_parse_options(mixmonitor_opts, &flags, opts, args.options);
525 
526  if (ast_test_flag(&flags, MUXFLAG_READVOLUME)) {
527  if (ast_strlen_zero(opts[OPT_ARG_READVOLUME])) {
528  ast_log(LOG_WARNING, "No volume level was provided for the heard volume ('v') option.\n");
529  } else if ((sscanf(opts[OPT_ARG_READVOLUME], "%2d", &x) != 1) || (x < -4) || (x > 4)) {
530  ast_log(LOG_NOTICE, "Heard volume must be a number between -4 and 4, not '%s'\n", opts[OPT_ARG_READVOLUME]);
531  } else {
532  readvol = get_volfactor(x);
533  }
534  }
535 
536  if (ast_test_flag(&flags, MUXFLAG_WRITEVOLUME)) {
538  ast_log(LOG_WARNING, "No volume level was provided for the spoken volume ('V') option.\n");
539  } else if ((sscanf(opts[OPT_ARG_WRITEVOLUME], "%2d", &x) != 1) || (x < -4) || (x > 4)) {
540  ast_log(LOG_NOTICE, "Spoken volume must be a number between -4 and 4, not '%s'\n", opts[OPT_ARG_WRITEVOLUME]);
541  } else {
542  writevol = get_volfactor(x);
543  }
544  }
545 
546  if (ast_test_flag(&flags, MUXFLAG_VOLUME)) {
547  if (ast_strlen_zero(opts[OPT_ARG_VOLUME])) {
548  ast_log(LOG_WARNING, "No volume level was provided for the combined volume ('W') option.\n");
549  } else if ((sscanf(opts[OPT_ARG_VOLUME], "%2d", &x) != 1) || (x < -4) || (x > 4)) {
550  ast_log(LOG_NOTICE, "Combined volume must be a number between -4 and 4, not '%s'\n", opts[OPT_ARG_VOLUME]);
551  } else {
552  readvol = writevol = get_volfactor(x);
553  }
554  }
555  }
556 
557  /* if not provided an absolute path, use the system-configured monitoring directory */
558  if (args.filename[0] != '/') {
559  char *build;
560 
561  build = ast_alloca(strlen(ast_config_AST_MONITOR_DIR) + strlen(args.filename) + 3);
562  sprintf(build, "%s/%s", ast_config_AST_MONITOR_DIR, args.filename);
563  args.filename = build;
564  }
565 
566  tmp = ast_strdupa(args.filename);
567  if ((slash = strrchr(tmp, '/')))
568  *slash = '\0';
569  ast_mkdir(tmp, 0777);
570 
571  pbx_builtin_setvar_helper(chan, "MIXMONITOR_FILENAME", args.filename);
572 
573  /* If launch_monitor_thread works, the module reference must not be released until it is finished. */
575  if (launch_monitor_thread(chan, args.filename, flags.flags, readvol, writevol, args.post_process)) {
577  }
578 
579  return 0;
580 }
static int launch_monitor_thread(struct ast_channel *chan, const char *filename, unsigned int flags, int readvol, int writevol, const char *post_process)
void ast_module_unref(struct ast_module *)
Definition: loader.c:1312
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: utils.h:653
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define LOG_WARNING
Definition: logger.h:144
int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr)
Parses a string containing application options and sets flags/arguments.
Definition: app.c:2101
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Definition: app.h:572
unsigned int flags
Definition: utils.h:201
#define get_volfactor(x)
struct ast_module * self
Definition: module.h:227
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
static struct @350 args
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1858
const char * ast_config_AST_MONITOR_DIR
Definition: asterisk.c:260
Structure used to handle boolean flags.
Definition: utils.h:200
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
Definition: pbx.c:10546
#define AST_APP_ARG(name)
Define an application argument.
Definition: app.h:555
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the &#39;standard&#39; argument separation process for an application.
Definition: app.h:604
static struct ast_app_option mixmonitor_opts[128]
int ast_mkdir(const char *path, int mode)
Recursively create directory path.
Definition: utils.c:2151
struct ast_module * ast_module_ref(struct ast_module *)
Definition: loader.c:1300
static void mixmonitor_free ( struct mixmonitor mixmonitor)
static

Definition at line 279 of file app_mixmonitor.c.

References ast_cond_destroy, ast_free, ast_mutex_destroy, mixmonitor_ds::destruction_condition, mixmonitor_ds::lock, and mixmonitor::mixmonitor_ds.

Referenced by launch_monitor_thread(), and mixmonitor_thread().

280 {
281  if (mixmonitor) {
282  if (mixmonitor->mixmonitor_ds) {
283  ast_mutex_destroy(&mixmonitor->mixmonitor_ds->lock);
285  ast_free(mixmonitor->mixmonitor_ds);
286  }
287  ast_free(mixmonitor);
288  }
289 }
struct mixmonitor_ds * mixmonitor_ds
ast_cond_t destruction_condition
#define ast_cond_destroy(cond)
Definition: lock.h:168
ast_mutex_t lock
#define ast_free(a)
Definition: astmm.h:97
#define ast_mutex_destroy(a)
Definition: lock.h:154
static void* mixmonitor_thread ( void *  obj)
static

Definition at line 290 of file app_mixmonitor.c.

References AST_AUDIOHOOK_DIRECTION_BOTH, ast_audiohook_lock, ast_audiohook_read_frame(), AST_AUDIOHOOK_STATUS_RUNNING, ast_audiohook_trigger_wait(), ast_audiohook_unlock, ast_autochan_destroy(), ast_bridged_channel(), ast_cond_wait, AST_FORMAT_SLINEAR, ast_frame_free(), AST_LIST_NEXT, ast_log(), ast_module_unref(), ast_mutex_lock, ast_mutex_unlock, ast_safe_system(), ast_test_flag, ast_test_suite_event_notify, ast_verb, ast_writefile(), ast_writestream(), mixmonitor::audiohook, mixmonitor::autochan, ast_autochan::chan, destroy_monitor_audiohook(), mixmonitor_ds::destruction_condition, mixmonitor_ds::destruction_ok, ext, mixmonitor::filename, mixmonitor_ds::fs, mixmonitor_ds::fs_quit, mixmonitor_ds::lock, LOG_ERROR, mixmonitor::mixmonitor_ds, mixmonitor_ds_close_fs(), mixmonitor_free(), MUXFLAG_APPEND, MUXFLAG_BRIDGED, mixmonitor::name, ast_channel::name, mixmonitor::post_process, SAMPLES_PER_FRAME, ast_module_info::self, and ast_audiohook::status.

Referenced by launch_monitor_thread().

291 {
292  struct mixmonitor *mixmonitor = obj;
293  struct ast_filestream **fs = NULL;
294  unsigned int oflags;
295  char *ext;
296  char *last_slash;
297  int errflag = 0;
298 
299  ast_verb(2, "Begin MixMonitor Recording %s\n", mixmonitor->name);
300 
301  fs = &mixmonitor->mixmonitor_ds->fs;
302 
303  /* The audiohook must enter and exit the loop locked */
304  ast_audiohook_lock(&mixmonitor->audiohook);
305  while (mixmonitor->audiohook.status == AST_AUDIOHOOK_STATUS_RUNNING && !mixmonitor->mixmonitor_ds->fs_quit) {
306  struct ast_frame *fr = NULL;
307 
310 
311  if (mixmonitor->audiohook.status != AST_AUDIOHOOK_STATUS_RUNNING) {
312  break;
313  }
314  continue;
315  }
316 
317  /* audiohook lock is not required for the next block.
318  * Unlock it, but remember to lock it before looping or exiting */
319  ast_audiohook_unlock(&mixmonitor->audiohook);
320 
321  if (!ast_test_flag(mixmonitor, MUXFLAG_BRIDGED) || (mixmonitor->autochan->chan && ast_bridged_channel(mixmonitor->autochan->chan))) {
322  ast_mutex_lock(&mixmonitor->mixmonitor_ds->lock);
323  /* Initialize the file if not already done so */
324  if (!*fs && !errflag && !mixmonitor->mixmonitor_ds->fs_quit) {
325  oflags = O_CREAT | O_WRONLY;
326  oflags |= ast_test_flag(mixmonitor, MUXFLAG_APPEND) ? O_APPEND : O_TRUNC;
327 
328  last_slash = strrchr(mixmonitor->filename, '/');
329  if ((ext = strrchr(mixmonitor->filename, '.')) && (ext > last_slash))
330  *(ext++) = '\0';
331  else
332  ext = "raw";
333 
334  if (!(*fs = ast_writefile(mixmonitor->filename, ext, NULL, oflags, 0, 0666))) {
335  ast_log(LOG_ERROR, "Cannot open %s.%s\n", mixmonitor->filename, ext);
336  errflag = 1;
337  }
338  }
339 
340  /* Write out the frame(s) */
341  if (*fs) {
342  struct ast_frame *cur;
343 
344  for (cur = fr; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
345  ast_writestream(*fs, cur);
346  }
347  }
348  ast_mutex_unlock(&mixmonitor->mixmonitor_ds->lock);
349  }
350  /* All done! free it. */
351  ast_frame_free(fr, 0);
352 
353  ast_audiohook_lock(&mixmonitor->audiohook);
354  }
355 
356  /* Test Event */
357  ast_test_suite_event_notify("MIXMONITOR_END", "Channel: %s\r\n"
358  "File: %s\r\n",
359  mixmonitor->autochan->chan->name,
360  mixmonitor->filename);
361 
362  ast_audiohook_unlock(&mixmonitor->audiohook);
363 
364  ast_autochan_destroy(mixmonitor->autochan);
365 
366  /* Datastore cleanup. close the filestream and wait for ds destruction */
367  ast_mutex_lock(&mixmonitor->mixmonitor_ds->lock);
369  if (!mixmonitor->mixmonitor_ds->destruction_ok) {
371  }
372  ast_mutex_unlock(&mixmonitor->mixmonitor_ds->lock);
373 
374  /* kill the audiohook */
375  destroy_monitor_audiohook(mixmonitor);
376 
377  if (mixmonitor->post_process) {
378  ast_verb(2, "Executing [%s]\n", mixmonitor->post_process);
379  ast_safe_system(mixmonitor->post_process);
380  }
381 
382  ast_verb(2, "End MixMonitor Recording %s\n", mixmonitor->name);
383  mixmonitor_free(mixmonitor);
384 
386  return NULL;
387 }
void ast_frame_free(struct ast_frame *fr, int cache)
Requests a frame to be allocated.
Definition: frame.c:375
struct ast_frame * ast_audiohook_read_frame(struct ast_audiohook *audiohook, size_t samples, enum ast_audiohook_direction direction, format_t format)
Reads a frame in from the audiohook structure.
Definition: audiohook.c:313
int ast_safe_system(const char *s)
Safely spawn an external program while closing file descriptors.
Definition: asterisk.c:1077
void ast_module_unref(struct ast_module *)
Definition: loader.c:1312
static void destroy_monitor_audiohook(struct mixmonitor *mixmonitor)
struct ast_filestream * fs
#define ast_test_flag(p, flag)
Definition: utils.h:63
unsigned int destruction_ok
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:438
#define ast_cond_wait(cond, mutex)
Definition: lock.h:171
struct ast_channel * chan
Definition: autochan.h:33
char * post_process
#define ast_mutex_lock(a)
Definition: lock.h:155
struct mixmonitor_ds * mixmonitor_ds
const char * ext
Definition: http.c:112
#define ast_verb(level,...)
Definition: logger.h:243
ast_cond_t destruction_condition
#define ast_audiohook_unlock(ah)
Unlock an audiohook.
Definition: audiohook.h:272
static void mixmonitor_free(struct mixmonitor *mixmonitor)
struct ast_module * self
Definition: module.h:227
#define ast_test_suite_event_notify(s, f,...)
Definition: test.h:184
#define LOG_ERROR
Definition: logger.h:155
static void mixmonitor_ds_close_fs(struct mixmonitor_ds *mixmonitor_ds)
struct ast_channel * ast_bridged_channel(struct ast_channel *chan)
Find bridged channel.
Definition: channel.c:7160
const ast_string_field name
Definition: channel.h:787
struct ast_filestream * ast_writefile(const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode)
Starts writing a file.
Definition: file.c:1049
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
ast_mutex_t lock
char * filename
#define SAMPLES_PER_FRAME
void ast_autochan_destroy(struct ast_autochan *autochan)
destroy an ast_autochan structure
Definition: autochan.c:63
This structure is allocated by file.c in one chunk, together with buf_size and desc_size bytes of mem...
Definition: mod_format.h:100
#define AST_FORMAT_SLINEAR
Definition: frame.h:254
int ast_writestream(struct ast_filestream *fs, struct ast_frame *f)
Writes a frame to a stream.
Definition: file.c:150
Data structure associated with a single frame of data.
Definition: frame.h:142
enum ast_audiohook_status status
Definition: audiohook.h:107
struct ast_audiohook audiohook
#define ast_audiohook_lock(ah)
Lock an audiohook.
Definition: audiohook.h:267
struct ast_autochan * autochan
void ast_audiohook_trigger_wait(struct ast_audiohook *audiohook)
Wait for audiohook trigger to be triggered.
Definition: audiohook.c:776
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int setup_mixmonitor_ds ( struct mixmonitor mixmonitor,
struct ast_channel chan 
)
static

Definition at line 389 of file app_mixmonitor.c.

References ast_calloc, ast_channel_datastore_add(), ast_channel_lock, ast_channel_unlock, ast_cond_destroy, ast_cond_init, ast_datastore_alloc(), ast_free, ast_mutex_destroy, ast_mutex_init, mixmonitor_ds::audiohook, mixmonitor::audiohook, ast_datastore::data, mixmonitor_ds::destruction_condition, mixmonitor_ds::lock, and mixmonitor::mixmonitor_ds.

Referenced by launch_monitor_thread().

390 {
391  struct ast_datastore *datastore = NULL;
393 
394  if (!(mixmonitor_ds = ast_calloc(1, sizeof(*mixmonitor_ds)))) {
395  return -1;
396  }
397 
398  ast_mutex_init(&mixmonitor_ds->lock);
399  ast_cond_init(&mixmonitor_ds->destruction_condition, NULL);
400 
401  if (!(datastore = ast_datastore_alloc(&mixmonitor_ds_info, NULL))) {
402  ast_mutex_destroy(&mixmonitor_ds->lock);
403  ast_cond_destroy(&mixmonitor_ds->destruction_condition);
404  ast_free(mixmonitor_ds);
405  return -1;
406  }
407 
408  mixmonitor_ds->audiohook = &mixmonitor->audiohook;
409  datastore->data = mixmonitor_ds;
410 
411  ast_channel_lock(chan);
412  ast_channel_datastore_add(chan, datastore);
413  ast_channel_unlock(chan);
414 
415  mixmonitor->mixmonitor_ds = mixmonitor_ds;
416  return 0;
417 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
#define ast_cond_init(cond, attr)
Definition: lock.h:167
struct mixmonitor_ds * mixmonitor_ds
Structure for a data store object.
Definition: datastore.h:54
ast_cond_t destruction_condition
#define ast_cond_destroy(cond)
Definition: lock.h:168
struct ast_datastore * ast_datastore_alloc(const struct ast_datastore_info *info, const char *uid)
Definition: datastore.c:98
#define ast_channel_unlock(chan)
Definition: channel.h:2467
ast_mutex_t lock
#define ast_free(a)
Definition: astmm.h:97
void * data
Definition: datastore.h:56
#define ast_calloc(a, b)
Definition: astmm.h:82
struct ast_audiohook * audiohook
static struct ast_datastore_info mixmonitor_ds_info
#define ast_mutex_init(pmutex)
Definition: lock.h:152
#define ast_mutex_destroy(a)
Definition: lock.h:154
struct ast_audiohook audiohook
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
Definition: channel.c:2590
static int startmon ( struct ast_channel chan,
struct ast_audiohook audiohook 
)
static

Definition at line 261 of file app_mixmonitor.c.

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

Referenced by launch_monitor_thread().

262 {
263  struct ast_channel *peer = NULL;
264  int res = 0;
265 
266  if (!chan)
267  return -1;
268 
269  ast_audiohook_attach(chan, audiohook);
270 
271  if (!res && ast_test_flag(chan, AST_FLAG_NBRIDGE) && (peer = ast_bridged_channel(chan)))
273 
274  return res;
275 }
Main Channel structure associated with a channel.
Definition: channel.h:742
#define ast_test_flag(p, flag)
Definition: utils.h:63
int ast_audiohook_attach(struct ast_channel *chan, struct ast_audiohook *audiohook)
Attach audiohook to channel.
Definition: audiohook.c:348
int ast_softhangup(struct ast_channel *chan, int reason)
Softly hangup up a channel.
Definition: channel.c:2746
struct ast_channel * ast_bridged_channel(struct ast_channel *chan)
Find bridged channel.
Definition: channel.c:7160
static int stop_mixmonitor_exec ( struct ast_channel chan,
const char *  data 
)
static

Definition at line 582 of file app_mixmonitor.c.

References ast_audiohook_detach_source(), ast_audiohook_lock, ast_audiohook_unlock, ast_channel_datastore_find(), ast_channel_datastore_remove(), ast_channel_lock, ast_channel_unlock, ast_cond_signal, ast_datastore_free(), ast_mutex_lock, ast_mutex_unlock, mixmonitor_ds::audiohook, ast_datastore::data, mixmonitor_ds::lock, mixmonitor_ds_close_fs(), and ast_audiohook::trigger.

Referenced by load_module().

583 {
584  struct ast_datastore *datastore = NULL;
585 
586  ast_channel_lock(chan);
588  if ((datastore = ast_channel_datastore_find(chan, &mixmonitor_ds_info, NULL))) {
589  struct mixmonitor_ds *mixmonitor_ds = datastore->data;
590 
591  ast_mutex_lock(&mixmonitor_ds->lock);
592 
593  /* closing the filestream here guarantees the file is available to the dialplan
594  * after calling StopMixMonitor */
595  mixmonitor_ds_close_fs(mixmonitor_ds);
596 
597  /* The mixmonitor thread may be waiting on the audiohook trigger.
598  * In order to exit from the mixmonitor loop before waiting on channel
599  * destruction, poke the audiohook trigger. */
600  if (mixmonitor_ds->audiohook) {
601  ast_audiohook_lock(mixmonitor_ds->audiohook);
602  ast_cond_signal(&mixmonitor_ds->audiohook->trigger);
603  ast_audiohook_unlock(mixmonitor_ds->audiohook);
604  mixmonitor_ds->audiohook = NULL;
605  }
606 
607  ast_mutex_unlock(&mixmonitor_ds->lock);
608 
609  /* Remove the datastore so the monitor thread can exit */
610  if (!ast_channel_datastore_remove(chan, datastore)) {
611  ast_datastore_free(datastore);
612  }
613  }
614  ast_channel_unlock(chan);
615 
616  return 0;
617 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
#define ast_mutex_lock(a)
Definition: lock.h:155
Structure for a data store object.
Definition: datastore.h:54
struct ast_datastore * ast_channel_datastore_find(struct ast_channel *chan, const struct ast_datastore_info *info, const char *uid)
Find a datastore on a channel.
Definition: channel.c:2604
#define ast_cond_signal(cond)
Definition: lock.h:169
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
Definition: datastore.c:65
#define ast_audiohook_unlock(ah)
Unlock an audiohook.
Definition: audiohook.h:272
static const char *const mixmonitor_spy_type
int ast_audiohook_detach_source(struct ast_channel *chan, const char *source)
Detach specified source audiohook from channel.
Definition: audiohook.c:509
static void mixmonitor_ds_close_fs(struct mixmonitor_ds *mixmonitor_ds)
#define ast_channel_unlock(chan)
Definition: channel.h:2467
ast_mutex_t lock
ast_cond_t trigger
Definition: audiohook.h:105
void * data
Definition: datastore.h:56
struct ast_audiohook * audiohook
static struct ast_datastore_info mixmonitor_ds_info
#define ast_audiohook_lock(ah)
Lock an audiohook.
Definition: audiohook.h:267
int ast_channel_datastore_remove(struct ast_channel *chan, struct ast_datastore *datastore)
Remove a datastore from a channel.
Definition: channel.c:2599
#define ast_mutex_unlock(a)
Definition: lock.h:156
static int unload_module ( void  )
static

Definition at line 730 of file app_mixmonitor.c.

References ARRAY_LEN, ast_cli_unregister_multiple(), ast_manager_unregister(), and ast_unregister_application().

731 {
732  int res;
733 
737  res |= ast_manager_unregister("MixMonitorMute");
738 
739  return res;
740 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: cli.c:2177
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx.c:7705
static const char *const stop_app
static const char *const app
static struct ast_cli_entry cli_mixmonitor[]
int ast_manager_unregister(char *action)
Unregister a registered manager command.
Definition: manager.c:5355

Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .load_pri = AST_MODPRI_DEFAULT, }
static

Definition at line 754 of file app_mixmonitor.c.

const char* const app = "MixMonitor"
static

Definition at line 166 of file app_mixmonitor.c.

Definition at line 754 of file app_mixmonitor.c.

struct ast_cli_entry cli_mixmonitor[]
static
Initial value:
= {
AST_CLI_DEFINE(handle_cli_mixmonitor, "Execute a MixMonitor command")
}
#define AST_CLI_DEFINE(fn, txt,...)
Definition: cli.h:191
static char * handle_cli_mixmonitor(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)

Definition at line 726 of file app_mixmonitor.c.

struct ast_datastore_info mixmonitor_ds_info
static
Initial value:
= {
.type = "mixmonitor",
}
static void mixmonitor_ds_destroy(void *data)

Definition at line 242 of file app_mixmonitor.c.

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 203 of file app_mixmonitor.c.

Referenced by mixmonitor_exec().

const char* const mixmonitor_spy_type = "MixMonitor"
static

Definition at line 170 of file app_mixmonitor.c.

Referenced by builtin_automixmonitor().

const char* const stop_app = "StopMixMonitor"
static

Definition at line 168 of file app_mixmonitor.c.