#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 = "6989f2ec67f8497e38c12890500c525b" , .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 = { PTHREAD_MUTEX_INITIALIZER , 1, { NULL }, { 0 }, 0, { NULL }, { 0 }, 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 655 of file res_monitor.c.
00656 { 00657 MONITOR_ACTION_PAUSE, 00658 MONITOR_ACTION_UNPAUSE 00659 };
static void __reg_module | ( | void | ) | [static] |
Definition at line 746 of file res_monitor.c.
static void __unreg_module | ( | void | ) | [static] |
Definition at line 746 of file res_monitor.c.
int ast_monitor_change_fname | ( | struct ast_channel * | chan, | |
const char * | fname_base, | |||
int | need_lock | |||
) |
Definition at line 368 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().
00369 { 00370 char tmp[256]; 00371 if (ast_strlen_zero(fname_base)) { 00372 ast_log(LOG_WARNING, "Cannot change monitor filename of channel %s to null\n", chan->name); 00373 return -1; 00374 } 00375 00376 LOCK_IF_NEEDED(chan, need_lock); 00377 00378 if (chan->monitor) { 00379 int directory = strchr(fname_base, '/') ? 1 : 0; 00380 const char *absolute = *fname_base == '/' ? "" : "/"; 00381 char tmpstring[sizeof(chan->monitor->filename_base)] = ""; 00382 int i, fd[2] = { -1, -1 }, doexit = 0; 00383 00384 /* before continuing, see if we're trying to rename the file to itself... */ 00385 snprintf(tmpstring, sizeof(tmpstring), "%s%s%s", directory ? "" : ast_config_AST_MONITOR_DIR, absolute, fname_base); 00386 00387 /*!\note We cannot just compare filenames, due to symlinks, relative 00388 * paths, and other possible filesystem issues. We could use 00389 * realpath(3), but its use is discouraged. However, if we try to 00390 * create the same file from two different paths, the second will 00391 * fail, and so we have our notification that the filenames point to 00392 * the same path. 00393 * 00394 * Remember, also, that we're using the basename of the file (i.e. 00395 * the file without the format suffix), so it does not already exist 00396 * and we aren't interfering with the recording itself. 00397 */ 00398 if (option_debug > 2) { 00399 ast_log(LOG_DEBUG, "comparing tmpstring %s to filename_base %s\n", tmpstring, chan->monitor->filename_base); 00400 } 00401 if ((fd[0] = open(tmpstring, O_CREAT | O_WRONLY, 0644)) < 0 || 00402 (fd[1] = open(chan->monitor->filename_base, O_CREAT | O_EXCL | O_WRONLY, 0644)) < 0) { 00403 if (fd[0] < 0) { 00404 ast_log(LOG_ERROR, "Unable to compare filenames: %s\n", strerror(errno)); 00405 } else { 00406 if (option_debug > 2) { 00407 ast_log(LOG_DEBUG, "No need to rename monitor filename to itself\n"); 00408 } 00409 } 00410 doexit = 1; 00411 } 00412 00413 /* Cleanup temporary files */ 00414 for (i = 0; i < 2; i++) { 00415 if (fd[i] >= 0) { 00416 while (close(fd[i]) < 0 && errno == EINTR); 00417 } 00418 } 00419 unlink(tmpstring); 00420 unlink(chan->monitor->filename_base); 00421 00422 if (doexit) { 00423 UNLOCK_IF_NEEDED(chan, need_lock); 00424 return 0; 00425 } 00426 00427 /* try creating the directory just in case it doesn't exist */ 00428 if (directory) { 00429 char *name = strdup(fname_base); 00430 snprintf(tmp, sizeof(tmp), "mkdir -p %s",dirname(name)); 00431 free(name); 00432 ast_safe_system(tmp); 00433 } 00434 00435 ast_copy_string(chan->monitor->filename_base, tmpstring, sizeof(chan->monitor->filename_base)); 00436 chan->monitor->filename_changed = 1; 00437 } else { 00438 ast_log(LOG_WARNING, "Cannot change monitor filename of channel %s to %s, monitoring not started\n", chan->name, fname_base); 00439 } 00440 00441 UNLOCK_IF_NEEDED(chan, need_lock); 00442 00443 return 0; 00444 }
int ast_monitor_pause | ( | struct ast_channel * | chan | ) |
Definition at line 346 of file res_monitor.c.
References AST_MONITOR_PAUSED, and ast_monitor_set_state().
Referenced by do_pause_or_unpause(), and pause_monitor_exec().
00347 { 00348 return ast_monitor_set_state(chan, AST_MONITOR_PAUSED); 00349 }
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 647 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 == '/' ? "" : "/"; 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 snprintf(monitor->filename_base, FILENAME_MAX, "%s%s%s", 00173 directory ? "" : ast_config_AST_MONITOR_DIR, absolute, fname_base); 00174 } else { 00175 ast_mutex_lock(&monitorlock); 00176 snprintf(monitor->read_filename, FILENAME_MAX, "%s/audio-in-%ld", 00177 ast_config_AST_MONITOR_DIR, seq); 00178 snprintf(monitor->write_filename, FILENAME_MAX, "%s/audio-out-%ld", 00179 ast_config_AST_MONITOR_DIR, seq); 00180 seq++; 00181 ast_mutex_unlock(&monitorlock); 00182 00183 channel_name = ast_strdupa(chan->name); 00184 while ((p = strchr(channel_name, '/'))) { 00185 *p = '-'; 00186 } 00187 snprintf(monitor->filename_base, FILENAME_MAX, "%s/%d-%s", 00188 ast_config_AST_MONITOR_DIR, (int)time(NULL), channel_name); 00189 monitor->filename_changed = 1; 00190 } 00191 00192 monitor->stop = ast_monitor_stop; 00193 00194 /* Determine file format */ 00195 if (!ast_strlen_zero(format_spec)) { 00196 monitor->format = strdup(format_spec); 00197 } else { 00198 monitor->format = strdup("wav"); 00199 } 00200 00201 /* open files */ 00202 if (ast_fileexists(monitor->read_filename, NULL, NULL) > 0) { 00203 ast_filedelete(monitor->read_filename, NULL); 00204 } 00205 if (!(monitor->read_stream = ast_writefile(monitor->read_filename, 00206 monitor->format, NULL, 00207 O_CREAT|O_TRUNC|O_WRONLY, 0, 0644))) { 00208 ast_log(LOG_WARNING, "Could not create file %s\n", 00209 monitor->read_filename); 00210 free(monitor); 00211 UNLOCK_IF_NEEDED(chan, need_lock); 00212 return -1; 00213 } 00214 if (ast_fileexists(monitor->write_filename, NULL, NULL) > 0) { 00215 ast_filedelete(monitor->write_filename, NULL); 00216 } 00217 if (!(monitor->write_stream = ast_writefile(monitor->write_filename, 00218 monitor->format, NULL, 00219 O_CREAT|O_TRUNC|O_WRONLY, 0, 0644))) { 00220 ast_log(LOG_WARNING, "Could not create file %s\n", 00221 monitor->write_filename); 00222 ast_closestream(monitor->read_stream); 00223 free(monitor); 00224 UNLOCK_IF_NEEDED(chan, need_lock); 00225 return -1; 00226 } 00227 chan->monitor = monitor; 00228 ast_monitor_set_state(chan, AST_MONITOR_RUNNING); 00229 /* so we know this call has been monitored in case we need to bill for it or something */ 00230 pbx_builtin_setvar_helper(chan, "__MONITORED","true"); 00231 } else { 00232 ast_log(LOG_DEBUG,"Cannot start monitoring %s, already monitored\n", 00233 chan->name); 00234 res = -1; 00235 } 00236 00237 UNLOCK_IF_NEEDED(chan, need_lock); 00238 00239 return res; 00240 }
int ast_monitor_stop | ( | struct ast_channel * | chan, | |
int | need_lock | |||
) |
Definition at line 260 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, format, ast_channel_monitor::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().
00261 { 00262 int delfiles = 0; 00263 00264 LOCK_IF_NEEDED(chan, need_lock); 00265 00266 if (chan->monitor) { 00267 char filename[ FILENAME_MAX ]; 00268 00269 if (chan->monitor->read_stream) { 00270 ast_closestream(chan->monitor->read_stream); 00271 } 00272 if (chan->monitor->write_stream) { 00273 ast_closestream(chan->monitor->write_stream); 00274 } 00275 00276 if (chan->monitor->filename_changed && !ast_strlen_zero(chan->monitor->filename_base)) { 00277 if (ast_fileexists(chan->monitor->read_filename,NULL,NULL) > 0) { 00278 snprintf(filename, FILENAME_MAX, "%s-in", chan->monitor->filename_base); 00279 if (ast_fileexists(filename, NULL, NULL) > 0) { 00280 ast_filedelete(filename, NULL); 00281 } 00282 ast_filerename(chan->monitor->read_filename, filename, chan->monitor->format); 00283 } else { 00284 ast_log(LOG_WARNING, "File %s not found\n", chan->monitor->read_filename); 00285 } 00286 00287 if (ast_fileexists(chan->monitor->write_filename,NULL,NULL) > 0) { 00288 snprintf(filename, FILENAME_MAX, "%s-out", chan->monitor->filename_base); 00289 if (ast_fileexists(filename, NULL, NULL) > 0) { 00290 ast_filedelete(filename, NULL); 00291 } 00292 ast_filerename(chan->monitor->write_filename, filename, chan->monitor->format); 00293 } else { 00294 ast_log(LOG_WARNING, "File %s not found\n", chan->monitor->write_filename); 00295 } 00296 } 00297 00298 if (chan->monitor->joinfiles && !ast_strlen_zero(chan->monitor->filename_base)) { 00299 char tmp[1024]; 00300 char tmp2[1024]; 00301 const char *format = !strcasecmp(chan->monitor->format,"wav49") ? "WAV" : chan->monitor->format; 00302 char *name = chan->monitor->filename_base; 00303 int directory = strchr(name, '/') ? 1 : 0; 00304 char *dir = directory ? "" : ast_config_AST_MONITOR_DIR; 00305 const char *execute, *execute_args; 00306 const char *absolute = *name == '/' ? "" : "/"; 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%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); 00325 if (delfiles) { 00326 snprintf(tmp2,sizeof(tmp2), "( %s& rm -f \"%s%s%s-\"* ) &",tmp, dir, absolute, name); /* remove legs when done mixing */ 00327 ast_copy_string(tmp, tmp2, sizeof(tmp)); 00328 } 00329 ast_log(LOG_DEBUG,"monitor executing %s\n",tmp); 00330 if (ast_safe_system(tmp) == -1) 00331 ast_log(LOG_WARNING, "Execute of %s failed.\n",tmp); 00332 } 00333 00334 free(chan->monitor->format); 00335 free(chan->monitor); 00336 chan->monitor = NULL; 00337 } 00338 00339 UNLOCK_IF_NEEDED(chan, need_lock); 00340 00341 return 0; 00342 }
int ast_monitor_unpause | ( | struct ast_channel * | chan | ) |
Definition at line 352 of file res_monitor.c.
References AST_MONITOR_RUNNING, and ast_monitor_set_state().
Referenced by do_pause_or_unpause(), and unpause_monitor_exec().
00353 { 00354 return ast_monitor_set_state(chan, AST_MONITOR_RUNNING); 00355 }
static int change_monitor_action | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 619 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().
00620 { 00621 struct ast_channel *c = NULL; 00622 const char *name = astman_get_header(m, "Channel"); 00623 const char *fname = astman_get_header(m, "File"); 00624 if (ast_strlen_zero(name)) { 00625 astman_send_error(s, m, "No channel specified"); 00626 return 0; 00627 } 00628 if (ast_strlen_zero(fname)) { 00629 astman_send_error(s, m, "No filename specified"); 00630 return 0; 00631 } 00632 c = ast_get_channel_by_name_locked(name); 00633 if (!c) { 00634 astman_send_error(s, m, "No such channel"); 00635 return 0; 00636 } 00637 if (ast_monitor_change_fname(c, fname, 1)) { 00638 astman_send_error(s, m, "Could not change monitored filename of channel"); 00639 ast_channel_unlock(c); 00640 return 0; 00641 } 00642 ast_channel_unlock(c); 00643 astman_send_ack(s, m, "Changed monitor filename"); 00644 return 0; 00645 }
static int change_monitor_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 519 of file res_monitor.c.
References ast_monitor_change_fname().
Referenced by load_module().
00520 { 00521 return ast_monitor_change_fname(chan, (const char*)data, 1); 00522 }
static int do_pause_or_unpause | ( | struct mansession * | s, | |
const struct message * | m, | |||
int | action | |||
) | [static] |
Definition at line 661 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().
00662 { 00663 struct ast_channel *c = NULL; 00664 const char *name = astman_get_header(m, "Channel"); 00665 00666 if (IS_NULL_STRING(name)) { 00667 astman_send_error(s, m, "No channel specified"); 00668 return -1; 00669 } 00670 00671 c = ast_get_channel_by_name_locked(name); 00672 if (!c) { 00673 astman_send_error(s, m, "No such channel"); 00674 return -1; 00675 } 00676 00677 if (action == MONITOR_ACTION_PAUSE) 00678 ast_monitor_pause(c); 00679 else 00680 ast_monitor_unpause(c); 00681 00682 ast_channel_unlock(c); 00683 astman_send_ack(s, m, (action == MONITOR_ACTION_PAUSE ? "Paused monitoring of the channel" : "Unpaused monitoring of the channel")); 00684 return 0; 00685 }
static const char* get_soxmix_format | ( | const char * | format | ) | [static] |
Definition at line 247 of file res_monitor.c.
Referenced by ast_monitor_stop().
00248 { 00249 const char *res = format; 00250 00251 if (!strcasecmp(format,"ulaw")) 00252 res = "ul"; 00253 if (!strcasecmp(format,"alaw")) 00254 res = "al"; 00255 00256 return res; 00257 }
static int load_module | ( | void | ) | [static] |
Definition at line 710 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().
00711 { 00712 ast_register_application("Monitor", start_monitor_exec, monitor_synopsis, monitor_descrip); 00713 ast_register_application("StopMonitor", stop_monitor_exec, stopmonitor_synopsis, stopmonitor_descrip); 00714 ast_register_application("ChangeMonitor", change_monitor_exec, changemonitor_synopsis, changemonitor_descrip); 00715 ast_register_application("PauseMonitor", pause_monitor_exec, pausemonitor_synopsis, pausemonitor_descrip); 00716 ast_register_application("UnpauseMonitor", unpause_monitor_exec, unpausemonitor_synopsis, unpausemonitor_descrip); 00717 ast_manager_register2("Monitor", EVENT_FLAG_CALL, start_monitor_action, monitor_synopsis, start_monitor_action_help); 00718 ast_manager_register2("StopMonitor", EVENT_FLAG_CALL, stop_monitor_action, stopmonitor_synopsis, stop_monitor_action_help); 00719 ast_manager_register2("ChangeMonitor", EVENT_FLAG_CALL, change_monitor_action, changemonitor_synopsis, change_monitor_action_help); 00720 ast_manager_register2("PauseMonitor", EVENT_FLAG_CALL, pause_monitor_action, pausemonitor_synopsis, pause_monitor_action_help); 00721 ast_manager_register2("UnpauseMonitor", EVENT_FLAG_CALL, unpause_monitor_action, unpausemonitor_synopsis, unpause_monitor_action_help); 00722 00723 return 0; 00724 }
static int pause_monitor_action | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 693 of file res_monitor.c.
References do_pause_or_unpause(), MONITOR_ACTION_PAUSE, and s.
Referenced by load_module().
00694 { 00695 return do_pause_or_unpause(s, m, MONITOR_ACTION_PAUSE); 00696 }
static int pause_monitor_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 357 of file res_monitor.c.
References ast_monitor_pause().
Referenced by load_module().
00358 { 00359 return ast_monitor_pause(chan); 00360 }
static int start_monitor_action | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 538 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().
00539 { 00540 struct ast_channel *c = NULL; 00541 const char *name = astman_get_header(m, "Channel"); 00542 const char *fname = astman_get_header(m, "File"); 00543 const char *format = astman_get_header(m, "Format"); 00544 const char *mix = astman_get_header(m, "Mix"); 00545 char *d; 00546 00547 if (ast_strlen_zero(name)) { 00548 astman_send_error(s, m, "No channel specified"); 00549 return 0; 00550 } 00551 c = ast_get_channel_by_name_locked(name); 00552 if (!c) { 00553 astman_send_error(s, m, "No such channel"); 00554 return 0; 00555 } 00556 00557 if (ast_strlen_zero(fname)) { 00558 /* No filename base specified, default to channel name as per CLI */ 00559 fname = ast_strdupa(c->name); 00560 /* Channels have the format technology/channel_name - have to replace that / */ 00561 if ((d = strchr(fname, '/'))) 00562 *d = '-'; 00563 } 00564 00565 if (ast_monitor_start(c, format, fname, 1)) { 00566 if (ast_monitor_change_fname(c, fname, 1)) { 00567 astman_send_error(s, m, "Could not start monitoring channel"); 00568 ast_channel_unlock(c); 00569 return 0; 00570 } 00571 } 00572 00573 if (ast_true(mix)) { 00574 ast_monitor_setjoinfiles(c, 1); 00575 } 00576 00577 ast_channel_unlock(c); 00578 astman_send_ack(s, m, "Started monitoring channel"); 00579 return 0; 00580 }
static int start_monitor_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 446 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().
00447 { 00448 char *arg = NULL; 00449 char *format = NULL; 00450 char *fname_base = NULL; 00451 char *options = NULL; 00452 char *delay = NULL; 00453 char *urlprefix = NULL; 00454 char tmp[256]; 00455 int joinfiles = 0; 00456 int waitforbridge = 0; 00457 int res = 0; 00458 00459 /* Parse arguments. */ 00460 if (!ast_strlen_zero((char*)data)) { 00461 arg = ast_strdupa((char*)data); 00462 format = arg; 00463 fname_base = strchr(arg, '|'); 00464 if (fname_base) { 00465 *fname_base = 0; 00466 fname_base++; 00467 if ((options = strchr(fname_base, '|'))) { 00468 *options = 0; 00469 options++; 00470 if (strchr(options, 'm')) 00471 joinfiles = 1; 00472 if (strchr(options, 'b')) 00473 waitforbridge = 1; 00474 } 00475 } 00476 arg = strchr(format,':'); 00477 if (arg) { 00478 *arg++ = 0; 00479 urlprefix = arg; 00480 } 00481 } 00482 if (urlprefix) { 00483 snprintf(tmp,sizeof(tmp) - 1,"%s/%s.%s",urlprefix,fname_base, 00484 ((strcmp(format,"gsm")) ? "wav" : "gsm")); 00485 if (!chan->cdr && !(chan->cdr = ast_cdr_alloc())) 00486 return -1; 00487 ast_cdr_setuserfield(chan, tmp); 00488 } 00489 if (waitforbridge) { 00490 /* We must remove the "b" option if listed. In principle none of 00491 the following could give NULL results, but we check just to 00492 be pedantic. Reconstructing with checks for 'm' option does not 00493 work if we end up adding more options than 'm' in the future. */ 00494 delay = ast_strdupa(data); 00495 options = strrchr(delay, '|'); 00496 if (options) { 00497 arg = strchr(options, 'b'); 00498 if (arg) { 00499 *arg = 'X'; 00500 pbx_builtin_setvar_helper(chan,"AUTO_MONITOR",delay); 00501 } 00502 } 00503 return 0; 00504 } 00505 00506 res = ast_monitor_start(chan, format, fname_base, 1); 00507 if (res < 0) 00508 res = ast_monitor_change_fname(chan, fname_base, 1); 00509 ast_monitor_setjoinfiles(chan, joinfiles); 00510 00511 return res; 00512 }
static int stop_monitor_action | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 587 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().
00588 { 00589 struct ast_channel *c = NULL; 00590 const char *name = astman_get_header(m, "Channel"); 00591 int res; 00592 if (ast_strlen_zero(name)) { 00593 astman_send_error(s, m, "No channel specified"); 00594 return 0; 00595 } 00596 c = ast_get_channel_by_name_locked(name); 00597 if (!c) { 00598 astman_send_error(s, m, "No such channel"); 00599 return 0; 00600 } 00601 res = ast_monitor_stop(c, 1); 00602 ast_channel_unlock(c); 00603 if (res) { 00604 astman_send_error(s, m, "Could not stop monitoring channel"); 00605 return 0; 00606 } 00607 astman_send_ack(s, m, "Stopped monitoring channel"); 00608 return 0; 00609 }
static int stop_monitor_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 514 of file res_monitor.c.
References ast_monitor_stop().
Referenced by load_module().
00515 { 00516 return ast_monitor_stop(chan, 1); 00517 }
static int unload_module | ( | void | ) | [static] |
Definition at line 726 of file res_monitor.c.
References ast_manager_unregister(), and ast_unregister_application().
00727 { 00728 ast_unregister_application("Monitor"); 00729 ast_unregister_application("StopMonitor"); 00730 ast_unregister_application("ChangeMonitor"); 00731 ast_unregister_application("PauseMonitor"); 00732 ast_unregister_application("UnpauseMonitor"); 00733 ast_manager_unregister("Monitor"); 00734 ast_manager_unregister("StopMonitor"); 00735 ast_manager_unregister("ChangeMonitor"); 00736 ast_manager_unregister("PauseMonitor"); 00737 ast_manager_unregister("UnpauseMonitor"); 00738 00739 return 0; 00740 }
static int unpause_monitor_action | ( | struct mansession * | s, | |
const struct message * | m | |||
) | [static] |
Definition at line 704 of file res_monitor.c.
References do_pause_or_unpause(), and s.
Referenced by load_module().
00705 { 00706 return do_pause_or_unpause(s, m, MONITOR_ACTION_UNPAUSE); 00707 }
static int unpause_monitor_exec | ( | struct ast_channel * | chan, | |
void * | data | |||
) | [static] |
Definition at line 362 of file res_monitor.c.
References ast_monitor_unpause().
Referenced by load_module().
00363 { 00364 return ast_monitor_unpause(chan); 00365 }
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 = "6989f2ec67f8497e38c12890500c525b" , .load = load_module, .unload = unload_module, } [static] |
Definition at line 746 of file res_monitor.c.
const struct ast_module_info* ast_module_info = &__mod_info [static] |
Definition at line 746 of file res_monitor.c.
char change_monitor_action_help[] [static] |
Definition at line 611 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 = { PTHREAD_MUTEX_INITIALIZER , 1, { NULL }, { 0 }, 0, { NULL }, { 0 }, 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 687 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 524 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 582 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 698 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.