#include "asterisk.h"
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <libgen.h>
#include "asterisk/lock.h"
#include "asterisk/channel.h"
#include "asterisk/logger.h"
#include "asterisk/file.h"
#include "asterisk/pbx.h"
#include "asterisk/module.h"
#include "asterisk/manager.h"
#include "asterisk/cli.h"
#include "asterisk/monitor.h"
#include "asterisk/app.h"
#include "asterisk/utils.h"
#include "asterisk/config.h"
#include "asterisk/options.h"
Go to the source code of this file.
Defines | |
#define | IS_NULL_STRING(string) ((!(string)) || (ast_strlen_zero((string)))) |
#define | LOCK_IF_NEEDED(lock, needed) |
#define | UNLOCK_IF_NEEDED(lock, needed) |
Enumerations | |
enum | MONITOR_PAUSING_ACTION { MONITOR_ACTION_PAUSE, MONITOR_ACTION_UNPAUSE } |
Functions | |
static void | __reg_module (void) |
static void | __unreg_module (void) |
int | ast_monitor_change_fname (struct ast_channel *chan, const char *fname_base, int need_lock) |
int | ast_monitor_pause (struct ast_channel *chan) |
static int | ast_monitor_set_state (struct ast_channel *chan, int state) |
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) |
static int | change_monitor_action (struct mansession *s, const struct message *m) |
static int | change_monitor_exec (struct ast_channel *chan, void *data) |
static int | do_pause_or_unpause (struct mansession *s, const struct message *m, int action) |
static const char * | get_soxmix_format (const char *format) |
static int | load_module (void) |
static int | pause_monitor_action (struct mansession *s, const struct message *m) |
static int | pause_monitor_exec (struct ast_channel *chan, void *data) |
static int | start_monitor_action (struct mansession *s, const struct message *m) |
static int | start_monitor_exec (struct ast_channel *chan, void *data) |
static int | stop_monitor_action (struct mansession *s, const struct message *m) |
static int | stop_monitor_exec (struct ast_channel *chan, void *data) |
static int | unload_module (void) |
static int | unpause_monitor_action (struct mansession *s, const struct message *m) |
static int | unpause_monitor_exec (struct ast_channel *chan, void *data) |
Variables | |
static struct ast_module_info | __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_BUILDSUM, .description = "Call Monitoring Resource" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "361d7bb937402d51e4658efb5b4d76e4" , .load = load_module, .unload = unload_module, } |
static const struct ast_module_info * | ast_module_info = &__mod_info |
static char | change_monitor_action_help [] |
static char * | changemonitor_descrip |
static char * | changemonitor_synopsis = "Change monitoring filename of a channel" |
static char * | monitor_descrip |
static char * | monitor_synopsis = "Monitor a channel" |
static ast_mutex_t | monitorlock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) |
static char | pause_monitor_action_help [] |
static char * | pausemonitor_descrip |
static char * | pausemonitor_synopsis = "Pause monitoring of a channel" |
static unsigned long | seq = 0 |
static char | start_monitor_action_help [] |
static char | stop_monitor_action_help [] |
static char * | stopmonitor_descrip |
static char * | stopmonitor_synopsis = "Stop monitoring a channel" |
static char | unpause_monitor_action_help [] |
static char * | unpausemonitor_descrip |
static char * | unpausemonitor_synopsis = "Unpause monitoring of a channel" |
Definition in file res_monitor.c.
#define IS_NULL_STRING | ( | string | ) | ((!(string)) || (ast_strlen_zero((string)))) |
#define LOCK_IF_NEEDED | ( | lock, | |||
needed | ) |
Value:
do { \ if (needed) \ ast_channel_lock(lock); \ } while(0)
Definition at line 54 of file res_monitor.c.
Referenced by ast_monitor_change_fname(), ast_monitor_set_state(), ast_monitor_start(), and ast_monitor_stop().
#define UNLOCK_IF_NEEDED | ( | lock, | |||
needed | ) |
Value:
do { \ if (needed) \ ast_channel_unlock(lock); \ } while (0)
Definition at line 59 of file res_monitor.c.
Referenced by ast_monitor_change_fname(), ast_monitor_set_state(), ast_monitor_start(), and ast_monitor_stop().
Definition at line 660 of file res_monitor.c.
00661 { 00662 MONITOR_ACTION_PAUSE, 00663 MONITOR_ACTION_UNPAUSE 00664 };
static void __reg_module | ( | void | ) | [static] |
Definition at line 751 of file res_monitor.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 751 of file res_monitor.c.
int ast_monitor_change_fname | ( | struct ast_channel * | chan, | |
const char * | fname_base, | |||
int | need_lock | |||
) |
Definition at line 371 of file res_monitor.c.
References ast_config_AST_MONITOR_DIR, ast_copy_string(), ast_log(), ast_safe_system(), ast_strlen_zero(), errno, ast_channel_monitor::filename_base, ast_channel_monitor::filename_changed, free, LOCK_IF_NEEDED, LOG_DEBUG, LOG_ERROR, LOG_WARNING, ast_channel::monitor, name, ast_channel::name, option_debug, strdup, and UNLOCK_IF_NEEDED.
Referenced by change_monitor_action(), change_monitor_exec(), start_monitor_action(), and start_monitor_exec().
00372 { 00373 char tmp[256]; 00374 if (ast_strlen_zero(fname_base)) { 00375 ast_log(LOG_WARNING, "Cannot change monitor filename of channel %s to null\n", chan->name); 00376 return -1; 00377 } 00378 00379 LOCK_IF_NEEDED(chan, need_lock); 00380 00381 if (chan->monitor) { 00382 int directory = strchr(fname_base, '/') ? 1 : 0; 00383 const char *absolute = *fname_base == '/' ? "" : ast_config_AST_MONITOR_DIR; 00384 const char *absolute_suffix = *fname_base == '/' ? "" : "/"; 00385 char tmpstring[sizeof(chan->monitor->filename_base)] = ""; 00386 int i, fd[2] = { -1, -1 }, doexit = 0; 00387 00388 /* before continuing, see if we're trying to rename the file to itself... */ 00389 snprintf(tmpstring, sizeof(tmpstring), "%s%s%s", absolute, absolute_suffix, fname_base); 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%s%s\"", absolute, absolute_suffix, dirname(name)); 00395 free(name); 00396 ast_safe_system(tmp); 00397 } 00398 00399 /*!\note We cannot just compare filenames, due to symlinks, relative 00400 * paths, and other possible filesystem issues. We could use 00401 * realpath(3), but its use is discouraged. However, if we try to 00402 * create the same file from two different paths, the second will 00403 * fail, and so we have our notification that the filenames point to 00404 * the same path. 00405 * 00406 * Remember, also, that we're using the basename of the file (i.e. 00407 * the file without the format suffix), so it does not already exist 00408 * and we aren't interfering with the recording itself. 00409 */ 00410 if (option_debug > 2) { 00411 ast_log(LOG_DEBUG, "comparing tmpstring %s to filename_base %s\n", tmpstring, chan->monitor->filename_base); 00412 } 00413 if ((fd[0] = open(tmpstring, O_CREAT | O_WRONLY, 0644)) < 0 || 00414 (fd[1] = open(chan->monitor->filename_base, O_CREAT | O_EXCL | O_WRONLY, 0644)) < 0) { 00415 if (fd[0] < 0) { 00416 ast_log(LOG_ERROR, "Unable to compare filenames: %s\n", strerror(errno)); 00417 } else { 00418 if (option_debug > 2) { 00419 ast_log(LOG_DEBUG, "No need to rename monitor filename to itself\n"); 00420 } 00421 } 00422 doexit = 1; 00423 } 00424 00425 /* Cleanup temporary files */ 00426 for (i = 0; i < 2; i++) { 00427 if (fd[i] >= 0) { 00428 while (close(fd[i]) < 0 && errno == EINTR); 00429 } 00430 } 00431 unlink(tmpstring); 00432 /* if previous monitor file existed in a subdirectory, the directory will not be removed */ 00433 unlink(chan->monitor->filename_base); 00434 00435 if (doexit) { 00436 UNLOCK_IF_NEEDED(chan, need_lock); 00437 return 0; 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 | ) |
Definition at line 349 of file res_monitor.c.
References AST_MONITOR_PAUSED, and ast_monitor_set_state().
Referenced by do_pause_or_unpause(), and pause_monitor_exec().
00350 { 00351 return ast_monitor_set_state(chan, AST_MONITOR_PAUSED); 00352 }
static int ast_monitor_set_state | ( | struct ast_channel * | chan, | |
int | state | |||
) | [static] |
Definition at line 119 of file res_monitor.c.
References LOCK_IF_NEEDED, ast_channel::monitor, ast_channel_monitor::state, and UNLOCK_IF_NEEDED.
Referenced by ast_monitor_pause(), ast_monitor_start(), and ast_monitor_unpause().
00120 { 00121 LOCK_IF_NEEDED(chan, 1); 00122 if (!chan->monitor) { 00123 UNLOCK_IF_NEEDED(chan, 1); 00124 return -1; 00125 } 00126 chan->monitor->state = state; 00127 UNLOCK_IF_NEEDED(chan, 1); 00128 return 0; 00129 }
void ast_monitor_setjoinfiles | ( | struct ast_channel * | chan, | |
int | turnon | |||
) |
Definition at line 652 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().
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_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, monitor, ast_channel::monitor, monitorlock, ast_channel::name, 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 == '/' ? "" : ast_config_AST_MONITOR_DIR; 00161 const char *absolute_suffix = *fname_base == '/' ? "" : "/"; 00162 /* try creating the directory just in case it doesn't exist */ 00163 if (directory) { 00164 char *name = strdup(fname_base); 00165 snprintf(tmp, sizeof(tmp), "mkdir -p \"%s%s%s\"", 00166 absolute, absolute_suffix, dirname(name)); 00167 free(name); 00168 ast_safe_system(tmp); 00169 } 00170 snprintf(monitor->read_filename, FILENAME_MAX, "%s%s%s-in", 00171 absolute, absolute_suffix, fname_base); 00172 snprintf(monitor->write_filename, FILENAME_MAX, "%s%s%s-out", 00173 absolute, absolute_suffix, fname_base); 00174 snprintf(monitor->filename_base, FILENAME_MAX, "%s%s%s", 00175 absolute, absolute_suffix, fname_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_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, format, ast_channel_monitor::format, free, get_soxmix_format(), ast_channel_monitor::joinfiles, LOCK_IF_NEEDED, LOG_DEBUG, LOG_WARNING, ast_channel::monitor, pbx_builtin_getvar_helper(), pbx_builtin_setvar_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().
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 const char *format = !strcasecmp(chan->monitor->format,"wav49") ? "WAV" : chan->monitor->format; 00304 char *fname_base = chan->monitor->filename_base; 00305 const char *execute, *execute_args; 00306 /* at this point, fname_base really is the full path */ 00307 00308 /* Set the execute application */ 00309 execute = pbx_builtin_getvar_helper(chan, "MONITOR_EXEC"); 00310 if (ast_strlen_zero(execute)) { 00311 #ifdef HAVE_SOXMIX 00312 execute = "nice -n 19 soxmix"; 00313 #else 00314 execute = "nice -n 19 sox -m"; 00315 #endif 00316 format = get_soxmix_format(format); 00317 delfiles = 1; 00318 } 00319 execute_args = pbx_builtin_getvar_helper(chan, "MONITOR_EXEC_ARGS"); 00320 if (ast_strlen_zero(execute_args)) { 00321 execute_args = ""; 00322 } 00323 00324 snprintf(tmp, sizeof(tmp), "%s \"%s-in.%s\" \"%s-out.%s\" \"%s.%s\" %s &", 00325 execute, fname_base, format, fname_base, format, fname_base, format,execute_args); 00326 if (delfiles) { 00327 snprintf(tmp2,sizeof(tmp2), "( %s& rm -f \"%s-\"* ) &",tmp, fname_base); /* remove legs when done mixing */ 00328 ast_copy_string(tmp, tmp2, sizeof(tmp)); 00329 } 00330 ast_log(LOG_DEBUG,"monitor executing %s\n",tmp); 00331 if (ast_safe_system(tmp) == -1) 00332 ast_log(LOG_WARNING, "Execute of %s failed.\n",tmp); 00333 } 00334 00335 free(chan->monitor->format); 00336 free(chan->monitor); 00337 chan->monitor = NULL; 00338 pbx_builtin_setvar_helper(chan, "MONITORED", NULL); 00339 } 00340 pbx_builtin_setvar_helper(chan, "AUTO_MONITOR", NULL); 00341 00342 UNLOCK_IF_NEEDED(chan, need_lock); 00343 00344 return 0; 00345 }
int ast_monitor_unpause | ( | struct ast_channel * | chan | ) |
Definition at line 355 of file res_monitor.c.
References AST_MONITOR_RUNNING, and ast_monitor_set_state().
Referenced by do_pause_or_unpause(), and unpause_monitor_exec().
00356 { 00357 return ast_monitor_set_state(chan, AST_MONITOR_RUNNING); 00358 }
static int change_monitor_action | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 624 of file res_monitor.c.
References ast_channel_unlock, ast_get_channel_by_name_locked(), ast_monitor_change_fname(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), name, and s.
Referenced by load_module().
00625 { 00626 struct ast_channel *c = NULL; 00627 const char *name = astman_get_header(m, "Channel"); 00628 const char *fname = astman_get_header(m, "File"); 00629 if (ast_strlen_zero(name)) { 00630 astman_send_error(s, m, "No channel specified"); 00631 return 0; 00632 } 00633 if (ast_strlen_zero(fname)) { 00634 astman_send_error(s, m, "No filename specified"); 00635 return 0; 00636 } 00637 c = ast_get_channel_by_name_locked(name); 00638 if (!c) { 00639 astman_send_error(s, m, "No such channel"); 00640 return 0; 00641 } 00642 if (ast_monitor_change_fname(c, fname, 1)) { 00643 astman_send_error(s, m, "Could not change monitored filename of channel"); 00644 ast_channel_unlock(c); 00645 return 0; 00646 } 00647 ast_channel_unlock(c); 00648 astman_send_ack(s, m, "Changed monitor filename"); 00649 return 0; 00650 }
static int change_monitor_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 524 of file res_monitor.c.
References ast_monitor_change_fname().
Referenced by load_module().
00525 { 00526 return ast_monitor_change_fname(chan, (const char*)data, 1); 00527 }
static int do_pause_or_unpause | ( | struct mansession * | s, | |
const struct message * | m, | |||
int | action | |||
) | [static] |
Definition at line 666 of file res_monitor.c.
References ast_channel_unlock, ast_get_channel_by_name_locked(), ast_monitor_pause(), ast_monitor_unpause(), astman_get_header(), astman_send_ack(), astman_send_error(), IS_NULL_STRING, MONITOR_ACTION_PAUSE, name, and s.
Referenced by pause_monitor_action(), and unpause_monitor_action().
00667 { 00668 struct ast_channel *c = NULL; 00669 const char *name = astman_get_header(m, "Channel"); 00670 00671 if (IS_NULL_STRING(name)) { 00672 astman_send_error(s, m, "No channel specified"); 00673 return -1; 00674 } 00675 00676 c = ast_get_channel_by_name_locked(name); 00677 if (!c) { 00678 astman_send_error(s, m, "No such channel"); 00679 return -1; 00680 } 00681 00682 if (action == MONITOR_ACTION_PAUSE) 00683 ast_monitor_pause(c); 00684 else 00685 ast_monitor_unpause(c); 00686 00687 ast_channel_unlock(c); 00688 astman_send_ack(s, m, (action == MONITOR_ACTION_PAUSE ? "Paused monitoring of the channel" : "Unpaused monitoring of the channel")); 00689 return 0; 00690 }
static const char* get_soxmix_format | ( | const char * | format | ) | [static] |
Definition at line 249 of file res_monitor.c.
Referenced by ast_monitor_stop().
00250 { 00251 const char *res = format; 00252 00253 if (!strcasecmp(format,"ulaw")) 00254 res = "ul"; 00255 if (!strcasecmp(format,"alaw")) 00256 res = "al"; 00257 00258 return res; 00259 }
static int load_module | ( | void | ) | [static] |
Definition at line 715 of file res_monitor.c.
References ast_manager_register2(), ast_register_application(), change_monitor_action(), change_monitor_exec(), EVENT_FLAG_CALL, pause_monitor_action(), pause_monitor_exec(), start_monitor_action(), start_monitor_exec(), stop_monitor_action(), stop_monitor_exec(), unpause_monitor_action(), and unpause_monitor_exec().
00716 { 00717 ast_register_application("Monitor", start_monitor_exec, monitor_synopsis, monitor_descrip); 00718 ast_register_application("StopMonitor", stop_monitor_exec, stopmonitor_synopsis, stopmonitor_descrip); 00719 ast_register_application("ChangeMonitor", change_monitor_exec, changemonitor_synopsis, changemonitor_descrip); 00720 ast_register_application("PauseMonitor", pause_monitor_exec, pausemonitor_synopsis, pausemonitor_descrip); 00721 ast_register_application("UnpauseMonitor", unpause_monitor_exec, unpausemonitor_synopsis, unpausemonitor_descrip); 00722 ast_manager_register2("Monitor", EVENT_FLAG_CALL, start_monitor_action, monitor_synopsis, start_monitor_action_help); 00723 ast_manager_register2("StopMonitor", EVENT_FLAG_CALL, stop_monitor_action, stopmonitor_synopsis, stop_monitor_action_help); 00724 ast_manager_register2("ChangeMonitor", EVENT_FLAG_CALL, change_monitor_action, changemonitor_synopsis, change_monitor_action_help); 00725 ast_manager_register2("PauseMonitor", EVENT_FLAG_CALL, pause_monitor_action, pausemonitor_synopsis, pause_monitor_action_help); 00726 ast_manager_register2("UnpauseMonitor", EVENT_FLAG_CALL, unpause_monitor_action, unpausemonitor_synopsis, unpause_monitor_action_help); 00727 00728 return 0; 00729 }
static int pause_monitor_action | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 698 of file res_monitor.c.
References do_pause_or_unpause(), MONITOR_ACTION_PAUSE, and s.
Referenced by load_module().
00699 { 00700 return do_pause_or_unpause(s, m, MONITOR_ACTION_PAUSE); 00701 }
static int pause_monitor_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 360 of file res_monitor.c.
References ast_monitor_pause().
Referenced by load_module().
00361 { 00362 return ast_monitor_pause(chan); 00363 }
static int start_monitor_action | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 543 of file res_monitor.c.
References ast_channel_unlock, ast_get_channel_by_name_locked(), ast_monitor_change_fname(), ast_monitor_setjoinfiles(), ast_monitor_start(), ast_strdupa, ast_strlen_zero(), ast_true(), astman_get_header(), astman_send_ack(), astman_send_error(), format, ast_channel::name, name, and s.
Referenced by load_module().
00544 { 00545 struct ast_channel *c = NULL; 00546 const char *name = astman_get_header(m, "Channel"); 00547 const char *fname = astman_get_header(m, "File"); 00548 const char *format = astman_get_header(m, "Format"); 00549 const char *mix = astman_get_header(m, "Mix"); 00550 char *d; 00551 00552 if (ast_strlen_zero(name)) { 00553 astman_send_error(s, m, "No channel specified"); 00554 return 0; 00555 } 00556 c = ast_get_channel_by_name_locked(name); 00557 if (!c) { 00558 astman_send_error(s, m, "No such channel"); 00559 return 0; 00560 } 00561 00562 if (ast_strlen_zero(fname)) { 00563 /* No filename base specified, default to channel name as per CLI */ 00564 fname = ast_strdupa(c->name); 00565 /* Channels have the format technology/channel_name - have to replace that / */ 00566 if ((d = strchr(fname, '/'))) 00567 *d = '-'; 00568 } 00569 00570 if (ast_monitor_start(c, format, fname, 1)) { 00571 if (ast_monitor_change_fname(c, fname, 1)) { 00572 astman_send_error(s, m, "Could not start monitoring channel"); 00573 ast_channel_unlock(c); 00574 return 0; 00575 } 00576 } 00577 00578 if (ast_true(mix)) { 00579 ast_monitor_setjoinfiles(c, 1); 00580 } 00581 00582 ast_channel_unlock(c); 00583 astman_send_ack(s, m, "Started monitoring channel"); 00584 return 0; 00585 }
static int start_monitor_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 451 of file res_monitor.c.
References ast_cdr_alloc(), ast_cdr_setuserfield(), ast_monitor_change_fname(), ast_monitor_setjoinfiles(), ast_monitor_start(), ast_strdupa, ast_strlen_zero(), ast_channel::cdr, format, ast_channel_monitor::joinfiles, pbx_builtin_setvar_helper(), and urlprefix.
Referenced by load_module().
00452 { 00453 char *arg = NULL; 00454 char *format = NULL; 00455 char *fname_base = NULL; 00456 char *options = NULL; 00457 char *delay = NULL; 00458 char *urlprefix = NULL; 00459 char tmp[256]; 00460 int joinfiles = 0; 00461 int waitforbridge = 0; 00462 int res = 0; 00463 00464 /* Parse arguments. */ 00465 if (!ast_strlen_zero((char*)data)) { 00466 arg = ast_strdupa((char*)data); 00467 format = arg; 00468 fname_base = strchr(arg, '|'); 00469 if (fname_base) { 00470 *fname_base = 0; 00471 fname_base++; 00472 if ((options = strchr(fname_base, '|'))) { 00473 *options = 0; 00474 options++; 00475 if (strchr(options, 'm')) 00476 joinfiles = 1; 00477 if (strchr(options, 'b')) 00478 waitforbridge = 1; 00479 } 00480 } 00481 arg = strchr(format,':'); 00482 if (arg) { 00483 *arg++ = 0; 00484 urlprefix = arg; 00485 } 00486 } 00487 if (urlprefix) { 00488 snprintf(tmp,sizeof(tmp) - 1,"%s/%s.%s",urlprefix,fname_base, 00489 ((strcmp(format,"gsm")) ? "wav" : "gsm")); 00490 if (!chan->cdr && !(chan->cdr = ast_cdr_alloc())) 00491 return -1; 00492 ast_cdr_setuserfield(chan, tmp); 00493 } 00494 if (waitforbridge) { 00495 /* We must remove the "b" option if listed. In principle none of 00496 the following could give NULL results, but we check just to 00497 be pedantic. Reconstructing with checks for 'm' option does not 00498 work if we end up adding more options than 'm' in the future. */ 00499 delay = ast_strdupa(data); 00500 options = strrchr(delay, '|'); 00501 if (options) { 00502 arg = strchr(options, 'b'); 00503 if (arg) { 00504 *arg = 'X'; 00505 pbx_builtin_setvar_helper(chan,"AUTO_MONITOR",delay); 00506 } 00507 } 00508 return 0; 00509 } 00510 00511 res = ast_monitor_start(chan, format, fname_base, 1); 00512 if (res < 0) 00513 res = ast_monitor_change_fname(chan, fname_base, 1); 00514 ast_monitor_setjoinfiles(chan, joinfiles); 00515 00516 return res; 00517 }
static int stop_monitor_action | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 592 of file res_monitor.c.
References ast_channel_unlock, ast_get_channel_by_name_locked(), ast_monitor_stop(), ast_strlen_zero(), astman_get_header(), astman_send_ack(), astman_send_error(), name, and s.
Referenced by load_module().
00593 { 00594 struct ast_channel *c = NULL; 00595 const char *name = astman_get_header(m, "Channel"); 00596 int res; 00597 if (ast_strlen_zero(name)) { 00598 astman_send_error(s, m, "No channel specified"); 00599 return 0; 00600 } 00601 c = ast_get_channel_by_name_locked(name); 00602 if (!c) { 00603 astman_send_error(s, m, "No such channel"); 00604 return 0; 00605 } 00606 res = ast_monitor_stop(c, 1); 00607 ast_channel_unlock(c); 00608 if (res) { 00609 astman_send_error(s, m, "Could not stop monitoring channel"); 00610 return 0; 00611 } 00612 astman_send_ack(s, m, "Stopped monitoring channel"); 00613 return 0; 00614 }
static int stop_monitor_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 519 of file res_monitor.c.
References ast_monitor_stop().
Referenced by load_module().
00520 { 00521 return ast_monitor_stop(chan, 1); 00522 }
static int unload_module | ( | void | ) | [static] |
Definition at line 731 of file res_monitor.c.
References ast_manager_unregister(), and ast_unregister_application().
00732 { 00733 ast_unregister_application("Monitor"); 00734 ast_unregister_application("StopMonitor"); 00735 ast_unregister_application("ChangeMonitor"); 00736 ast_unregister_application("PauseMonitor"); 00737 ast_unregister_application("UnpauseMonitor"); 00738 ast_manager_unregister("Monitor"); 00739 ast_manager_unregister("StopMonitor"); 00740 ast_manager_unregister("ChangeMonitor"); 00741 ast_manager_unregister("PauseMonitor"); 00742 ast_manager_unregister("UnpauseMonitor"); 00743 00744 return 0; 00745 }
static int unpause_monitor_action | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 709 of file res_monitor.c.
References do_pause_or_unpause(), and s.
Referenced by load_module().
00710 { 00711 return do_pause_or_unpause(s, m, MONITOR_ACTION_UNPAUSE); 00712 }
static int unpause_monitor_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 365 of file res_monitor.c.
References ast_monitor_unpause().
Referenced by load_module().
00366 { 00367 return ast_monitor_unpause(chan); 00368 }
struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_BUILDSUM, .description = "Call Monitoring Resource" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = "361d7bb937402d51e4658efb5b4d76e4" , .load = load_module, .unload = unload_module, } [static] |
Definition at line 751 of file res_monitor.c.
const struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 751 of file res_monitor.c.
char change_monitor_action_help[] [static] |
Definition at line 616 of file res_monitor.c.
char* changemonitor_descrip [static] |
Initial value:
"ChangeMonitor(filename_base)\n" "Changes monitoring filename of a channel. Has no effect if the channel is not monitored\n" "The argument is the new filename base to use for monitoring this channel.\n"
Definition at line 104 of file res_monitor.c.
char* changemonitor_synopsis = "Change monitoring filename of a channel" [static] |
Definition at line 102 of file res_monitor.c.
char* monitor_descrip [static] |
Definition at line 68 of file res_monitor.c.
char* monitor_synopsis = "Monitor a channel" [static] |
Definition at line 66 of file res_monitor.c.
ast_mutex_t monitorlock = ((ast_mutex_t) PTHREAD_MUTEX_INITIALIZER ) [static] |
char pause_monitor_action_help[] [static] |
Initial value:
"Description: The 'PauseMonitor' action may be used to temporarily stop the\n" " recording of a channel. The following parameters may\n" " be used to control this:\n" " Channel - Required. Used to specify the channel to record.\n"
Definition at line 692 of file res_monitor.c.
char* pausemonitor_descrip [static] |
Initial value:
"PauseMonitor\n" "Pauses monitoring of a channel until it is re-enabled by a call to UnpauseMonitor.\n"
Definition at line 110 of file res_monitor.c.
char* pausemonitor_synopsis = "Pause monitoring of a channel" [static] |
Definition at line 108 of file res_monitor.c.
unsigned long seq = 0 [static] |
Definition at line 64 of file res_monitor.c.
char start_monitor_action_help[] [static] |
Definition at line 529 of file res_monitor.c.
char stop_monitor_action_help[] [static] |
Initial value:
"Description: The 'StopMonitor' action may be used to end a previously\n" " started 'Monitor' action. The only parameter is 'Channel', the name\n" " of the channel monitored.\n"
Definition at line 587 of file res_monitor.c.
char* stopmonitor_descrip [static] |
Initial value:
"StopMonitor\n" "Stops monitoring a channel. Has no effect if the channel is not monitored\n"
Definition at line 99 of file res_monitor.c.
char* stopmonitor_synopsis = "Stop monitoring a channel" [static] |
Definition at line 97 of file res_monitor.c.
char unpause_monitor_action_help[] [static] |
Initial value:
"Description: The 'UnpauseMonitor' action may be used to re-enable recording\n" " of a channel after calling PauseMonitor. The following parameters may\n" " be used to control this:\n" " Channel - Required. Used to specify the channel to record.\n"
Definition at line 703 of file res_monitor.c.
char* unpausemonitor_descrip [static] |
Initial value:
"UnpauseMonitor\n" "Unpauses monitoring of a channel on which monitoring had\n" "previously been paused with PauseMonitor.\n"
Definition at line 115 of file res_monitor.c.
char* unpausemonitor_synopsis = "Unpause monitoring of a channel" [static] |
Definition at line 113 of file res_monitor.c.