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