4814f4ce5db4ce75bb6efd201da7f91cdb98ca99
[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 /*** MODULEINFO
33         <support_level>core</support_level>
34  ***/
35
36 #include "asterisk.h"
37
38 #include <ctype.h>
39 #include <errno.h>
40
41 #include "asterisk/paths.h" /* use ast_config_AST_MONITOR_DIR */
42 #include "asterisk/file.h"
43 #include "asterisk/channel.h"
44 #include "asterisk/audiohook.h"
45 #include "asterisk/features.h"
46 #include "asterisk/app.h"
47 #include "asterisk/utils.h"
48 #include "asterisk/say.h"
49 #include "asterisk/pbx.h"
50 #include "asterisk/translate.h"
51 #include "asterisk/manager.h"
52 #include "asterisk/module.h"
53 #include "asterisk/lock.h"
54 #include "asterisk/options.h"
55 #include "asterisk/autochan.h"
56 #include "asterisk/stasis_channels.h"
57 #include "asterisk/json.h"
58 #include "asterisk/format_cache.h"
59
60 #define AST_NAME_STRLEN 256
61 #define NUM_SPYGROUPS 128
62
63 /*** DOCUMENTATION
64         <application name="ChanSpy" language="en_US">
65                 <synopsis>
66                         Listen to a channel, and optionally whisper into it.
67                 </synopsis>
68                 <syntax>
69                         <parameter name="chanprefix" />
70                         <parameter name="options">
71                                 <optionlist>
72                                         <option name="b">
73                                                 <para>Only spy on channels involved in a bridged call.</para>
74                                         </option>
75                                         <option name="B">
76                                                 <para>Instead of whispering on a single channel barge in on both
77                                                 channels involved in the call.</para>
78                                         </option>
79                                         <option name="c">
80                                                 <argument name="digit" required="true">
81                                                         <para>Specify a DTMF digit that can be used to spy on the next available channel.</para>
82                                                 </argument>
83                                         </option>
84                                         <option name="d">
85                                                 <para>Override the typical numeric DTMF functionality and instead
86                                                 use DTMF to switch between spy modes.</para>
87                                                 <enumlist>
88                                                         <enum name="4">
89                                                                 <para>spy mode</para>
90                                                         </enum>
91                                                         <enum name="5">
92                                                                 <para>whisper mode</para>
93                                                         </enum>
94                                                         <enum name="6">
95                                                                 <para>barge mode</para>
96                                                         </enum>
97                                                 </enumlist>
98                                         </option>
99                                         <option name="e">
100                                                 <argument name="ext" required="true" />
101                                                 <para>Enable <emphasis>enforced</emphasis> mode, so the spying channel can
102                                                 only monitor extensions whose name is in the <replaceable>ext</replaceable> : delimited 
103                                                 list.</para>
104                                         </option>
105                                         <option name="E">
106                                                 <para>Exit when the spied-on channel hangs up.</para>
107                                         </option>
108                                         <option name="g">
109                                                 <argument name="grp" required="true">
110                                                         <para>Only spy on channels in which one or more of the groups
111                                                         listed in <replaceable>grp</replaceable> matches one or more groups from the
112                                                         <variable>SPYGROUP</variable> variable set on the channel to be spied upon.</para>
113                                                 </argument>
114                                                 <note><para>both <replaceable>grp</replaceable> and <variable>SPYGROUP</variable> can contain 
115                                                 either a single group or a colon-delimited list of groups, such
116                                                 as <literal>sales:support:accounting</literal>.</para></note>
117                                         </option>
118                                         <option name="l">
119                                                 <para>Allow usage of a long queue to store audio frames.</para>
120                                                 <note><para>This may introduce some delay in the received audio feed, but will improve the audio quality.</para></note>
121                                         </option>
122                                         <option name="n" argsep="@">
123                                                 <para>Say the name of the person being spied on if that person has recorded
124                                                 his/her name. If a context is specified, then that voicemail context will
125                                                 be searched when retrieving the name, otherwise the <literal>default</literal> context
126                                                 be used when searching for the name (i.e. if SIP/1000 is the channel being
127                                                 spied on and no mailbox is specified, then <literal>1000</literal> will be used when searching
128                                                 for the name).</para>
129                                                 <argument name="mailbox" />
130                                                 <argument name="context" />
131                                         </option>
132                                         <option name="o">
133                                                 <para>Only listen to audio coming from this channel.</para>
134                                         </option>
135                                         <option name="q">
136                                                 <para>Don't play a beep when beginning to spy on a channel, or speak the
137                                                 selected channel name.</para>
138                                         </option>
139                                         <option name="r">
140                                                 <para>Record the session to the monitor spool directory. An optional base for the filename 
141                                                 may be specified. The default is <literal>chanspy</literal>.</para>
142                                                 <argument name="basename" />
143                                         </option>
144                                         <option name="s">
145                                                 <para>Skip the playback of the channel type (i.e. SIP, IAX, etc) when
146                                                 speaking the selected channel name.</para>
147                                         </option>
148                                         <option name="S">
149                                                 <para>Stop when no more channels are left to spy on.</para>
150                                         </option>
151                                         <option name="u">
152                                                 <para>The <literal>chanprefix</literal> parameter is a channel uniqueid
153                                                 or fully specified channel name.</para>
154                                         </option>
155                                         <option name="v">
156                                                 <argument name="value" />
157                                                 <para>Adjust the initial volume in the range from <literal>-4</literal> 
158                                                 to <literal>4</literal>. A negative value refers to a quieter setting.</para>
159                                         </option>
160                                         <option name="w">
161                                                 <para>Enable <literal>whisper</literal> mode, so the spying channel can talk to
162                                                 the spied-on channel.</para>
163                                         </option>
164                                         <option name="W">
165                                                 <para>Enable <literal>private whisper</literal> mode, so the spying channel can
166                                                 talk to the spied-on channel but cannot listen to that channel.</para>
167                                         </option>
168                                         <option name="x">
169                                                 <argument name="digit" required="true">
170                                                         <para>Specify a DTMF digit that can be used to exit the application while actively
171                                                         spying on a channel. If there is no channel being spied on, the DTMF digit will be
172                                                         ignored.</para>
173                                                 </argument>
174                                         </option>
175                                         <option name="X">
176                                                 <para>Allow the user to exit ChanSpy to a valid single digit
177                                                 numeric extension in the current context or the context
178                                                 specified by the <variable>SPY_EXIT_CONTEXT</variable> channel variable. The
179                                                 name of the last channel that was spied on will be stored
180                                                 in the <variable>SPY_CHANNEL</variable> variable.</para>
181                                         </option>
182                                 </optionlist>           
183                         </parameter>
184                 </syntax>
185                 <description>
186                         <para>This application is used to listen to the audio from an Asterisk channel. This includes the audio 
187                         coming in and out of the channel being spied on. If the <literal>chanprefix</literal> parameter is specified,
188                         only channels beginning with this string will be spied upon.</para>
189                         <para>While spying, the following actions may be performed:</para>
190                         <para> - Dialing <literal>#</literal> cycles the volume level.</para>
191                         <para> - Dialing <literal>*</literal> will stop spying and look for another channel to spy on.</para>
192                         <para> - Dialing a series of digits followed by <literal>#</literal> builds a channel name to append
193                         to <literal>chanprefix</literal>. For example, executing ChanSpy(Agent) and then dialing the digits '1234#'
194                         while spying will begin spying on the channel 'Agent/1234'. Note that this feature will be overridden
195                         if the 'd' or 'u' options are used.</para>
196                         <note><para>The <replaceable>X</replaceable> option supersedes the three features above in that if a valid
197                         single digit extension exists in the correct context ChanSpy will exit to it.
198                         This also disables choosing a channel based on <literal>chanprefix</literal> and a digit sequence.</para></note>
199                 </description>
200                 <see-also>
201                         <ref type="application">ExtenSpy</ref>
202                         <ref type="managerEvent">ChanSpyStart</ref>
203                         <ref type="managerEvent">ChanSpyStop</ref>
204                 </see-also>
205         </application>
206         <application name="ExtenSpy" language="en_US">
207                 <synopsis>
208                         Listen to a channel, and optionally whisper into it.
209                 </synopsis>
210                 <syntax>
211                         <parameter name="exten" required="true" argsep="@">
212                                 <argument name="exten" required="true">
213                                         <para>Specify extension.</para>
214                                 </argument>
215                                 <argument name="context">
216                                         <para>Optionally specify a context, defaults to <literal>default</literal>.</para>
217                                 </argument>
218                         </parameter>
219                         <parameter name="options">
220                                 <optionlist>
221                                         <option name="b">
222                                                 <para>Only spy on channels involved in a bridged call.</para>
223                                         </option>
224                                         <option name="B">
225                                                 <para>Instead of whispering on a single channel barge in on both
226                                                 channels involved in the call.</para>
227                                         </option>
228                                         <option name="c">
229                                                 <argument name="digit" required="true">
230                                                         <para>Specify a DTMF digit that can be used to spy on the next available channel.</para>
231                                                 </argument>
232                                         </option>
233                                         <option name="d">
234                                                 <para>Override the typical numeric DTMF functionality and instead
235                                                 use DTMF to switch between spy modes.</para>
236                                                 <enumlist>
237                                                         <enum name="4">
238                                                                 <para>spy mode</para>
239                                                         </enum>
240                                                         <enum name="5">
241                                                                 <para>whisper mode</para>
242                                                         </enum>
243                                                         <enum name="6">
244                                                                 <para>barge mode</para>
245                                                         </enum>
246                                                 </enumlist>
247                                         </option>
248                                         <option name="e">
249                                                 <argument name="ext" required="true" />
250                                                 <para>Enable <emphasis>enforced</emphasis> mode, so the spying channel can
251                                                 only monitor extensions whose name is in the <replaceable>ext</replaceable> : delimited 
252                                                 list.</para>
253                                         </option>
254                                         <option name="E">
255                                                 <para>Exit when the spied-on channel hangs up.</para>
256                                         </option>
257                                         <option name="g">
258                                                 <argument name="grp" required="true">
259                                                         <para>Only spy on channels in which one or more of the groups
260                                                         listed in <replaceable>grp</replaceable> matches one or more groups from the
261                                                         <variable>SPYGROUP</variable> variable set on the channel to be spied upon.</para>
262                                                 </argument>
263                                                 <note><para>both <replaceable>grp</replaceable> and <variable>SPYGROUP</variable> can contain 
264                                                 either a single group or a colon-delimited list of groups, such
265                                                 as <literal>sales:support:accounting</literal>.</para></note>
266                                         </option>
267                                         <option name="l">
268                                                 <para>Allow usage of a long queue to store audio frames.</para>
269                                                 <note><para>This may introduce some delay in the received audio feed, but will improve the audio quality.</para></note>
270                                         </option>
271                                         <option name="n" argsep="@">
272                                                 <para>Say the name of the person being spied on if that person has recorded
273                                                 his/her name. If a context is specified, then that voicemail context will
274                                                 be searched when retrieving the name, otherwise the <literal>default</literal> context
275                                                 be used when searching for the name (i.e. if SIP/1000 is the channel being
276                                                 spied on and no mailbox is specified, then <literal>1000</literal> will be used when searching
277                                                 for the name).</para>
278                                                 <argument name="mailbox" />
279                                                 <argument name="context" />
280                                         </option>
281                                         <option name="o">
282                                                 <para>Only listen to audio coming from this channel.</para>
283                                         </option>
284                                         <option name="q">
285                                                 <para>Don't play a beep when beginning to spy on a channel, or speak the
286                                                 selected channel name.</para>
287                                         </option>
288                                         <option name="r">
289                                                 <para>Record the session to the monitor spool directory. An optional base for the filename 
290                                                 may be specified. The default is <literal>chanspy</literal>.</para>
291                                                 <argument name="basename" />
292                                         </option>
293                                         <option name="s">
294                                                 <para>Skip the playback of the channel type (i.e. SIP, IAX, etc) when
295                                                 speaking the selected channel name.</para>
296                                         </option>
297                                         <option name="S">
298                                                 <para>Stop when there are no more extensions left to spy on.</para>
299                                         </option>
300                                         <option name="v">
301                                                 <argument name="value" />
302                                                 <para>Adjust the initial volume in the range from <literal>-4</literal> 
303                                                 to <literal>4</literal>. A negative value refers to a quieter setting.</para>
304                                         </option>
305                                         <option name="w">
306                                                 <para>Enable <literal>whisper</literal> mode, so the spying channel can talk to
307                                                 the spied-on channel.</para>
308                                         </option>
309                                         <option name="W">
310                                                 <para>Enable <literal>private whisper</literal> mode, so the spying channel can
311                                                 talk to the spied-on channel but cannot listen to that channel.</para>
312                                         </option>
313                                         <option name="x">
314                                                 <argument name="digit" required="true">
315                                                         <para>Specify a DTMF digit that can be used to exit the application while actively
316                                                         spying on a channel. If there is no channel being spied on, the DTMF digit will be
317                                                         ignored.</para>
318                                                 </argument>
319                                         </option>
320                                         <option name="X">
321                                                 <para>Allow the user to exit ChanSpy to a valid single digit
322                                                 numeric extension in the current context or the context
323                                                 specified by the <variable>SPY_EXIT_CONTEXT</variable> channel variable. The
324                                                 name of the last channel that was spied on will be stored
325                                                 in the <variable>SPY_CHANNEL</variable> variable.</para>
326                                         </option>
327                                 </optionlist>   
328                         </parameter>
329                 </syntax>
330                 <description>
331                         <para>This application is used to listen to the audio from an Asterisk channel. This includes 
332                         the audio coming in and out of the channel being spied on. Only channels created by outgoing calls for the
333                         specified extension will be selected for spying. If the optional context is not supplied, 
334                         the current channel's context will be used.</para>
335                         <para>While spying, the following actions may be performed:</para>
336                         <para> - Dialing <literal>#</literal> cycles the volume level.</para>
337                         <para> - Dialing <literal>*</literal> will stop spying and look for another channel to spy on.</para>
338                         <note><para>The <replaceable>X</replaceable> option supersedes the three features above in that if a valid
339                         single digit extension exists in the correct context ChanSpy will exit to it.
340                         This also disables choosing a channel based on <literal>chanprefix</literal> and a digit sequence.</para></note>
341                 </description>
342                 <see-also>
343                         <ref type="application">ChanSpy</ref>
344                         <ref type="managerEvent">ChanSpyStart</ref>
345                         <ref type="managerEvent">ChanSpyStop</ref>
346                 </see-also>
347         </application>
348         <application name="DAHDIScan" language="en_US">
349                 <synopsis>
350                         Scan DAHDI channels to monitor calls.
351                 </synopsis>
352                 <syntax>
353                         <parameter name="group">
354                                 <para>Limit scanning to a channel <replaceable>group</replaceable> by setting this option.</para>
355                         </parameter>
356                 </syntax>
357                 <description>
358                         <para>Allows a call center manager to monitor DAHDI channels in a
359                         convenient way.  Use <literal>#</literal> to select the next channel and use <literal>*</literal> to exit.</para>
360                 </description>
361                 <see-also>
362                         <ref type="managerEvent">ChanSpyStart</ref>
363                         <ref type="managerEvent">ChanSpyStop</ref>
364                 </see-also>
365         </application>
366  ***/
367
368 static const char app_chan[] = "ChanSpy";
369
370 static const char app_ext[] = "ExtenSpy";
371
372 static const char app_dahdiscan[] = "DAHDIScan";
373
374 enum {
375         OPTION_QUIET             = (1 << 0),    /* Quiet, no announcement */
376         OPTION_BRIDGED           = (1 << 1),    /* Only look at bridged calls */
377         OPTION_VOLUME            = (1 << 2),    /* Specify initial volume */
378         OPTION_GROUP             = (1 << 3),    /* Only look at channels in group */
379         OPTION_RECORD            = (1 << 4),
380         OPTION_WHISPER           = (1 << 5),
381         OPTION_PRIVATE           = (1 << 6),    /* Private Whisper mode */
382         OPTION_READONLY          = (1 << 7),    /* Don't mix the two channels */
383         OPTION_EXIT              = (1 << 8),    /* Exit to a valid single digit extension */
384         OPTION_ENFORCED          = (1 << 9),    /* Enforced mode */
385         OPTION_NOTECH            = (1 << 10),   /* Skip technology name playback */
386         OPTION_BARGE             = (1 << 11),   /* Barge mode (whisper to both channels) */
387         OPTION_NAME              = (1 << 12),   /* Say the name of the person on whom we will spy */
388         OPTION_DTMF_SWITCH_MODES = (1 << 13),   /* Allow numeric DTMF to switch between chanspy modes */
389         OPTION_DTMF_EXIT         = (1 << 14),   /* Set DTMF to exit, added for DAHDIScan integration */
390         OPTION_DTMF_CYCLE        = (1 << 15),   /* Custom DTMF for cycling next available channel, (default is '*') */
391         OPTION_DAHDI_SCAN        = (1 << 16),   /* Scan groups in DAHDIScan mode */
392         OPTION_STOP              = (1 << 17),
393         OPTION_EXITONHANGUP      = (1 << 18),   /* Hang up when the spied-on channel hangs up. */
394         OPTION_UNIQUEID          = (1 << 19),   /* The chanprefix is a channel uniqueid or fully specified channel name. */
395         OPTION_LONG_QUEUE        = (1 << 20),   /* Allow usage of a long queue to store audio frames. */
396 };
397
398 enum {
399         OPT_ARG_VOLUME = 0,
400         OPT_ARG_GROUP,
401         OPT_ARG_RECORD,
402         OPT_ARG_ENFORCED,
403         OPT_ARG_NAME,
404         OPT_ARG_EXIT,
405         OPT_ARG_CYCLE,
406         OPT_ARG_ARRAY_SIZE,
407 };
408
409 AST_APP_OPTIONS(spy_opts, {
410         AST_APP_OPTION('b', OPTION_BRIDGED),
411         AST_APP_OPTION('B', OPTION_BARGE),
412         AST_APP_OPTION_ARG('c', OPTION_DTMF_CYCLE, OPT_ARG_CYCLE),
413         AST_APP_OPTION('d', OPTION_DTMF_SWITCH_MODES),
414         AST_APP_OPTION_ARG('e', OPTION_ENFORCED, OPT_ARG_ENFORCED),
415         AST_APP_OPTION('E', OPTION_EXITONHANGUP),
416         AST_APP_OPTION_ARG('g', OPTION_GROUP, OPT_ARG_GROUP),
417         AST_APP_OPTION('l', OPTION_LONG_QUEUE),
418         AST_APP_OPTION_ARG('n', OPTION_NAME, OPT_ARG_NAME),
419         AST_APP_OPTION('o', OPTION_READONLY),
420         AST_APP_OPTION('q', OPTION_QUIET),
421         AST_APP_OPTION_ARG('r', OPTION_RECORD, OPT_ARG_RECORD),
422         AST_APP_OPTION('s', OPTION_NOTECH),
423         AST_APP_OPTION('S', OPTION_STOP),
424         AST_APP_OPTION('u', OPTION_UNIQUEID),
425         AST_APP_OPTION_ARG('v', OPTION_VOLUME, OPT_ARG_VOLUME),
426         AST_APP_OPTION('w', OPTION_WHISPER),
427         AST_APP_OPTION('W', OPTION_PRIVATE),
428         AST_APP_OPTION_ARG('x', OPTION_DTMF_EXIT, OPT_ARG_EXIT),
429         AST_APP_OPTION('X', OPTION_EXIT),
430 });
431
432 struct chanspy_translation_helper {
433         /* spy data */
434         struct ast_audiohook spy_audiohook;
435         struct ast_audiohook whisper_audiohook;
436         struct ast_audiohook bridge_whisper_audiohook;
437         int fd;
438         int volfactor;
439         struct ast_flags flags;
440 };
441
442 struct spy_dtmf_options {
443         char exit;
444         char cycle;
445         char volume;
446 };
447
448 static void *spy_alloc(struct ast_channel *chan, void *data)
449 {
450         /* just store the data pointer in the channel structure */
451         return data;
452 }
453
454 static void spy_release(struct ast_channel *chan, void *data)
455 {
456         /* nothing to do */
457 }
458
459 static int spy_generate(struct ast_channel *chan, void *data, int len, int samples)
460 {
461         struct chanspy_translation_helper *csth = data;
462         struct ast_frame *f, *cur;
463
464         ast_audiohook_lock(&csth->spy_audiohook);
465         if (csth->spy_audiohook.status != AST_AUDIOHOOK_STATUS_RUNNING) {
466                 /* Channel is already gone more than likely */
467                 ast_audiohook_unlock(&csth->spy_audiohook);
468                 return -1;
469         }
470
471         if (ast_test_flag(&csth->flags, OPTION_READONLY)) {
472                 /* Option 'o' was set, so don't mix channel audio */
473                 f = ast_audiohook_read_frame(&csth->spy_audiohook, samples, AST_AUDIOHOOK_DIRECTION_READ, ast_format_slin);
474         } else {
475                 f = ast_audiohook_read_frame(&csth->spy_audiohook, samples, AST_AUDIOHOOK_DIRECTION_BOTH, ast_format_slin);
476         }
477
478         ast_audiohook_unlock(&csth->spy_audiohook);
479
480         if (!f)
481                 return 0;
482
483         for (cur = f; cur; cur = AST_LIST_NEXT(cur, frame_list)) {
484                 if (ast_write(chan, cur)) {
485                         ast_frfree(f);
486                         return -1;
487                 }
488
489                 if (csth->fd) {
490                         if (write(csth->fd, cur->data.ptr, cur->datalen) < 0) {
491                                 ast_log(LOG_WARNING, "write() failed: %s\n", strerror(errno));
492                         }
493                 }
494         }
495
496         ast_frfree(f);
497
498         return 0;
499 }
500
501 static struct ast_generator spygen = {
502         .alloc = spy_alloc,
503         .release = spy_release,
504         .generate = spy_generate,
505 };
506
507 static int start_spying(struct ast_autochan *autochan, const char *spychan_name, struct ast_audiohook *audiohook, struct ast_flags *flags)
508 {
509         int res;
510
511         ast_autochan_channel_lock(autochan);
512         ast_log(LOG_NOTICE, "Attaching %s to %s\n", spychan_name, ast_channel_name(autochan->chan));
513
514         if (ast_test_flag(flags, OPTION_READONLY)) {
515                 ast_set_flag(audiohook, AST_AUDIOHOOK_MUTE_WRITE);
516         } else {
517                 ast_set_flag(audiohook, AST_AUDIOHOOK_TRIGGER_SYNC);
518         }
519         if (ast_test_flag(flags, OPTION_LONG_QUEUE)) {
520                 ast_debug(9, "Using a long queue to store audio frames in spy audiohook\n");
521         } else {
522                 ast_set_flag(audiohook, AST_AUDIOHOOK_SMALL_QUEUE);
523         }
524         res = ast_audiohook_attach(autochan->chan, audiohook);
525         ast_autochan_channel_unlock(autochan);
526         return res;
527 }
528
529 static void change_spy_mode(const char digit, struct ast_flags *flags)
530 {
531         if (digit == '4') {
532                 ast_clear_flag(flags, OPTION_WHISPER);
533                 ast_clear_flag(flags, OPTION_BARGE);
534         } else if (digit == '5') {
535                 ast_clear_flag(flags, OPTION_BARGE);
536                 ast_set_flag(flags, OPTION_WHISPER);
537         } else if (digit == '6') {
538                 ast_clear_flag(flags, OPTION_WHISPER);
539                 ast_set_flag(flags, OPTION_BARGE);
540         }
541 }
542
543 static int pack_channel_into_message(struct ast_channel *chan, const char *role,
544                                                                          struct ast_multi_channel_blob *payload)
545 {
546         RAII_VAR(struct ast_channel_snapshot *, snapshot,
547                         ast_channel_snapshot_get_latest(ast_channel_uniqueid(chan)),
548                         ao2_cleanup);
549
550         if (!snapshot) {
551                 return -1;
552         }
553         ast_multi_channel_blob_add_channel(payload, role, snapshot);
554         return 0;
555 }
556
557 /*! \internal
558  * \brief Publish the chanspy message over Stasis-Core
559  * \param spyer The channel doing the spying
560  * \param spyee Who is being spied upon
561  * \start start If non-zero, the spying is starting. Otherwise, the spyer is
562  * finishing
563  */
564 static void publish_chanspy_message(struct ast_channel *spyer,
565                                                                         struct ast_channel *spyee,
566                                                                         int start)
567 {
568         RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
569         RAII_VAR(struct ast_multi_channel_blob *, payload, NULL, ao2_cleanup);
570         RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
571         struct stasis_message_type *type = start ? ast_channel_chanspy_start_type(): ast_channel_chanspy_stop_type();
572
573         if (!spyer) {
574                 ast_log(AST_LOG_WARNING, "Attempt to publish ChanSpy message for NULL spyer channel\n");
575                 return;
576         }
577         blob = ast_json_null();
578         if (!blob || !type) {
579                 return;
580         }
581
582         payload = ast_multi_channel_blob_create(blob);
583         if (!payload) {
584                 return;
585         }
586
587         if (pack_channel_into_message(spyer, "spyer_channel", payload)) {
588                 return;
589         }
590
591         if (spyee) {
592                 if (pack_channel_into_message(spyee, "spyee_channel", payload)) {
593                         return;
594                 }
595         }
596
597         message = stasis_message_create(type, payload);
598         if (!message) {
599                 return;
600         }
601         stasis_publish(ast_channel_topic(spyer), message);
602 }
603
604 static int attach_barge(struct ast_autochan *spyee_autochan,
605         struct ast_autochan **spyee_bridge_autochan, struct ast_audiohook *bridge_whisper_audiohook,
606         const char *spyer_name, const char *name, struct ast_flags *flags)
607 {
608         int retval = 0;
609         struct ast_autochan *internal_bridge_autochan;
610         struct ast_channel *spyee_chan;
611         RAII_VAR(struct ast_channel *, bridged, NULL, ast_channel_cleanup);
612
613         ast_autochan_channel_lock(spyee_autochan);
614         spyee_chan = ast_channel_ref(spyee_autochan->chan);
615         ast_autochan_channel_unlock(spyee_autochan);
616         bridged = ast_channel_bridge_peer(spyee_chan);
617         ast_channel_unref(spyee_chan);
618         if (!bridged) {
619                 return -1;
620         }
621
622         ast_audiohook_init(bridge_whisper_audiohook, AST_AUDIOHOOK_TYPE_WHISPER, "Chanspy", 0);
623
624         internal_bridge_autochan = ast_autochan_setup(bridged);
625         if (!internal_bridge_autochan) {
626                 return -1;
627         }
628
629         if (start_spying(internal_bridge_autochan, spyer_name, bridge_whisper_audiohook, flags)) {
630                 ast_log(LOG_WARNING, "Unable to attach barge audiohook on spyee '%s'. Barge mode disabled.\n", name);
631                 retval = -1;
632         }
633
634         *spyee_bridge_autochan = internal_bridge_autochan;
635
636         return retval;
637 }
638
639 static int channel_spy(struct ast_channel *chan, struct ast_autochan *spyee_autochan,
640         int *volfactor, int fd, struct spy_dtmf_options *user_options, struct ast_flags *flags,
641         char *exitcontext)
642 {
643         struct chanspy_translation_helper csth;
644         int running = 0, bridge_connected = 0, res, x = 0;
645         char inp[24] = {0};
646         char *name;
647         struct ast_frame *f;
648         struct ast_silence_generator *silgen = NULL;
649         struct ast_autochan *spyee_bridge_autochan = NULL;
650         const char *spyer_name;
651
652         ast_channel_lock(chan);
653         if (ast_check_hangup(chan)) {
654                 ast_channel_unlock(chan);
655                 return 0;
656         }
657         spyer_name = ast_strdupa(ast_channel_name(chan));
658         ast_channel_unlock(chan);
659
660         ast_autochan_channel_lock(spyee_autochan);
661         if (ast_check_hangup(spyee_autochan->chan)
662                 || ast_test_flag(ast_channel_flags(spyee_autochan->chan), AST_FLAG_ZOMBIE)) {
663                 ast_autochan_channel_unlock(spyee_autochan);
664                 return 0;
665         }
666         name = ast_strdupa(ast_channel_name(spyee_autochan->chan));
667
668         ast_verb(2, "Spying on channel %s\n", name);
669         publish_chanspy_message(chan, spyee_autochan->chan, 1);
670         ast_autochan_channel_unlock(spyee_autochan);
671
672         memset(&csth, 0, sizeof(csth));
673         ast_copy_flags(&csth.flags, flags, AST_FLAGS_ALL);
674
675         /* This is the audiohook which gives us the audio off the channel we are
676            spying on.
677         */
678         ast_audiohook_init(&csth.spy_audiohook, AST_AUDIOHOOK_TYPE_SPY, "ChanSpy", 0);
679
680         if (start_spying(spyee_autochan, spyer_name, &csth.spy_audiohook, flags)) {
681                 ast_audiohook_destroy(&csth.spy_audiohook);
682                 return 0;
683         }
684
685         if (ast_test_flag(flags, OPTION_WHISPER | OPTION_BARGE | OPTION_DTMF_SWITCH_MODES)) {
686                 /* This audiohook will let us inject audio from our channel into the
687                    channel we are currently spying on.
688                 */
689                 ast_audiohook_init(&csth.whisper_audiohook, AST_AUDIOHOOK_TYPE_WHISPER, "ChanSpy", 0);
690
691                 if (start_spying(spyee_autochan, spyer_name, &csth.whisper_audiohook, flags)) {
692                         ast_log(LOG_WARNING, "Unable to attach whisper audiohook to spyee %s. Whisper mode disabled!\n", name);
693                 }
694         }
695
696         ast_channel_lock(chan);
697         ast_set_flag(ast_channel_flags(chan), AST_FLAG_END_DTMF_ONLY);
698         ast_channel_unlock(chan);
699
700         csth.volfactor = *volfactor;
701
702         if (csth.volfactor) {
703                 csth.spy_audiohook.options.read_volume = csth.volfactor;
704                 csth.spy_audiohook.options.write_volume = csth.volfactor;
705         }
706
707         csth.fd = fd;
708
709         if (ast_test_flag(flags, OPTION_PRIVATE))
710                 silgen = ast_channel_start_silence_generator(chan);
711         else
712                 ast_activate_generator(chan, &spygen, &csth);
713
714         /* We can no longer rely on 'spyee' being an actual channel;
715            it can be hung up and freed out from under us. However, the
716            channel destructor will put NULL into our csth.spy.chan
717            field when that happens, so that is our signal that the spyee
718            channel has gone away.
719         */
720
721         /* Note: it is very important that the ast_waitfor() be the first
722            condition in this expression, so that if we wait for some period
723            of time before receiving a frame from our spying channel, we check
724            for hangup on the spied-on channel _after_ knowing that a frame
725            has arrived, since the spied-on channel could have gone away while
726            we were waiting
727         */
728         while (ast_waitfor(chan, -1) > -1 && csth.spy_audiohook.status == AST_AUDIOHOOK_STATUS_RUNNING) {
729                 if (!(f = ast_read(chan)) || ast_check_hangup(chan)) {
730                         running = -1;
731                         if (f) {
732                                 ast_frfree(f);
733                         }
734                         break;
735                 }
736
737                 if (ast_test_flag(flags, OPTION_BARGE) && f->frametype == AST_FRAME_VOICE) {
738                         /* This hook lets us inject audio into the channel that the spyee is currently
739                          * bridged with. If the spyee isn't bridged with anything yet, nothing will
740                          * be attached and we'll need to continue attempting to attach the barge
741                          * audio hook. */
742                         if (!bridge_connected && attach_barge(spyee_autochan, &spyee_bridge_autochan,
743                                         &csth.bridge_whisper_audiohook, spyer_name, name, flags) == 0) {
744                                 bridge_connected = 1;
745                         }
746
747                         ast_audiohook_lock(&csth.whisper_audiohook);
748                         ast_audiohook_write_frame(&csth.whisper_audiohook, AST_AUDIOHOOK_DIRECTION_WRITE, f);
749                         ast_audiohook_unlock(&csth.whisper_audiohook);
750
751                         if (bridge_connected) {
752                                 ast_audiohook_lock(&csth.bridge_whisper_audiohook);
753                                 ast_audiohook_write_frame(&csth.bridge_whisper_audiohook, AST_AUDIOHOOK_DIRECTION_WRITE, f);
754                                 ast_audiohook_unlock(&csth.bridge_whisper_audiohook);
755                         }
756
757                         ast_frfree(f);
758                         continue;
759                 } else if (ast_test_flag(flags, OPTION_WHISPER) && f->frametype == AST_FRAME_VOICE) {
760                         ast_audiohook_lock(&csth.whisper_audiohook);
761                         ast_audiohook_write_frame(&csth.whisper_audiohook, AST_AUDIOHOOK_DIRECTION_WRITE, f);
762                         ast_audiohook_unlock(&csth.whisper_audiohook);
763                         ast_frfree(f);
764                         continue;
765                 }
766
767                 res = (f->frametype == AST_FRAME_DTMF) ? f->subclass.integer : 0;
768                 ast_frfree(f);
769                 if (!res)
770                         continue;
771
772                 if (x == sizeof(inp))
773                         x = 0;
774
775                 if (res < 0) {
776                         running = -1;
777                         break;
778                 }
779
780                 if (ast_test_flag(flags, OPTION_EXIT)) {
781                         char tmp[2];
782                         tmp[0] = res;
783                         tmp[1] = '\0';
784                         if (!ast_goto_if_exists(chan, exitcontext, tmp, 1)) {
785                                 ast_debug(1, "Got DTMF %c, goto context %s\n", tmp[0], exitcontext);
786                                 pbx_builtin_setvar_helper(chan, "SPY_CHANNEL", name);
787                                 running = -2;
788                                 break;
789                         } else {
790                                 ast_debug(2, "Exit by single digit did not work in chanspy. Extension %s does not exist in context %s\n", tmp, exitcontext);
791                         }
792                 } else if (res >= '0' && res <= '9') {
793                         if (ast_test_flag(flags, OPTION_DTMF_SWITCH_MODES)) {
794                                 change_spy_mode(res, flags);
795                         } else {
796                                 inp[x++] = res;
797                         }
798                 }
799
800                 if (res == user_options->cycle) {
801                         running = 0;
802                         break;
803                 } else if (res == user_options->exit) {
804                         running = -2;
805                         break;
806                 } else if (res == user_options->volume) {
807                         if (!ast_strlen_zero(inp)) {
808                                 running = atoi(inp);
809                                 break;
810                         }
811
812                         (*volfactor)++;
813                         if (*volfactor > 4)
814                                 *volfactor = -4;
815                         ast_verb(3, "Setting spy volume on %s to %d\n", ast_channel_name(chan), *volfactor);
816
817                         csth.volfactor = *volfactor;
818                         csth.spy_audiohook.options.read_volume = csth.volfactor;
819                         csth.spy_audiohook.options.write_volume = csth.volfactor;
820                 }
821         }
822
823         if (ast_test_flag(flags, OPTION_PRIVATE))
824                 ast_channel_stop_silence_generator(chan, silgen);
825         else
826                 ast_deactivate_generator(chan);
827
828         ast_channel_lock(chan);
829         ast_clear_flag(ast_channel_flags(chan), AST_FLAG_END_DTMF_ONLY);
830         ast_channel_unlock(chan);
831
832         if (ast_test_flag(flags, OPTION_WHISPER | OPTION_BARGE | OPTION_DTMF_SWITCH_MODES)) {
833                 ast_audiohook_lock(&csth.whisper_audiohook);
834                 ast_audiohook_detach(&csth.whisper_audiohook);
835                 ast_audiohook_unlock(&csth.whisper_audiohook);
836                 ast_audiohook_destroy(&csth.whisper_audiohook);
837         }
838
839         if (ast_test_flag(flags, OPTION_BARGE | OPTION_DTMF_SWITCH_MODES)) {
840                 ast_audiohook_lock(&csth.bridge_whisper_audiohook);
841                 ast_audiohook_detach(&csth.bridge_whisper_audiohook);
842                 ast_audiohook_unlock(&csth.bridge_whisper_audiohook);
843                 ast_audiohook_destroy(&csth.bridge_whisper_audiohook);
844         }
845
846         ast_audiohook_lock(&csth.spy_audiohook);
847         ast_audiohook_detach(&csth.spy_audiohook);
848         ast_audiohook_unlock(&csth.spy_audiohook);
849         ast_audiohook_destroy(&csth.spy_audiohook);
850
851         if (spyee_bridge_autochan) {
852                 ast_autochan_destroy(spyee_bridge_autochan);
853         }
854
855         ast_verb(2, "Done Spying on channel %s\n", name);
856         publish_chanspy_message(chan, NULL, 0);
857
858         return running;
859 }
860
861 static struct ast_autochan *next_channel(struct ast_channel_iterator *iter,
862         struct ast_channel *chan)
863 {
864         struct ast_channel *next;
865         struct ast_autochan *autochan_store;
866         const size_t pseudo_len = strlen("DAHDI/pseudo");
867
868         if (!iter) {
869                 return NULL;
870         }
871
872         for (; (next = ast_channel_iterator_next(iter)); ast_channel_unref(next)) {
873                 if (!strncmp(ast_channel_name(next), "DAHDI/pseudo", pseudo_len)
874                         || next == chan) {
875                         continue;
876                 }
877
878                 autochan_store = ast_autochan_setup(next);
879                 ast_channel_unref(next);
880
881                 return autochan_store;
882         }
883         return NULL;
884 }
885
886 static int spy_sayname(struct ast_channel *chan, const char *mailbox, const char *context)
887 {
888         char *mailbox_id;
889
890         mailbox_id = ast_alloca(strlen(mailbox) + strlen(context) + 2);
891         sprintf(mailbox_id, "%s@%s", mailbox, context); /* Safe */
892         return ast_app_sayname(chan, mailbox_id);
893 }
894
895 static int common_exec(struct ast_channel *chan, struct ast_flags *flags,
896         int volfactor, const int fd, struct spy_dtmf_options *user_options,
897         const char *mygroup, const char *myenforced, const char *spec, const char *exten,
898         const char *context, const char *mailbox, const char *name_context)
899 {
900         char nameprefix[AST_NAME_STRLEN];
901         char exitcontext[AST_MAX_CONTEXT] = "";
902         signed char zero_volume = 0;
903         int waitms;
904         int res;
905         int num_spyed_upon = 1;
906         struct ast_channel_iterator *iter = NULL;
907
908         if (ast_test_flag(flags, OPTION_EXIT)) {
909                 const char *c;
910                 ast_channel_lock(chan);
911                 if ((c = pbx_builtin_getvar_helper(chan, "SPY_EXIT_CONTEXT"))) {
912                         ast_copy_string(exitcontext, c, sizeof(exitcontext));
913                 } else if (!ast_strlen_zero(ast_channel_macrocontext(chan))) {
914                         ast_copy_string(exitcontext, ast_channel_macrocontext(chan), sizeof(exitcontext));
915                 } else {
916                         ast_copy_string(exitcontext, ast_channel_context(chan), sizeof(exitcontext));
917                 }
918                 ast_channel_unlock(chan);
919         }
920
921         if (ast_channel_state(chan) != AST_STATE_UP)
922                 ast_answer(chan);
923
924         ast_set_flag(ast_channel_flags(chan), AST_FLAG_SPYING); /* so nobody can spy on us while we are spying */
925
926         waitms = 100;
927
928         for (;;) {
929                 struct ast_autochan *autochan = NULL, *next_autochan = NULL;
930                 struct ast_channel *prev = NULL;
931
932                 if (!ast_test_flag(flags, OPTION_QUIET) && num_spyed_upon) {
933                         res = ast_streamfile(chan, "beep", ast_channel_language(chan));
934                         if (!res)
935                                 res = ast_waitstream(chan, "");
936                         else if (res < 0) {
937                                 ast_clear_flag(ast_channel_flags(chan), AST_FLAG_SPYING);
938                                 break;
939                         }
940                         if (!ast_strlen_zero(exitcontext)) {
941                                 char tmp[2];
942                                 tmp[0] = res;
943                                 tmp[1] = '\0';
944                                 if (!ast_goto_if_exists(chan, exitcontext, tmp, 1))
945                                         goto exit;
946                                 else
947                                         ast_debug(2, "Exit by single digit did not work in chanspy. Extension %s does not exist in context %s\n", tmp, exitcontext);
948                         }
949                 }
950
951                 /* Set up the iterator we'll be using during this call */
952                 if (!ast_strlen_zero(spec)) {
953                         if (ast_test_flag(flags, OPTION_UNIQUEID)) {
954                                 struct ast_channel *unique_chan;
955
956                                 unique_chan = ast_channel_get_by_name(spec);
957                                 if (!unique_chan) {
958                                         res = -1;
959                                         goto exit;
960                                 }
961                                 iter = ast_channel_iterator_by_name_new(ast_channel_name(unique_chan), 0);
962                                 ast_channel_unref(unique_chan);
963                         } else {
964                                 iter = ast_channel_iterator_by_name_new(spec, strlen(spec));
965                         }
966                 } else if (!ast_strlen_zero(exten)) {
967                         iter = ast_channel_iterator_by_exten_new(exten, context);
968                 } else {
969                         iter = ast_channel_iterator_all_new();
970                 }
971
972                 if (!iter) {
973                         res = -1;
974                         goto exit;
975                 }
976
977                 res = ast_waitfordigit(chan, waitms);
978                 if (res < 0) {
979                         iter = ast_channel_iterator_destroy(iter);
980                         ast_clear_flag(ast_channel_flags(chan), AST_FLAG_SPYING);
981                         break;
982                 }
983                 if (!ast_strlen_zero(exitcontext)) {
984                         char tmp[2];
985                         tmp[0] = res;
986                         tmp[1] = '\0';
987                         if (!ast_goto_if_exists(chan, exitcontext, tmp, 1)) {
988                                 iter = ast_channel_iterator_destroy(iter);
989                                 goto exit;
990                         } else {
991                                 ast_debug(2, "Exit by single digit did not work in chanspy. Extension %s does not exist in context %s\n", tmp, exitcontext);
992                         }
993                 }
994
995                 /* reset for the next loop around, unless overridden later */
996                 waitms = 100;
997                 num_spyed_upon = 0;
998
999                 for (autochan = next_channel(iter, chan);
1000                         autochan;
1001                         prev = autochan->chan,
1002                                 ast_autochan_destroy(autochan),
1003                                 autochan = next_autochan ?: next_channel(iter, chan),
1004                                 next_autochan = NULL) {
1005                         int igrp = !mygroup;
1006                         int ienf = !myenforced;
1007
1008                         if (autochan->chan == prev) {
1009                                 ast_autochan_destroy(autochan);
1010                                 break;
1011                         }
1012
1013                         if (ast_check_hangup(chan)) {
1014                                 ast_autochan_destroy(autochan);
1015                                 break;
1016                         }
1017
1018                         ast_autochan_channel_lock(autochan);
1019                         if (ast_test_flag(flags, OPTION_BRIDGED)
1020                                 && !ast_channel_is_bridged(autochan->chan)) {
1021                                 ast_autochan_channel_unlock(autochan);
1022                                 continue;
1023                         }
1024
1025                         if (ast_check_hangup(autochan->chan)
1026                                 || ast_test_flag(ast_channel_flags(autochan->chan), AST_FLAG_SPYING)) {
1027                                 ast_autochan_channel_unlock(autochan);
1028                                 continue;
1029                         }
1030                         ast_autochan_channel_unlock(autochan);
1031
1032                         if (mygroup) {
1033                                 int num_groups = 0;
1034                                 int num_mygroups = 0;
1035                                 char dup_group[512];
1036                                 char dup_mygroup[512];
1037                                 char *groups[NUM_SPYGROUPS];
1038                                 char *mygroups[NUM_SPYGROUPS];
1039                                 const char *group = NULL;
1040                                 int x;
1041                                 int y;
1042                                 ast_copy_string(dup_mygroup, mygroup, sizeof(dup_mygroup));
1043                                 num_mygroups = ast_app_separate_args(dup_mygroup, ':', mygroups,
1044                                         ARRAY_LEN(mygroups));
1045
1046                                 /* Before dahdi scan was part of chanspy, it would use the "GROUP" variable 
1047                                  * rather than "SPYGROUP", this check is done to preserve expected behavior */
1048                                 ast_autochan_channel_lock(autochan);
1049                                 if (ast_test_flag(flags, OPTION_DAHDI_SCAN)) {
1050                                         group = pbx_builtin_getvar_helper(autochan->chan, "GROUP");
1051                                 } else {
1052                                         group = pbx_builtin_getvar_helper(autochan->chan, "SPYGROUP");
1053                                 }
1054                                 ast_autochan_channel_unlock(autochan);
1055
1056                                 if (!ast_strlen_zero(group)) {
1057                                         ast_copy_string(dup_group, group, sizeof(dup_group));
1058                                         num_groups = ast_app_separate_args(dup_group, ':', groups,
1059                                                 ARRAY_LEN(groups));
1060                                 }
1061
1062                                 for (y = 0; y < num_mygroups; y++) {
1063                                         for (x = 0; x < num_groups; x++) {
1064                                                 if (!strcmp(mygroups[y], groups[x])) {
1065                                                         igrp = 1;
1066                                                         break;
1067                                                 }
1068                                         }
1069                                 }
1070                         }
1071
1072                         if (!igrp) {
1073                                 continue;
1074                         }
1075                         if (myenforced) {
1076                                 char ext[AST_CHANNEL_NAME + 3];
1077                                 char buffer[512];
1078                                 char *end;
1079
1080                                 snprintf(buffer, sizeof(buffer) - 1, ":%s:", myenforced);
1081
1082                                 ast_autochan_channel_lock(autochan);
1083                                 ast_copy_string(ext + 1, ast_channel_name(autochan->chan), sizeof(ext) - 1);
1084                                 ast_autochan_channel_unlock(autochan);
1085                                 if ((end = strchr(ext, '-'))) {
1086                                         *end++ = ':';
1087                                         *end = '\0';
1088                                 }
1089
1090                                 ext[0] = ':';
1091
1092                                 if (strcasestr(buffer, ext)) {
1093                                         ienf = 1;
1094                                 }
1095                         }
1096
1097                         if (!ienf) {
1098                                 continue;
1099                         }
1100
1101                         if (!ast_test_flag(flags, OPTION_QUIET)) {
1102                                 char peer_name[AST_NAME_STRLEN + 5];
1103                                 char *ptr, *s;
1104
1105                                 strcpy(peer_name, "spy-");
1106                                 ast_autochan_channel_lock(autochan);
1107                                 strncat(peer_name, ast_channel_name(autochan->chan), AST_NAME_STRLEN - 4 - 1);
1108                                 ast_autochan_channel_unlock(autochan);
1109                                 if ((ptr = strchr(peer_name, '/'))) {
1110                                         *ptr++ = '\0';
1111                                         for (s = peer_name; s < ptr; s++) {
1112                                                 *s = tolower(*s);
1113                                         }
1114                                         if ((s = strchr(ptr, '-'))) {
1115                                                 *s = '\0';
1116                                         }
1117                                 }
1118
1119                                 if (ast_test_flag(flags, OPTION_NAME)) {
1120                                         const char *local_context = S_OR(name_context, "default");
1121                                         const char *local_mailbox = S_OR(mailbox, ptr);
1122
1123                                         if (local_mailbox) {
1124                                                 res = spy_sayname(chan, local_mailbox, local_context);
1125                                         } else {
1126                                                 res = -1;
1127                                         }
1128                                 }
1129                                 if (!ast_test_flag(flags, OPTION_NAME) || res < 0) {
1130                                         int num;
1131                                         if (!ast_test_flag(flags, OPTION_NOTECH)) {
1132                                                 if (ast_fileexists(peer_name, NULL, NULL) > 0) {
1133                                                         res = ast_streamfile(chan, peer_name, ast_channel_language(chan));
1134                                                         if (!res) {
1135                                                                 res = ast_waitstream(chan, "");
1136                                                         }
1137                                                         if (res) {
1138                                                                 ast_autochan_destroy(autochan);
1139                                                                 break;
1140                                                         }
1141                                                 } else {
1142                                                         res = ast_say_character_str(chan, peer_name, "", ast_channel_language(chan), AST_SAY_CASE_NONE);
1143                                                 }
1144                                         }
1145                                         if (ptr && (num = atoi(ptr))) {
1146                                                 ast_say_digits(chan, num, "", ast_channel_language(chan));
1147                                         }
1148                                 }
1149                         }
1150
1151                         res = channel_spy(chan, autochan, &volfactor, fd, user_options, flags, exitcontext);
1152                         num_spyed_upon++;
1153
1154                         if (res == -1) {
1155                                 ast_autochan_destroy(autochan);
1156                                 iter = ast_channel_iterator_destroy(iter);
1157                                 goto exit;
1158                         } else if (res == -2) {
1159                                 res = 0;
1160                                 ast_autochan_destroy(autochan);
1161                                 iter = ast_channel_iterator_destroy(iter);
1162                                 goto exit;
1163                         } else if (res > 1 && spec && !ast_test_flag(flags, OPTION_UNIQUEID)) {
1164                                 struct ast_channel *next;
1165
1166                                 snprintf(nameprefix, AST_NAME_STRLEN, "%s/%d", spec, res);
1167
1168                                 if ((next = ast_channel_get_by_name_prefix(nameprefix, strlen(nameprefix)))) {
1169                                         next_autochan = ast_autochan_setup(next);
1170                                         next = ast_channel_unref(next);
1171                                 } else {
1172                                         /* stay on this channel, if it is still valid */
1173                                         ast_autochan_channel_lock(autochan);
1174                                         if (!ast_check_hangup(autochan->chan)) {
1175                                                 next_autochan = ast_autochan_setup(autochan->chan);
1176                                         } else {
1177                                                 /* the channel is gone */
1178                                                 next_autochan = NULL;
1179                                         }
1180                                         ast_autochan_channel_unlock(autochan);
1181                                 }
1182                         } else if (res == 0 && ast_test_flag(flags, OPTION_EXITONHANGUP)) {
1183                                 ast_autochan_destroy(autochan);
1184                                 iter = ast_channel_iterator_destroy(iter);
1185                                 goto exit;
1186                         }
1187                 }
1188
1189                 iter = ast_channel_iterator_destroy(iter);
1190
1191                 if (res == -1 || ast_check_hangup(chan))
1192                         break;
1193                 if (ast_test_flag(flags, OPTION_STOP) && !next_autochan) {
1194                         break;
1195                 }
1196         }
1197 exit:
1198
1199         ast_clear_flag(ast_channel_flags(chan), AST_FLAG_SPYING);
1200
1201         ast_channel_setoption(chan, AST_OPTION_TXGAIN, &zero_volume, sizeof(zero_volume), 0);
1202
1203         return res;
1204 }
1205
1206 static int chanspy_exec(struct ast_channel *chan, const char *data)
1207 {
1208         char *myenforced = NULL;
1209         char *mygroup = NULL;
1210         char *recbase = NULL;
1211         int fd = 0;
1212         struct ast_flags flags;
1213         struct spy_dtmf_options user_options = {
1214                 .cycle = '*',
1215                 .volume = '#',
1216                 .exit = '\0',
1217         };
1218         RAII_VAR(struct ast_format *, oldwf, NULL, ao2_cleanup);
1219         int volfactor = 0;
1220         int res;
1221         char *mailbox = NULL;
1222         char *name_context = NULL;
1223         AST_DECLARE_APP_ARGS(args,
1224                 AST_APP_ARG(spec);
1225                 AST_APP_ARG(options);
1226         );
1227         char *opts[OPT_ARG_ARRAY_SIZE];
1228         char *parse = ast_strdupa(data);
1229
1230         AST_STANDARD_APP_ARGS(args, parse);
1231
1232         if (args.spec && !strcmp(args.spec, "all"))
1233                 args.spec = NULL;
1234
1235         if (args.options) {
1236                 char tmp;
1237                 ast_app_parse_options(spy_opts, &flags, opts, args.options);
1238                 if (ast_test_flag(&flags, OPTION_GROUP))
1239                         mygroup = opts[OPT_ARG_GROUP];
1240
1241                 if (ast_test_flag(&flags, OPTION_RECORD) &&
1242                         !(recbase = opts[OPT_ARG_RECORD]))
1243                         recbase = "chanspy";
1244
1245                 if (ast_test_flag(&flags, OPTION_DTMF_EXIT) && opts[OPT_ARG_EXIT]) {
1246                         tmp = opts[OPT_ARG_EXIT][0];
1247                         if (strchr("0123456789*#", tmp) && tmp != '\0') {
1248                                 user_options.exit = tmp;
1249                         } else {
1250                                 ast_log(LOG_NOTICE, "Argument for option 'x' must be a valid DTMF digit.\n");
1251                         }
1252                 }
1253
1254                 if (ast_test_flag(&flags, OPTION_DTMF_CYCLE) && opts[OPT_ARG_CYCLE]) {
1255                         tmp = opts[OPT_ARG_CYCLE][0];
1256                         if (strchr("0123456789*#", tmp) && tmp != '\0') {
1257                                 user_options.cycle = tmp;
1258                         } else {
1259                                 ast_log(LOG_NOTICE, "Argument for option 'c' must be a valid DTMF digit.\n");
1260                         }
1261                 }
1262
1263                 if (ast_test_flag(&flags, OPTION_VOLUME) && opts[OPT_ARG_VOLUME]) {
1264                         int vol;
1265
1266                         if ((sscanf(opts[OPT_ARG_VOLUME], "%30d", &vol) != 1) || (vol > 4) || (vol < -4))
1267                                 ast_log(LOG_NOTICE, "Volume factor must be a number between -4 and 4\n");
1268                         else
1269                                 volfactor = vol;
1270                 }
1271
1272                 if (ast_test_flag(&flags, OPTION_PRIVATE))
1273                         ast_set_flag(&flags, OPTION_WHISPER);
1274
1275                 if (ast_test_flag(&flags, OPTION_ENFORCED))
1276                         myenforced = opts[OPT_ARG_ENFORCED];
1277
1278                 if (ast_test_flag(&flags, OPTION_NAME)) {
1279                         if (!ast_strlen_zero(opts[OPT_ARG_NAME])) {
1280                                 char *delimiter;
1281                                 if ((delimiter = strchr(opts[OPT_ARG_NAME], '@'))) {
1282                                         mailbox = opts[OPT_ARG_NAME];
1283                                         *delimiter++ = '\0';
1284                                         name_context = delimiter;
1285                                 } else {
1286                                         mailbox = opts[OPT_ARG_NAME];
1287                                 }
1288                         }
1289                 }
1290         } else {
1291                 ast_clear_flag(&flags, AST_FLAGS_ALL);
1292         }
1293
1294         oldwf = ao2_bump(ast_channel_writeformat(chan));
1295         if (ast_set_write_format(chan, ast_format_slin) < 0) {
1296                 ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
1297                 return -1;
1298         }
1299
1300         if (recbase) {
1301                 char filename[PATH_MAX];
1302
1303                 snprintf(filename, sizeof(filename), "%s/%s.%d.raw", ast_config_AST_MONITOR_DIR, recbase, (int) time(NULL));
1304                 if ((fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, AST_FILE_MODE)) <= 0) {
1305                         ast_log(LOG_WARNING, "Cannot open '%s' for recording\n", filename);
1306                         fd = 0;
1307                 }
1308         }
1309
1310         res = common_exec(chan, &flags, volfactor, fd, &user_options, mygroup, myenforced, args.spec, NULL, NULL, mailbox, name_context);
1311
1312         if (fd)
1313                 close(fd);
1314
1315         if (oldwf && ast_set_write_format(chan, oldwf) < 0)
1316                 ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
1317
1318         if (ast_test_flag(&flags, OPTION_EXITONHANGUP)) {
1319                 ast_verb(3, "Stopped spying due to the spied-on channel hanging up.\n");
1320         }
1321
1322         return res;
1323 }
1324
1325 static int extenspy_exec(struct ast_channel *chan, const char *data)
1326 {
1327         char *ptr, *exten = NULL;
1328         char *mygroup = NULL;
1329         char *recbase = NULL;
1330         int fd = 0;
1331         struct ast_flags flags;
1332         struct spy_dtmf_options user_options = {
1333                 .cycle = '*',
1334                 .volume = '#',
1335                 .exit = '\0',
1336         };
1337         RAII_VAR(struct ast_format *, oldwf, NULL, ao2_cleanup);
1338         int volfactor = 0;
1339         int res;
1340         char *mailbox = NULL;
1341         char *name_context = NULL;
1342         AST_DECLARE_APP_ARGS(args,
1343                 AST_APP_ARG(context);
1344                 AST_APP_ARG(options);
1345         );
1346         char *parse = ast_strdupa(data);
1347
1348         AST_STANDARD_APP_ARGS(args, parse);
1349
1350         if (!ast_strlen_zero(args.context) && (ptr = strchr(args.context, '@'))) {
1351                 exten = args.context;
1352                 *ptr++ = '\0';
1353                 args.context = ptr;
1354         }
1355         if (ast_strlen_zero(args.context))
1356                 args.context = ast_strdupa(ast_channel_context(chan));
1357
1358         if (args.options) {
1359                 char *opts[OPT_ARG_ARRAY_SIZE];
1360                 char tmp;
1361
1362                 ast_app_parse_options(spy_opts, &flags, opts, args.options);
1363                 if (ast_test_flag(&flags, OPTION_GROUP))
1364                         mygroup = opts[OPT_ARG_GROUP];
1365
1366                 if (ast_test_flag(&flags, OPTION_RECORD) &&
1367                         !(recbase = opts[OPT_ARG_RECORD]))
1368                         recbase = "chanspy";
1369
1370                 if (ast_test_flag(&flags, OPTION_DTMF_EXIT) && opts[OPT_ARG_EXIT]) {
1371                         tmp = opts[OPT_ARG_EXIT][0];
1372                         if (strchr("0123456789*#", tmp) && tmp != '\0') {
1373                                 user_options.exit = tmp;
1374                         } else {
1375                                 ast_log(LOG_NOTICE, "Argument for option 'x' must be a valid DTMF digit.\n");
1376                         }
1377                 }
1378
1379                 if (ast_test_flag(&flags, OPTION_DTMF_CYCLE) && opts[OPT_ARG_CYCLE]) {
1380                         tmp = opts[OPT_ARG_CYCLE][0];
1381                         if (strchr("0123456789*#", tmp) && tmp != '\0') {
1382                                 user_options.cycle = tmp;
1383                         } else {
1384                                 ast_log(LOG_NOTICE, "Argument for option 'c' must be a valid DTMF digit.\n");
1385                         }
1386                 }
1387
1388                 if (ast_test_flag(&flags, OPTION_VOLUME) && opts[OPT_ARG_VOLUME]) {
1389                         int vol;
1390
1391                         if ((sscanf(opts[OPT_ARG_VOLUME], "%30d", &vol) != 1) || (vol > 4) || (vol < -4))
1392                                 ast_log(LOG_NOTICE, "Volume factor must be a number between -4 and 4\n");
1393                         else
1394                                 volfactor = vol;
1395                 }
1396
1397                 if (ast_test_flag(&flags, OPTION_PRIVATE))
1398                         ast_set_flag(&flags, OPTION_WHISPER);
1399
1400                 if (ast_test_flag(&flags, OPTION_NAME)) {
1401                         if (!ast_strlen_zero(opts[OPT_ARG_NAME])) {
1402                                 char *delimiter;
1403                                 if ((delimiter = strchr(opts[OPT_ARG_NAME], '@'))) {
1404                                         mailbox = opts[OPT_ARG_NAME];
1405                                         *delimiter++ = '\0';
1406                                         name_context = delimiter;
1407                                 } else {
1408                                         mailbox = opts[OPT_ARG_NAME];
1409                                 }
1410                         }
1411                 }
1412
1413         } else {
1414                 /* Coverity - This uninit_use should be ignored since this macro initializes the flags */
1415                 ast_clear_flag(&flags, AST_FLAGS_ALL);
1416         }
1417
1418         oldwf = ao2_bump(ast_channel_writeformat(chan));
1419         if (ast_set_write_format(chan, ast_format_slin) < 0) {
1420                 ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
1421                 return -1;
1422         }
1423
1424         if (recbase) {
1425                 char filename[PATH_MAX];
1426
1427                 snprintf(filename, sizeof(filename), "%s/%s.%d.raw", ast_config_AST_MONITOR_DIR, recbase, (int) time(NULL));
1428                 if ((fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, AST_FILE_MODE)) <= 0) {
1429                         ast_log(LOG_WARNING, "Cannot open '%s' for recording\n", filename);
1430                         fd = 0;
1431                 }
1432         }
1433
1434
1435         res = common_exec(chan, &flags, volfactor, fd, &user_options, mygroup, NULL, NULL, exten, args.context, mailbox, name_context);
1436
1437         if (fd)
1438                 close(fd);
1439
1440         if (oldwf && ast_set_write_format(chan, oldwf) < 0)
1441                 ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
1442
1443         return res;
1444 }
1445
1446 static int dahdiscan_exec(struct ast_channel *chan, const char *data)
1447 {
1448         const char *spec = "DAHDI";
1449         struct ast_flags flags;
1450         struct spy_dtmf_options user_options = {
1451                 .cycle = '#',
1452                 .volume = '\0',
1453                 .exit = '*',
1454         };
1455         struct ast_format *oldwf;
1456         int res;
1457         char *mygroup = NULL;
1458
1459         /* Coverity - This uninit_use should be ignored since this macro initializes the flags */
1460         ast_clear_flag(&flags, AST_FLAGS_ALL);
1461
1462         if (!ast_strlen_zero(data)) {
1463                 mygroup = ast_strdupa(data);
1464         }
1465         ast_set_flag(&flags, OPTION_DTMF_EXIT);
1466         ast_set_flag(&flags, OPTION_DTMF_CYCLE);
1467         ast_set_flag(&flags, OPTION_DAHDI_SCAN);
1468
1469         oldwf = ao2_bump(ast_channel_writeformat(chan));
1470         if (ast_set_write_format(chan, ast_format_slin) < 0) {
1471                 ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
1472                 ao2_cleanup(oldwf);
1473                 return -1;
1474         }
1475
1476         res = common_exec(chan, &flags, 0, 0, &user_options, mygroup, NULL, spec, NULL, NULL, NULL, NULL);
1477
1478         if (oldwf && ast_set_write_format(chan, oldwf) < 0)
1479                 ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
1480         ao2_cleanup(oldwf);
1481
1482         return res;
1483 }
1484
1485 static int unload_module(void)
1486 {
1487         int res = 0;
1488
1489         res |= ast_unregister_application(app_chan);
1490         res |= ast_unregister_application(app_ext);
1491         res |= ast_unregister_application(app_dahdiscan);
1492
1493         return res;
1494 }
1495
1496 static int load_module(void)
1497 {
1498         int res = 0;
1499
1500         res |= ast_register_application_xml(app_chan, chanspy_exec);
1501         res |= ast_register_application_xml(app_ext, extenspy_exec);
1502         res |= ast_register_application_xml(app_dahdiscan, dahdiscan_exec);
1503
1504         return res;
1505 }
1506
1507 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Listen to the audio of an active channel");