Asterisk.org: Developer Documentation (28 Oct 2009)

Wed Oct 28 15:49:05 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

## Functions

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

## Detailed Description

Channel monitoring.

Definition in file monitor.h.

## Function Documentation

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

Definition at line 315 of file res_monitor.c.

References ast_config_AST_MONITOR_DIR, ast_log(), ast_mutex_lock(), ast_mutex_unlock(), ast_safe_system(), ast_strlen_zero(), ast_channel_monitor::filename_base, ast_channel_monitor::filename_changed, FILENAME_MAX, free, ast_channel::lock, LOG_WARNING, ast_channel::monitor, name, ast_channel::name, and strdup.

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

    00316 {
    00317    char tmp[256];
    00318    if (ast_strlen_zero(fname_base)) {
    00319       ast_log(LOG_WARNING, "Cannot change monitor filename of channel %s to null\n", chan->name);
    00320       return -1;
    00321    }
    00322
    00323    if (need_lock) {
    00324       if (ast_mutex_lock(&chan->lock)) {
    00325          ast_log(LOG_WARNING, "Unable to lock channel\n");
    00326          return -1;
    00327       }
    00328    }
    00329
    00330    if (chan->monitor) {
    00331       int directory = strchr(fname_base, '/') ? 1 : 0;
    00332       /* try creating the directory just in case it doesn't exist */
    00333       if (directory) {
    00334          char *name = strdup(fname_base);
    00335          snprintf(tmp, sizeof(tmp), "mkdir -p %s",dirname(name));
    00336          free(name);
    00337          ast_safe_system(tmp);
    00338       }
    00339
    00340       snprintf(chan->monitor->filename_base, FILENAME_MAX, "%s/%s", directory ? "" : ast_config_AST_MONITOR_DIR, fname_base);
    00341       chan->monitor->filename_changed = 1;
    00342    } else {
    00343       ast_log(LOG_WARNING, "Cannot change monitor filename of channel %s to %s, monitoring not started\n", chan->name, fname_base);
    00344    }
    00345
    00346    if (need_lock)
    00347       ast_mutex_unlock(&chan->lock);
    00348
    00349    return 0;
    00350 }

void ast_monitor_setjoinfiles | ( | struct ast_channel * | chan,
|  | int | turnon |
| ) |  |  |

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

    00562 {
    00563    if (chan->monitor)
    00564       chan->monitor->joinfiles = turnon;
    00565 }

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

Definition at line 92 of file res_monitor.c.

