ARI: Add ability to raise arbitrary User Events
[asterisk/asterisk.git] / main / stasis_bridges.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2013, Digium, Inc.
5  *
6  * Kinsey Moore <kmoore@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 Stasis Messages and Data Types for Bridge Objects
22  *
23  * \author Kinsey Moore <kmoore@digium.com>
24  */
25
26 /*** MODULEINFO
27         <support_level>core</support_level>
28  ***/
29
30 #include "asterisk.h"
31
32 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
33
34 #include "asterisk/astobj2.h"
35 #include "asterisk/stasis.h"
36 #include "asterisk/stasis_cache_pattern.h"
37 #include "asterisk/channel.h"
38 #include "asterisk/stasis_bridges.h"
39 #include "asterisk/stasis_channels.h"
40 #include "asterisk/bridge.h"
41 #include "asterisk/bridge_technology.h"
42
43 /* The container of channel snapshots in a bridge snapshot should always be
44    equivalent to a linked list; otherwise things (like CDRs) that depend on some
45    consistency in the ordering of channels in a bridge will break. */
46 #define SNAPSHOT_CHANNELS_BUCKETS 1
47
48 /*** DOCUMENTATION
49         <managerEvent language="en_US" name="BlindTransfer">
50                 <managerEventInstance class="EVENT_FLAG_CALL">
51                         <synopsis>Raised when a blind transfer is complete.</synopsis>
52                         <syntax>
53                                 <parameter name="Result">
54                                         <para>Indicates if the transfer was successful or if it failed.</para>
55                                         <enumlist>
56                                                 <enum name="Fail"><para>An internal error occurred.</para></enum>
57                                                 <enum name="Invalid"><para>Invalid configuration for transfer (e.g. Not bridged)</para></enum>
58                                                 <enum name="Not Permitted"><para>Bridge does not permit transfers</para></enum>
59                                                 <enum name="Success"><para>Transfer completed successfully</para></enum>
60                                         </enumlist>
61                                         <note><para>A result of <literal>Success</literal> does not necessarily mean that a target was succesfully
62                                         contacted. It means that a party was succesfully placed into the dialplan at the expected location.</para></note>
63                                 </parameter>
64                                 <channel_snapshot prefix="Transferer"/>
65                                 <bridge_snapshot/>
66                                 <parameter name="IsExternal">
67                                         <para>Indicates if the transfer was performed outside of Asterisk. For instance,
68                                         a channel protocol native transfer is external. A DTMF transfer is internal.</para>
69                                                 <enumlist>
70                                                         <enum name="Yes" />
71                                                         <enum name="No" />
72                                                 </enumlist>
73                                 </parameter>
74                                 <parameter name="Context">
75                                         <para>Destination context for the blind transfer.</para>
76                                 </parameter>
77                                 <parameter name="Extension">
78                                         <para>Destination extension for the blind transfer.</para>
79                                 </parameter>
80                         </syntax>
81                 </managerEventInstance>
82         </managerEvent>
83         <managerEvent language="en_US" name="AttendedTransfer">
84                 <managerEventInstance class="EVENT_FLAG_CALL">
85                         <synopsis>Raised when an attended transfer is complete.</synopsis>
86                         <syntax>
87                                 <xi:include xpointer="xpointer(docs/managerEvent[@name='BlindTransfer']/managerEventInstance/syntax/parameter[@name='Result'])" />
88                                 <channel_snapshot prefix="OrigTransferer"/>
89                                 <bridge_snapshot prefix="Orig"/>
90                                 <channel_snapshot prefix="SecondTransferer"/>
91                                 <bridge_snapshot prefix="Second"/>
92                                 <parameter name="DestType">
93                                         <para>Indicates the method by which the attended transfer completed.</para>
94                                         <enumlist>
95                                                 <enum name="Bridge"><para>The transfer was accomplished by merging two bridges into one.</para></enum>
96                                                 <enum name="App"><para>The transfer was accomplished by having a channel or bridge run a dialplan application.</para></enum>
97                                                 <enum name="Link"><para>The transfer was accomplished by linking two bridges together using a local channel pair.</para></enum>
98                                                 <enum name="Threeway"><para>The transfer was accomplished by placing all parties into a threeway call.</para></enum>
99                                                 <enum name="Fail"><para>The transfer failed.</para></enum>
100                                         </enumlist>
101                                 </parameter>
102                                 <parameter name="DestBridgeUniqueid">
103                                         <para>Indicates the surviving bridge when bridges were merged to complete the transfer</para>
104                                         <note><para>This header is only present when <replaceable>DestType</replaceable> is <literal>Bridge</literal> or <literal>Threeway</literal></para></note>
105                                 </parameter>
106                                 <parameter name="DestApp">
107                                         <para>Indicates the application that is running when the transfer completes</para>
108                                         <note><para>This header is only present when <replaceable>DestType</replaceable> is <literal>App</literal></para></note>
109                                 </parameter>
110                                 <channel_snapshot prefix="LocalOne"/>
111                                 <channel_snapshot prefix="LocalTwo"/>
112                                 <parameter name="DestTransfererChannel">
113                                         <para>The name of the surviving transferer channel when a transfer results in a threeway call</para>
114                                         <note><para>This header is only present when <replaceable>DestType</replaceable> is <literal>Threeway</literal></para></note>
115                                 </parameter>
116                         </syntax>
117                         <description>
118                                 <para>The headers in this event attempt to describe all the major details of the attended transfer. The two transferer channels
119                                 and the two bridges are determined based on their chronological establishment. So consider that Alice calls Bob, and then Alice
120                                 transfers the call to Voicemail. The transferer and bridge headers would be arranged as follows:</para>
121                                 <para>  <replaceable>OrigTransfererChannel</replaceable>: Alice's channel in the bridge with Bob.</para>
122                                 <para>  <replaceable>OrigBridgeUniqueid</replaceable>: The bridge between Alice and Bob.</para>
123                                 <para>  <replaceable>SecondTransfererChannel</replaceable>: Alice's channel that called Voicemail.</para>
124                                 <para>  <replaceable>SecondBridgeUniqueid</replaceable>: Not present, since a call to Voicemail has no bridge.</para>
125                                 <para>Now consider if the order were reversed; instead of having Alice call Bob and transfer him to Voicemail, Alice instead
126                                 calls her Voicemail and transfers that to Bob. The transferer and bridge headers would be arranged as follows:</para>
127                                 <para>  <replaceable>OrigTransfererChannel</replaceable>: Alice's channel that called Voicemail.</para>
128                                 <para>  <replaceable>OrigBridgeUniqueid</replaceable>: Not present, since a call to Voicemail has no bridge.</para>
129                                 <para>  <replaceable>SecondTransfererChannel</replaceable>: Alice's channel in the bridge with Bob.</para>
130                                 <para>  <replaceable>SecondBridgeUniqueid</replaceable>: The bridge between Alice and Bob.</para>
131                         </description>
132                 </managerEventInstance>
133         </managerEvent>
134  ***/
135
136 static struct ast_json *attended_transfer_to_json(struct stasis_message *msg,
137         const struct stasis_message_sanitizer *sanitize);
138 static struct ast_manager_event_blob *attended_transfer_to_ami(struct stasis_message *message);
139 static struct ast_json *blind_transfer_to_json(struct stasis_message *msg,
140         const struct stasis_message_sanitizer *sanitize);
141 static struct ast_manager_event_blob *blind_transfer_to_ami(struct stasis_message *message);
142 static struct ast_json *ast_channel_entered_bridge_to_json(
143         struct stasis_message *msg,
144         const struct stasis_message_sanitizer *sanitize);
145 static struct ast_json *ast_channel_left_bridge_to_json(
146         struct stasis_message *msg,
147         const struct stasis_message_sanitizer *sanitize);
148 static struct ast_json *ast_bridge_merge_message_to_json(
149         struct stasis_message *msg,
150         const struct stasis_message_sanitizer *sanitize);
151
152 static struct stasis_cp_all *bridge_cache_all;
153
154 /*!
155  * @{ \brief Define bridge message types.
156  */
157 STASIS_MESSAGE_TYPE_DEFN(ast_bridge_snapshot_type);
158 STASIS_MESSAGE_TYPE_DEFN(ast_bridge_merge_message_type,
159         .to_json = ast_bridge_merge_message_to_json);
160 STASIS_MESSAGE_TYPE_DEFN(ast_channel_entered_bridge_type,
161         .to_json = ast_channel_entered_bridge_to_json);
162 STASIS_MESSAGE_TYPE_DEFN(ast_channel_left_bridge_type,
163         .to_json = ast_channel_left_bridge_to_json);
164 STASIS_MESSAGE_TYPE_DEFN(ast_blind_transfer_type,
165         .to_json = blind_transfer_to_json,
166         .to_ami = blind_transfer_to_ami);
167 STASIS_MESSAGE_TYPE_DEFN(ast_attended_transfer_type,
168         .to_json = attended_transfer_to_json,
169         .to_ami = attended_transfer_to_ami);
170 /*! @} */
171
172 struct stasis_cache *ast_bridge_cache(void)
173 {
174         return stasis_cp_all_cache(bridge_cache_all);
175 }
176
177 struct stasis_topic *ast_bridge_topic_all(void)
178 {
179         return stasis_cp_all_topic(bridge_cache_all);
180 }
181
182 struct stasis_topic *ast_bridge_topic_all_cached(void)
183 {
184         return stasis_cp_all_topic_cached(bridge_cache_all);
185 }
186
187 int bridge_topics_init(struct ast_bridge *bridge)
188 {
189         if (ast_strlen_zero(bridge->uniqueid)) {
190                 ast_log(LOG_ERROR, "Bridge id initialization required\n");
191                 return -1;
192         }
193         bridge->topics = stasis_cp_single_create(bridge_cache_all,
194                 bridge->uniqueid);
195         if (!bridge->topics) {
196                 return -1;
197         }
198         return 0;
199 }
200
201 struct stasis_topic *ast_bridge_topic(struct ast_bridge *bridge)
202 {
203         if (!bridge) {
204                 return ast_bridge_topic_all();
205         }
206
207         return stasis_cp_single_topic(bridge->topics);
208 }
209
210 struct stasis_topic *ast_bridge_topic_cached(struct ast_bridge *bridge)
211 {
212         if (!bridge) {
213                 return ast_bridge_topic_all_cached();
214         }
215
216         return stasis_cp_single_topic_cached(bridge->topics);
217 }
218
219 /*! \brief Destructor for bridge snapshots */
220 static void bridge_snapshot_dtor(void *obj)
221 {
222         struct ast_bridge_snapshot *snapshot = obj;
223         ast_string_field_free_memory(snapshot);
224         ao2_cleanup(snapshot->channels);
225         snapshot->channels = NULL;
226 }
227
228 struct ast_bridge_snapshot *ast_bridge_snapshot_create(struct ast_bridge *bridge)
229 {
230         RAII_VAR(struct ast_bridge_snapshot *, snapshot, NULL, ao2_cleanup);
231         struct ast_bridge_channel *bridge_channel;
232
233         snapshot = ao2_alloc(sizeof(*snapshot), bridge_snapshot_dtor);
234         if (!snapshot || ast_string_field_init(snapshot, 128)) {
235                 return NULL;
236         }
237
238         snapshot->channels = ast_str_container_alloc(SNAPSHOT_CHANNELS_BUCKETS);
239         if (!snapshot->channels) {
240                 return NULL;
241         }
242
243         AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
244                 if (ast_str_container_add(snapshot->channels,
245                                 ast_channel_uniqueid(bridge_channel->chan))) {
246                         return NULL;
247                 }
248         }
249
250         ast_string_field_set(snapshot, uniqueid, bridge->uniqueid);
251         ast_string_field_set(snapshot, technology, bridge->technology->name);
252         ast_string_field_set(snapshot, subclass, bridge->v_table->name);
253         ast_string_field_set(snapshot, creator, bridge->creator);
254         ast_string_field_set(snapshot, name, bridge->name);
255
256         snapshot->feature_flags = bridge->feature_flags;
257         snapshot->capabilities = bridge->technology->capabilities;
258         snapshot->num_channels = bridge->num_channels;
259         snapshot->num_active = bridge->num_active;
260
261         ao2_ref(snapshot, +1);
262         return snapshot;
263 }
264
265 void ast_bridge_publish_state(struct ast_bridge *bridge)
266 {
267         RAII_VAR(struct ast_bridge_snapshot *, snapshot, NULL, ao2_cleanup);
268         RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
269
270         ast_assert(bridge != NULL);
271
272         snapshot = ast_bridge_snapshot_create(bridge);
273         if (!snapshot) {
274                 return;
275         }
276
277         msg = stasis_message_create(ast_bridge_snapshot_type(), snapshot);
278         if (!msg) {
279                 return;
280         }
281
282         stasis_publish(ast_bridge_topic(bridge), msg);
283 }
284
285 static void bridge_publish_state_from_blob(struct ast_bridge *bridge,
286         struct ast_bridge_blob *obj)
287 {
288         RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
289
290         ast_assert(obj != NULL);
291
292         msg = stasis_message_create(ast_bridge_snapshot_type(), obj->bridge);
293         if (!msg) {
294                 return;
295         }
296
297         stasis_publish(ast_bridge_topic(bridge), msg);
298 }
299
300 /*! \brief Destructor for bridge merge messages */
301 static void bridge_merge_message_dtor(void *obj)
302 {
303         struct ast_bridge_merge_message *msg = obj;
304
305         ao2_cleanup(msg->to);
306         msg->to = NULL;
307         ao2_cleanup(msg->from);
308         msg->from = NULL;
309 }
310
311 /*! \brief Bridge merge message creation helper */
312 static struct ast_bridge_merge_message *bridge_merge_message_create(struct ast_bridge *to, struct ast_bridge *from)
313 {
314         RAII_VAR(struct ast_bridge_merge_message *, msg, NULL, ao2_cleanup);
315
316         msg = ao2_alloc(sizeof(*msg), bridge_merge_message_dtor);
317         if (!msg) {
318                 return NULL;
319         }
320
321         msg->to = ast_bridge_snapshot_create(to);
322         if (!msg->to) {
323                 return NULL;
324         }
325
326         msg->from = ast_bridge_snapshot_create(from);
327         if (!msg->from) {
328                 return NULL;
329         }
330
331         ao2_ref(msg, +1);
332         return msg;
333 }
334
335 static struct ast_json *ast_bridge_merge_message_to_json(
336         struct stasis_message *msg,
337         const struct stasis_message_sanitizer *sanitize)
338 {
339         struct ast_bridge_merge_message *merge = stasis_message_data(msg);
340         RAII_VAR(struct ast_json *, json_bridge_to,
341                 ast_bridge_snapshot_to_json(merge->to, sanitize), ast_json_unref);
342         RAII_VAR(struct ast_json *, json_bridge_from,
343                 ast_bridge_snapshot_to_json(merge->from, sanitize), ast_json_unref);
344
345         if (!json_bridge_to || !json_bridge_from) {
346                 return NULL;
347         }
348
349         return ast_json_pack("{s: s, s: o, s: O, s: O}",
350                 "type", "BridgeMerged",
351                 "timestamp", ast_json_timeval(*stasis_message_timestamp(msg), NULL),
352                 "bridge", json_bridge_to,
353                 "bridge_from", json_bridge_from);
354 }
355
356 void ast_bridge_publish_merge(struct ast_bridge *to, struct ast_bridge *from)
357 {
358         RAII_VAR(struct ast_bridge_merge_message *, merge_msg, NULL, ao2_cleanup);
359         RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
360
361         ast_assert(to != NULL);
362         ast_assert(from != NULL);
363
364         merge_msg = bridge_merge_message_create(to, from);
365         if (!merge_msg) {
366                 return;
367         }
368
369         msg = stasis_message_create(ast_bridge_merge_message_type(), merge_msg);
370         if (!msg) {
371                 return;
372         }
373
374         stasis_publish(ast_bridge_topic_all(), msg);
375 }
376
377 static void bridge_blob_dtor(void *obj)
378 {
379         struct ast_bridge_blob *event = obj;
380         ao2_cleanup(event->bridge);
381         event->bridge = NULL;
382         ao2_cleanup(event->channel);
383         event->channel = NULL;
384         ast_json_unref(event->blob);
385         event->blob = NULL;
386 }
387
388 struct stasis_message *ast_bridge_blob_create(
389         struct stasis_message_type *message_type,
390         struct ast_bridge *bridge,
391         struct ast_channel *chan,
392         struct ast_json *blob)
393 {
394         RAII_VAR(struct ast_bridge_blob *, obj, NULL, ao2_cleanup);
395         RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
396
397         obj = ao2_alloc(sizeof(*obj), bridge_blob_dtor);
398         if (!obj) {
399                 return NULL;
400         }
401
402         if (bridge) {
403                 obj->bridge = ast_bridge_snapshot_create(bridge);
404                 if (obj->bridge == NULL) {
405                         return NULL;
406                 }
407         }
408
409         if (chan) {
410                 ast_channel_lock(chan);
411                 obj->channel = ast_channel_snapshot_create(chan);
412                 ast_channel_unlock(chan);
413                 if (obj->channel == NULL) {
414                         return NULL;
415                 }
416         }
417
418         if (blob) {
419                 obj->blob = ast_json_ref(blob);
420         }
421
422         msg = stasis_message_create(message_type, obj);
423         if (!msg) {
424                 return NULL;
425         }
426
427         ao2_ref(msg, +1);
428         return msg;
429 }
430
431 void ast_bridge_publish_enter(struct ast_bridge *bridge, struct ast_channel *chan,
432                 struct ast_channel *swap)
433 {
434         RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
435         RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
436
437         if (swap) {
438                 blob = ast_json_pack("{s: s}", "swap", ast_channel_uniqueid(swap));
439                 if (!blob) {
440                         return;
441                 }
442         }
443
444         msg = ast_bridge_blob_create(ast_channel_entered_bridge_type(), bridge, chan, blob);
445         if (!msg) {
446                 return;
447         }
448
449         /* enter blob first, then state */
450         stasis_publish(ast_bridge_topic(bridge), msg);
451         bridge_publish_state_from_blob(bridge, stasis_message_data(msg));
452 }
453
454 void ast_bridge_publish_leave(struct ast_bridge *bridge, struct ast_channel *chan)
455 {
456         RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
457
458         msg = ast_bridge_blob_create(ast_channel_left_bridge_type(), bridge, chan, NULL);
459         if (!msg) {
460                 return;
461         }
462
463         /* state first, then leave blob (opposite of enter, preserves nesting of events) */
464         bridge_publish_state_from_blob(bridge, stasis_message_data(msg));
465         stasis_publish(ast_bridge_topic(bridge), msg);
466 }
467
468 static struct ast_json *simple_bridge_channel_event(
469         const char *type,
470         struct ast_bridge_snapshot *bridge_snapshot,
471         struct ast_channel_snapshot *channel_snapshot,
472         const struct timeval *tv,
473         const struct stasis_message_sanitizer *sanitize)
474 {
475         RAII_VAR(struct ast_json *, json_bridge,
476                 ast_bridge_snapshot_to_json(bridge_snapshot, sanitize), ast_json_unref);
477         RAII_VAR(struct ast_json *, json_channel,
478                 ast_channel_snapshot_to_json(channel_snapshot, sanitize), ast_json_unref);
479
480         if (!json_bridge || !json_channel) {
481                 return NULL;
482         }
483
484         return ast_json_pack("{s: s, s: o, s: O, s: O}",
485                 "type", type,
486                 "timestamp", ast_json_timeval(*tv, NULL),
487                 "bridge", json_bridge,
488                 "channel", json_channel);
489 }
490
491 struct ast_json *ast_channel_entered_bridge_to_json(
492         struct stasis_message *msg,
493         const struct stasis_message_sanitizer *sanitize)
494 {
495         struct ast_bridge_blob *obj = stasis_message_data(msg);
496
497         return simple_bridge_channel_event("ChannelEnteredBridge", obj->bridge,
498                 obj->channel, stasis_message_timestamp(msg), sanitize);
499 }
500
501 struct ast_json *ast_channel_left_bridge_to_json(
502         struct stasis_message *msg,
503         const struct stasis_message_sanitizer *sanitize)
504 {
505         struct ast_bridge_blob *obj = stasis_message_data(msg);
506
507         return simple_bridge_channel_event("ChannelLeftBridge", obj->bridge,
508                 obj->channel, stasis_message_timestamp(msg), sanitize);
509 }
510
511 static struct ast_json *container_to_json_array(struct ao2_container *items,
512         const struct stasis_message_sanitizer *sanitize)
513 {
514         RAII_VAR(struct ast_json *, json_items, ast_json_array_create(), ast_json_unref);
515         char *item;
516         struct ao2_iterator it;
517         if (!json_items) {
518                 return NULL;
519         }
520
521         for (it = ao2_iterator_init(items, 0);
522                 (item = ao2_iterator_next(&it)); ao2_cleanup(item)) {
523                 if (sanitize && sanitize->channel_id && sanitize->channel_id(item)) {
524                         continue;
525                 }
526
527                 if (ast_json_array_append(json_items, ast_json_string_create(item))) {
528                         ao2_cleanup(item);
529                         ao2_iterator_destroy(&it);
530                         return NULL;
531                 }
532         }
533         ao2_iterator_destroy(&it);
534
535         return ast_json_ref(json_items);
536 }
537
538 static const char *capability2str(uint32_t capabilities)
539 {
540         if (capabilities & AST_BRIDGE_CAPABILITY_HOLDING) {
541                 return "holding";
542         } else {
543                 return "mixing";
544         }
545 }
546
547 struct ast_json *ast_bridge_snapshot_to_json(
548         const struct ast_bridge_snapshot *snapshot,
549         const struct stasis_message_sanitizer *sanitize)
550 {
551         RAII_VAR(struct ast_json *, json_bridge, NULL, ast_json_unref);
552         struct ast_json *json_channels;
553
554         if (snapshot == NULL) {
555                 return NULL;
556         }
557
558         json_channels = container_to_json_array(snapshot->channels, sanitize);
559         if (!json_channels) {
560                 return NULL;
561         }
562
563         json_bridge = ast_json_pack("{s: s, s: s, s: s, s: s, s: s, s: s, s: o}",
564                 "id", snapshot->uniqueid,
565                 "technology", snapshot->technology,
566                 "bridge_type", capability2str(snapshot->capabilities),
567                 "bridge_class", snapshot->subclass,
568                 "creator", snapshot->creator,
569                 "name", snapshot->name,
570                 "channels", json_channels);
571         if (!json_bridge) {
572                 return NULL;
573         }
574
575         return ast_json_ref(json_bridge);
576 }
577
578 /*!
579  * \internal
580  * \brief Allocate the fields of an \ref ast_bridge_channel_snapshot_pair.
581  *
582  * \param pair A bridge and channel to get snapshots of
583  * \param[out] snapshot_pair An allocated snapshot pair.
584  * \retval 0 Success
585  * \retval non-zero Failure
586  */
587 static int bridge_channel_snapshot_pair_init(struct ast_bridge_channel_pair *pair, struct ast_bridge_channel_snapshot_pair *snapshot_pair)
588 {
589         if (pair->bridge) {
590                 snapshot_pair->bridge_snapshot = ast_bridge_snapshot_create(pair->bridge);
591                 if (!snapshot_pair->bridge_snapshot) {
592                         return -1;
593                 }
594         }
595
596         ast_channel_lock(pair->channel);
597         snapshot_pair->channel_snapshot = ast_channel_snapshot_create(pair->channel);
598         ast_channel_unlock(pair->channel);
599         if (!snapshot_pair->channel_snapshot) {
600                 return -1;
601         }
602
603         return 0;
604 }
605
606 /*!
607  * \internal
608  * \brief Free the fields of an \ref ast_bridge_channel_snapshot_pair.
609  *
610  * \param pair The snapshot pair whose fields are to be cleaned up
611  */
612 static void bridge_channel_snapshot_pair_cleanup(struct ast_bridge_channel_snapshot_pair *pair)
613 {
614         ao2_cleanup(pair->bridge_snapshot);
615         ao2_cleanup(pair->channel_snapshot);
616 }
617
618 static const char *result_strs[] = {
619         [AST_BRIDGE_TRANSFER_FAIL] = "Fail",
620         [AST_BRIDGE_TRANSFER_INVALID] = "Invalid",
621         [AST_BRIDGE_TRANSFER_NOT_PERMITTED] = "Not Permitted",
622         [AST_BRIDGE_TRANSFER_SUCCESS] = "Success",
623 };
624
625 static struct ast_json *blind_transfer_to_json(struct stasis_message *msg,
626         const struct stasis_message_sanitizer *sanitize)
627 {
628         struct ast_bridge_blob *blob = stasis_message_data(msg);
629         struct ast_json *json_channel, *out;
630         const struct timeval *tv = stasis_message_timestamp(msg);
631
632         json_channel = ast_channel_snapshot_to_json(blob->channel, sanitize);
633         if (!json_channel) {
634                 return NULL;
635         }
636
637         out = ast_json_pack("{s: s, s: o, s: o, s: O, s: O, s: s, s: o}",
638                 "type", "BridgeBlindTransfer",
639                 "timestamp", ast_json_timeval(*tv, NULL),
640                 "channel", json_channel,
641                 "exten", ast_json_object_get(blob->blob, "exten"),
642                 "context", ast_json_object_get(blob->blob, "context"),
643                 "result", result_strs[ast_json_integer_get(ast_json_object_get(blob->blob, "result"))],
644                 "is_external", ast_json_boolean(ast_json_integer_get(ast_json_object_get(blob->blob, "is_external"))));
645
646         if (!out) {
647                 return NULL;
648         }
649
650         if (blob->bridge) {
651                 struct ast_json *json_bridge = ast_bridge_snapshot_to_json(blob->bridge, sanitize);
652
653                 if (!json_bridge || ast_json_object_set(out, "bridge", json_bridge)) {
654                         ast_json_unref(out);
655                         return NULL;
656                 }
657         }
658
659         return out;
660 }
661
662 static struct ast_manager_event_blob *blind_transfer_to_ami(struct stasis_message *msg)
663 {
664         RAII_VAR(struct ast_str *, channel_state, NULL, ast_free_ptr);
665         RAII_VAR(struct ast_str *, bridge_state, NULL, ast_free_ptr);
666         struct ast_bridge_blob *blob = stasis_message_data(msg);
667         const char *exten;
668         const char *context;
669         enum ast_transfer_result result;
670         int is_external;
671
672         if (!blob) {
673                 return NULL;
674         }
675
676         channel_state = ast_manager_build_channel_state_string_prefix(blob->channel, "Transferer");
677         if (!channel_state) {
678                 return NULL;
679         }
680
681         if (blob->bridge) {
682                 bridge_state = ast_manager_build_bridge_state_string(blob->bridge);
683                 if (!bridge_state) {
684                         return NULL;
685                 }
686         }
687
688         exten = ast_json_string_get(ast_json_object_get(blob->blob, "exten"));
689         context = ast_json_string_get(ast_json_object_get(blob->blob, "context"));
690         result = ast_json_integer_get(ast_json_object_get(blob->blob, "result"));
691         is_external = ast_json_integer_get(ast_json_object_get(blob->blob, "is_external"));
692
693         return ast_manager_event_blob_create(EVENT_FLAG_CALL, "BlindTransfer",
694                         "Result: %s\r\n"
695                         "%s"
696                         "%s"
697                         "IsExternal: %s\r\n"
698                         "Context: %s\r\n"
699                         "Extension: %s\r\n",
700                         result_strs[result],
701                         ast_str_buffer(channel_state),
702                         bridge_state ? ast_str_buffer(bridge_state) : "",
703                         is_external ? "Yes" : "No",
704                         context,
705                         exten);
706 }
707
708 void ast_bridge_publish_blind_transfer(int is_external, enum ast_transfer_result result,
709                 struct ast_bridge_channel_pair *transferer, const char *context, const char *exten)
710 {
711         RAII_VAR(struct ast_json *, json_object, NULL, ast_json_unref);
712         RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
713
714         json_object = ast_json_pack("{s: s, s: s, s: i, s: i}",
715                         "context", context, "exten", exten, "result", result, "is_external", is_external);
716
717         if (!json_object) {
718                 ast_log(LOG_NOTICE, "Failed to create json bridge blob\n");
719                 return;
720         }
721
722         msg = ast_bridge_blob_create(ast_blind_transfer_type(),
723                         transferer->bridge, transferer->channel, json_object);
724
725         if (!msg) {
726                 ast_log(LOG_NOTICE, "Failed to create blob msg\n");
727                 return;
728         }
729
730         stasis_publish(ast_bridge_topic_all(), msg);
731 }
732
733 static struct ast_json *attended_transfer_to_json(struct stasis_message *msg,
734         const struct stasis_message_sanitizer *sanitize)
735 {
736         struct ast_attended_transfer_message *transfer_msg = stasis_message_data(msg);
737         RAII_VAR(struct ast_json *, out, NULL, ast_json_unref);
738         struct ast_json *json_transferer1, *json_transferer2, *json_bridge, *json_channel;
739         const struct timeval *tv = stasis_message_timestamp(msg);
740         int res = 0;
741
742         json_transferer1 = ast_channel_snapshot_to_json(transfer_msg->to_transferee.channel_snapshot, sanitize);
743         if (!json_transferer1) {
744                 return NULL;
745         }
746
747         json_transferer2 = ast_channel_snapshot_to_json(transfer_msg->to_transfer_target.channel_snapshot, sanitize);
748         if (!json_transferer2) {
749                 ast_json_unref(json_transferer1);
750                 return NULL;
751         }
752
753         out = ast_json_pack("{s: s, s: o, s: o, s: o, s: s, s: o}",
754                 "type", "BridgeAttendedTransfer",
755                 "timestamp", ast_json_timeval(*tv, NULL),
756                 "transferer_first_leg", json_transferer1,
757                 "transferer_second_leg", json_transferer2,
758                 "result", result_strs[transfer_msg->result],
759                 "is_external", ast_json_boolean(transfer_msg->is_external));
760         if (!out) {
761                 return NULL;
762         }
763
764         if (transfer_msg->to_transferee.bridge_snapshot) {
765                 json_bridge = ast_bridge_snapshot_to_json(transfer_msg->to_transferee.bridge_snapshot, sanitize);
766
767                 if (!json_bridge) {
768                         return NULL;
769                 }
770
771                 res |= ast_json_object_set(out, "transferer_first_leg_bridge", json_bridge);
772         }
773
774         if (transfer_msg->to_transfer_target.bridge_snapshot) {
775                 json_bridge = ast_bridge_snapshot_to_json(transfer_msg->to_transfer_target.bridge_snapshot, sanitize);
776
777                 if (!json_bridge) {
778                         return NULL;
779                 }
780
781                 res |= ast_json_object_set(out, "transferer_second_leg_bridge", json_bridge);
782         }
783
784         switch (transfer_msg->dest_type) {
785         case AST_ATTENDED_TRANSFER_DEST_BRIDGE_MERGE:
786                 res |= ast_json_object_set(out, "destination_type", ast_json_string_create("bridge"));
787                 res |= ast_json_object_set(out, "destination_bridge", ast_json_string_create(transfer_msg->dest.bridge));
788                 break;
789         case AST_ATTENDED_TRANSFER_DEST_APP:
790                 res |= ast_json_object_set(out, "destination_type", ast_json_string_create("application"));
791                 res |= ast_json_object_set(out, "destination_application", ast_json_string_create(transfer_msg->dest.app));
792                 break;
793         case AST_ATTENDED_TRANSFER_DEST_LINK:
794                 res |= ast_json_object_set(out, "destination_type", ast_json_string_create("link"));
795
796                 json_channel = ast_channel_snapshot_to_json(transfer_msg->dest.links[0], sanitize);
797                 if (!json_channel) {
798                         return NULL;
799                 }
800                 res |= ast_json_object_set(out, "destination_link_first_leg", json_channel);
801
802                 json_channel = ast_channel_snapshot_to_json(transfer_msg->dest.links[1], sanitize);
803                 if (!json_channel) {
804                         return NULL;
805                 }
806                 res |= ast_json_object_set(out, "destination_link_second_leg", json_channel);
807
808                 break;
809         case AST_ATTENDED_TRANSFER_DEST_THREEWAY:
810                 res |= ast_json_object_set(out, "destination_type", ast_json_string_create("threeway"));
811
812                 json_channel = ast_channel_snapshot_to_json(transfer_msg->dest.threeway.channel_snapshot, sanitize);
813                 if (!json_channel) {
814                         return NULL;
815                 }
816                 res |= ast_json_object_set(out, "destination_threeway_channel", json_channel);
817
818                 json_bridge = ast_bridge_snapshot_to_json(transfer_msg->dest.threeway.bridge_snapshot, sanitize);
819                 if (!json_bridge) {
820                         return NULL;
821                 }
822                 res |= ast_json_object_set(out, "destination_threeway_bridge", json_bridge);
823
824                 break;
825         case AST_ATTENDED_TRANSFER_DEST_FAIL:
826                 res |= ast_json_object_set(out, "destination_type", ast_json_string_create("fail"));
827                 break;
828         }
829
830         if (res) {
831                 return NULL;
832         }
833
834         return ast_json_ref(out);
835 }
836
837 static struct ast_manager_event_blob *attended_transfer_to_ami(struct stasis_message *msg)
838 {
839         RAII_VAR(struct ast_str *, variable_data, ast_str_create(64), ast_free_ptr);
840         RAII_VAR(struct ast_str *, transferer1_state, NULL, ast_free_ptr);
841         RAII_VAR(struct ast_str *, bridge1_state, NULL, ast_free_ptr);
842         RAII_VAR(struct ast_str *, transferer2_state, NULL, ast_free_ptr);
843         RAII_VAR(struct ast_str *, bridge2_state, NULL, ast_free_ptr);
844         RAII_VAR(struct ast_str *, local1_state, NULL, ast_free_ptr);
845         RAII_VAR(struct ast_str *, local2_state, NULL, ast_free_ptr);
846         struct ast_attended_transfer_message *transfer_msg = stasis_message_data(msg);
847
848         if (!variable_data) {
849                 return NULL;
850         }
851
852         transferer1_state = ast_manager_build_channel_state_string_prefix(transfer_msg->to_transferee.channel_snapshot, "OrigTransferer");
853         transferer2_state = ast_manager_build_channel_state_string_prefix(transfer_msg->to_transfer_target.channel_snapshot, "SecondTransferer");
854         if (!transferer1_state || !transferer2_state) {
855                 return NULL;
856         }
857
858         if (transfer_msg->to_transferee.bridge_snapshot) {
859                 bridge1_state = ast_manager_build_bridge_state_string_prefix(
860                         transfer_msg->to_transferee.bridge_snapshot, "Orig");
861                 if (!bridge1_state) {
862                         return NULL;
863                 }
864         }
865
866         if (transfer_msg->to_transfer_target.bridge_snapshot) {
867                 bridge2_state = ast_manager_build_bridge_state_string_prefix(
868                         transfer_msg->to_transfer_target.bridge_snapshot, "Second");
869                 if (!bridge2_state) {
870                         return NULL;
871                 }
872         }
873
874         switch (transfer_msg->dest_type) {
875         case AST_ATTENDED_TRANSFER_DEST_BRIDGE_MERGE:
876                 ast_str_append(&variable_data, 0, "DestType: Bridge\r\n");
877                 ast_str_append(&variable_data, 0, "DestBridgeUniqueid: %s\r\n", transfer_msg->dest.bridge);
878                 break;
879         case AST_ATTENDED_TRANSFER_DEST_APP:
880                 ast_str_append(&variable_data, 0, "DestType: App\r\n");
881                 ast_str_append(&variable_data, 0, "DestApp: %s\r\n", transfer_msg->dest.app);
882                 break;
883         case AST_ATTENDED_TRANSFER_DEST_LINK:
884                 local1_state = ast_manager_build_channel_state_string_prefix(transfer_msg->dest.links[0], "LocalOne");
885                 local2_state = ast_manager_build_channel_state_string_prefix(transfer_msg->dest.links[1], "LocalTwo");
886                 if (!local1_state || !local2_state) {
887                         return NULL;
888                 }
889                 ast_str_append(&variable_data, 0, "DestType: Link\r\n");
890                 ast_str_append(&variable_data, 0, "%s", ast_str_buffer(local1_state));
891                 ast_str_append(&variable_data, 0, "%s", ast_str_buffer(local2_state));
892                 break;
893         case AST_ATTENDED_TRANSFER_DEST_THREEWAY:
894                 ast_str_append(&variable_data, 0, "DestType: Threeway\r\n");
895                 ast_str_append(&variable_data, 0, "DestBridgeUniqueid: %s\r\n", transfer_msg->dest.threeway.bridge_snapshot->uniqueid);
896                 ast_str_append(&variable_data, 0, "DestTransfererChannel: %s\r\n", transfer_msg->dest.threeway.channel_snapshot->name);
897                 break;
898         case AST_ATTENDED_TRANSFER_DEST_FAIL:
899                 ast_str_append(&variable_data, 0, "DestType: Fail\r\n");
900                 break;
901         }
902
903         return ast_manager_event_blob_create(EVENT_FLAG_CALL, "AttendedTransfer",
904                         "Result: %s\r\n"
905                         "%s"
906                         "%s"
907                         "%s"
908                         "%s"
909                         "IsExternal: %s\r\n"
910                         "%s",
911                         result_strs[transfer_msg->result],
912                         ast_str_buffer(transferer1_state),
913                         bridge1_state ? ast_str_buffer(bridge1_state) : "",
914                         ast_str_buffer(transferer2_state),
915                         bridge2_state ? ast_str_buffer(bridge2_state) : "",
916                         transfer_msg->is_external ? "Yes" : "No",
917                         ast_str_buffer(variable_data));
918 }
919
920 static void attended_transfer_dtor(void *obj)
921 {
922         struct ast_attended_transfer_message *msg = obj;
923         int i;
924
925         bridge_channel_snapshot_pair_cleanup(&msg->to_transferee);
926         bridge_channel_snapshot_pair_cleanup(&msg->to_transfer_target);
927
928         if (msg->dest_type != AST_ATTENDED_TRANSFER_DEST_LINK) {
929                 return;
930         }
931
932         for (i = 0; i < ARRAY_LEN(msg->dest.links); ++i) {
933                 ao2_cleanup(msg->dest.links[i]);
934         }
935 }
936
937 static struct ast_attended_transfer_message *attended_transfer_message_create(int is_external, enum ast_transfer_result result,
938                 struct ast_bridge_channel_pair *transferee, struct ast_bridge_channel_pair *target)
939 {
940         RAII_VAR(struct ast_attended_transfer_message *, msg, NULL, ao2_cleanup);
941
942         msg = ao2_alloc(sizeof(*msg), attended_transfer_dtor);
943         if (!msg) {
944                 return NULL;
945         }
946
947         if (bridge_channel_snapshot_pair_init(transferee, &msg->to_transferee) ||
948                         bridge_channel_snapshot_pair_init(target, &msg->to_transfer_target)) {
949                 return NULL;
950         }
951
952         msg->is_external = is_external;
953         msg->result = result;
954
955         ao2_ref(msg, +1);
956         return msg;
957 }
958
959 void ast_bridge_publish_attended_transfer_fail(int is_external, enum ast_transfer_result result,
960                 struct ast_bridge_channel_pair *transferee, struct ast_bridge_channel_pair *target)
961 {
962         RAII_VAR(struct ast_attended_transfer_message *, transfer_msg, NULL, ao2_cleanup);
963         RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
964
965         transfer_msg = attended_transfer_message_create(is_external, result, transferee, target);
966         if (!transfer_msg) {
967                 return;
968         }
969
970         transfer_msg->dest_type = AST_ATTENDED_TRANSFER_DEST_FAIL;
971
972         msg = stasis_message_create(ast_attended_transfer_type(), transfer_msg);
973         if (!msg) {
974                 return;
975         }
976
977         stasis_publish(ast_bridge_topic_all(), msg);
978 }
979
980 void ast_bridge_publish_attended_transfer_bridge_merge(int is_external, enum ast_transfer_result result,
981                 struct ast_bridge_channel_pair *transferee, struct ast_bridge_channel_pair *target,
982                 struct ast_bridge *final_bridge)
983 {
984         RAII_VAR(struct ast_attended_transfer_message *, transfer_msg, NULL, ao2_cleanup);
985         RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
986
987         transfer_msg = attended_transfer_message_create(is_external, result, transferee, target);
988         if (!transfer_msg) {
989                 return;
990         }
991
992         transfer_msg->dest_type = AST_ATTENDED_TRANSFER_DEST_BRIDGE_MERGE;
993         ast_copy_string(transfer_msg->dest.bridge, final_bridge->uniqueid,
994                         sizeof(transfer_msg->dest.bridge));
995
996         msg = stasis_message_create(ast_attended_transfer_type(), transfer_msg);
997         if (!msg) {
998                 return;
999         }
1000
1001         stasis_publish(ast_bridge_topic_all(), msg);
1002 }
1003
1004 void ast_bridge_publish_attended_transfer_threeway(int is_external, enum ast_transfer_result result,
1005                 struct ast_bridge_channel_pair *transferee, struct ast_bridge_channel_pair *target,
1006                 struct ast_bridge_channel_pair *final_pair)
1007 {
1008         RAII_VAR(struct ast_attended_transfer_message *, transfer_msg, NULL, ao2_cleanup);
1009         RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
1010
1011         transfer_msg = attended_transfer_message_create(is_external, result, transferee, target);
1012         if (!transfer_msg) {
1013                 return;
1014         }
1015
1016         transfer_msg->dest_type = AST_ATTENDED_TRANSFER_DEST_THREEWAY;
1017         if (final_pair->channel == transferee->channel) {
1018                 transfer_msg->dest.threeway.channel_snapshot = transfer_msg->to_transferee.channel_snapshot;
1019         } else {
1020                 transfer_msg->dest.threeway.channel_snapshot = transfer_msg->to_transfer_target.channel_snapshot;
1021         }
1022
1023         if (final_pair->bridge == transferee->bridge) {
1024                 transfer_msg->dest.threeway.bridge_snapshot = transfer_msg->to_transferee.bridge_snapshot;
1025         } else {
1026                 transfer_msg->dest.threeway.bridge_snapshot = transfer_msg->to_transfer_target.bridge_snapshot;
1027         }
1028
1029         msg = stasis_message_create(ast_attended_transfer_type(), transfer_msg);
1030         if (!msg) {
1031                 return;
1032         }
1033
1034         stasis_publish(ast_bridge_topic_all(), msg);
1035 }
1036
1037 void ast_bridge_publish_attended_transfer_app(int is_external, enum ast_transfer_result result,
1038                 struct ast_bridge_channel_pair *transferee, struct ast_bridge_channel_pair *target,
1039                 const char *dest_app)
1040 {
1041         RAII_VAR(struct ast_attended_transfer_message *, transfer_msg, NULL, ao2_cleanup);
1042         RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
1043
1044         transfer_msg = attended_transfer_message_create(is_external, result, transferee, target);
1045         if (!transfer_msg) {
1046                 return;
1047         }
1048
1049         transfer_msg->dest_type = AST_ATTENDED_TRANSFER_DEST_APP;
1050         ast_copy_string(transfer_msg->dest.app, dest_app, sizeof(transfer_msg->dest.app));
1051
1052         msg = stasis_message_create(ast_attended_transfer_type(), transfer_msg);
1053         if (!msg) {
1054                 return;
1055         }
1056
1057         stasis_publish(ast_bridge_topic_all(), msg);
1058 }
1059
1060 void ast_bridge_publish_attended_transfer_link(int is_external, enum ast_transfer_result result,
1061                 struct ast_bridge_channel_pair *transferee, struct ast_bridge_channel_pair *target,
1062                 struct ast_channel *locals[2])
1063 {
1064         RAII_VAR(struct ast_attended_transfer_message *, transfer_msg, NULL, ao2_cleanup);
1065         RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
1066         int i;
1067
1068         transfer_msg = attended_transfer_message_create(is_external, result, transferee, target);
1069         if (!transfer_msg) {
1070                 return;
1071         }
1072
1073         transfer_msg->dest_type = AST_ATTENDED_TRANSFER_DEST_LINK;
1074         for (i = 0; i < 2; ++i) {
1075                 ast_channel_lock(locals[i]);
1076                 transfer_msg->dest.links[i] = ast_channel_snapshot_create(locals[i]);
1077                 ast_channel_unlock(locals[i]);
1078                 if (!transfer_msg->dest.links[i]) {
1079                         return;
1080                 }
1081         }
1082
1083         msg = stasis_message_create(ast_attended_transfer_type(), transfer_msg);
1084         if (!msg) {
1085                 return;
1086         }
1087
1088         stasis_publish(ast_bridge_topic_all(), msg);
1089 }
1090
1091 struct ast_bridge_snapshot *ast_bridge_snapshot_get_latest(const char *uniqueid)
1092 {
1093         RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
1094         struct ast_bridge_snapshot *snapshot;
1095
1096         ast_assert(!ast_strlen_zero(uniqueid));
1097
1098         message = stasis_cache_get(ast_bridge_cache(),
1099                         ast_bridge_snapshot_type(),
1100                         uniqueid);
1101         if (!message) {
1102                 return NULL;
1103         }
1104
1105         snapshot = stasis_message_data(message);
1106         if (!snapshot) {
1107                 return NULL;
1108         }
1109         ao2_ref(snapshot, +1);
1110         return snapshot;
1111 }
1112
1113 /*! \brief snapshot ID getter for caching topic */
1114 static const char *bridge_snapshot_get_id(struct stasis_message *msg)
1115 {
1116         struct ast_bridge_snapshot *snapshot;
1117         if (stasis_message_type(msg) != ast_bridge_snapshot_type()) {
1118                 return NULL;
1119         }
1120         snapshot = stasis_message_data(msg);
1121         return snapshot->uniqueid;
1122 }
1123
1124 static void stasis_bridging_cleanup(void)
1125 {
1126         STASIS_MESSAGE_TYPE_CLEANUP(ast_bridge_snapshot_type);
1127         STASIS_MESSAGE_TYPE_CLEANUP(ast_bridge_merge_message_type);
1128         STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_entered_bridge_type);
1129         STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_left_bridge_type);
1130         STASIS_MESSAGE_TYPE_CLEANUP(ast_blind_transfer_type);
1131         STASIS_MESSAGE_TYPE_CLEANUP(ast_attended_transfer_type);
1132
1133         ao2_cleanup(bridge_cache_all);
1134         bridge_cache_all = NULL;
1135 }
1136
1137 int ast_stasis_bridging_init(void)
1138 {
1139         int res = 0;
1140
1141         ast_register_cleanup(stasis_bridging_cleanup);
1142
1143         bridge_cache_all = stasis_cp_all_create("ast_bridge_topic_all",
1144                 bridge_snapshot_get_id);
1145
1146         if (!bridge_cache_all) {
1147                 return -1;
1148         }
1149
1150         res |= STASIS_MESSAGE_TYPE_INIT(ast_bridge_snapshot_type);
1151         res |= STASIS_MESSAGE_TYPE_INIT(ast_bridge_merge_message_type);
1152         res |= STASIS_MESSAGE_TYPE_INIT(ast_channel_entered_bridge_type);
1153         res |= STASIS_MESSAGE_TYPE_INIT(ast_channel_left_bridge_type);
1154         res |= STASIS_MESSAGE_TYPE_INIT(ast_blind_transfer_type);
1155         res |= STASIS_MESSAGE_TYPE_INIT(ast_attended_transfer_type);
1156
1157         return res;
1158 }