Thu Oct 8 21:56:33 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 "asterisk/options.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 664 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 54 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 59 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 666 of file res_monitor.c.

00667 {
00668    MONITOR_ACTION_PAUSE,
00669    MONITOR_ACTION_UNPAUSE
00670 };


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 384 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, free, LOCK_IF_NEEDED, LOG_DEBUG, LOG_WARNING, ast_channel::monitor, name, option_debug, strdup, and UNLOCK_IF_NEEDED.

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

00385 {
00386    char tmp[256];
00387    if (ast_strlen_zero(fname_base)) {
00388       ast_log(LOG_WARNING, "Cannot change monitor filename of channel %s to null\n", chan->name);
00389       return -1;
00390    }
00391 
00392    LOCK_IF_NEEDED(chan, need_lock);
00393 
00394    if (chan->monitor) {
00395       int directory = strchr(fname_base, '/') ? 1 : 0;
00396       const char *absolute = *fname_base == '/' ? "" : "/";
00397       char tmpstring[sizeof(chan->monitor->filename_base)] = "";
00398 
00399       /* before continuing, see if we're trying to rename the file to itself... */
00400       snprintf(tmpstring, sizeof(tmpstring), "%s%s%s", directory ? "" : ast_config_AST_MONITOR_DIR, absolute, fname_base);
00401       if (!strcmp(tmpstring, chan->monitor->filename_base)) {
00402          if (option_debug > 2)
00403             ast_log(LOG_DEBUG, "No need to rename monitor filename to itself\n");
00404          UNLOCK_IF_NEEDED(chan, need_lock);
00405          return 0;
00406       }
00407 
00408       /* try creating the directory just in case it doesn't exist */
00409       if (directory) {
00410          char *name = strdup(fname_base);
00411          snprintf(tmp, sizeof(tmp), "mkdir -p %s",dirname(name));
00412          free(name);
00413          ast_safe_system(tmp);
00414       }
00415 
00416       ast_copy_string(chan->monitor->filename_base, tmpstring, sizeof(chan->monitor->filename_base));
00417       chan->monitor->filename_changed = 1;
00418    } else {
00419       ast_log(LOG_WARNING, "Cannot change monitor filename of channel %s to %s, monitoring not started\n", chan->name, fname_base);
00420    }
00421 
00422    UNLOCK_IF_NEEDED(chan, need_lock);
00423 
00424    return 0;
00425 }

int ast_monitor_pause ( struct ast_channel chan  ) 

Definition at line 362 of file res_monitor.c.

References AST_MONITOR_PAUSED, and ast_monitor_set_state().

Referenced by do_pause_or_unpause(), and pause_monitor_exec().

00363 {
00364    return ast_monitor_set_state(chan, AST_MONITOR_PAUSED);
00365 }

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

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

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

void ast_monitor_setjoinfiles ( struct ast_channel chan,
int  turnon 
)

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

00659 {
00660    if (chan->monitor)
00661       chan->monitor->joinfiles = turnon;
00662 }

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

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

int ast_monitor_stop ( struct ast_channel chan,
int  need_lock 
)

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

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

int ast_monitor_unpause ( struct ast_channel chan  ) 

Definition at line 368 of file res_monitor.c.

References AST_MONITOR_RUNNING, and ast_monitor_set_state().

Referenced by do_pause_or_unpause(), and unpause_monitor_exec().

00369 {
00370    return ast_monitor_set_state(chan, AST_MONITOR_RUNNING);
00371 }

AST_MUTEX_DEFINE_STATIC ( monitorlock   ) 

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

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

00631 {
00632    struct ast_channel *c = NULL;
00633    const char *name = astman_get_header(m, "Channel");
00634    const char *fname = astman_get_header(m, "File");
00635    if (ast_strlen_zero(name)) {
00636       astman_send_error(s, m, "No channel specified");
00637       return 0;
00638    }
00639    if (ast_strlen_zero(fname)) {
00640       astman_send_error(s, m, "No filename specified");
00641       return 0;
00642    }
00643    c = ast_get_channel_by_name_locked(name);
00644    if (!c) {
00645       astman_send_error(s, m, "No such channel");
00646       return 0;
00647    }
00648    if (ast_monitor_change_fname(c, fname, 1)) {
00649       astman_send_error(s, m, "Could not change monitored filename of channel");
00650       ast_channel_unlock(c);
00651       return 0;
00652    }
00653    ast_channel_unlock(c);
00654    astman_send_ack(s, m, "Changed monitor filename");
00655    return 0;
00656 }

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

Definition at line 500 of file res_monitor.c.

References ast_monitor_change_fname().

Referenced by load_module().

00501 {
00502    return ast_monitor_change_fname(chan, (const char*)data, 1);
00503 }

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

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

