#include "asterisk/channel.h"
Go to the source code of this file.
Data Structures | |
struct | ast_channel_monitor |
Defines | |
#define | X_JOIN 4 |
#define | X_REC_IN 1 |
#define | X_REC_OUT 2 |
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) attribute_weak |
Change monitored filename of channel. | |
int | ast_monitor_pause (struct ast_channel *chan) attribute_weak |
Pause monitoring of channel. | |
void | ast_monitor_setjoinfiles (struct ast_channel *chan, int turnon) attribute_weak |
int | ast_monitor_start (struct ast_channel *chan, const char *format_spec, const char *fname_base, int need_lock, int stream_action) attribute_weak |
Start monitoring a channel. | |
int | ast_monitor_stop (struct ast_channel *chan, int need_lock) attribute_weak |
Stop monitoring channel. | |
int | ast_monitor_unpause (struct ast_channel *chan) attribute_weak |
Unpause monitoring of channel. |
Definition in file monitor.h.
#define X_JOIN 4 |
#define X_REC_IN 1 |
Definition at line 34 of file monitor.h.
Referenced by __agent_start_monitoring(), ast_monitor_start(), start_monitor_action(), and start_monitor_exec().
#define X_REC_OUT 2 |
Definition at line 35 of file monitor.h.
Referenced by __agent_start_monitoring(), ast_monitor_start(), start_monitor_action(), and start_monitor_exec().
enum AST_MONITORING_STATE |
Definition at line 28 of file monitor.h.
00028 { 00029 AST_MONITOR_RUNNING, 00030 AST_MONITOR_PAUSED 00031 };
int ast_monitor_change_fname | ( | struct ast_channel * | chan, | |
const char * | fname_base, | |||
int | need_lock | |||
) |
Change monitored filename of channel.
chan | ||
fname_base | new filename | |
need_lock |
0 | on success. | |
-1 | on failure. |
Definition at line 411 of file res_monitor.c.
References ast_config_AST_MONITOR_DIR, ast_copy_string(), ast_log(), ast_mkdir(), ast_strdupa, ast_strlen_zero(), chan, ast_channel_monitor::filename_base, ast_channel_monitor::filename_changed, LOCK_IF_NEEDED, LOG_DEBUG, LOG_WARNING, ast_channel::monitor, ast_channel::name, name, option_debug, and UNLOCK_IF_NEEDED.
Referenced by change_monitor_action(), change_monitor_exec(), start_monitor_action(), and start_monitor_exec().
00412 { 00413 if (ast_strlen_zero(fname_base)) { 00414 ast_log(LOG_WARNING, "Cannot change monitor filename of channel %s to null\n", chan->name); 00415 return -1; 00416 } 00417 00418 LOCK_IF_NEEDED(chan, need_lock); 00419 00420 if (chan->monitor) { 00421 int directory = strchr(fname_base, '/') ? 1 : 0; 00422 const char *absolute = *fname_base == '/' ? "" : "/"; 00423 char tmpstring[sizeof(chan->monitor->filename_base)] = ""; 00424 00425 /* before continuing, see if we're trying to rename the file to itself... */ 00426 snprintf(tmpstring, sizeof(tmpstring), "%s%s%s", directory ? "" : ast_config_AST_MONITOR_DIR, absolute, fname_base); 00427 if (!strcmp(tmpstring, chan->monitor->filename_base)) { 00428 if (option_debug > 2) 00429 ast_log(LOG_DEBUG, "No need to rename monitor filename to itself\n"); 00430 UNLOCK_IF_NEEDED(chan, need_lock); 00431 return 0; 00432 } 00433 00434 /* try creating the directory just in case it doesn't exist */ 00435 if (directory) { 00436 char *name = ast_strdupa(fname_base); 00437 ast_mkdir(dirname(name), 0777); 00438 } 00439 00440 ast_copy_string(chan->monitor->filename_base, tmpstring, sizeof(chan->monitor->filename_base)); 00441 chan->monitor->filename_changed = 1; 00442 } else { 00443 ast_log(LOG_WARNING, "Cannot change monitor filename of channel %s to %s, monitoring not started\n", chan->name, fname_base); 00444 } 00445 00446 UNLOCK_IF_NEEDED(chan, need_lock); 00447 00448 return 0; 00449 }
int ast_monitor_pause | ( | struct ast_channel * | chan | ) |
Pause monitoring of channel.
Definition at line 380 of file res_monitor.c.
References AST_MONITOR_PAUSED, ast_monitor_set_state(), and chan.
Referenced by do_pause_or_unpause(), and pause_monitor_exec().
00381 { 00382 return ast_monitor_set_state(chan, AST_MONITOR_PAUSED); 00383 }
void ast_monitor_setjoinfiles | ( | struct ast_channel * | chan, | |
int | turnon | |||
) |
Definition at line 680 of file res_monitor.c.
References chan, ast_channel_monitor::joinfiles, and ast_channel::monitor.
Referenced by __agent_start_monitoring(), start_monitor_action(), and start_monitor_exec().
int ast_monitor_start | ( | struct ast_channel * | chan, | |
const char * | format_spec, | |||
const char * | fname_base, | |||
int | need_lock, | |||
int | stream_action | |||
) |
Start monitoring a channel.
chan | ast_channel struct to record | |
format_spec | file format to use for recording | |
fname_base | filename base to record to | |
need_lock | whether to lock the channel mutex | |
stream_action | whether to record the input and/or output streams. X_REC_IN | X_REC_OUT is most often used Creates the file to record, if no format is specified it assumes WAV It also sets channel variable __MONITORED=yes |
0 | on success | |
-1 | on failure |
Definition at line 147 of file res_monitor.c.
References ast_calloc, ast_closestream(), ast_config_AST_MONITOR_DIR, ast_copy_string(), ast_debug, AST_FILE_MODE, ast_filedelete(), ast_fileexists(), ast_free, ast_log(), ast_mkdir(), AST_MONITOR_RUNNING, ast_monitor_set_state(), ast_monitor_stop(), ast_mutex_lock(), ast_mutex_unlock(), ast_strdup, ast_strdupa, ast_strlen_zero(), ast_writefile(), chan, EVENT_FLAG_CALL, FILENAME_MAX, LOCK_IF_NEEDED, LOG_WARNING, manager_event, ast_channel::monitor, monitor, monitorlock, name, ast_channel::name, pbx_builtin_setvar_helper(), ast_channel::uniqueid, UNLOCK_IF_NEEDED, X_REC_IN, and X_REC_OUT.
Referenced by __agent_start_monitoring(), start_monitor_action(), and start_monitor_exec().
00149 { 00150 int res = 0; 00151 00152 LOCK_IF_NEEDED(chan, need_lock); 00153 00154 if (!(chan->monitor)) { 00155 struct ast_channel_monitor *monitor; 00156 char *channel_name, *p; 00157 00158 /* Create monitoring directory if needed */ 00159 ast_mkdir(ast_config_AST_MONITOR_DIR, 0777); 00160 00161 if (!(monitor = ast_calloc(1, sizeof(*monitor)))) { 00162 UNLOCK_IF_NEEDED(chan, need_lock); 00163 return -1; 00164 } 00165 00166 /* Determine file names */ 00167 if (!ast_strlen_zero(fname_base)) { 00168 int directory = strchr(fname_base, '/') ? 1 : 0; 00169 const char *absolute = *fname_base == '/' ? "" : "/"; 00170 /* try creating the directory just in case it doesn't exist */ 00171 if (directory) { 00172 char *name = ast_strdupa(fname_base); 00173 ast_mkdir(dirname(name), 0777); 00174 } 00175 snprintf(monitor->read_filename, FILENAME_MAX, "%s%s%s-in", 00176 directory ? "" : ast_config_AST_MONITOR_DIR, absolute, fname_base); 00177 snprintf(monitor->write_filename, FILENAME_MAX, "%s%s%s-out", 00178 directory ? "" : ast_config_AST_MONITOR_DIR, absolute, fname_base); 00179 ast_copy_string(monitor->filename_base, fname_base, sizeof(monitor->filename_base)); 00180 } else { 00181 ast_mutex_lock(&monitorlock); 00182 snprintf(monitor->read_filename, FILENAME_MAX, "%s/audio-in-%ld", 00183 ast_config_AST_MONITOR_DIR, seq); 00184 snprintf(monitor->write_filename, FILENAME_MAX, "%s/audio-out-%ld", 00185 ast_config_AST_MONITOR_DIR, seq); 00186 seq++; 00187 ast_mutex_unlock(&monitorlock); 00188 00189 channel_name = ast_strdupa(chan->name); 00190 while ((p = strchr(channel_name, '/'))) { 00191 *p = '-'; 00192 } 00193 snprintf(monitor->filename_base, FILENAME_MAX, "%s/%d-%s", 00194 ast_config_AST_MONITOR_DIR, (int)time(NULL), channel_name); 00195 monitor->filename_changed = 1; 00196 } 00197 00198 monitor->stop = ast_monitor_stop; 00199 00200 /* Determine file format */ 00201 if (!ast_strlen_zero(format_spec)) { 00202 monitor->format = ast_strdup(format_spec); 00203 } else { 00204 monitor->format = ast_strdup("wav"); 00205 } 00206 00207 /* open files */ 00208 if (stream_action & X_REC_IN) { 00209 if (ast_fileexists(monitor->read_filename, NULL, NULL) > 0) 00210 ast_filedelete(monitor->read_filename, NULL); 00211 if (!(monitor->read_stream = ast_writefile(monitor->read_filename, 00212 monitor->format, NULL, 00213 O_CREAT|O_TRUNC|O_WRONLY, 0, AST_FILE_MODE))) { 00214 ast_log(LOG_WARNING, "Could not create file %s\n", 00215 monitor->read_filename); 00216 ast_free(monitor); 00217 UNLOCK_IF_NEEDED(chan, need_lock); 00218 return -1; 00219 } 00220 } else 00221 monitor->read_stream = NULL; 00222 00223 if (stream_action & X_REC_OUT) { 00224 if (ast_fileexists(monitor->write_filename, NULL, NULL) > 0) { 00225 ast_filedelete(monitor->write_filename, NULL); 00226 } 00227 if (!(monitor->write_stream = ast_writefile(monitor->write_filename, 00228 monitor->format, NULL, 00229 O_CREAT|O_TRUNC|O_WRONLY, 0, AST_FILE_MODE))) { 00230 ast_log(LOG_WARNING, "Could not create file %s\n", 00231 monitor->write_filename); 00232 ast_closestream(monitor->read_stream); 00233 ast_free(monitor); 00234 UNLOCK_IF_NEEDED(chan, need_lock); 00235 return -1; 00236 } 00237 } else 00238 monitor->write_stream = NULL; 00239 00240 chan->monitor = monitor; 00241 ast_monitor_set_state(chan, AST_MONITOR_RUNNING); 00242 /* so we know this call has been monitored in case we need to bill for it or something */ 00243 pbx_builtin_setvar_helper(chan, "__MONITORED","true"); 00244 00245 manager_event(EVENT_FLAG_CALL, "MonitorStart", 00246 "Channel: %s\r\n" 00247 "Uniqueid: %s\r\n", 00248 chan->name, 00249 chan->uniqueid 00250 ); 00251 } else { 00252 ast_debug(1,"Cannot start monitoring %s, already monitored\n", chan->name); 00253 res = -1; 00254 } 00255 00256 UNLOCK_IF_NEEDED(chan, need_lock); 00257 00258 return res; 00259 }
int ast_monitor_stop | ( | struct ast_channel * | chan, | |
int | need_lock | |||
) |
Stop monitoring channel.
chan | ||
need_lock | Stop the recording, close any open streams, mix in/out channels if required |
Definition at line 287 of file res_monitor.c.
References ast_closestream(), ast_config_AST_MONITOR_DIR, ast_copy_string(), ast_debug, ast_filedelete(), ast_fileexists(), ast_filerename(), ast_free, ast_log(), ast_safe_system(), ast_strlen_zero(), chan, dir, EVENT_FLAG_CALL, ast_channel_monitor::filename_base, ast_channel_monitor::filename_changed, FILENAME_MAX, ast_channel_monitor::format, format, get_soxmix_format(), ast_channel_monitor::joinfiles, LOCK_IF_NEEDED, LOG_WARNING, manager_event, ast_channel::monitor, name, ast_channel::name, pbx_builtin_getvar_helper(), ast_channel_monitor::read_filename, ast_channel_monitor::read_stream, ast_channel::uniqueid, UNLOCK_IF_NEEDED, ast_channel_monitor::write_filename, and ast_channel_monitor::write_stream.
Referenced by ast_monitor_start(), stop_monitor_action(), and stop_monitor_exec().
00288 { 00289 int delfiles = 0; 00290 00291 LOCK_IF_NEEDED(chan, need_lock); 00292 00293 if (chan->monitor) { 00294 char filename[ FILENAME_MAX ]; 00295 00296 if (chan->monitor->read_stream) { 00297 ast_closestream(chan->monitor->read_stream); 00298 } 00299 if (chan->monitor->write_stream) { 00300 ast_closestream(chan->monitor->write_stream); 00301 } 00302 00303 if (chan->monitor->filename_changed && !ast_strlen_zero(chan->monitor->filename_base)) { 00304 if (ast_fileexists(chan->monitor->read_filename,NULL,NULL) > 0) { 00305 snprintf(filename, FILENAME_MAX, "%s-in", chan->monitor->filename_base); 00306 if (ast_fileexists(filename, NULL, NULL) > 0) { 00307 ast_filedelete(filename, NULL); 00308 } 00309 ast_filerename(chan->monitor->read_filename, filename, chan->monitor->format); 00310 } else { 00311 ast_log(LOG_WARNING, "File %s not found\n", chan->monitor->read_filename); 00312 } 00313 00314 if (ast_fileexists(chan->monitor->write_filename,NULL,NULL) > 0) { 00315 snprintf(filename, FILENAME_MAX, "%s-out", chan->monitor->filename_base); 00316 if (ast_fileexists(filename, NULL, NULL) > 0) { 00317 ast_filedelete(filename, NULL); 00318 } 00319 ast_filerename(chan->monitor->write_filename, filename, chan->monitor->format); 00320 } else { 00321 ast_log(LOG_WARNING, "File %s not found\n", chan->monitor->write_filename); 00322 } 00323 } 00324 00325 if (chan->monitor->joinfiles && !ast_strlen_zero(chan->monitor->filename_base)) { 00326 char tmp[1024]; 00327 char tmp2[1024]; 00328 const char *format = !strcasecmp(chan->monitor->format,"wav49") ? "WAV" : chan->monitor->format; 00329 char *name = chan->monitor->filename_base; 00330 int directory = strchr(name, '/') ? 1 : 0; 00331 const char *dir = directory ? "" : ast_config_AST_MONITOR_DIR; 00332 const char *execute, *execute_args; 00333 const char *absolute = *name == '/' ? "" : "/"; 00334 00335 /* Set the execute application */ 00336 execute = pbx_builtin_getvar_helper(chan, "MONITOR_EXEC"); 00337 if (ast_strlen_zero(execute)) { 00338 #ifdef HAVE_SOXMIX 00339 execute = "nice -n 19 soxmix"; 00340 #else 00341 execute = "nice -n 19 sox -m"; 00342 #endif 00343 format = get_soxmix_format(format); 00344 delfiles = 1; 00345 } 00346 execute_args = pbx_builtin_getvar_helper(chan, "MONITOR_EXEC_ARGS"); 00347 if (ast_strlen_zero(execute_args)) { 00348 execute_args = ""; 00349 } 00350 00351 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); 00352 if (delfiles) { 00353 snprintf(tmp2,sizeof(tmp2), "( %s& rm -f \"%s%s%s-\"* ) &",tmp, dir, absolute, name); /* remove legs when done mixing */ 00354 ast_copy_string(tmp, tmp2, sizeof(tmp)); 00355 } 00356 ast_debug(1,"monitor executing %s\n",tmp); 00357 if (ast_safe_system(tmp) == -1) 00358 ast_log(LOG_WARNING, "Execute of %s failed.\n",tmp); 00359 } 00360 00361 ast_free(chan->monitor->format); 00362 ast_free(chan->monitor); 00363 chan->monitor = NULL; 00364 00365 manager_event(EVENT_FLAG_CALL, "MonitorStop", 00366 "Channel: %s\r\n" 00367 "Uniqueid: %s\r\n", 00368 chan->name, 00369 chan->uniqueid 00370 ); 00371 } 00372 00373 UNLOCK_IF_NEEDED(chan, need_lock); 00374 00375 return 0; 00376 }
int ast_monitor_unpause | ( | struct ast_channel * | chan | ) |
Unpause monitoring of channel.
Definition at line 386 of file res_monitor.c.
References AST_MONITOR_RUNNING, ast_monitor_set_state(), and chan.
Referenced by do_pause_or_unpause(), and unpause_monitor_exec().
00387 { 00388 return ast_monitor_set_state(chan, AST_MONITOR_RUNNING); 00389 }