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