Fri Sep 25 19:28:43 2009

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, const char *target_url, const char *target_script, 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 649 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

Enumerator:
MONITOR_ACTION_PAUSE 
MONITOR_ACTION_UNPAUSE 

Definition at line 651 of file res_monitor.c.

00652 {
00653    MONITOR_ACTION_PAUSE,
00654    MONITOR_ACTION_UNPAUSE
00655 };


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 381 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().

00382 {
00383    char tmp[256];
00384    if (ast_strlen_zero(fname_base)) {
00385       ast_log(LOG_WARNING, "Cannot change monitor filename of channel %s to null\n", chan->name);
00386       return -1;
00387    }
00388 
00389    LOCK_IF_NEEDED(chan, need_lock);
00390 
00391    if (chan->monitor) {
00392       int directory = strchr(fname_base, '/') ? 1 : 0;
00393       /* try creating the directory just in case it doesn't exist */
00394       if (directory) {
00395          char *name = strdup(fname_base);
00396          snprintf(tmp, sizeof(tmp), "mkdir -p %s",dirname(name));
00397          free(name);
00398          ast_safe_system(tmp);
00399       }
00400 
00401       snprintf(chan->monitor->filename_base, FILENAME_MAX, "%s/%s", directory ? "" : ast_config_AST_MONITOR_DIR, fname_base);
00402       chan->monitor->filename_changed = 1;
00403    } else {
00404       ast_log(LOG_WARNING, "Cannot change monitor filename of channel %s to %s, monitoring not started\n", chan->name, fname_base);
00405    }
00406 
00407    UNLOCK_IF_NEEDED(chan, need_lock);
00408 
00409    return 0;
00410 }

int ast_monitor_pause ( struct ast_channel chan  ) 

Definition at line 359 of file res_monitor.c.

References AST_MONITOR_PAUSED, and ast_monitor_set_state().

Referenced by do_pause_or_unpause(), and pause_monitor_exec().

00360 {
00361    return ast_monitor_set_state(chan, AST_MONITOR_PAUSED);
00362 }

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

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

00119 {
00120    LOCK_IF_NEEDED(chan, 1);
00121    if (!chan->monitor) {
00122       UNLOCK_IF_NEEDED(chan, 1);
00123       return -1;
00124    }
00125    chan->monitor->state = state;
00126    UNLOCK_IF_NEEDED(chan, 1);
00127    return 0;
00128 }

void ast_monitor_setjoinfiles ( struct ast_channel chan,
int  turnon 
)

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

00644 {
00645    if (chan->monitor)
00646       chan->monitor->joinfiles = turnon;
00647 }

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

Definition at line 131 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(), errno, ast_channel_monitor::filename_base, ast_channel_monitor::filename_changed, FILENAME_MAX, ast_channel_monitor::format, free, LOCK_IF_NEEDED, LOG_DEBUG, LOG_WARNING, monitor, ast_channel::monitor, name, pbx_builtin_setvar_helper(), ast_channel_monitor::read_filename, ast_channel_monitor::read_stream, ast_channel_monitor::stop, strdup, ast_channel_monitor::target_script, ast_channel_monitor::target_url, UNLOCK_IF_NEEDED, ast_channel_monitor::write_filename, and ast_channel_monitor::write_stream.

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

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

int ast_monitor_stop ( struct ast_channel chan,
int  need_lock 
)

Definition at line 262 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(), EVENT_FLAG_CALL, 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_NOTICE, LOG_WARNING, manager_event(), ast_channel::monitor, name, pbx_builtin_getvar_helper(), ast_channel_monitor::read_filename, ast_channel_monitor::read_stream, ast_channel_monitor::target_script, ast_channel_monitor::target_url, 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().