00673 {
00674    struct ast_channel *c = NULL;
00675    const char *name = astman_get_header(m, "Channel");
00676    
00677    if (IS_NULL_STRING(name)) {
00678       astman_send_error(s, m, "No channel specified");
00679       return -1;
00680    }
00681    
00682    c = ast_get_channel_by_name_locked(name);
00683    if (!c) {
00684       astman_send_error(s, m, "No such channel");
00685       return -1;
00686    }
00687 
00688    if (action == MONITOR_ACTION_PAUSE)
00689       ast_monitor_pause(c);
00690    else
00691       ast_monitor_unpause(c);
00692    
00693    ast_channel_unlock(c);
00694    astman_send_ack(s, m, (action == MONITOR_ACTION_PAUSE ? "Paused monitoring of the channel" : "Unpaused monitoring of the channel"));
00695    return 0;   
00696 }

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

Definition at line 251 of file res_monitor.c.

Referenced by ast_monitor_stop().

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

static int load_module ( void   )  [static]

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

References do_pause_or_unpause(), and MONITOR_ACTION_PAUSE.

Referenced by load_module().

00705 {
00706    return do_pause_or_unpause(s, m, MONITOR_ACTION_PAUSE);
00707 }

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

Definition at line 373 of file res_monitor.c.

References ast_monitor_pause().

Referenced by load_module().

00374 {
00375    return ast_monitor_pause(chan);
00376 }

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

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

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

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

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

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

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

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

00585 {
00586    struct ast_channel *c = NULL;
00587    const char *name = astman_get_header(m, "Channel");
00588    const char *uniqueid = astman_get_header(m, "Uniqueid");
00589    int res;
00590    if (ast_strlen_zero(name)) {
00591       astman_send_error(s, m, "No channel specified");
00592       return 0;
00593    }
00594    if (ast_strlen_zero(name) && ast_strlen_zero(uniqueid)) {
00595       astman_send_error(s, m, "No channel/uniqueid specified");
00596       return 0;
00597    }
00598    if (!ast_strlen_zero(uniqueid)) {
00599        c = ast_get_channel_by_uniqueid_locked(uniqueid);
00600        if (!c) {
00601       astman_send_error(s, m, "No such uniqueid");
00602       return 0;
00603        }
00604    } else {
00605        c = ast_get_channel_by_name_locked(name);
00606        if (!c) {
00607       astman_send_error(s, m, "No such channel");
00608       return 0;
00609        }
00610    }
00611 
00612    res = ast_monitor_stop(c, 1);
00613    ast_channel_unlock(c);
00614    if (res) {
00615       astman_send_error(s, m, "Could not stop monitoring channel");
00616       return 0;
00617    }
00618    astman_send_ack(s, m, "Stopped monitoring channel");
00619    return 0;
00620 }

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

Definition at line 495 of file res_monitor.c.

References ast_monitor_stop().

Referenced by load_module().

00496 {
00497    return ast_monitor_stop(chan, 1);
00498 }

static int unload_module ( void   )  [static]

Definition at line 737 of file res_monitor.c.

References ast_manager_unregister(), and ast_unregister_application().

00738 {
00739    ast_unregister_application("Monitor");
00740    ast_unregister_application("StopMonitor");
00741    ast_unregister_application("ChangeMonitor");
00742    ast_unregister_application("PauseMonitor");
00743    ast_unregister_application("UnpauseMonitor");
00744    ast_manager_unregister("Monitor");
00745    ast_manager_unregister("StopMonitor");
00746    ast_manager_unregister("ChangeMonitor");
00747    ast_manager_unregister("PauseMonitor");
00748    ast_manager_unregister("UnpauseMonitor");
00749 
00750    return 0;
00751 }

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

Definition at line 715 of file res_monitor.c.

References do_pause_or_unpause(), and MONITOR_ACTION_UNPAUSE.

Referenced by load_module().

00716 {
00717    return do_pause_or_unpause(s, m, MONITOR_ACTION_UNPAUSE);
00718 }

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

Definition at line 378 of file res_monitor.c.

References ast_monitor_unpause().

Referenced by load_module().

00379 {
00380    return ast_monitor_unpause(chan);
00381 }


Variable Documentation

char change_monitor_action_help[] [static]

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

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

Definition at line 102 of file res_monitor.c.

char* monitor_descrip [static]

Definition at line 68 of file res_monitor.c.

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

Definition at line 66 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 698 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 110 of file res_monitor.c.

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

Definition at line 108 of file res_monitor.c.

unsigned long seq = 0 [static]

Definition at line 64 of file res_monitor.c.

char start_monitor_action_help[] [static]

Definition at line 505 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 579 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 99 of file res_monitor.c.

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

Definition at line 97 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 709 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 115 of file res_monitor.c.

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

Definition at line 113 of file res_monitor.c.


Generated on Thu Oct 8 21:56:33 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.6