Thu May 14 14:50:14 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"

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

static void __reg_module (void)
static void __unreg_module (void)
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)
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 struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_BUILDSUM, .description = "Call Monitoring Resource" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "f450f61f60e761b3aa089ebed76ca8a5" , .load = load_module, .unload = unload_module, }
static const struct ast_module_infoast_module_info = &__mod_info
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 ast_mutex_t monitorlock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER )
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 621 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

enum MONITOR_PAUSING_ACTION

Enumerator:
MONITOR_ACTION_PAUSE 
MONITOR_ACTION_UNPAUSE 

Definition at line 623 of file res_monitor.c.

00624 {
00625    MONITOR_ACTION_PAUSE,
00626    MONITOR_ACTION_UNPAUSE
00627 };


Function Documentation

static void __reg_module ( void   )  [static]

Definition at line 714 of file res_monitor.c.

static void __unreg_module ( void   )  [static]

Definition at line 714 of file res_monitor.c.

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

Definition at line 367 of file res_monitor.c.

References ast_config_AST_MONITOR_DIR, ast_copy_string(), 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, ast_channel::name, option_debug, strdup, and UNLOCK_IF_NEEDED.

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

00368 {
00369    char tmp[256];
00370    if (ast_strlen_zero(fname_base)) {
00371       ast_log(LOG_WARNING, "Cannot change monitor filename of channel %s to null\n", chan->name);
00372       return -1;
00373    }
00374 
00375    LOCK_IF_NEEDED(chan, need_lock);
00376 
00377    if (chan->monitor) {
00378       int directory = strchr(fname_base, '/') ? 1 : 0;
00379       const char *absolute = *fname_base == '/' ? "" : "/";
00380       char tmpstring[sizeof(chan->monitor->filename_base)] = "";
00381 
00382       /* before continuing, see if we're trying to rename the file to itself... */
00383       snprintf(tmpstring, sizeof(tmpstring), "%s%s%s", directory ? "" : ast_config_AST_MONITOR_DIR, absolute, fname_base);
00384       if (!strcmp(tmpstring, chan->monitor->filename_base)) {
00385          if (option_debug > 2)
00386             ast_log(LOG_DEBUG, "No need to rename monitor filename to itself\n");
00387          UNLOCK_IF_NEEDED(chan, need_lock);
00388          return 0;
00389       }
00390 
00391       /* try creating the directory just in case it doesn't exist */
00392       if (directory) {
00393          char *name = strdup(fname_base);
00394          snprintf(tmp, sizeof(tmp), "mkdir -p %s",dirname(name));
00395          free(name);
00396          ast_safe_system(tmp);
00397       }
00398 
00399       ast_copy_string(chan->monitor->filename_base, tmpstring, sizeof(chan->monitor->filename_base));
00400       chan->monitor->filename_changed = 1;
00401    } else {
00402       ast_log(LOG_WARNING, "Cannot change monitor filename of channel %s to %s, monitoring not started\n", chan->name, fname_base);
00403    }
00404 
00405    UNLOCK_IF_NEEDED(chan, need_lock);
00406 
00407    return 0;
00408 }

int ast_monitor_pause ( struct ast_channel chan  ) 

Definition at line 345 of file res_monitor.c.

References AST_MONITOR_PAUSED, and ast_monitor_set_state().

Referenced by do_pause_or_unpause(), and pause_monitor_exec().

00346 {
00347    return ast_monitor_set_state(chan, AST_MONITOR_PAUSED);
00348 }

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

00616 {
00617    if (chan->monitor)
00618       chan->monitor->joinfiles = turnon;
00619 }

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

Definition at line 132 of file res_monitor.c.

References ast_calloc, ast_closestream(), ast_config_AST_MONITOR_DIR, ast_copy_string(), 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, FILENAME_MAX, free, LOCK_IF_NEEDED, LOG_DEBUG, LOG_WARNING, monitor, ast_channel::monitor, monitorlock, ast_channel::name, name, pbx_builtin_setvar_helper(), strdup, and UNLOCK_IF_NEEDED.

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

int ast_monitor_stop ( struct ast_channel chan,
int  need_lock 
)

Definition at line 259 of file res_monitor.c.

References ast_closestream(), ast_config_AST_MONITOR_DIR, ast_copy_string(), 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().

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

int ast_monitor_unpause ( struct ast_channel chan  ) 

Definition at line 351 of file res_monitor.c.

References AST_MONITOR_RUNNING, and ast_monitor_set_state().

Referenced by do_pause_or_unpause(), and unpause_monitor_exec().

00352 {
00353    return ast_monitor_set_state(chan, AST_MONITOR_RUNNING);
00354 }

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

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