00263 {
00264    int delfiles = 0;
00265 
00266    LOCK_IF_NEEDED(chan, need_lock);
00267 
00268    if (chan->monitor) {
00269       char filename[ FILENAME_MAX ];
00270 
00271       if (chan->monitor->read_stream) {
00272          ast_closestream(chan->monitor->read_stream);
00273       }
00274       if (chan->monitor->write_stream) {
00275          ast_closestream(chan->monitor->write_stream);
00276       }
00277 
00278       if (chan->monitor->filename_changed && !ast_strlen_zero(chan->monitor->filename_base)) {
00279          if (ast_fileexists(chan->monitor->read_filename,NULL,NULL) > 0) {
00280             snprintf(filename, FILENAME_MAX, "%s-in", chan->monitor->filename_base);
00281             if (ast_fileexists(filename, NULL, NULL) > 0) {
00282                ast_filedelete(filename, NULL);
00283             }
00284             ast_filerename(chan->monitor->read_filename, filename, chan->monitor->format);
00285          } else {
00286             ast_log(LOG_WARNING, "File %s not found\n", chan->monitor->read_filename);
00287          }
00288 
00289          if (ast_fileexists(chan->monitor->write_filename,NULL,NULL) > 0) {
00290             snprintf(filename, FILENAME_MAX, "%s-out", chan->monitor->filename_base);
00291             if (ast_fileexists(filename, NULL, NULL) > 0) {
00292                ast_filedelete(filename, NULL);
00293             }
00294             ast_filerename(chan->monitor->write_filename, filename, chan->monitor->format);
00295          } else {
00296             ast_log(LOG_WARNING, "File %s not found\n", chan->monitor->write_filename);
00297          }
00298       }
00299 
00300       if (chan->monitor->joinfiles && !ast_strlen_zero(chan->monitor->filename_base)) {
00301          char tmp[1024];
00302          char tmp2[1024];
00303          char tmp3[1024];
00304          int result;
00305          const char *format = !strcasecmp(chan->monitor->format,"wav49") ? "WAV" : chan->monitor->format;
00306          char *name = chan->monitor->filename_base;
00307          int directory = strchr(name, '/') ? 1 : 0;
00308          char *dir = directory ? "" : ast_config_AST_MONITOR_DIR;
00309          const char *execute, *execute_args;
00310 
00311          /* Set the execute application */
00312          execute = pbx_builtin_getvar_helper(chan, "MONITOR_EXEC");
00313          if (ast_strlen_zero(execute)) {
00314 #ifdef HAVE_SOXMIX
00315             execute = "nice -n 19 soxmix";
00316 #else
00317             execute = "nice -n 19 sox -m";
00318 #endif
00319             format = get_soxmix_format(format);
00320             delfiles = 1;
00321          } 
00322          execute_args = pbx_builtin_getvar_helper(chan, "MONITOR_EXEC_ARGS");
00323          if (ast_strlen_zero(execute_args)) {
00324             execute_args = "";
00325          }
00326          
00327          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);
00328          if (delfiles) {
00329             snprintf(tmp2,sizeof(tmp2), "( %s& rm -f \"%s/%s-\"* ) &",tmp, dir ,name); /* remove legs when done mixing */
00330             ast_copy_string(tmp, tmp2, sizeof(tmp));
00331          }
00332          if (!ast_strlen_zero(chan->monitor->target_script) && !ast_strlen_zero(chan->monitor->target_url)) {
00333             snprintf(tmp3,sizeof(tmp3), "( %s& nice -19 %s \"%s/%s.%s\" \"%s\" ) &",tmp, chan->monitor->target_script , dir, name, format, chan->monitor->target_url); 
00334             ast_copy_string(tmp, tmp3, sizeof(tmp));
00335          }
00336          ast_log(LOG_NOTICE,"monitor executing %s\n",tmp);
00337          result = ast_safe_system(tmp);
00338          if (result == -1)
00339             ast_log(LOG_WARNING, "Execute of %s failed.\n",tmp);
00340          manager_event(EVENT_FLAG_CALL, "MonitorStopped",
00341                                "Channel: %s\r\n"
00342                                "Uniqueid: %s\r\n"
00343                    "Result: %d\r\n"
00344                            ,chan->name, chan->uniqueid, result);
00345       }
00346       
00347       free(chan->monitor->format);
00348       free(chan->monitor);
00349       chan->monitor = NULL;
00350    }
00351 
00352    UNLOCK_IF_NEEDED(chan, need_lock);
00353 
00354    return 0;
00355 }

