2 * Asterisk -- A telephony toolkit for Linux.
4 * ChanSpy Listen in on any channel.
6 * Copyright (C) 2005 Anthony Minessale II (anthmct@yahoo.com)
10 * This program is free software, distributed under the terms of
11 * the GNU General Public License
14 #include <asterisk/file.h>
15 #include <asterisk/logger.h>
16 #include <asterisk/channel.h>
17 #include <asterisk/features.h>
18 #include <asterisk/options.h>
19 #include <asterisk/app.h>
20 #include <asterisk/utils.h>
21 #include <asterisk/say.h>
22 #include <asterisk/pbx.h>
23 #include <asterisk/translate.h>
24 #include <asterisk/module.h>
25 #include <asterisk/lock.h>
31 AST_MUTEX_DEFINE_STATIC(modlock);
33 #define ast_fit_in_short(in) (in < -32768 ? -32768 : in > 32767 ? 32767 : in)
34 #define AST_NAME_STRLEN 256
35 #define ALL_DONE(u, ret) LOCAL_USER_REMOVE(u); return ret;
36 #define get_volfactor(x) x ? ((x > 0) ? (1 << x) : ((1 << abs(x)) * -1)) : 0
37 #define minmax(x,y) x ? (x > y) ? y : ((x < (y * -1)) ? (y * -1) : x) : 0
40 static char *synopsis = "Tap into any type of asterisk channel and listen to audio";
41 static char *app = "ChanSpy";
42 static char *desc = " Chanspy([<scanspec>][|<options>])\n\n"
44 " - q: quiet, don't announce channels beep, etc.\n"
45 " - b: bridged, only spy on channels involved in a bridged call.\n"
46 " - v([-4..4]): adjust the initial volume. (negative is quieter)\n"
47 " - g(grp): enforce group. Match only calls where their ${SPYGROUP} is 'grp'.\n\n"
48 "If <scanspec> is specified, only channel names *beginning* with that string will be scanned.\n"
49 "('all' or an empty string are also both valid <scanspec>)\n\n"
51 "Dialing # cycles the volume level.\n"
52 "Dialing * will stop spying and look for another channel to spy on.\n"
53 "Dialing a series of digits followed by # builds a channel name to append to <scanspec>\n"
54 "(e.g. run Chanspy(Agent) and dial 1234# while spying to jump to channel Agent/1234)\n\n"
57 #define OPTION_QUIET (1 << 0) /* Quiet, no announcement */
58 #define OPTION_BRIDGED (1 << 1) /* Only look at bridged calls */
59 #define OPTION_VOLUME (1 << 2) /* Specify initial volume */
60 #define OPTION_GROUP (1 << 3) /* Only look at channels in group */
62 AST_DECLARE_OPTIONS(chanspy_opts,{
63 ['q'] = { OPTION_QUIET },
64 ['b'] = { OPTION_BRIDGED },
65 ['v'] = { OPTION_VOLUME, 1 },
66 ['g'] = { OPTION_GROUP, 2 },
72 struct chanspy_translation_helper {
74 struct ast_channel_spy spy;
80 struct ast_trans_pvt *trans0;
84 struct ast_trans_pvt *trans1;
89 struct ast_frame frame;
99 static struct ast_channel *local_get_channel_by_name(char *name);
100 static struct ast_channel *local_get_channel_begin_name(char *name);
101 static struct ast_channel *local_channel_walk(struct ast_channel *chan);
102 static void spy_release(struct ast_channel *chan, void *data);
103 static void *spy_alloc(struct ast_channel *chan, void *params);
104 static struct ast_frame *spy_queue_shift(struct ast_channel_spy *spy, int qnum);
105 static void ast_flush_spy_queue(struct ast_channel_spy *spy);
106 static int spy_generate(struct ast_channel *chan, void *data, int len, int samples);
107 static void start_spying(struct ast_channel *chan, struct ast_channel *spychan, struct ast_channel_spy *spy);
108 static void stop_spying(struct ast_channel *chan, struct ast_channel_spy *spy);
109 static int channel_spy(struct ast_channel *chan, struct ast_channel *spyee, int *volfactor);
110 static int chanspy_exec(struct ast_channel *chan, void *data);
113 static struct ast_channel *local_get_channel_by_name(char *name)
115 struct ast_channel *ret;
116 ast_mutex_lock(&modlock);
117 if ((ret = ast_get_channel_by_name_locked(name))) {
118 ast_mutex_unlock(&ret->lock);
120 ast_mutex_unlock(&modlock);
125 static struct ast_channel *local_channel_walk(struct ast_channel *chan)
127 struct ast_channel *ret;
128 ast_mutex_lock(&modlock);
129 if ((ret = ast_channel_walk_locked(chan))) {
130 ast_mutex_unlock(&ret->lock);
132 ast_mutex_unlock(&modlock);
136 static struct ast_channel *local_get_channel_begin_name(char *name)
138 struct ast_channel *chan, *ret = NULL;
139 ast_mutex_lock(&modlock);
140 chan = local_channel_walk(NULL);
142 if (!strncmp(chan->name, name, strlen(name))) {
146 chan = local_channel_walk(chan);
148 ast_mutex_unlock(&modlock);
154 static void spy_release(struct ast_channel *chan, void *data)
156 struct chanspy_translation_helper *csth = data;
160 ast_translator_free_path(csth->trans0);
164 ast_translator_free_path(csth->trans1);
183 static void *spy_alloc(struct ast_channel *chan, void *params)
188 static struct ast_frame *spy_queue_shift(struct ast_channel_spy *spy, int qnum)
192 if (qnum < 0 || qnum > 1)
195 f = spy->queue[qnum];
197 spy->queue[qnum] = f->next;
204 static void ast_flush_spy_queue(struct ast_channel_spy *spy)
206 struct ast_frame *f=NULL;
208 ast_mutex_lock(&spy->lock);
211 while((f = spy_queue_shift(spy, x)))
214 ast_mutex_unlock(&spy->lock);
217 static int spy_generate(struct ast_channel *chan, void *data, int len, int samples)
219 struct ast_frame *f, *f0, *f1;
220 int x, vf, dlen, maxsamp, loops;
221 struct chanspy_translation_helper *csth = data;
223 if (csth->rsamples < csth->samples) {
224 csth->rsamples += samples;
227 csth->rsamples += samples;
232 x = vf = dlen = maxsamp = 0;
233 if (csth->rsamples == csth->samples) {
234 csth->rsamples = csth->samples = 0;
237 ast_mutex_lock(&csth->spy.lock);
238 f0 = spy_queue_shift(&csth->spy, 0);
239 f1 = spy_queue_shift(&csth->spy, 1);
240 ast_mutex_unlock(&csth->spy.lock);
242 if (csth->spy.status == CHANSPY_DONE) {
250 if (f0 && csth->fmt0 && csth->fmt0 != f0->subclass) {
251 ast_translator_free_path(csth->trans0);
253 csth->fmt0 = csth->fmt0;
256 if (f1 && csth->fmt1 && csth->fmt1 != f1->subclass) {
257 ast_translator_free_path(csth->trans1);
259 csth->fmt1 = csth->fmt1;
262 if (!csth->fmt0 && f0) {
263 csth->fmt0 = f0->subclass;
266 if (!csth->fmt1 && f1) {
267 csth->fmt1 = f1->subclass;
270 if (csth->fmt0 && csth->fmt0 != AST_FORMAT_SLINEAR && !csth->trans0) {
271 if ((csth->trans0 = ast_translator_build_path(AST_FORMAT_SLINEAR, csth->fmt0)) == NULL) {
272 ast_log(LOG_WARNING, "Cannot build a path from %s to slin\n", ast_getformatname(csth->fmt0));
273 csth->spy.status = CHANSPY_DONE;
277 if (csth->fmt1 && csth->fmt1 != AST_FORMAT_SLINEAR && !csth->trans1) {
278 if ((csth->trans1 = ast_translator_build_path(AST_FORMAT_SLINEAR, csth->fmt1)) == NULL) {
279 ast_log(LOG_WARNING, "Cannot build a path from %s to slin\n", ast_getformatname(csth->fmt1));
280 csth->spy.status = CHANSPY_DONE;
287 if ((f = ast_translate(csth->trans0, f0, 0))) {
288 if (csth->len0 < f->datalen) {
290 if (!(csth->buf0 = malloc(f->datalen * 2))) {
291 csth->spy.status = CHANSPY_DONE;
295 if (!realloc(csth->buf0, f->datalen * 2)) {
296 csth->spy.status = CHANSPY_DONE;
300 csth->len0 = f->datalen;
302 memcpy(csth->buf0, f->data, f->datalen);
303 maxsamp = f->samples;
309 memcpy(csth->buf0, f0->data, f0->datalen);
310 maxsamp = f0->samples;
316 if ((f = ast_translate(csth->trans1, f1, 0))) {
317 if (csth->len1 < f->datalen) {
319 if (!(csth->buf1 = malloc(f->datalen))) {
320 csth->spy.status = CHANSPY_DONE;
324 if (!realloc(csth->buf1, f->datalen)) {
325 csth->spy.status = CHANSPY_DONE;
329 csth->len1 = f->datalen;
331 memcpy(csth->buf1, f->data, f->datalen);
332 if (f->samples > maxsamp) {
333 maxsamp = f->samples;
341 memcpy(csth->buf1, f1->data, f1->datalen);
342 if (f1->samples > maxsamp) {
343 maxsamp = f1->samples;
348 vf = get_volfactor(csth->volfactor);
351 dlen = (csth->len0 > csth->len1) ? csth->len0 : csth->len1;
353 if (csth->len < dlen) {
355 if (!(csth->buf = malloc(dlen*2))) {
356 csth->spy.status = CHANSPY_DONE;
360 if (!realloc(csth->buf, dlen * 2)) {
361 csth->spy.status = CHANSPY_DONE;
368 for(x=0; x < maxsamp; x++) {
371 csth->buf0[x] /= abs(vf);
374 csth->buf1[x] /= abs(vf);
385 if (x < csth->len0 && x < csth->len1) {
386 csth->buf[x] = ast_fit_in_short(csth->buf0[x] + csth->buf1[x]);
387 } else if (x < csth->len0) {
388 csth->buf[x] = csth->buf0[x];
389 } else if (x < csth->len1) {
390 csth->buf[x] = csth->buf1[x];
392 } else if (f0 && x < csth->len0) {
393 csth->buf[x] = csth->buf0[x];
394 } else if (f1 && x < csth->len1) {
395 csth->buf[x] = csth->buf1[x];
399 csth->frame.data = csth->buf;
400 csth->frame.samples = maxsamp;
401 csth->frame.datalen = csth->frame.samples * 2;
402 csth->samples += csth->frame.samples;
404 if (ast_write(chan, &csth->frame)) {
405 csth->spy.status = CHANSPY_DONE;
417 ast_log(LOG_WARNING, "Too Many Loops Bailing Out....");
420 } while (csth->samples < csth->rsamples);
425 static struct ast_generator spygen = {
427 release: spy_release,
428 generate: spy_generate,
431 static void start_spying(struct ast_channel *chan, struct ast_channel *spychan, struct ast_channel_spy *spy)
434 struct ast_channel_spy *cptr=NULL;
435 struct ast_channel *peer;
438 ast_log(LOG_WARNING, "Attaching %s to %s\n", spychan->name, chan->name);
441 ast_mutex_lock(&chan->lock);
443 for(cptr=chan->spiers;cptr && cptr->next;cptr=cptr->next);
448 ast_mutex_unlock(&chan->lock);
449 if ( ast_test_flag(chan, AST_FLAG_NBRIDGE) && (peer = ast_bridged_channel(chan))) {
450 ast_softhangup(peer, AST_SOFTHANGUP_UNBRIDGE);
455 static void stop_spying(struct ast_channel *chan, struct ast_channel_spy *spy)
457 struct ast_channel_spy *cptr=NULL, *prev=NULL;
460 while(ast_mutex_trylock(&chan->lock)) {
461 /* if its locked already it's almost surely hanging up and we are too late
462 we can safely remove the head pointer if it points at us without needing a lock.
463 since everybody spying will be in the same boat whomever is pointing at the head
464 will surely erase it which is all we really need since it's a linked list of
465 staticly declared structs that belong to each spy.
467 if (chan->spiers == spy) {
478 for(cptr=chan->spiers; cptr; cptr=cptr->next) {
481 prev->next = cptr->next;
488 ast_mutex_unlock(&chan->lock);
492 static int channel_spy(struct ast_channel *chan, struct ast_channel *spyee, int *volfactor)
494 struct chanspy_translation_helper csth;
495 int running = 1, res = 0, x = 0;
500 if (chan && !ast_check_hangup(chan) && spyee && !ast_check_hangup(spyee)) {
501 memset(inp, 0, sizeof(inp));
502 name = ast_strdupa(spyee->name);
503 if (option_verbose >= 2)
504 ast_verbose(VERBOSE_PREFIX_2 "Spying on channel %s\n", name);
506 memset(&csth, 0, sizeof(csth));
507 csth.spy.status = CHANSPY_RUNNING;
508 ast_mutex_init(&csth.spy.lock);
509 csth.volfactor = *volfactor;
510 csth.frame.frametype = AST_FRAME_VOICE;
511 csth.frame.subclass = AST_FORMAT_SLINEAR;
512 csth.frame.datalen = 320;
513 csth.frame.samples = 160;
514 start_spying(spyee, chan, &csth.spy);
515 ast_activate_generator(chan, &spygen, &csth);
517 while(csth.spy.status == CHANSPY_RUNNING &&
518 chan && !ast_check_hangup(chan) &&
520 !ast_check_hangup(spyee)
522 (res = ast_waitfor(chan, -1) > -1)) {
523 if ((f = ast_read(chan))) {
525 if (f->frametype == AST_FRAME_DTMF) {
535 if (x == sizeof(inp)) {
543 } else if (res == '*') {
545 } else if (res == '#') {
546 if (!ast_strlen_zero(inp)) {
547 running = x ? atoi(inp) : -1;
551 if (csth.volfactor > 4) {
554 if (option_verbose > 2) {
555 ast_verbose(VERBOSE_PREFIX_3"Setting spy volume on %s to %d\n", chan->name, csth.volfactor);
557 *volfactor = csth.volfactor;
559 } else if (res >= 48 && res <= 57) {
563 ast_deactivate_generator(chan);
564 stop_spying(spyee, &csth.spy);
566 if (option_verbose >= 2) {
567 ast_verbose(VERBOSE_PREFIX_2 "Done Spying on channel %s\n", name);
569 ast_flush_spy_queue(&csth.spy);
573 ast_mutex_destroy(&csth.spy.lock);
579 static int chanspy_exec(struct ast_channel *chan, void *data)
582 struct ast_channel *peer=NULL, *prev=NULL;
583 char name[AST_NAME_STRLEN],
584 peer_name[AST_NAME_STRLEN],
600 struct ast_flags flags;
603 if (!(args = ast_strdupa((char *)data))) {
604 ast_log(LOG_ERROR, "Out of memory!\n");
608 if (ast_set_read_format(chan, AST_FORMAT_SLINEAR) < 0) {
609 ast_log(LOG_ERROR, "Could Not Set Read Format.\n");
613 if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
614 ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
621 ast_set_flag(chan, AST_FLAG_SPYING); /* so nobody can spy on us while we are spying */
624 if ((argc = ast_separate_app_args(args, '|', argv, sizeof(argv) / sizeof(argv[0])))) {
629 if (ast_strlen_zero(spec) || !strcmp(spec, "all")) {
636 ast_parseoptions(chanspy_opts, &flags, opts, options);
637 if (ast_test_flag(&flags, OPTION_GROUP)) {
640 silent = ast_test_flag(&flags, OPTION_QUIET);
641 bronly = ast_test_flag(&flags, OPTION_BRIDGED);
642 if (ast_test_flag(&flags, OPTION_VOLUME) && opts[1]) {
643 if (sscanf(opts[0], "%d", &volfactor) != 1)
644 ast_log(LOG_NOTICE, "volfactor must be a number between -4 and 4\n");
646 volfactor = minmax(volfactor, 4);
653 res = ast_streamfile(chan, "beep", chan->language);
655 res = ast_waitstream(chan, "");
657 ast_clear_flag(chan, AST_FLAG_SPYING);
662 res = ast_waitfordigit(chan, waitms);
664 ast_clear_flag(chan, AST_FLAG_SPYING);
668 peer = local_channel_walk(NULL);
675 if (peer == prev && !chosen) {
679 group = pbx_builtin_getvar_helper(peer, "SPYGROUP");
681 if (!group || strcmp(mygroup, group)) {
686 if (igrp && (!spec || ((strlen(spec) < strlen(peer->name) &&
687 !strncasecmp(peer->name, spec, strlen(spec)))))) {
688 if (peer && (!bronly || ast_bridged_channel(peer)) &&
689 !ast_check_hangup(peer) && !ast_test_flag(peer, AST_FLAG_SPYING)) {
692 strncpy(peer_name, peer->name, AST_NAME_STRLEN);
693 ptr = strchr(peer_name, '/');
696 for (x = 0 ; x < strlen(peer_name) ; x++) {
697 if (peer_name[x] == '/') {
700 peer_name[x] = tolower(peer_name[x]);
704 if (ast_fileexists(peer_name, NULL, NULL) != -1) {
705 res = ast_streamfile(chan, peer_name, chan->language);
707 res = ast_waitstream(chan, "");
711 res = ast_say_character_str(chan, peer_name, "", chan->language);
713 ast_say_digits(chan, atoi(ptr), "", chan->language);
717 res = channel_spy(chan, peer, &volfactor);
719 ast_clear_flag(chan, AST_FLAG_SPYING);
721 } else if (res > 1 && spec) {
722 snprintf(name, AST_NAME_STRLEN, "%s/%d", spec, res);
723 if ((peer = local_get_channel_begin_name(name))) {
731 if ((peer = local_channel_walk(peer)) == NULL) {
735 waitms = count ? 100 : 5000;
739 ast_clear_flag(chan, AST_FLAG_SPYING);
743 int unload_module(void)
745 STANDARD_HANGUP_LOCALUSERS;
746 return ast_unregister_application(app);
749 int load_module(void)
751 return ast_register_application(app, chanspy_exec, synopsis, desc);
754 char *description(void)
762 STANDARD_USECOUNT(res);
768 return ASTERISK_GPL_KEY;