References ast_closestream(), ast_config_AST_MONITOR_DIR, ast_filedelete(), ast_fileexists(), ast_log(), ast_monitor_stop(), ast_mutex_lock(), ast_mutex_unlock(), ast_safe_system(), ast_strdupa, ast_strlen_zero(), ast_writefile(), ast_channel_monitor::filename_base, ast_channel_monitor::filename_changed, FILENAME_MAX, ast_channel_monitor::format, free, ast_channel::lock, LOG_DEBUG, LOG_ERROR, LOG_WARNING, malloc, ast_channel::monitor, ast_channel::name, name, pbx_builtin_setvar_helper(), ast_channel_monitor::read_filename, ast_channel_monitor::read_stream, ast_channel_monitor::stop, strdup, 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().

    00094 {
    00095    int res = 0;
    00096    char tmp[256];
    00097
    00098    if (need_lock) {
    00099       if (ast_mutex_lock(&chan->lock)) {
    00100          ast_log(LOG_WARNING, "Unable to lock channel\n");
    00101          return -1;
    00102       }
    00103    }
    00104
    00105    if (!(chan->monitor)) {
    00106       struct ast_channel_monitor *monitor;
    00107       char *channel_name, *p;
    00108
    00109       /* Create monitoring directory if needed */
    00110       if (mkdir(ast_config_AST_MONITOR_DIR, 0770) < 0) {
    00111          if (errno != EEXIST) {
    00112             ast_log(LOG_WARNING, "Unable to create audio monitor directory: %s\n",
    00113                strerror(errno));
    00114          }
    00115       }
    00116
    00117       monitor = malloc(sizeof(struct ast_channel_monitor));
    00118       if (!monitor) {
    00119          if (need_lock)
    00120             ast_mutex_unlock(&chan->lock);
    00121          return -1;
    00122       }
    00123       memset(monitor, 0, sizeof(struct ast_channel_monitor));
    00124
    00125       /* Determine file names */
    00126       if (!ast_strlen_zero(fname_base)) {
    00127          int directory = strchr(fname_base, '/') ? 1 : 0;
    00128          /* try creating the directory just in case it doesn't exist */
    00129          if (directory) {
    00130             char *name = strdup(fname_base);
    00131             snprintf(tmp, sizeof(tmp), "mkdir -p \"%s\"",dirname(name));
    00132             free(name);
    00133             ast_safe_system(tmp);
    00134          }
    00135          snprintf(monitor->read_filename, FILENAME_MAX, "%s/%s-in",
    00136                   directory ? "" : ast_config_AST_MONITOR_DIR, fname_base);
    00137          snprintf(monitor->write_filename, FILENAME_MAX, "%s/%s-out",
    00138                   directory ? "" : ast_config_AST_MONITOR_DIR, fname_base);
    00139          ast_copy_string(monitor->filename_base, fname_base, sizeof(monitor->filename_base));
    00140       } else {
    00141          ast_mutex_lock(&monitorlock);
    00142          snprintf(monitor->read_filename, FILENAME_MAX, "%s/audio-in-%ld",
    00143                   ast_config_AST_MONITOR_DIR, seq);
    00144          snprintf(monitor->write_filename, FILENAME_MAX, "%s/audio-out-%ld",
    00145                   ast_config_AST_MONITOR_DIR, seq);
    00146          seq++;
    00147          ast_mutex_unlock(&monitorlock);
    00148
    00149          if((channel_name = ast_strdupa(chan->name))) {
    00150             while((p = strchr(channel_name, '/'))) {
    00151                *p = '-';
    00152             }
    00153             snprintf(monitor->filename_base, FILENAME_MAX, "%s/%d-%s",
    00154                    ast_config_AST_MONITOR_DIR, (int)time(NULL),channel_name);
    00155             monitor->filename_changed = 1;
    00156          } else {
    00157             ast_log(LOG_ERROR,"Failed to allocate Memory\n");
    00158             return -1;
    00159          }
    00160       }
    00161
    00162       monitor->stop = ast_monitor_stop;
    00163
    00164       /* Determine file format */
    00165       if (!ast_strlen_zero(format_spec)) {
    00166          monitor->format = strdup(format_spec);
    00167       } else {
    00168          monitor->format = strdup("wav");
    00169       }
    00170
    00171       /* open files */
    00172       if (ast_fileexists(monitor->read_filename, NULL, NULL) > 0) {
    00173          ast_filedelete(monitor->read_filename, NULL);
    00174       }
    00175       if (!(monitor->read_stream = ast_writefile(monitor->read_filename,
    00176                   monitor->format, NULL,
    00177                   O_CREAT|O_TRUNC|O_WRONLY, 0, 0644))) {
    00178          ast_log(LOG_WARNING, "Could not create file %s\n",
    00179                   monitor->read_filename);
    00180          free(monitor);
    00181          ast_mutex_unlock(&chan->lock);
    00182          return -1;
    00183       }
    00184       if (ast_fileexists(monitor->write_filename, NULL, NULL) > 0) {
    00185          ast_filedelete(monitor->write_filename, NULL);
    00186       }
    00187       if (!(monitor->write_stream = ast_writefile(monitor->write_filename,
    00188                   monitor->format, NULL,
    00189                   O_CREAT|O_TRUNC|O_WRONLY, 0, 0644))) {
    00190          ast_log(LOG_WARNING, "Could not create file %s\n",
    00191                   monitor->write_filename);
    00192          ast_closestream(monitor->read_stream);
    00193          free(monitor);
    00194          ast_mutex_unlock(&chan->lock);
    00195          return -1;
    00196       }
    00197       chan->monitor = monitor;
    00198       /* so we know this call has been monitored in case we need to bill for it or something */
    00199       pbx_builtin_setvar_helper(chan, "__MONITORED","true");
    00200    } else {
    00201       ast_log(LOG_DEBUG,"Cannot start monitoring %s, already monitored\n",
    00202                chan->name);
    00203       res = -1;
    00204    }
    00205
    00206    if (need_lock) {
    00207       ast_mutex_unlock(&chan->lock);
    00208    }
    00209    return res;
    00210 }

int ast_monitor_stop | ( | struct ast_channel * | chan,
|  | int | need_lock |
| ) |  |  |

Definition at line 230 of file res_monitor.c.

