Fri Aug 24 02:27:20 2007

Asterisk developer's documentation


res_monitor.c File Reference

PBX channel monitoring. More...

#include "asterisk.h"
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <libgen.h>
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/logger.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 dependency graph for res_monitor.c:

Go to the source code of this file.

Defines

#define IS_NULL_STRING(string)   ((!(string)) || (ast_strlen_zero((string))))
#define LOCK_IF_NEEDED(lock, needed)
#define UNLOCK_IF_NEEDED(lock, needed)

Enumerations

enum  MONITOR_PAUSING_ACTION { MONITOR_ACTION_PAUSE, MONITOR_ACTION_UNPAUSE }

Functions

 AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS,"Call Monitoring Resource",.load=load_module,.unload=unload_module,)
int ast_monitor_change_fname (struct ast_channel *chan, const char *fname_base, int need_lock)
int ast_monitor_pause (struct ast_channel *chan)
static int ast_monitor_set_state (struct ast_channel *chan, int state)
void ast_monitor_setjoinfiles (struct ast_channel *chan, int turnon)
int ast_monitor_start (struct ast_channel *chan, const char *format_spec, const char *fname_base, int need_lock)
int ast_monitor_stop (struct ast_channel *chan, int need_lock)
int ast_monitor_unpause (struct ast_channel *chan)
 AST_MUTEX_DEFINE_STATIC (monitorlock)
static int change_monitor_action (struct mansession *s, const struct message *m)
static int change_monitor_exec (struct ast_channel *chan, void *data)
static int do_pause_or_unpause (struct mansession *s, const struct message *m, int action)
static const char * get_soxmix_format (const char *format)
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, void *data)
static int start_monitor_action (struct mansession *s, const struct message *m)
static int start_monitor_exec (struct ast_channel *chan, void *data)
static int stop_monitor_action (struct mansession *s, const struct message *m)
static int stop_monitor_exec (struct ast_channel *chan, void *data)
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, void *data)

Variables

static char change_monitor_action_help []
static char * changemonitor_descrip
static char * changemonitor_synopsis = "Change monitoring filename of a channel"
static char * monitor_descrip
static char * monitor_synopsis = "Monitor a channel"
static char pause_monitor_action_help []
static char * pausemonitor_descrip
static char * pausemonitor_synopsis = "Pause monitoring of a channel"
static unsigned long seq = 0
static char start_monitor_action_help []
static char stop_monitor_action_help []
static char * stopmonitor_descrip
static char * stopmonitor_synopsis = "Stop monitoring a channel"
static char unpause_monitor_action_help []
static char * unpausemonitor_descrip
static char * unpausemonitor_synopsis = "Unpause monitoring of a channel"


Detailed Description

PBX channel monitoring.

Author:
Mark Spencer <markster@digium.com>

Definition in file res_monitor.c.


Define Documentation

#define IS_NULL_STRING ( string   )     ((!(string)) || (ast_strlen_zero((string))))

Definition at line 597 of file res_monitor.c.

Referenced by do_pause_or_unpause().

#define LOCK_IF_NEEDED ( lock,
needed   ) 

Value:

do { \
   if (needed) \
      ast_channel_lock(lock); \
   } while(0)

Definition at line 53 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) \
      ast_channel_unlock(lock); \
   } while (0)

Definition at line 58 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

enum MONITOR_PAUSING_ACTION

Enumerator:
MONITOR_ACTION_PAUSE 
MONITOR_ACTION_UNPAUSE 

Definition at line 599 of file res_monitor.c.

00600 {
00601    MONITOR_ACTION_PAUSE,
00602    MONITOR_ACTION_UNPAUSE
00603 };


Function Documentation

AST_MODULE_INFO ( ASTERISK_GPL_KEY  ,
AST_MODFLAG_GLOBAL_SYMBOLS  ,
"Call Monitoring Resource"  ,
load = load_module,
unload = unload_module 
)

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

Definition at line 355 of file res_monitor.c.

