Newer
Older
if (ptr && (num = atoi(ptr))) {
ast_say_digits(chan, num, "", ast_channel_language(chan));
}
Sean Bright
committed
}
res = channel_spy(chan, autochan, &volfactor, fd, user_options, flags, exitcontext);
num_spyed_upon++;
ast_autochan_destroy(autochan);
iter = ast_channel_iterator_destroy(iter);
Joshua Colp
committed
goto exit;
} else if (res == -2) {
res = 0;
ast_autochan_destroy(autochan);
iter = ast_channel_iterator_destroy(iter);
Joshua Colp
committed
goto exit;
struct ast_channel *next;
snprintf(nameprefix, AST_NAME_STRLEN, "%s/%d", spec, res);
if ((next = ast_channel_get_by_name_prefix(nameprefix, strlen(nameprefix)))) {
next_autochan = ast_autochan_setup(next);
next = ast_channel_unref(next);
/* stay on this channel, if it is still valid */
if (!ast_check_hangup(autochan->chan)) {
next_autochan = ast_autochan_setup(autochan->chan);
} else {
/* the channel is gone */
next_autochan = NULL;
Tilghman Lesher
committed
} else if (res == 0 && ast_test_flag(flags, OPTION_EXITONHANGUP)) {
iter = ast_channel_iterator_destroy(iter);
Tilghman Lesher
committed
goto exit;
iter = ast_channel_iterator_destroy(iter);
if (res == -1 || ast_check_hangup(chan))
break;
Russell Bryant
committed
if (ast_test_flag(flags, OPTION_STOP) && !next_autochan) {
break;
}
Joshua Colp
committed
exit:
ast_clear_flag(ast_channel_flags(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, const char *data)
char *myenforced = NULL;
char *mygroup = NULL;
char *recbase = NULL;
int fd = 0;
struct ast_flags flags;
struct spy_dtmf_options user_options = {
.cycle = '*',
.volume = '#',
.exit = '\0',
};
struct ast_format oldwf;
int volfactor = 0;
int res;
Mark Michelson
committed
char *mailbox = NULL;
char *name_context = NULL;
Tilghman Lesher
committed
AST_DECLARE_APP_ARGS(args,
AST_APP_ARG(spec);
AST_APP_ARG(options);
);
char *opts[OPT_ARG_ARRAY_SIZE];
char *parse = ast_strdupa(data);
AST_STANDARD_APP_ARGS(args, parse);
ast_format_clear(&oldwf);
Tilghman Lesher
committed
if (args.spec && !strcmp(args.spec, "all"))
args.spec = NULL;
Tilghman Lesher
committed
if (args.options) {
char tmp;
Tilghman Lesher
committed
ast_app_parse_options(spy_opts, &flags, opts, args.options);
if (ast_test_flag(&flags, OPTION_GROUP))
mygroup = opts[OPT_ARG_GROUP];
if (ast_test_flag(&flags, OPTION_RECORD) &&
if (ast_test_flag(&flags, OPTION_DTMF_EXIT) && opts[OPT_ARG_EXIT]) {
tmp = opts[OPT_ARG_EXIT][0];
if (strchr("0123456789*#", tmp) && tmp != '\0') {
user_options.exit = tmp;
} else {
ast_log(LOG_NOTICE, "Argument for option 'x' must be a valid DTMF digit.\n");
}
}
if (ast_test_flag(&flags, OPTION_DTMF_CYCLE) && opts[OPT_ARG_CYCLE]) {
tmp = opts[OPT_ARG_CYCLE][0];
if (strchr("0123456789*#", tmp) && tmp != '\0') {
user_options.cycle = tmp;
} else {
ast_log(LOG_NOTICE, "Argument for option 'c' must be a valid DTMF digit.\n");
}
}
if (ast_test_flag(&flags, OPTION_VOLUME) && opts[OPT_ARG_VOLUME]) {
int vol;
if ((sscanf(opts[OPT_ARG_VOLUME], "%30d", &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 (ast_test_flag(&flags, OPTION_PRIVATE))
ast_set_flag(&flags, OPTION_WHISPER);
if (ast_test_flag(&flags, OPTION_ENFORCED))
myenforced = opts[OPT_ARG_ENFORCED];
Mark Michelson
committed
if (ast_test_flag(&flags, OPTION_NAME)) {
if (!ast_strlen_zero(opts[OPT_ARG_NAME])) {
char *delimiter;
if ((delimiter = strchr(opts[OPT_ARG_NAME], '@'))) {
mailbox = opts[OPT_ARG_NAME];
*delimiter++ = '\0';
name_context = delimiter;
} else {
mailbox = opts[OPT_ARG_NAME];
}
}
}
} else {
ast_clear_flag(&flags, AST_FLAGS_ALL);
}
ast_format_copy(&oldwf, ast_channel_writeformat(chan));
if (ast_set_write_format_by_id(chan, AST_FORMAT_SLINEAR) < 0) {
ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
return -1;
}
if (recbase) {
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, AST_FILE_MODE)) <= 0) {
ast_log(LOG_WARNING, "Cannot open '%s' for recording\n", filename);
fd = 0;
}
}
res = common_exec(chan, &flags, volfactor, fd, &user_options, mygroup, myenforced, args.spec, NULL, NULL, mailbox, name_context);
if (oldwf.id && ast_set_write_format(chan, &oldwf) < 0)
ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
Tilghman Lesher
committed
if (ast_test_flag(&flags, OPTION_EXITONHANGUP)) {
ast_verb(3, "Stopped spying due to the spied-on channel hanging up.\n");
}
static int extenspy_exec(struct ast_channel *chan, const char *data)
Tilghman Lesher
committed
char *ptr, *exten = NULL;
char *mygroup = NULL;
char *recbase = NULL;
int fd = 0;
struct ast_flags flags;
struct spy_dtmf_options user_options = {
.cycle = '*',
.volume = '#',
.exit = '\0',
};
struct ast_format oldwf;
Mark Michelson
committed
char *mailbox = NULL;
char *name_context = NULL;
Tilghman Lesher
committed
AST_DECLARE_APP_ARGS(args,
AST_APP_ARG(context);
AST_APP_ARG(options);
);
char *parse = ast_strdupa(data);
AST_STANDARD_APP_ARGS(args, parse);
ast_format_clear(&oldwf);
Tilghman Lesher
committed
if (!ast_strlen_zero(args.context) && (ptr = strchr(args.context, '@'))) {
exten = args.context;
*ptr++ = '\0';
args.context = ptr;
Tilghman Lesher
committed
if (ast_strlen_zero(args.context))
args.context = ast_strdupa(ast_channel_context(chan));
Tilghman Lesher
committed
if (args.options) {
char tmp;
Tilghman Lesher
committed
ast_app_parse_options(spy_opts, &flags, opts, args.options);
if (ast_test_flag(&flags, OPTION_GROUP))
mygroup = opts[OPT_ARG_GROUP];
if (ast_test_flag(&flags, OPTION_RECORD) &&
if (ast_test_flag(&flags, OPTION_DTMF_EXIT) && opts[OPT_ARG_EXIT]) {
tmp = opts[OPT_ARG_EXIT][0];
if (strchr("0123456789*#", tmp) && tmp != '\0') {
user_options.exit = tmp;
} else {
ast_log(LOG_NOTICE, "Argument for option 'x' must be a valid DTMF digit.\n");
}
}
if (ast_test_flag(&flags, OPTION_DTMF_CYCLE) && opts[OPT_ARG_CYCLE]) {
tmp = opts[OPT_ARG_CYCLE][0];
if (strchr("0123456789*#", tmp) && tmp != '\0') {
user_options.cycle = tmp;
} else {
ast_log(LOG_NOTICE, "Argument for option 'c' must be a valid DTMF digit.\n");
}
}
if (ast_test_flag(&flags, OPTION_VOLUME) && opts[OPT_ARG_VOLUME]) {
int vol;
if ((sscanf(opts[OPT_ARG_VOLUME], "%30d", &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 (ast_test_flag(&flags, OPTION_PRIVATE))
ast_set_flag(&flags, OPTION_WHISPER);
Mark Michelson
committed
if (ast_test_flag(&flags, OPTION_NAME)) {
if (!ast_strlen_zero(opts[OPT_ARG_NAME])) {
char *delimiter;
if ((delimiter = strchr(opts[OPT_ARG_NAME], '@'))) {
mailbox = opts[OPT_ARG_NAME];
*delimiter++ = '\0';
name_context = delimiter;
} else {
mailbox = opts[OPT_ARG_NAME];
}
}
}
} else {
/* Coverity - This uninit_use should be ignored since this macro initializes the flags */
ast_clear_flag(&flags, AST_FLAGS_ALL);
}
ast_format_copy(&oldwf, ast_channel_writeformat(chan));
if (ast_set_write_format_by_id(chan, AST_FORMAT_SLINEAR) < 0) {
ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
return -1;
}
if (recbase) {
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, AST_FILE_MODE)) <= 0) {
ast_log(LOG_WARNING, "Cannot open '%s' for recording\n", filename);
fd = 0;
}
}
res = common_exec(chan, &flags, volfactor, fd, &user_options, mygroup, NULL, NULL, exten, args.context, mailbox, name_context);
Anthony Minessale II
committed
close(fd);
if (oldwf.id && ast_set_write_format(chan, &oldwf) < 0)
Anthony Minessale II
committed
ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
static int dahdiscan_exec(struct ast_channel *chan, const char *data)
{
const char *spec = "DAHDI";
struct ast_flags flags;
struct spy_dtmf_options user_options = {
.cycle = '#',
.volume = '\0',
.exit = '*',
};
struct ast_format oldwf;
int res;
char *mygroup = NULL;
/* Coverity - This uninit_use should be ignored since this macro initializes the flags */
ast_clear_flag(&flags, AST_FLAGS_ALL);
ast_format_clear(&oldwf);
if (!ast_strlen_zero(data)) {
mygroup = ast_strdupa(data);
}
ast_set_flag(&flags, OPTION_DTMF_EXIT);
ast_set_flag(&flags, OPTION_DTMF_CYCLE);
ast_set_flag(&flags, OPTION_DAHDI_SCAN);
ast_format_copy(&oldwf, ast_channel_writeformat(chan));
if (ast_set_write_format_by_id(chan, AST_FORMAT_SLINEAR) < 0) {
ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
return -1;
}
res = common_exec(chan, &flags, 0, 0, &user_options, mygroup, NULL, spec, NULL, NULL, NULL, NULL);
if (oldwf.id && ast_set_write_format(chan, &oldwf) < 0)
ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
return res;
}
static int unload_module(void)
Russell Bryant
committed
res |= ast_unregister_application(app_chan);
res |= ast_unregister_application(app_ext);
res |= ast_unregister_application(app_dahdiscan);
Russell Bryant
committed
return res;
static int load_module(void)
res |= ast_register_application_xml(app_chan, chanspy_exec);
res |= ast_register_application_xml(app_ext, extenspy_exec);
res |= ast_register_application_xml(app_dahdiscan, dahdiscan_exec);
AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Listen to the audio of an active channel");