int ast_monitor_unpause ( struct ast_channel chan  ) 

Definition at line 365 of file res_monitor.c.

References AST_MONITOR_RUNNING, and ast_monitor_set_state().

Referenced by do_pause_or_unpause(), and unpause_monitor_exec().

00366 {
00367    return ast_monitor_set_state(chan, AST_MONITOR_RUNNING);
00368 }

AST_MUTEX_DEFINE_STATIC ( monitorlock   ) 

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

Definition at line 615 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(), and name.

Referenced by load_module().

00616 {
00617    struct ast_channel *c = NULL;
00618    const char *name = astman_get_header(m, "Channel");
00619    const char *fname = astman_get_header(m, "File");
00620    if (ast_strlen_zero(name)) {
00621       astman_send_error(s, m, "No channel specified");
00622       return 0;
00623    }
00624    if (ast_strlen_zero(fname)) {
00625       astman_send_error(s, m, "No filename specified");
00626       return 0;
00627    }
00628    c = ast_get_channel_by_name_locked(name);
00629    if (!c) {
00630       astman_send_error(s, m, "No such channel");
00631       return 0;
00632    }
00633    if (ast_monitor_change_fname(c, fname, 1)) {
00634       astman_send_error(s, m, "Could not change monitored filename of channel");
00635       ast_channel_unlock(c);
00636       return 0;
00637    }
00638    ast_channel_unlock(c);
00639    astman_send_ack(s, m, "Changed monitor filename");
00640    return 0;
00641 }

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

Definition at line 485 of file res_monitor.c.

References ast_monitor_change_fname().

Referenced by load_module().

00486 {
00487    return ast_monitor_change_fname(chan, (const char*)data, 1);
00488 }

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

Definition at line 657 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, and name.

Referenced by pause_monitor_action(), and unpause_monitor_action().

00658 {
00659    struct ast_channel *c = NULL;
00660    const char *name = astman_get_header(m, "Channel");
00661    
00662    if (IS_NULL_STRING(name)) {
00663       astman_send_error(s, m, "No channel specified");
00664       return -1;
00665    }
00666    
00667    c = ast_get_channel_by_name_locked(name);
00668    if (!c) {
00669       astman_send_error(s, m, "No such channel");
00670       return -1;
00671    }
00672 
00673    if (action == MONITOR_ACTION_PAUSE)
00674       ast_monitor_pause(c);
00675    else
00676       ast_monitor_unpause(c);
00677    
00678    ast_channel_unlock(c);
00679    astman_send_ack(s, m, (action == MONITOR_ACTION_PAUSE ? "Paused monitoring of the channel" : "Unpaused monitoring of the channel"));
00680    return 0;   
00681 }

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

Definition at line 249 of file res_monitor.c.

Referenced by ast_monitor_stop().

00250 {
00251    const char *res = format;
00252 
00253    if (!strcasecmp(format,"ulaw"))
00254       res = "ul";
00255    if (!strcasecmp(format,"alaw"))
00256       res = "al";
00257    
00258    return res;
00259 }

static int load_module ( void   )  [static]

Definition at line 706 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 689 of file res_monitor.c.

References do_pause_or_unpause(), and MONITOR_ACTION_PAUSE.

Referenced by load_module().

00690 {
00691    return do_pause_or_unpause(s, m, MONITOR_ACTION_PAUSE);
00692 }

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

Definition at line 370 of file res_monitor.c.

References ast_monitor_pause().

Referenced by load_module().

00371 {
00372    return ast_monitor_pause(chan);
00373 }

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

Definition at line 504 of file res_monitor.c.

References ast_channel_unlock, ast_get_channel_by_name_locked(), ast_get_channel_by_uniqueid_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, and name.

Referenced by load_module().