References ast_config_AST_MONITOR_DIR, ast_log(), ast_safe_system(), ast_strlen_zero(), ast_channel_monitor::filename_base, ast_channel_monitor::filename_changed, FILENAME_MAX, free, LOCK_IF_NEEDED, LOG_WARNING, ast_channel::monitor, name, strdup, and UNLOCK_IF_NEEDED.

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

00356 {
00357    char tmp[256];
00358    if (ast_strlen_zero(fname_base)) {
00359       ast_log(LOG_WARNING, "Cannot change monitor filename of channel %s to null\n", chan->name);
00360       return -1;
00361    }
00362 
00363    LOCK_IF_NEEDED(chan, need_lock);
00364 
00365    if (chan->monitor) {
00366       int directory = strchr(fname_base, '/') ? 1 : 0;
00367       /* try creating the directory just in case it doesn't exist */
00368       if (directory) {
00369          char *name = strdup(fname_base);
00370          snprintf(tmp, sizeof(tmp), "mkdir -p %s",dirname(name));
00371          free(name);
00372          ast_safe_system(tmp);
00373       }
00374 
00375       snprintf(chan->monitor->filename_base, FILENAME_MAX, "%s/%s", directory ? "" : ast_config_AST_MONITOR_DIR, fname_base);
00376       chan->monitor->filename_changed = 1;
00377    } else {
00378       ast_log(LOG_WARNING, "Cannot change monitor filename of channel %s to %s, monitoring not started\n", chan->name, fname_base);
00379    }
00380 
00381    UNLOCK_IF_NEEDED(chan, need_lock);
00382 
00383    return 0;
00384 }

int ast_monitor_pause ( struct ast_channel chan  ) 

Definition at line 333 of file res_monitor.c.

References AST_MONITOR_PAUSED, and ast_monitor_set_state().

Referenced by do_pause_or_unpause(), and pause_monitor_exec().

00334 {
00335    return ast_monitor_set_state(chan, AST_MONITOR_PAUSED);
00336 }

static int ast_monitor_set_state ( struct ast_channel chan,
int  state 
) [static]

Definition at line 113 of file res_monitor.c.

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

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

00114 {
00115    LOCK_IF_NEEDED(chan, 1);
00116    if (!chan->monitor) {
00117       UNLOCK_IF_NEEDED(chan, 1);
00118       return -1;
00119    }
00120    chan->monitor->state = state;
00121    UNLOCK_IF_NEEDED(chan, 1);
00122    return 0;
00123 }

void ast_monitor_setjoinfiles ( struct ast_channel chan,
int  turnon 
)

Definition at line 591 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().

00592 {
00593    if (chan->monitor)
00594       chan->monitor->joinfiles = turnon;
00595 }

int ast_monitor_start ( struct ast_channel chan,
const char *  format_spec,
const char *  fname_base,
int  need_lock 
)

Definition at line 126 of file res_monitor.c.

References ast_calloc, ast_closestream(), ast_config_AST_MONITOR_DIR, ast_filedelete(), ast_fileexists(), ast_log(), AST_MONITOR_RUNNING, ast_monitor_set_state(), ast_monitor_stop(), ast_mutex_lock(), ast_mutex_unlock(), ast_safe_system(), ast_strdupa, ast_strlen_zero(), ast_writefile(), FILENAME_MAX, free, LOCK_IF_NEEDED, LOG_DEBUG, LOG_WARNING, monitor, ast_channel::monitor, name, pbx_builtin_setvar_helper(), strdup, and UNLOCK_IF_NEEDED.

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

