Asterisk - The Open Source Telephony Project GIT-master-754dea3
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Modules Pages
manager_bridges.c
Go to the documentation of this file.
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 The Asterisk Management Interface - AMI (bridge event handling)
22 *
23 * \author Kinsey Moore <kmoore@digium.com>
24 */
25
26#include "asterisk.h"
27
30#include "asterisk/manager.h"
32
33/*! \brief Message router for cached bridge state snapshot updates */
35
36/*** DOCUMENTATION
37 <managerEvent language="en_US" name="BridgeCreate">
38 <managerEventInstance class="EVENT_FLAG_CALL">
39 <since>
40 <version>12.0.0</version>
41 </since>
42 <synopsis>Raised when a bridge is created.</synopsis>
43 <syntax>
44 <bridge_snapshot/>
45 </syntax>
46 <see-also>
47 <ref type="managerEvent">BridgeDestroy</ref>
48 <ref type="managerEvent">BridgeEnter</ref>
49 <ref type="managerEvent">BridgeLeave</ref>
50 </see-also>
51 </managerEventInstance>
52 </managerEvent>
53 <managerEvent language="en_US" name="BridgeDestroy">
54 <managerEventInstance class="EVENT_FLAG_CALL">
55 <since>
56 <version>12.0.0</version>
57 </since>
58 <synopsis>Raised when a bridge is destroyed.</synopsis>
59 <syntax>
60 <bridge_snapshot/>
61 </syntax>
62 <see-also>
63 <ref type="managerEvent">BridgeCreate</ref>
64 <ref type="managerEvent">BridgeEnter</ref>
65 <ref type="managerEvent">BridgeLeave</ref>
66 </see-also>
67 </managerEventInstance>
68 </managerEvent>
69 <managerEvent language="en_US" name="BridgeEnter">
70 <managerEventInstance class="EVENT_FLAG_CALL">
71 <since>
72 <version>12.0.0</version>
73 </since>
74 <synopsis>Raised when a channel enters a bridge.</synopsis>
75 <syntax>
76 <bridge_snapshot/>
77 <channel_snapshot/>
78 <parameter name="SwapUniqueid">
79 <para>The uniqueid of the channel being swapped out of the bridge</para>
80 </parameter>
81 </syntax>
82 <see-also>
83 <ref type="managerEvent">BridgeCreate</ref>
84 <ref type="managerEvent">BridgeDestroy</ref>
85 <ref type="managerEvent">BridgeLeave</ref>
86 </see-also>
87 </managerEventInstance>
88 </managerEvent>
89 <managerEvent language="en_US" name="BridgeLeave">
90 <managerEventInstance class="EVENT_FLAG_CALL">
91 <since>
92 <version>12.0.0</version>
93 </since>
94 <synopsis>Raised when a channel leaves a bridge.</synopsis>
95 <syntax>
96 <bridge_snapshot/>
97 <channel_snapshot/>
98 </syntax>
99 <see-also>
100 <ref type="managerEvent">BridgeCreate</ref>
101 <ref type="managerEvent">BridgeDestroy</ref>
102 <ref type="managerEvent">BridgeEnter</ref>
103 </see-also>
104 </managerEventInstance>
105 </managerEvent>
106 <managerEvent language="en_US" name="BridgeVideoSourceUpdate">
107 <managerEventInstance class="EVENT_FLAG_CALL">
108 <since>
109 <version>13.13.0</version>
110 <version>14.2.0</version>
111 </since>
112 <synopsis>Raised when the channel that is the source of video in a bridge changes.</synopsis>
113 <syntax>
114 <bridge_snapshot/>
115 <parameter name="BridgePreviousVideoSource">
116 <para>The unique ID of the channel that was the video source.</para>
117 </parameter>
118 </syntax>
119 <see-also>
120 <ref type="managerEvent">BridgeCreate</ref>
121 <ref type="managerEvent">BridgeDestroy</ref>
122 </see-also>
123 </managerEventInstance>
124 </managerEvent>
125 <manager name="BridgeList" language="en_US">
126 <since>
127 <version>12.0.0</version>
128 </since>
129 <synopsis>
130 Get a list of bridges in the system.
131 </synopsis>
132 <syntax>
133 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
134 <parameter name="BridgeType">
135 <para>Optional type for filtering the resulting list of bridges.</para>
136 </parameter>
137 </syntax>
138 <description>
139 <para>Returns a list of bridges, optionally filtering on a bridge type.</para>
140 </description>
141 <see-also>
142 <ref type="manager">Bridge</ref>
143 <ref type="manager">BridgeDestroy</ref>
144 <ref type="manager">BridgeInfo</ref>
145 <ref type="manager">BridgeKick</ref>
146 </see-also>
147 </manager>
148 <manager name="BridgeInfo" language="en_US">
149 <since>
150 <version>12.0.0</version>
151 </since>
152 <synopsis>
153 Get information about a bridge.
154 </synopsis>
155 <syntax>
156 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
157 <parameter name="BridgeUniqueid" required="true">
158 <para>The unique ID of the bridge about which to retrieve information.</para>
159 </parameter>
160 </syntax>
161 <description>
162 <para>Returns detailed information about a bridge and the channels in it.</para>
163 </description>
164 <see-also>
165 <ref type="manager">Bridge</ref>
166 <ref type="manager">BridgeDestroy</ref>
167 <ref type="manager">BridgeKick</ref>
168 <ref type="manager">BridgeList</ref>
169 </see-also>
170 <responses>
171 <list-elements>
172 <managerEvent language="en_US" name="BridgeInfoChannel">
173 <managerEventInstance class="EVENT_FLAG_COMMAND">
174 <since>
175 <version>13.0.0</version>
176 </since>
177 <synopsis>Information about a channel in a bridge.</synopsis>
178 <syntax>
179 <channel_snapshot/>
180 </syntax>
181 </managerEventInstance>
182 </managerEvent>
183 </list-elements>
184 <managerEvent language="en_US" name="BridgeInfoComplete">
185 <managerEventInstance class="EVENT_FLAG_COMMAND">
186 <since>
187 <version>13.0.0</version>
188 </since>
189 <synopsis>Information about a bridge.</synopsis>
190 <syntax>
191 <bridge_snapshot/>
192 </syntax>
193 </managerEventInstance>
194 </managerEvent>
195 </responses>
196 </manager>
197 <manager name="BridgeDestroy" language="en_US">
198 <since>
199 <version>12.0.0</version>
200 </since>
201 <synopsis>
202 Destroy a bridge.
203 </synopsis>
204 <syntax>
205 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
206 <parameter name="BridgeUniqueid" required="true">
207 <para>The unique ID of the bridge to destroy.</para>
208 </parameter>
209 </syntax>
210 <description>
211 <para>Deletes the bridge, causing channels to continue or hang up.</para>
212 </description>
213 <see-also>
214 <ref type="manager">Bridge</ref>
215 <ref type="manager">BridgeInfo</ref>
216 <ref type="manager">BridgeKick</ref>
217 <ref type="manager">BridgeList</ref>
218 <ref type="managerEvent">BridgeDestroy</ref>
219 </see-also>
220 </manager>
221 <manager name="BridgeKick" language="en_US">
222 <since>
223 <version>12.0.0</version>
224 </since>
225 <synopsis>
226 Kick a channel from a bridge.
227 </synopsis>
228 <syntax>
229 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
230 <parameter name="BridgeUniqueid" required="false">
231 <para>The unique ID of the bridge containing the channel to
232 destroy. This parameter can be omitted, or supplied to insure
233 that the channel is not removed from the wrong bridge.</para>
234 </parameter>
235 <parameter name="Channel" required="true">
236 <para>The channel to kick out of a bridge.</para>
237 </parameter>
238 </syntax>
239 <description>
240 <para>The channel is removed from the bridge.</para>
241 </description>
242 <see-also>
243 <ref type="manager">Bridge</ref>
244 <ref type="manager">BridgeDestroy</ref>
245 <ref type="manager">BridgeInfo</ref>
246 <ref type="manager">BridgeList</ref>
247 <ref type="managerEvent">BridgeLeave</ref>
248 </see-also>
249 </manager>
250 ***/
251
252/*! \brief The \ref stasis subscription returned by the forwarding of the channel topic
253 * to the manager topic
254 */
256
258 const struct ast_bridge_snapshot *snapshot,
259 const char *prefix)
260{
261 struct ast_str *out = ast_str_create(128);
262 int res;
263
264 if (!out) {
265 return NULL;
266 }
267
268 res = ast_str_set(&out, 0,
269 "%sBridgeUniqueid: %s\r\n"
270 "%sBridgeType: %s\r\n"
271 "%sBridgeTechnology: %s\r\n"
272 "%sBridgeCreator: %s\r\n"
273 "%sBridgeName: %s\r\n"
274 "%sBridgeNumChannels: %u\r\n"
275 "%sBridgeVideoSourceMode: %s\r\n",
276 prefix, snapshot->uniqueid,
277 prefix, snapshot->subclass,
278 prefix, snapshot->technology,
279 prefix, ast_strlen_zero(snapshot->creator) ? "<unknown>": snapshot->creator,
280 prefix, ast_strlen_zero(snapshot->name) ? "<unknown>": snapshot->name,
281 prefix, snapshot->num_channels,
283 if (!res) {
284 ast_free(out);
285 return NULL;
286 }
287
289 && !ast_strlen_zero(snapshot->video_source_id)) {
290 res = ast_str_append(&out, 0, "%sBridgeVideoSource: %s\r\n",
291 prefix, snapshot->video_source_id);
292 if (!res) {
293 ast_free(out);
294 return NULL;
295 }
296 }
297
298 return out;
299}
300
302 const struct ast_bridge_snapshot *snapshot)
303{
305}
306
307/*! \brief Typedef for callbacks that get called on channel snapshot updates */
308typedef struct ast_manager_event_blob *(*bridge_snapshot_monitor)(
309 struct ast_bridge_snapshot *old_snapshot,
310 struct ast_bridge_snapshot *new_snapshot);
311
312/*! \brief Handle bridge creation */
314 struct ast_bridge_snapshot *old_snapshot,
315 struct ast_bridge_snapshot *new_snapshot)
316{
317 if (!new_snapshot || old_snapshot) {
318 return NULL;
319 }
320
322 EVENT_FLAG_CALL, "BridgeCreate", NO_EXTRA_FIELDS);
323}
324
325/*! \brief Handle video source updates */
327 struct ast_bridge_snapshot *old_snapshot,
328 struct ast_bridge_snapshot *new_snapshot)
329{
330 if (!new_snapshot || !old_snapshot) {
331 return NULL;
332 }
333
334 if (!strcmp(old_snapshot->video_source_id, new_snapshot->video_source_id)) {
335 return NULL;
336 }
337
339 EVENT_FLAG_CALL, "BridgeVideoSourceUpdate",
340 "BridgePreviousVideoSource: %s\r\n",
341 old_snapshot->video_source_id);
342}
343
344/*! \brief Handle bridge destruction */
346 struct ast_bridge_snapshot *old_snapshot,
347 struct ast_bridge_snapshot *new_snapshot)
348{
349 if (new_snapshot || !old_snapshot) {
350 return NULL;
351 }
352
354 EVENT_FLAG_CALL, "BridgeDestroy", NO_EXTRA_FIELDS);
355}
356
361};
362
363static void bridge_snapshot_update(void *data, struct stasis_subscription *sub,
364 struct stasis_message *message)
365{
366 RAII_VAR(struct ast_str *, bridge_event_string, NULL, ast_free);
368 size_t i;
369
371
372 for (i = 0; i < ARRAY_LEN(bridge_monitors); ++i) {
374
375 event = bridge_monitors[i](update->old_snapshot, update->new_snapshot);
376 if (!event) {
377 continue;
378 }
379
380 /* If we haven't already, build the channel event string */
381 if (!bridge_event_string) {
382 bridge_event_string =
384 update->new_snapshot ? update->new_snapshot : update->old_snapshot);
385 if (!bridge_event_string) {
386 return;
387 }
388 }
389
390 manager_event(event->event_flags, event->manager_event, "%s%s",
391 ast_str_buffer(bridge_event_string),
392 event->extra_fields);
393 }
394}
395
396static void bridge_merge_cb(void *data, struct stasis_subscription *sub,
397 struct stasis_message *message)
398{
400 RAII_VAR(struct ast_str *, to_text, NULL, ast_free);
401 RAII_VAR(struct ast_str *, from_text, NULL, ast_free);
402
403 ast_assert(merge_msg->to != NULL);
404 ast_assert(merge_msg->from != NULL);
405
406 to_text = ast_manager_build_bridge_state_string_prefix(merge_msg->to, "To");
407 from_text = ast_manager_build_bridge_state_string_prefix(merge_msg->from, "From");
408 if (!to_text || !from_text) {
409 return;
410 }
411
412 /*** DOCUMENTATION
413 <managerEvent language="en_US" name="BridgeMerge">
414 <managerEventInstance class="EVENT_FLAG_CALL">
415 <since>
416 <version>16.24.0</version>
417 <version>18.10.0</version>
418 <version>19.2.0</version>
419 </since>
420 <synopsis>Raised when two bridges are merged.</synopsis>
421 <syntax>
422 <bridge_snapshot prefix="To"/>
423 <bridge_snapshot prefix="From"/>
424 </syntax>
425 </managerEventInstance>
426 </managerEvent>
427 ***/
428 manager_event(EVENT_FLAG_CALL, "BridgeMerge",
429 "%s"
430 "%s",
431 ast_str_buffer(to_text),
432 ast_str_buffer(from_text));
433}
434
435static void channel_enter_cb(void *data, struct stasis_subscription *sub,
436 struct stasis_message *message)
437{
438 static const char *swap_name = "SwapUniqueid: ";
440 RAII_VAR(struct ast_str *, bridge_text, NULL, ast_free);
441 RAII_VAR(struct ast_str *, channel_text, NULL, ast_free);
442 const char *swap_id;
443
444 bridge_text = ast_manager_build_bridge_state_string(blob->bridge);
445 channel_text = ast_manager_build_channel_state_string(blob->channel);
446 if (!bridge_text || !channel_text) {
447 return;
448 }
449
450 swap_id = ast_json_string_get(ast_json_object_get(blob->blob, "swap"));
451
452 manager_event(EVENT_FLAG_CALL, "BridgeEnter",
453 "%s"
454 "%s"
455 "%s%s%s",
456 ast_str_buffer(bridge_text),
457 ast_str_buffer(channel_text),
458 swap_id ? swap_name : "",
459 S_OR(swap_id, ""),
460 swap_id ? "\r\n" : "");
461}
462
463static void channel_leave_cb(void *data, struct stasis_subscription *sub,
464 struct stasis_message *message)
465{
467 RAII_VAR(struct ast_str *, bridge_text, NULL, ast_free);
468 RAII_VAR(struct ast_str *, channel_text, NULL, ast_free);
469
470 bridge_text = ast_manager_build_bridge_state_string(blob->bridge);
471 channel_text = ast_manager_build_channel_state_string(blob->channel);
472 if (!bridge_text || !channel_text) {
473 return;
474 }
475
476 manager_event(EVENT_FLAG_CALL, "BridgeLeave",
477 "%s"
478 "%s",
479 ast_str_buffer(bridge_text),
480 ast_str_buffer(channel_text));
481}
482
485 const char *type_filter;
486 int count;
487};
488
489static int send_bridge_list_item_cb(void *obj, void *arg, void *data, int flags)
490{
491 struct ast_bridge *bridge = obj;
493 struct mansession *s = arg;
494 struct bridge_list_data *list_data = data;
495 struct ast_str * bridge_info;
496
497 if (!snapshot) {
498 return 0;
499 }
500
501 if (!ast_strlen_zero(list_data->type_filter)
502 && strcmp(list_data->type_filter, snapshot->technology)) {
503 return 0;
504 }
505
506 bridge_info = ast_manager_build_bridge_state_string(snapshot);
507 if (!bridge_info) {
508 return 0;
509 }
510
512 "Event: BridgeListItem\r\n"
513 "%s"
514 "%s"
515 "\r\n",
516 ast_str_buffer(list_data->id_text),
517 ast_str_buffer(bridge_info));
518 ++list_data->count;
519
520 ast_free(bridge_info);
521
522 return 0;
523}
524
525static int manager_bridges_list(struct mansession *s, const struct message *m)
526{
527 const char *id = astman_get_header(m, "ActionID");
528 const char *type_filter = astman_get_header(m, "BridgeType");
529 struct ao2_container *bridges;
530 struct bridge_list_data list_data = { 0 };
531
533 if (!bridges) {
534 astman_send_error(s, m, "Internal error");
535 return -1;
536 }
537
538 list_data.id_text = ast_str_create(128);
539 if (!list_data.id_text) {
540 ao2_ref(bridges, -1);
541 astman_send_error(s, m, "Internal error");
542 return -1;
543 }
544
545 if (!ast_strlen_zero(id)) {
546 ast_str_set(&list_data.id_text, 0, "ActionID: %s\r\n", id);
547 }
548 list_data.type_filter = type_filter;
549
550 astman_send_listack(s, m, "Bridge listing will follow", "start");
551
553
554 astman_send_list_complete_start(s, m, "BridgeListComplete", list_data.count);
556
557 ast_free(list_data.id_text);
558 ao2_ref(bridges, -1);
559
560 return 0;
561}
562
563static int send_bridge_info_item_cb(void *obj, void *arg, void *data, int flags)
564{
565 char *uniqueid = obj;
566 struct mansession *s = arg;
567 struct bridge_list_data *list_data = data;
568 RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);
569 RAII_VAR(struct ast_str *, channel_text, NULL, ast_free);
570
571 snapshot = ast_channel_snapshot_get_latest(uniqueid);
572 if (!snapshot) {
573 return 0;
574 }
575
576 if (snapshot->base->tech_properties & AST_CHAN_TP_INTERNAL) {
577 return 0;
578 }
579
580 channel_text = ast_manager_build_channel_state_string(snapshot);
581 if (!channel_text) {
582 return 0;
583 }
584
586 "Event: BridgeInfoChannel\r\n"
587 "%s"
588 "%s"
589 "\r\n",
590 ast_str_buffer(list_data->id_text),
591 ast_str_buffer(channel_text));
592 ++list_data->count;
593 return 0;
594}
595
596static int manager_bridge_info(struct mansession *s, const struct message *m)
597{
598 const char *id = astman_get_header(m, "ActionID");
599 const char *bridge_uniqueid = astman_get_header(m, "BridgeUniqueid");
600 RAII_VAR(struct ast_str *, bridge_info, NULL, ast_free);
601 RAII_VAR(struct ast_bridge_snapshot *, snapshot, NULL, ao2_cleanup);
602 struct bridge_list_data list_data = { 0 };
603
604 if (ast_strlen_zero(bridge_uniqueid)) {
605 astman_send_error(s, m, "BridgeUniqueid must be provided");
606 return 0;
607 }
608
609 snapshot = ast_bridge_get_snapshot_by_uniqueid(bridge_uniqueid);
610 if (!snapshot) {
611 astman_send_error(s, m, "Specified BridgeUniqueid not found");
612 return 0;
613 }
614
615 bridge_info = ast_manager_build_bridge_state_string(snapshot);
616 if (!bridge_info) {
617 astman_send_error(s, m, "Internal error");
618 return -1;
619 }
620
621 list_data.id_text = ast_str_create(128);
622 if (!list_data.id_text) {
623 astman_send_error(s, m, "Internal error");
624 return -1;
625 }
626
627 if (!ast_strlen_zero(id)) {
628 ast_str_set(&list_data.id_text, 0, "ActionID: %s\r\n", id);
629 }
630
631 astman_send_listack(s, m, "Bridge channel listing will follow", "start");
632
633 ao2_callback_data(snapshot->channels, OBJ_NODATA, send_bridge_info_item_cb, s, &list_data);
634
635 astman_send_list_complete_start(s, m, "BridgeInfoComplete", list_data.count);
636 if (!ast_strlen_zero(ast_str_buffer(bridge_info))) {
637 astman_append(s, "%s", ast_str_buffer(bridge_info));
638 }
640 ast_free(list_data.id_text);
641
642 return 0;
643}
644
645static int manager_bridge_destroy(struct mansession *s, const struct message *m)
646{
647 const char *bridge_uniqueid = astman_get_header(m, "BridgeUniqueid");
648 struct ast_bridge *bridge;
649
650 if (ast_strlen_zero(bridge_uniqueid)) {
651 astman_send_error(s, m, "BridgeUniqueid must be provided");
652 return 0;
653 }
654
655 bridge = ast_bridge_find_by_id(bridge_uniqueid);
656 if (!bridge) {
657 astman_send_error(s, m, "Specified BridgeUniqueid not found");
658 return 0;
659 }
660 ast_bridge_destroy(bridge, 0);
661
662 astman_send_ack(s, m, "Bridge has been destroyed");
663
664 return 0;
665}
666
667static int manager_bridge_kick(struct mansession *s, const struct message *m)
668{
669 const char *bridge_uniqueid = astman_get_header(m, "BridgeUniqueid");
670 const char *channel_name = astman_get_header(m, "Channel");
671 RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
672 RAII_VAR(struct ast_channel *, channel, NULL, ao2_cleanup);
673
674 if (ast_strlen_zero(channel_name)) {
675 astman_send_error(s, m, "Channel must be provided");
676 return 0;
677 }
678
679 channel = ast_channel_get_by_name(channel_name);
680 if (!channel) {
681 astman_send_error(s, m, "Channel does not exist");
682 return 0;
683 }
684
685 if (ast_strlen_zero(bridge_uniqueid)) {
686 /* get the bridge from the channel */
687 ast_channel_lock(channel);
688 bridge = ast_channel_get_bridge(channel);
689 ast_channel_unlock(channel);
690 if (!bridge) {
691 astman_send_error(s, m, "Channel is not in a bridge");
692 return 0;
693 }
694 } else {
695 bridge = ast_bridge_find_by_id(bridge_uniqueid);
696 if (!bridge || ast_test_flag(&bridge->feature_flags, AST_BRIDGE_FLAG_INVISIBLE)) {
697 astman_send_error(s, m, "Bridge not found");
698 return 0;
699 }
700 }
701
702 if (ast_bridge_kick(bridge, channel)) {
703 astman_send_error(s, m, "Channel kick from bridge failed");
704 return 0;
705 }
706
707 astman_send_ack(s, m, "Channel has been kicked");
708 return 0;
709}
710
712{
715
716 ast_manager_unregister("BridgeList");
717 ast_manager_unregister("BridgeInfo");
718 ast_manager_unregister("BridgeDestroy");
719 ast_manager_unregister("BridgeKick");
720}
721
723{
724 int ret = 0;
726 struct stasis_topic *bridge_topic;
727
729 /* Already initialized */
730 return 0;
731 }
732
734
736 if (!manager_topic) {
737 return -1;
738 }
739
740 bridge_topic = ast_bridge_topic_all();
741 if (!bridge_topic) {
742 return -1;
743 }
744
746 if (!topic_forwarder) {
747 return -1;
748 }
749
751 if (!bridge_state_router) {
752 return -1;
753 }
754
757
760
763
766
768 ret |= ast_manager_register_xml_core("BridgeInfo", 0, manager_bridge_info);
769 ret |= ast_manager_register_xml_core("BridgeDestroy", 0, manager_bridge_destroy);
770 ret |= ast_manager_register_xml_core("BridgeKick", 0, manager_bridge_kick);
771
772 /* If somehow we failed to add any routes, just shut down the whole
773 * thing and fail it.
774 */
775 if (ret) {
777 return -1;
778 }
779
780 return 0;
781}
Asterisk main include file. File version handling, generic pbx functions.
int ast_register_cleanup(void(*func)(void))
Register a function to be executed before Asterisk gracefully exits.
Definition: clicompat.c:19
#define ast_free(a)
Definition: astmm.h:180
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
#define ao2_callback_data(container, flags, cb_fn, arg, data)
Definition: astobj2.h:1723
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
@ OBJ_NODATA
Definition: astobj2.h:1044
static struct ao2_container * bridges
Definition: bridge.c:132
struct ao2_container * ast_bridges(void)
Returns the global bridges container.
Definition: bridge.c:185
int ast_bridge_destroy(struct ast_bridge *bridge, int cause)
Destroy a bridge.
Definition: bridge.c:1009
int ast_bridge_kick(struct ast_bridge *bridge, struct ast_channel *chan)
Kick a channel from a bridge.
Definition: bridge.c:2048
struct ast_bridge * ast_bridge_find_by_id(const char *bridge_id)
Find bridge by id.
Definition: bridge.c:5081
const char * ast_bridge_video_mode_to_string(enum ast_bridge_video_mode_type video_mode)
Converts an enum representation of a bridge video mode to string.
Definition: bridge.c:4020
@ AST_BRIDGE_VIDEO_MODE_NONE
Definition: bridge.h:104
@ AST_BRIDGE_FLAG_INVISIBLE
#define ast_channel_lock(chan)
Definition: channel.h:2970
@ AST_CHAN_TP_INTERNAL
Channels with this particular technology are an implementation detail of Asterisk and should generall...
Definition: channel.h:991
struct ast_bridge * ast_channel_get_bridge(const struct ast_channel *chan)
Get the bridge associated with a channel.
Definition: channel.c:10560
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1481
#define ast_channel_unlock(chan)
Definition: channel.h:2971
static void update(int code_size, int y, int wi, int fi, int dq, int sr, int dqsez, struct g726_state *state_ptr)
Definition: codec_g726.c:367
void astman_send_listack(struct mansession *s, const struct message *m, char *msg, char *listflag)
Send ack in manager transaction to begin a list.
Definition: manager.c:2028
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:1986
void astman_send_list_complete_start(struct mansession *s, const struct message *m, const char *event_name, int count)
Start the list complete event.
Definition: manager.c:2064
struct stasis_message_router * ast_manager_get_message_router(void)
Get the stasis_message_router for AMI.
Definition: manager.c:459
struct stasis_topic * ast_manager_get_topic(void)
Get the Stasis Message Bus API topic for AMI.
Definition: manager.c:454
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:2018
const char * astman_get_header(const struct message *m, char *var)
Get header from manager transaction.
Definition: manager.c:1647
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
Definition: manager.c:2072
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:1907
static struct stasis_topic * manager_topic
A stasis_topic that all topics AMI cares about will be forwarded to.
Definition: manager.c:186
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
Definition: manager.c:7697
struct ast_channel_snapshot * ast_channel_snapshot_get_latest(const char *uniqueid)
Obtain the latest ast_channel_snapshot from the Stasis Message Bus API cache. This is an ao2 object,...
static char prefix[MAX_PREFIX]
Definition: http.c:144
const char * ast_json_string_get(const struct ast_json *string)
Get the value of a JSON string.
Definition: json.c:283
struct ast_json * ast_json_object_get(struct ast_json *object, const char *key)
Get a field from a JSON object.
Definition: json.c:407
The AMI - Asterisk Manager Interface - is a TCP protocol created to manage Asterisk with third-party ...
#define ast_manager_register_xml_core(action, authority, func)
Register a manager callback using XML documentation to describe the manager.
Definition: manager.h:203
#define manager_event(category, event, contents,...)
External routines may send asterisk manager events this way.
Definition: manager.h:254
struct ast_str * ast_manager_build_channel_state_string(const struct ast_channel_snapshot *snapshot)
Generate the AMI message body from a channel snapshot.
#define NO_EXTRA_FIELDS
Definition: manager.h:534
struct ast_manager_event_blob * ast_manager_event_blob_create(int event_flags, const char *manager_event, const char *extra_fields_fmt,...)
Construct a ast_manager_event_blob.
Definition: manager.c:10237
#define EVENT_FLAG_CALL
Definition: manager.h:76
bridge_snapshot_monitor bridge_monitors[]
static int send_bridge_list_item_cb(void *obj, void *arg, void *data, int flags)
int manager_bridging_init(void)
Initialize support for AMI channel events.
static void bridge_merge_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
static struct stasis_message_router * bridge_state_router
Message router for cached bridge state snapshot updates.
static void channel_leave_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
static struct ast_manager_event_blob * bridge_create(struct ast_bridge_snapshot *old_snapshot, struct ast_bridge_snapshot *new_snapshot)
Handle bridge creation.
struct ast_str * ast_manager_build_bridge_state_string_prefix(const struct ast_bridge_snapshot *snapshot, const char *prefix)
Generate the AMI message body from a bridge snapshot.
static int manager_bridge_kick(struct mansession *s, const struct message *m)
static struct ast_manager_event_blob * bridge_destroy(struct ast_bridge_snapshot *old_snapshot, struct ast_bridge_snapshot *new_snapshot)
Handle bridge destruction.
static int manager_bridges_list(struct mansession *s, const struct message *m)
static void manager_bridging_cleanup(void)
static int manager_bridge_destroy(struct mansession *s, const struct message *m)
static int manager_bridge_info(struct mansession *s, const struct message *m)
static int send_bridge_info_item_cb(void *obj, void *arg, void *data, int flags)
static struct ast_manager_event_blob * bridge_video_update(struct ast_bridge_snapshot *old_snapshot, struct ast_bridge_snapshot *new_snapshot)
Handle video source updates.
struct ast_str * ast_manager_build_bridge_state_string(const struct ast_bridge_snapshot *snapshot)
Generate the AMI message body from a bridge snapshot.
struct ast_manager_event_blob *(* bridge_snapshot_monitor)(struct ast_bridge_snapshot *old_snapshot, struct ast_bridge_snapshot *new_snapshot)
Typedef for callbacks that get called on channel snapshot updates.
static void bridge_snapshot_update(void *data, struct stasis_subscription *sub, struct stasis_message *message)
static void channel_enter_cb(void *data, struct stasis_subscription *sub, struct stasis_message *message)
static struct stasis_forward * topic_forwarder
The Stasis Message Bus API subscription returned by the forwarding of the channel topic to the manage...
struct stasis_forward * sub
Definition: res_corosync.c:240
#define NULL
Definition: resample.c:96
struct stasis_forward * stasis_forward_cancel(struct stasis_forward *forward)
Definition: stasis.c:1575
void * stasis_message_data(const struct stasis_message *msg)
Get the data contained in a message.
struct stasis_forward * stasis_forward_all(struct stasis_topic *from_topic, struct stasis_topic *to_topic)
Create a subscription which forwards all messages from one topic to another.
Definition: stasis.c:1605
struct ast_bridge_snapshot * ast_bridge_get_snapshot(struct ast_bridge *bridge)
Returns the current snapshot for the bridge.
struct ast_bridge_snapshot * ast_bridge_get_snapshot_by_uniqueid(const char *bridge_id)
Returns the current snapshot for the bridge.
struct stasis_message_type * ast_bridge_snapshot_type(void)
Message type for ast_bridge_snapshot.
struct stasis_message_type * ast_channel_entered_bridge_type(void)
Message type for ast_channel enter bridge blob messages.
struct stasis_message_type * ast_bridge_merge_message_type(void)
Message type for ast_bridge_merge_message.
struct stasis_topic * ast_bridge_topic_all(void)
A topic which publishes the events for all bridges.
struct stasis_message_type * ast_channel_left_bridge_type(void)
Message type for ast_channel leave bridge blob messages.
int stasis_message_router_add(struct stasis_message_router *router, struct stasis_message_type *message_type, stasis_subscription_cb callback, void *data)
Add a route to a message router.
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition: strings.h:1139
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition: strings.h:761
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition: strings.h:80
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:65
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition: strings.h:659
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition: strings.h:1113
Generic container type.
Blob of data associated with a bridge.
struct ast_json * blob
Message representing the merge of two bridges.
struct ast_bridge_snapshot * from
struct ast_bridge_snapshot * to
Structure that contains a snapshot of information about a bridge.
Definition: bridge.h:318
enum ast_bridge_video_mode_type video_mode
Definition: bridge.h:345
const ast_string_field video_source_id
Definition: bridge.h:332
const ast_string_field creator
Definition: bridge.h:332
const ast_string_field uniqueid
Definition: bridge.h:332
unsigned int num_channels
Definition: bridge.h:341
const ast_string_field technology
Definition: bridge.h:332
const ast_string_field name
Definition: bridge.h:332
const ast_string_field subclass
Definition: bridge.h:332
Structure that contains information about a bridge.
Definition: bridge.h:353
Structure representing a snapshot of channel state.
Main Channel structure associated with a channel.
Struct containing info for an AMI event to send out.
Definition: manager.h:503
Support for dynamic strings.
Definition: strings.h:623
const char * type_filter
struct ast_str * id_text
Definition: astman.c:222
In case you didn't read that giant block of text above the mansession_session struct,...
Definition: manager.c:327
Forwarding information.
Definition: stasis.c:1558
FILE * out
Definition: utils/frame.c:33
#define ast_test_flag(p, flag)
Definition: utils.h:63
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941
#define ast_assert(a)
Definition: utils.h:739
#define ARRAY_LEN(a)
Definition: utils.h:666