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