Wed Jan 8 2020 09:50:19

Asterisk developer's documentation


res_monitor.c File Reference

PBX channel monitoring. More...

#include "asterisk.h"
#include <sys/stat.h>
#include <libgen.h>
#include "asterisk/paths.h"
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/file.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/manager.h"
#include "asterisk/cli.h"
#include "asterisk/monitor.h"
#include "asterisk/app.h"
#include "asterisk/utils.h"
#include "asterisk/config.h"
#include "asterisk/options.h"

Go to the source code of this file.

Macros

#define AST_API_MODULE
 
#define LOCK_IF_NEEDED(lock, needed)
 
#define UNLOCK_IF_NEEDED(lock, needed)
 

Enumerations

enum  MONITOR_PAUSING_ACTION { MONITOR_ACTION_PAUSE, MONITOR_ACTION_UNPAUSE }
 

Functions

static void __reg_module (void)
 
static void __unreg_module (void)
 
int AST_OPTIONAL_API_NAME() ast_monitor_change_fname (struct ast_channel *chan, const char *fname_base, int need_lock)
 Change monitored filename of channel. More...
 
int AST_OPTIONAL_API_NAME() ast_monitor_pause (struct ast_channel *chan)
 Pause monitoring of channel. More...
 
static int ast_monitor_set_state (struct ast_channel *chan, int state)
 Change state of monitored channel. More...
 
void AST_OPTIONAL_API_NAME() ast_monitor_setjoinfiles (struct ast_channel *chan, int turnon)
 
int AST_OPTIONAL_API_NAME() ast_monitor_start (struct ast_channel *chan, const char *format_spec, const char *fname_base, int need_lock, int stream_action)
 Start monitoring a channel. More...
 
int AST_OPTIONAL_API_NAME() ast_monitor_stop (struct ast_channel *chan, int need_lock)
 Stop monitoring channel. More...
 
int AST_OPTIONAL_API_NAME() ast_monitor_unpause (struct ast_channel *chan)
 Unpause monitoring of channel. More...
 
static int change_monitor_action (struct mansession *s, const struct message *m)
 Change filename of a monitored channel by manager connection. More...
 
static int change_monitor_exec (struct ast_channel *chan, const char *data)
 Wrapper function. More...
 
static int do_pause_or_unpause (struct mansession *s, const struct message *m, int action)
 
static const char * get_soxmix_format (const char *format)
 Get audio format. More...
 
static int load_module (void)
 
static int pause_monitor_action (struct mansession *s, const struct message *m)
 
static int pause_monitor_exec (struct ast_channel *chan, const char *data)
 Wrapper for ast_monitor_pause. More...
 
static int start_monitor_action (struct mansession *s, const struct message *m)
 Start monitoring a channel by manager connection. More...
 
static int start_monitor_exec (struct ast_channel *chan, const char *data)
 Start monitor. More...
 
static int stop_monitor_action (struct mansession *s, const struct message *m)
 Stop monitoring a channel by manager connection. More...
 
static int stop_monitor_exec (struct ast_channel *chan, const char *data)
 Wrapper function. More...
 
static int unload_module (void)
 
static int unpause_monitor_action (struct mansession *s, const struct message *m)
 
static int unpause_monitor_exec (struct ast_channel *chan, const char *data)
 Wrapper for ast_monitor_unpause. More...
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "Call Monitoring Resource" , .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_CHANNEL_DEPEND, }
 
static struct ast_module_infoast_module_info = &__mod_info
 
static ast_mutex_t monitorlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
 
static unsigned long seq = 0
 

Detailed Description

PBX channel monitoring.

Author
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m

Definition in file res_monitor.c.

Macro Definition Documentation

#define AST_API_MODULE

Definition at line 45 of file res_monitor.c.

#define LOCK_IF_NEEDED (   lock,
  needed 
)
Value:
do { \
if (needed) \
} while(0)
#define ast_channel_lock(chan)
Definition: channel.h:2466
ast_mutex_t lock
Definition: app_meetme.c:964
if(yyss+yystacksize-1<=yyssp)
Definition: ast_expr2.c:1874

Definition at line 248 of file res_monitor.c.

Referenced by ast_monitor_change_fname(), ast_monitor_set_state(), ast_monitor_start(), and ast_monitor_stop().

#define UNLOCK_IF_NEEDED (   lock,
  needed 
)
Value:
do { \
if (needed) \
} while (0)
ast_mutex_t lock
Definition: app_meetme.c:964
#define ast_channel_unlock(chan)
Definition: channel.h:2467
if(yyss+yystacksize-1<=yyssp)
Definition: ast_expr2.c:1874

Definition at line 253 of file res_monitor.c.

Referenced by ast_monitor_change_fname(), ast_monitor_set_state(), ast_monitor_start(), and ast_monitor_stop().

Enumeration Type Documentation

Enumerator
MONITOR_ACTION_PAUSE 
MONITOR_ACTION_UNPAUSE 

Definition at line 873 of file res_monitor.c.

Function Documentation

static void __reg_module ( void  )
static

Definition at line 954 of file res_monitor.c.

static void __unreg_module ( void  )
static

Definition at line 954 of file res_monitor.c.

int AST_OPTIONAL_API_NAME() ast_monitor_change_fname ( struct ast_channel chan,
const char *  fname_base,
int  need_lock 
)

Change monitored filename of channel.

Parameters
chan
fname_basenew filename
need_lock
Return values
0on success.
-1on failure.
Note
We cannot just compare filenames, due to symlinks, relative paths, and other possible filesystem issues. We could use realpath(3), but its use is discouraged. However, if we try to create the same file from two different paths, the second will fail, and so we have our notification that the filenames point to the same path.

Remember, also, that we're using the basename of the file (i.e. the file without the format suffix), so it does not already exist and we aren't interfering with the recording itself.

Definition at line 566 of file res_monitor.c.

References ast_config_AST_MONITOR_DIR, ast_copy_string(), ast_debug, ast_log(), ast_mkdir(), ast_strdupa, ast_strlen_zero(), doexit, errno, ast_channel_monitor::filename_base, ast_channel_monitor::filename_changed, LOCK_IF_NEEDED, LOG_ERROR, LOG_WARNING, ast_channel::monitor, name, ast_channel::name, and UNLOCK_IF_NEEDED.