00505 {
00506    struct ast_channel *c = NULL;
00507    const char *name = astman_get_header(m, "Channel");
00508    const char *fname = astman_get_header(m, "File");
00509    const char *format = astman_get_header(m, "Format");
00510    const char *mix = astman_get_header(m, "Mix");
00511    const char *uniqueid = astman_get_header(m, "Uniqueid");
00512    const char *target_url = astman_get_header(m, "TargetURL");
00513    const char *target_script = astman_get_header(m, "TargetScript");
00514    char *d;
00515    
00516    if (ast_strlen_zero(name) && ast_strlen_zero(uniqueid)) {
00517       astman_send_error(s, m, "No channel/uniqueid specified");
00518       return 0;
00519    }
00520 
00521    if (!ast_strlen_zero(uniqueid)) {
00522        c = ast_get_channel_by_uniqueid_locked(uniqueid);
00523        if (!c) {
00524       astman_send_error(s, m, "No such uniqueid");
00525       return 0;
00526        }
00527    } else {
00528        c = ast_get_channel_by_name_locked(name);
00529        if (!c) {
00530       astman_send_error(s, m, "No such channel");
00531       return 0;
00532        }
00533    }
00534 
00535    if (ast_strlen_zero(fname)) {
00536       /* No filename base specified, default to channel name as per CLI */    
00537       if (!(fname = ast_strdup(c->name))) {
00538          astman_send_error(s, m, "Could not start monitoring channel");
00539          ast_channel_unlock(c);
00540          return 0;
00541       }
00542       /* Channels have the format technology/channel_name - have to replace that /  */
00543       if ((d = strchr(fname, '/'))) 
00544          *d = '-';
00545    }
00546    
00547    if (ast_monitor_start(c, format, fname, target_url, target_script, 1)) {
00548       if (ast_monitor_change_fname(c, fname, 1)) {
00549          astman_send_error(s, m, "Could not start monitoring channel");
00550          ast_channel_unlock(c);
00551          return 0;
00552       }
00553    }
00554 
00555    if (ast_true(mix)) {
00556       ast_monitor_setjoinfiles(c, 1);
00557    }
00558 
00559    ast_channel_unlock(c);
00560    astman_send_ack(s, m, "Started monitoring channel");
00561    return 0;
00562 }

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

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

00413 {
00414    char *arg = NULL;
00415    char *format = NULL;
00416    char *fname_base = NULL;
00417    char *options = NULL;
00418    char *delay = NULL;
00419    char *urlprefix = NULL;
00420    char tmp[256];
00421    int joinfiles = 0;
00422    int waitforbridge = 0;
00423    int res = 0;
00424    
00425    /* Parse arguments. */
00426    if (!ast_strlen_zero((char*)data)) {
00427       arg = ast_strdupa((char*)data);
00428       format = arg;
00429       fname_base = strchr(arg, '|');
00430       if (fname_base) {
00431          *fname_base = 0;
00432          fname_base++;
00433          if ((options = strchr(fname_base, '|'))) {
00434             *options = 0;
00435             options++;
00436             if (strchr(options, 'm'))
00437                joinfiles = 1;
00438             if (strchr(options, 'b'))
00439                waitforbridge = 1;
00440          }
00441       }
00442       arg = strchr(format,':');
00443       if (arg) {
00444          *arg++ = 0;
00445          urlprefix = arg;
00446       }
00447    }
00448    if (urlprefix) {
00449       snprintf(tmp,sizeof(tmp) - 1,"%s/%s.%s",urlprefix,fname_base,
00450          ((strcmp(format,"gsm")) ? "wav" : "gsm"));
00451       if (!chan->cdr && !(chan->cdr = ast_cdr_alloc()))
00452          return -1;
00453       ast_cdr_setuserfield(chan, tmp);
00454    }
00455    if (waitforbridge) {
00456       /* We must remove the "b" option if listed.  In principle none of
00457          the following could give NULL results, but we check just to
00458          be pedantic. Reconstructing with checks for 'm' option does not
00459          work if we end up adding more options than 'm' in the future. */
00460       delay = ast_strdupa(data);
00461       options = strrchr(delay, '|');
00462       if (options) {
00463          arg = strchr(options, 'b');
00464          if (arg) {
00465             *arg = 'X';
00466             pbx_builtin_setvar_helper(chan,"AUTO_MONITOR",delay);
00467          }
00468       }
00469       return 0;
00470    }
00471 
00472    res = ast_monitor_start(chan, format, fname_base, NULL, NULL, 1);
00473    if (res < 0)
00474       res = ast_monitor_change_fname(chan, fname_base, 1);
00475    ast_monitor_setjoinfiles(chan, joinfiles);
00476 
00477    return res;
00478 }

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