00128 {
00129    int res = 0;
00130    char tmp[256];
00131 
00132    LOCK_IF_NEEDED(chan, need_lock);
00133 
00134    if (!(chan->monitor)) {
00135       struct ast_channel_monitor *monitor;
00136       char *channel_name, *p;
00137 
00138       /* Create monitoring directory if needed */
00139       if (mkdir(ast_config_AST_MONITOR_DIR, 0770) < 0) {
00140          if (errno != EEXIST) {
00141             ast_log(LOG_WARNING, "Unable to create audio monitor directory: %s\n",
00142                strerror(errno));
00143          }
00144       }
00145 
00146       if (!(monitor = ast_calloc(1, sizeof(*monitor)))) {
00147          UNLOCK_IF_NEEDED(chan, need_lock);
00148          return -1;
00149       }
00150 
00151       /* Determine file names */
00152       if (!ast_strlen_zero(fname_base)) {
00153          int directory = strchr(fname_base, '/') ? 1 : 0;
00154          /* try creating the directory just in case it doesn't exist */
00155          if (directory) {
00156             char *name = strdup(fname_base);
00157             snprintf(tmp, sizeof(tmp), "mkdir -p \"%s\"",dirname(name));
00158             free(name);
00159             ast_safe_system(tmp);
00160          }
00161          snprintf(monitor->read_filename, FILENAME_MAX, "%s/%s-in",
00162                   directory ? "" : ast_config_AST_MONITOR_DIR, fname_base);
00163          snprintf(monitor->write_filename, FILENAME_MAX, "%s/%s-out",
00164                   directory ? "" : ast_config_AST_MONITOR_DIR, fname_base);
00165          ast_copy_string(monitor->filename_base, fname_base, sizeof(monitor->filename_base));
00166       } else {
00167          ast_mutex_lock(&monitorlock);
00168          snprintf(monitor->read_filename, FILENAME_MAX, "%s/audio-in-%ld",
00169                   ast_config_AST_MONITOR_DIR, seq);
00170          snprintf(monitor->write_filename, FILENAME_MAX, "%s/audio-out-%ld",
00171                   ast_config_AST_MONITOR_DIR, seq);
00172          seq++;
00173          ast_mutex_unlock(&monitorlock);
00174 
00175          channel_name = ast_strdupa(chan->name);
00176          while ((p = strchr(channel_name, '/'))) {
00177             *p = '-';
00178          }
00179          snprintf(monitor->filename_base, FILENAME_MAX, "%s/%d-%s",
00180                 ast_config_AST_MONITOR_DIR, (int)time(NULL), channel_name);
00181          monitor->filename_changed = 1;
00182       }
00183 
00184       monitor->stop = ast_monitor_stop;
00185 
00186       /* Determine file format */
00187       if (!ast_strlen_zero(format_spec)) {
00188          monitor->format = strdup(format_spec);
00189       } else {
00190          monitor->format = strdup("wav");
00191       }
00192       
00193       /* open files */
00194       if (ast_fileexists(monitor->read_filename, NULL, NULL) > 0) {
00195          ast_filedelete(monitor->read_filename, NULL);
00196       }
00197       if (!(monitor->read_stream = ast_writefile(monitor->read_filename,
00198                   monitor->format, NULL,
00199                   O_CREAT|O_TRUNC|O_WRONLY, 0, 0644))) {
00200          ast_log(LOG_WARNING, "Could not create file %s\n",
00201                   monitor->read_filename);
00202          free(monitor);
00203          UNLOCK_IF_NEEDED(chan, need_lock);
00204          return -1;
00205       }
00206       if (ast_fileexists(monitor->write_filename, NULL, NULL) > 0) {
00207          ast_filedelete(monitor->write_filename, NULL);
00208       }
00209       if (!(monitor->write_stream = ast_writefile(monitor->write_filename,
00210                   monitor->format, NULL,
00211                   O_CREAT|O_TRUNC|O_WRONLY, 0, 0644))) {
00212          ast_log(LOG_WARNING, "Could not create file %s\n",
00213                   monitor->write_filename);
00214          ast_closestream(monitor->read_stream);
00215          free(monitor);
00216          UNLOCK_IF_NEEDED(chan, need_lock);
00217          return -1;
00218       }
00219       chan->monitor = monitor;
00220       ast_monitor_set_state(chan, AST_MONITOR_RUNNING);
00221       /* so we know this call has been monitored in case we need to bill for it or something */
00222       pbx_builtin_setvar_helper(chan, "__MONITORED","true");
00223    } else {
00224       ast_log(LOG_DEBUG,"Cannot start monitoring %s, already monitored\n",
00225                chan->name);
00226       res = -1;
00227    }
00228 
00229    UNLOCK_IF_NEEDED(chan, need_lock);
00230 
00231    return res;
00232 }

