Newer
Older
char *recbase = NULL;
int fd = 0;
struct ast_flags flags;
struct spy_dtmf_options user_options = {
.cycle = '*',
.volume = '#',
.exit = '\0',
};
int oldwf = 0;
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);
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.");
}
}
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.");
}
}
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);
}
oldwf = chan->writeformat;
if (ast_set_write_format(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 (fd)
close(fd);
if (oldwf && 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',
};
int oldwf = 0;
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(context);
AST_APP_ARG(options);
);
char *parse = ast_strdupa(data);
AST_STANDARD_APP_ARGS(args, parse);
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(chan->context);
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.");
}
}
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.");
}
}
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 {
ast_clear_flag(&flags, AST_FLAGS_ALL);
}
oldwf = chan->writeformat;
if (ast_set_write_format(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 && 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)
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
{
const char *spec = "DAHDI";
struct ast_flags flags;
struct spy_dtmf_options user_options = {
.cycle = '#',
.volume = '\0',
.exit = '*',
};
int oldwf = 0;
int res;
char *mygroup = NULL;
ast_clear_flag(&flags, AST_FLAGS_ALL);
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);
oldwf = chan->writeformat;
if (ast_set_write_format(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 && 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");