Merge "core/frame: Fix ast_frdup() and ast_frisolate() for empty text frames"
[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_cp_all *bridge_cache_all;
159
160 /*!
161  * @{ \brief Define bridge message types.
162  */
163 STASIS_MESSAGE_TYPE_DEFN(ast_bridge_snapshot_type);
164 STASIS_MESSAGE_TYPE_DEFN(ast_bridge_merge_message_type,
165         .to_json = ast_bridge_merge_message_to_json);
166 STASIS_MESSAGE_TYPE_DEFN(ast_channel_entered_bridge_type,
167         .to_json = ast_channel_entered_bridge_to_json);
168 STASIS_MESSAGE_TYPE_DEFN(ast_channel_left_bridge_type,
169         .to_json = ast_channel_left_bridge_to_json);
170 STASIS_MESSAGE_TYPE_DEFN(ast_blind_transfer_type,
171         .to_json = blind_transfer_to_json,
172         .to_ami = blind_transfer_to_ami);
173 STASIS_MESSAGE_TYPE_DEFN(ast_attended_transfer_type,
174         .to_json = attended_transfer_to_json,
175         .to_ami = attended_transfer_to_ami);
176 /*! @} */
177
178 struct stasis_cache *ast_bridge_cache(void)
179 {
180         return stasis_cp_all_cache(bridge_cache_all);
181 }
182
183 struct stasis_topic *ast_bridge_topic_all(void)
184 {
185         return stasis_cp_all_topic(bridge_cache_all);
186 }
187
188 struct stasis_topic *ast_bridge_topic_all_cached(void)
189 {
190         return stasis_cp_all_topic_cached(bridge_cache_all);
191 }
192
193 int bridge_topics_init(struct ast_bridge *bridge)
194 {
195         if (ast_strlen_zero(bridge->uniqueid)) {
196                 ast_log(LOG_ERROR, "Bridge id initialization required\n");
197                 return -1;
198         }
199         bridge->topics = stasis_cp_single_create(bridge_cache_all,
200                 bridge->uniqueid);
201         if (!bridge->topics) {
202                 return -1;
203         }
204         return 0;
205 }
206
207 struct stasis_topic *ast_bridge_topic(struct ast_bridge *bridge)
208 {
209         if (!bridge) {
210                 return ast_bridge_topic_all();
211         }
212
213         return stasis_cp_single_topic(bridge->topics);
214 }
215
216 struct stasis_topic *ast_bridge_topic_cached(struct ast_bridge *bridge)
217 {
218         if (!bridge) {
219                 return ast_bridge_topic_all_cached();
220         }
221
222         return stasis_cp_single_topic_cached(bridge->topics);
223 }
224
225 /*! \brief Destructor for bridge snapshots */
226 static void bridge_snapshot_dtor(void *obj)
227 {
228         struct ast_bridge_snapshot *snapshot = obj;
229         ast_string_field_free_memory(snapshot);
230         ao2_cleanup(snapshot->channels);
231         snapshot->channels = NULL;
232 }
233
234 struct ast_bridge_snapshot *ast_bridge_snapshot_create(struct ast_bridge *bridge)
235 {
236         struct ast_bridge_snapshot *snapshot;
237         struct ast_bridge_channel *bridge_channel;
238
239         if (ast_test_flag(&bridge->feature_flags, AST_BRIDGE_FLAG_INVISIBLE)) {
240                 return NULL;
241         }
242
243         snapshot = ao2_alloc_options(sizeof(*snapshot), bridge_snapshot_dtor,
244                 AO2_ALLOC_OPT_LOCK_NOLOCK);
245         if (!snapshot) {
246                 return NULL;
247         }
248
249         if (ast_string_field_init(snapshot, 128)) {
250                 ao2_ref(snapshot, -1);
251
252                 return NULL;
253         }
254
255         snapshot->channels = ast_str_container_alloc(SNAPSHOT_CHANNELS_BUCKETS);
256         if (!snapshot->channels) {
257                 ao2_ref(snapshot, -1);
258
259                 return NULL;
260         }
261
262         AST_LIST_TRAVERSE(&bridge->channels, bridge_channel, entry) {
263                 if (ast_str_container_add(snapshot->channels,
264                                 ast_channel_uniqueid(bridge_channel->chan))) {
265                         ao2_ref(snapshot, -1);
266
267                         return NULL;
268                 }
269         }
270
271         ast_string_field_set(snapshot, uniqueid, bridge->uniqueid);
272         ast_string_field_set(snapshot, technology, bridge->technology->name);
273         ast_string_field_set(snapshot, subclass, bridge->v_table->name);
274         ast_string_field_set(snapshot, creator, bridge->creator);
275         ast_string_field_set(snapshot, name, bridge->name);
276
277         snapshot->feature_flags = bridge->feature_flags;
278         snapshot->capabilities = bridge->technology->capabilities;
279         snapshot->num_channels = bridge->num_channels;
280         snapshot->num_active = bridge->num_active;
281         snapshot->video_mode = bridge->softmix.video_mode.mode;
282         if (snapshot->video_mode == AST_BRIDGE_VIDEO_MODE_SINGLE_SRC
283                 && bridge->softmix.video_mode.mode_data.single_src_data.chan_vsrc) {
284                 ast_string_field_set(snapshot, video_source_id,
285                         ast_channel_uniqueid(bridge->softmix.video_mode.mode_data.single_src_data.chan_vsrc));
286         } else if (snapshot->video_mode == AST_BRIDGE_VIDEO_MODE_TALKER_SRC
287                 && bridge->softmix.video_mode.mode_data.talker_src_data.chan_vsrc) {
288                 ast_string_field_set(snapshot, video_source_id,
289                         ast_channel_uniqueid(bridge->softmix.video_mode.mode_data.talker_src_data.chan_vsrc));
290         }
291
292         return snapshot;
293 }
294
295 void ast_bridge_publish_state(struct ast_bridge *bridge)
296 {
297         struct ast_bridge_snapshot *snapshot;
298         struct stasis_message *msg;
299
300         if (!ast_bridge_snapshot_type()) {
301                 return;
302         }
303
304         ast_assert(bridge != NULL);
305
306         snapshot = ast_bridge_snapshot_create(bridge);
307         if (!snapshot) {
308                 return;
309         }
310
311         msg = stasis_message_create(ast_bridge_snapshot_type(), snapshot);
312         ao2_ref(snapshot, -1);
313         if (!msg) {
314                 return;
315         }
316
317         stasis_publish(ast_bridge_topic(bridge), msg);
318         ao2_ref(msg, -1);
319 }
320
321 static void bridge_publish_state_from_blob(struct ast_bridge *bridge,
322         struct ast_bridge_blob *obj)
323 {
324         struct stasis_message *msg;
325
326         ast_assert(obj != NULL);
327
328         msg = stasis_message_create(ast_bridge_snapshot_type(), obj->bridge);
329         if (!msg) {
330                 return;
331         }
332
333         stasis_publish(ast_bridge_topic(bridge), msg);
334         ao2_ref(msg, -1);
335 }
336
337 /*! \brief Destructor for bridge merge messages */
338 static void bridge_merge_message_dtor(void *obj)
339 {
340         struct ast_bridge_merge_message *msg = obj;
341
342         ao2_cleanup(msg->to);
343         msg->to = NULL;
344         ao2_cleanup(msg->from);
345         msg->from = NULL;
346 }
347
348 /*! \brief Bridge merge message creation helper */
349 static struct ast_bridge_merge_message *bridge_merge_message_create(struct ast_bridge *to, struct ast_bridge *from)
350 {
351         struct ast_bridge_merge_message *msg;
352
353         msg = ao2_alloc(sizeof(*msg), bridge_merge_message_dtor);
354         if (!msg) {
355                 return NULL;
356         }
357
358         msg->to = ast_bridge_snapshot_create(to);
359         msg->from = ast_bridge_snapshot_create(from);
360         if (!msg->to || !msg->from) {
361                 ao2_ref(msg, -1);
362
363                 return NULL;
364         }
365
366         return msg;
367 }
368
369 static struct ast_json *ast_bridge_merge_message_to_json(
370         struct stasis_message *msg,
371         const struct stasis_message_sanitizer *sanitize)
372 {
373         struct ast_bridge_merge_message *merge = stasis_message_data(msg);
374         struct ast_json *json_bridge_to = ast_bridge_snapshot_to_json(merge->to, sanitize);
375         struct ast_json *json_bridge_from = ast_bridge_snapshot_to_json(merge->from, sanitize);
376
377         if (!json_bridge_to || !json_bridge_from) {
378                 ast_json_unref(json_bridge_to);
379                 ast_json_unref(json_bridge_from);
380
381                 return NULL;
382         }
383
384         return ast_json_pack("{s: s, s: o, s: o, s: o}",
385                 "type", "BridgeMerged",
386                 "timestamp", ast_json_timeval(*stasis_message_timestamp(msg), NULL),
387                 "bridge", json_bridge_to,
388                 "bridge_from", json_bridge_from);
389 }
390
391 void ast_bridge_publish_merge(struct ast_bridge *to, struct ast_bridge *from)
392 {
393         struct ast_bridge_merge_message *merge_msg;
394         struct stasis_message *msg;
395
396         if (!ast_bridge_merge_message_type()) {
397                 return;
398         }
399
400         ast_assert(to != NULL);
401         ast_assert(from != NULL);
402         ast_assert(ast_test_flag(&to->feature_flags, AST_BRIDGE_FLAG_INVISIBLE) == 0);
403         ast_assert(ast_test_flag(&from->feature_flags, AST_BRIDGE_FLAG_INVISIBLE) == 0);
404
405         merge_msg = bridge_merge_message_create(to, from);
406         if (!merge_msg) {
407                 return;
408         }
409
410         msg = stasis_message_create(ast_bridge_merge_message_type(), merge_msg);
411         ao2_ref(merge_msg, -1);
412         if (!msg) {
413                 return;
414         }
415
416         stasis_publish(ast_bridge_topic_all(), msg);
417         ao2_ref(msg, -1);
418 }
419
420 static void bridge_blob_dtor(void *obj)
421 {
422         struct ast_bridge_blob *event = obj;
423         ao2_cleanup(event->bridge);
424         event->bridge = NULL;
425         ao2_cleanup(event->channel);
426         event->channel = NULL;
427         ast_json_unref(event->blob);
428         event->blob = NULL;
429 }
430
431 struct stasis_message *ast_bridge_blob_create(
432         struct stasis_message_type *message_type,
433         struct ast_bridge *bridge,
434         struct ast_channel *chan,
435         struct ast_json *blob)
436 {
437         struct ast_bridge_blob *obj;
438         struct stasis_message *msg;
439
440         if (!message_type) {
441                 return NULL;
442         }
443
444         obj = ao2_alloc(sizeof(*obj), bridge_blob_dtor);
445         if (!obj) {
446                 return NULL;
447         }
448
449         if (bridge) {
450                 obj->bridge = ast_bridge_snapshot_create(bridge);
451                 if (obj->bridge == NULL) {
452                         ao2_ref(obj, -1);
453
454                         return NULL;
455                 }
456         }
457
458         if (chan) {
459                 obj->channel = ast_channel_snapshot_get_latest(ast_channel_uniqueid(chan));
460                 if (obj->channel == NULL) {
461                         ao2_ref(obj, -1);
462
463                         return NULL;
464                 }
465         }
466
467         if (blob) {
468                 obj->blob = ast_json_ref(blob);
469         }
470
471         msg = stasis_message_create(message_type, obj);
472         ao2_ref(obj, -1);
473
474         return msg;
475 }
476
477 void ast_bridge_publish_enter(struct ast_bridge *bridge, struct ast_channel *chan,
478                 struct ast_channel *swap)
479 {
480         struct stasis_message *msg;
481         struct ast_json *blob = NULL;
482
483         if (ast_test_flag(&bridge->feature_flags, AST_BRIDGE_FLAG_INVISIBLE)) {
484                 return;
485         }
486
487         if (swap) {
488                 blob = ast_json_pack("{s: s}", "swap", ast_channel_uniqueid(swap));
489                 if (!blob) {
490                         return;
491                 }
492         }
493
494         msg = ast_bridge_blob_create(ast_channel_entered_bridge_type(), bridge, chan, blob);
495         ast_json_unref(blob);
496         if (!msg) {
497                 return;
498         }
499
500         /* enter blob first, then state */
501         stasis_publish(ast_bridge_topic(bridge), msg);
502         bridge_publish_state_from_blob(bridge, stasis_message_data(msg));
503         ao2_ref(msg, -1);
504 }
505
506 void ast_bridge_publish_leave(struct ast_bridge *bridge, struct ast_channel *chan)
507 {
508         struct stasis_message *msg;
509
510         if (ast_test_flag(&bridge->feature_flags, AST_BRIDGE_FLAG_INVISIBLE)) {
511                 return;
512         }
513         msg = ast_bridge_blob_create(ast_channel_left_bridge_type(), bridge, chan, NULL);
514         if (!msg) {
515                 return;
516         }
517
518         /* state first, then leave blob (opposite of enter, preserves nesting of events) */
519         bridge_publish_state_from_blob(bridge, stasis_message_data(msg));
520         stasis_publish(ast_bridge_topic(bridge), msg);
521         ao2_ref(msg, -1);
522 }
523
524 static struct ast_json *simple_bridge_channel_event(
525         const char *type,
526         struct ast_bridge_snapshot *bridge_snapshot,
527         struct ast_channel_snapshot *channel_snapshot,
528         const struct timeval *tv,
529         const struct stasis_message_sanitizer *sanitize)
530 {
531         struct ast_json *json_bridge = ast_bridge_snapshot_to_json(bridge_snapshot, sanitize);
532         struct ast_json *json_channel = ast_channel_snapshot_to_json(channel_snapshot, sanitize);
533
534         if (!json_bridge || !json_channel) {
535                 ast_json_unref(json_bridge);
536                 ast_json_unref(json_channel);
537
538                 return NULL;
539         }
540
541         return ast_json_pack("{s: s, s: o, s: o, s: o}",
542                 "type", type,
543                 "timestamp", ast_json_timeval(*tv, NULL),
544                 "bridge", json_bridge,
545                 "channel", json_channel);
546 }
547
548 struct ast_json *ast_channel_entered_bridge_to_json(
549         struct stasis_message *msg,
550         const struct stasis_message_sanitizer *sanitize)
551 {
552         struct ast_bridge_blob *obj = stasis_message_data(msg);
553
554         return simple_bridge_channel_event("ChannelEnteredBridge", obj->bridge,
555                 obj->channel, stasis_message_timestamp(msg), sanitize);
556 }
557
558 struct ast_json *ast_channel_left_bridge_to_json(
559         struct stasis_message *msg,
560         const struct stasis_message_sanitizer *sanitize)
561 {
562         struct ast_bridge_blob *obj = stasis_message_data(msg);
563
564         return simple_bridge_channel_event("ChannelLeftBridge", obj->bridge,
565                 obj->channel, stasis_message_timestamp(msg), sanitize);
566 }
567
568 static struct ast_json *container_to_json_array(struct ao2_container *items,
569         const struct stasis_message_sanitizer *sanitize)
570 {
571         struct ast_json *json_items = ast_json_array_create();
572         char *item;
573         struct ao2_iterator it;
574
575         if (!json_items) {
576                 return NULL;
577         }
578
579         for (it = ao2_iterator_init(items, 0);
580                 (item = ao2_iterator_next(&it)); ao2_cleanup(item)) {
581                 if (sanitize && sanitize->channel_id && sanitize->channel_id(item)) {
582                         continue;
583                 }
584
585                 if (ast_json_array_append(json_items, ast_json_string_create(item))) {
586                         ao2_cleanup(item);
587                         ao2_iterator_destroy(&it);
588                         ast_json_unref(json_items);
589
590                         return NULL;
591                 }
592         }
593         ao2_iterator_destroy(&it);
594
595         return json_items;
596 }
597
598 static const char *capability2str(uint32_t capabilities)
599 {
600         if (capabilities & AST_BRIDGE_CAPABILITY_HOLDING) {
601                 return "holding";
602         } else {
603                 return "mixing";
604         }
605 }
606
607 struct ast_json *ast_bridge_snapshot_to_json(
608         const struct ast_bridge_snapshot *snapshot,
609         const struct stasis_message_sanitizer *sanitize)
610 {
611         struct ast_json *json_bridge;
612         struct ast_json *json_channels;
613
614         if (snapshot == NULL) {
615                 return NULL;
616         }
617
618         json_channels = container_to_json_array(snapshot->channels, sanitize);
619         if (!json_channels) {
620                 return NULL;
621         }
622
623         json_bridge = ast_json_pack("{s: s, s: s, s: s, s: s, s: s, s: s, s: o, s: s}",
624                 "id", snapshot->uniqueid,
625                 "technology", snapshot->technology,
626                 "bridge_type", capability2str(snapshot->capabilities),
627                 "bridge_class", snapshot->subclass,
628                 "creator", snapshot->creator,
629                 "name", snapshot->name,
630                 "channels", json_channels,
631                 "video_mode", ast_bridge_video_mode_to_string(snapshot->video_mode));
632         if (!json_bridge) {
633                 return NULL;
634         }
635
636         if (snapshot->video_mode != AST_BRIDGE_VIDEO_MODE_NONE
637                 && !ast_strlen_zero(snapshot->video_source_id)) {
638                 ast_json_object_set(json_bridge, "video_source_id",
639                         ast_json_string_create(snapshot->video_source_id));
640         }
641
642         return json_bridge;
643 }
644
645 /*!
646  * \internal
647  * \brief Allocate the fields of an \ref ast_bridge_channel_snapshot_pair.
648  *
649  * \param pair A bridge and channel to get snapshots of
650  * \param[out] snapshot_pair An allocated snapshot pair.
651  * \retval 0 Success
652  * \retval non-zero Failure
653  */
654 static int bridge_channel_snapshot_pair_init(struct ast_channel *channel, struct ast_bridge *bridge,
655                 struct ast_bridge_channel_snapshot_pair *snapshot_pair)
656 {
657         if (bridge) {
658                 ast_bridge_lock(bridge);
659                 snapshot_pair->bridge_snapshot = ast_bridge_snapshot_create(bridge);
660                 ast_bridge_unlock(bridge);
661                 if (!snapshot_pair->bridge_snapshot) {
662                         return -1;
663                 }
664         }
665
666         snapshot_pair->channel_snapshot = ast_channel_snapshot_get_latest(ast_channel_uniqueid(channel));
667         if (!snapshot_pair->channel_snapshot) {
668                 return -1;
669         }
670
671         return 0;
672 }
673
674 /*!
675  * \internal
676  * \brief Free the fields of an \ref ast_bridge_channel_snapshot_pair.
677  *
678  * \param pair The snapshot pair whose fields are to be cleaned up
679  */
680 static void bridge_channel_snapshot_pair_cleanup(struct ast_bridge_channel_snapshot_pair *pair)
681 {
682         ao2_cleanup(pair->bridge_snapshot);
683         ao2_cleanup(pair->channel_snapshot);
684 }
685
686 static const char *result_strs[] = {
687         [AST_BRIDGE_TRANSFER_FAIL] = "Fail",
688         [AST_BRIDGE_TRANSFER_INVALID] = "Invalid",
689         [AST_BRIDGE_TRANSFER_NOT_PERMITTED] = "Not Permitted",
690         [AST_BRIDGE_TRANSFER_SUCCESS] = "Success",
691 };
692
693 static struct ast_json *blind_transfer_to_json(struct stasis_message *msg,
694         const struct stasis_message_sanitizer *sanitize)
695 {
696         struct ast_blind_transfer_message *transfer_msg = stasis_message_data(msg);
697         struct ast_json *json_transferer;
698         struct ast_json *json_transferee = NULL;
699         struct ast_json *out;
700         struct ast_json *json_replace = NULL;
701         const struct timeval *tv = stasis_message_timestamp(msg);
702
703         json_transferer = ast_channel_snapshot_to_json(transfer_msg->transferer, sanitize);
704         if (!json_transferer) {
705                 return NULL;
706         }
707
708         if (transfer_msg->transferee) {
709                 json_transferee = ast_channel_snapshot_to_json(transfer_msg->transferee, sanitize);
710                 if (!json_transferee) {
711                         ast_json_unref(json_transferer);
712                         return NULL;
713                 }
714         }
715
716         if (transfer_msg->replace_channel) {
717                 json_replace = ast_channel_snapshot_to_json(transfer_msg->replace_channel, sanitize);
718                 if (!json_replace) {
719                         ast_json_unref(json_transferee);
720                         ast_json_unref(json_transferer);
721                         return NULL;
722                 }
723         }
724
725         out = ast_json_pack("{s: s, s: o, s: o, s: s, s: s, s: s, s: o}",
726                 "type", "BridgeBlindTransfer",
727                 "timestamp", ast_json_timeval(*tv, NULL),
728                 "channel", json_transferer,
729                 "exten", transfer_msg->exten,
730                 "context", transfer_msg->context,
731                 "result", result_strs[transfer_msg->result],
732                 "is_external", ast_json_boolean(transfer_msg->is_external));
733
734         if (!out) {
735                 ast_json_unref(json_transferee);
736                 ast_json_unref(json_replace);
737                 return NULL;
738         }
739
740         if (json_transferee && ast_json_object_set(out, "transferee", json_transferee)) {
741                 ast_json_unref(out);
742                 ast_json_unref(json_replace);
743                 return NULL;
744         }
745
746         if (json_replace && ast_json_object_set(out, "replace_channel", json_replace)) {
747                 ast_json_unref(out);
748                 return NULL;
749         }
750
751         if (transfer_msg->bridge) {
752                 struct ast_json *json_bridge = ast_bridge_snapshot_to_json(
753                                 transfer_msg->bridge, sanitize);
754
755                 if (!json_bridge || ast_json_object_set(out, "bridge", json_bridge)) {
756                         ast_json_unref(out);
757                         return NULL;
758                 }
759         }
760
761         return out;
762 }
763
764 static struct ast_manager_event_blob *blind_transfer_to_ami(struct stasis_message *msg)
765 {
766         RAII_VAR(struct ast_str *, transferer_state, NULL, ast_free_ptr);
767         RAII_VAR(struct ast_str *, bridge_state, NULL, ast_free_ptr);
768         RAII_VAR(struct ast_str *, transferee_state, NULL, ast_free_ptr);
769         struct ast_blind_transfer_message *transfer_msg = stasis_message_data(msg);
770
771         if (!transfer_msg) {
772                 return NULL;
773         }
774
775         transferer_state = ast_manager_build_channel_state_string_prefix(
776                         transfer_msg->transferer, "Transferer");
777         if (!transferer_state) {
778                 return NULL;
779         }
780
781         if (transfer_msg->bridge) {
782                 bridge_state = ast_manager_build_bridge_state_string(transfer_msg->bridge);
783                 if (!bridge_state) {
784                         return NULL;
785                 }
786         }
787
788         if (transfer_msg->transferee) {
789                 transferee_state = ast_manager_build_channel_state_string_prefix(
790                                 transfer_msg->transferee, "Transferee");
791                 if (!transferee_state) {
792                         return NULL;
793                 }
794         }
795
796         return ast_manager_event_blob_create(EVENT_FLAG_CALL, "BlindTransfer",
797                         "Result: %s\r\n"
798                         "%s"
799                         "%s"
800                         "%s"
801                         "IsExternal: %s\r\n"
802                         "Context: %s\r\n"
803                         "Extension: %s\r\n",
804                         result_strs[transfer_msg->result],
805                         ast_str_buffer(transferer_state),
806                         transferee_state ? ast_str_buffer(transferee_state) : "",
807                         bridge_state ? ast_str_buffer(bridge_state) : "",
808                         transfer_msg->is_external ? "Yes" : "No",
809                         transfer_msg->context,
810                         transfer_msg->exten);
811 }
812
813 static void blind_transfer_dtor(void *obj)
814 {
815         struct ast_blind_transfer_message *msg = obj;
816
817         ao2_cleanup(msg->transferer);
818         ao2_cleanup(msg->bridge);
819         ao2_cleanup(msg->transferee);
820         ao2_cleanup(msg->replace_channel);
821 }
822
823 struct ast_blind_transfer_message *ast_blind_transfer_message_create(int is_external,
824                 struct ast_channel *transferer, const char *exten, const char *context)
825 {
826         struct ast_blind_transfer_message *msg;
827
828         msg = ao2_alloc(sizeof(*msg), blind_transfer_dtor);
829         if (!msg) {
830                 return NULL;
831         }
832
833         msg->transferer = ast_channel_snapshot_get_latest(ast_channel_uniqueid(transferer));
834         if (!msg->transferer) {
835                 ao2_cleanup(msg);
836                 return NULL;
837         }
838
839         msg->is_external = is_external;
840         ast_copy_string(msg->context, context, sizeof(msg->context));
841         ast_copy_string(msg->exten, exten, sizeof(msg->exten));
842
843         return msg;
844 }
845
846
847 void ast_bridge_publish_blind_transfer(struct ast_blind_transfer_message *transfer_message)
848 {
849         struct stasis_message *stasis;
850
851         stasis = stasis_message_create(ast_blind_transfer_type(), transfer_message);
852         if (!stasis) {
853                 return;
854         }
855
856         stasis_publish(ast_bridge_topic_all(), stasis);
857
858         ao2_cleanup(stasis);
859 }
860
861 static struct ast_json *attended_transfer_to_json(struct stasis_message *msg,
862         const struct stasis_message_sanitizer *sanitize)
863 {
864         struct ast_attended_transfer_message *transfer_msg = stasis_message_data(msg);
865         RAII_VAR(struct ast_json *, out, NULL, ast_json_unref);
866         struct ast_json *json_transferer1, *json_transferer2, *json_bridge, *json_channel;
867         struct ast_json *json_transferee = NULL, *json_target = NULL;
868         const struct timeval *tv = stasis_message_timestamp(msg);
869         int res = 0;
870
871         json_transferer1 = ast_channel_snapshot_to_json(transfer_msg->to_transferee.channel_snapshot, sanitize);
872         if (!json_transferer1) {
873                 return NULL;
874         }
875
876         json_transferer2 = ast_channel_snapshot_to_json(transfer_msg->to_transfer_target.channel_snapshot, sanitize);
877         if (!json_transferer2) {
878                 ast_json_unref(json_transferer1);
879                 return NULL;
880         }
881
882         if (transfer_msg->transferee) {
883                 json_transferee = ast_channel_snapshot_to_json(transfer_msg->transferee, sanitize);
884                 if (!json_transferee) {
885                         ast_json_unref(json_transferer2);
886                         ast_json_unref(json_transferer1);
887                         return NULL;
888                 }
889         }
890
891         if (transfer_msg->target) {
892                 json_target = ast_channel_snapshot_to_json(transfer_msg->target, sanitize);
893                 if (!json_target) {
894                         ast_json_unref(json_transferee);
895                         ast_json_unref(json_transferer2);
896                         ast_json_unref(json_transferer1);
897                         return NULL;
898                 }
899         }
900
901         out = ast_json_pack("{s: s, s: o, s: o, s: o, s: s, s: o}",
902                 "type", "BridgeAttendedTransfer",
903                 "timestamp", ast_json_timeval(*tv, NULL),
904                 "transferer_first_leg", json_transferer1,
905                 "transferer_second_leg", json_transferer2,
906                 "result", result_strs[transfer_msg->result],
907                 "is_external", ast_json_boolean(transfer_msg->is_external));
908         if (!out) {
909                 ast_json_unref(json_target);
910                 ast_json_unref(json_transferee);
911                 return NULL;
912         }
913         if (json_transferee && ast_json_object_set(out, "transferee", json_transferee)) {
914                 ast_json_unref(json_target);
915                 return NULL;
916         }
917         if (json_target && ast_json_object_set(out, "transfer_target", json_target)) {
918                 return NULL;
919         }
920
921         if (transfer_msg->to_transferee.bridge_snapshot) {
922                 json_bridge = ast_bridge_snapshot_to_json(transfer_msg->to_transferee.bridge_snapshot, sanitize);
923
924                 if (!json_bridge) {
925                         return NULL;
926                 }
927
928                 res |= ast_json_object_set(out, "transferer_first_leg_bridge", json_bridge);
929         }
930
931         if (transfer_msg->to_transfer_target.bridge_snapshot) {
932                 json_bridge = ast_bridge_snapshot_to_json(transfer_msg->to_transfer_target.bridge_snapshot, sanitize);
933
934                 if (!json_bridge) {
935                         return NULL;
936                 }
937
938                 res |= ast_json_object_set(out, "transferer_second_leg_bridge", json_bridge);
939         }
940
941         switch (transfer_msg->dest_type) {
942         case AST_ATTENDED_TRANSFER_DEST_BRIDGE_MERGE:
943                 res |= ast_json_object_set(out, "destination_type", ast_json_string_create("bridge"));
944                 res |= ast_json_object_set(out, "destination_bridge", ast_json_string_create(transfer_msg->dest.bridge));
945                 break;
946         case AST_ATTENDED_TRANSFER_DEST_LOCAL_APP:
947                 res |= ast_json_object_set(out, "replace_channel", ast_channel_snapshot_to_json(transfer_msg->replace_channel, sanitize));
948                 /* fallthrough */
949         case AST_ATTENDED_TRANSFER_DEST_APP:
950                 res |= ast_json_object_set(out, "destination_type", ast_json_string_create("application"));
951                 res |= ast_json_object_set(out, "destination_application", ast_json_string_create(transfer_msg->dest.app));
952                 break;
953         case AST_ATTENDED_TRANSFER_DEST_LINK:
954                 res |= ast_json_object_set(out, "destination_type", ast_json_string_create("link"));
955
956                 json_channel = ast_channel_snapshot_to_json(transfer_msg->dest.links[0], sanitize);
957                 if (!json_channel) {
958                         return NULL;
959                 }
960                 res |= ast_json_object_set(out, "destination_link_first_leg", json_channel);
961
962                 json_channel = ast_channel_snapshot_to_json(transfer_msg->dest.links[1], sanitize);
963                 if (!json_channel) {
964                         return NULL;
965                 }
966                 res |= ast_json_object_set(out, "destination_link_second_leg", json_channel);
967
968                 break;
969         case AST_ATTENDED_TRANSFER_DEST_THREEWAY:
970                 res |= ast_json_object_set(out, "destination_type", ast_json_string_create("threeway"));
971
972                 json_channel = ast_channel_snapshot_to_json(transfer_msg->dest.threeway.channel_snapshot, sanitize);
973                 if (!json_channel) {
974                         return NULL;
975                 }
976                 res |= ast_json_object_set(out, "destination_threeway_channel", json_channel);
977
978                 json_bridge = ast_bridge_snapshot_to_json(transfer_msg->dest.threeway.bridge_snapshot, sanitize);
979                 if (!json_bridge) {
980                         return NULL;
981                 }
982                 res |= ast_json_object_set(out, "destination_threeway_bridge", json_bridge);
983
984                 break;
985         case AST_ATTENDED_TRANSFER_DEST_FAIL:
986                 res |= ast_json_object_set(out, "destination_type", ast_json_string_create("fail"));
987                 break;
988         }
989
990         if (res) {
991                 return NULL;
992         }
993
994         return ast_json_ref(out);
995 }
996
997 static struct ast_manager_event_blob *attended_transfer_to_ami(struct stasis_message *msg)
998 {
999         RAII_VAR(struct ast_str *, variable_data, ast_str_create(64), ast_free_ptr);
1000         RAII_VAR(struct ast_str *, transferer1_state, NULL, ast_free_ptr);
1001         RAII_VAR(struct ast_str *, bridge1_state, NULL, ast_free_ptr);
1002         RAII_VAR(struct ast_str *, transferer2_state, NULL, ast_free_ptr);
1003         RAII_VAR(struct ast_str *, bridge2_state, NULL, ast_free_ptr);
1004         RAII_VAR(struct ast_str *, local1_state, NULL, ast_free_ptr);
1005         RAII_VAR(struct ast_str *, local2_state, NULL, ast_free_ptr);
1006         RAII_VAR(struct ast_str *, transferee_state, NULL, ast_free_ptr);
1007         RAII_VAR(struct ast_str *, target_state, NULL, ast_free_ptr);
1008         struct ast_attended_transfer_message *transfer_msg = stasis_message_data(msg);
1009
1010         if (!variable_data) {
1011                 return NULL;
1012         }
1013
1014         transferer1_state = ast_manager_build_channel_state_string_prefix(transfer_msg->to_transferee.channel_snapshot, "OrigTransferer");
1015         transferer2_state = ast_manager_build_channel_state_string_prefix(transfer_msg->to_transfer_target.channel_snapshot, "SecondTransferer");
1016         if (!transferer1_state || !transferer2_state) {
1017                 return NULL;
1018         }
1019         if (transfer_msg->transferee) {
1020                 transferee_state = ast_manager_build_channel_state_string_prefix(transfer_msg->transferee, "Transferee");
1021                 if (!transferee_state) {
1022                         return NULL;
1023                 }
1024         }
1025
1026         if (transfer_msg->target) {
1027                 target_state = ast_manager_build_channel_state_string_prefix(transfer_msg->target, "TransferTarget");
1028                 if (!target_state) {
1029                         return NULL;
1030                 }
1031         }
1032
1033         if (transfer_msg->to_transferee.bridge_snapshot) {
1034                 bridge1_state = ast_manager_build_bridge_state_string_prefix(
1035                         transfer_msg->to_transferee.bridge_snapshot, "Orig");
1036                 if (!bridge1_state) {
1037                         return NULL;
1038                 }
1039         }
1040
1041         if (transfer_msg->to_transfer_target.bridge_snapshot) {
1042                 bridge2_state = ast_manager_build_bridge_state_string_prefix(
1043                         transfer_msg->to_transfer_target.bridge_snapshot, "Second");
1044                 if (!bridge2_state) {
1045                         return NULL;
1046                 }
1047         }
1048
1049         switch (transfer_msg->dest_type) {
1050         case AST_ATTENDED_TRANSFER_DEST_BRIDGE_MERGE:
1051                 ast_str_append(&variable_data, 0, "DestType: Bridge\r\n");
1052                 ast_str_append(&variable_data, 0, "DestBridgeUniqueid: %s\r\n", transfer_msg->dest.bridge);
1053                 break;
1054         case AST_ATTENDED_TRANSFER_DEST_APP:
1055         case AST_ATTENDED_TRANSFER_DEST_LOCAL_APP:
1056                 ast_str_append(&variable_data, 0, "DestType: App\r\n");
1057                 ast_str_append(&variable_data, 0, "DestApp: %s\r\n", transfer_msg->dest.app);
1058                 break;
1059         case AST_ATTENDED_TRANSFER_DEST_LINK:
1060                 local1_state = ast_manager_build_channel_state_string_prefix(transfer_msg->dest.links[0], "LocalOne");
1061                 local2_state = ast_manager_build_channel_state_string_prefix(transfer_msg->dest.links[1], "LocalTwo");
1062                 if (!local1_state || !local2_state) {
1063                         return NULL;
1064                 }
1065                 ast_str_append(&variable_data, 0, "DestType: Link\r\n");
1066                 ast_str_append(&variable_data, 0, "%s", ast_str_buffer(local1_state));
1067                 ast_str_append(&variable_data, 0, "%s", ast_str_buffer(local2_state));
1068                 break;
1069         case AST_ATTENDED_TRANSFER_DEST_THREEWAY:
1070                 ast_str_append(&variable_data, 0, "DestType: Threeway\r\n");
1071                 ast_str_append(&variable_data, 0, "DestBridgeUniqueid: %s\r\n", transfer_msg->dest.threeway.bridge_snapshot->uniqueid);
1072                 ast_str_append(&variable_data, 0, "DestTransfererChannel: %s\r\n", transfer_msg->dest.threeway.channel_snapshot->name);
1073                 break;
1074         case AST_ATTENDED_TRANSFER_DEST_FAIL:
1075                 ast_str_append(&variable_data, 0, "DestType: Fail\r\n");
1076                 break;
1077         }
1078
1079         return ast_manager_event_blob_create(EVENT_FLAG_CALL, "AttendedTransfer",
1080                         "Result: %s\r\n"
1081                         "%s"
1082                         "%s"
1083                         "%s"
1084                         "%s"
1085                         "%s"
1086                         "%s"
1087                         "IsExternal: %s\r\n"
1088                         "%s",
1089                         result_strs[transfer_msg->result],
1090                         ast_str_buffer(transferer1_state),
1091                         bridge1_state ? ast_str_buffer(bridge1_state) : "",
1092                         ast_str_buffer(transferer2_state),
1093                         bridge2_state ? ast_str_buffer(bridge2_state) : "",
1094                         transferee_state ? ast_str_buffer(transferee_state) : "",
1095                         target_state ? ast_str_buffer(target_state) : "",
1096                         transfer_msg->is_external ? "Yes" : "No",
1097                         ast_str_buffer(variable_data));
1098 }
1099
1100 static void attended_transfer_dtor(void *obj)
1101 {
1102         struct ast_attended_transfer_message *msg = obj;
1103         int i;
1104
1105         bridge_channel_snapshot_pair_cleanup(&msg->to_transferee);
1106         bridge_channel_snapshot_pair_cleanup(&msg->to_transfer_target);
1107         ao2_cleanup(msg->replace_channel);
1108         ao2_cleanup(msg->transferee);
1109         ao2_cleanup(msg->target);
1110
1111         if (msg->dest_type != AST_ATTENDED_TRANSFER_DEST_LINK) {
1112                 return;
1113         }
1114
1115         for (i = 0; i < ARRAY_LEN(msg->dest.links); ++i) {
1116                 ao2_cleanup(msg->dest.links[i]);
1117         }
1118 }
1119
1120 struct ast_attended_transfer_message *ast_attended_transfer_message_create(int is_external,
1121                 struct ast_channel *to_transferee, struct ast_bridge *transferee_bridge,
1122                 struct ast_channel *to_transfer_target, struct ast_bridge *target_bridge,
1123                 struct ast_channel *transferee, struct ast_channel *transfer_target)
1124 {
1125         struct ast_attended_transfer_message *transfer_msg;
1126
1127         transfer_msg = ao2_alloc(sizeof(*transfer_msg), attended_transfer_dtor);
1128         if (!transfer_msg) {
1129                 return NULL;
1130         }
1131
1132         if (bridge_channel_snapshot_pair_init(to_transferee, transferee_bridge, &transfer_msg->to_transferee) ||
1133                         bridge_channel_snapshot_pair_init(to_transfer_target, target_bridge, &transfer_msg->to_transfer_target)) {
1134                 ao2_cleanup(transfer_msg);
1135                 return NULL;
1136         }
1137
1138         if (transferee) {
1139                 transfer_msg->transferee = ast_channel_snapshot_get_latest(ast_channel_uniqueid(transferee));
1140                 if (!transfer_msg->transferee) {
1141                         ao2_cleanup(transfer_msg);
1142                         return NULL;
1143                 }
1144         } else if (transferee_bridge) {
1145                 transferee = ast_bridge_peer(transferee_bridge, to_transferee);
1146                 if (transferee) {
1147                         transfer_msg->transferee = ast_channel_snapshot_get_latest(ast_channel_uniqueid(transferee));
1148                         ao2_cleanup(transferee);
1149                         if (!transfer_msg->transferee) {
1150                                 ao2_cleanup(transfer_msg);
1151                                 return NULL;
1152                         }
1153                 }
1154         }
1155
1156         if (transfer_target) {
1157                 transfer_msg->target = ast_channel_snapshot_get_latest(ast_channel_uniqueid(transfer_target));
1158                 if (!transfer_msg->target) {
1159                         ao2_cleanup(transfer_msg);
1160                         return NULL;
1161                 }
1162         } else if (target_bridge) {
1163                 transfer_target = ast_bridge_peer(target_bridge, to_transfer_target);
1164                 if (transfer_target) {
1165                         transfer_msg->target = ast_channel_snapshot_get_latest(ast_channel_uniqueid(transfer_target));
1166                         ao2_cleanup(transfer_target);
1167                         if (!transfer_msg->target) {
1168                                 ao2_cleanup(transfer_msg);
1169                                 return NULL;
1170                         }
1171                 }
1172         }
1173
1174         return transfer_msg;
1175 }
1176
1177 int ast_attended_transfer_message_add_merge(struct ast_attended_transfer_message *transfer_msg,
1178                 struct ast_bridge *final_bridge)
1179 {
1180         transfer_msg->dest_type = AST_ATTENDED_TRANSFER_DEST_BRIDGE_MERGE;
1181         ast_copy_string(transfer_msg->dest.bridge, final_bridge->uniqueid,
1182                         sizeof(transfer_msg->dest.bridge));
1183
1184         return 0;
1185 }
1186
1187 int ast_attended_transfer_message_add_threeway(struct ast_attended_transfer_message *transfer_msg,
1188                 struct ast_channel *survivor_channel, struct ast_bridge *survivor_bridge)
1189 {
1190         transfer_msg->dest_type = AST_ATTENDED_TRANSFER_DEST_THREEWAY;
1191
1192         if (!strcmp(ast_channel_uniqueid(survivor_channel), transfer_msg->to_transferee.channel_snapshot->uniqueid)) {
1193                 transfer_msg->dest.threeway.channel_snapshot = transfer_msg->to_transferee.channel_snapshot;
1194         } else {
1195                 transfer_msg->dest.threeway.channel_snapshot = transfer_msg->to_transfer_target.channel_snapshot;
1196         }
1197
1198         if (!strcmp(survivor_bridge->uniqueid, transfer_msg->to_transferee.bridge_snapshot->uniqueid)) {
1199                 transfer_msg->dest.threeway.bridge_snapshot = transfer_msg->to_transferee.bridge_snapshot;
1200         } else {
1201                 transfer_msg->dest.threeway.bridge_snapshot = transfer_msg->to_transfer_target.bridge_snapshot;
1202         }
1203
1204         return 0;
1205 }
1206
1207 int ast_attended_transfer_message_add_app(struct ast_attended_transfer_message *transfer_msg,
1208                 const char *app, struct ast_channel *replace_channel)
1209 {
1210         transfer_msg->dest_type = replace_channel ? AST_ATTENDED_TRANSFER_DEST_LOCAL_APP : AST_ATTENDED_TRANSFER_DEST_APP;
1211
1212         if (replace_channel) {
1213                 transfer_msg->replace_channel = ast_channel_snapshot_get_latest(ast_channel_uniqueid(replace_channel));
1214                 if (!transfer_msg->replace_channel) {
1215                         return -1;
1216                 }
1217         }
1218
1219         ast_copy_string(transfer_msg->dest.app, app, sizeof(transfer_msg->dest.app));
1220
1221         return 0;
1222 }
1223
1224 int ast_attended_transfer_message_add_link(struct ast_attended_transfer_message *transfer_msg,
1225                 struct ast_channel *locals[2])
1226 {
1227         int i;
1228
1229         transfer_msg->dest_type = AST_ATTENDED_TRANSFER_DEST_LINK;
1230         for (i = 0; i < 2; ++i) {
1231                 transfer_msg->dest.links[i] = ast_channel_snapshot_get_latest(ast_channel_uniqueid(locals[i]));
1232                 if (!transfer_msg->dest.links[i]) {
1233                         return -1;
1234                 }
1235         }
1236
1237         return 0;
1238 }
1239
1240 void ast_bridge_publish_attended_transfer(struct ast_attended_transfer_message *transfer_msg)
1241 {
1242         struct stasis_message *msg;
1243
1244         msg = stasis_message_create(ast_attended_transfer_type(), transfer_msg);
1245         if (!msg) {
1246                 return;
1247         }
1248
1249         stasis_publish(ast_bridge_topic_all(), msg);
1250         ao2_ref(msg, -1);
1251 }
1252
1253 struct ast_bridge_snapshot *ast_bridge_snapshot_get_latest(const char *uniqueid)
1254 {
1255         struct stasis_message *message;
1256         struct ast_bridge_snapshot *snapshot;
1257
1258         ast_assert(!ast_strlen_zero(uniqueid));
1259
1260         message = stasis_cache_get(ast_bridge_cache(),
1261                         ast_bridge_snapshot_type(),
1262                         uniqueid);
1263         if (!message) {
1264                 return NULL;
1265         }
1266
1267         snapshot = ao2_bump(stasis_message_data(message));
1268         ao2_ref(message, -1);
1269
1270         return snapshot;
1271 }
1272
1273 /*! \brief snapshot ID getter for caching topic */
1274 static const char *bridge_snapshot_get_id(struct stasis_message *msg)
1275 {
1276         struct ast_bridge_snapshot *snapshot;
1277         if (stasis_message_type(msg) != ast_bridge_snapshot_type()) {
1278                 return NULL;
1279         }
1280         snapshot = stasis_message_data(msg);
1281         return snapshot->uniqueid;
1282 }
1283
1284 static void stasis_bridging_cleanup(void)
1285 {
1286         STASIS_MESSAGE_TYPE_CLEANUP(ast_bridge_snapshot_type);
1287         STASIS_MESSAGE_TYPE_CLEANUP(ast_bridge_merge_message_type);
1288         STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_entered_bridge_type);
1289         STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_left_bridge_type);
1290         STASIS_MESSAGE_TYPE_CLEANUP(ast_blind_transfer_type);
1291         STASIS_MESSAGE_TYPE_CLEANUP(ast_attended_transfer_type);
1292
1293         ao2_cleanup(bridge_cache_all);
1294         bridge_cache_all = NULL;
1295 }
1296
1297 int ast_stasis_bridging_init(void)
1298 {
1299         int res = 0;
1300
1301         ast_register_cleanup(stasis_bridging_cleanup);
1302
1303         bridge_cache_all = stasis_cp_all_create("ast_bridge_topic_all",
1304                 bridge_snapshot_get_id);
1305
1306         if (!bridge_cache_all) {
1307                 return -1;
1308         }
1309
1310         res |= STASIS_MESSAGE_TYPE_INIT(ast_bridge_snapshot_type);
1311         res |= STASIS_MESSAGE_TYPE_INIT(ast_bridge_merge_message_type);
1312         res |= STASIS_MESSAGE_TYPE_INIT(ast_channel_entered_bridge_type);
1313         res |= STASIS_MESSAGE_TYPE_INIT(ast_channel_left_bridge_type);
1314         res |= STASIS_MESSAGE_TYPE_INIT(ast_blind_transfer_type);
1315         res |= STASIS_MESSAGE_TYPE_INIT(ast_attended_transfer_type);
1316
1317         return res;
1318 }