int ast_monitor_stop ( struct ast_channel chan,
int  need_lock 
)

Definition at line 252 of file res_monitor.c.

References ast_closestream(), ast_config_AST_MONITOR_DIR, ast_filedelete(), ast_fileexists(), ast_filerename(), ast_log(), ast_safe_system(), ast_strlen_zero(), ast_channel_monitor::filename_base, ast_channel_monitor::filename_changed, FILENAME_MAX, format, ast_channel_monitor::format, free, get_soxmix_format(), ast_channel_monitor::joinfiles, LOCK_IF_NEEDED, LOG_DEBUG, LOG_WARNING, ast_channel::monitor, name, pbx_builtin_getvar_helper(), ast_channel_monitor::read_filename, ast_channel_monitor::read_stream, UNLOCK_IF_NEEDED, ast_channel_monitor::write_filename, and ast_channel_monitor::write_stream.

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

00253 {
00254    int delfiles = 0;
00255 
00256    LOCK_IF_NEEDED(chan, need_lock);
00257 
00258    if (chan->monitor) {
00259       char filename[ FILENAME_MAX ];
00260 
00261       if (chan->monitor->read_stream) {
00262          ast_closestream(chan->monitor->read_stream);
00263       }
00264       if (chan->monitor->write_stream) {
00265          ast_closestream(chan->monitor->write_stream);
00266       }
00267 
00268       if (chan->monitor->filename_changed && !ast_strlen_zero(chan->monitor->filename_base)) {
00269          if (ast_fileexists(chan->monitor->read_filename,NULL,NULL) > 0) {
00270             snprintf(filename, FILENAME_MAX, "%s-in", chan->monitor->filename_base);
00271             if (ast_fileexists(filename, NULL, NULL) > 0) {
00272                ast_filedelete(filename, NULL);
00273             }
00274             ast_filerename(chan->monitor->read_filename, filename, chan->monitor->format);
00275          } else {
00276             ast_log(LOG_WARNING, "File %s not found\n", chan->monitor->read_filename);
00277          }
00278 
00279          if (ast_fileexists(chan->monitor->write_filename,NULL,NULL) > 0) {
00280             snprintf(filename, FILENAME_MAX, "%s-out", chan->monitor->filename_base);
00281             if (ast_fileexists(filename, NULL, NULL) > 0) {
00282                ast_filedelete(filename, NULL);
00283             }
00284             ast_filerename(chan->monitor->write_filename, filename, chan->monitor->format);
00285          } else {
00286             ast_log(LOG_WARNING, "File %s not found\n", chan->monitor->write_filename);
00287          }
00288       }
00289 
00290       if (chan->monitor->joinfiles && !ast_strlen_zero(chan->monitor->filename_base)) {
00291          char tmp[1024];
00292          char tmp2[1024];
00293          const char *format = !strcasecmp(chan->monitor->format,"wav49") ? "WAV" : chan->monitor->format;
00294          char *name = chan->monitor->filename_base;
00295          int directory = strchr(name, '/') ? 1 : 0;
00296          char *dir = directory ? "" : ast_config_AST_MONITOR_DIR;
00297          const char *execute, *execute_args;
00298 
00299          /* Set the execute application */
00300          execute = pbx_builtin_getvar_helper(chan, "MONITOR_EXEC");
00301          if (ast_strlen_zero(execute)) { 
00302             execute = "nice -n 19 soxmix";
00303             format = get_soxmix_format(format);
00304             delfiles = 1;
00305          } 
00306          execute_args = pbx_builtin_getvar_helper(chan, "MONITOR_EXEC_ARGS");
00307          if (ast_strlen_zero(execute_args)) {
00308             execute_args = "";
00309          }
00310          
00311          snprintf(tmp, sizeof(tmp), "%s \"%s/%s-in.%s\" \"%s/%s-out.%s\" \"%s/%s.%s\" %s &", execute, dir, name, format, dir, name, format, dir, name, format,execute_args);
00312          if (delfiles) {
00313             snprintf(tmp2,sizeof(tmp2), "( %s& rm -f \"%s/%s-\"* ) &",tmp, dir ,name); /* remove legs when done mixing */
00314             ast_copy_string(tmp, tmp2, sizeof(tmp));
00315          }
00316          ast_log(LOG_DEBUG,"monitor executing %s\n",tmp);
00317          if (ast_safe_system(tmp) == -1)
00318             ast_log(LOG_WARNING, "Execute of %s failed.\n",tmp);
00319       }
00320       
00321       free(chan->monitor->format);
00322       free(chan->monitor);
00323       chan->monitor = NULL;
00324    }
00325 
00326    UNLOCK_IF_NEEDED(chan, need_lock);
00327 
00328    return 0;
00329 }

