Sat Jul 26 06:14:18 2008

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

enum AST_MONITORING_STATE

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 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 }

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

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

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, ast_channel_monitor::format, 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 }


Generated on Sat Jul 26 06:14:18 2008 for Asterisk - the Open Source PBX by  doxygen 1.5.1