00588 {
00589    struct ast_channel *c = NULL;
00590    const char *name = astman_get_header(m, "Channel");
00591    const char *fname = astman_get_header(m, "File");
00592    if (ast_strlen_zero(name)) {
00593       astman_send_error(s, m, "No channel specified");
00594       return 0;
00595    }
00596    if (ast_strlen_zero(fname)) {
00597       astman_send_error(s, m, "No filename specified");
00598       return 0;
00599    }
00600    c = ast_get_channel_by_name_locked(name);
00601    if (!c) {
00602       astman_send_error(s, m, "No such channel");
00603       return 0;
00604    }
00605    if (ast_monitor_change_fname(c, fname, 1)) {
00606       astman_send_error(s, m, "Could not change monitored filename of channel");
00607       ast_channel_unlock(c);
00608       return 0;
00609    }
00610    ast_channel_unlock(c);
00611    astman_send_ack(s, m, "Changed monitor filename");
00612    return 0;
00613 }

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

Definition at line 483 of file res_monitor.c.

References ast_monitor_change_fname().

Referenced by load_module().

00484 {
00485    return ast_monitor_change_fname(chan, (const char*)data, 1);
00486 }

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

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

00630 {
00631    struct ast_channel *c = NULL;
00632    const char *name = astman_get_header(m, "Channel");
00633    
00634    if (IS_NULL_STRING(name)) {
00635       astman_send_error(s, m, "No channel specified");
00636       return -1;
00637    }
00638    
00639    c = ast_get_channel_by_name_locked(name);
00640    if (!c) {
00641       astman_send_error(s, m, "No such channel");
00642       return -1;
00643    }
00644 
00645    if (action == MONITOR_ACTION_PAUSE)
00646       ast_monitor_pause(c);
00647    else
00648       ast_monitor_unpause(c);
00649    
00650    ast_channel_unlock(c);
00651    astman_send_ack(s, m, (action == MONITOR_ACTION_PAUSE ? "Paused monitoring of the channel" : "Unpaused monitoring of the channel"));
00652    return 0;   
00653 }

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

Definition at line 246 of file res_monitor.c.

Referenced by ast_monitor_stop().

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

static int load_module ( void   )  [static]

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

References do_pause_or_unpause(), MONITOR_ACTION_PAUSE, and s.

Referenced by load_module().

00662 {
00663    return do_pause_or_unpause(s, m, MONITOR_ACTION_PAUSE);
00664 }

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

Definition at line 356 of file res_monitor.c.

References ast_monitor_pause().

Referenced by load_module().

00357 {
00358    return ast_monitor_pause(chan);
00359 }

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

Definition at line 502 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, ast_channel::name, name, and s.

Referenced by load_module().

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

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

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

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

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

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

00556 {
00557    struct ast_channel *c = NULL;
00558    const char *name = astman_get_header(m, "Channel");
00559    int res;
00560    if (ast_strlen_zero(name)) {
00561       astman_send_error(s, m, "No channel specified");
00562       return 0;
00563    }
00564    c = ast_get_channel_by_name_locked(name);
00565    if (!c) {
00566       astman_send_error(s, m, "No such channel");
00567       return 0;
00568    }
00569    res = ast_monitor_stop(c, 1);
00570    ast_channel_unlock(c);
00571    if (res) {
00572       astman_send_error(s, m, "Could not stop monitoring channel");
00573       return 0;
00574    }
00575    astman_send_ack(s, m, "Stopped monitoring channel");
00576    return 0;
00577 }

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

Definition at line 478 of file res_monitor.c.

References ast_monitor_stop().

Referenced by load_module().

00479 {
00480    return ast_monitor_stop(chan, 1);
00481 }

static int unload_module ( void   )  [static]

Definition at line 694 of file res_monitor.c.

References ast_manager_unregister(), and ast_unregister_application().

00695 {
00696    ast_unregister_application("Monitor");
00697    ast_unregister_application("StopMonitor");
00698    ast_unregister_application("ChangeMonitor");
00699    ast_unregister_application("PauseMonitor");
00700    ast_unregister_application("UnpauseMonitor");
00701    ast_manager_unregister("Monitor");
00702    ast_manager_unregister("StopMonitor");
00703    ast_manager_unregister("ChangeMonitor");
00704    ast_manager_unregister("PauseMonitor");
00705    ast_manager_unregister("UnpauseMonitor");
00706 
00707    return 0;
00708 }

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

Definition at line 672 of file res_monitor.c.

References do_pause_or_unpause(), and s.

Referenced by load_module().

00673 {
00674    return do_pause_or_unpause(s, m, MONITOR_ACTION_UNPAUSE);
00675 }

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

Definition at line 361 of file res_monitor.c.

References ast_monitor_unpause().

Referenced by load_module().

00362 {
00363    return ast_monitor_unpause(chan);
00364 }


Variable Documentation

struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_BUILDSUM, .description = "Call Monitoring Resource" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "f450f61f60e761b3aa089ebed76ca8a5" , .load = load_module, .unload = unload_module, } [static]

Definition at line 714 of file res_monitor.c.

const struct ast_module_info* ast_module_info = &__mod_info [static]

Definition at line 714 of file res_monitor.c.

char change_monitor_action_help[] [static]

Definition at line 579 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.

ast_mutex_t monitorlock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static]

Definition at line 52 of file res_monitor.c.

Referenced by ast_monitor_start().

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 655 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 488 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 550 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 666 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 May 14 14:50:14 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7