2646f5618882f112a08a32ca72eac03eefe080b3
[asterisk/asterisk.git] / apps / app_chanspy.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2005 Anthony Minessale II (anthmct@yahoo.com)
5  * Copyright (C) 2005 - 2008, Digium, Inc.
6  *
7  * A license has been granted to Digium (via disclaimer) for the use of
8  * this code.
9  *
10  * See http://www.asterisk.org for more information about
11  * the Asterisk project. Please do not directly contact
12  * any of the maintainers of this project for assistance;
13  * the project provides a web site, mailing lists and IRC
14  * channels for your use.
15  *
16  * This program is free software, distributed under the terms of
17  * the GNU General Public License Version 2. See the LICENSE file
18  * at the top of the source tree.
19  */
20
21 /*! \file
22  *
23  * \brief ChanSpy: Listen in on any channel.
24  *
25  * \author Anthony Minessale II <anthmct@yahoo.com>
26  * \author Joshua Colp <jcolp@digium.com>
27  * \author Russell Bryant <russell@digium.com>
28  *
29  * \ingroup applications
30  */
31
32 #include "asterisk.h"
33
34 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
35
36 #include <ctype.h>
37
38 #include "asterisk/paths.h" /* use ast_config_AST_MONITOR_DIR */
39 #include "asterisk/file.h"
40 #include "asterisk/channel.h"
41 #include "asterisk/audiohook.h"
42 #include "asterisk/features.h"
43 #include "asterisk/app.h"
44 #include "asterisk/utils.h"
45 #include "asterisk/say.h"
46 #include "asterisk/pbx.h"
47 #include "asterisk/translate.h"
48 #include "asterisk/module.h"
49 #include "asterisk/lock.h"
50 #include "asterisk/options.h"
51
52 #define AST_NAME_STRLEN 256
53 #define NUM_SPYGROUPS 128
54
55  /* "DAHDI/pseudo" is twelve characters */
56 #define PSEUDO_CHAN_LEN 12
57
58 static const char *tdesc = "Listen to a channel, and optionally whisper into it";
59 static const char *app_chan = "ChanSpy";
60 static const char *desc_chan =
61 "  ChanSpy([chanprefix][,options]): This application is used to listen to the\n"
62 "audio from an Asterisk channel. This includes the audio coming in and\n"
63 "out of the channel being spied on. If the 'chanprefix' parameter is specified,\n"
64 "only channels beginning with this string will be spied upon.\n"
65 "  While spying, the following actions may be performed:\n"
66 "    - Dialing # cycles the volume level.\n"
67 "    - Dialing * will stop spying and look for another channel to spy on.\n"
68 "    - Dialing a series of digits followed by # builds a channel name to append\n"
69 "      to 'chanprefix'. For example, executing ChanSpy(Agent) and then dialing\n"
70 "      the digits '1234#' while spying will begin spying on the channel\n"
71 "      'Agent/1234'. Note that this feature will be overriden if the 'd' option\n"
72 "       is used\n"
73 "  Note: The X option supersedes the three features above in that if a valid\n"
74 "        single digit extension exists in the correct context ChanSpy will\n"
75 "        exit to it. This also disables choosing a channel based on 'chanprefix'\n"
76 "        and a digit sequence.\n"
77 "  Options:\n"
78 "    b                      - Only spy on channels involved in a bridged call.\n"
79 "    B                      - Instead of whispering on a single channel barge in on both\n"
80 "                             channels involved in the call.\n"
81 "    d                      - Override the typical numeric DTMF functionality and instead\n"
82 "                             use DTMF to switch between spy modes.\n"
83 "                                     4 = spy mode\n"
84 "                                     5 = whisper mode\n"
85 "                                     6 = barge mode\n"
86 "    g(grp)                 - Only spy on channels in which one or more of the groups \n"
87 "                             listed in 'grp' matches one or more groups from the\n"
88 "                             SPYGROUP variable set on the channel to be spied upon.\n"
89 "                             Note that both 'grp' and SPYGROUP can contain either a\n"
90 "                             single group or a colon-delimited list of groups, such\n"
91 "                             as 'sales:support:accounting'.\n"
92 "    n([mailbox][@context]) - Say the name of the person being spied on if that person has recorded\n"
93 "                             his/her name. If a context is specified, then that voicemail context will\n"
94 "                             be searched when retrieving the name, otherwise the \"default\" context\n"
95 "                             will be searched. If no mailbox is specified, then the channel name will\n"
96 "                             be used when searching for the name (i.e. if SIP/1000 is the channel being\n"
97 "                             spied on and no mailbox is specified, then \"1000\" will be used when searching\n"
98 "                             for the name).\n"
99 "    q                      - Don't play a beep when beginning to spy on a channel, or speak the\n"
100 "                             selected channel name.\n"
101 "    r[(basename)]          - Record the session to the monitor spool directory. An\n"
102 "                             optional base for the filename may be specified. The\n"
103 "                             default is 'chanspy'.\n"
104 "    s                      - Skip the playback of the channel type (i.e. SIP, IAX, etc) when\n"
105 "                             speaking the selected channel name.\n"
106 "    v([value])             - Adjust the initial volume in the range from -4 to 4. A\n"
107 "                             negative value refers to a quieter setting.\n"
108 "    w                      - Enable 'whisper' mode, so the spying channel can talk to\n"
109 "                             the spied-on channel.\n"
110 "    W                      - Enable 'private whisper' mode, so the spying channel can\n"
111 "                             talk to the spied-on channel but cannot listen to that\n"
112 "                             channel.\n"
113 "    o                      - Only listen to audio coming from this channel.\n"
114 "    X                      - Allow the user to exit ChanSpy to a valid single digit\n"
115 "                             numeric extension in the current context or the context\n"
116 "                             specified by the SPY_EXIT_CONTEXT channel variable. The\n"
117 "                             name of the last channel that was spied on will be stored\n"
118 "                             in the SPY_CHANNEL variable.\n"
119 "    e(ext)                 - Enable 'enforced' mode, so the spying channel can\n"
120 "                             only monitor extensions whose name is in the 'ext' : \n"
121 "                             delimited list.\n"
122 ;
123
124 static const char *app_ext = "ExtenSpy";
125 static const char *desc_ext =
126 "  ExtenSpy(exten[@context][,options]): This application is used to listen to the\n"
127 "audio from an Asterisk channel. This includes the audio coming in and\n"
128 "out of the channel being spied on. Only channels created by outgoing calls for the\n"
129 "specified extension will be selected for spying. If the optional context is not\n"
130 "supplied, the current channel's context will be used.\n"
131 "  While spying, the following actions may be performed:\n"
132 "    - Dialing # cycles the volume level.\n"
133 "    - Dialing * will stop spying and look for another channel to spy on.\n"
134 "  Note: The X option superseeds the two features above in that if a valid\n"
135 "        single digit extension exists in the correct context it ChanSpy will\n"
136 "        exit to it.\n"
137 "  Options:\n"
138 "    b                      - Only spy on channels involved in a bridged call.\n"
139 "    B                      - Instead of whispering on a single channel barge in on both\n"
140 "                             channels involved in the call.\n"
141 "    d                      - Override the typical numeric DTMF functionality and instead\n"
142 "                             use DTMF to switch between spy modes.\n"
143 "                                     4 = spy mode\n"
144 "                                     5 = whisper mode\n"
145 "                                     6 = barge mode\n"
146 "    g(grp)                 - Only spy on channels in which one or more of the groups \n"
147 "                             listed in 'grp' matches one or more groups from the\n"
148 "                             SPYGROUP variable set on the channel to be spied upon.\n"
149 "                             Note that both 'grp' and SPYGROUP can contain either a\n"
150 "                             single group or a colon-delimited list of groups, such\n"
151 "                             as 'sales:support:accounting'.\n"
152 "    n([mailbox][@context]) - Say the name of the person being spied on if that person has recorded\n"
153 "                             his/her name. If a context is specified, then that voicemail context will\n"
154 "                             be searched when retrieving the name, otherwise the \"default\" context\n"
155 "                             will be searched. If no mailbox is specified, then the channel name will\n"
156 "                             be used when searching for the name (i.e. if SIP/1000 is the channel being\n"
157 "                             spied on and no mailbox is specified, then \"1000\" will be used when searching\n"
158 "                             for the name).\n"
159 "    q                      - Don't play a beep when beginning to spy on a channel, or speak the\n"
160 "                             selected channel name.\n"
161 "    r[(basename)]          - Record the session to the monitor spool directory. An\n"
162 "                             optional base for the filename may be specified. The\n"
163 "                             default is 'chanspy'.\n"
164 "    s                      - Skip the playback of the channel type (i.e. SIP, IAX, etc) when\n"
165 "                             speaking the selected channel name.\n"
166 "    v([value])             - Adjust the initial volume in the range from -4 to 4. A\n"
167 "                             negative value refers to a quieter setting.\n"
168 "    w                      - Enable 'whisper' mode, so the spying channel can talk to\n"
169 "                             the spied-on channel.\n"
170 "    W                      - Enable 'private whisper' mode, so the spying channel can\n"
171 "                             talk to the spied-on channel but cannot listen to that\n"
172 "                             channel.\n"
173 "    o                      - Only listen to audio coming from this channel.\n"
174 "    X                      - Allow the user to exit ChanSpy to a valid single digit\n"
175 "                             numeric extension in the current context or the context\n"
176 "                             specified by the SPY_EXIT_CONTEXT channel variable. The\n"
177 "                             name of the last channel that was spied on will be stored\n"
178 "                             in the SPY_CHANNEL variable.\n"
179 ;
180
181 enum {
182         OPTION_QUIET             = (1 << 0),    /* Quiet, no announcement */
183         OPTION_BRIDGED           = (1 << 1),    /* Only look at bridged calls */
184         OPTION_VOLUME            = (1 << 2),    /* Specify initial volume */
185         OPTION_GROUP             = (1 << 3),    /* Only look at channels in group */
186         OPTION_RECORD            = (1 << 4),
187         OPTION_WHISPER           = (1 << 5),
188         OPTION_PRIVATE           = (1 << 6),    /* Private Whisper mode */
189         OPTION_READONLY          = (1 << 7),    /* Don't mix the two channels */
190         OPTION_EXIT              = (1 << 8),    /* Exit to a valid single digit extension */
191         OPTION_ENFORCED          = (1 << 9),    /* Enforced mode */
192         OPTION_NOTECH            = (1 << 10),   /* Skip technology name playback */
193         OPTION_BARGE             = (1 << 11),   /* Barge mode (whisper to both channels) */
194         OPTION_NAME              = (1 << 12),   /* Say the name of the person on whom we will spy */
195         OPTION_DTMF_SWITCH_MODES = (1 << 13),   /*Allow numeric DTMF to switch between chanspy modes */
196 } chanspy_opt_flags;
197
198 enum {
199         OPT_ARG_VOLUME = 0,
200         OPT_ARG_GROUP,
201         OPT_ARG_RECORD,
202         OPT_ARG_ENFORCED,
203         OPT_ARG_NAME,
204         OPT_ARG_ARRAY_SIZE,
205 } chanspy_opt_args;
206
207 AST_APP_OPTIONS(spy_opts, {
208         AST_APP_OPTION('q', OPTION_QUIET),
209         AST_APP_OPTION('b', OPTION_BRIDGED),
210         AST_APP_OPTION('B', OPTION_BARGE),
211         AST_APP_OPTION('w', OPTION_WHISPER),
212         AST_APP_OPTION('W', OPTION_PRIVATE),
213         AST_APP_OPTION_ARG('v', OPTION_VOLUME, OPT_ARG_VOLUME),
214         AST_APP_OPTION_ARG('g', OPTION_GROUP, OPT_ARG_GROUP),
215         AST_APP_OPTION_ARG('r', OPTION_RECORD, OPT_ARG_RECORD),
216         AST_APP_OPTION_ARG('e', OPTION_ENFORCED, OPT_ARG_ENFORCED),
217         AST_APP_OPTION('o', OPTION_READONLY),
218         AST_APP_OPTION('X', OPTION_EXIT),
219         AST_APP_OPTION('s', OPTION_NOTECH),
220         AST_APP_OPTION_ARG('n', OPTION_NAME, OPT_ARG_NAME),
221         AST_APP_OPTION('d', OPTION_DTMF_SWITCH_MODES),
222 });
223
224 int next_unique_id_to_use = 0;
225
226 struct chanspy_translation_helper {
227         /* spy data */
228         struct ast_audiohook spy_audiohook;
229         struct ast_audiohook whisper_audiohook;
230         struct ast_audiohook bridge_whisper_audiohook;
231         int fd;
232         int volfactor;
233 };
234
235 static void *spy_alloc(struct ast_channel *chan, void *data)
236 {
237         /* just store the data pointer in the channel structure */
238         return data;
239 }
240
241 static void spy_release(struct ast_channel *chan, void *data)
242 {
243         /* nothing to do */
244 }
245
246 static int spy_generate(struct ast_channel *chan, void *data, int len, int samples)
247 {
248         struct chanspy_translation_helper *csth = data;
249         struct ast_frame *f = NULL;
250
251         ast_audiohook_lock(&csth->spy_audiohook);
252         if (csth->spy_audiohook.status != AST_AUDIOHOOK_STATUS_RUNNING) {
253                 /* Channel is already gone more than likely */
254                 ast_audiohook_unlock(&csth->spy_audiohook);
255                 return -1;
256         }
257
258         f = ast_audiohook_read_frame(&csth->spy_audiohook, samples, AST_AUDIOHOOK_DIRECTION_BOTH, AST_FORMAT_SLINEAR);
259
260         ast_audiohook_unlock(&csth->spy_audiohook);
261
262         if (!f)
263                 return 0;
264
265         if (ast_write(chan, f)) {
266                 ast_frfree(f);
267                 return -1;
268         }
269
270         if (csth->fd)
271                 write(csth->fd, f->data.ptr, f->datalen);
272
273         ast_frfree(f);
274
275         return 0;
276 }
277
278 static struct ast_generator spygen = {
279         .alloc = spy_alloc,
280         .release = spy_release,
281         .generate = spy_generate,
282 };
283
284 static int start_spying(struct ast_channel *chan, const char *spychan_name, struct ast_audiohook *audiohook)
285 {
286         int res = 0;
287         struct ast_channel *peer = NULL;
288
289         ast_log(LOG_NOTICE, "Attaching %s to %s\n", spychan_name, chan->name);
290
291         res = ast_audiohook_attach(chan, audiohook);
292
293         if (!res && ast_test_flag(chan, AST_FLAG_NBRIDGE) && (peer = ast_bridged_channel(chan))) { 
294                 ast_softhangup(peer, AST_SOFTHANGUP_UNBRIDGE);
295         }
296         return res;
297 }
298
299 struct chanspy_ds {
300         struct ast_channel *chan;
301         char unique_id[20];
302         ast_mutex_t lock;
303 };
304
305 static void change_spy_mode(const char digit, struct ast_flags *flags)
306 {
307         if (digit == '4') {
308                 ast_clear_flag(flags, OPTION_WHISPER);
309                 ast_clear_flag(flags, OPTION_BARGE);
310         } else if (digit == '5') {
311                 ast_clear_flag(flags, OPTION_BARGE);
312                 ast_set_flag(flags, OPTION_WHISPER);
313         } else if (digit == '6') {
314                 ast_clear_flag(flags, OPTION_WHISPER);
315                 ast_set_flag(flags, OPTION_BARGE);
316         }
317 }
318
319 static int channel_spy(struct ast_channel *chan, struct chanspy_ds *spyee_chanspy_ds, 
320         int *volfactor, int fd, struct ast_flags *flags, char *exitcontext) 
321 {
322         struct chanspy_translation_helper csth;
323         int running = 0, res, x = 0;
324         char inp[24] = {0};
325         char *name;
326         struct ast_frame *f;
327         struct ast_silence_generator *silgen = NULL;
328         struct ast_channel *spyee = NULL, *spyee_bridge = NULL;
329         const char *spyer_name;
330
331         ast_channel_lock(chan);
332         spyer_name = ast_strdupa(chan->name);
333         ast_channel_unlock(chan);
334
335         ast_mutex_lock(&spyee_chanspy_ds->lock);
336         if (spyee_chanspy_ds->chan) {
337                 spyee = spyee_chanspy_ds->chan;
338                 ast_channel_lock(spyee);
339         }
340         ast_mutex_unlock(&spyee_chanspy_ds->lock);
341
342         if (!spyee)
343                 return 0;
344
345         /* We now hold the channel lock on spyee */
346
347         if (ast_check_hangup(chan) || ast_check_hangup(spyee)) {
348                 ast_channel_unlock(spyee);
349                 return 0;
350         }
351
352         name = ast_strdupa(spyee->name);
353         ast_verb(2, "Spying on channel %s\n", name);
354
355         memset(&csth, 0, sizeof(csth));
356
357         ast_audiohook_init(&csth.spy_audiohook, AST_AUDIOHOOK_TYPE_SPY, "ChanSpy");
358
359         if (start_spying(spyee, spyer_name, &csth.spy_audiohook)) {
360                 ast_audiohook_destroy(&csth.spy_audiohook);
361                 ast_channel_unlock(spyee);
362                 return 0;
363         }
364
365         ast_audiohook_init(&csth.whisper_audiohook, AST_AUDIOHOOK_TYPE_WHISPER, "ChanSpy");
366         ast_audiohook_init(&csth.bridge_whisper_audiohook, AST_AUDIOHOOK_TYPE_WHISPER, "Chanspy");
367         if (start_spying(spyee, spyer_name, &csth.whisper_audiohook)) {
368                 ast_log(LOG_WARNING, "Unable to attach whisper audiohook to spyee %s. Whisper mode disabled!\n", spyee->name);
369         }
370         if ((spyee_bridge = ast_bridged_channel(spyee))) {
371                 ast_channel_lock(spyee_bridge);
372                 if (start_spying(spyee_bridge, spyer_name, &csth.bridge_whisper_audiohook)) {
373                         ast_log(LOG_WARNING, "Unable to attach barge audiohook on spyee %s. Barge mode disabled!\n", spyee->name);
374                 }
375                 ast_channel_unlock(spyee_bridge);
376         }
377         ast_channel_unlock(spyee);
378         spyee = NULL;
379
380         ast_channel_lock(chan);
381         ast_set_flag(chan, AST_FLAG_END_DTMF_ONLY);
382         ast_channel_unlock(chan);
383
384         csth.volfactor = *volfactor;
385
386         if (csth.volfactor) {
387                 csth.spy_audiohook.options.read_volume = csth.volfactor;
388                 csth.spy_audiohook.options.write_volume = csth.volfactor;
389         }
390
391         csth.fd = fd;
392
393         if (ast_test_flag(flags, OPTION_PRIVATE))
394                 silgen = ast_channel_start_silence_generator(chan);
395         else
396                 ast_activate_generator(chan, &spygen, &csth);
397
398         /* We can no longer rely on 'spyee' being an actual channel;
399            it can be hung up and freed out from under us. However, the
400            channel destructor will put NULL into our csth.spy.chan
401            field when that happens, so that is our signal that the spyee
402            channel has gone away.
403         */
404
405         /* Note: it is very important that the ast_waitfor() be the first
406            condition in this expression, so that if we wait for some period
407            of time before receiving a frame from our spying channel, we check
408            for hangup on the spied-on channel _after_ knowing that a frame
409            has arrived, since the spied-on channel could have gone away while
410            we were waiting
411         */
412         while ((res = ast_waitfor(chan, -1) > -1) && csth.spy_audiohook.status == AST_AUDIOHOOK_STATUS_RUNNING) {
413                 if (!(f = ast_read(chan)) || ast_check_hangup(chan)) {
414                         running = -1;
415                         break;
416                 }
417
418                 if (ast_test_flag(flags, OPTION_BARGE) && f->frametype == AST_FRAME_VOICE) {
419                         ast_audiohook_lock(&csth.whisper_audiohook);
420                         ast_audiohook_lock(&csth.bridge_whisper_audiohook);
421                         ast_audiohook_write_frame(&csth.whisper_audiohook, AST_AUDIOHOOK_DIRECTION_WRITE, f);
422                         ast_audiohook_write_frame(&csth.bridge_whisper_audiohook, AST_AUDIOHOOK_DIRECTION_WRITE, f);
423                         ast_audiohook_unlock(&csth.whisper_audiohook);
424                         ast_audiohook_unlock(&csth.bridge_whisper_audiohook);
425                         ast_frfree(f);
426                         continue;
427                 } else if (ast_test_flag(flags, OPTION_WHISPER) && f->frametype == AST_FRAME_VOICE) {
428                         ast_audiohook_lock(&csth.whisper_audiohook);
429                         ast_audiohook_write_frame(&csth.whisper_audiohook, AST_AUDIOHOOK_DIRECTION_WRITE, f);
430                         ast_audiohook_unlock(&csth.whisper_audiohook);
431                         ast_frfree(f);
432                         continue;
433                 }
434                 
435                 res = (f->frametype == AST_FRAME_DTMF) ? f->subclass : 0;
436                 ast_frfree(f);
437                 if (!res)
438                         continue;
439
440                 if (x == sizeof(inp))
441                         x = 0;
442
443                 if (res < 0) {
444                         running = -1;
445                         break;
446                 }
447
448                 if (ast_test_flag(flags, OPTION_EXIT)) {
449                         char tmp[2];
450                         tmp[0] = res;
451                         tmp[1] = '\0';
452                         if (!ast_goto_if_exists(chan, exitcontext, tmp, 1)) {
453                                 ast_debug(1, "Got DTMF %c, goto context %s\n", tmp[0], exitcontext);
454                                 pbx_builtin_setvar_helper(chan, "SPY_CHANNEL", name);
455                                 running = -2;
456                                 break;
457                         } else {
458                                 ast_debug(2, "Exit by single digit did not work in chanspy. Extension %s does not exist in context %s\n", tmp, exitcontext);
459                         }
460                 } else if (res >= '0' && res <= '9') {
461                         if (ast_test_flag(flags, OPTION_DTMF_SWITCH_MODES)) {
462                                 change_spy_mode(res, flags);
463                         } else {
464                                 inp[x++] = res;
465                         }
466                 }
467
468                 if (res == '*') {
469                         running = 0;
470                         break;
471                 } else if (res == '#') {
472                         if (!ast_strlen_zero(inp)) {
473                                 running = atoi(inp);
474                                 break;
475                         }
476
477                         (*volfactor)++;
478                         if (*volfactor > 4)
479                                 *volfactor = -4;
480                         ast_verb(3, "Setting spy volume on %s to %d\n", chan->name, *volfactor);
481
482                         csth.volfactor = *volfactor;
483                         csth.spy_audiohook.options.read_volume = csth.volfactor;
484                         csth.spy_audiohook.options.write_volume = csth.volfactor;
485                 }
486         }
487
488         if (ast_test_flag(flags, OPTION_PRIVATE))
489                 ast_channel_stop_silence_generator(chan, silgen);
490         else
491                 ast_deactivate_generator(chan);
492
493         ast_channel_lock(chan);
494         ast_clear_flag(chan, AST_FLAG_END_DTMF_ONLY);
495         ast_channel_unlock(chan);
496
497         ast_audiohook_lock(&csth.whisper_audiohook);
498         ast_audiohook_detach(&csth.whisper_audiohook);
499         ast_audiohook_unlock(&csth.whisper_audiohook);
500         ast_audiohook_destroy(&csth.whisper_audiohook);
501         ast_audiohook_lock(&csth.bridge_whisper_audiohook);
502         ast_audiohook_detach(&csth.bridge_whisper_audiohook);
503         ast_audiohook_unlock(&csth.bridge_whisper_audiohook);
504         ast_audiohook_destroy(&csth.bridge_whisper_audiohook);
505
506         ast_audiohook_lock(&csth.spy_audiohook);
507         ast_audiohook_detach(&csth.spy_audiohook);
508         ast_audiohook_unlock(&csth.spy_audiohook);
509         ast_audiohook_destroy(&csth.spy_audiohook);
510         
511         ast_verb(2, "Done Spying on channel %s\n", name);
512
513         return running;
514 }
515
516 /*!
517  * \note This relies on the embedded lock to be recursive, as it may be called
518  * due to a call to chanspy_ds_free with the lock held there.
519  */
520 static void chanspy_ds_destroy(void *data)
521 {
522         struct chanspy_ds *chanspy_ds = data;
523
524         /* Setting chan to be NULL is an atomic operation, but we don't want this
525          * value to change while this lock is held.  The lock is held elsewhere
526          * while it performs non-atomic operations with this channel pointer */
527
528         ast_mutex_lock(&chanspy_ds->lock);
529         chanspy_ds->chan = NULL;
530         ast_mutex_unlock(&chanspy_ds->lock);
531 }
532
533 static void chanspy_ds_chan_fixup(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan)
534 {
535         struct chanspy_ds *chanspy_ds = data;
536         
537         ast_mutex_lock(&chanspy_ds->lock);
538         chanspy_ds->chan = new_chan;
539         ast_mutex_unlock(&chanspy_ds->lock);
540 }
541
542 static const struct ast_datastore_info chanspy_ds_info = {
543         .type = "chanspy",
544         .destroy = chanspy_ds_destroy,
545         .chan_fixup = chanspy_ds_chan_fixup,
546 };
547
548 static struct chanspy_ds *chanspy_ds_free(struct chanspy_ds *chanspy_ds)
549 {
550         if (!chanspy_ds)
551                 return NULL;
552
553         ast_mutex_lock(&chanspy_ds->lock);
554         if (chanspy_ds->chan) {
555                 struct ast_datastore *datastore;
556                 struct ast_channel *chan;
557
558                 chan = chanspy_ds->chan;
559
560                 ast_channel_lock(chan);
561                 if ((datastore = ast_channel_datastore_find(chan, &chanspy_ds_info, chanspy_ds->unique_id))) {
562                         ast_channel_datastore_remove(chan, datastore);
563                         /* chanspy_ds->chan is NULL after this call */
564                         chanspy_ds_destroy(datastore->data);
565                         datastore->data = NULL;
566                         ast_channel_datastore_free(datastore);
567                 }
568                 ast_channel_unlock(chan);
569         }
570         ast_mutex_unlock(&chanspy_ds->lock);
571
572         return NULL;
573 }
574
575 /*! \note Returns the channel in the chanspy_ds locked as well as the chanspy_ds locked */
576 static struct chanspy_ds *setup_chanspy_ds(struct ast_channel *chan, struct chanspy_ds *chanspy_ds)
577 {
578         struct ast_datastore *datastore = NULL;
579
580         ast_mutex_lock(&chanspy_ds->lock);
581
582         if (!(datastore = ast_channel_datastore_alloc(&chanspy_ds_info, chanspy_ds->unique_id))) {
583                 ast_mutex_unlock(&chanspy_ds->lock);
584                 chanspy_ds = chanspy_ds_free(chanspy_ds);
585                 ast_channel_unlock(chan);
586                 return NULL;
587         }
588         
589         chanspy_ds->chan = chan;
590         datastore->data = chanspy_ds;
591         ast_channel_datastore_add(chan, datastore);
592
593         return chanspy_ds;
594 }
595
596 static struct chanspy_ds *next_channel(struct ast_channel *chan,
597         const struct ast_channel *last, const char *spec,
598         const char *exten, const char *context, struct chanspy_ds *chanspy_ds)
599 {
600         struct ast_channel *next;
601         char channel_name[AST_CHANNEL_NAME];
602
603 redo:
604         if (!ast_strlen_zero(spec))
605                 next = ast_walk_channel_by_name_prefix_locked(last, spec, strlen(spec));
606         else if (!ast_strlen_zero(exten))
607                 next = ast_walk_channel_by_exten_locked(last, exten, context);
608         else
609                 next = ast_channel_walk_locked(last);
610
611         if (!next)
612                 return NULL;
613
614         snprintf(channel_name, AST_CHANNEL_NAME, "%s/pseudo", dahdi_chan_name);
615         if (!strncmp(next->name, channel_name, PSEUDO_CHAN_LEN)) {
616                 last = next;
617                 ast_channel_unlock(next);
618                 goto redo;
619         } else if (next == chan) {
620                 last = next;
621                 ast_channel_unlock(next);
622                 goto redo;
623         }
624
625         return setup_chanspy_ds(next, chanspy_ds);
626 }
627
628 static int common_exec(struct ast_channel *chan, struct ast_flags *flags,
629         int volfactor, const int fd, const char *mygroup, const char *myenforced,
630         const char *spec, const char *exten, const char *context, const char *mailbox,
631         const char *name_context)
632 {
633         char nameprefix[AST_NAME_STRLEN];
634         char peer_name[AST_NAME_STRLEN + 5];
635         char exitcontext[AST_MAX_CONTEXT] = "";
636         signed char zero_volume = 0;
637         int waitms;
638         int res;
639         char *ptr;
640         int num;
641         int num_spyed_upon = 1;
642         struct chanspy_ds chanspy_ds;
643
644         if (ast_test_flag(flags, OPTION_EXIT)) {
645                 const char *c;
646                 ast_channel_lock(chan);
647                 if ((c = pbx_builtin_getvar_helper(chan, "SPY_EXIT_CONTEXT"))) {
648                         ast_copy_string(exitcontext, c, sizeof(exitcontext));
649                 } else if (!ast_strlen_zero(chan->macrocontext)) {
650                         ast_copy_string(exitcontext, chan->macrocontext, sizeof(exitcontext));
651                 } else {
652                         ast_copy_string(exitcontext, chan->context, sizeof(exitcontext));
653                 }
654                 ast_channel_unlock(chan);
655         }
656
657         ast_mutex_init(&chanspy_ds.lock);
658
659         snprintf(chanspy_ds.unique_id, sizeof(chanspy_ds.unique_id), "%d", ast_atomic_fetchadd_int(&next_unique_id_to_use, +1));
660
661         if (chan->_state != AST_STATE_UP)
662                 ast_answer(chan);
663
664         ast_set_flag(chan, AST_FLAG_SPYING); /* so nobody can spy on us while we are spying */
665
666         waitms = 100;
667
668         for (;;) {
669                 struct chanspy_ds *peer_chanspy_ds = NULL, *next_chanspy_ds = NULL;
670                 struct ast_channel *prev = NULL, *peer = NULL;
671
672                 if (!ast_test_flag(flags, OPTION_QUIET) && num_spyed_upon) {
673                         res = ast_streamfile(chan, "beep", chan->language);
674                         if (!res)
675                                 res = ast_waitstream(chan, "");
676                         else if (res < 0) {
677                                 ast_clear_flag(chan, AST_FLAG_SPYING);
678                                 break;
679                         }
680                         if (!ast_strlen_zero(exitcontext)) {
681                                 char tmp[2];
682                                 tmp[0] = res;
683                                 tmp[1] = '\0';
684                                 if (!ast_goto_if_exists(chan, exitcontext, tmp, 1))
685                                         goto exit;
686                                 else
687                                         ast_debug(2, "Exit by single digit did not work in chanspy. Extension %s does not exist in context %s\n", tmp, exitcontext);
688                         }
689                 }
690
691                 res = ast_waitfordigit(chan, waitms);
692                 if (res < 0) {
693                         ast_clear_flag(chan, AST_FLAG_SPYING);
694                         break;
695                 }
696                 if (!ast_strlen_zero(exitcontext)) {
697                         char tmp[2];
698                         tmp[0] = res;
699                         tmp[1] = '\0';
700                         if (!ast_goto_if_exists(chan, exitcontext, tmp, 1))
701                                 goto exit;
702                         else
703                                 ast_debug(2, "Exit by single digit did not work in chanspy. Extension %s does not exist in context %s\n", tmp, exitcontext);
704                 }
705
706                 /* reset for the next loop around, unless overridden later */
707                 waitms = 100;
708                 num_spyed_upon = 0;
709
710                 for (peer_chanspy_ds = next_channel(chan, prev, spec, exten, context, &chanspy_ds);
711                      peer_chanspy_ds;
712                          chanspy_ds_free(peer_chanspy_ds), prev = peer,
713                      peer_chanspy_ds = next_chanspy_ds ? next_chanspy_ds : 
714                                 next_channel(chan, prev, spec, exten, context, &chanspy_ds), next_chanspy_ds = NULL) {
715                         const char *group;
716                         int igrp = !mygroup;
717                         char *groups[NUM_SPYGROUPS];
718                         char *mygroups[NUM_SPYGROUPS];
719                         int num_groups = 0;
720                         char *dup_group;
721                         int num_mygroups = 0;
722                         char *dup_mygroup;
723                         int x;
724                         int y;
725                         char *s;
726                         char *buffer;
727                         char *end;
728                         char *ext;
729                         char *form_enforced;
730                         int ienf = !myenforced;
731
732                         peer = peer_chanspy_ds->chan;
733
734                         ast_mutex_unlock(&peer_chanspy_ds->lock);
735
736                         if (peer == prev) {
737                                 ast_channel_unlock(peer);
738                                 chanspy_ds_free(peer_chanspy_ds);
739                                 break;
740                         }
741
742                         if (ast_check_hangup(chan)) {
743                                 ast_channel_unlock(peer);
744                                 chanspy_ds_free(peer_chanspy_ds);
745                                 break;
746                         }
747
748                         if (ast_test_flag(flags, OPTION_BRIDGED) && !ast_bridged_channel(peer)) {
749                                 ast_channel_unlock(peer);
750                                 continue;
751                         }
752
753                         if (ast_check_hangup(peer) || ast_test_flag(peer, AST_FLAG_SPYING)) {
754                                 ast_channel_unlock(peer);
755                                 continue;
756                         }
757
758                         if (mygroup) {
759                                 dup_mygroup = ast_strdupa(mygroup);
760                                 num_mygroups = ast_app_separate_args(dup_mygroup, ':', mygroups,
761                                         ARRAY_LEN(mygroups));
762
763                                 if ((group = pbx_builtin_getvar_helper(peer, "SPYGROUP"))) {
764                                         dup_group = ast_strdupa(group);
765                                         num_groups = ast_app_separate_args(dup_group, ':', groups,
766                                                 ARRAY_LEN(groups));
767                                 }
768
769                                 for (y = 0; y < num_mygroups; y++) {
770                                         for (x = 0; x < num_groups; x++) {
771                                                 if (!strcmp(mygroups[y], groups[x])) {
772                                                         igrp = 1;
773                                                         break;
774                                                 }
775                                         }
776                                 }
777                         }
778
779                         if (!igrp) {
780                                 ast_channel_unlock(peer);
781                                 continue;
782                         }
783
784                         if (myenforced) {
785
786                                 /* We don't need to allocate more space than just the
787                                 length of (peer->name) for ext as we will cut the
788                                 channel name's ending before copying into ext */
789
790                                 ext = alloca(strlen(peer->name));
791
792                                 form_enforced = alloca(strlen(myenforced) + 3);
793
794                                 strcpy(form_enforced, ":");
795                                 strcat(form_enforced, myenforced);
796                                 strcat(form_enforced, ":");
797
798                                 buffer = ast_strdupa(peer->name);
799                                 
800                                 if ((end = strchr(buffer, '-'))) {
801                                         *end++ = ':';
802                                         *end = '\0';
803                                 }
804
805                                 strcpy(ext, ":");
806                                 strcat(ext, buffer);
807
808                                 if (strcasestr(form_enforced, ext))
809                                         ienf = 1;
810                         }
811
812                         if (!ienf)
813                                 continue;
814
815                         strcpy(peer_name, "spy-");
816                         strncat(peer_name, peer->name, AST_NAME_STRLEN - 4 - 1);
817                         ptr = strchr(peer_name, '/');
818                         *ptr++ = '\0';
819                         ptr = strsep(&ptr, "-");
820
821                         for (s = peer_name; s < ptr; s++)
822                                 *s = tolower(*s);
823                         /* We have to unlock the peer channel here to avoid a deadlock.
824                          * So, when we need to dereference it again, we have to lock the 
825                          * datastore and get the pointer from there to see if the channel 
826                          * is still valid. */
827                         ast_channel_unlock(peer);
828
829                         if (!ast_test_flag(flags, OPTION_QUIET)) {
830                                 if (ast_test_flag(flags, OPTION_NAME)) {
831                                         const char *local_context = S_OR(name_context, "default");
832                                         const char *local_mailbox = S_OR(mailbox, ptr);
833                                         res = ast_app_sayname(chan, local_mailbox, local_context);
834                                 }
835                                 if (!ast_test_flag(flags, OPTION_NAME) || res < 0) {
836                                         if (!ast_test_flag(flags, OPTION_NOTECH)) {
837                                                 if (ast_fileexists(peer_name, NULL, NULL) != -1) {
838                                                         res = ast_streamfile(chan, peer_name, chan->language);
839                                                         if (!res) {
840                                                                 res = ast_waitstream(chan, "");
841                                                         }
842                                                         if (res) {
843                                                                 chanspy_ds_free(peer_chanspy_ds);
844                                                                 break;
845                                                         }
846                                                 } else {
847                                                         res = ast_say_character_str(chan, peer_name, "", chan->language);
848                                                 }
849                                         }
850                                         if ((num = atoi(ptr)))
851                                                 ast_say_digits(chan, atoi(ptr), "", chan->language);
852                                 }
853                         }
854
855                         res = channel_spy(chan, peer_chanspy_ds, &volfactor, fd, flags, exitcontext);
856                         num_spyed_upon++;       
857
858                         if (res == -1) {
859                                 chanspy_ds_free(peer_chanspy_ds);
860                                 goto exit;
861                         } else if (res == -2) {
862                                 res = 0;
863                                 chanspy_ds_free(peer_chanspy_ds);
864                                 goto exit;
865                         } else if (res > 1 && spec) {
866                                 struct ast_channel *next;
867
868                                 snprintf(nameprefix, AST_NAME_STRLEN, "%s/%d", spec, res);
869
870                                 if ((next = ast_get_channel_by_name_prefix_locked(nameprefix, strlen(nameprefix)))) {
871                                         peer_chanspy_ds = chanspy_ds_free(peer_chanspy_ds);
872                                         next_chanspy_ds = setup_chanspy_ds(next, &chanspy_ds);
873                                 } else {
874                                         /* stay on this channel, if it is still valid */
875
876                                         ast_mutex_lock(&peer_chanspy_ds->lock);
877                                         if (peer_chanspy_ds->chan) {
878                                                 ast_channel_lock(peer_chanspy_ds->chan);
879                                                 next_chanspy_ds = peer_chanspy_ds;
880                                                 peer_chanspy_ds = NULL;
881                                         } else {
882                                                 /* the channel is gone */
883                                                 ast_mutex_unlock(&peer_chanspy_ds->lock);
884                                                 next_chanspy_ds = NULL;
885                                         }
886                                 }
887
888                                 peer = NULL;
889                         }
890                 }
891                 if (res == -1 || ast_check_hangup(chan))
892                         break;
893         }
894 exit:
895
896         ast_clear_flag(chan, AST_FLAG_SPYING);
897
898         ast_channel_setoption(chan, AST_OPTION_TXGAIN, &zero_volume, sizeof(zero_volume), 0);
899
900         ast_mutex_destroy(&chanspy_ds.lock);
901
902         return res;
903 }
904
905 static int chanspy_exec(struct ast_channel *chan, void *data)
906 {
907         char *myenforced = NULL;
908         char *mygroup = NULL;
909         char *recbase = NULL;
910         int fd = 0;
911         struct ast_flags flags;
912         int oldwf = 0;
913         int volfactor = 0;
914         int res;
915         char *mailbox = NULL;
916         char *name_context = NULL;
917         AST_DECLARE_APP_ARGS(args,
918                 AST_APP_ARG(spec);
919                 AST_APP_ARG(options);
920         );
921         char *opts[OPT_ARG_ARRAY_SIZE];
922
923         data = ast_strdupa(data);
924         AST_STANDARD_APP_ARGS(args, data);
925
926         if (args.spec && !strcmp(args.spec, "all"))
927                 args.spec = NULL;
928
929         if (args.options) {
930                 ast_app_parse_options(spy_opts, &flags, opts, args.options);
931                 if (ast_test_flag(&flags, OPTION_GROUP))
932                         mygroup = opts[OPT_ARG_GROUP];
933
934                 if (ast_test_flag(&flags, OPTION_RECORD) &&
935                         !(recbase = opts[OPT_ARG_RECORD]))
936                         recbase = "chanspy";
937
938                 if (ast_test_flag(&flags, OPTION_VOLUME) && opts[OPT_ARG_VOLUME]) {
939                         int vol;
940
941                         if ((sscanf(opts[OPT_ARG_VOLUME], "%d", &vol) != 1) || (vol > 4) || (vol < -4))
942                                 ast_log(LOG_NOTICE, "Volume factor must be a number between -4 and 4\n");
943                         else
944                                 volfactor = vol;
945                 }
946
947                 if (ast_test_flag(&flags, OPTION_PRIVATE))
948                         ast_set_flag(&flags, OPTION_WHISPER);
949
950                 if (ast_test_flag(&flags, OPTION_ENFORCED))
951                         myenforced = opts[OPT_ARG_ENFORCED];
952                 
953                 if (ast_test_flag(&flags, OPTION_NAME)) {
954                         if (!ast_strlen_zero(opts[OPT_ARG_NAME])) {
955                                 char *delimiter;
956                                 if ((delimiter = strchr(opts[OPT_ARG_NAME], '@'))) {
957                                         mailbox = opts[OPT_ARG_NAME];
958                                         *delimiter++ = '\0';
959                                         name_context = delimiter;
960                                 } else {
961                                         mailbox = opts[OPT_ARG_NAME];
962                                 }
963                         }
964                 }
965
966
967         } else
968                 ast_clear_flag(&flags, AST_FLAGS_ALL);
969
970         oldwf = chan->writeformat;
971         if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
972                 ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
973                 return -1;
974         }
975
976         if (recbase) {
977                 char filename[PATH_MAX];
978
979                 snprintf(filename, sizeof(filename), "%s/%s.%d.raw", ast_config_AST_MONITOR_DIR, recbase, (int) time(NULL));
980                 if ((fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, AST_FILE_MODE)) <= 0) {
981                         ast_log(LOG_WARNING, "Cannot open '%s' for recording\n", filename);
982                         fd = 0;
983                 }
984         }
985
986         res = common_exec(chan, &flags, volfactor, fd, mygroup, myenforced, args.spec, NULL, NULL, mailbox, name_context);
987
988         if (fd)
989                 close(fd);
990
991         if (oldwf && ast_set_write_format(chan, oldwf) < 0)
992                 ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
993
994         return res;
995 }
996
997 static int extenspy_exec(struct ast_channel *chan, void *data)
998 {
999         char *ptr, *exten = NULL;
1000         char *mygroup = NULL;
1001         char *recbase = NULL;
1002         int fd = 0;
1003         struct ast_flags flags;
1004         int oldwf = 0;
1005         int volfactor = 0;
1006         int res;
1007         char *mailbox = NULL;
1008         char *name_context = NULL;
1009         AST_DECLARE_APP_ARGS(args,
1010                 AST_APP_ARG(context);
1011                 AST_APP_ARG(options);
1012         );
1013
1014         data = ast_strdupa(data);
1015
1016         AST_STANDARD_APP_ARGS(args, data);
1017         if (!ast_strlen_zero(args.context) && (ptr = strchr(args.context, '@'))) {
1018                 exten = args.context;
1019                 *ptr++ = '\0';
1020                 args.context = ptr;
1021         }
1022
1023         if (ast_strlen_zero(args.context))
1024                 args.context = ast_strdupa(chan->context);
1025
1026         if (args.options) {
1027                 char *opts[OPT_ARG_ARRAY_SIZE];
1028
1029                 ast_app_parse_options(spy_opts, &flags, opts, args.options);
1030                 if (ast_test_flag(&flags, OPTION_GROUP))
1031                         mygroup = opts[OPT_ARG_GROUP];
1032
1033                 if (ast_test_flag(&flags, OPTION_RECORD) &&
1034                         !(recbase = opts[OPT_ARG_RECORD]))
1035                         recbase = "chanspy";
1036
1037                 if (ast_test_flag(&flags, OPTION_VOLUME) && opts[OPT_ARG_VOLUME]) {
1038                         int vol;
1039
1040                         if ((sscanf(opts[OPT_ARG_VOLUME], "%d", &vol) != 1) || (vol > 4) || (vol < -4))
1041                                 ast_log(LOG_NOTICE, "Volume factor must be a number between -4 and 4\n");
1042                         else
1043                                 volfactor = vol;
1044                 }
1045
1046                 if (ast_test_flag(&flags, OPTION_PRIVATE))
1047                         ast_set_flag(&flags, OPTION_WHISPER);
1048
1049                 
1050                 if (ast_test_flag(&flags, OPTION_NAME)) {
1051                         if (!ast_strlen_zero(opts[OPT_ARG_NAME])) {
1052                                 char *delimiter;
1053                                 if ((delimiter = strchr(opts[OPT_ARG_NAME], '@'))) {
1054                                         mailbox = opts[OPT_ARG_NAME];
1055                                         *delimiter++ = '\0';
1056                                         name_context = delimiter;
1057                                 } else {
1058                                         mailbox = opts[OPT_ARG_NAME];
1059                                 }
1060                         }
1061                 }
1062
1063         } else
1064                 ast_clear_flag(&flags, AST_FLAGS_ALL);
1065
1066         oldwf = chan->writeformat;
1067         if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
1068                 ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
1069                 return -1;
1070         }
1071
1072         if (recbase) {
1073                 char filename[PATH_MAX];
1074
1075                 snprintf(filename, sizeof(filename), "%s/%s.%d.raw", ast_config_AST_MONITOR_DIR, recbase, (int) time(NULL));
1076                 if ((fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, AST_FILE_MODE)) <= 0) {
1077                         ast_log(LOG_WARNING, "Cannot open '%s' for recording\n", filename);
1078                         fd = 0;
1079                 }
1080         }
1081
1082
1083         res = common_exec(chan, &flags, volfactor, fd, mygroup, NULL, NULL, exten, args.context, mailbox, name_context);
1084
1085         if (fd)
1086                 close(fd);
1087
1088         if (oldwf && ast_set_write_format(chan, oldwf) < 0)
1089                 ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
1090
1091         return res;
1092 }
1093
1094 static int unload_module(void)
1095 {
1096         int res = 0;
1097
1098         res |= ast_unregister_application(app_chan);
1099         res |= ast_unregister_application(app_ext);
1100
1101         return res;
1102 }
1103
1104 static int load_module(void)
1105 {
1106         int res = 0;
1107
1108         res |= ast_register_application(app_chan, chanspy_exec, tdesc, desc_chan);
1109         res |= ast_register_application(app_ext, extenspy_exec, tdesc, desc_ext);
1110
1111         return res;
1112 }
1113
1114 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Listen to the audio of an active channel");