Referenced by change_monitor_action(), change_monitor_exec(), start_monitor_action(), and start_monitor_exec().

567 {
568  if (ast_strlen_zero(fname_base)) {
569  ast_log(LOG_WARNING, "Cannot change monitor filename of channel %s to null\n", chan->name);
570  return -1;
571  }
572 
573  LOCK_IF_NEEDED(chan, need_lock);
574 
575  if (chan->monitor) {
576  int directory = strchr(fname_base, '/') ? 1 : 0;
577  const char *absolute = *fname_base == '/' ? "" : ast_config_AST_MONITOR_DIR;
578  const char *absolute_suffix = *fname_base == '/' ? "" : "/";
579  char tmpstring[sizeof(chan->monitor->filename_base)] = "";
580  int i, fd[2] = { -1, -1 }, doexit = 0;
581 
582  /* before continuing, see if we're trying to rename the file to itself... */
583  snprintf(tmpstring, sizeof(tmpstring), "%s%s%s", absolute, absolute_suffix, fname_base);
584 
585  /* try creating the directory just in case it doesn't exist */
586  if (directory) {
587  char *name = ast_strdupa(tmpstring);
588  ast_mkdir(dirname(name), 0777);
589  }
590 
591  /*!
592  * \note We cannot just compare filenames, due to symlinks, relative
593  * paths, and other possible filesystem issues. We could use
594  * realpath(3), but its use is discouraged. However, if we try to
595  * create the same file from two different paths, the second will
596  * fail, and so we have our notification that the filenames point to
597  * the same path.
598  *
599  * Remember, also, that we're using the basename of the file (i.e.
600  * the file without the format suffix), so it does not already exist
601  * and we aren't interfering with the recording itself.
602  */
603  ast_debug(2, "comparing tmpstring %s to filename_base %s\n", tmpstring, chan->monitor->filename_base);
604 
605  if ((fd[0] = open(tmpstring, O_CREAT | O_WRONLY, 0644)) < 0 ||
606  (fd[1] = open(chan->monitor->filename_base, O_CREAT | O_EXCL | O_WRONLY, 0644)) < 0) {
607  if (fd[0] < 0) {
608  ast_log(LOG_ERROR, "Unable to compare filenames: %s\n", strerror(errno));
609  } else {
610  ast_debug(2, "No need to rename monitor filename to itself\n");
611  }
612  doexit = 1;
613  }
614 
615  /* Cleanup temporary files */
616  for (i = 0; i < 2; i++) {
617  if (fd[i] >= 0) {
618  while (close(fd[i]) < 0 && errno == EINTR);
619  }
620  }
621  unlink(tmpstring);
622  /* if previous monitor file existed in a subdirectory, the directory will not be removed */
623  unlink(chan->monitor->filename_base);
624 
625  if (doexit) {
626  UNLOCK_IF_NEEDED(chan, need_lock);
627  return 0;
628  }
629 
630  ast_copy_string(chan->monitor->filename_base, tmpstring, sizeof(chan->monitor->filename_base));
631  chan->monitor->filename_changed = 1;
632  } else {
633  ast_log(LOG_WARNING, "Cannot change monitor filename of channel %s to %s, monitoring not started\n", chan->name, fname_base);
634  }
635 
636  UNLOCK_IF_NEEDED(chan, need_lock);
637 
638  return 0;
639 }
#define UNLOCK_IF_NEEDED(lock, needed)
Definition: res_monitor.c:253
#define LOG_WARNING
Definition: logger.h:144
char filename_base[FILENAME_MAX]
Definition: monitor.h:45
#define LOCK_IF_NEEDED(lock, needed)
Definition: res_monitor.c:248
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
const int fd
Definition: cli.h:153
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static int doexit
Definition: db.c:113
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
#define LOG_ERROR
Definition: logger.h:155
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
int errno
static const char name[]
const char * ast_config_AST_MONITOR_DIR
Definition: asterisk.c:260
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
struct ast_channel_monitor * monitor
Definition: channel.h:769
int ast_mkdir(const char *path, int mode)
Recursively create directory path.
Definition: utils.c:2151
int AST_OPTIONAL_API_NAME() ast_monitor_pause ( struct ast_channel chan)

Pause monitoring of channel.

Definition at line 535 of file res_monitor.c.

References AST_MONITOR_PAUSED, and ast_monitor_set_state().

Referenced by do_pause_or_unpause(), and pause_monitor_exec().

536 {
538 }
static int ast_monitor_set_state(struct ast_channel *chan, int state)
Change state of monitored channel.
Definition: res_monitor.c:267
static int ast_monitor_set_state ( struct ast_channel chan,
int  state 
)
static

Change state of monitored channel.

Parameters
chan
statemonitor state
Return values
0on success.
-1on failure.

Definition at line 267 of file res_monitor.c.

References LOCK_IF_NEEDED, ast_channel::monitor, ast_channel_monitor::state, state, and UNLOCK_IF_NEEDED.

Referenced by ast_monitor_pause(), ast_monitor_start(), and ast_monitor_unpause().

268 {
269  LOCK_IF_NEEDED(chan, 1);
270  if (!chan->monitor) {
271  UNLOCK_IF_NEEDED(chan, 1);
272  return -1;
273  }
274  chan->monitor->state = state;
275  UNLOCK_IF_NEEDED(chan, 1);
276  return 0;
277 }
enum sip_cc_notify_state state
Definition: chan_sip.c:842
#define UNLOCK_IF_NEEDED(lock, needed)
Definition: res_monitor.c:253
#define LOCK_IF_NEEDED(lock, needed)
Definition: res_monitor.c:248
struct ast_channel_monitor * monitor
Definition: channel.h:769
enum AST_MONITORING_STATE state
Definition: monitor.h:49
void AST_OPTIONAL_API_NAME() ast_monitor_setjoinfiles ( struct ast_channel chan,
int  turnon 
)

Definition at line 867 of file res_monitor.c.

References ast_channel_monitor::joinfiles, and ast_channel::monitor.

