diff options
author | kpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b> | 2006-07-27 23:00:27 +0000 |
---|---|---|
committer | kpfleming <kpfleming@f38db490-d61c-443f-a65b-d21fe96a405b> | 2006-07-27 23:00:27 +0000 |
commit | fafa6738a3e225eb27e3af06cdefd266f1119679 (patch) | |
tree | 9ba2142ecd71a11a7c6cdc20feda4fb093fe40c7 /apps | |
parent | 87c1d75227977f85781104edaff23421c07f61c4 (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')
-rw-r--r-- | apps/app_chanspy.c | 228 |
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; |