Definition at line 569 of file res_monitor.c.

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

Referenced by load_module().

00570 {
00571    struct ast_channel *c = NULL;
00572    const char *name = astman_get_header(m, "Channel");
00573    const char *uniqueid = astman_get_header(m, "Uniqueid");
00574    int res;
00575    if (ast_strlen_zero(name)) {
00576       astman_send_error(s, m, "No channel specified");
00577       return 0;
00578    }
00579    if (ast_strlen_zero(name) && ast_strlen_zero(uniqueid)) {
00580       astman_send_error(s, m, "No channel/uniqueid specified");
00581       return 0;
00582    }
00583    if (!ast_strlen_zero(uniqueid)) {
00584        c = ast_get_channel_by_uniqueid_locked(uniqueid);
00585        if (!c) {
00586       astman_send_error(s, m, "No such uniqueid");
00587       return 0;
00588        }
00589    } else {
00590        c = ast_get_channel_by_name_locked(name);
00591        if (!c) {
00592       astman_send_error(s, m, "No such channel");
00593       return 0;
00594        }
00595    }
00596 
00597    res = ast_monitor_stop(c, 1);
00598    ast_channel_unlock(c);
00599    if (res) {
00600       astman_send_error(s, m, "Could not stop monitoring channel");
00601       return 0;
00602    }
00603    astman_send_ack(s, m, "Stopped monitoring channel");
00604    return 0;
00605 }

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

Definition at line 480 of file res_monitor.c.

References ast_monitor_stop().

Referenced by load_module().

00481 {
00482    return ast_monitor_stop(chan, 1);
00483 }

static int unload_module ( void   )  [static]

Definition at line 722 of file res_monitor.c.

References ast_manager_unregister(), and ast_unregister_application().

00723 {
00724    ast_unregister_application("Monitor");
00725    ast_unregister_application("StopMonitor");
00726    ast_unregister_application("ChangeMonitor");
00727    ast_unregister_application("PauseMonitor");
00728    ast_unregister_application("UnpauseMonitor");
00729    ast_manager_unregister("Monitor");
00730    ast_manager_unregister("StopMonitor");
00731    ast_manager_unregister("ChangeMonitor");
00732    ast_manager_unregister("PauseMonitor");
00733    ast_manager_unregister("UnpauseMonitor");
00734 
00735    return 0;
00736 }

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

Definition at line 700 of file res_monitor.c.

References do_pause_or_unpause(), and MONITOR_ACTION_UNPAUSE.

Referenced by load_module().

00701 {
00702    return do_pause_or_unpause(s, m, MONITOR_ACTION_UNPAUSE);
00703 }

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

Definition at line 375 of file res_monitor.c.

References ast_monitor_unpause().

Referenced by load_module().

00376 {
00377    return ast_monitor_unpause(chan);
00378 }


Variable Documentation

char change_monitor_action_help[] [static]

Definition at line 607 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 103 of file res_monitor.c.

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

Definition at line 101 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 683 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 109 of file res_monitor.c.

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

Definition at line 107 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 490 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 564 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 98 of file res_monitor.c.

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

Definition at line 96 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 694 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 114 of file res_monitor.c.

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

Definition at line 112 of file res_monitor.c.


Generated on Fri Sep 25 19:28:43 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.5