Fri Sep 25 19:28:39 2009

Asterisk developer's documentation


monitor.h File Reference

Channel monitoring. More...

#include "asterisk/channel.h"

Include dependency graph for monitor.h:

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  ast_channel_monitor

Enumerations

enum  AST_MONITORING_STATE { AST_MONITOR_RUNNING, AST_MONITOR_PAUSED }

Functions

int ast_monitor_change_fname (struct ast_channel *chan, const char *fname_base, int need_lock)
int ast_monitor_pause (struct ast_channel *chan)
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)


Detailed Description

Channel monitoring.

Definition in file monitor.h.


Enumeration Type Documentation

Enumerator:
AST_MONITOR_RUNNING 
AST_MONITOR_PAUSED 

Definition at line 28 of file monitor.h.

00028                           {
00029    AST_MONITOR_RUNNING,
00030    AST_MONITOR_PAUSED
00031 };


Function Documentation

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 }

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 }


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