aboutsummaryrefslogtreecommitdiffstats
path: root/apps/app_chanspy.c
diff options
context:
space:
mode:
authorkpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b>2006-07-27 23:00:27 +0000
committerkpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b>2006-07-27 23:00:27 +0000
commitfafa6738a3e225eb27e3af06cdefd266f1119679 (patch)
tree9ba2142ecd71a11a7c6cdc20feda4fb093fe40c7 /apps/app_chanspy.c
parent87c1d75227977f85781104edaff23421c07f61c4 (diff)
remove local channel finding wrappers
move guts of dialplan application into separate function, so it can be shared bythe new application i'm about to add :-) git-svn-id: http://svn.digium.com/svn/asterisk/trunk@38374 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'apps/app_chanspy.c')
-rw-r--r--apps/app_chanspy.c228
1 files changed, 111 insertions, 117 deletions
diff --git a/apps/app_chanspy.c b/apps/app_chanspy.c
index 63f743d01..a109673f5 100644
--- a/apps/app_chanspy.c
+++ b/apps/app_chanspy.c
@@ -51,8 +51,6 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/module.h"
#include "asterisk/lock.h"
-AST_MUTEX_DEFINE_STATIC(modlock);
-
#define AST_NAME_STRLEN 256
static const char *tdesc = "Listen to the audio of an active channel";
@@ -115,34 +113,6 @@ struct chanspy_translation_helper {
int volfactor;
};
-static struct ast_channel *local_channel_walk(struct ast_channel *chan)
-{
- struct ast_channel *ret;
-
- ast_mutex_lock(&modlock);
-
- if ((ret = ast_channel_walk_locked(chan)))
- ast_mutex_unlock(&ret->lock);
-
- ast_mutex_unlock(&modlock);
-
- return ret;
-}
-
-static struct ast_channel *local_get_channel_begin_name(char *name)
-{
- struct ast_channel *ret;
-
- ast_mutex_lock(&modlock);
-
- if ((ret = ast_get_channel_by_name_prefix_locked(name, strlen(name))))
- ast_mutex_unlock(&ret->lock);
-
- ast_mutex_unlock(&modlock);
-
- return ret;
-}
-
static void *spy_alloc(struct ast_channel *chan, void *data)
{
/* just store the data pointer in the channel structure */
@@ -344,89 +314,33 @@ static int channel_spy(struct ast_channel *chan, struct ast_channel *spyee, int
return running;
}
-static int chanspy_exec(struct ast_channel *chan, void *data)
+static struct ast_channel *next_channel(const struct ast_channel *last)
{
- struct localuser *u;
- struct ast_channel *peer, *prev;
- char name[AST_NAME_STRLEN],
- peer_name[AST_NAME_STRLEN + 5],
- *ptr,
- *options = NULL,
- *spec = NULL,
- *argv[5],
- *mygroup = NULL,
- *recbase = NULL;
- int res = -1,
- volfactor,
- silent = 0,
- argc,
- bronly = 0,
- waitms,
- num,
- oldwf,
- fd = 0;
- struct ast_flags flags;
- signed char zero_volume = 0;
+ struct ast_channel *this;
- data = ast_strdupa(data);
+ if ((this = ast_channel_walk_locked(last)))
+ ast_channel_unlock(this);
- LOCAL_USER_ADD(u);
+ return this;
+}
- oldwf = chan->writeformat;
- if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
- ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
- LOCAL_USER_REMOVE(u);
- return -1;
- }
+static int common_exec(struct ast_channel *chan, const int silent, const int bronly,
+ int volfactor, const int fd, const char *spec, const char *mygroup)
+{
+ struct ast_channel *peer, *prev, *next;
+ char nameprefix[AST_NAME_STRLEN];
+ char peer_name[AST_NAME_STRLEN + 5];
+ signed char zero_volume = 0;
+ int waitms;
+ int res;
+ char *ptr;
+ int num;
- ast_answer(chan);
+ if (chan->_state != AST_STATE_UP)
+ ast_answer(chan);
ast_set_flag(chan, AST_FLAG_SPYING); /* so nobody can spy on us while we are spying */
- if ((argc = ast_app_separate_args(data, '|', argv, sizeof(argv) / sizeof(argv[0])))) {
- spec = argv[0];
- if (argc > 1) {
- options = argv[1];
- }
- if (ast_strlen_zero(spec) || !strcmp(spec, "all")) {
- spec = NULL;
- }
- }
-
- if (options) {
- char *opts[OPT_ARG_ARRAY_SIZE];
-
- ast_app_parse_options(chanspy_opts, &flags, opts, options);
- if (ast_test_flag(&flags, OPTION_GROUP))
- mygroup = opts[OPT_ARG_GROUP];
-
- if (ast_test_flag(&flags, OPTION_RECORD) &&
- !(recbase = opts[OPT_ARG_RECORD]))
- recbase = "chanspy";
-
- silent = ast_test_flag(&flags, OPTION_QUIET);
- bronly = ast_test_flag(&flags, OPTION_BRIDGED);
-
- if (ast_test_flag(&flags, OPTION_VOLUME) && opts[OPT_ARG_VOLUME]) {
- int vol;
-
- if ((sscanf(opts[OPT_ARG_VOLUME], "%d", &vol) != 1) || (vol > 4) || (vol < -4))
- ast_log(LOG_NOTICE, "Volume factor must be a number between -4 and 4\n");
- else
- volfactor = vol;
- }
- }
-
- if (recbase) {
- char filename[512];
-
- snprintf(filename, sizeof(filename), "%s/%s.%d.raw", ast_config_AST_MONITOR_DIR, recbase, (int) time(NULL));
- if ((fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0644)) <= 0) {
- ast_log(LOG_WARNING, "Cannot open '%s' for recording\n", filename);
- fd = 0;
- }
- }
-
waitms = 100;
for (;;) {
@@ -448,10 +362,11 @@ static int chanspy_exec(struct ast_channel *chan, void *data)
/* reset for the next loop around, unless overridden later */
waitms = 100;
+ peer = prev = next = NULL;
- for (peer = local_channel_walk(NULL), prev = NULL;
+ for (peer = next_channel(peer);
peer;
- peer = local_channel_walk(peer)) {
+ prev = peer, peer = next ? next : next_channel(peer), next = NULL) {
const char *group;
int igrp = 0;
char *groups[25];
@@ -517,31 +432,110 @@ static int chanspy_exec(struct ast_channel *chan, void *data)
}
waitms = 5000;
- prev = peer;
res = channel_spy(chan, peer, &volfactor, fd);
if (res == -1) {
break;
} else if (res > 1 && spec) {
- snprintf(name, AST_NAME_STRLEN, "%s/%d", spec, res);
- if ((peer = local_get_channel_begin_name(name)))
- prev = NULL;
-
- continue;
+ snprintf(nameprefix, AST_NAME_STRLEN, "%s/%d", spec, res);
+ if ((next = ast_get_channel_by_name_prefix_locked(nameprefix, strlen(nameprefix)))) {
+ ast_channel_unlock(next);
+ } else {
+ /* stay on this channel */
+ next = peer;
+ }
+ peer = NULL;
}
}
}
+ ast_clear_flag(chan, AST_FLAG_SPYING);
+
+ ast_channel_setoption(chan, AST_OPTION_TXGAIN, &zero_volume, sizeof(zero_volume), 0);
+
+ return res;
+}
+
+static int chanspy_exec(struct ast_channel *chan, void *data)
+{
+ struct localuser *u;
+ char *options = NULL;
+ char *spec = NULL;
+ char *argv[5];
+ char *mygroup = NULL;
+ char *recbase = NULL;
+ int fd = 0;
+ struct ast_flags flags;
+ int oldwf = 0;
+ int argc = 0;
+ int silent = 0;
+ int bronly = 0;
+ int volfactor = 0;
+ int res;
+
+ data = ast_strdupa(data);
+
+ LOCAL_USER_ADD(u);
+
+ if ((argc = ast_app_separate_args(data, '|', argv, sizeof(argv) / sizeof(argv[0])))) {
+ spec = argv[0];
+ if (argc > 1) {
+ options = argv[1];
+ }
+ if (ast_strlen_zero(spec) || !strcmp(spec, "all")) {
+ spec = NULL;
+ }
+ }
+
+ if (options) {
+ char *opts[OPT_ARG_ARRAY_SIZE];
+
+ ast_app_parse_options(chanspy_opts, &flags, opts, options);
+ if (ast_test_flag(&flags, OPTION_GROUP))
+ mygroup = opts[OPT_ARG_GROUP];
+
+ if (ast_test_flag(&flags, OPTION_RECORD) &&
+ !(recbase = opts[OPT_ARG_RECORD]))
+ recbase = "chanspy";
+
+ silent = ast_test_flag(&flags, OPTION_QUIET);
+ bronly = ast_test_flag(&flags, OPTION_BRIDGED);
+
+ if (ast_test_flag(&flags, OPTION_VOLUME) && opts[OPT_ARG_VOLUME]) {
+ int vol;
+
+ if ((sscanf(opts[OPT_ARG_VOLUME], "%d", &vol) != 1) || (vol > 4) || (vol < -4))
+ ast_log(LOG_NOTICE, "Volume factor must be a number between -4 and 4\n");
+ else
+ volfactor = vol;
+ }
+ }
+
+ oldwf = chan->writeformat;
+ if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
+ ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
+ LOCAL_USER_REMOVE(u);
+ return -1;
+ }
+
+ if (recbase) {
+ char filename[512];
+
+ snprintf(filename, sizeof(filename), "%s/%s.%d.raw", ast_config_AST_MONITOR_DIR, recbase, (int) time(NULL));
+ if ((fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0644)) <= 0) {
+ ast_log(LOG_WARNING, "Cannot open '%s' for recording\n", filename);
+ fd = 0;
+ }
+ }
+
+ res = common_exec(chan, silent, bronly, volfactor, fd, mygroup, spec);
+
if (fd)
close(fd);
if (oldwf && ast_set_write_format(chan, oldwf) < 0)
ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
- ast_clear_flag(chan, AST_FLAG_SPYING);
-
- ast_channel_setoption(chan, AST_OPTION_TXGAIN, &zero_volume, sizeof(zero_volume), 0);
-
LOCAL_USER_REMOVE(u);
return res;