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