Referenced by __agent_start_monitoring(), start_monitor_action(), start_monitor_exec(), and try_calling().

868 {
869  if (chan->monitor)
870  chan->monitor->joinfiles = turnon;
871 }
struct ast_channel_monitor * monitor
Definition: channel.h:769
int AST_OPTIONAL_API_NAME() ast_monitor_start ( struct ast_channel chan,
const char *  format_spec,
const char *  fname_base,
int  need_lock,
int  stream_action 
)

Start monitoring a channel.

Parameters
chanast_channel struct to record
format_specfile format to use for recording
fname_basefilename base to record to
need_lockwhether to lock the channel mutex
stream_actionwhether to record the input and/or output streams. X_REC_IN | X_REC_OUT is most often used Creates the file to record, if no format is specified it assumes WAV It also sets channel variable __MONITORED=yes
Return values
0on success
-1on failure

Definition at line 290 of file res_monitor.c.

References ast_calloc, ast_closestream(), ast_config_AST_MONITOR_DIR, ast_debug, AST_FILE_MODE, ast_filedelete(), ast_fileexists(), ast_free, ast_log(), ast_manager_event, ast_mkdir(), AST_MONITOR_RUNNING, ast_monitor_set_state(), ast_monitor_stop(), ast_mutex_lock, ast_mutex_unlock, ast_strdup, ast_strdupa, ast_strlen_zero(), ast_writefile(), EVENT_FLAG_CALL, ast_channel_monitor::filename_base, ast_channel_monitor::filename_changed, FILENAME_MAX, ast_channel_monitor::format, LOCK_IF_NEEDED, LOG_WARNING, monitor, ast_channel::monitor, monitorlock, name, ast_channel::name, pbx_builtin_setvar_helper(), ast_channel_monitor::read_filename, ast_channel_monitor::read_stream, ast_channel_monitor::stop, ast_channel::uniqueid, UNLOCK_IF_NEEDED, ast_channel_monitor::write_filename, ast_channel_monitor::write_stream, X_REC_IN, and X_REC_OUT.

Referenced by __agent_start_monitoring(), start_monitor_action(), start_monitor_exec(), and try_calling().

