Merge "astobj2: Create function to copy weak proxied objects from container."
[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_set_flag(chan, AST_FLAG_END_DTMF_ONLY);
697
698         csth.volfactor = *volfactor;
699
700         if (csth.volfactor) {
701                 csth.spy_audiohook.options.read_volume = csth.volfactor;
702                 csth.spy_audiohook.options.write_volume = csth.volfactor;
703         }
704
705         csth.fd = fd;
706
707         if (ast_test_flag(flags, OPTION_PRIVATE))
708                 silgen = ast_channel_start_silence_generator(chan);
709         else
710                 ast_activate_generator(chan, &spygen, &csth);
711
712         /* We can no longer rely on 'spyee' being an actual channel;
713            it can be hung up and freed out from under us. However, the
714            channel destructor will put NULL into our csth.spy.chan
715            field when that happens, so that is our signal that the spyee
716            channel has gone away.
717         */
718
719         /* Note: it is very important that the ast_waitfor() be the first
720            condition in this expression, so that if we wait for some period
721            of time before receiving a frame from our spying channel, we check
722            for hangup on the spied-on channel _after_ knowing that a frame
723            has arrived, since the spied-on channel could have gone away while
724            we were waiting
725         */
726         while (ast_waitfor(chan, -1) > -1 && csth.spy_audiohook.status == AST_AUDIOHOOK_STATUS_RUNNING) {
727                 if (!(f = ast_read(chan)) || ast_check_hangup(chan)) {
728                         running = -1;
729                         if (f) {
730                                 ast_frfree(f);
731                         }
732                         break;
733                 }
734
735                 if (ast_test_flag(flags, OPTION_BARGE) && f->frametype == AST_FRAME_VOICE) {
736                         /* This hook lets us inject audio into the channel that the spyee is currently
737                          * bridged with. If the spyee isn't bridged with anything yet, nothing will
738                          * be attached and we'll need to continue attempting to attach the barge
739                          * audio hook. */
740                         if (!bridge_connected && attach_barge(spyee_autochan, &spyee_bridge_autochan,
741                                         &csth.bridge_whisper_audiohook, spyer_name, name, flags) == 0) {
742                                 bridge_connected = 1;
743                         }
744
745                         ast_audiohook_lock(&csth.whisper_audiohook);
746                         ast_audiohook_write_frame(&csth.whisper_audiohook, AST_AUDIOHOOK_DIRECTION_WRITE, f);
747                         ast_audiohook_unlock(&csth.whisper_audiohook);
748
749                         if (bridge_connected) {
750                                 ast_audiohook_lock(&csth.bridge_whisper_audiohook);
751                                 ast_audiohook_write_frame(&csth.bridge_whisper_audiohook, AST_AUDIOHOOK_DIRECTION_WRITE, f);
752                                 ast_audiohook_unlock(&csth.bridge_whisper_audiohook);
753                         }
754
755                         ast_frfree(f);
756                         continue;
757                 } else if (ast_test_flag(flags, OPTION_WHISPER) && f->frametype == AST_FRAME_VOICE) {
758                         ast_audiohook_lock(&csth.whisper_audiohook);
759                         ast_audiohook_write_frame(&csth.whisper_audiohook, AST_AUDIOHOOK_DIRECTION_WRITE, f);
760                         ast_audiohook_unlock(&csth.whisper_audiohook);
761                         ast_frfree(f);
762                         continue;
763                 }
764
765                 res = (f->frametype == AST_FRAME_DTMF) ? f->subclass.integer : 0;
766                 ast_frfree(f);
767                 if (!res)
768                         continue;
769
770                 if (x == sizeof(inp))
771                         x = 0;
772
773                 if (res < 0) {
774                         running = -1;
775                         break;
776                 }
777
778                 if (ast_test_flag(flags, OPTION_EXIT)) {
779                         char tmp[2];
780                         tmp[0] = res;
781                         tmp[1] = '\0';
782                         if (!ast_goto_if_exists(chan, exitcontext, tmp, 1)) {
783                                 ast_debug(1, "Got DTMF %c, goto context %s\n", tmp[0], exitcontext);
784                                 pbx_builtin_setvar_helper(chan, "SPY_CHANNEL", name);
785                                 running = -2;
786                                 break;
787                         } else {
788                                 ast_debug(2, "Exit by single digit did not work in chanspy. Extension %s does not exist in context %s\n", tmp, exitcontext);
789                         }
790                 } else if (res >= '0' && res <= '9') {
791                         if (ast_test_flag(flags, OPTION_DTMF_SWITCH_MODES)) {
792                                 change_spy_mode(res, flags);
793                         } else {
794                                 inp[x++] = res;
795                         }
796                 }
797
798                 if (res == user_options->cycle) {
799                         running = 0;
800                         break;
801                 } else if (res == user_options->exit) {
802                         running = -2;
803                         break;
804                 } else if (res == user_options->volume) {
805                         if (!ast_strlen_zero(inp)) {
806                                 running = atoi(inp);
807                                 break;
808                         }
809
810                         (*volfactor)++;
811                         if (*volfactor > 4)
812                                 *volfactor = -4;
813                         ast_verb(3, "Setting spy volume on %s to %d\n", ast_channel_name(chan), *volfactor);
814
815                         csth.volfactor = *volfactor;
816                         csth.spy_audiohook.options.read_volume = csth.volfactor;
817                         csth.spy_audiohook.options.write_volume = csth.volfactor;
818                 }
819         }
820
821         if (ast_test_flag(flags, OPTION_PRIVATE))
822                 ast_channel_stop_silence_generator(chan, silgen);
823         else
824                 ast_deactivate_generator(chan);
825
826         ast_channel_clear_flag(chan, AST_FLAG_END_DTMF_ONLY);
827
828         if (ast_test_flag(flags, OPTION_WHISPER | OPTION_BARGE | OPTION_DTMF_SWITCH_MODES)) {
829                 ast_audiohook_lock(&csth.whisper_audiohook);
830                 ast_audiohook_detach(&csth.whisper_audiohook);
831                 ast_audiohook_unlock(&csth.whisper_audiohook);
832                 ast_audiohook_destroy(&csth.whisper_audiohook);
833         }
834
835         if (ast_test_flag(flags, OPTION_BARGE | OPTION_DTMF_SWITCH_MODES)) {
836                 ast_audiohook_lock(&csth.bridge_whisper_audiohook);
837                 ast_audiohook_detach(&csth.bridge_whisper_audiohook);
838                 ast_audiohook_unlock(&csth.bridge_whisper_audiohook);
839                 ast_audiohook_destroy(&csth.bridge_whisper_audiohook);
840         }
841
842         ast_audiohook_lock(&csth.spy_audiohook);
843         ast_audiohook_detach(&csth.spy_audiohook);
844         ast_audiohook_unlock(&csth.spy_audiohook);
845         ast_audiohook_destroy(&csth.spy_audiohook);
846
847         if (spyee_bridge_autochan) {
848                 ast_autochan_destroy(spyee_bridge_autochan);
849         }
850
851         ast_verb(2, "Done Spying on channel %s\n", name);
852         publish_chanspy_message(chan, NULL, 0);
853
854         return running;
855 }
856
857 static struct ast_autochan *next_channel(struct ast_channel_iterator *iter,
858         struct ast_channel *chan)
859 {
860         struct ast_channel *next;
861         struct ast_autochan *autochan_store;
862         const size_t pseudo_len = strlen("DAHDI/pseudo");
863
864         if (!iter) {
865                 return NULL;
866         }
867
868         for (; (next = ast_channel_iterator_next(iter)); ast_channel_unref(next)) {
869                 if (!strncmp(ast_channel_name(next), "DAHDI/pseudo", pseudo_len)
870                         || next == chan) {
871                         continue;
872                 }
873
874                 autochan_store = ast_autochan_setup(next);
875                 ast_channel_unref(next);
876
877                 return autochan_store;
878         }
879         return NULL;
880 }
881
882 static int spy_sayname(struct ast_channel *chan, const char *mailbox, const char *context)
883 {
884         char *mailbox_id;
885
886         mailbox_id = ast_alloca(strlen(mailbox) + strlen(context) + 2);
887         sprintf(mailbox_id, "%s@%s", mailbox, context); /* Safe */
888         return ast_app_sayname(chan, mailbox_id);
889 }
890
891 static int common_exec(struct ast_channel *chan, struct ast_flags *flags,
892         int volfactor, const int fd, struct spy_dtmf_options *user_options,
893         const char *mygroup, const char *myenforced, const char *spec, const char *exten,
894         const char *context, const char *mailbox, const char *name_context)
895 {
896         char nameprefix[AST_NAME_STRLEN];
897         char exitcontext[AST_MAX_CONTEXT] = "";
898         signed char zero_volume = 0;
899         int waitms;
900         int res;
901         int num_spyed_upon = 1;
902         struct ast_channel_iterator *iter = NULL;
903
904         if (ast_test_flag(flags, OPTION_EXIT)) {
905                 const char *c;
906                 ast_channel_lock(chan);
907                 if ((c = pbx_builtin_getvar_helper(chan, "SPY_EXIT_CONTEXT"))) {
908                         ast_copy_string(exitcontext, c, sizeof(exitcontext));
909                 } else if (!ast_strlen_zero(ast_channel_macrocontext(chan))) {
910                         ast_copy_string(exitcontext, ast_channel_macrocontext(chan), sizeof(exitcontext));
911                 } else {
912                         ast_copy_string(exitcontext, ast_channel_context(chan), sizeof(exitcontext));
913                 }
914                 ast_channel_unlock(chan);
915         }
916
917         if (ast_channel_state(chan) != AST_STATE_UP)
918                 ast_answer(chan);
919
920         ast_channel_set_flag(chan, AST_FLAG_SPYING);
921
922         waitms = 100;
923
924         for (;;) {
925                 struct ast_autochan *autochan = NULL, *next_autochan = NULL;
926                 struct ast_channel *prev = NULL;
927
928                 if (!ast_test_flag(flags, OPTION_QUIET) && num_spyed_upon) {
929                         res = ast_streamfile(chan, "beep", ast_channel_language(chan));
930                         if (!res)
931                                 res = ast_waitstream(chan, "");
932                         else if (res < 0) {
933                                 ast_channel_clear_flag(chan, AST_FLAG_SPYING);
934                                 break;
935                         }
936                         if (!ast_strlen_zero(exitcontext)) {
937                                 char tmp[2];
938                                 tmp[0] = res;
939                                 tmp[1] = '\0';
940                                 if (!ast_goto_if_exists(chan, exitcontext, tmp, 1))
941                                         goto exit;
942                                 else
943                                         ast_debug(2, "Exit by single digit did not work in chanspy. Extension %s does not exist in context %s\n", tmp, exitcontext);
944                         }
945                 }
946
947                 /* Set up the iterator we'll be using during this call */
948                 if (!ast_strlen_zero(spec)) {
949                         if (ast_test_flag(flags, OPTION_UNIQUEID)) {
950                                 struct ast_channel *unique_chan;
951
952                                 unique_chan = ast_channel_get_by_name(spec);
953                                 if (!unique_chan) {
954                                         res = -1;
955                                         goto exit;
956                                 }
957                                 iter = ast_channel_iterator_by_name_new(ast_channel_name(unique_chan), 0);
958                                 ast_channel_unref(unique_chan);
959                         } else {
960                                 iter = ast_channel_iterator_by_name_new(spec, strlen(spec));
961                         }
962                 } else if (!ast_strlen_zero(exten)) {
963                         iter = ast_channel_iterator_by_exten_new(exten, context);
964                 } else {
965                         iter = ast_channel_iterator_all_new();
966                 }
967
968                 if (!iter) {
969                         res = -1;
970                         goto exit;
971                 }
972
973                 res = ast_waitfordigit(chan, waitms);
974                 if (res < 0) {
975                         iter = ast_channel_iterator_destroy(iter);
976                         ast_channel_clear_flag(chan, AST_FLAG_SPYING);
977                         break;
978                 }
979                 if (!ast_strlen_zero(exitcontext)) {
980                         char tmp[2];
981                         tmp[0] = res;
982                         tmp[1] = '\0';
983                         if (!ast_goto_if_exists(chan, exitcontext, tmp, 1)) {
984                                 iter = ast_channel_iterator_destroy(iter);
985                                 goto exit;
986                         } else {
987                                 ast_debug(2, "Exit by single digit did not work in chanspy. Extension %s does not exist in context %s\n", tmp, exitcontext);
988                         }
989                 }
990
991                 /* reset for the next loop around, unless overridden later */
992                 waitms = 100;
993                 num_spyed_upon = 0;
994
995                 for (autochan = next_channel(iter, chan);
996                         autochan;
997                         prev = autochan->chan,
998                                 ast_autochan_destroy(autochan),
999                                 autochan = next_autochan ?: next_channel(iter, chan),
1000                                 next_autochan = NULL) {
1001                         int igrp = !mygroup;
1002                         int ienf = !myenforced;
1003
1004                         if (autochan->chan == prev) {
1005                                 ast_autochan_destroy(autochan);
1006                                 break;
1007                         }
1008
1009                         if (ast_check_hangup(chan)) {
1010                                 ast_autochan_destroy(autochan);
1011                                 break;
1012                         }
1013
1014                         ast_autochan_channel_lock(autochan);
1015                         if (ast_test_flag(flags, OPTION_BRIDGED)
1016                                 && !ast_channel_is_bridged(autochan->chan)) {
1017                                 ast_autochan_channel_unlock(autochan);
1018                                 continue;
1019                         }
1020
1021                         if (ast_check_hangup(autochan->chan)
1022                                 || ast_test_flag(ast_channel_flags(autochan->chan), AST_FLAG_SPYING)) {
1023                                 ast_autochan_channel_unlock(autochan);
1024                                 continue;
1025                         }
1026                         ast_autochan_channel_unlock(autochan);
1027
1028                         if (mygroup) {
1029                                 int num_groups = 0;
1030                                 int num_mygroups = 0;
1031                                 char dup_group[512];
1032                                 char dup_mygroup[512];
1033                                 char *groups[NUM_SPYGROUPS];
1034                                 char *mygroups[NUM_SPYGROUPS];
1035                                 const char *group = NULL;
1036                                 int x;
1037                                 int y;
1038                                 ast_copy_string(dup_mygroup, mygroup, sizeof(dup_mygroup));
1039                                 num_mygroups = ast_app_separate_args(dup_mygroup, ':', mygroups,
1040                                         ARRAY_LEN(mygroups));
1041
1042                                 /* Before dahdi scan was part of chanspy, it would use the "GROUP" variable
1043                                  * rather than "SPYGROUP", this check is done to preserve expected behavior */
1044                                 ast_autochan_channel_lock(autochan);
1045                                 if (ast_test_flag(flags, OPTION_DAHDI_SCAN)) {
1046                                         group = pbx_builtin_getvar_helper(autochan->chan, "GROUP");
1047                                 } else {
1048                                         group = pbx_builtin_getvar_helper(autochan->chan, "SPYGROUP");
1049                                 }
1050                                 ast_autochan_channel_unlock(autochan);
1051
1052                                 if (!ast_strlen_zero(group)) {
1053                                         ast_copy_string(dup_group, group, sizeof(dup_group));
1054                                         num_groups = ast_app_separate_args(dup_group, ':', groups,
1055                                                 ARRAY_LEN(groups));
1056                                 }
1057
1058                                 for (y = 0; y < num_mygroups; y++) {
1059                                         for (x = 0; x < num_groups; x++) {
1060                                                 if (!strcmp(mygroups[y], groups[x])) {
1061                                                         igrp = 1;
1062                                                         break;
1063                                                 }
1064                                         }
1065                                 }
1066                         }
1067
1068                         if (!igrp) {
1069                                 continue;
1070                         }
1071                         if (myenforced) {
1072                                 char ext[AST_CHANNEL_NAME + 3];
1073                                 char buffer[512];
1074                                 char *end;
1075
1076                                 snprintf(buffer, sizeof(buffer) - 1, ":%s:", myenforced);
1077
1078                                 ast_autochan_channel_lock(autochan);
1079                                 ast_copy_string(ext + 1, ast_channel_name(autochan->chan), sizeof(ext) - 1);
1080                                 ast_autochan_channel_unlock(autochan);
1081                                 if ((end = strchr(ext, '-'))) {
1082                                         *end++ = ':';
1083                                         *end = '\0';
1084                                 }
1085
1086                                 ext[0] = ':';
1087
1088                                 if (strcasestr(buffer, ext)) {
1089                                         ienf = 1;
1090                                 }
1091                         }
1092
1093                         if (!ienf) {
1094                                 continue;
1095                         }
1096
1097                         if (!ast_test_flag(flags, OPTION_QUIET)) {
1098                                 char peer_name[AST_NAME_STRLEN + 5];
1099                                 char *ptr, *s;
1100
1101                                 strcpy(peer_name, "spy-");
1102                                 ast_autochan_channel_lock(autochan);
1103                                 strncat(peer_name, ast_channel_name(autochan->chan), AST_NAME_STRLEN - 4 - 1);
1104                                 ast_autochan_channel_unlock(autochan);
1105                                 if ((ptr = strchr(peer_name, '/'))) {
1106                                         *ptr++ = '\0';
1107                                         for (s = peer_name; s < ptr; s++) {
1108                                                 *s = tolower(*s);
1109                                         }
1110                                         if ((s = strchr(ptr, '-'))) {
1111                                                 *s = '\0';
1112                                         }
1113                                 }
1114
1115                                 if (ast_test_flag(flags, OPTION_NAME)) {
1116                                         const char *local_context = S_OR(name_context, "default");
1117                                         const char *local_mailbox = S_OR(mailbox, ptr);
1118
1119                                         if (local_mailbox) {
1120                                                 res = spy_sayname(chan, local_mailbox, local_context);
1121                                         } else {
1122                                                 res = -1;
1123                                         }
1124                                 }
1125                                 if (!ast_test_flag(flags, OPTION_NAME) || res < 0) {
1126                                         int num;
1127                                         if (!ast_test_flag(flags, OPTION_NOTECH)) {
1128                                                 if (ast_fileexists(peer_name, NULL, NULL) > 0) {
1129                                                         res = ast_streamfile(chan, peer_name, ast_channel_language(chan));
1130                                                         if (!res) {
1131                                                                 res = ast_waitstream(chan, "");
1132                                                         }
1133                                                         if (res) {
1134                                                                 ast_autochan_destroy(autochan);
1135                                                                 break;
1136                                                         }
1137                                                 } else {
1138                                                         res = ast_say_character_str(chan, peer_name, "", ast_channel_language(chan), AST_SAY_CASE_NONE);
1139                                                 }
1140                                         }
1141                                         if (ptr && (num = atoi(ptr))) {
1142                                                 ast_say_digits(chan, num, "", ast_channel_language(chan));
1143                                         }
1144                                 }
1145                         }
1146
1147                         res = channel_spy(chan, autochan, &volfactor, fd, user_options, flags, exitcontext);
1148                         num_spyed_upon++;
1149
1150                         if (res == -1) {
1151                                 ast_autochan_destroy(autochan);
1152                                 iter = ast_channel_iterator_destroy(iter);
1153                                 goto exit;
1154                         } else if (res == -2) {
1155                                 res = 0;
1156                                 ast_autochan_destroy(autochan);
1157                                 iter = ast_channel_iterator_destroy(iter);
1158                                 goto exit;
1159                         } else if (res > 1 && spec && !ast_test_flag(flags, OPTION_UNIQUEID)) {
1160                                 struct ast_channel *next;
1161
1162                                 snprintf(nameprefix, AST_NAME_STRLEN, "%s/%d", spec, res);
1163
1164                                 if ((next = ast_channel_get_by_name_prefix(nameprefix, strlen(nameprefix)))) {
1165                                         next_autochan = ast_autochan_setup(next);
1166                                         next = ast_channel_unref(next);
1167                                 } else {
1168                                         /* stay on this channel, if it is still valid */
1169                                         ast_autochan_channel_lock(autochan);
1170                                         if (!ast_check_hangup(autochan->chan)) {
1171                                                 next_autochan = ast_autochan_setup(autochan->chan);
1172                                         } else {
1173                                                 /* the channel is gone */
1174                                                 next_autochan = NULL;
1175                                         }
1176                                         ast_autochan_channel_unlock(autochan);
1177                                 }
1178                         } else if (res == 0 && ast_test_flag(flags, OPTION_EXITONHANGUP)) {
1179                                 ast_autochan_destroy(autochan);
1180                                 iter = ast_channel_iterator_destroy(iter);
1181                                 goto exit;
1182                         }
1183                 }
1184
1185                 iter = ast_channel_iterator_destroy(iter);
1186
1187                 if (res == -1 || ast_check_hangup(chan))
1188                         break;
1189                 if (ast_test_flag(flags, OPTION_STOP) && !next_autochan) {
1190                         break;
1191                 }
1192         }
1193 exit:
1194
1195         ast_channel_clear_flag(chan, AST_FLAG_SPYING);
1196
1197         ast_channel_setoption(chan, AST_OPTION_TXGAIN, &zero_volume, sizeof(zero_volume), 0);
1198
1199         return res;
1200 }
1201
1202 static int chanspy_exec(struct ast_channel *chan, const char *data)
1203 {
1204         char *myenforced = NULL;
1205         char *mygroup = NULL;
1206         char *recbase = NULL;
1207         int fd = 0;
1208         struct ast_flags flags;
1209         struct spy_dtmf_options user_options = {
1210                 .cycle = '*',
1211                 .volume = '#',
1212                 .exit = '\0',
1213         };
1214         RAII_VAR(struct ast_format *, oldwf, NULL, ao2_cleanup);
1215         int volfactor = 0;
1216         int res;
1217         char *mailbox = NULL;
1218         char *name_context = NULL;
1219         AST_DECLARE_APP_ARGS(args,
1220                 AST_APP_ARG(spec);
1221                 AST_APP_ARG(options);
1222         );
1223         char *opts[OPT_ARG_ARRAY_SIZE];
1224         char *parse = ast_strdupa(data);
1225
1226         AST_STANDARD_APP_ARGS(args, parse);
1227
1228         if (args.spec && !strcmp(args.spec, "all"))
1229                 args.spec = NULL;
1230
1231         if (args.options) {
1232                 char tmp;
1233                 ast_app_parse_options(spy_opts, &flags, opts, args.options);
1234                 if (ast_test_flag(&flags, OPTION_GROUP))
1235                         mygroup = opts[OPT_ARG_GROUP];
1236
1237                 if (ast_test_flag(&flags, OPTION_RECORD) &&
1238                         !(recbase = opts[OPT_ARG_RECORD]))
1239                         recbase = "chanspy";
1240
1241                 if (ast_test_flag(&flags, OPTION_DTMF_EXIT) && opts[OPT_ARG_EXIT]) {
1242                         tmp = opts[OPT_ARG_EXIT][0];
1243                         if (strchr("0123456789*#", tmp) && tmp != '\0') {
1244                                 user_options.exit = tmp;
1245                         } else {
1246                                 ast_log(LOG_NOTICE, "Argument for option 'x' must be a valid DTMF digit.\n");
1247                         }
1248                 }
1249
1250                 if (ast_test_flag(&flags, OPTION_DTMF_CYCLE) && opts[OPT_ARG_CYCLE]) {
1251                         tmp = opts[OPT_ARG_CYCLE][0];
1252                         if (strchr("0123456789*#", tmp) && tmp != '\0') {
1253                                 user_options.cycle = tmp;
1254                         } else {
1255                                 ast_log(LOG_NOTICE, "Argument for option 'c' must be a valid DTMF digit.\n");
1256                         }
1257                 }
1258
1259                 if (ast_test_flag(&flags, OPTION_VOLUME) && opts[OPT_ARG_VOLUME]) {
1260                         int vol;
1261
1262                         if ((sscanf(opts[OPT_ARG_VOLUME], "%30d", &vol) != 1) || (vol > 4) || (vol < -4))
1263                                 ast_log(LOG_NOTICE, "Volume factor must be a number between -4 and 4\n");
1264                         else
1265                                 volfactor = vol;
1266                 }
1267
1268                 if (ast_test_flag(&flags, OPTION_PRIVATE))
1269                         ast_set_flag(&flags, OPTION_WHISPER);
1270
1271                 if (ast_test_flag(&flags, OPTION_ENFORCED))
1272                         myenforced = opts[OPT_ARG_ENFORCED];
1273
1274                 if (ast_test_flag(&flags, OPTION_NAME)) {
1275                         if (!ast_strlen_zero(opts[OPT_ARG_NAME])) {
1276                                 char *delimiter;
1277                                 if ((delimiter = strchr(opts[OPT_ARG_NAME], '@'))) {
1278                                         mailbox = opts[OPT_ARG_NAME];
1279                                         *delimiter++ = '\0';
1280                                         name_context = delimiter;
1281                                 } else {
1282                                         mailbox = opts[OPT_ARG_NAME];
1283                                 }
1284                         }
1285                 }
1286         } else {
1287                 ast_clear_flag(&flags, AST_FLAGS_ALL);
1288         }
1289
1290         oldwf = ao2_bump(ast_channel_writeformat(chan));
1291         if (ast_set_write_format(chan, ast_format_slin) < 0) {
1292                 ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
1293                 return -1;
1294         }
1295
1296         if (recbase) {
1297                 char filename[PATH_MAX];
1298
1299                 snprintf(filename, sizeof(filename), "%s/%s.%d.raw", ast_config_AST_MONITOR_DIR, recbase, (int) time(NULL));
1300                 if ((fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, AST_FILE_MODE)) <= 0) {
1301                         ast_log(LOG_WARNING, "Cannot open '%s' for recording\n", filename);
1302                         fd = 0;
1303                 }
1304         }
1305
1306         res = common_exec(chan, &flags, volfactor, fd, &user_options, mygroup, myenforced, args.spec, NULL, NULL, mailbox, name_context);
1307
1308         if (fd)
1309                 close(fd);
1310
1311         if (oldwf && ast_set_write_format(chan, oldwf) < 0)
1312                 ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
1313
1314         if (ast_test_flag(&flags, OPTION_EXITONHANGUP)) {
1315                 ast_verb(3, "Stopped spying due to the spied-on channel hanging up.\n");
1316         }
1317
1318         return res;
1319 }
1320
1321 static int extenspy_exec(struct ast_channel *chan, const char *data)
1322 {
1323         char *ptr, *exten = NULL;
1324         char *mygroup = NULL;
1325         char *recbase = NULL;
1326         int fd = 0;
1327         struct ast_flags flags;
1328         struct spy_dtmf_options user_options = {
1329                 .cycle = '*',
1330                 .volume = '#',
1331                 .exit = '\0',
1332         };
1333         RAII_VAR(struct ast_format *, oldwf, NULL, ao2_cleanup);
1334         int volfactor = 0;
1335         int res;
1336         char *mailbox = NULL;
1337         char *name_context = NULL;
1338         AST_DECLARE_APP_ARGS(args,
1339                 AST_APP_ARG(context);
1340                 AST_APP_ARG(options);
1341         );
1342         char *parse = ast_strdupa(data);
1343
1344         AST_STANDARD_APP_ARGS(args, parse);
1345
1346         if (!ast_strlen_zero(args.context) && (ptr = strchr(args.context, '@'))) {
1347                 exten = args.context;
1348                 *ptr++ = '\0';
1349                 args.context = ptr;
1350         }
1351         if (ast_strlen_zero(args.context))
1352                 args.context = ast_strdupa(ast_channel_context(chan));
1353
1354         if (args.options) {
1355                 char *opts[OPT_ARG_ARRAY_SIZE];
1356                 char tmp;
1357
1358                 ast_app_parse_options(spy_opts, &flags, opts, args.options);
1359                 if (ast_test_flag(&flags, OPTION_GROUP))
1360                         mygroup = opts[OPT_ARG_GROUP];
1361
1362                 if (ast_test_flag(&flags, OPTION_RECORD) &&
1363                         !(recbase = opts[OPT_ARG_RECORD]))
1364                         recbase = "chanspy";
1365
1366                 if (ast_test_flag(&flags, OPTION_DTMF_EXIT) && opts[OPT_ARG_EXIT]) {
1367                         tmp = opts[OPT_ARG_EXIT][0];
1368                         if (strchr("0123456789*#", tmp) && tmp != '\0') {
1369                                 user_options.exit = tmp;
1370                         } else {
1371                                 ast_log(LOG_NOTICE, "Argument for option 'x' must be a valid DTMF digit.\n");
1372                         }
1373                 }
1374
1375                 if (ast_test_flag(&flags, OPTION_DTMF_CYCLE) && opts[OPT_ARG_CYCLE]) {
1376                         tmp = opts[OPT_ARG_CYCLE][0];
1377                         if (strchr("0123456789*#", tmp) && tmp != '\0') {
1378                                 user_options.cycle = tmp;
1379                         } else {
1380                                 ast_log(LOG_NOTICE, "Argument for option 'c' must be a valid DTMF digit.\n");
1381                         }
1382                 }
1383
1384                 if (ast_test_flag(&flags, OPTION_VOLUME) && opts[OPT_ARG_VOLUME]) {
1385                         int vol;
1386
1387                         if ((sscanf(opts[OPT_ARG_VOLUME], "%30d", &vol) != 1) || (vol > 4) || (vol < -4))
1388                                 ast_log(LOG_NOTICE, "Volume factor must be a number between -4 and 4\n");
1389                         else
1390                                 volfactor = vol;
1391                 }
1392
1393                 if (ast_test_flag(&flags, OPTION_PRIVATE))
1394                         ast_set_flag(&flags, OPTION_WHISPER);
1395
1396                 if (ast_test_flag(&flags, OPTION_NAME)) {
1397                         if (!ast_strlen_zero(opts[OPT_ARG_NAME])) {
1398                                 char *delimiter;
1399                                 if ((delimiter = strchr(opts[OPT_ARG_NAME], '@'))) {
1400                                         mailbox = opts[OPT_ARG_NAME];
1401                                         *delimiter++ = '\0';
1402                                         name_context = delimiter;
1403                                 } else {
1404                                         mailbox = opts[OPT_ARG_NAME];
1405                                 }
1406                         }
1407                 }
1408
1409         } else {
1410                 /* Coverity - This uninit_use should be ignored since this macro initializes the flags */
1411                 ast_clear_flag(&flags, AST_FLAGS_ALL);
1412         }
1413
1414         oldwf = ao2_bump(ast_channel_writeformat(chan));
1415         if (ast_set_write_format(chan, ast_format_slin) < 0) {
1416                 ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
1417                 return -1;
1418         }
1419
1420         if (recbase) {
1421                 char filename[PATH_MAX];
1422
1423                 snprintf(filename, sizeof(filename), "%s/%s.%d.raw", ast_config_AST_MONITOR_DIR, recbase, (int) time(NULL));
1424                 if ((fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, AST_FILE_MODE)) <= 0) {
1425                         ast_log(LOG_WARNING, "Cannot open '%s' for recording\n", filename);
1426                         fd = 0;
1427                 }
1428         }
1429
1430
1431         res = common_exec(chan, &flags, volfactor, fd, &user_options, mygroup, NULL, NULL, exten, args.context, mailbox, name_context);
1432
1433         if (fd)
1434                 close(fd);
1435
1436         if (oldwf && ast_set_write_format(chan, oldwf) < 0)
1437                 ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
1438
1439         return res;
1440 }
1441
1442 static int dahdiscan_exec(struct ast_channel *chan, const char *data)
1443 {
1444         const char *spec = "DAHDI";
1445         struct ast_flags flags = {0};
1446         struct spy_dtmf_options user_options = {
1447                 .cycle = '#',
1448                 .volume = '\0',
1449                 .exit = '*',
1450         };
1451         struct ast_format *oldwf;
1452         int res;
1453         char *mygroup = NULL;
1454
1455         /* Coverity - This uninit_use should be ignored since this macro initializes the flags */
1456         ast_clear_flag(&flags, AST_FLAGS_ALL);
1457
1458         if (!ast_strlen_zero(data)) {
1459                 mygroup = ast_strdupa(data);
1460         }
1461         ast_set_flag(&flags, OPTION_DTMF_EXIT);
1462         ast_set_flag(&flags, OPTION_DTMF_CYCLE);
1463         ast_set_flag(&flags, OPTION_DAHDI_SCAN);
1464
1465         oldwf = ao2_bump(ast_channel_writeformat(chan));
1466         if (ast_set_write_format(chan, ast_format_slin) < 0) {
1467                 ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
1468                 ao2_cleanup(oldwf);
1469                 return -1;
1470         }
1471
1472         res = common_exec(chan, &flags, 0, 0, &user_options, mygroup, NULL, spec, NULL, NULL, NULL, NULL);
1473
1474         if (oldwf && ast_set_write_format(chan, oldwf) < 0)
1475                 ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
1476         ao2_cleanup(oldwf);
1477
1478         return res;
1479 }
1480
1481 static int unload_module(void)
1482 {
1483         int res = 0;
1484
1485         res |= ast_unregister_application(app_chan);
1486         res |= ast_unregister_application(app_ext);
1487         res |= ast_unregister_application(app_dahdiscan);
1488
1489         return res;
1490 }
1491
1492 static int load_module(void)
1493 {
1494         int res = 0;
1495
1496         res |= ast_register_application_xml(app_chan, chanspy_exec);
1497         res |= ast_register_application_xml(app_ext, extenspy_exec);
1498         res |= ast_register_application_xml(app_dahdiscan, dahdiscan_exec);
1499
1500         return res;
1501 }
1502
1503 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "Listen to the audio of an active channel");