Filter channels used as internal mechanisms
[asterisk/asterisk.git] / main / manager_channels.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2013, Digium, Inc.
5  *
6  * David M. Lee, II <dlee@digium.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18
19 /*! \file
20  *
21  * \brief The Asterisk Management Interface - AMI (channel event handling)
22  *
23  * \author David M. Lee, II <dlee@digium.com>
24  *
25  * AMI generated many per-channel and global-channel events by converting Stasis
26  * messages to AMI events. It makes sense to simply put them into a single file.
27  */
28
29 #include "asterisk.h"
30
31 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
32
33 #include "asterisk/callerid.h"
34 #include "asterisk/channel.h"
35 #include "asterisk/manager.h"
36 #include "asterisk/stasis_message_router.h"
37 #include "asterisk/pbx.h"
38 #include "asterisk/stasis_channels.h"
39
40 /*** DOCUMENTATION
41         <managerEvent language="en_US" name="Newchannel">
42                 <managerEventInstance class="EVENT_FLAG_CALL">
43                         <synopsis>Raised when a new channel is created.</synopsis>
44                         <syntax>
45                                 <parameter name="Channel">
46                                         <para>Name of the channel</para>
47                                 </parameter>
48                                 <parameter name="ChannelState">
49                                         <para>A numeric code for the channel's current state, related to ChannelStateDesc</para>
50                                 </parameter>
51                                 <parameter name="ChannelStateDesc">
52                                         <para>Name for the channel's current state</para>
53                                         <enumlist>
54                                                 <enum name="Down"/>
55                                                 <enum name="Rsrvd"/>
56                                                 <enum name="OffHook"/>
57                                                 <enum name="Dialing"/>
58                                                 <enum name="Ring"/>
59                                                 <enum name="Ringing"/>
60                                                 <enum name="Up"/>
61                                                 <enum name="Busy"/>
62                                                 <enum name="Dialing Offhook"/>
63                                                 <enum name="Pre-ring"/>
64                                                 <enum name="Unknown"/>
65                                         </enumlist>
66                                 </parameter>
67                                 <parameter name="CallerIDNum">
68                                 </parameter>
69                                 <parameter name="CallerIDName">
70                                 </parameter>
71                                 <parameter name="ConnectedLineNum">
72                                 </parameter>
73                                 <parameter name="ConnectedLineName">
74                                 </parameter>
75                                 <parameter name="AccountCode">
76                                 </parameter>
77                                 <parameter name="Context">
78                                 </parameter>
79                                 <parameter name="Exten">
80                                 </parameter>
81                                 <parameter name="Priority">
82                                 </parameter>
83                                 <parameter name="Uniqueid">
84                                         <para>Unique identifier for the channel</para>
85                                 </parameter>
86                         </syntax>
87                 </managerEventInstance>
88         </managerEvent>
89         <managerEvent language="en_US" name="Newstate">
90                 <managerEventInstance class="EVENT_FLAG_CALL">
91                         <synopsis>Raised when a channel's state changes.</synopsis>
92                         <syntax>
93                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='Newchannel']/managerEventInstance/syntax/parameter)" />
94                         </syntax>
95                 </managerEventInstance>
96         </managerEvent>
97         <managerEvent language="en_US" name="Hangup">
98                 <managerEventInstance class="EVENT_FLAG_CALL">
99                         <synopsis>Raised when a channel is hung up.</synopsis>
100                         <syntax>
101                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='Newchannel']/managerEventInstance/syntax/parameter)" />
102                                 <parameter name="Cause">
103                                         <para>A numeric cause code for why the channel was hung up.</para>
104                                 </parameter>
105                                 <parameter name="Cause-txt">
106                                         <para>A description of why the channel was hung up.</para>
107                                 </parameter>
108                         </syntax>
109                 </managerEventInstance>
110         </managerEvent>
111         <managerEvent language="en_US" name="HangupRequest">
112                 <managerEventInstance class="EVENT_FLAG_CALL">
113                         <synopsis>Raised when a hangup is requested.</synopsis>
114                         <syntax>
115                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='Newchannel']/managerEventInstance/syntax/parameter)" />
116                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='Hangup']/managerEventInstance/syntax/parameter[@name='Cause'])" />
117                         </syntax>
118                 </managerEventInstance>
119         </managerEvent>
120         <managerEvent language="en_US" name="SoftHangupRequest">
121                 <managerEventInstance class="EVENT_FLAG_CALL">
122                         <synopsis>Raised when a soft hangup is requested with a specific cause code.</synopsis>
123                         <syntax>
124                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='Newchannel']/managerEventInstance/syntax/parameter)" />
125                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='Hangup']/managerEventInstance/syntax/parameter[@name='Cause'])" />
126                         </syntax>
127                 </managerEventInstance>
128         </managerEvent>
129         <managerEvent language="en_US" name="NewExten">
130                 <managerEventInstance class="EVENT_FLAG_DIALPLAN">
131                         <synopsis>Raised when a channel enters a new context, extension, priority.</synopsis>
132                         <syntax>
133                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='Newchannel']/managerEventInstance/syntax/parameter)" />
134                                 <parameter name="Extension">
135                                         <para>Deprecated in 12, but kept for
136                                         backward compatability. Please use
137                                         'Exten' instead.</para>
138                                 </parameter>
139                                 <parameter name="Application">
140                                         <para>The application about to be executed.</para>
141                                 </parameter>
142                                 <parameter name="AppData">
143                                         <para>The data to be passed to the application.</para>
144                                 </parameter>
145                         </syntax>
146                 </managerEventInstance>
147         </managerEvent>
148         <managerEvent language="en_US" name="NewCallerid">
149                 <managerEventInstance class="EVENT_FLAG_CALL">
150                         <synopsis>Raised when a channel receives new Caller ID information.</synopsis>
151                         <syntax>
152                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='Newchannel']/managerEventInstance/syntax/parameter)" />
153                                 <parameter name="CID-CallingPres">
154                                         <para>A description of the Caller ID presentation.</para>
155                                 </parameter>
156                         </syntax>
157                 </managerEventInstance>
158         </managerEvent>
159         <managerEvent language="en_US" name="NewAccountCode">
160                 <managerEventInstance class="EVENT_FLAG_CALL">
161                         <synopsis>Raised when a Channel's AccountCode is changed.</synopsis>
162                         <syntax>
163                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='Newchannel']/managerEventInstance/syntax/parameter)" />
164                                 <parameter name="OldAccountCode">
165                                         <para>The channel's previous account code</para>
166                                 </parameter>
167                         </syntax>
168                 </managerEventInstance>
169         </managerEvent>
170         <managerEvent language="en_US" name="DialBegin">
171                 <managerEventInstance class="EVENT_FLAG_CALL">
172                         <synopsis>Raised when a dial action has started.</synopsis>
173                         <syntax>
174                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='Newchannel']/managerEventInstance/syntax/parameter)" />
175                                 <parameter name="DestChannel">
176                                 </parameter>
177                                 <parameter name="DestChannelState">
178                                         <para>A numeric code for the channel's current state, related to DestChannelStateDesc</para>
179                                 </parameter>
180                                 <parameter name="DestChannelStateDesc">
181                                         <enumlist>
182                                                 <enum name="Down"/>
183                                                 <enum name="Rsrvd"/>
184                                                 <enum name="OffHook"/>
185                                                 <enum name="Dialing"/>
186                                                 <enum name="Ring"/>
187                                                 <enum name="Ringing"/>
188                                                 <enum name="Up"/>
189                                                 <enum name="Busy"/>
190                                                 <enum name="Dialing Offhook"/>
191                                                 <enum name="Pre-ring"/>
192                                                 <enum name="Unknown"/>
193                                         </enumlist>
194                                 </parameter>
195                                 <parameter name="DestCallerIDNum">
196                                 </parameter>
197                                 <parameter name="DestCallerIDName">
198                                 </parameter>
199                                 <parameter name="DestConnectedLineNum">
200                                 </parameter>
201                                 <parameter name="DestConnectedLineName">
202                                 </parameter>
203                                 <parameter name="DestAccountCode">
204                                 </parameter>
205                                 <parameter name="DestContext">
206                                 </parameter>
207                                 <parameter name="DestExten">
208                                 </parameter>
209                                 <parameter name="DestPriority">
210                                 </parameter>
211                                 <parameter name="DestUniqueid">
212                                 </parameter>
213                                 <parameter name="DialString">
214                                         <para>The non-technology specific device being dialed.</para>
215                                 </parameter>
216                         </syntax>
217                         <see-also>
218                                 <ref type="application">Dial</ref>
219                         </see-also>
220                 </managerEventInstance>
221         </managerEvent>
222         <managerEvent language="en_US" name="DialEnd">
223                 <managerEventInstance class="EVENT_FLAG_CALL">
224                         <synopsis>Raised when a dial action has completed.</synopsis>
225                         <syntax>
226                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='Newchannel']/managerEventInstance/syntax/parameter)" />
227                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='DialBegin']/managerEventInstance/syntax/parameter[contains(@name, 'Dest')])" />
228                                 <parameter name="DialStatus">
229                                         <para>The result of the dial operation.</para>
230                                         <enumlist>
231                                                 <enum name="ANSWER" />
232                                                 <enum name="BUSY" />
233                                                 <enum name="CANCEL" />
234                                                 <enum name="CHANUNAVAIL" />
235                                                 <enum name="CONGESTION" />
236                                                 <enum name="NOANSWER" />
237                                         </enumlist>
238                                 </parameter>
239                         </syntax>
240                         <see-also>
241                                 <ref type="application">Dial</ref>
242                         </see-also>
243                 </managerEventInstance>
244         </managerEvent>
245         <managerEvent language="en_US" name="Hold">
246                 <managerEventInstance class="EVENT_FLAG_CALL">
247                         <synopsis>Raised when a channel goes on hold.</synopsis>
248                         <syntax>
249                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='Newchannel']/managerEventInstance/syntax/parameter)" />
250                                 <parameter name="MusicClass">
251                                         <para>The suggested MusicClass, if provided.</para>
252                                 </parameter>
253                         </syntax>
254                 </managerEventInstance>
255         </managerEvent>
256         <managerEvent language="en_US" name="Unhold">
257                 <managerEventInstance class="EVENT_FLAG_CALL">
258                         <synopsis>Raised when a channel goes off hold.</synopsis>
259                         <syntax>
260                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='Newchannel']/managerEventInstance/syntax/parameter)" />
261                         </syntax>
262                 </managerEventInstance>
263         </managerEvent>
264         <managerEvent language="en_US" name="ChanSpyStart">
265                 <managerEventInstance class="EVENT_FLAG_CALL">
266                         <synopsis>Raised when one channel begins spying on another channel.</synopsis>
267                         <syntax>
268                                 <parameter name="SpyerChannel">
269                                         <para>The channel performing the spying.</para>
270                                 </parameter>
271                                 <parameter name="SpyerChannelState">
272                                         <para>A numeric code for the channel's current state, related to SpyerChannelStateDesc</para>
273                                 </parameter>
274                                 <parameter name="SpyerChannelStateDesc">
275                                         <enumlist>
276                                                 <enum name="Down"/>
277                                                 <enum name="Rsrvd"/>
278                                                 <enum name="OffHook"/>
279                                                 <enum name="Dialing"/>
280                                                 <enum name="Ring"/>
281                                                 <enum name="Ringing"/>
282                                                 <enum name="Up"/>
283                                                 <enum name="Busy"/>
284                                                 <enum name="Dialing Offhook"/>
285                                                 <enum name="Pre-ring"/>
286                                                 <enum name="Unknown"/>
287                                         </enumlist>
288                                 </parameter>
289                                 <parameter name="SpyerCallerIDNum">
290                                 </parameter>
291                                 <parameter name="SpyerCallerIDName">
292                                 </parameter>
293                                 <parameter name="SpyerConnectedLineNum">
294                                 </parameter>
295                                 <parameter name="SpyerConnectedLineName">
296                                 </parameter>
297                                 <parameter name="SpyerAccountCode">
298                                 </parameter>
299                                 <parameter name="SpyerContext">
300                                 </parameter>
301                                 <parameter name="SpyerExten">
302                                 </parameter>
303                                 <parameter name="SpyerPriority">
304                                 </parameter>
305                                 <parameter name="SpyerUniqueid">
306                                 </parameter>
307                                 <parameter name="SpyeeChannel">
308                                         <para>The channel being spied upon.</para>
309                                 </parameter>
310                                 <parameter name="SpyeeChannelState">
311                                         <para>A numeric code for the channel's current state, related to SpyeeChannelStateDesc</para>
312                                 </parameter>
313                                 <parameter name="SpyeeChannelStateDesc">
314                                         <enumlist>
315                                                 <enum name="Down"/>
316                                                 <enum name="Rsrvd"/>
317                                                 <enum name="OffHook"/>
318                                                 <enum name="Dialing"/>
319                                                 <enum name="Ring"/>
320                                                 <enum name="Ringing"/>
321                                                 <enum name="Up"/>
322                                                 <enum name="Busy"/>
323                                                 <enum name="Dialing Offhook"/>
324                                                 <enum name="Pre-ring"/>
325                                                 <enum name="Unknown"/>
326                                         </enumlist>
327                                 </parameter>
328                                 <parameter name="SpyeeCallerIDNum">
329                                 </parameter>
330                                 <parameter name="SpyeeCallerIDName">
331                                 </parameter>
332                                 <parameter name="SpyeeConnectedLineNum">
333                                 </parameter>
334                                 <parameter name="SpyeeConnectedLineName">
335                                 </parameter>
336                                 <parameter name="SpyeeAccountCode">
337                                 </parameter>
338                                 <parameter name="SpyeeContext">
339                                 </parameter>
340                                 <parameter name="SpyeeExten">
341                                 </parameter>
342                                 <parameter name="SpyeePriority">
343                                 </parameter>
344                                 <parameter name="SpyeeUniqueid">
345                                 </parameter>
346                         </syntax>
347                         <see-also>
348                                 <ref type="application">ChanSpyStop</ref>
349                         </see-also>
350                 </managerEventInstance>
351         </managerEvent>
352         <managerEvent language="en_US" name="ChanSpyStop">
353                 <managerEventInstance class="EVENT_FLAG_CALL">
354                         <synopsis>Raised when a channel has stopped spying.</synopsis>
355                         <syntax>
356                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='ChanSpyStart']/managerEventInstance/syntax/parameter[contains(@name, 'Spyer')])" />
357                         </syntax>
358                         <see-also>
359                                 <ref type="application">ChanSpyStart</ref>
360                         </see-also>
361                 </managerEventInstance>
362         </managerEvent>
363         <managerEvent language="en_US" name="HangupHandlerRun">
364                 <managerEventInstance class="EVENT_FLAG_DIALPLAN">
365                         <synopsis>Raised when a hangup handler is about to be called.</synopsis>
366                         <syntax>
367                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='Newchannel']/managerEventInstance/syntax/parameter)" />
368                                 <parameter name="Handler">
369                                         <para>Hangup handler parameter string passed to the Gosub application.</para>
370                                 </parameter>
371                         </syntax>
372                 </managerEventInstance>
373         </managerEvent>
374         <managerEvent language="en_US" name="HangupHandlerPop">
375                 <managerEventInstance class="EVENT_FLAG_DIALPLAN">
376                         <synopsis>
377                                 Raised when a hangup handler is removed from the handler stack
378                                 by the CHANNEL() function.
379                         </synopsis>
380                         <syntax>
381                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='HangupHandlerRun']/managerEventInstance/syntax/parameter)" />
382                         </syntax>
383                         <see-also>
384                                 <ref type="managerEvent">HangupHandlerPush</ref>
385                                 <ref type="function">CHANNEL</ref>
386                         </see-also>
387                 </managerEventInstance>
388         </managerEvent>
389         <managerEvent language="en_US" name="HangupHandlerPush">
390                 <managerEventInstance class="EVENT_FLAG_DIALPLAN">
391                         <synopsis>
392                                 Raised when a hangup handler is added to the handler stack by
393                                 the CHANNEL() function.
394                         </synopsis>
395                         <syntax>
396                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='HangupHandlerRun']/managerEventInstance/syntax/parameter)" />
397                         </syntax>
398                         <see-also>
399                                 <ref type="managerEvent">HangupHandlerPop</ref>
400                                 <ref type="function">CHANNEL</ref>
401                         </see-also>
402                 </managerEventInstance>
403         </managerEvent>
404         <managerEvent language="en_US" name="FAXStatus">
405                 <managerEventInstance class="EVENT_FLAG_CALL">
406                         <synopsis>
407                                 Raised periodically during a fax transmission.
408                         </synopsis>
409                         <syntax>
410                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='Newchannel']/managerEventInstance/syntax/parameter)" />
411                                 <parameter name="Operation">
412                                         <enumlist>
413                                                 <enum name="gateway"/>
414                                                 <enum name="receive"/>
415                                                 <enum name="send"/>
416                                         </enumlist>
417                                 </parameter>
418                                 <parameter name="Status">
419                                         <para>A text message describing the current status of the fax</para>
420                                 </parameter>
421                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='ReceiveFAX']/managerEventInstance/syntax/parameter[@name='LocalStationID'])" />
422                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='ReceiveFAX']/managerEventInstance/syntax/parameter[@name='FileName'])" />
423                         </syntax>
424                 </managerEventInstance>
425         </managerEvent>
426         <managerEvent language="en_US" name="ReceiveFAX">
427                 <managerEventInstance class="EVENT_FLAG_CALL">
428                         <synopsis>
429                                 Raised when a receive fax operation has completed.
430                         </synopsis>
431                         <syntax>
432                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='Newchannel']/managerEventInstance/syntax/parameter)" />
433                                 <parameter name="LocalStationID">
434                                         <para>The value of the <variable>LOCALSTATIONID</variable> channel variable</para>
435                                 </parameter>
436                                 <parameter name="RemoteStationID">
437                                         <para>The value of the <variable>REMOTESTATIONID</variable> channel variable</para>
438                                 </parameter>
439                                 <parameter name="PagesTransferred">
440                                         <para>The number of pages that have been transferred</para>
441                                 </parameter>
442                                 <parameter name="Resolution">
443                                         <para>The negotiated resolution</para>
444                                 </parameter>
445                                 <parameter name="TransferRate">
446                                         <para>The negotiated transfer rate</para>
447                                 </parameter>
448                                 <parameter name="FileName" multiple="yes">
449                                         <para>The files being affected by the fax operation</para>
450                                 </parameter>
451                         </syntax>
452                 </managerEventInstance>
453         </managerEvent>
454         <managerEvent language="en_US" name="SendFAX">
455                 <managerEventInstance class="EVENT_FLAG_CALL">
456                         <synopsis>
457                                 Raised when a send fax operation has completed.
458                         </synopsis>
459                         <syntax>
460                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='Newchannel']/managerEventInstance/syntax/parameter)" />
461                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='ReceiveFAX']/managerEventInstance/syntax/parameter)" />
462                         </syntax>
463                 </managerEventInstance>
464         </managerEvent>
465         <managerEvent language="en_US" name="MusicOnHoldStart">
466                 <managerEventInstance class="EVENT_FLAG_CALL">
467                         <synopsis>Raised when music on hold has started on a channel.</synopsis>
468                         <syntax>
469                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='Newchannel']/managerEventInstance/syntax/parameter)" />
470                                 <parameter name="Class">
471                                         <para>The class of music being played on the channel</para>
472                                 </parameter>
473                         </syntax>
474                         <see-also>
475                                 <ref type="managerEvent">MusicOnHoldStop</ref>
476                                 <ref type="application">MusicOnHold</ref>
477                         </see-also>
478                 </managerEventInstance>
479         </managerEvent>
480         <managerEvent language="en_US" name="MusicOnHoldStop">
481                 <managerEventInstance class="EVENT_FLAG_CALL">
482                         <synopsis>Raised when music on hold has stopped on a channel.</synopsis>
483                         <syntax>
484                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='Newchannel']/managerEventInstance/syntax/parameter)" />
485                         </syntax>
486                         <see-also>
487                                 <ref type="managerEvent">MusicOnHoldStart</ref>
488                                 <ref type="application">StopMusicOnHold</ref>
489                         </see-also>
490                 </managerEventInstance>
491         </managerEvent>
492         <managerEvent language="en_US" name="MonitorStart">
493                 <managerEventInstance class="EVENT_FLAG_CALL">
494                         <synopsis>Raised when monitoring has started on a channel.</synopsis>
495                         <syntax>
496                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='Newchannel']/managerEventInstance/syntax/parameter)" />
497                         </syntax>
498                         <see-also>
499                                 <ref type="managerEvent">MonitorStop</ref>
500                                 <ref type="application">Monitor</ref>
501                                 <ref type="manager">Monitor</ref>
502                         </see-also>
503                 </managerEventInstance>
504         </managerEvent>
505         <managerEvent language="en_US" name="MonitorStop">
506                 <managerEventInstance class="EVENT_FLAG_CALL">
507                 <synopsis>Raised when monitoring has stopped on a channel.</synopsis>
508                 <syntax>
509                         <xi:include xpointer="xpointer(/docs/managerEvent[@name='Newchannel']/managerEventInstance/syntax/parameter)" />
510                 </syntax>
511                 <see-also>
512                         <ref type="managerEvent">MonitorStart</ref>
513                         <ref type="application">StopMonitor</ref>
514                         <ref type="manager">StopMonitor</ref>
515                 </see-also>
516                 </managerEventInstance>
517         </managerEvent>
518 ***/
519
520 /*! \brief The \ref stasis subscription returned by the forwarding of the channel topic
521  * to the manager topic
522  */
523 static struct stasis_subscription *topic_forwarder;
524
525 struct ast_str *ast_manager_build_channel_state_string_prefix(
526                 const struct ast_channel_snapshot *snapshot,
527                 const char *prefix)
528 {
529         struct ast_str *out = ast_str_create(1024);
530         int res = 0;
531
532         if (!out) {
533                 return NULL;
534         }
535
536         if (snapshot->tech_properties & (AST_CHAN_TP_ANNOUNCER | AST_CHAN_TP_RECORDER)) {
537                 ast_free(out);
538                 return NULL;
539         }
540
541         res = ast_str_set(&out, 0,
542                 "%sChannel: %s\r\n"
543                 "%sChannelState: %d\r\n"
544                 "%sChannelStateDesc: %s\r\n"
545                 "%sCallerIDNum: %s\r\n"
546                 "%sCallerIDName: %s\r\n"
547                 "%sConnectedLineNum: %s\r\n"
548                 "%sConnectedLineName: %s\r\n"
549                 "%sAccountCode: %s\r\n"
550                 "%sContext: %s\r\n"
551                 "%sExten: %s\r\n"
552                 "%sPriority: %d\r\n"
553                 "%sUniqueid: %s\r\n",
554                 prefix, snapshot->name,
555                 prefix, snapshot->state,
556                 prefix, ast_state2str(snapshot->state),
557                 prefix, S_OR(snapshot->caller_number, "<unknown>"),
558                 prefix, S_OR(snapshot->caller_name, "<unknown>"),
559                 prefix, S_OR(snapshot->connected_number, "<unknown>"),
560                 prefix, S_OR(snapshot->connected_name, "<unknown>"),
561                 prefix, snapshot->accountcode,
562                 prefix, snapshot->context,
563                 prefix, snapshot->exten,
564                 prefix, snapshot->priority,
565                 prefix, snapshot->uniqueid);
566
567         if (!res) {
568                 ast_free(out);
569                 return NULL;
570         }
571
572         if (snapshot->manager_vars) {
573                 struct ast_var_t *var;
574                 AST_LIST_TRAVERSE(snapshot->manager_vars, var, entries) {
575                         ast_str_append(&out, 0, "%sChanVariable: %s=%s\r\n",
576                                        prefix,
577                                        var->name, var->value);
578                 }
579         }
580
581         return out;
582 }
583
584 struct ast_str *ast_manager_build_channel_state_string(
585                 const struct ast_channel_snapshot *snapshot)
586 {
587         return ast_manager_build_channel_state_string_prefix(snapshot, "");
588 }
589
590 /*! \brief Typedef for callbacks that get called on channel snapshot updates */
591 typedef struct ast_manager_event_blob *(*channel_snapshot_monitor)(
592         struct ast_channel_snapshot *old_snapshot,
593         struct ast_channel_snapshot *new_snapshot);
594
595 /*! \brief Handle channel state changes */
596 static struct ast_manager_event_blob *channel_state_change(
597         struct ast_channel_snapshot *old_snapshot,
598         struct ast_channel_snapshot *new_snapshot)
599 {
600         int is_hungup, was_hungup;
601
602         if (!new_snapshot) {
603                 /* Ignore cache clearing events; we'll see the hangup first */
604                 return NULL;
605         }
606
607         /* The Newchannel, Newstate and Hangup events are closely related, in
608          * in that they are mutually exclusive, basically different flavors
609          * of a new channel state event.
610          */
611
612         if (!old_snapshot) {
613                 return ast_manager_event_blob_create(
614                         EVENT_FLAG_CALL, "Newchannel", NO_EXTRA_FIELDS);
615         }
616
617         was_hungup = ast_test_flag(&old_snapshot->flags, AST_FLAG_DEAD) ? 1 : 0;
618         is_hungup = ast_test_flag(&new_snapshot->flags, AST_FLAG_DEAD) ? 1 : 0;
619
620         if (!was_hungup && is_hungup) {
621                 return ast_manager_event_blob_create(
622                         EVENT_FLAG_CALL, "Hangup",
623                         "Cause: %d\r\n"
624                         "Cause-txt: %s\r\n",
625                         new_snapshot->hangupcause,
626                         ast_cause2str(new_snapshot->hangupcause));
627         }
628
629         if (old_snapshot->state != new_snapshot->state) {
630                 return ast_manager_event_blob_create(
631                         EVENT_FLAG_CALL, "Newstate", NO_EXTRA_FIELDS);
632         }
633
634         /* No event */
635         return NULL;
636 }
637
638 static struct ast_manager_event_blob *channel_newexten(
639         struct ast_channel_snapshot *old_snapshot,
640         struct ast_channel_snapshot *new_snapshot)
641 {
642         /* No Newexten event on cache clear */
643         if (!new_snapshot) {
644                 return NULL;
645         }
646
647         /* Empty application is not valid for a Newexten event */
648         if (ast_strlen_zero(new_snapshot->appl)) {
649                 return NULL;
650         }
651
652         /* Ignore any updates if we're hungup */
653         if (ast_test_flag(&new_snapshot->flags, AST_FLAG_DEAD)) {
654                 return NULL;
655         }
656
657         if (old_snapshot && ast_channel_snapshot_cep_equal(old_snapshot, new_snapshot)
658                 && !strcmp(old_snapshot->appl, new_snapshot->appl)) {
659                 return NULL;
660         }
661
662         /* DEPRECATED: Extension field deprecated in 12; remove in 14 */
663         return ast_manager_event_blob_create(
664                 EVENT_FLAG_CALL, "Newexten",
665                 "Extension: %s\r\n"
666                 "Application: %s\r\n"
667                 "AppData: %s\r\n",
668                 new_snapshot->exten,
669                 new_snapshot->appl,
670                 new_snapshot->data);
671 }
672
673 static struct ast_manager_event_blob *channel_new_callerid(
674         struct ast_channel_snapshot *old_snapshot,
675         struct ast_channel_snapshot *new_snapshot)
676 {
677         /* No NewCallerid event on cache clear or first event */
678         if (!old_snapshot || !new_snapshot) {
679                 return NULL;
680         }
681
682         if (ast_channel_snapshot_caller_id_equal(old_snapshot, new_snapshot)) {
683                 return NULL;
684         }
685
686         return ast_manager_event_blob_create(
687                 EVENT_FLAG_CALL, "NewCallerid",
688                 "CID-CallingPres: %d (%s)\r\n",
689                 new_snapshot->caller_pres,
690                 ast_describe_caller_presentation(new_snapshot->caller_pres));
691 }
692
693 static struct ast_manager_event_blob *channel_new_accountcode(
694         struct ast_channel_snapshot *old_snapshot,
695         struct ast_channel_snapshot *new_snapshot)
696 {
697         if (!old_snapshot || !new_snapshot) {
698                 return NULL;
699         }
700
701         if (!strcmp(old_snapshot->accountcode, new_snapshot->accountcode)) {
702                 return NULL;
703         }
704
705         return ast_manager_event_blob_create(
706                 EVENT_FLAG_CALL, "NewAccountCode",
707                 "OldAccountCode: %s\r\n", old_snapshot->accountcode);
708 }
709
710 channel_snapshot_monitor channel_monitors[] = {
711         channel_state_change,
712         channel_newexten,
713         channel_new_callerid,
714         channel_new_accountcode
715 };
716
717 static void channel_snapshot_update(void *data, struct stasis_subscription *sub,
718                                     struct stasis_topic *topic,
719                                     struct stasis_message *message)
720 {
721         RAII_VAR(struct ast_str *, channel_event_string, NULL, ast_free);
722         struct stasis_cache_update *update;
723         struct ast_channel_snapshot *old_snapshot;
724         struct ast_channel_snapshot *new_snapshot;
725         size_t i;
726
727         update = stasis_message_data(message);
728
729         if (ast_channel_snapshot_type() != update->type) {
730                 return;
731         }
732
733         old_snapshot = stasis_message_data(update->old_snapshot);
734         new_snapshot = stasis_message_data(update->new_snapshot);
735
736         for (i = 0; i < ARRAY_LEN(channel_monitors); ++i) {
737                 RAII_VAR(struct ast_manager_event_blob *, ev, NULL, ao2_cleanup);
738                 ev = channel_monitors[i](old_snapshot, new_snapshot);
739
740                 if (!ev) {
741                         continue;
742                 }
743
744                 /* If we haven't already, build the channel event string */
745                 if (!channel_event_string) {
746                         channel_event_string =
747                                 ast_manager_build_channel_state_string(new_snapshot);
748                         if (!channel_event_string) {
749                                 return;
750                         }
751                 }
752
753                 manager_event(ev->event_flags, ev->manager_event, "%s%s",
754                         ast_str_buffer(channel_event_string),
755                         ev->extra_fields);
756         }
757 }
758
759 static int userevent_exclusion_cb(const char *key)
760 {
761         if (!strcmp("type", key)) {
762                 return 1;
763         }
764         if (!strcmp("eventname", key)) {
765                 return 1;
766         }
767         return 0;
768 }
769
770 static void channel_user_event_cb(void *data, struct stasis_subscription *sub,
771         struct stasis_topic *topic, struct stasis_message *message)
772 {
773         struct ast_channel_blob *obj = stasis_message_data(message);
774         RAII_VAR(struct ast_str *, channel_event_string, NULL, ast_free);
775         RAII_VAR(struct ast_str *, body, NULL, ast_free);
776         const char *eventname;
777
778         eventname = ast_json_string_get(ast_json_object_get(obj->blob, "eventname"));
779         body = ast_manager_str_from_json_object(obj->blob, userevent_exclusion_cb);
780         channel_event_string = ast_manager_build_channel_state_string(obj->snapshot);
781
782         if (!channel_event_string || !body) {
783                 return;
784         }
785
786         /*** DOCUMENTATION
787                 <managerEventInstance>
788                         <synopsis>A user defined event raised from the dialplan.</synopsis>
789                         <syntax>
790                                 <xi:include xpointer="xpointer(/docs/managerEvent[@name='Newchannel']/managerEventInstance/syntax/parameter)" />
791                                 <parameter name="UserEvent">
792                                         <para>The event name, as specified in the dialplan.</para>
793                                 </parameter>
794                         </syntax>
795                         <see-also>
796                                 <ref type="application">UserEvent</ref>
797                         </see-also>
798                 </managerEventInstance>
799         ***/
800         manager_event(EVENT_FLAG_USER, "UserEvent",
801                       "%s"
802                       "UserEvent: %s\r\n"
803                       "%s",
804                       ast_str_buffer(channel_event_string), eventname, ast_str_buffer(body));
805 }
806
807 static void publish_basic_channel_event(const char *event, int class, struct ast_channel_snapshot *snapshot)
808 {
809         RAII_VAR(struct ast_str *, channel_event_string, NULL, ast_free);
810
811         channel_event_string = ast_manager_build_channel_state_string(snapshot);
812         if (!channel_event_string) {
813                 return;
814         }
815
816         manager_event(class, event,
817                 "%s",
818                 ast_str_buffer(channel_event_string));
819 }
820
821 static void channel_hangup_request_cb(void *data,
822         struct stasis_subscription *sub, struct stasis_topic *topic,
823         struct stasis_message *message)
824 {
825         struct ast_channel_blob *obj = stasis_message_data(message);
826         RAII_VAR(struct ast_str *, extra, NULL, ast_free);
827         RAII_VAR(struct ast_str *, channel_event_string, NULL, ast_free);
828         struct ast_json *cause;
829         int is_soft;
830         char *manager_event = "HangupRequest";
831
832         extra = ast_str_create(20);
833         if (!extra) {
834                 return;
835         }
836
837         channel_event_string = ast_manager_build_channel_state_string(obj->snapshot);
838
839         if (!channel_event_string) {
840                 return;
841         }
842
843         cause = ast_json_object_get(obj->blob, "cause");
844         if (cause) {
845                 ast_str_append(&extra, 0,
846                                "Cause: %jd\r\n",
847                                ast_json_integer_get(cause));
848         }
849
850         is_soft = ast_json_is_true(ast_json_object_get(obj->blob, "soft"));
851         if (is_soft) {
852                 manager_event = "SoftHangupRequest";
853         }
854
855         manager_event(EVENT_FLAG_CALL, manager_event,
856                       "%s%s",
857                       ast_str_buffer(channel_event_string),
858                       ast_str_buffer(extra));
859 }
860
861 static void channel_chanspy_stop_cb(void *data, struct stasis_subscription *sub,
862                 struct stasis_topic *topic, struct stasis_message *message)
863 {
864         RAII_VAR(struct ast_str *, spyer_channel_string, NULL, ast_free);
865         struct ast_channel_snapshot *spyer;
866         struct ast_multi_channel_blob *payload = stasis_message_data(message);
867
868         spyer = ast_multi_channel_blob_get_channel(payload, "spyer_channel");
869         if (!spyer) {
870                 ast_log(AST_LOG_WARNING, "Received ChanSpy Start event with no spyer channel!\n");
871                 return;
872         }
873
874         spyer_channel_string = ast_manager_build_channel_state_string_prefix(spyer, "Spyer");
875         if (!spyer_channel_string) {
876                 return;
877         }
878
879         manager_event(EVENT_FLAG_CALL, "ChanSpyStop",
880                       "%s",
881                       ast_str_buffer(spyer_channel_string));
882 }
883
884 static void channel_chanspy_start_cb(void *data, struct stasis_subscription *sub,
885                 struct stasis_topic *topic, struct stasis_message *message)
886 {
887         RAII_VAR(struct ast_str *, spyer_channel_string, NULL, ast_free);
888         RAII_VAR(struct ast_str *, spyee_channel_string, NULL, ast_free);
889         struct ast_channel_snapshot *spyer;
890         struct ast_channel_snapshot *spyee;
891         struct ast_multi_channel_blob *payload = stasis_message_data(message);
892
893         spyer = ast_multi_channel_blob_get_channel(payload, "spyer_channel");
894         if (!spyer) {
895                 ast_log(AST_LOG_WARNING, "Received ChanSpy Start event with no spyer channel!\n");
896                 return;
897         }
898         spyee = ast_multi_channel_blob_get_channel(payload, "spyee_channel");
899         if (!spyee) {
900                 ast_log(AST_LOG_WARNING, "Received ChanSpy Start event with no spyee channel!\n");
901                 return;
902         }
903
904         spyer_channel_string = ast_manager_build_channel_state_string_prefix(spyer, "Spyer");
905         if (!spyer_channel_string) {
906                 return;
907         }
908         spyee_channel_string = ast_manager_build_channel_state_string_prefix(spyee, "Spyee");
909         if (!spyee_channel_string) {
910                 return;
911         }
912
913         manager_event(EVENT_FLAG_CALL, "ChanSpyStart",
914                       "%s%s",
915                       ast_str_buffer(spyer_channel_string),
916                       ast_str_buffer(spyee_channel_string));
917 }
918
919 static void channel_dtmf_begin_cb(void *data, struct stasis_subscription *sub,
920         struct stasis_topic *topic, struct stasis_message *message)
921 {
922         struct ast_channel_blob *obj = stasis_message_data(message);
923         RAII_VAR(struct ast_str *, channel_event_string, NULL, ast_free);
924         const char *digit =
925                 ast_json_string_get(ast_json_object_get(obj->blob, "digit"));
926         const char *direction =
927                 ast_json_string_get(ast_json_object_get(obj->blob, "direction"));
928
929         channel_event_string = ast_manager_build_channel_state_string(obj->snapshot);
930
931         if (!channel_event_string) {
932                 return;
933         }
934
935         /*** DOCUMENTATION
936                 <managerEventInstance>
937                         <synopsis>Raised when a DTMF digit has started on a channel.</synopsis>
938                                 <syntax>
939                                         <xi:include xpointer="xpointer(/docs/managerEvent[@name='Newchannel']/managerEventInstance/syntax/parameter)" />
940                                         <parameter name="Digit">
941                                                 <para>DTMF digit received or transmitted (0-9, A-E, # or *</para>
942                                         </parameter>
943                                         <parameter name="Direction">
944                                                 <enumlist>
945                                                         <enum name="Received"/>
946                                                         <enum name="Sent"/>
947                                                 </enumlist>
948                                         </parameter>
949                                 </syntax>
950                 </managerEventInstance>
951         ***/
952         manager_event(EVENT_FLAG_DTMF, "DTMFBegin",
953                 "%s"
954                 "Digit: %s\r\n"
955                 "Direction: %s\r\n",
956                 ast_str_buffer(channel_event_string),
957                 digit, direction);
958 }
959
960 static void channel_dtmf_end_cb(void *data, struct stasis_subscription *sub,
961         struct stasis_topic *topic, struct stasis_message *message)
962 {
963         struct ast_channel_blob *obj = stasis_message_data(message);
964         RAII_VAR(struct ast_str *, channel_event_string, NULL, ast_free);
965         const char *digit =
966                 ast_json_string_get(ast_json_object_get(obj->blob, "digit"));
967         const char *direction =
968                 ast_json_string_get(ast_json_object_get(obj->blob, "direction"));
969         long duration_ms =
970                 ast_json_integer_get(ast_json_object_get(obj->blob, "duration_ms"));
971
972         channel_event_string = ast_manager_build_channel_state_string(obj->snapshot);
973
974         if (!channel_event_string) {
975                 return;
976         }
977
978         /*** DOCUMENTATION
979                 <managerEventInstance>
980                         <synopsis>Raised when a DTMF digit has ended on a channel.</synopsis>
981                                 <syntax>
982                                         <xi:include xpointer="xpointer(/docs/managerEvent[@name='Newchannel']/managerEventInstance/syntax/parameter)" />
983                                         <parameter name="Digit">
984                                                 <para>DTMF digit received or transmitted (0-9, A-E, # or *</para>
985                                         </parameter>
986                                         <parameter name="DurationMs">
987                                                 <para>Duration (in milliseconds) DTMF was sent/received</para>
988                                         </parameter>
989                                         <parameter name="Direction">
990                                                 <enumlist>
991                                                         <enum name="Received"/>
992                                                         <enum name="Sent"/>
993                                                 </enumlist>
994                                         </parameter>
995                                 </syntax>
996                 </managerEventInstance>
997         ***/
998         manager_event(EVENT_FLAG_DTMF, "DTMFEnd",
999                 "%s"
1000                 "Digit: %s\r\n"
1001                 "DurationMs: %ld\r\n"
1002                 "Direction: %s\r\n",
1003                 ast_str_buffer(channel_event_string),
1004                 digit, duration_ms, direction);
1005 }
1006
1007 static void channel_hangup_handler_cb(void *data, struct stasis_subscription *sub,
1008                 struct stasis_topic *topic, struct stasis_message *message)
1009 {
1010         RAII_VAR(struct ast_str *, channel_event_string, NULL, ast_free);
1011         struct ast_channel_blob *payload = stasis_message_data(message);
1012         const char *action = ast_json_string_get(ast_json_object_get(payload->blob, "type"));
1013         const char *handler = ast_json_string_get(ast_json_object_get(payload->blob, "handler"));
1014         const char *event;
1015
1016         channel_event_string = ast_manager_build_channel_state_string(payload->snapshot);
1017
1018         if (!channel_event_string) {
1019                 return;
1020         }
1021
1022         if (!strcmp(action, "type")) {
1023                 event = "HangupHandlerRun";
1024         } else if (!strcmp(action, "type")) {
1025                 event = "HangupHandlerPop";
1026         } else if (!strcmp(action, "type")) {
1027                 event = "HangupHandlerPush";
1028         } else {
1029                 return;
1030         }
1031         manager_event(EVENT_FLAG_DIALPLAN, event,
1032                 "%s"
1033                 "Handler: %s\r\n",
1034                 ast_str_buffer(channel_event_string),
1035                 handler);
1036 }
1037
1038 static void channel_fax_cb(void *data, struct stasis_subscription *sub,
1039                 struct stasis_topic *topic, struct stasis_message *message)
1040 {
1041         RAII_VAR(struct ast_str *, channel_event_string, NULL, ast_free);
1042         RAII_VAR(struct ast_str *, event_buffer, ast_str_create(256), ast_free);
1043         struct ast_channel_blob *payload = stasis_message_data(message);
1044         const char *type = ast_json_string_get(ast_json_object_get(payload->blob, "type"));
1045         struct ast_json *operation = ast_json_object_get(payload->blob, "operation");
1046         struct ast_json *status = ast_json_object_get(payload->blob, "status");
1047         struct ast_json *local_station_id = ast_json_object_get(payload->blob, "local_station_id");
1048         struct ast_json *remote_station_id = ast_json_object_get(payload->blob, "remote_station_id");
1049         struct ast_json *fax_pages = ast_json_object_get(payload->blob, "fax_pages");
1050         struct ast_json *fax_resolution = ast_json_object_get(payload->blob, "fax_resolution");
1051         struct ast_json *fax_bitrate = ast_json_object_get(payload->blob, "fax_bitrate");
1052         struct ast_json *filenames = ast_json_object_get(payload->blob, "filenames");
1053         const char *event;
1054         size_t array_len;
1055         size_t i;
1056
1057         if (!event_buffer) {
1058                 return;
1059         }
1060
1061         channel_event_string = ast_manager_build_channel_state_string(payload->snapshot);
1062         if (!channel_event_string) {
1063                 return;
1064         }
1065
1066         if (!strcmp(type, "status")) {
1067                 event = "FAXStatus";
1068         } else if (!strcmp(type, "receive")) {
1069                 event = "ReceiveFAX";
1070         } else if (!strcmp(type, "send")) {
1071                 event = "SendFAX";
1072         } else {
1073                 return;
1074         }
1075
1076         if (operation) {
1077                 ast_str_append(&event_buffer, 0, "Operation: %s\r\n", ast_json_string_get(operation));
1078         }
1079         if (status) {
1080                 ast_str_append(&event_buffer, 0, "Status: %s\r\n", ast_json_string_get(status));
1081         }
1082         if (local_station_id) {
1083                 ast_str_append(&event_buffer, 0, "LocalStationID: %s\r\n", ast_json_string_get(local_station_id));
1084         }
1085         if (remote_station_id) {
1086                 ast_str_append(&event_buffer, 0, "RemoteStationID: %s\r\n", ast_json_string_get(remote_station_id));
1087         }
1088         if (fax_pages) {
1089                 ast_str_append(&event_buffer, 0, "PagesTransferred: %s\r\n", ast_json_string_get(fax_pages));
1090         }
1091         if (fax_resolution) {
1092                 ast_str_append(&event_buffer, 0, "Resolution: %s\r\n", ast_json_string_get(fax_resolution));
1093         }
1094         if (fax_bitrate) {
1095                 ast_str_append(&event_buffer, 0, "TransferRate: %s\r\n", ast_json_string_get(fax_bitrate));
1096         }
1097         if (filenames) {
1098                 array_len = ast_json_array_size(filenames);
1099                 for (i = 0; i < array_len; i++) {
1100                         ast_str_append(&event_buffer, 0, "FileName: %s\r\n", ast_json_string_get(ast_json_array_get(filenames, i)));
1101                 }
1102         }
1103
1104         manager_event(EVENT_FLAG_CALL, event,
1105                 "%s"
1106                 "%s",
1107                 ast_str_buffer(channel_event_string),
1108                 ast_str_buffer(event_buffer));
1109 }
1110
1111 static void channel_moh_start_cb(void *data, struct stasis_subscription *sub,
1112                 struct stasis_topic *topic, struct stasis_message *message)
1113 {
1114         struct ast_channel_blob *payload = stasis_message_data(message);
1115         struct ast_json *blob = payload->blob;
1116         RAII_VAR(struct ast_str *, channel_event_string, NULL, ast_free);
1117
1118         channel_event_string = ast_manager_build_channel_state_string(payload->snapshot);
1119         if (!channel_event_string) {
1120                 return;
1121         }
1122
1123         manager_event(EVENT_FLAG_CALL, "MusicOnHoldStart",
1124                 "%s"
1125                 "Class: %s\r\n",
1126                 ast_str_buffer(channel_event_string),
1127                 ast_json_string_get(ast_json_object_get(blob, "class")));
1128
1129 }
1130
1131 static void channel_moh_stop_cb(void *data, struct stasis_subscription *sub,
1132                 struct stasis_topic *topic, struct stasis_message *message)
1133 {
1134         struct ast_channel_blob *payload = stasis_message_data(message);
1135
1136         publish_basic_channel_event("MusicOnHoldStop", EVENT_FLAG_CALL, payload->snapshot);
1137 }
1138
1139 static void channel_monitor_start_cb(void *data, struct stasis_subscription *sub,
1140                 struct stasis_topic *topic, struct stasis_message *message)
1141 {
1142         struct ast_channel_blob *payload = stasis_message_data(message);
1143
1144         publish_basic_channel_event("MonitorStart", EVENT_FLAG_CALL, payload->snapshot);
1145 }
1146
1147 static void channel_monitor_stop_cb(void *data, struct stasis_subscription *sub,
1148                 struct stasis_topic *topic, struct stasis_message *message)
1149 {
1150         struct ast_channel_blob *payload = stasis_message_data(message);
1151
1152         publish_basic_channel_event("MonitorStop", EVENT_FLAG_CALL, payload->snapshot);
1153 }
1154
1155 /*!
1156  * \brief Callback processing messages for channel dialing
1157  */
1158 static void channel_dial_cb(void *data, struct stasis_subscription *sub,
1159         struct stasis_topic *topic, struct stasis_message *message)
1160 {
1161         struct ast_multi_channel_blob *obj = stasis_message_data(message);
1162         const char *dialstatus;
1163         const char *dialstring;
1164         struct ast_channel_snapshot *caller;
1165         struct ast_channel_snapshot *peer;
1166         RAII_VAR(struct ast_str *, caller_event_string, NULL, ast_free);
1167         RAII_VAR(struct ast_str *, peer_event_string, NULL, ast_free);
1168
1169         caller = ast_multi_channel_blob_get_channel(obj, "caller");
1170         peer = ast_multi_channel_blob_get_channel(obj, "peer");
1171
1172         /* Peer is required - otherwise, who are we dialing? */
1173         ast_assert(peer != NULL);
1174         peer_event_string = ast_manager_build_channel_state_string_prefix(peer, "Dest");
1175         if (!peer_event_string) {
1176                 return;
1177         }
1178
1179         if (caller && !(caller_event_string = ast_manager_build_channel_state_string(caller))) {
1180                 return;
1181         }
1182
1183         dialstatus = ast_json_string_get(ast_json_object_get(ast_multi_channel_blob_get_json(obj), "dialstatus"));
1184         dialstring = ast_json_string_get(ast_json_object_get(ast_multi_channel_blob_get_json(obj), "dialstring"));
1185         if (ast_strlen_zero(dialstatus)) {
1186                 manager_event(EVENT_FLAG_CALL, "DialBegin",
1187                                 "%s"
1188                                 "%s"
1189                                 "DialString: %s\r\n",
1190                                 caller_event_string ? ast_str_buffer(caller_event_string) : "",
1191                                 ast_str_buffer(peer_event_string),
1192                                 S_OR(dialstring, "unknown"));
1193         } else {
1194                 manager_event(EVENT_FLAG_CALL, "DialEnd",
1195                                 "%s"
1196                                 "%s"
1197                                 "DialStatus: %s\r\n",
1198                                 caller_event_string ? ast_str_buffer(caller_event_string) : "",
1199                                 ast_str_buffer(peer_event_string),
1200                                 S_OR(dialstatus, "unknown"));
1201         }
1202
1203 }
1204
1205 static void channel_hold_cb(void *data, struct stasis_subscription *sub,
1206         struct stasis_topic *topic, struct stasis_message *message)
1207 {
1208         struct ast_channel_blob *obj = stasis_message_data(message);
1209         const char *musicclass;
1210         RAII_VAR(struct ast_str *, musicclass_string, NULL, ast_free);
1211         RAII_VAR(struct ast_str *, channel_event_string, NULL, ast_free);
1212
1213         if (!(musicclass_string = ast_str_create(32))) {
1214                 return;
1215         }
1216
1217         channel_event_string = ast_manager_build_channel_state_string(obj->snapshot);
1218         if (!channel_event_string) {
1219                 return;
1220         }
1221
1222         if (obj->blob) {
1223                 musicclass = ast_json_string_get(ast_json_object_get(obj->blob, "musicclass"));
1224
1225                 if (!ast_strlen_zero(musicclass)) {
1226                         ast_str_set(&musicclass_string, 0, "MusicClass: %s\r\n", musicclass);
1227                 }
1228         }
1229
1230         manager_event(EVENT_FLAG_CALL, "Hold",
1231                 "%s"
1232                 "%s",
1233                 ast_str_buffer(channel_event_string),
1234                 ast_str_buffer(musicclass_string));
1235 }
1236
1237 static void channel_unhold_cb(void *data, struct stasis_subscription *sub,
1238         struct stasis_topic *topic, struct stasis_message *message)
1239 {
1240         struct ast_channel_blob *obj = stasis_message_data(message);
1241         RAII_VAR(struct ast_str *, channel_event_string, NULL, ast_free);
1242
1243         channel_event_string = ast_manager_build_channel_state_string(obj->snapshot);
1244         if (!channel_event_string) {
1245                 return;
1246         }
1247
1248         manager_event(EVENT_FLAG_CALL, "Unhold",
1249                 "%s",
1250                 ast_str_buffer(channel_event_string));
1251 }
1252
1253 static void manager_channels_shutdown(void)
1254 {
1255         stasis_unsubscribe(topic_forwarder);
1256         topic_forwarder = NULL;
1257 }
1258
1259 int manager_channels_init(void)
1260 {
1261         int ret = 0;
1262         struct stasis_topic *manager_topic;
1263         struct stasis_topic *channel_topic;
1264         struct stasis_message_router *message_router;
1265
1266         manager_topic = ast_manager_get_topic();
1267         if (!manager_topic) {
1268                 return -1;
1269         }
1270         message_router = ast_manager_get_message_router();
1271         if (!message_router) {
1272                 return -1;
1273         }
1274         channel_topic = stasis_caching_get_topic(ast_channel_topic_all_cached());
1275         if (!channel_topic) {
1276                 return -1;
1277         }
1278
1279         topic_forwarder = stasis_forward_all(channel_topic, manager_topic);
1280         if (!topic_forwarder) {
1281                 return -1;
1282         }
1283
1284         ast_register_atexit(manager_channels_shutdown);
1285
1286         ret |= stasis_message_router_add(message_router,
1287                                          stasis_cache_update_type(),
1288                                          channel_snapshot_update,
1289                                          NULL);
1290
1291         ret |= stasis_message_router_add(message_router,
1292                                          ast_channel_user_event_type(),
1293                                          channel_user_event_cb,
1294                                          NULL);
1295
1296         ret |= stasis_message_router_add(message_router,
1297                                          ast_channel_dtmf_begin_type(),
1298                                          channel_dtmf_begin_cb,
1299                                          NULL);
1300
1301         ret |= stasis_message_router_add(message_router,
1302                                          ast_channel_dtmf_end_type(),
1303                                          channel_dtmf_end_cb,
1304                                          NULL);
1305
1306         ret |= stasis_message_router_add(message_router,
1307                                          ast_channel_hangup_request_type(),
1308                                          channel_hangup_request_cb,
1309                                          NULL);
1310
1311         ret |= stasis_message_router_add(message_router,
1312                                          ast_channel_dial_type(),
1313                                          channel_dial_cb,
1314                                          NULL);
1315
1316         ret |= stasis_message_router_add(message_router,
1317                                          ast_channel_hold_type(),
1318                                          channel_hold_cb,
1319                                          NULL);
1320
1321         ret |= stasis_message_router_add(message_router,
1322                                          ast_channel_unhold_type(),
1323                                          channel_unhold_cb,
1324                                          NULL);
1325
1326         ret |= stasis_message_router_add(message_router,
1327                                          ast_channel_fax_type(),
1328                                          channel_fax_cb,
1329                                          NULL);
1330
1331         ret |= stasis_message_router_add(message_router,
1332                                          ast_channel_chanspy_start_type(),
1333                                          channel_chanspy_start_cb,
1334                                          NULL);
1335
1336         ret |= stasis_message_router_add(message_router,
1337                                          ast_channel_chanspy_stop_type(),
1338                                          channel_chanspy_stop_cb,
1339                                          NULL);
1340
1341         ret |= stasis_message_router_add(message_router,
1342                                          ast_channel_hangup_handler_type(),
1343                                          channel_hangup_handler_cb,
1344                                          NULL);
1345
1346         ret |= stasis_message_router_add(message_router,
1347                                          ast_channel_moh_start_type(),
1348                                          channel_moh_start_cb,
1349                                          NULL);
1350
1351         ret |= stasis_message_router_add(message_router,
1352                                          ast_channel_moh_stop_type(),
1353                                          channel_moh_stop_cb,
1354                                          NULL);
1355
1356         ret |= stasis_message_router_add(message_router,
1357                                          ast_channel_monitor_start_type(),
1358                                          channel_monitor_start_cb,
1359                                          NULL);
1360
1361         ret |= stasis_message_router_add(message_router,
1362                                          ast_channel_monitor_stop_type(),
1363                                          channel_monitor_stop_cb,
1364                                          NULL);
1365
1366         /* If somehow we failed to add any routes, just shut down the whole
1367          * thing and fail it.
1368          */
1369         if (ret) {
1370                 manager_channels_shutdown();
1371                 return -1;
1372         }
1373
1374         return 0;
1375 }
1376