int ast_monitor_unpause ( struct ast_channel chan  ) 

Definition at line 339 of file res_monitor.c.

References AST_MONITOR_RUNNING, and ast_monitor_set_state().

Referenced by do_pause_or_unpause(), and unpause_monitor_exec().

00340 {
00341    return ast_monitor_set_state(chan, AST_MONITOR_RUNNING);
00342 }

AST_MUTEX_DEFINE_STATIC ( monitorlock   ) 

static int change_monitor_action ( struct mansession s,
const struct message m 
) [static]

Definition at line 563 of file res_monitor.c.

References ast_channel_unlock, ast_get_channel_by_name_locked(), ast_monitor_change_fname(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), name, and s.

Referenced by load_module().

00564 {
00565    struct ast_channel *c = NULL;
00566    const char *name = astman_get_header(m, "Channel");
00567    const char *fname = astman_get_header(m, "File");
00568    if (ast_strlen_zero(name)) {
00569       astman_send_error(s, m, "No channel specified");
00570       return 0;
00571    }
00572    if (ast_strlen_zero(fname)) {
00573       astman_send_error(s, m, "No filename specified");
00574       return 0;
00575    }
00576    c = ast_get_channel_by_name_locked(name);
00577    if (!c) {
00578       astman_send_error(s, m, "No such channel");
00579       return 0;
00580    }
00581    if (ast_monitor_change_fname(c, fname, 1)) {
00582       astman_send_error(s, m, "Could not change monitored filename of channel");
00583       ast_channel_unlock(c);
00584       return 0;
00585    }
00586    ast_channel_unlock(c);
00587    astman_send_ack(s, m, "Changed monitor filename");
00588    return 0;
00589 }

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

Definition at line 459 of file res_monitor.c.

References ast_monitor_change_fname().

Referenced by load_module().

00460 {
00461    return ast_monitor_change_fname(chan, (const char*)data, 1);
00462 }

static int do_pause_or_unpause ( struct mansession s,
const struct message m,
int  action 
) [static]

Definition at line 605 of file res_monitor.c.

References ast_channel_unlock, ast_get_channel_by_name_locked(), ast_monitor_pause(), ast_monitor_unpause(), astman_get_header(), astman_send_ack(), astman_send_error(), IS_NULL_STRING, MONITOR_ACTION_PAUSE, name, and s.

Referenced by pause_monitor_action(), and unpause_monitor_action().

00606 {
00607    struct ast_channel *c = NULL;
00608    const char *name = astman_get_header(m, "Channel");
00609    
00610    if (IS_NULL_STRING(name)) {
00611       astman_send_error(s, m, "No channel specified");
00612       return -1;
00613    }
00614    
00615    c = ast_get_channel_by_name_locked(name);
00616    if (!c) {
00617       astman_send_error(s, m, "No such channel");
00618       return -1;
00619    }
00620 
00621    if (action == MONITOR_ACTION_PAUSE)
00622       ast_monitor_pause(c);
00623    else
00624       ast_monitor_unpause(c);
00625    
00626    ast_channel_unlock(c);
00627    astman_send_ack(s, m, (action == MONITOR_ACTION_PAUSE ? "Paused monitoring of the channel" : "Unpaused monitoring of the channel"));
00628    return 0;   
00629 }

