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