References ast_closestream(), ast_config_AST_MONITOR_DIR, ast_filedelete(), ast_fileexists(), ast_filerename(), ast_log(), ast_mutex_lock(), ast_mutex_unlock(), 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, ast_channel::lock, LOG_DEBUG, LOG_WARNING, ast_channel::monitor, name, pbx_builtin_getvar_helper(), ast_channel_monitor::read_filename, ast_channel_monitor::read_stream, 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().

    00231 {
    00232    char *execute, *execute_args;
    00233    int delfiles = 0;
    00234
    00235    if (need_lock) {
    00236       if (ast_mutex_lock(&chan->lock)) {
    00237          ast_log(LOG_WARNING, "Unable to lock channel\n");
    00238          return -1;
    00239       }
    00240    }
    00241
    00242    if (chan->monitor) {
    00243       char filename[ FILENAME_MAX ];
    00244
    00245       if (chan->monitor->read_stream) {
    00246          ast_closestream(chan->monitor->read_stream);
    00247       }
    00248       if (chan->monitor->write_stream) {
    00249          ast_closestream(chan->monitor->write_stream);
    00250       }
    00251
    00252       if (chan->monitor->filename_changed && !ast_strlen_zero(chan->monitor->filename_base)) {
    00253          if (ast_fileexists(chan->monitor->read_filename,NULL,NULL) > 0) {
    00254             snprintf(filename, FILENAME_MAX, "%s-in", chan->monitor->filename_base);
    00255             if (ast_fileexists(filename, NULL, NULL) > 0) {
    00256                ast_filedelete(filename, NULL);
    00257             }
    00258             ast_filerename(chan->monitor->read_filename, filename, chan->monitor->format);
    00259          } else {
    00260             ast_log(LOG_WARNING, "File %s not found\n", chan->monitor->read_filename);
    00261          }
    00262
    00263          if (ast_fileexists(chan->monitor->write_filename,NULL,NULL) > 0) {
    00264             snprintf(filename, FILENAME_MAX, "%s-out", chan->monitor->filename_base);
    00265             if (ast_fileexists(filename, NULL, NULL) > 0) {
    00266                ast_filedelete(filename, NULL);
    00267             }
    00268             ast_filerename(chan->monitor->write_filename, filename, chan->monitor->format);
    00269          } else {
    00270             ast_log(LOG_WARNING, "File %s not found\n", chan->monitor->write_filename);
    00271          }
    00272       }
    00273
    00274       if (chan->monitor->joinfiles && !ast_strlen_zero(chan->monitor->filename_base)) {
    00275          char tmp[1024];
    00276          char tmp2[1024];
    00277          const char *format = !strcasecmp(chan->monitor->format,"wav49") ? "WAV" : chan->monitor->format;
    00278          char *name = chan->monitor->filename_base;
    00279          int directory = strchr(name, '/') ? 1 : 0;
    00280          char *dir = directory ? "" : ast_config_AST_MONITOR_DIR;
    00281
    00282          /* Set the execute application */
    00283          execute = pbx_builtin_getvar_helper(chan, "MONITOR_EXEC");
    00284          if (ast_strlen_zero(execute)) {
    00285             execute = "nice -n 19 soxmix";
    00286             format = get_soxmix_format(format);
    00287             delfiles = 1;
    00288          }
    00289          execute_args = pbx_builtin_getvar_helper(chan, "MONITOR_EXEC_ARGS");
    00290          if (ast_strlen_zero(execute_args)) {
    00291             execute_args = "";
    00292          }
    00293
    00294          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);
    00295          if (delfiles) {
    00296             snprintf(tmp2,sizeof(tmp2), "( %s& rm -f \"%s/%s-\"* ) &",tmp, dir ,name); /* remove legs when done mixing */
    00297             ast_copy_string(tmp, tmp2, sizeof(tmp));
    00298          }
    00299          ast_log(LOG_DEBUG,"monitor executing %s\n",tmp);
    00300          if (ast_safe_system(tmp) == -1)
    00301             ast_log(LOG_WARNING, "Execute of %s failed.\n",tmp);
    00302       }
    00303
    00304       free(chan->monitor->format);
    00305       free(chan->monitor);
    00306       chan->monitor = NULL;
    00307    }
    00308
    00309    if (need_lock)
    00310       ast_mutex_unlock(&chan->lock);
    00311    return 0;
    00312 }