static const char* get_soxmix_format ( const char *  format  )  [static]

Definition at line 239 of file res_monitor.c.

Referenced by ast_monitor_stop().

00240 {
00241    const char *res = format;
00242 
00243    if (!strcasecmp(format,"ulaw"))
00244       res = "ul";
00245    if (!strcasecmp(format,"alaw"))
00246       res = "al";
00247    
00248    return res;
00249 }

static int load_module ( void   )  [static]

Definition at line 654 of file res_monitor.c.

References ast_manager_register2(), ast_register_application(), 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().

static int pause_monitor_action ( struct mansession s,
const struct message m 
) [static]

Definition at line 637 of file res_monitor.c.

References do_pause_or_unpause(), MONITOR_ACTION_PAUSE, and s.

Referenced by load_module().

00638 {
00639    return do_pause_or_unpause(s, m, MONITOR_ACTION_PAUSE);
00640 }

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

Definition at line 344 of file res_monitor.c.

References ast_monitor_pause().

Referenced by load_module().

00345 {
00346    return ast_monitor_pause(chan);
00347 }

static int start_monitor_action ( struct mansession s,
const struct message m 
) [static]

Definition at line 478 of file res_monitor.c.

References ast_channel_unlock, ast_get_channel_by_name_locked(), ast_monitor_change_fname(), ast_monitor_setjoinfiles(), ast_monitor_start(), ast_strdup, ast_strlen_zero(), ast_true(), astman_get_header(), astman_send_ack(), astman_send_error(), format, name, and s.

Referenced by load_module().

00479 {
00480    struct ast_channel *c = NULL;
00481    const char *name = astman_get_header(m, "Channel");
00482    const char *fname = astman_get_header(m, "File");
00483    const char *format = astman_get_header(m, "Format");
00484    const char *mix = astman_get_header(m, "Mix");
00485    char *d;
00486    
00487    if (ast_strlen_zero(name)) {
00488       astman_send_error(s, m, "No channel specified");
00489       return 0;
00490    }
00491    c = ast_get_channel_by_name_locked(name);
00492    if (!c) {
00493       astman_send_error(s, m, "No such channel");
00494       return 0;
00495    }
00496 
00497    if (ast_strlen_zero(fname)) {
00498       /* No filename base specified, default to channel name as per CLI */    
00499       if (!(fname = ast_strdup(c->name))) {
00500          astman_send_error(s, m, "Could not start monitoring channel");
00501          ast_channel_unlock(c);
00502          return 0;
00503       }
00504       /* Channels have the format technology/channel_name - have to replace that /  */
00505       if ((d = strchr(fname, '/'))) 
00506          *d = '-';
00507    }
00508    
00509    if (ast_monitor_start(c, format, fname, 1)) {
00510       if (ast_monitor_change_fname(c, fname, 1)) {
00511          astman_send_error(s, m, "Could not start monitoring channel");
00512          ast_channel_unlock(c);
00513          return 0;
00514       }
00515    }
00516 
00517    if (ast_true(mix)) {
00518       ast_monitor_setjoinfiles(c, 1);
00519    }
00520 
00521    ast_channel_unlock(c);
00522    astman_send_ack(s, m, "Started monitoring channel");
00523    return 0;
00524 }

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

Definition at line 386 of file res_monitor.c.

References ast_cdr_alloc(), ast_cdr_setuserfield(), ast_monitor_change_fname(), ast_monitor_setjoinfiles(), ast_monitor_start(), ast_strdupa, ast_strlen_zero(), ast_channel::cdr, format, ast_channel_monitor::joinfiles, pbx_builtin_setvar_helper(), and urlprefix.

Referenced by load_module().

