44 #include "asterisk/paths.h"
164 #define get_volfactor(x) x ? ((x > 0) ? (1 << x) : ((1 << abs(x)) * -1)) : 0
166 static const char *
const app =
"MixMonitor";
168 static const char *
const stop_app =
"StopMixMonitor";
223 if (mixmonitor_ds->
fs) {
225 mixmonitor_ds->
fs = NULL;
227 ast_verb(2,
"MixMonitor close filestream\n");
243 .
type =
"mixmonitor",
277 #define SAMPLES_PER_FRAME 160
299 ast_verb(2,
"Begin MixMonitor Recording %s\n", mixmonitor->
name);
325 oflags = O_CREAT | O_WRONLY;
328 last_slash = strrchr(mixmonitor->
filename,
'/');
329 if ((ext = strrchr(mixmonitor->
filename,
'.')) && (ext > last_slash))
382 ast_verb(2,
"End MixMonitor Recording %s\n", mixmonitor->
name);
394 if (!(mixmonitor_ds =
ast_calloc(1,
sizeof(*mixmonitor_ds)))) {
409 datastore->
data = mixmonitor_ds;
420 int readvol,
int writevol,
const char *post_process)
424 char postprocess2[1024] =
"";
427 len =
sizeof(*mixmonitor) + strlen(chan->
name) + strlen(filename) + 2;
435 for (p2 = p1; *p2 ; p2++) {
436 if (*p2 ==
'^' && *(p2+1) ==
'{') {
442 len += strlen(postprocess2) + 1;
468 mixmonitor->
name = (
char *) mixmonitor +
sizeof(*mixmonitor);
469 strcpy(mixmonitor->
name, chan->
name);
475 mixmonitor->
filename = (
char *) mixmonitor +
sizeof(*mixmonitor) + strlen(chan->
name) + 1;
476 strcpy(mixmonitor->
filename, filename);
487 mixmonitor_spy_type, chan->
name);
498 int x, readvol = 0, writevol = 0;
500 char *
parse, *tmp, *slash;
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]);
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]);
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]);
558 if (
args.filename[0] !=
'/') {
563 args.filename = build;
567 if ((slash = strrchr(tmp,
'/')))
625 e->
command =
"mixmonitor {start|stop}";
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";
639 ast_cli(a->
fd,
"No channel matching '%s' found.\n", a->
argv[2]);
646 if (!strcasecmp(a->
argv[1],
"start")) {
678 if (!strcasecmp(direction,
"read")) {
680 }
else if (!strcasecmp(direction,
"write")) {
682 }
else if (!strcasecmp(direction,
"both")) {
685 astman_send_error(s, m,
"Invalid direction specified. Must be read, write or both");
static int stop_mixmonitor_exec(struct ast_channel *chan, const char *data)
void pbx_substitute_variables_helper(struct ast_channel *c, const char *cp1, char *cp2, int count)
void ast_frame_free(struct ast_frame *fr, int cache)
Requests a frame to be allocated.
#define ast_channel_lock(chan)
Main Channel structure associated with a channel.
static int launch_monitor_thread(struct ast_channel *chan, const char *filename, unsigned int flags, int readvol, int writevol, const char *post_process)
#define AST_CLI_DEFINE(fn, txt,...)
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.
#define AST_MODULE_INFO_STANDARD(keystr, desc)
#define AST_APP_OPTION_ARG(option, flagno, argno)
Declares an application option that accepts an argument.
int ast_safe_system(const char *s)
Safely spawn an external program while closing file descriptors.
void astman_append(struct mansession *s, const char *fmt,...)
Asterisk main include file. File version handling, generic pbx functions.
#define AST_APP_OPTIONS(holder, options...)
Declares an array of options for an application.
void ast_module_unref(struct ast_module *)
static void destroy_monitor_audiohook(struct mixmonitor *mixmonitor)
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
struct ast_filestream * fs
#define ast_channel_unref(c)
Decrease channel reference count.
#define ast_test_flag(p, flag)
unsigned int destruction_ok
#define ast_set_flag(p, flag)
int ast_audiohook_init(struct ast_audiohook *audiohook, enum ast_audiohook_type type, const char *source)
Initialize an audiohook structure.
descriptor for a cli entry.
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.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
static int startmon(struct ast_channel *chan, struct ast_audiohook *audiohook)
static void mixmonitor_ds_destroy(void *data)
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.
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Structure for a data store type.
int ast_audiohook_attach(struct ast_channel *chan, struct ast_audiohook *audiohook)
Attach audiohook to channel.
#define ast_cond_wait(cond, mutex)
#define ast_cond_init(cond, attr)
struct ast_channel * chan
#define ast_mutex_lock(a)
struct mixmonitor_ds * mixmonitor_ds
static int manager_mute_mixmonitor(struct mansession *s, const struct message *m)
Mute / unmute a MixMonitor channel.
Structure for a data store object.
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.
Generic File Format Support. Should be included by clients of the file handling routines. File service providers should instead include mod_format.h.
void ast_cli(int fd, const char *fmt,...)
int ast_unregister_application(const char *app)
Unregister an application.
int ast_audiohook_destroy(struct ast_audiohook *audiohook)
Destroys an audiohook structure.
#define ast_cond_signal(cond)
#define ast_pthread_create_detached_background(a, b, c, d)
#define ast_verb(level,...)
int ast_datastore_free(struct ast_datastore *datastore)
Free a data store object.
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.
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
pthread_cond_t ast_cond_t
ast_cond_t destruction_condition
#define ast_audiohook_unlock(ah)
Unlock an audiohook.
static void mixmonitor_free(struct mixmonitor *mixmonitor)
static const char *const stop_app
General Asterisk PBX channel definitions.
static const char *const mixmonitor_spy_type
#define ast_manager_register_xml(a, b, c)
Register a manager callback using XML documentation to describe the manager.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
int ast_softhangup(struct ast_channel *chan, int reason)
Softly hangup up a channel.
int ast_audiohook_detach_source(struct ast_channel *chan, const char *source)
Detach specified source audiohook from channel.
Core PBX routines and definitions.
static int setup_mixmonitor_ds(struct mixmonitor *mixmonitor, struct ast_channel *chan)
#define ast_test_suite_event_notify(s, f,...)
static int unload_module(void)
The AMI - Asterisk Manager Interface - is a TCP protocol created to manage Asterisk with third-party ...
#define ast_strdupa(s)
duplicate a string in memory from the stack
"smart" channels that update automatically if a channel is masqueraded
int ast_audiohook_detach(struct ast_audiohook *audiohook)
Detach audiohook from channel.
static void mixmonitor_ds_close_fs(struct mixmonitor_ds *mixmonitor_ds)
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
struct ast_channel * ast_bridged_channel(struct ast_channel *chan)
Find bridged channel.
const ast_string_field name
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.
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...
#define ast_cond_destroy(cond)
struct ast_datastore * ast_datastore_alloc(const struct ast_datastore_info *info, const char *uid)
#define ast_channel_unlock(chan)
static void parse(struct mgcp_request *req)
const char * ast_config_AST_MONITOR_DIR
int ast_closestream(struct ast_filestream *f)
Closes a stream.
static char * handle_cli_mixmonitor(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
#define SAMPLES_PER_FRAME
static const char *const app
Structure used to handle boolean flags.
void ast_autochan_destroy(struct ast_autochan *autochan)
destroy an ast_autochan structure
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...
struct ast_autochan * ast_autochan_setup(struct ast_channel *chan)
set up a new ast_autochan structure
struct ast_audiohook_options options
This structure is allocated by file.c in one chunk, together with buf_size and desc_size bytes of mem...
static void * mixmonitor_thread(void *obj)
#define AST_FORMAT_SLINEAR
Standard Command Line Interface.
int ast_writestream(struct ast_filestream *fs, struct ast_frame *f)
Writes a frame to a stream.
int attribute_pure ast_false(const char *val)
Make sure something is false. Determine if a string containing a boolean value is "false"...
int ast_cli_register_multiple(struct ast_cli_entry *e, int len)
Register multiple commands.
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
struct ast_audiohook * audiohook
char * ast_complete_channels(const char *line, const char *word, int pos, int state, int rpos)
Command completion for the list of active channels.
Data structure associated with a single frame of data.
enum ast_audiohook_status status
#define AST_APP_ARG(name)
Define an application argument.
static struct ast_datastore_info mixmonitor_ds_info
static struct ast_cli_entry cli_mixmonitor[]
#define ast_mutex_init(pmutex)
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
#define ast_mutex_destroy(a)
#define ASTERISK_GPL_KEY
The text the key() function should return.
static struct ast_app_option mixmonitor_opts[128]
struct ast_audiohook audiohook
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
#define ast_audiohook_lock(ah)
Lock an audiohook.
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Asterisk module definitions.
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
struct ast_autochan * autochan
void ast_audiohook_trigger_wait(struct ast_audiohook *audiohook)
Wait for audiohook trigger to be triggered.
int ast_channel_datastore_remove(struct ast_channel *chan, struct ast_datastore *datastore)
Remove a datastore from a channel.
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Structure for mutex and tracking information.
int ast_manager_unregister(char *action)
Unregister a registered manager command.
#define ASTERISK_FILE_VERSION(file, version)
Register/unregister a source code file with the core.
#define AST_APP_OPTION(option, flagno)
Declares an application option that does not accept an argument.
#define ast_mutex_unlock(a)
int ast_mkdir(const char *path, int mode)
Recursively create directory path.
struct ast_module * ast_module_ref(struct ast_module *)
static int load_module(void)