CI: Various updates to buildAsterisk.sh
[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 #include "asterisk/astobj2.h"
33 #include "asterisk/stasis.h"
34 #include "asterisk/stasis_cache_pattern.h"
35 #include "asterisk/channel.h"
36 #include "asterisk/stasis_bridges.h"
37 #include "asterisk/stasis_channels.h"
38 #include "asterisk/bridge.h"
39 #include "asterisk/bridge_technology.h"
40
41 /* The container of channel snapshots in a bridge snapshot should always be
42    equivalent to a linked list; otherwise things (like CDRs) that depend on some
43    consistency in the ordering of channels in a bridge will break. */
44 #define SNAPSHOT_CHANNELS_BUCKETS 1
45
46 /*** DOCUMENTATION
47         <managerEvent language="en_US" name="BlindTransfer">
48                 <managerEventInstance class="EVENT_FLAG_CALL">
49                         <synopsis>Raised when a blind transfer is complete.</synopsis>
50                         <syntax>
51                                 <parameter name="Result">
52                                         <para>Indicates if the transfer was successful or if it failed.</para>
53                                         <enumlist>
54                                                 <enum name="Fail"><para>An internal error occurred.</para></enum>
55                                                 <enum name="Invalid"><para>Invalid configuration for transfer (e.g. Not bridged)</para></enum>
56                                                 <enum name="Not Permitted"><para>Bridge does not permit transfers</para></enum>
57                                                 <enum name="Success"><para>Transfer completed successfully</para></enum>
58                                         </enumlist>
59                                         <note><para>A result of <literal>Success</literal> does not necessarily mean that a target was succesfully
60                                         contacted. It means that a party was succesfully placed into the dialplan at the expected location.</para></note>
61                                 </parameter>
62                                 <channel_snapshot prefix="Transferer"/>
63                                 <channel_snapshot prefix="Transferee"/>
64                                 <bridge_snapshot/>
65                                 <parameter name="IsExternal">
66                                         <para>Indicates if the transfer was performed outside of Asterisk. For instance,
67                                         a channel protocol native transfer is external. A DTMF transfer is internal.</para>
68                                                 <enumlist>
69                                                         <enum name="Yes" />
70                                                         <enum name="No" />
71                                                 </enumlist>
72                                 </parameter>
73                                 <parameter name="Context">
74                                         <para>Destination context for the blind transfer.</para>
75                                 </parameter>
76                                 <parameter name="Extension">
77                                         <para>Destination extension for the blind transfer.</para>
78                                 </parameter>
79                         </syntax>
80                         <see-also>
81                                 <ref type="manager">BlindTransfer</ref>
82                         </see-also>
83                 </managerEventInstance>
84         </managerEvent>
85         <managerEvent language="en_US" name="AttendedTransfer">
86                 <managerEventInstance class="EVENT_FLAG_CALL">
87                         <synopsis>Raised when an attended transfer is complete.</synopsis>
88                         <syntax>
89                                 <xi:include xpointer="xpointer(docs/managerEvent[@name='BlindTransfer']/managerEventInstance/syntax/parameter[@name='Result'])" />
90                                 <channel_snapshot prefix="OrigTransferer"/>
91                                 <bridge_snapshot prefix="Orig"/>
92                                 <channel_snapshot prefix="SecondTransferer"/>
93                                 <bridge_snapshot prefix="Second"/>
94                                 <parameter name="DestType">
95                                         <para>Indicates the method by which the attended transfer completed.</para>
96                                         <enumlist>
97                                                 <enum name="Bridge"><para>The transfer was accomplished by merging two bridges into one.</para></enum>
98                                                 <enum name="App"><para>The transfer was accomplished by having a channel or bridge run a dialplan application.</para></enum>
99                                                 <enum name="Link"><para>The transfer was accomplished by linking two bridges together using a local channel pair.</para></enum>
100                                                 <enum name="Threeway"><para>The transfer was accomplished by placing all parties into a threeway call.</para></enum>
101                                                 <enum name="Fail"><para>The transfer failed.</para></enum>
102                                         </enumlist>
103                                 </parameter>
104                                 <parameter name="DestBridgeUniqueid">
105                                         <para>Indicates the surviving bridge when bridges were merged to complete the transfer</para>
106                                         <note><para>This header is only present when <replaceable>DestType</replaceable> is <literal>Bridge</literal> or <literal>Threeway</literal></para></note>
107                                 </parameter>
108                                 <parameter name="DestApp">
109                                         <para>Indicates the application that is running when the transfer completes</para>
110                                         <note><para>This header is only present when <replaceable>DestType</replaceable> is <literal>App</literal></para></note>
111                                 </parameter>
112                                 <channel_snapshot prefix="LocalOne"/>
113                                 <channel_snapshot prefix="LocalTwo"/>
114                                 <parameter name="DestTransfererChannel">
115                                         <para>The name of the surviving transferer channel when a transfer results in a threeway call</para>
116                                         <note><para>This header is only present when <replaceable>DestType</replaceable> is <literal>Threeway</literal></para></note>
117                                 </parameter>
118                                 <channel_snapshot prefix="Transferee" />
119                         </syntax>
120                         <description>
121                                 <para>The headers in this event attempt to describe all the major details of the attended transfer. The two transferer channels
122                                 and the two bridges are determined based on their chronological establishment. So consider that Alice calls Bob, and then Alice
123                                 transfers the call to Voicemail. The transferer and bridge headers would be arranged as follows:</para>
124                                 <para>  <replaceable>OrigTransfererChannel</replaceable>: Alice's channel in the bridge with Bob.</para>
125                                 <para>  <replaceable>OrigBridgeUniqueid</replaceable>: The bridge between Alice and Bob.</para>
126                                 <para>  <replaceable>SecondTransfererChannel</replaceable>: Alice's channel that called Voicemail.</para>
127                                 <para>  <replaceable>SecondBridgeUniqueid</replaceable>: Not present, since a call to Voicemail has no bridge.</para>
128                                 <para>Now consider if the order were reversed; instead of having Alice call Bob and transfer him to Voicemail, Alice instead
129                                 calls her Voicemail and transfers that to Bob. The transferer and bridge headers would be arranged as follows:</para>
130                                 <para>  <replaceable>OrigTransfererChannel</replaceable>: Alice's channel that called Voicemail.</para>
131                                 <para>  <replaceable>OrigBridgeUniqueid</replaceable>: Not present, since a call to Voicemail has no bridge.</para>
132                                 <para>  <replaceable>SecondTransfererChannel</replaceable>: Alice's channel in the bridge with Bob.</para>
133                                 <para>  <replaceable>SecondBridgeUniqueid</replaceable>: The bridge between Alice and Bob.</para>
134                         </description>
135                         <see-also>
136                                 <ref type="manager">AtxFer</ref>
137                         </see-also>
138                 </managerEventInstance>
139         </managerEvent>
140  ***/
141
142 static struct ast_json *attended_transfer_to_json(struct stasis_message *msg,
143         const struct stasis_message_sanitizer *sanitize);
144 static struct ast_manager_event_blob *attended_transfer_to_ami(struct stasis_message *message);
145 static struct ast_json *blind_transfer_to_json(struct stasis_message *msg,
146         const struct stasis_message_sanitizer *sanitize);
147 static struct ast_manager_event_blob *blind_transfer_to_ami(struct stasis_message *message);
148 static struct ast_json *ast_channel_entered_bridge_to_json(
149         struct stasis_message *msg,
150         const struct stasis_message_sanitizer *sanitize);
151 static struct ast_json *ast_channel_left_bridge_to_json(
152         struct stasis_message *msg,
153         const struct stasis_message_sanitizer *sanitize);
154 static struct ast_json *ast_bridge_merge_message_to_json(
155         struct stasis_message *msg,
156         const struct stasis_message_sanitizer *sanitize);
157
158 static struct stasis_topic *bridge_topic_all;
159 static struct stasis_topic_pool *bridge_topic_pool;
160
161 /*!
162  * @{ \brief Define bridge message types.
163  */
164 STASIS_MESSAGE_TYPE_DEFN(ast_bridge_snapshot_type);
165 STASIS_MESSAGE_TYPE_DEFN(ast_bridge_merge_message_type,
166         .to_json = ast_bridge_merge_message_to_json);
167 STASIS_MESSAGE_TYPE_DEFN(ast_channel_entered_bridge_type,
168         .to_json = ast_channel_entered_bridge_to_json);
169 STASIS_MESSAGE_TYPE_DEFN(ast_channel_left_bridge_type,
170         .to_json = ast_channel_left_bridge_to_json);
171 STASIS_MESSAGE_TYPE_DEFN(ast_blind_transfer_type,
172         .to_json = blind_transfer_to_json,
173         .to_ami = blind_transfer_to_ami);
174 STASIS_MESSAGE_TYPE_DEFN(ast_attended_transfer_type,
175         .to_json = attended_transfer_to_json,
176         .to_ami = attended_transfer_to_ami);
177 /*! @} */
178
179 struct stasis_topic *ast_bridge_topic_all(void)
180 {
181         return bridge_topic_all;
182 }
183
184 struct stasis_topic *ast_bridge_topic(struct ast_bridge *bridge)
185 {
186         if (!bridge) {
187                 return ast_bridge_topic_all();
188         }
189
190         return bridge->topic;
191 }
192
193 /*! \brief Destructor for bridge snapshots */
194 static void bridge_snapshot_dtor(void *obj)
195 {
196         struct ast_bridge_snapshot *snapshot = obj;
197         ast_string_field_free_memory(snapshot);
198         ao2_cleanup(snapshot->channels);
199         snapshot->channels = NULL;
200 }
201
202 struct ast_bridge_snapshot *ast_bridge_snapshot_create(struct ast_bridge *bridge)
203 {
204         struct ast_bridge_snapshot *snapshot;
205         struct ast_bridge_channel *bridge_channel;
206
207         if (ast_test_flag(&bridge->feature_flags, AST_BRIDGE_FLAG_INVISIBLE)) {
208                 return NULL;
209         }
210
211         snapshot = ao2_alloc_options(sizeof(*snapshot), bridge_snapshot_dtor,
212                 AO2_ALLOC_OPT_LOCK_NOLOCK);
213         if (!snapshot) {
214                 return NULL;
215         }
216
217         if (ast_string_field_init(snapshot, 128)) {
218                 ao2_ref(snapshot, -1);
219
220                 return NULL;
221         }
222
223         snapshot->channels = ast_str_container_alloc(SNAPSHOT_CHANNELS_BUCKETS);
224         if (!snapshot->channels) {
225                 ao2_ref(snapshot, -1);
226
227                 return NULL;
228         }
229
230         AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
231                 if (ast_str_container_add(snapshot->channels,
232                                 ast_channel_uniqueid(bridge_channel->chan))) {
233                         ao2_ref(snapshot, -1);
234
235                         return NULL;
236                 }
237         }
238
239         ast_string_field_set(snapshot, uniqueid, bridge->uniqueid);
240         ast_string_field_set(snapshot, technology, bridge->technology->name);
241         ast_string_field_set(snapshot, subclass, bridge->v_table->name);
242         ast_string_field_set(snapshot, creator, bridge->creator);
243         ast_string_field_set(snapshot, name, bridge->name);
244
245         snapshot->feature_flags = bridge->feature_flags;
246         snapshot->capabilities = bridge->technology->capabilities;
247         snapshot->num_channels = bridge->num_channels;
248         snapshot->num_active = bridge->num_active;
249         snapshot->video_mode = bridge->softmix.video_mode.mode;
250         if (snapshot->video_mode == AST_BRIDGE_VIDEO_MODE_SINGLE_SRC
251                 && bridge->softmix.video_mode.mode_data.single_src_data.chan_vsrc) {
252                 ast_string_field_set(snapshot, video_source_id,
253                         ast_channel_uniqueid(bridge->softmix.video_mode.mode_data.single_src_data.chan_vsrc));
254         } else if (snapshot->video_mode == AST_BRIDGE_VIDEO_MODE_TALKER_SRC
255                 && bridge->softmix.video_mode.mode_data.talker_src_data.chan_vsrc) {
256                 ast_string_field_set(snapshot, video_source_id,
257                         ast_channel_uniqueid(bridge->softmix.video_mode.mode_data.talker_src_data.chan_vsrc));
258         }
259
260         return snapshot;
261 }
262
263 static void bridge_snapshot_update_dtor(void *obj)
264 {
265         struct ast_bridge_snapshot_update *update = obj;
266
267         ast_debug(3, "Update: %p  Old: %s  New: %s\n", update,
268                 update->old_snapshot ? update->old_snapshot->uniqueid : "<none>",
269                 update->new_snapshot ? update->new_snapshot->uniqueid : "<none>");
270         ao2_cleanup(update->old_snapshot);
271         ao2_cleanup(update->new_snapshot);
272 }
273
274 static struct ast_bridge_snapshot_update *bridge_snapshot_update_create(
275         struct ast_bridge_snapshot *old, struct ast_bridge_snapshot *new)
276 {
277         struct ast_bridge_snapshot_update *update;
278
279         update = ao2_alloc_options(sizeof(*update), bridge_snapshot_update_dtor,
280                         AO2_ALLOC_OPT_LOCK_NOLOCK);
281         if (!update) {
282                 return NULL;
283         }
284         update->old_snapshot = ao2_bump(old);
285         update->new_snapshot = ao2_bump(new);
286
287         ast_debug(3, "Update: %p  Old: %s  New: %s\n", update,
288                 update->old_snapshot ? update->old_snapshot->uniqueid : "<none>",
289                 update->new_snapshot ? update->new_snapshot->uniqueid : "<none>");
290
291         return update;
292 }
293
294 int bridge_topics_init(struct ast_bridge *bridge)
295 {
296         if (ast_strlen_zero(bridge->uniqueid)) {
297                 ast_log(LOG_ERROR, "Bridge id initialization required\n");
298                 return -1;
299         }
300
301         bridge->topic = stasis_topic_pool_get_topic(bridge_topic_pool, bridge->uniqueid);
302         if (!bridge->topic) {
303                 return -1;
304         }
305
306         return 0;
307 }
308
309 void bridge_topics_destroy(struct ast_bridge *bridge)
310 {
311         struct ast_bridge_snapshot_update *update;
312         struct stasis_message *msg;
313
314         ast_assert(bridge != NULL);
315
316         if (!bridge->current_snapshot) {
317                 bridge->current_snapshot = ast_bridge_snapshot_create(bridge);
318                 if (!bridge->current_snapshot) {
319                         return;
320                 }
321         }
322
323         update = bridge_snapshot_update_create(bridge->current_snapshot, NULL);
324         if (!update) {
325                 return;
326         }
327
328         msg = stasis_message_create(ast_bridge_snapshot_type(), update);
329         ao2_ref(update, -1);
330         if (!msg) {
331                 return;
332         }
333
334         stasis_publish(ast_bridge_topic(bridge), msg);
335         ao2_ref(msg, -1);
336
337         stasis_topic_pool_delete_topic(bridge_topic_pool, stasis_topic_name(ast_bridge_topic(bridge)));
338 }
339
340 void ast_bridge_publish_state(struct ast_bridge *bridge)
341 {
342         struct ast_bridge_snapshot *new_snapshot;
343         struct ast_bridge_snapshot_update *update;
344         struct stasis_message *msg;
345
346         ast_assert(bridge != NULL);
347
348         new_snapshot = ast_bridge_snapshot_create(bridge);
349         if (!new_snapshot) {
350                 return;
351         }
352
353         update = bridge_snapshot_update_create(bridge->current_snapshot, new_snapshot);
354         /* There may not have been an old snapshot */
355         ao2_cleanup(bridge->current_snapshot);
356         bridge->current_snapshot = new_snapshot;
357         if (!update) {
358                 return;
359         }
360
361         msg = stasis_message_create(ast_bridge_snapshot_type(), update);
362         ao2_ref(update, -1);
363         if (!msg) {
364                 return;
365         }
366
367         stasis_publish(ast_bridge_topic(bridge), msg);
368         ao2_ref(msg, -1);
369 }
370
371 static void bridge_publish_state_from_blob(struct ast_bridge *bridge,
372         struct ast_bridge_blob *obj)
373 {
374         struct ast_bridge_snapshot_update *update;
375         struct stasis_message *msg;
376
377         ast_assert(obj != NULL);
378
379         update = bridge_snapshot_update_create(bridge->current_snapshot, obj->bridge);
380         ao2_cleanup(bridge->current_snapshot);
381         bridge->current_snapshot = ao2_bump(obj->bridge);
382         if (!update) {
383                 return;
384         }
385
386         msg = stasis_message_create(ast_bridge_snapshot_type(), update);
387         ao2_ref(update, -1);
388         if (!msg) {
389                 return;
390         }
391
392         stasis_publish(ast_bridge_topic(bridge), msg);
393         ao2_ref(msg, -1);
394 }
395
396 /*! \brief Destructor for bridge merge messages */
397 static void bridge_merge_message_dtor(void *obj)
398 {
399         struct ast_bridge_merge_message *msg = obj;
400
401         ao2_cleanup(msg->to);
402         msg->to = NULL;
403         ao2_cleanup(msg->from);
404         msg->from = NULL;
405 }
406
407 /*! \brief Bridge merge message creation helper */
408 static struct ast_bridge_merge_message *bridge_merge_message_create(struct ast_bridge *to, struct ast_bridge *from)
409 {
410         struct ast_bridge_merge_message *msg;
411
412         msg = ao2_alloc(sizeof(*msg), bridge_merge_message_dtor);
413         if (!msg) {
414                 return NULL;
415         }
416
417         msg->to = ast_bridge_snapshot_create(to);
418         msg->from = ast_bridge_snapshot_create(from);
419         if (!msg->to || !msg->from) {
420                 ao2_ref(msg, -1);
421
422                 return NULL;
423         }
424
425         return msg;
426 }
427
428 static struct ast_json *ast_bridge_merge_message_to_json(
429         struct stasis_message *msg,
430         const struct stasis_message_sanitizer *sanitize)
431 {
432         struct ast_bridge_merge_message *merge = stasis_message_data(msg);
433         struct ast_json *json_bridge_to = ast_bridge_snapshot_to_json(merge->to, sanitize);
434         struct ast_json *json_bridge_from = ast_bridge_snapshot_to_json(merge->from, sanitize);
435
436         if (!json_bridge_to || !json_bridge_from) {
437                 ast_json_unref(json_bridge_to);
438                 ast_json_unref(json_bridge_from);
439
440                 return NULL;
441         }
442
443         return ast_json_pack("{s: s, s: o, s: o, s: o}",
444                 "type", "BridgeMerged",
445                 "timestamp", ast_json_timeval(*stasis_message_timestamp(msg), NULL),
446                 "bridge", json_bridge_to,
447                 "bridge_from", json_bridge_from);
448 }
449
450 void ast_bridge_publish_merge(struct ast_bridge *to, struct ast_bridge *from)
451 {
452         struct ast_bridge_merge_message *merge_msg;
453         struct stasis_message *msg;
454
455         if (!ast_bridge_merge_message_type()) {
456                 return;
457         }
458
459         ast_assert(to != NULL);
460         ast_assert(from != NULL);
461         ast_assert(ast_test_flag(&to->feature_flags, AST_BRIDGE_FLAG_INVISIBLE) == 0);
462         ast_assert(ast_test_flag(&from->feature_flags, AST_BRIDGE_FLAG_INVISIBLE) == 0);
463
464         merge_msg = bridge_merge_message_create(to, from);
465         if (!merge_msg) {
466                 return;
467         }
468
469         msg = stasis_message_create(ast_bridge_merge_message_type(), merge_msg);
470         ao2_ref(merge_msg, -1);
471         if (!msg) {
472                 return;
473         }
474
475         stasis_publish(ast_bridge_topic_all(), msg);
476         ao2_ref(msg, -1);
477 }
478
479 static void bridge_blob_dtor(void *obj)
480 {
481         struct ast_bridge_blob *event = obj;
482         ao2_cleanup(event->bridge);
483         event->bridge = NULL;
484         ao2_cleanup(event->channel);
485         event->channel = NULL;
486         ast_json_unref(event->blob);
487         event->blob = NULL;
488 }
489
490 struct stasis_message *ast_bridge_blob_create(
491         struct stasis_message_type *message_type,
492         struct ast_bridge *bridge,
493         struct ast_channel *chan,
494         struct ast_json *blob)
495 {
496         struct ast_bridge_blob *obj;
497         struct stasis_message *msg;
498
499         if (!message_type) {
500                 return NULL;
501         }
502
503         obj = ao2_alloc(sizeof(*obj), bridge_blob_dtor);
504         if (!obj) {
505                 return NULL;
506         }
507
508         if (bridge) {
509                 obj->bridge = ast_bridge_snapshot_create(bridge);
510                 if (obj->bridge == NULL) {
511                         ao2_ref(obj, -1);
512
513                         return NULL;
514                 }
515         }
516
517         if (chan) {
518                 obj->channel = ast_channel_snapshot_get_latest(ast_channel_uniqueid(chan));
519                 if (obj->channel == NULL) {
520                         ao2_ref(obj, -1);
521
522                         return NULL;
523                 }
524         }
525
526         if (blob) {
527                 obj->blob = ast_json_ref(blob);
528         }
529
530         msg = stasis_message_create(message_type, obj);
531         ao2_ref(obj, -1);
532
533         return msg;
534 }
535
536 void ast_bridge_publish_enter(struct ast_bridge *bridge, struct ast_channel *chan,
537                 struct ast_channel *swap)
538 {
539         struct stasis_message *msg;
540         struct ast_json *blob = NULL;
541
542         if (ast_test_flag(&bridge->feature_flags, AST_BRIDGE_FLAG_INVISIBLE)) {
543                 return;
544         }
545
546         if (swap) {
547                 blob = ast_json_pack("{s: s}", "swap", ast_channel_uniqueid(swap));
548                 if (!blob) {
549                         return;
550                 }
551         }
552
553         msg = ast_bridge_blob_create(ast_channel_entered_bridge_type(), bridge, chan, blob);
554         ast_json_unref(blob);
555         if (!msg) {
556                 return;
557         }
558
559         /* enter blob first, then state */
560         stasis_publish(ast_bridge_topic(bridge), msg);
561         bridge_publish_state_from_blob(bridge, stasis_message_data(msg));
562         ao2_ref(msg, -1);
563 }
564
565 void ast_bridge_publish_leave(struct ast_bridge *bridge, struct ast_channel *chan)
566 {
567         struct stasis_message *msg;
568
569         if (ast_test_flag(&bridge->feature_flags, AST_BRIDGE_FLAG_INVISIBLE)) {
570                 return;
571         }
572         msg = ast_bridge_blob_create(ast_channel_left_bridge_type(), bridge, chan, NULL);
573         if (!msg) {
574                 return;
575         }
576
577         /* state first, then leave blob (opposite of enter, preserves nesting of events) */
578         bridge_publish_state_from_blob(bridge, stasis_message_data(msg));
579         stasis_publish(ast_bridge_topic(bridge), msg);
580         ao2_ref(msg, -1);
581 }
582
583 static struct ast_json *simple_bridge_channel_event(
584         const char *type,
585         struct ast_bridge_snapshot *bridge_snapshot,
586         struct ast_channel_snapshot *channel_snapshot,
587         const struct timeval *tv,
588         const struct stasis_message_sanitizer *sanitize)
589 {
590         struct ast_json *json_bridge = ast_bridge_snapshot_to_json(bridge_snapshot, sanitize);
591         struct ast_json *json_channel = ast_channel_snapshot_to_json(channel_snapshot, sanitize);
592
593         if (!json_bridge || !json_channel) {
594                 ast_json_unref(json_bridge);
595                 ast_json_unref(json_channel);
596
597                 return NULL;
598         }
599
600         return ast_json_pack("{s: s, s: o, s: o, s: o}",
601                 "type", type,
602                 "timestamp", ast_json_timeval(*tv, NULL),
603                 "bridge", json_bridge,
604                 "channel", json_channel);
605 }
606
607 struct ast_json *ast_channel_entered_bridge_to_json(
608         struct stasis_message *msg,
609         const struct stasis_message_sanitizer *sanitize)
610 {
611         struct ast_bridge_blob *obj = stasis_message_data(msg);
612
613         return simple_bridge_channel_event("ChannelEnteredBridge", obj->bridge,
614                 obj->channel, stasis_message_timestamp(msg), sanitize);
615 }
616
617 struct ast_json *ast_channel_left_bridge_to_json(
618         struct stasis_message *msg,
619         const struct stasis_message_sanitizer *sanitize)
620 {
621         struct ast_bridge_blob *obj = stasis_message_data(msg);
622
623         return simple_bridge_channel_event("ChannelLeftBridge", obj->bridge,
624                 obj->channel, stasis_message_timestamp(msg), sanitize);
625 }
626
627 static struct ast_json *container_to_json_array(struct ao2_container *items,
628         const struct stasis_message_sanitizer *sanitize)
629 {
630         struct ast_json *json_items = ast_json_array_create();
631         char *item;
632         struct ao2_iterator it;
633
634         if (!json_items) {
635                 return NULL;
636         }
637
638         for (it = ao2_iterator_init(items, 0);
639                 (item = ao2_iterator_next(&it)); ao2_cleanup(item)) {
640                 if (sanitize && sanitize->channel_id && sanitize->channel_id(item)) {
641                         continue;
642                 }
643
644                 if (ast_json_array_append(json_items, ast_json_string_create(item))) {
645                         ao2_cleanup(item);
646                         ao2_iterator_destroy(&it);
647                         ast_json_unref(json_items);
648
649                         return NULL;
650                 }
651         }
652         ao2_iterator_destroy(&it);
653
654         return json_items;
655 }
656
657 static const char *capability2str(uint32_t capabilities)
658 {
659         if (capabilities & AST_BRIDGE_CAPABILITY_HOLDING) {
660                 return "holding";
661         } else {
662                 return "mixing";
663         }
664 }
665
666 struct ast_json *ast_bridge_snapshot_to_json(
667         const struct ast_bridge_snapshot *snapshot,
668         const struct stasis_message_sanitizer *sanitize)
669 {
670         struct ast_json *json_bridge;
671         struct ast_json *json_channels;
672
673         if (snapshot == NULL) {
674                 return NULL;
675         }
676
677         json_channels = container_to_json_array(snapshot->channels, sanitize);
678         if (!json_channels) {
679                 return NULL;
680         }
681
682         json_bridge = ast_json_pack("{s: s, s: s, s: s, s: s, s: s, s: s, s: o, s: s}",
683                 "id", snapshot->uniqueid,
684                 "technology", snapshot->technology,
685                 "bridge_type", capability2str(snapshot->capabilities),
686                 "bridge_class", snapshot->subclass,
687                 "creator", snapshot->creator,
688                 "name", snapshot->name,
689                 "channels", json_channels,
690                 "video_mode", ast_bridge_video_mode_to_string(snapshot->video_mode));
691         if (!json_bridge) {
692                 return NULL;
693         }
694
695         if (snapshot->video_mode != AST_BRIDGE_VIDEO_MODE_NONE
696                 && !ast_strlen_zero(snapshot->video_source_id)) {
697                 ast_json_object_set(json_bridge, "video_source_id",
698                         ast_json_string_create(snapshot->video_source_id));
699         }
700
701         return json_bridge;
702 }
703
704 /*!
705  * \internal
706  * \brief Allocate the fields of an \ref ast_bridge_channel_snapshot_pair.
707  *
708  * \param pair A bridge and channel to get snapshots of
709  * \param[out] snapshot_pair An allocated snapshot pair.
710  * \retval 0 Success
711  * \retval non-zero Failure
712  */
713 static int bridge_channel_snapshot_pair_init(struct ast_channel *channel, struct ast_bridge *bridge,
714                 struct ast_bridge_channel_snapshot_pair *snapshot_pair)
715 {
716         if (bridge) {
717                 ast_bridge_lock(bridge);
718                 snapshot_pair->bridge_snapshot = ast_bridge_snapshot_create(bridge);
719                 ast_bridge_unlock(bridge);
720                 if (!snapshot_pair->bridge_snapshot) {
721                         return -1;
722                 }
723         }
724
725         snapshot_pair->channel_snapshot = ast_channel_snapshot_get_latest(ast_channel_uniqueid(channel));
726         if (!snapshot_pair->channel_snapshot) {
727                 return -1;
728         }
729
730         return 0;
731 }
732
733 /*!
734  * \internal
735  * \brief Free the fields of an \ref ast_bridge_channel_snapshot_pair.
736  *
737  * \param pair The snapshot pair whose fields are to be cleaned up
738  */
739 static void bridge_channel_snapshot_pair_cleanup(struct ast_bridge_channel_snapshot_pair *pair)
740 {
741         ao2_cleanup(pair->bridge_snapshot);
742         ao2_cleanup(pair->channel_snapshot);
743 }
744
745 static const char *result_strs[] = {
746         [AST_BRIDGE_TRANSFER_FAIL] = "Fail",
747         [AST_BRIDGE_TRANSFER_INVALID] = "Invalid",
748         [AST_BRIDGE_TRANSFER_NOT_PERMITTED] = "Not Permitted",
749         [AST_BRIDGE_TRANSFER_SUCCESS] = "Success",
750 };
751
752 static struct ast_json *blind_transfer_to_json(struct stasis_message *msg,
753         const struct stasis_message_sanitizer *sanitize)
754 {
755         struct ast_blind_transfer_message *transfer_msg = stasis_message_data(msg);
756         struct ast_json *json_transferer;
757         struct ast_json *json_transferee = NULL;
758         struct ast_json *out;
759         struct ast_json *json_replace = NULL;
760         const struct timeval *tv = stasis_message_timestamp(msg);
761
762         json_transferer = ast_channel_snapshot_to_json(transfer_msg->transferer, sanitize);
763         if (!json_transferer) {
764                 return NULL;
765         }
766
767         if (transfer_msg->transferee) {
768                 json_transferee = ast_channel_snapshot_to_json(transfer_msg->transferee, sanitize);
769                 if (!json_transferee) {
770                         ast_json_unref(json_transferer);
771                         return NULL;
772                 }
773         }
774
775         if (transfer_msg->replace_channel) {
776                 json_replace = ast_channel_snapshot_to_json(transfer_msg->replace_channel, sanitize);
777                 if (!json_replace) {
778                         ast_json_unref(json_transferee);
779                         ast_json_unref(json_transferer);
780                         return NULL;
781                 }
782         }
783
784         out = ast_json_pack("{s: s, s: o, s: o, s: s, s: s, s: s, s: o}",
785                 "type", "BridgeBlindTransfer",
786                 "timestamp", ast_json_timeval(*tv, NULL),
787                 "channel", json_transferer,
788                 "exten", transfer_msg->exten,
789                 "context", transfer_msg->context,
790                 "result", result_strs[transfer_msg->result],
791                 "is_external", ast_json_boolean(transfer_msg->is_external));
792
793         if (!out) {
794                 ast_json_unref(json_transferee);
795                 ast_json_unref(json_replace);
796                 return NULL;
797         }
798
799         if (json_transferee && ast_json_object_set(out, "transferee", json_transferee)) {
800                 ast_json_unref(out);
801                 ast_json_unref(json_replace);
802                 return NULL;
803         }
804
805         if (json_replace && ast_json_object_set(out, "replace_channel", json_replace)) {
806                 ast_json_unref(out);
807                 return NULL;
808         }
809
810         if (transfer_msg->bridge) {
811                 struct ast_json *json_bridge = ast_bridge_snapshot_to_json(
812                                 transfer_msg->bridge, sanitize);
813
814                 if (!json_bridge || ast_json_object_set(out, "bridge", json_bridge)) {
815                         ast_json_unref(out);
816                         return NULL;
817                 }
818         }
819
820         return out;
821 }
822
823 static struct ast_manager_event_blob *blind_transfer_to_ami(struct stasis_message *msg)
824 {
825         RAII_VAR(struct ast_str *, transferer_state, NULL, ast_free_ptr);
826         RAII_VAR(struct ast_str *, bridge_state, NULL, ast_free_ptr);
827         RAII_VAR(struct ast_str *, transferee_state, NULL, ast_free_ptr);
828         struct ast_blind_transfer_message *transfer_msg = stasis_message_data(msg);
829
830         if (!transfer_msg) {
831                 return NULL;
832         }
833
834         transferer_state = ast_manager_build_channel_state_string_prefix(
835                         transfer_msg->transferer, "Transferer");
836         if (!transferer_state) {
837                 return NULL;
838         }
839
840         if (transfer_msg->bridge) {
841                 bridge_state = ast_manager_build_bridge_state_string(transfer_msg->bridge);
842                 if (!bridge_state) {
843                         return NULL;
844                 }
845         }
846
847         if (transfer_msg->transferee) {
848                 transferee_state = ast_manager_build_channel_state_string_prefix(
849                                 transfer_msg->transferee, "Transferee");
850                 if (!transferee_state) {
851                         return NULL;
852                 }
853         }
854
855         return ast_manager_event_blob_create(EVENT_FLAG_CALL, "BlindTransfer",
856                         "Result: %s\r\n"
857                         "%s"
858                         "%s"
859                         "%s"
860                         "IsExternal: %s\r\n"
861                         "Context: %s\r\n"
862                         "Extension: %s\r\n",
863                         result_strs[transfer_msg->result],
864                         ast_str_buffer(transferer_state),
865                         transferee_state ? ast_str_buffer(transferee_state) : "",
866                         bridge_state ? ast_str_buffer(bridge_state) : "",
867                         transfer_msg->is_external ? "Yes" : "No",
868                         transfer_msg->context,
869                         transfer_msg->exten);
870 }
871
872 static void blind_transfer_dtor(void *obj)
873 {
874         struct ast_blind_transfer_message *msg = obj;
875
876         ao2_cleanup(msg->transferer);
877         ao2_cleanup(msg->bridge);
878         ao2_cleanup(msg->transferee);
879         ao2_cleanup(msg->replace_channel);
880 }
881
882 struct ast_blind_transfer_message *ast_blind_transfer_message_create(int is_external,
883                 struct ast_channel *transferer, const char *exten, const char *context)
884 {
885         struct ast_blind_transfer_message *msg;
886
887         msg = ao2_alloc(sizeof(*msg), blind_transfer_dtor);
888         if (!msg) {
889                 return NULL;
890         }
891
892         msg->transferer = ast_channel_snapshot_get_latest(ast_channel_uniqueid(transferer));
893         if (!msg->transferer) {
894                 ao2_cleanup(msg);
895                 return NULL;
896         }
897
898         msg->is_external = is_external;
899         ast_copy_string(msg->context, context, sizeof(msg->context));
900         ast_copy_string(msg->exten, exten, sizeof(msg->exten));
901
902         return msg;
903 }
904
905
906 void ast_bridge_publish_blind_transfer(struct ast_blind_transfer_message *transfer_message)
907 {
908         struct stasis_message *stasis;
909
910         stasis = stasis_message_create(ast_blind_transfer_type(), transfer_message);
911         if (!stasis) {
912                 return;
913         }
914
915         stasis_publish(ast_bridge_topic_all(), stasis);
916
917         ao2_cleanup(stasis);
918 }
919
920 static struct ast_json *attended_transfer_to_json(struct stasis_message *msg,
921         const struct stasis_message_sanitizer *sanitize)
922 {
923         struct ast_attended_transfer_message *transfer_msg = stasis_message_data(msg);
924         RAII_VAR(struct ast_json *, out, NULL, ast_json_unref);
925         struct ast_json *json_transferer1, *json_transferer2, *json_bridge, *json_channel;
926         struct ast_json *json_transferee = NULL, *json_target = NULL;
927         const struct timeval *tv = stasis_message_timestamp(msg);
928         int res = 0;
929
930         json_transferer1 = ast_channel_snapshot_to_json(transfer_msg->to_transferee.channel_snapshot, sanitize);
931         if (!json_transferer1) {
932                 return NULL;
933         }
934
935         json_transferer2 = ast_channel_snapshot_to_json(transfer_msg->to_transfer_target.channel_snapshot, sanitize);
936         if (!json_transferer2) {
937                 ast_json_unref(json_transferer1);
938                 return NULL;
939         }
940
941         if (transfer_msg->transferee) {
942                 json_transferee = ast_channel_snapshot_to_json(transfer_msg->transferee, sanitize);
943                 if (!json_transferee) {
944                         ast_json_unref(json_transferer2);
945                         ast_json_unref(json_transferer1);
946                         return NULL;
947                 }
948         }
949
950         if (transfer_msg->target) {
951                 json_target = ast_channel_snapshot_to_json(transfer_msg->target, sanitize);
952                 if (!json_target) {
953                         ast_json_unref(json_transferee);
954                         ast_json_unref(json_transferer2);
955                         ast_json_unref(json_transferer1);
956                         return NULL;
957                 }
958         }
959
960         out = ast_json_pack("{s: s, s: o, s: o, s: o, s: s, s: o}",
961                 "type", "BridgeAttendedTransfer",
962                 "timestamp", ast_json_timeval(*tv, NULL),
963                 "transferer_first_leg", json_transferer1,
964                 "transferer_second_leg", json_transferer2,
965                 "result", result_strs[transfer_msg->result],
966                 "is_external", ast_json_boolean(transfer_msg->is_external));
967         if (!out) {
968                 ast_json_unref(json_target);
969                 ast_json_unref(json_transferee);
970                 return NULL;
971         }
972         if (json_transferee && ast_json_object_set(out, "transferee", json_transferee)) {
973                 ast_json_unref(json_target);
974                 return NULL;
975         }
976         if (json_target && ast_json_object_set(out, "transfer_target", json_target)) {
977                 return NULL;
978         }
979
980         if (transfer_msg->to_transferee.bridge_snapshot) {
981                 json_bridge = ast_bridge_snapshot_to_json(transfer_msg->to_transferee.bridge_snapshot, sanitize);
982
983                 if (!json_bridge) {
984                         return NULL;
985                 }
986
987                 res |= ast_json_object_set(out, "transferer_first_leg_bridge", json_bridge);
988         }
989
990         if (transfer_msg->to_transfer_target.bridge_snapshot) {
991                 json_bridge = ast_bridge_snapshot_to_json(transfer_msg->to_transfer_target.bridge_snapshot, sanitize);
992
993                 if (!json_bridge) {
994                         return NULL;
995                 }
996
997                 res |= ast_json_object_set(out, "transferer_second_leg_bridge", json_bridge);
998         }
999
1000         switch (transfer_msg->dest_type) {
1001         case AST_ATTENDED_TRANSFER_DEST_BRIDGE_MERGE:
1002                 res |= ast_json_object_set(out, "destination_type", ast_json_string_create("bridge"));
1003                 res |= ast_json_object_set(out, "destination_bridge", ast_json_string_create(transfer_msg->dest.bridge));
1004                 break;
1005         case AST_ATTENDED_TRANSFER_DEST_LOCAL_APP:
1006                 res |= ast_json_object_set(out, "replace_channel", ast_channel_snapshot_to_json(transfer_msg->replace_channel, sanitize));
1007                 /* fallthrough */
1008         case AST_ATTENDED_TRANSFER_DEST_APP:
1009                 res |= ast_json_object_set(out, "destination_type", ast_json_string_create("application"));
1010                 res |= ast_json_object_set(out, "destination_application", ast_json_string_create(transfer_msg->dest.app));
1011                 break;
1012         case AST_ATTENDED_TRANSFER_DEST_LINK:
1013                 res |= ast_json_object_set(out, "destination_type", ast_json_string_create("link"));
1014
1015                 json_channel = ast_channel_snapshot_to_json(transfer_msg->dest.links[0], sanitize);
1016                 if (!json_channel) {
1017                         return NULL;
1018                 }
1019                 res |= ast_json_object_set(out, "destination_link_first_leg", json_channel);
1020
1021                 json_channel = ast_channel_snapshot_to_json(transfer_msg->dest.links[1], sanitize);
1022                 if (!json_channel) {
1023                         return NULL;
1024                 }
1025                 res |= ast_json_object_set(out, "destination_link_second_leg", json_channel);
1026
1027                 break;
1028         case AST_ATTENDED_TRANSFER_DEST_THREEWAY:
1029                 res |= ast_json_object_set(out, "destination_type", ast_json_string_create("threeway"));
1030
1031                 json_channel = ast_channel_snapshot_to_json(transfer_msg->dest.threeway.channel_snapshot, sanitize);
1032                 if (!json_channel) {
1033                         return NULL;
1034                 }
1035                 res |= ast_json_object_set(out, "destination_threeway_channel", json_channel);
1036
1037                 json_bridge = ast_bridge_snapshot_to_json(transfer_msg->dest.threeway.bridge_snapshot, sanitize);
1038                 if (!json_bridge) {
1039                         return NULL;
1040                 }
1041                 res |= ast_json_object_set(out, "destination_threeway_bridge", json_bridge);
1042
1043                 break;
1044         case AST_ATTENDED_TRANSFER_DEST_FAIL:
1045                 res |= ast_json_object_set(out, "destination_type", ast_json_string_create("fail"));
1046                 break;
1047         }
1048
1049         if (res) {
1050                 return NULL;
1051         }
1052
1053         return ast_json_ref(out);
1054 }
1055
1056 static struct ast_manager_event_blob *attended_transfer_to_ami(struct stasis_message *msg)
1057 {
1058         RAII_VAR(struct ast_str *, variable_data, ast_str_create(64), ast_free_ptr);
1059         RAII_VAR(struct ast_str *, transferer1_state, NULL, ast_free_ptr);
1060         RAII_VAR(struct ast_str *, bridge1_state, NULL, ast_free_ptr);
1061         RAII_VAR(struct ast_str *, transferer2_state, NULL, ast_free_ptr);
1062         RAII_VAR(struct ast_str *, bridge2_state, NULL, ast_free_ptr);
1063         RAII_VAR(struct ast_str *, local1_state, NULL, ast_free_ptr);
1064         RAII_VAR(struct ast_str *, local2_state, NULL, ast_free_ptr);
1065         RAII_VAR(struct ast_str *, transferee_state, NULL, ast_free_ptr);
1066         RAII_VAR(struct ast_str *, target_state, NULL, ast_free_ptr);
1067         struct ast_attended_transfer_message *transfer_msg = stasis_message_data(msg);
1068
1069         if (!variable_data) {
1070                 return NULL;
1071         }
1072
1073         transferer1_state = ast_manager_build_channel_state_string_prefix(transfer_msg->to_transferee.channel_snapshot, "OrigTransferer");
1074         transferer2_state = ast_manager_build_channel_state_string_prefix(transfer_msg->to_transfer_target.channel_snapshot, "SecondTransferer");
1075         if (!transferer1_state || !transferer2_state) {
1076                 return NULL;
1077         }
1078         if (transfer_msg->transferee) {
1079                 transferee_state = ast_manager_build_channel_state_string_prefix(transfer_msg->transferee, "Transferee");
1080                 if (!transferee_state) {
1081                         return NULL;
1082                 }
1083         }
1084
1085         if (transfer_msg->target) {
1086                 target_state = ast_manager_build_channel_state_string_prefix(transfer_msg->target, "TransferTarget");
1087                 if (!target_state) {
1088                         return NULL;
1089                 }
1090         }
1091
1092         if (transfer_msg->to_transferee.bridge_snapshot) {
1093                 bridge1_state = ast_manager_build_bridge_state_string_prefix(
1094                         transfer_msg->to_transferee.bridge_snapshot, "Orig");
1095                 if (!bridge1_state) {
1096                         return NULL;
1097                 }
1098         }
1099
1100         if (transfer_msg->to_transfer_target.bridge_snapshot) {
1101                 bridge2_state = ast_manager_build_bridge_state_string_prefix(
1102                         transfer_msg->to_transfer_target.bridge_snapshot, "Second");
1103                 if (!bridge2_state) {
1104                         return NULL;
1105                 }
1106         }
1107
1108         switch (transfer_msg->dest_type) {
1109         case AST_ATTENDED_TRANSFER_DEST_BRIDGE_MERGE:
1110                 ast_str_append(&variable_data, 0, "DestType: Bridge\r\n");
1111                 ast_str_append(&variable_data, 0, "DestBridgeUniqueid: %s\r\n", transfer_msg->dest.bridge);
1112                 break;
1113         case AST_ATTENDED_TRANSFER_DEST_APP:
1114         case AST_ATTENDED_TRANSFER_DEST_LOCAL_APP:
1115                 ast_str_append(&variable_data, 0, "DestType: App\r\n");
1116                 ast_str_append(&variable_data, 0, "DestApp: %s\r\n", transfer_msg->dest.app);
1117                 break;
1118         case AST_ATTENDED_TRANSFER_DEST_LINK:
1119                 local1_state = ast_manager_build_channel_state_string_prefix(transfer_msg->dest.links[0], "LocalOne");
1120                 local2_state = ast_manager_build_channel_state_string_prefix(transfer_msg->dest.links[1], "LocalTwo");
1121                 if (!local1_state || !local2_state) {
1122                         return NULL;
1123                 }
1124                 ast_str_append(&variable_data, 0, "DestType: Link\r\n");
1125                 ast_str_append(&variable_data, 0, "%s", ast_str_buffer(local1_state));
1126                 ast_str_append(&variable_data, 0, "%s", ast_str_buffer(local2_state));
1127                 break;
1128         case AST_ATTENDED_TRANSFER_DEST_THREEWAY:
1129                 ast_str_append(&variable_data, 0, "DestType: Threeway\r\n");
1130                 ast_str_append(&variable_data, 0, "DestBridgeUniqueid: %s\r\n", transfer_msg->dest.threeway.bridge_snapshot->uniqueid);
1131                 ast_str_append(&variable_data, 0, "DestTransfererChannel: %s\r\n", transfer_msg->dest.threeway.channel_snapshot->base->name);
1132                 break;
1133         case AST_ATTENDED_TRANSFER_DEST_FAIL:
1134                 ast_str_append(&variable_data, 0, "DestType: Fail\r\n");
1135                 break;
1136         }
1137
1138         return ast_manager_event_blob_create(EVENT_FLAG_CALL, "AttendedTransfer",
1139                         "Result: %s\r\n"
1140                         "%s"
1141                         "%s"
1142                         "%s"
1143                         "%s"
1144                         "%s"
1145                         "%s"
1146                         "IsExternal: %s\r\n"
1147                         "%s",
1148                         result_strs[transfer_msg->result],
1149                         ast_str_buffer(transferer1_state),
1150                         bridge1_state ? ast_str_buffer(bridge1_state) : "",
1151                         ast_str_buffer(transferer2_state),
1152                         bridge2_state ? ast_str_buffer(bridge2_state) : "",
1153                         transferee_state ? ast_str_buffer(transferee_state) : "",
1154                         target_state ? ast_str_buffer(target_state) : "",
1155                         transfer_msg->is_external ? "Yes" : "No",
1156                         ast_str_buffer(variable_data));
1157 }
1158
1159 static void attended_transfer_dtor(void *obj)
1160 {
1161         struct ast_attended_transfer_message *msg = obj;
1162         int i;
1163
1164         bridge_channel_snapshot_pair_cleanup(&msg->to_transferee);
1165         bridge_channel_snapshot_pair_cleanup(&msg->to_transfer_target);
1166         ao2_cleanup(msg->replace_channel);
1167         ao2_cleanup(msg->transferee);
1168         ao2_cleanup(msg->target);
1169
1170         if (msg->dest_type != AST_ATTENDED_TRANSFER_DEST_LINK) {
1171                 return;
1172         }
1173
1174         for (i = 0; i < ARRAY_LEN(msg->dest.links); ++i) {
1175                 ao2_cleanup(msg->dest.links[i]);
1176         }
1177 }
1178
1179 struct ast_attended_transfer_message *ast_attended_transfer_message_create(int is_external,
1180                 struct ast_channel *to_transferee, struct ast_bridge *transferee_bridge,
1181                 struct ast_channel *to_transfer_target, struct ast_bridge *target_bridge,
1182                 struct ast_channel *transferee, struct ast_channel *transfer_target)
1183 {
1184         struct ast_attended_transfer_message *transfer_msg;
1185
1186         transfer_msg = ao2_alloc(sizeof(*transfer_msg), attended_transfer_dtor);
1187         if (!transfer_msg) {
1188                 return NULL;
1189         }
1190
1191         if (bridge_channel_snapshot_pair_init(to_transferee, transferee_bridge, &transfer_msg->to_transferee) ||
1192                         bridge_channel_snapshot_pair_init(to_transfer_target, target_bridge, &transfer_msg->to_transfer_target)) {
1193                 ao2_cleanup(transfer_msg);
1194                 return NULL;
1195         }
1196
1197         if (transferee) {
1198                 transfer_msg->transferee = ast_channel_snapshot_get_latest(ast_channel_uniqueid(transferee));
1199                 if (!transfer_msg->transferee) {
1200                         ao2_cleanup(transfer_msg);
1201                         return NULL;
1202                 }
1203         } else if (transferee_bridge) {
1204                 transferee = ast_bridge_peer(transferee_bridge, to_transferee);
1205                 if (transferee) {
1206                         transfer_msg->transferee = ast_channel_snapshot_get_latest(ast_channel_uniqueid(transferee));
1207                         ao2_cleanup(transferee);
1208                         if (!transfer_msg->transferee) {
1209                                 ao2_cleanup(transfer_msg);
1210                                 return NULL;
1211                         }
1212                 }
1213         }
1214
1215         if (transfer_target) {
1216                 transfer_msg->target = ast_channel_snapshot_get_latest(ast_channel_uniqueid(transfer_target));
1217                 if (!transfer_msg->target) {
1218                         ao2_cleanup(transfer_msg);
1219                         return NULL;
1220                 }
1221         } else if (target_bridge) {
1222                 transfer_target = ast_bridge_peer(target_bridge, to_transfer_target);
1223                 if (transfer_target) {
1224                         transfer_msg->target = ast_channel_snapshot_get_latest(ast_channel_uniqueid(transfer_target));
1225                         ao2_cleanup(transfer_target);
1226                         if (!transfer_msg->target) {
1227                                 ao2_cleanup(transfer_msg);
1228                                 return NULL;
1229                         }
1230                 }
1231         }
1232
1233         return transfer_msg;
1234 }
1235
1236 int ast_attended_transfer_message_add_merge(struct ast_attended_transfer_message *transfer_msg,
1237                 struct ast_bridge *final_bridge)
1238 {
1239         transfer_msg->dest_type = AST_ATTENDED_TRANSFER_DEST_BRIDGE_MERGE;
1240         ast_copy_string(transfer_msg->dest.bridge, final_bridge->uniqueid,
1241                         sizeof(transfer_msg->dest.bridge));
1242
1243         return 0;
1244 }
1245
1246 int ast_attended_transfer_message_add_threeway(struct ast_attended_transfer_message *transfer_msg,
1247                 struct ast_channel *survivor_channel, struct ast_bridge *survivor_bridge)
1248 {
1249         transfer_msg->dest_type = AST_ATTENDED_TRANSFER_DEST_THREEWAY;
1250
1251         if (!strcmp(ast_channel_uniqueid(survivor_channel), transfer_msg->to_transferee.channel_snapshot->base->uniqueid)) {
1252                 transfer_msg->dest.threeway.channel_snapshot = transfer_msg->to_transferee.channel_snapshot;
1253         } else {
1254                 transfer_msg->dest.threeway.channel_snapshot = transfer_msg->to_transfer_target.channel_snapshot;
1255         }
1256
1257         if (!strcmp(survivor_bridge->uniqueid, transfer_msg->to_transferee.bridge_snapshot->uniqueid)) {
1258                 transfer_msg->dest.threeway.bridge_snapshot = transfer_msg->to_transferee.bridge_snapshot;
1259         } else {
1260                 transfer_msg->dest.threeway.bridge_snapshot = transfer_msg->to_transfer_target.bridge_snapshot;
1261         }
1262
1263         return 0;
1264 }
1265
1266 int ast_attended_transfer_message_add_app(struct ast_attended_transfer_message *transfer_msg,
1267                 const char *app, struct ast_channel *replace_channel)
1268 {
1269         transfer_msg->dest_type = replace_channel ? AST_ATTENDED_TRANSFER_DEST_LOCAL_APP : AST_ATTENDED_TRANSFER_DEST_APP;
1270
1271         if (replace_channel) {
1272                 transfer_msg->replace_channel = ast_channel_snapshot_get_latest(ast_channel_uniqueid(replace_channel));
1273                 if (!transfer_msg->replace_channel) {
1274                         return -1;
1275                 }
1276         }
1277
1278         ast_copy_string(transfer_msg->dest.app, app, sizeof(transfer_msg->dest.app));
1279
1280         return 0;
1281 }
1282
1283 int ast_attended_transfer_message_add_link(struct ast_attended_transfer_message *transfer_msg,
1284                 struct ast_channel *locals[2])
1285 {
1286         int i;
1287
1288         transfer_msg->dest_type = AST_ATTENDED_TRANSFER_DEST_LINK;
1289         for (i = 0; i < 2; ++i) {
1290                 transfer_msg->dest.links[i] = ast_channel_snapshot_get_latest(ast_channel_uniqueid(locals[i]));
1291                 if (!transfer_msg->dest.links[i]) {
1292                         return -1;
1293                 }
1294         }
1295
1296         return 0;
1297 }
1298
1299 void ast_bridge_publish_attended_transfer(struct ast_attended_transfer_message *transfer_msg)
1300 {
1301         struct stasis_message *msg;
1302
1303         msg = stasis_message_create(ast_attended_transfer_type(), transfer_msg);
1304         if (!msg) {
1305                 return;
1306         }
1307
1308         stasis_publish(ast_bridge_topic_all(), msg);
1309         ao2_ref(msg, -1);
1310 }
1311
1312 struct ast_bridge_snapshot *ast_bridge_get_snapshot_by_uniqueid(const char *uniqueid)
1313 {
1314         struct ast_bridge *bridge;
1315         struct ast_bridge_snapshot *snapshot;
1316
1317         ast_assert(!ast_strlen_zero(uniqueid));
1318
1319         bridge = ast_bridge_find_by_id(uniqueid);
1320         if (!bridge) {
1321                 return NULL;
1322         }
1323         ast_bridge_lock(bridge);
1324         snapshot = ao2_bump(bridge->current_snapshot);
1325         ast_bridge_unlock(bridge);
1326         ao2_ref(bridge, -1);
1327
1328         return snapshot;
1329 }
1330
1331 struct ast_bridge_snapshot *ast_bridge_get_snapshot(struct ast_bridge *bridge)
1332 {
1333         struct ast_bridge_snapshot *snapshot;
1334
1335         if (!bridge) {
1336                 return NULL;
1337         }
1338         ast_bridge_lock(bridge);
1339         snapshot = ao2_bump(bridge->current_snapshot);
1340         ast_bridge_unlock(bridge);
1341
1342         return snapshot;
1343 }
1344
1345 static void stasis_bridging_cleanup(void)
1346 {
1347         STASIS_MESSAGE_TYPE_CLEANUP(ast_bridge_snapshot_type);
1348         STASIS_MESSAGE_TYPE_CLEANUP(ast_bridge_merge_message_type);
1349         STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_entered_bridge_type);
1350         STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_left_bridge_type);
1351         STASIS_MESSAGE_TYPE_CLEANUP(ast_blind_transfer_type);
1352         STASIS_MESSAGE_TYPE_CLEANUP(ast_attended_transfer_type);
1353
1354         ao2_cleanup(bridge_topic_pool);
1355         bridge_topic_pool = NULL;
1356         ao2_cleanup(bridge_topic_all);
1357         bridge_topic_all = NULL;
1358 }
1359
1360 int ast_stasis_bridging_init(void)
1361 {
1362         int res = 0;
1363
1364         ast_register_cleanup(stasis_bridging_cleanup);
1365
1366         bridge_topic_all = stasis_topic_create("ast_bridge_topic_all");
1367         if (!bridge_topic_all) {
1368                 return -1;
1369         }
1370         bridge_topic_pool = stasis_topic_pool_create(bridge_topic_all);
1371         if (!bridge_topic_pool) {
1372                 return -1;
1373         }
1374
1375         res |= STASIS_MESSAGE_TYPE_INIT(ast_bridge_snapshot_type);
1376         res |= STASIS_MESSAGE_TYPE_INIT(ast_bridge_merge_message_type);
1377         res |= STASIS_MESSAGE_TYPE_INIT(ast_channel_entered_bridge_type);
1378         res |= STASIS_MESSAGE_TYPE_INIT(ast_channel_left_bridge_type);
1379         res |= STASIS_MESSAGE_TYPE_INIT(ast_blind_transfer_type);
1380         res |= STASIS_MESSAGE_TYPE_INIT(ast_attended_transfer_type);
1381
1382         return res;
1383 }