292 {
293  int res = 0;
294 
295  LOCK_IF_NEEDED(chan, need_lock);
296 
297  if (!(chan->monitor)) {
299  char *channel_name, *p;
300 
301  /* Create monitoring directory if needed */
303 
304  if (!(monitor = ast_calloc(1, sizeof(*monitor)))) {
305  UNLOCK_IF_NEEDED(chan, need_lock);
306  return -1;
307  }
308 
309  /* Determine file names */
310  if (!ast_strlen_zero(fname_base)) {
311  int directory = strchr(fname_base, '/') ? 1 : 0;
312  const char *absolute = *fname_base == '/' ? "" : ast_config_AST_MONITOR_DIR;
313  const char *absolute_suffix = *fname_base == '/' ? "" : "/";
314 
315  snprintf(monitor->read_filename, FILENAME_MAX, "%s%s%s-in",
316  absolute, absolute_suffix, fname_base);
317  snprintf(monitor->write_filename, FILENAME_MAX, "%s%s%s-out",
318  absolute, absolute_suffix, fname_base);
319  snprintf(monitor->filename_base, FILENAME_MAX, "%s%s%s",
320  absolute, absolute_suffix, fname_base);
321 
322  /* try creating the directory just in case it doesn't exist */
323  if (directory) {
324  char *name = ast_strdupa(monitor->filename_base);
325  ast_mkdir(dirname(name), 0777);
326  }
327  } else {
329  snprintf(monitor->read_filename, FILENAME_MAX, "%s/audio-in-%lu",
331  snprintf(monitor->write_filename, FILENAME_MAX, "%s/audio-out-%lu",
333  seq++;
335 
336  /* Replace all '/' chars from the channel name with '-' chars. */
337  channel_name = ast_strdupa(chan->name);
338  for (p = channel_name; (p = strchr(p, '/')); ) {
339  *p = '-';
340  }
341 
342  snprintf(monitor->filename_base, FILENAME_MAX, "%s/%d-%s",
343  ast_config_AST_MONITOR_DIR, (int)time(NULL), channel_name);
344  monitor->filename_changed = 1;
345  }
346 
347  monitor->stop = ast_monitor_stop;
348 
349  /* Determine file format */
350  if (!ast_strlen_zero(format_spec)) {
351  monitor->format = ast_strdup(format_spec);
352  } else {
353  monitor->format = ast_strdup("wav");
354  }
355 
356  /* open files */
357  if (stream_action & X_REC_IN) {
358  if (ast_fileexists(monitor->read_filename, NULL, NULL) > 0)
359  ast_filedelete(monitor->read_filename, NULL);
360  if (!(monitor->read_stream = ast_writefile(monitor->read_filename,
361  monitor->format, NULL,
362  O_CREAT|O_TRUNC|O_WRONLY, 0, AST_FILE_MODE))) {
363  ast_log(LOG_WARNING, "Could not create file %s\n",
364  monitor->read_filename);
365  ast_free(monitor);
366  UNLOCK_IF_NEEDED(chan, need_lock);
367  return -1;
368  }
369  } else
370  monitor->read_stream = NULL;
371 
372  if (stream_action & X_REC_OUT) {
373  if (ast_fileexists(monitor->write_filename, NULL, NULL) > 0) {
374  ast_filedelete(monitor->write_filename, NULL);
375  }
376  if (!(monitor->write_stream = ast_writefile(monitor->write_filename,
377  monitor->format, NULL,
378  O_CREAT|O_TRUNC|O_WRONLY, 0, AST_FILE_MODE))) {
379  ast_log(LOG_WARNING, "Could not create file %s\n",
380  monitor->write_filename);
381  if (monitor->read_stream) {
382  ast_closestream(monitor->read_stream);
383  }
384  ast_free(monitor);
385  UNLOCK_IF_NEEDED(chan, need_lock);
386  return -1;
387  }
388  } else
389  monitor->write_stream = NULL;
390 
391  chan->monitor = monitor;
393  /* so we know this call has been monitored in case we need to bill for it or something */
394  pbx_builtin_setvar_helper(chan, "__MONITORED","true");
395 
396  ast_manager_event(chan, EVENT_FLAG_CALL, "MonitorStart",
397  "Channel: %s\r\n"
398  "Uniqueid: %s\r\n",
399  chan->name,
400  chan->uniqueid);
401  } else {
402  ast_debug(1,"Cannot start monitoring %s, already monitored\n", chan->name);
403  res = -1;
404  }
405 
406  UNLOCK_IF_NEEDED(chan, need_lock);
407 
408  return res;
409 }
#define X_REC_IN
Definition: monitor.h:35
char read_filename[FILENAME_MAX]
Definition: monitor.h:43
static int ast_monitor_set_state(struct ast_channel *chan, int state)
Change state of monitored channel.
Definition: res_monitor.c:267
const ast_string_field uniqueid
Definition: channel.h:787
#define ast_strdup(a)
Definition: astmm.h:109
#define UNLOCK_IF_NEEDED(lock, needed)
Definition: res_monitor.c:253
#define LOG_WARNING
Definition: logger.h:144
static ast_mutex_t monitorlock
Definition: res_monitor.c:246
char filename_base[FILENAME_MAX]
Definition: monitor.h:45
#define EVENT_FLAG_CALL
Definition: manager.h:72
int(* stop)(struct ast_channel *chan, int need_lock)
Definition: monitor.h:50
#define LOCK_IF_NEEDED(lock, needed)
Definition: res_monitor.c:248
#define ast_mutex_lock(a)
Definition: lock.h:155
int ast_filedelete(const char *filename, const char *fmt)
Deletes a file.
Definition: file.c:931
char write_filename[FILENAME_MAX]
Definition: monitor.h:44
#define AST_FILE_MODE
Definition: asterisk.h:36
#define X_REC_OUT
Definition: monitor.h:36
#define ast_manager_event(chan, category, event, contents,...)
Definition: manager.h:221
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define FILENAME_MAX
Definition: private.h:207
int ast_monitor_stop(struct ast_channel *chan, int need_lock)
Stop monitoring channel.
Definition: res_monitor.c:437
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
static unsigned int monitor
Definition: chan_phone.c:108
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
struct ast_filestream * read_stream
Definition: monitor.h:41
static const char name[]
#define ast_free(a)
Definition: astmm.h:97
const char * ast_config_AST_MONITOR_DIR
Definition: asterisk.c:260
struct ast_filestream * write_stream
Definition: monitor.h:42
int ast_closestream(struct ast_filestream *f)
Closes a stream.
Definition: file.c:904
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_calloc(a, b)
Definition: astmm.h:82
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:919
static unsigned long seq
Definition: res_monitor.c:258
struct ast_channel_monitor * monitor
Definition: channel.h:769
#define ast_mutex_unlock(a)
Definition: lock.h:156
int ast_mkdir(const char *path, int mode)
Recursively create directory path.
Definition: utils.c:2151
int AST_OPTIONAL_API_NAME() ast_monitor_stop ( struct ast_channel chan,
int  need_lock 
)

Stop monitoring channel.

Parameters
chan
need_lockStop the recording, close any open streams, mix in/out channels if required
Returns
Always 0

Definition at line 437 of file res_monitor.c.

References ast_closestream(), ast_copy_string(), ast_debug, ast_filedelete(), ast_fileexists(), ast_filerename(), ast_free, ast_log(), ast_manager_event, ast_safe_system(), ast_strlen_zero(), EVENT_FLAG_CALL, ast_channel_monitor::filename_base, ast_channel_monitor::filename_changed, FILENAME_MAX, ast_channel_monitor::format, format, get_soxmix_format(), ast_channel_monitor::joinfiles, LOCK_IF_NEEDED, LOG_WARNING, ast_channel::monitor, ast_channel::name, pbx_builtin_getvar_helper(), pbx_builtin_setvar_helper(), ast_channel_monitor::read_filename, ast_channel_monitor::read_stream, ast_channel::uniqueid, UNLOCK_IF_NEEDED, ast_channel_monitor::write_filename, and ast_channel_monitor::write_stream.

Referenced by ast_monitor_start(), stop_monitor_action(), and stop_monitor_exec().

438 {
439  int delfiles = 0;
440 
441  LOCK_IF_NEEDED(chan, need_lock);
442 
443  if (chan->monitor) {
444  char filename[ FILENAME_MAX ];
445 
446  if (chan->monitor->read_stream) {
448  }
449  if (chan->monitor->write_stream) {
451  }
452 
454  if (chan->monitor->read_stream) {
455  if (ast_fileexists(chan->monitor->read_filename,NULL,NULL) > 0) {
456  snprintf(filename, FILENAME_MAX, "%s-in", chan->monitor->filename_base);
457  if (ast_fileexists(filename, NULL, NULL) > 0) {
458  ast_filedelete(filename, NULL);
459  }
460  ast_filerename(chan->monitor->read_filename, filename, chan->monitor->format);
461  } else {
462  ast_log(LOG_WARNING, "File %s not found\n", chan->monitor->read_filename);
463  }
464  }
465 
466  if (chan->monitor->write_stream) {
467  if (ast_fileexists(chan->monitor->write_filename,NULL,NULL) > 0) {
468  snprintf(filename, FILENAME_MAX, "%s-out", chan->monitor->filename_base);
469  if (ast_fileexists(filename, NULL, NULL) > 0) {
470  ast_filedelete(filename, NULL);
471  }
472  ast_filerename(chan->monitor->write_filename, filename, chan->monitor->format);
473  } else {
474  ast_log(LOG_WARNING, "File %s not found\n", chan->monitor->write_filename);
475  }
476  }
477  }
478 
479  if (chan->monitor->joinfiles && !ast_strlen_zero(chan->monitor->filename_base)) {
480  char tmp[1024];
481  char tmp2[1024];
482  const char *format = !strcasecmp(chan->monitor->format,"wav49") ? "WAV" : chan->monitor->format;
483  char *fname_base = chan->monitor->filename_base;
484  const char *execute, *execute_args;
485  /* at this point, fname_base really is the full path */
486 
487  /* Set the execute application */
488  execute = pbx_builtin_getvar_helper(chan, "MONITOR_EXEC");
489  if (ast_strlen_zero(execute)) {
490 #ifdef HAVE_SOXMIX
491  execute = "nice -n 19 soxmix";
492 #else
493  execute = "nice -n 19 sox -m";
494 #endif
495  format = get_soxmix_format(format);
496  delfiles = 1;
497  }
498  execute_args = pbx_builtin_getvar_helper(chan, "MONITOR_EXEC_ARGS");
499  if (ast_strlen_zero(execute_args)) {
500  execute_args = "";
501  }
502 
503  snprintf(tmp, sizeof(tmp), "%s \"%s-in.%s\" \"%s-out.%s\" \"%s.%s\" %s &",
504  execute, fname_base, format, fname_base, format, fname_base, format,execute_args);
505  if (delfiles) {
506  snprintf(tmp2,sizeof(tmp2), "( %s& rm -f \"%s-\"* ) &",tmp, fname_base); /* remove legs when done mixing */
507  ast_copy_string(tmp, tmp2, sizeof(tmp));
508  }
509  ast_debug(1,"monitor executing %s\n",tmp);
510  if (ast_safe_system(tmp) == -1)
511  ast_log(LOG_WARNING, "Execute of %s failed.\n",tmp);
512  }
513 
514  ast_free(chan->monitor->format);
515  ast_free(chan->monitor);
516  chan->monitor = NULL;
517 
518  ast_manager_event(chan, EVENT_FLAG_CALL, "MonitorStop",
519  "Channel: %s\r\n"
520  "Uniqueid: %s\r\n",
521  chan->name,
522  chan->uniqueid
523  );
524  pbx_builtin_setvar_helper(chan, "MONITORED", NULL);
525  }
526  pbx_builtin_setvar_helper(chan, "AUTO_MONITOR", NULL);
527 
528  UNLOCK_IF_NEEDED(chan, need_lock);
529 
530  return 0;
531 }
char read_filename[FILENAME_MAX]
Definition: monitor.h:43
int ast_safe_system(const char *s)
Safely spawn an external program while closing file descriptors.
Definition: asterisk.c:1077
const ast_string_field uniqueid
Definition: channel.h:787
#define UNLOCK_IF_NEEDED(lock, needed)
Definition: res_monitor.c:253
#define LOG_WARNING
Definition: logger.h:144
char filename_base[FILENAME_MAX]
Definition: monitor.h:45
#define EVENT_FLAG_CALL
Definition: manager.h:72
#define LOCK_IF_NEEDED(lock, needed)
Definition: res_monitor.c:248
int ast_filedelete(const char *filename, const char *fmt)
Deletes a file.
Definition: file.c:931
char write_filename[FILENAME_MAX]
Definition: monitor.h:44
static const char * get_soxmix_format(const char *format)
Get audio format.
Definition: res_monitor.c:418
const char * pbx_builtin_getvar_helper(struct ast_channel *chan, const char *name)
Return a pointer to the value of the corresponding channel variable.
Definition: pbx.c:10475
#define ast_manager_event(chan, category, event, contents,...)
Definition: manager.h:221
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
#define FILENAME_MAX
Definition: private.h:207
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
struct ast_filestream * read_stream
Definition: monitor.h:41
#define ast_free(a)
Definition: astmm.h:97
struct ast_filestream * write_stream
Definition: monitor.h:42
int ast_closestream(struct ast_filestream *f)
Closes a stream.
Definition: file.c:904
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
void ast_copy_string(char *dst, const char *src, size_t size)
Size-limited null-terminating string copy.
Definition: strings.h:223
int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
Checks for the existence of a given file.
Definition: file.c:919
int ast_filerename(const char *oldname, const char *newname, const char *fmt)
Renames a file.
Definition: file.c:936
struct ast_channel_monitor * monitor
Definition: channel.h:769
static snd_pcm_format_t format
Definition: chan_alsa.c:93
int AST_OPTIONAL_API_NAME() ast_monitor_unpause ( struct ast_channel chan)

Unpause monitoring of channel.

Definition at line 541 of file res_monitor.c.

References AST_MONITOR_RUNNING, and ast_monitor_set_state().

Referenced by do_pause_or_unpause(), and unpause_monitor_exec().

542 {
544 }
static int ast_monitor_set_state(struct ast_channel *chan, int state)
Change state of monitored channel.
Definition: res_monitor.c:267
static int change_monitor_action ( struct mansession s,
const struct message m 
)
static

Change filename of a monitored channel by manager connection.

Definition at line 833 of file res_monitor.c.

References AMI_SUCCESS, ast_channel_get_by_name(), ast_channel_unref, ast_monitor_change_fname(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), and name.

Referenced by load_module().

834 {
835  struct ast_channel *c = NULL;
836  const char *name = astman_get_header(m, "Channel");
837  const char *fname = astman_get_header(m, "File");
838 
839  if (ast_strlen_zero(name)) {
840  astman_send_error(s, m, "No channel specified");
841  return AMI_SUCCESS;
842  }
843 
844  if (ast_strlen_zero(fname)) {
845  astman_send_error(s, m, "No filename specified");
846  return AMI_SUCCESS;
847  }
848 
849  if (!(c = ast_channel_get_by_name(name))) {
850  astman_send_error(s, m, "No such channel");
851  return AMI_SUCCESS;
852  }
853 
854  if (ast_monitor_change_fname(c, fname, 1)) {
855  c = ast_channel_unref(c);
856  astman_send_error(s, m, "Could not change monitored filename of channel");
857  return AMI_SUCCESS;
858  }
859 
860  c = ast_channel_unref(c);
861 
862  astman_send_ack(s, m, "Changed monitor filename");
863 
864  return AMI_SUCCESS;
865 }
Main Channel structure associated with a channel.
Definition: channel.h:742
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2502
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:2135
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
int ast_monitor_change_fname(struct ast_channel *chan, const char *fname_base, int need_lock)
Change monitored filename of channel.
Definition: res_monitor.c:566
static const char name[]
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 int change_monitor_exec ( struct ast_channel chan,
const char *  data 
)
static

Wrapper function.

See Also
ast_monitor_change_fname

Definition at line 743 of file res_monitor.c.

References ast_monitor_change_fname().

Referenced by load_module().

744 {
745  return ast_monitor_change_fname(chan, data, 1);
746 }
const char * data
Definition: channel.h:755
int ast_monitor_change_fname(struct ast_channel *chan, const char *fname_base, int need_lock)
Change monitored filename of channel.
Definition: res_monitor.c:566
static int do_pause_or_unpause ( struct mansession s,
const struct message m,
int  action 
)
static

Definition at line 879 of file res_monitor.c.

References AMI_SUCCESS, ast_channel_get_by_name(), ast_channel_unref, ast_monitor_pause(), ast_monitor_unpause(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), MONITOR_ACTION_PAUSE, and name.

Referenced by pause_monitor_action(), and unpause_monitor_action().

880 {
881  struct ast_channel *c = NULL;
882  const char *name = astman_get_header(m, "Channel");
883 
884  if (ast_strlen_zero(name)) {
885  astman_send_error(s, m, "No channel specified");
886  return AMI_SUCCESS;
887  }
888 
889  if (!(c = ast_channel_get_by_name(name))) {
890  astman_send_error(s, m, "No such channel");
891  return AMI_SUCCESS;
892  }
893 
894  if (action == MONITOR_ACTION_PAUSE) {
896  } else {
898  }
899 
900  c = ast_channel_unref(c);
901 
902  astman_send_ack(s, m, (action == MONITOR_ACTION_PAUSE ? "Paused monitoring of the channel" : "Unpaused monitoring of the channel"));
903 
904  return AMI_SUCCESS;
905 }
Main Channel structure associated with a channel.
Definition: channel.h:742
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2502
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:2135
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
int ast_monitor_unpause(struct ast_channel *chan)
Unpause monitoring of channel.
Definition: res_monitor.c:541
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
int ast_monitor_pause(struct ast_channel *chan)
Pause monitoring of channel.
Definition: res_monitor.c:535
static const char name[]
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 const char* get_soxmix_format ( const char *  format)
static

Get audio format.

Parameters
formatrecording format. The file format extensions that Asterisk uses are not all the same as that which soxmix expects. This function ensures that the format used as the extension on the filename is something soxmix will understand.

Definition at line 418 of file res_monitor.c.

References format.

Referenced by ast_monitor_stop().

419 {
420  const char *res = format;
421 
422  if (!strcasecmp(format,"ulaw"))
423  res = "ul";
424  if (!strcasecmp(format,"alaw"))
425  res = "al";
426 
427  return res;
428 }
static snd_pcm_format_t format
Definition: chan_alsa.c:93
static int load_module ( void  )
static

Definition at line 917 of file res_monitor.c.

References ast_manager_register_xml, AST_MODULE_LOAD_SUCCESS, ast_register_application_xml, change_monitor_action(), change_monitor_exec(), EVENT_FLAG_CALL, pause_monitor_action(), pause_monitor_exec(), start_monitor_action(), start_monitor_exec(), stop_monitor_action(), stop_monitor_exec(), unpause_monitor_action(), and unpause_monitor_exec().

918 {
929 
931 }
static int unpause_monitor_exec(struct ast_channel *chan, const char *data)
Wrapper for ast_monitor_unpause.
Definition: res_monitor.c:553
static int change_monitor_exec(struct ast_channel *chan, const char *data)
Wrapper function.
Definition: res_monitor.c:743
static int start_monitor_action(struct mansession *s, const struct message *m)
Start monitoring a channel by manager connection.
Definition: res_monitor.c:749
static int pause_monitor_action(struct mansession *s, const struct message *m)
Definition: res_monitor.c:907
#define EVENT_FLAG_CALL
Definition: manager.h:72
static int unpause_monitor_action(struct mansession *s, const struct message *m)
Definition: res_monitor.c:912
#define ast_manager_register_xml(a, b, c)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:172
static int stop_monitor_action(struct mansession *s, const struct message *m)
Stop monitoring a channel by manager connection.
Definition: res_monitor.c:802
static int change_monitor_action(struct mansession *s, const struct message *m)
Change filename of a monitored channel by manager connection.
Definition: res_monitor.c:833
static int stop_monitor_exec(struct ast_channel *chan, const char *data)
Wrapper function.
Definition: res_monitor.c:737
static int start_monitor_exec(struct ast_channel *chan, const char *data)
Start monitor.
Definition: res_monitor.c:649
static int pause_monitor_exec(struct ast_channel *chan, const char *data)
Wrapper for ast_monitor_pause.
Definition: res_monitor.c:547
#define ast_register_application_xml(app, execute)
Register an application using XML documentation.
Definition: module.h:437
static int pause_monitor_action ( struct mansession s,
const struct message m 
)
static

Definition at line 907 of file res_monitor.c.

References do_pause_or_unpause(), and MONITOR_ACTION_PAUSE.

Referenced by load_module().

908 {
910 }
static int do_pause_or_unpause(struct mansession *s, const struct message *m, int action)
Definition: res_monitor.c:879
static int pause_monitor_exec ( struct ast_channel chan,
const char *  data 
)
static

Wrapper for ast_monitor_pause.

Definition at line 547 of file res_monitor.c.

References ast_monitor_pause().

Referenced by load_module().

548 {
549  return ast_monitor_pause(chan);
550 }
int ast_monitor_pause(struct ast_channel *chan)
Pause monitoring of channel.
Definition: res_monitor.c:535
static int start_monitor_action ( struct mansession s,
const struct message m 
)
static

Start monitoring a channel by manager connection.

Definition at line 749 of file res_monitor.c.

References AMI_SUCCESS, ast_channel_get_by_name(), ast_channel_lock, ast_channel_unlock, ast_channel_unref, ast_monitor_change_fname(), ast_monitor_setjoinfiles(), ast_monitor_start(), ast_strdupa, ast_strlen_zero(), ast_true(), astman_get_header(), astman_send_ack(), astman_send_error(), format, name, ast_channel::name, X_REC_IN, and X_REC_OUT.

Referenced by load_module().

750 {
751  struct ast_channel *c = NULL;
752  const char *name = astman_get_header(m, "Channel");
753  const char *fname = astman_get_header(m, "File");
754  const char *format = astman_get_header(m, "Format");
755  const char *mix = astman_get_header(m, "Mix");
756  char *d;
757 
758  if (ast_strlen_zero(name)) {
759  astman_send_error(s, m, "No channel specified");
760  return AMI_SUCCESS;
761  }
762 
763  if (!(c = ast_channel_get_by_name(name))) {
764  astman_send_error(s, m, "No such channel");
765  return AMI_SUCCESS;
766  }
767 
768  if (ast_strlen_zero(fname)) {
769  /* No filename specified, default to the channel name. */
770  ast_channel_lock(c);
771  fname = ast_strdupa(c->name);
773 
774  /* Replace all '/' chars from the channel name with '-' chars. */
775  for (d = (char *) fname; (d = strchr(d, '/')); ) {
776  *d = '-';
777  }
778  }
779 
780  if (ast_monitor_start(c, format, fname, 1, X_REC_IN | X_REC_OUT)) {
781  if (ast_monitor_change_fname(c, fname, 1)) {
782  astman_send_error(s, m, "Could not start monitoring channel");
783  c = ast_channel_unref(c);
784  return AMI_SUCCESS;
785  }
786  }
787 
788  if (ast_true(mix)) {
789  ast_channel_lock(c);
792  }
793 
794  c = ast_channel_unref(c);
795 
796  astman_send_ack(s, m, "Started monitoring channel");
797 
798  return AMI_SUCCESS;
799 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
#define X_REC_IN
Definition: monitor.h:35
Main Channel structure associated with a channel.
Definition: channel.h:742
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2502
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:2135
void ast_monitor_setjoinfiles(struct ast_channel *chan, int turnon)
Definition: res_monitor.c:867
#define X_REC_OUT
Definition: monitor.h:36
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
int ast_monitor_start(struct ast_channel *chan, const char *format_spec, const char *fname_base, int need_lock, int stream_action)
Start monitoring a channel.
Definition: res_monitor.c:290
int ast_monitor_change_fname(struct ast_channel *chan, const char *fname_base, int need_lock)
Change monitored filename of channel.
Definition: res_monitor.c:566
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is &quot;true&quot;. This function checks to see whether a string passed to it is an indication of an &quot;true&quot; value. It checks to see if the string is &quot;yes&quot;, &quot;true&quot;, &quot;y&quot;, &quot;t&quot;, &quot;on&quot; or &quot;1&quot;.
Definition: utils.c:1533
const ast_string_field name
Definition: channel.h:787
#define ast_channel_unlock(chan)
Definition: channel.h:2467
static const char name[]
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
static snd_pcm_format_t format
Definition: chan_alsa.c:93
#define AMI_SUCCESS
Definition: manager.h:65
static int start_monitor_exec ( struct ast_channel chan,
const char *  data 
)
static

Start monitor.

Parameters
chan
dataarguments passed fname|options
Return values
0on success.
-1on failure.

Definition at line 649 of file res_monitor.c.

References args, AST_APP_ARG, ast_cdr_alloc(), ast_cdr_setuserfield(), ast_channel_lock, ast_channel_unlock, AST_DECLARE_APP_ARGS, ast_log(), ast_monitor_change_fname(), ast_monitor_setjoinfiles(), ast_monitor_start(), AST_STANDARD_APP_ARGS, ast_strdupa, ast_strlen_zero(), ast_channel::cdr, format, LOG_ERROR, LOG_WARNING, parse(), pbx_builtin_setvar_helper(), urlprefix, X_JOIN, X_REC_IN, and X_REC_OUT.

Referenced by load_module().

650 {
651  char *arg;
652  char *options;
653  char *delay;
654  char *urlprefix = NULL;
655  char tmp[256];
656  int stream_action = X_REC_IN | X_REC_OUT;
657  int joinfiles = 0;
658  int waitforbridge = 0;
659  int res = 0;
660  char *parse;
663  AST_APP_ARG(fname_base);
664  AST_APP_ARG(options);
665  );
666 
667  /* Parse arguments. */
668  if (ast_strlen_zero(data)) {
669  ast_log(LOG_ERROR, "Monitor requires an argument\n");
670  return 0;
671  }
672 
673  parse = ast_strdupa(data);
674  AST_STANDARD_APP_ARGS(args, parse);
675 
676  if (!ast_strlen_zero(args.options)) {
677  if (strchr(args.options, 'm'))
678  stream_action |= X_JOIN;
679  if (strchr(args.options, 'b'))
680  waitforbridge = 1;
681  if (strchr(args.options, 'i'))
682  stream_action &= ~X_REC_IN;
683  if (strchr(args.options, 'o'))
684  stream_action &= ~X_REC_OUT;
685  }
686 
687  arg = strchr(args.format, ':');
688  if (arg) {
689  *arg++ = 0;
690  urlprefix = arg;
691  }
692 
693  if (!ast_strlen_zero(urlprefix) && !ast_strlen_zero(args.fname_base)) {
694  snprintf(tmp, sizeof(tmp), "%s/%s.%s", urlprefix, args.fname_base,
695  ((strcmp(args.format, "gsm")) ? "wav" : "gsm"));
696  ast_channel_lock(chan);
697  if (!chan->cdr && !(chan->cdr = ast_cdr_alloc())) {
698  ast_channel_unlock(chan);
699  return -1;
700  }
701  ast_cdr_setuserfield(chan, tmp);
702  ast_channel_unlock(chan);
703  }
704  if (waitforbridge) {
705  /* We must remove the "b" option if listed. In principle none of
706  the following could give NULL results, but we check just to
707  be pedantic. Reconstructing with checks for 'm' option does not
708  work if we end up adding more options than 'm' in the future. */
709  delay = ast_strdupa(data);
710  options = strrchr(delay, ',');
711  if (options) {
712  arg = strchr(options, 'b');
713  if (arg) {
714  *arg = 'X';
715  pbx_builtin_setvar_helper(chan,"AUTO_MONITOR", delay);
716  }
717  }
718  return 0;
719  }
720 
721  res = ast_monitor_start(chan, args.format, args.fname_base, 1, stream_action);
722  if (res < 0)
723  res = ast_monitor_change_fname(chan, args.fname_base, 1);
724 
725  if (stream_action & X_JOIN) {
726  if ((stream_action & X_REC_IN) && (stream_action & X_REC_OUT))
727  joinfiles = 1;
728  else
729  ast_log(LOG_WARNING, "Won't mix streams unless both input and output streams are recorded\n");
730  }
731  ast_monitor_setjoinfiles(chan, joinfiles);
732 
733  return res;
734 }
#define ast_channel_lock(chan)
Definition: channel.h:2466
#define X_REC_IN
Definition: monitor.h:35
#define LOG_WARNING
Definition: logger.h:144
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application&#39;s arguments.
Definition: app.h:572
struct ast_cdr * cdr
Definition: channel.h:766
const char * data
Definition: channel.h:755
void ast_monitor_setjoinfiles(struct ast_channel *chan, int turnon)
Definition: res_monitor.c:867
static char urlprefix[AST_MAX_BUF]
Definition: chan_agent.c:236
#define X_REC_OUT
Definition: monitor.h:36
int ast_cdr_setuserfield(struct ast_channel *chan, const char *userfield)
Set CDR user field for channel (stored in CDR)
Definition: cdr.c:1057
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
int ast_monitor_start(struct ast_channel *chan, const char *format_spec, const char *fname_base, int need_lock, int stream_action)
Start monitoring a channel.
Definition: res_monitor.c:290
int ast_monitor_change_fname(struct ast_channel *chan, const char *fname_base, int need_lock)
Change monitored filename of channel.
Definition: res_monitor.c:566
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
#define LOG_ERROR
Definition: logger.h:155
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 ast_channel_unlock(chan)
Definition: channel.h:2467
static void parse(struct mgcp_request *req)
Definition: chan_mgcp.c:1858
#define X_JOIN
Definition: monitor.h:37
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 snd_pcm_format_t format
Definition: chan_alsa.c:93
struct ast_cdr * ast_cdr_alloc(void)
Allocate a CDR record.
Definition: cdr.c:499
static int stop_monitor_action ( struct mansession s,
const struct message m 
)
static

Stop monitoring a channel by manager connection.

Definition at line 802 of file res_monitor.c.

References AMI_SUCCESS, ast_channel_get_by_name(), ast_channel_unref, ast_monitor_stop(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), and name.

Referenced by load_module().

803 {
804  struct ast_channel *c = NULL;
805  const char *name = astman_get_header(m, "Channel");
806  int res;
807 
808  if (ast_strlen_zero(name)) {
809  astman_send_error(s, m, "No channel specified");
810  return AMI_SUCCESS;
811  }
812 
813  if (!(c = ast_channel_get_by_name(name))) {
814  astman_send_error(s, m, "No such channel");
815  return AMI_SUCCESS;
816  }
817 
818  res = ast_monitor_stop(c, 1);
819 
820  c = ast_channel_unref(c);
821 
822  if (res) {
823  astman_send_error(s, m, "Could not stop monitoring channel");
824  return AMI_SUCCESS;
825  }
826 
827  astman_send_ack(s, m, "Stopped monitoring channel");
828 
829  return AMI_SUCCESS;
830 }
Main Channel structure associated with a channel.
Definition: channel.h:742
#define ast_channel_unref(c)
Decrease channel reference count.
Definition: channel.h:2502
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:2135
const char * astman_get_header(const struct message *m, char *var)
Get header from mananger transaction.
Definition: manager.c:1860
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
int ast_monitor_stop(struct ast_channel *chan, int need_lock)
Stop monitoring channel.
Definition: res_monitor.c:437
static const char name[]
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 int stop_monitor_exec ( struct ast_channel chan,
const char *  data 
)
static

Wrapper function.

See Also
ast_monitor_stop

Definition at line 737 of file res_monitor.c.

References ast_monitor_stop().

Referenced by load_module().

738 {
739  return ast_monitor_stop(chan, 1);
740 }
int ast_monitor_stop(struct ast_channel *chan, int need_lock)
Stop monitoring channel.
Definition: res_monitor.c:437
static int unload_module ( void  )
static

Definition at line 933 of file res_monitor.c.

References ast_manager_unregister(), and ast_unregister_application().

934 {
935  ast_unregister_application("Monitor");
936  ast_unregister_application("StopMonitor");
937  ast_unregister_application("ChangeMonitor");
938  ast_unregister_application("PauseMonitor");
939  ast_unregister_application("UnpauseMonitor");
940  ast_manager_unregister("Monitor");
941  ast_manager_unregister("StopMonitor");
942  ast_manager_unregister("ChangeMonitor");
943  ast_manager_unregister("PauseMonitor");
944  ast_manager_unregister("UnpauseMonitor");
945 
946  return 0;
947 }
int ast_unregister_application(const char *app)
Unregister an application.
Definition: pbx.c:7705
int ast_manager_unregister(char *action)
Unregister a registered manager command.
Definition: manager.c:5355
static int unpause_monitor_action ( struct mansession s,
const struct message m 
)
static

Definition at line 912 of file res_monitor.c.

References do_pause_or_unpause(), and MONITOR_ACTION_UNPAUSE.

Referenced by load_module().

913 {
915 }
static int do_pause_or_unpause(struct mansession *s, const struct message *m, int action)
Definition: res_monitor.c:879
static int unpause_monitor_exec ( struct ast_channel chan,
const char *  data 
)
static

Wrapper for ast_monitor_unpause.

Definition at line 553 of file res_monitor.c.

References ast_monitor_unpause().

Referenced by load_module().

554 {
555  return ast_monitor_unpause(chan);
556 }
int ast_monitor_unpause(struct ast_channel *chan)
Unpause monitoring of channel.
Definition: res_monitor.c:541

Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER , .description = "Call Monitoring Resource" , .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_CHANNEL_DEPEND, }
static

Definition at line 954 of file res_monitor.c.

Definition at line 954 of file res_monitor.c.

ast_mutex_t monitorlock = { PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP , NULL, 1 }
static

Definition at line 246 of file res_monitor.c.

Referenced by ast_monitor_start().

unsigned long seq = 0
static

Definition at line 258 of file res_monitor.c.