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