00387 {
00388    char *arg = NULL;
00389    char *format = NULL;
00390    char *fname_base = NULL;
00391    char *options = NULL;
00392    char *delay = NULL;
00393    char *urlprefix = NULL;
00394    char tmp[256];
00395    int joinfiles = 0;
00396    int waitforbridge = 0;
00397    int res = 0;
00398    
00399    /* Parse arguments. */
00400    if (!ast_strlen_zero((char*)data)) {
00401       arg = ast_strdupa((char*)data);
00402       format = arg;
00403       fname_base = strchr(arg, '|');
00404       if (fname_base) {
00405          *fname_base = 0;
00406          fname_base++;
00407          if ((options = strchr(fname_base, '|'))) {
00408             *options = 0;
00409             options++;
00410             if (strchr(options, 'm'))
00411                joinfiles = 1;
00412             if (strchr(options, 'b'))
00413                waitforbridge = 1;
00414          }
00415       }
00416       arg = strchr(format,':');
00417       if (arg) {
00418          *arg++ = 0;
00419          urlprefix = arg;
00420       }
00421    }
00422    if (urlprefix) {
00423       snprintf(tmp,sizeof(tmp) - 1,"%s/%s.%s",urlprefix,fname_base,
00424          ((strcmp(format,"gsm")) ? "wav" : "gsm"));
00425       if (!chan->cdr && !(chan->cdr = ast_cdr_alloc()))
00426          return -1;
00427       ast_cdr_setuserfield(chan, tmp);
00428    }
00429    if (waitforbridge) {
00430       /* We must remove the "b" option if listed.  In principle none of
00431          the following could give NULL results, but we check just to
00432          be pedantic. Reconstructing with checks for 'm' option does not
00433          work if we end up adding more options than 'm' in the future. */
00434       delay = ast_strdupa(data);
00435       options = strrchr(delay, '|');
00436       if (options) {
00437          arg = strchr(options, 'b');
00438          if (arg) {
00439             *arg = 'X';
00440             pbx_builtin_setvar_helper(chan,"AUTO_MONITOR",delay);
00441          }
00442       }
00443       return 0;
00444    }
00445 
00446    res = ast_monitor_start(chan, format, fname_base, 1);
00447    if (res < 0)
00448       res = ast_monitor_change_fname(chan, fname_base, 1);
00449    ast_monitor_setjoinfiles(chan, joinfiles);
00450 
00451    return res;
00452 }

static int stop_monitor_action ( struct mansession s,
const struct message m 
) [static]

Definition at line 531 of file res_monitor.c.

References ast_channel_unlock, ast_get_channel_by_name_locked(), ast_monitor_stop(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), name, and s.

Referenced by load_module().

00532 {
00533    struct ast_channel *c = NULL;
00534    const char *name = astman_get_header(m, "Channel");
00535    int res;
00536    if (ast_strlen_zero(name)) {
00537       astman_send_error(s, m, "No channel specified");
00538       return 0;
00539    }
00540    c = ast_get_channel_by_name_locked(name);
00541    if (!c) {
00542       astman_send_error(s, m, "No such channel");
00543       return 0;
00544    }
00545    res = ast_monitor_stop(c, 1);
00546    ast_channel_unlock(c);
00547    if (res) {
00548       astman_send_error(s, m, "Could not stop monitoring channel");
00549       return 0;
00550    }
00551    astman_send_ack(s, m, "Stopped monitoring channel");
00552    return 0;
00553 }

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

Definition at line 454 of file res_monitor.c.

References ast_monitor_stop().

Referenced by load_module().

00455 {
00456    return ast_monitor_stop(chan, 1);
00457 }

static int unload_module ( void   )  [static]

Definition at line 670 of file res_monitor.c.

References ast_manager_unregister(), and ast_unregister_application().

