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