Fri Sep 11 13:45:35 2009

Asterisk developer's documentation


monitor.h File Reference

Channel monitoring. More...

#include "asterisk/channel.h"

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, 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 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, ast_channel::name, 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 }

void ast_monitor_setjoinfiles ( struct ast_channel chan,
int  turnon 
)

Definition at line 611 of file res_monitor.c.

References ast_channel_monitor::joinfiles, and ast_channel::monitor.

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

00612 {
00613    if (chan->monitor)
00614       chan->monitor->joinfiles = turnon;
00615 }

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, ast_channel::monitor, monitor, monitorlock, name, ast_channel::name, pbx_builtin_setvar_helper(), strdup, and UNLOCK_IF_NEEDED.

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

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


Generated on Fri Sep 11 13:45:35 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7