00671 {
00672    ast_unregister_application("Monitor");
00673    ast_unregister_application("StopMonitor");
00674    ast_unregister_application("ChangeMonitor");
00675    ast_unregister_application("PauseMonitor");
00676    ast_unregister_application("UnpauseMonitor");
00677    ast_manager_unregister("Monitor");
00678    ast_manager_unregister("StopMonitor");
00679    ast_manager_unregister("ChangeMonitor");
00680    ast_manager_unregister("PauseMonitor");
00681    ast_manager_unregister("UnpauseMonitor");
00682 
00683    return 0;
00684 }

static int unpause_monitor_action ( struct mansession s,
const struct message m 
) [static]

Definition at line 648 of file res_monitor.c.

References do_pause_or_unpause(), and s.

Referenced by load_module().

00649 {
00650    return do_pause_or_unpause(s, m, MONITOR_ACTION_UNPAUSE);
00651 }

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

Definition at line 349 of file res_monitor.c.

References ast_monitor_unpause().

Referenced by load_module().

00350 {
00351    return ast_monitor_unpause(chan);
00352 }


Variable Documentation

char change_monitor_action_help[] [static]

Definition at line 555 of file res_monitor.c.

char* changemonitor_descrip [static]

Initial value:

 "ChangeMonitor(filename_base)\n"
   "Changes monitoring filename of a channel. Has no effect if the channel is not monitored\n"
   "The argument is the new filename base to use for monitoring this channel.\n"

Definition at line 98 of file res_monitor.c.

char* changemonitor_synopsis = "Change monitoring filename of a channel" [static]

Definition at line 96 of file res_monitor.c.

char* monitor_descrip [static]

Definition at line 67 of file res_monitor.c.

char* monitor_synopsis = "Monitor a channel" [static]

Definition at line 65 of file res_monitor.c.

char pause_monitor_action_help[] [static]

Initial value:

   "Description: The 'PauseMonitor' action may be used to temporarily stop the\n"
   " recording of a channel.  The following parameters may\n"
   " be used to control this:\n"
   "  Channel     - Required.  Used to specify the channel to record.\n"

Definition at line 631 of file res_monitor.c.

char* pausemonitor_descrip [static]

Initial value:

 "PauseMonitor\n"
   "Pauses monitoring of a channel until it is re-enabled by a call to UnpauseMonitor.\n"

Definition at line 104 of file res_monitor.c.

char* pausemonitor_synopsis = "Pause monitoring of a channel" [static]

Definition at line 102 of file res_monitor.c.

unsigned long seq = 0 [static]

Definition at line 63 of file res_monitor.c.

char start_monitor_action_help[] [static]

Definition at line 464 of file res_monitor.c.

char stop_monitor_action_help[] [static]

Initial value:

"Description: The 'StopMonitor' action may be used to end a previously\n"
"  started 'Monitor' action.  The only parameter is 'Channel', the name\n"
"  of the channel monitored.\n"

Definition at line 526 of file res_monitor.c.

char* stopmonitor_descrip [static]

Initial value:

 "StopMonitor\n"
   "Stops monitoring a channel. Has no effect if the channel is not monitored\n"

Definition at line 93 of file res_monitor.c.

char* stopmonitor_synopsis = "Stop monitoring a channel" [static]

Definition at line 91 of file res_monitor.c.

char unpause_monitor_action_help[] [static]

Initial value:

   "Description: The 'UnpauseMonitor' action may be used to re-enable recording\n"
   "  of a channel after calling PauseMonitor.  The following parameters may\n"
   "  be used to control this:\n"
   "  Channel     - Required.  Used to specify the channel to record.\n"

Definition at line 642 of file res_monitor.c.

char* unpausemonitor_descrip [static]

Initial value:

 "UnpauseMonitor\n"
   "Unpauses monitoring of a channel on which monitoring had\n"
   "previously been paused with PauseMonitor.\n"

Definition at line 109 of file res_monitor.c.

char* unpausemonitor_synopsis = "Unpause monitoring of a channel" [static]

Definition at line 107 of file res_monitor.c.


Generated on Fri Aug 24 02:27:20 2007 for Asterisk - the Open Source PBX by  doxygen 1.5.1