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