Asterisk - The Open Source Telephony Project GIT-master-3dae2cf
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 <synopsis>Raised when a bridge is created.</synopsis>
40 <syntax>
41 <bridge_snapshot/>
42 </syntax>
43 <see-also>
44 <ref type="managerEvent">BridgeDestroy</ref>
45 <ref type="managerEvent">BridgeEnter</ref>
46 <ref type="managerEvent">BridgeLeave</ref>
47 </see-also>
48 </managerEventInstance>
49 </managerEvent>
50 <managerEvent language="en_US" name="BridgeDestroy">
51 <managerEventInstance class="EVENT_FLAG_CALL">
52 <synopsis>Raised when a bridge is destroyed.</synopsis>
53 <syntax>
54 <bridge_snapshot/>
55 </syntax>
56 <see-also>
57 <ref type="managerEvent">BridgeCreate</ref>
58 <ref type="managerEvent">BridgeEnter</ref>
59 <ref type="managerEvent">BridgeLeave</ref>
60 </see-also>
61 </managerEventInstance>
62 </managerEvent>
63 <managerEvent language="en_US" name="BridgeEnter">
64 <managerEventInstance class="EVENT_FLAG_CALL">
65 <synopsis>Raised when a channel enters a bridge.</synopsis>
66 <syntax>
67 <bridge_snapshot/>
68 <channel_snapshot/>
69 <parameter name="SwapUniqueid">
70 <para>The uniqueid of the channel being swapped out of the bridge</para>
71 </parameter>
72 </syntax>
73 <see-also>
74 <ref type="managerEvent">BridgeCreate</ref>
75 <ref type="managerEvent">BridgeDestroy</ref>
76 <ref type="managerEvent">BridgeLeave</ref>
77 </see-also>
78 </managerEventInstance>
79 </managerEvent>
80 <managerEvent language="en_US" name="BridgeLeave">
81 <managerEventInstance class="EVENT_FLAG_CALL">
82 <synopsis>Raised when a channel leaves a bridge.</synopsis>
83 <syntax>
84 <bridge_snapshot/>
85 <channel_snapshot/>
86 </syntax>
87 <see-also>
88 <ref type="managerEvent">BridgeCreate</ref>
89 <ref type="managerEvent">BridgeDestroy</ref>
90 <ref type="managerEvent">BridgeEnter</ref>
91 </see-also>
92 </managerEventInstance>
93 </managerEvent>
94 <managerEvent language="en_US" name="BridgeVideoSourceUpdate">
95 <managerEventInstance class="EVENT_FLAG_CALL">
96 <synopsis>Raised when the channel that is the source of video in a bridge changes.</synopsis>
97 <syntax>
98 <bridge_snapshot/>
99 <parameter name="BridgePreviousVideoSource">
100 <para>The unique ID of the channel that was the video source.</para>
101 </parameter>
102 </syntax>
103 <see-also>
104 <ref type="managerEvent">BridgeCreate</ref>
105 <ref type="managerEvent">BridgeDestroy</ref>
106 </see-also>
107 </managerEventInstance>
108 </managerEvent>
109 <manager name="BridgeList" language="en_US">
110 <synopsis>
111 Get a list of bridges in the system.
112 </synopsis>
113 <syntax>
114 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
115 <parameter name="BridgeType">
116 <para>Optional type for filtering the resulting list of bridges.</para>
117 </parameter>
118 </syntax>
119 <description>
120 <para>Returns a list of bridges, optionally filtering on a bridge type.</para>
121 </description>
122 <see-also>
123 <ref type="manager">Bridge</ref>
124 <ref type="manager">BridgeDestroy</ref>
125 <ref type="manager">BridgeInfo</ref>
126 <ref type="manager">BridgeKick</ref>
127 </see-also>
128 </manager>
129 <manager name="BridgeInfo" language="en_US">
130 <synopsis>
131 Get information about a bridge.
132 </synopsis>
133 <syntax>
134 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
135 <parameter name="BridgeUniqueid" required="true">
136 <para>The unique ID of the bridge about which to retrieve information.</para>
137 </parameter>
138 </syntax>
139 <description>
140 <para>Returns detailed information about a bridge and the channels in it.</para>
141 </description>
142 <see-also>
143 <ref type="manager">Bridge</ref>
144 <ref type="manager">BridgeDestroy</ref>
145 <ref type="manager">BridgeKick</ref>
146 <ref type="manager">BridgeList</ref>
147 </see-also>
148 <responses>
149 <list-elements>
150 <managerEvent language="en_US" name="BridgeInfoChannel">
151 <managerEventInstance class="EVENT_FLAG_COMMAND">
152 <synopsis>Information about a channel in a bridge.</synopsis>
153 <syntax>
154 <channel_snapshot/>
155 </syntax>
156 </managerEventInstance>
157 </managerEvent>
158 </list-elements>
159 <managerEvent language="en_US" name="BridgeInfoComplete">
160 <managerEventInstance class="EVENT_FLAG_COMMAND">
161 <synopsis>Information about a bridge.</synopsis>
162 <syntax>
163 <bridge_snapshot/>
164 </syntax>
165 </managerEventInstance>
166 </managerEvent>
167 </responses>
168 </manager>
169 <manager name="BridgeDestroy" language="en_US">
170 <synopsis>
171 Destroy a bridge.
172 </synopsis>
173 <syntax>
174 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
175 <parameter name="BridgeUniqueid" required="true">
176 <para>The unique ID of the bridge to destroy.</para>
177 </parameter>
178 </syntax>
179 <description>
180 <para>Deletes the bridge, causing channels to continue or hang up.</para>
181 </description>
182 <see-also>
183 <ref type="manager">Bridge</ref>
184 <ref type="manager">BridgeInfo</ref>
185 <ref type="manager">BridgeKick</ref>
186 <ref type="manager">BridgeList</ref>
187 <ref type="managerEvent">BridgeDestroy</ref>
188 </see-also>
189 </manager>
190 <manager name="BridgeKick" language="en_US">
191 <synopsis>
192 Kick a channel from a bridge.
193 </synopsis>
194 <syntax>
195 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
196 <parameter name="BridgeUniqueid" required="false">
197 <para>The unique ID of the bridge containing the channel to
198 destroy. This parameter can be omitted, or supplied to insure
199 that the channel is not removed from the wrong bridge.</para>
200 </parameter>
201 <parameter name="Channel" required="true">
202 <para>The channel to kick out of a bridge.</para>
203 </parameter>
204 </syntax>
205 <description>
206 <para>The channel is removed from the bridge.</para>
207 </description>
208 <see-also>
209 <ref type="manager">Bridge</ref>
210 <ref type="manager">BridgeDestroy</ref>
211 <ref type="manager">BridgeInfo</ref>
212 <ref type="manager">BridgeList</ref>
213 <ref type="managerEvent">BridgeLeave</ref>
214 </see-also>
215 </manager>
216 ***/
217
218/*! \brief The \ref stasis subscription returned by the forwarding of the channel topic
219 * to the manager topic
220 */
222
224 const struct ast_bridge_snapshot *snapshot,
225 const char *prefix)
226{
227 struct ast_str *out = ast_str_create(128);
228 int res;
229
230 if (!out) {
231 return NULL;
232 }
233
234 res = ast_str_set(&out, 0,
235 "%sBridgeUniqueid: %s\r\n"
236 "%sBridgeType: %s\r\n"
237 "%sBridgeTechnology: %s\r\n"
238 "%sBridgeCreator: %s\r\n"
239 "%sBridgeName: %s\r\n"
240 "%sBridgeNumChannels: %u\r\n"
241 "%sBridgeVideoSourceMode: %s\r\n",
242 prefix, snapshot->uniqueid,
243 prefix, snapshot->subclass,
244 prefix, snapshot->technology,
245 prefix, ast_strlen_zero(snapshot->creator) ? "<unknown>": snapshot->creator,
246 prefix, ast_strlen_zero(snapshot->name) ? "<unknown>": snapshot->name,
247 prefix, snapshot->num_channels,
249 if (!res) {
250 ast_free(out);
251 return NULL;
252 }
253
255 && !ast_strlen_zero(snapshot->video_source_id)) {
256 res = ast_str_append(&out, 0, "%sBridgeVideoSource: %s\r\n",
257 prefix, snapshot->video_source_id);
258 if (!res) {
259 ast_free(out);
260 return NULL;
261 }
262 }
263
264 return out;
265}
266
268 const struct ast_bridge_snapshot *snapshot)
269{
271}
272
273/*! \brief Typedef for callbacks that get called on channel snapshot updates */
274typedef struct ast_manager_event_blob *(*bridge_snapshot_monitor)(
275 struct ast_bridge_snapshot *old_snapshot,
276 struct ast_bridge_snapshot *new_snapshot);
277
278/*! \brief Handle bridge creation */
280 struct ast_bridge_snapshot *old_snapshot,
281 struct ast_bridge_snapshot *new_snapshot)
282{
283 if (!new_snapshot || old_snapshot) {
284 return NULL;
285 }
286
288 EVENT_FLAG_CALL, "BridgeCreate", NO_EXTRA_FIELDS);
289}
290
291/*! \brief Handle video source updates */
293 struct ast_bridge_snapshot *old_snapshot,
294 struct ast_bridge_snapshot *new_snapshot)
295{
296 if (!new_snapshot || !old_snapshot) {
297 return NULL;
298 }
299
300 if (!strcmp(old_snapshot->video_source_id, new_snapshot->video_source_id)) {
301 return NULL;
302 }
303
305 EVENT_FLAG_CALL, "BridgeVideoSourceUpdate",
306 "BridgePreviousVideoSource: %s\r\n",
307 old_snapshot->video_source_id);
308}
309
310/*! \brief Handle bridge destruction */
312 struct ast_bridge_snapshot *old_snapshot,
313 struct ast_bridge_snapshot *new_snapshot)
314{
315 if (new_snapshot || !old_snapshot) {
316 return NULL;
317 }
318
320 EVENT_FLAG_CALL, "BridgeDestroy", NO_EXTRA_FIELDS);
321}
322
327};
328
329static void bridge_snapshot_update(void *data, struct stasis_subscription *sub,
330 struct stasis_message *message)
331{
332 RAII_VAR(struct ast_str *, bridge_event_string, NULL, ast_free);
334 size_t i;
335
337
338 for (i = 0; i < ARRAY_LEN(bridge_monitors); ++i) {
340
341 event = bridge_monitors[i](update->old_snapshot, update->new_snapshot);
342 if (!event) {
343 continue;
344 }
345
346 /* If we haven't already, build the channel event string */
347 if (!bridge_event_string) {
348 bridge_event_string =
350 update->new_snapshot ? update->new_snapshot : update->old_snapshot);
351 if (!bridge_event_string) {
352 return;
353 }
354 }
355
356 manager_event(event->event_flags, event->manager_event, "%s%s",
357 ast_str_buffer(bridge_event_string),
358 event->extra_fields);
359 }
360}
361
362static void bridge_merge_cb(void *data, struct stasis_subscription *sub,
363 struct stasis_message *message)
364{
366 RAII_VAR(struct ast_str *, to_text, NULL, ast_free);
367 RAII_VAR(struct ast_str *, from_text, NULL, ast_free);
368
369 ast_assert(merge_msg->to != NULL);
370 ast_assert(merge_msg->from != NULL);
371
372 to_text = ast_manager_build_bridge_state_string_prefix(merge_msg->to, "To");
373 from_text = ast_manager_build_bridge_state_string_prefix(merge_msg->from, "From");
374 if (!to_text || !from_text) {
375 return;
376 }
377
378 /*** DOCUMENTATION
379 <managerEvent language="en_US" name="BridgeMerge">
380 <managerEventInstance class="EVENT_FLAG_CALL">
381 <synopsis>Raised when two bridges are merged.</synopsis>
382 <syntax>
383 <bridge_snapshot prefix="To"/>
384 <bridge_snapshot prefix="From"/>
385 </syntax>
386 </managerEventInstance>
387 </managerEvent>
388 ***/
389 manager_event(EVENT_FLAG_CALL, "BridgeMerge",
390 "%s"
391 "%s",
392 ast_str_buffer(to_text),
393 ast_str_buffer(from_text));
394}
395
396static void channel_enter_cb(void *data, struct stasis_subscription *sub,
397 struct stasis_message *message)
398{
399 static const char *swap_name = "SwapUniqueid: ";
401 RAII_VAR(struct ast_str *, bridge_text, NULL, ast_free);
402 RAII_VAR(struct ast_str *, channel_text, NULL, ast_free);
403 const char *swap_id;
404
405 bridge_text = ast_manager_build_bridge_state_string(blob->bridge);
406 channel_text = ast_manager_build_channel_state_string(blob->channel);
407 if (!bridge_text || !channel_text) {
408 return;
409 }
410
411 swap_id = ast_json_string_get(ast_json_object_get(blob->blob, "swap"));
412
413 manager_event(EVENT_FLAG_CALL, "BridgeEnter",
414 "%s"
415 "%s"
416 "%s%s%s",
417 ast_str_buffer(bridge_text),
418 ast_str_buffer(channel_text),
419 swap_id ? swap_name : "",
420 S_OR(swap_id, ""),
421 swap_id ? "\r\n" : "");
422}
423
424static void channel_leave_cb(void *data, struct stasis_subscription *sub,
425 struct stasis_message *message)
426{
428 RAII_VAR(struct ast_str *, bridge_text, NULL, ast_free);
429 RAII_VAR(struct ast_str *, channel_text, NULL, ast_free);
430
431 bridge_text = ast_manager_build_bridge_state_string(blob->bridge);
432 channel_text = ast_manager_build_channel_state_string(blob->channel);
433 if (!bridge_text || !channel_text) {
434 return;
435 }
436
437 manager_event(EVENT_FLAG_CALL, "BridgeLeave",
438 "%s"
439 "%s",
440 ast_str_buffer(bridge_text),
441 ast_str_buffer(channel_text));
442}
443
446 const char *type_filter;
447 int count;
448};
449
450static int send_bridge_list_item_cb(void *obj, void *arg, void *data, int flags)
451{
452 struct ast_bridge *bridge = obj;
454 struct mansession *s = arg;
455 struct bridge_list_data *list_data = data;
456 struct ast_str * bridge_info;
457
458 if (!snapshot) {
459 return 0;
460 }
461
462 if (!ast_strlen_zero(list_data->type_filter)
463 && strcmp(list_data->type_filter, snapshot->technology)) {
464 return 0;
465 }
466
467 bridge_info = ast_manager_build_bridge_state_string(snapshot);
468 if (!bridge_info) {
469 return 0;
470 }
471
473 "Event: BridgeListItem\r\n"
474 "%s"
475 "%s"
476 "\r\n",
477 ast_str_buffer(list_data->id_text),
478 ast_str_buffer(bridge_info));
479 ++list_data->count;
480
481 ast_free(bridge_info);
482
483 return 0;
484}
485
486static int manager_bridges_list(struct mansession *s, const struct message *m)
487{
488 const char *id = astman_get_header(m, "ActionID");
489 const char *type_filter = astman_get_header(m, "BridgeType");
490 struct ao2_container *bridges;
491 struct bridge_list_data list_data = { 0 };
492
494 if (!bridges) {
495 astman_send_error(s, m, "Internal error");
496 return -1;
497 }
498
499 list_data.id_text = ast_str_create(128);
500 if (!list_data.id_text) {
501 ao2_ref(bridges, -1);
502 astman_send_error(s, m, "Internal error");
503 return -1;
504 }
505
506 if (!ast_strlen_zero(id)) {
507 ast_str_set(&list_data.id_text, 0, "ActionID: %s\r\n", id);
508 }
509 list_data.type_filter = type_filter;
510
511 astman_send_listack(s, m, "Bridge listing will follow", "start");
512
514
515 astman_send_list_complete_start(s, m, "BridgeListComplete", list_data.count);
517
518 ast_free(list_data.id_text);
519 ao2_ref(bridges, -1);
520
521 return 0;
522}
523
524static int send_bridge_info_item_cb(void *obj, void *arg, void *data, int flags)
525{
526 char *uniqueid = obj;
527 struct mansession *s = arg;
528 struct bridge_list_data *list_data = data;
529 RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);
530 RAII_VAR(struct ast_str *, channel_text, NULL, ast_free);
531
532 snapshot = ast_channel_snapshot_get_latest(uniqueid);
533 if (!snapshot) {
534 return 0;
535 }
536
537 if (snapshot->base->tech_properties & AST_CHAN_TP_INTERNAL) {
538 return 0;
539 }
540
541 channel_text = ast_manager_build_channel_state_string(snapshot);
542 if (!channel_text) {
543 return 0;
544 }
545
547 "Event: BridgeInfoChannel\r\n"
548 "%s"
549 "%s"
550 "\r\n",
551 ast_str_buffer(list_data->id_text),
552 ast_str_buffer(channel_text));
553 ++list_data->count;
554 return 0;
555}
556
557static int manager_bridge_info(struct mansession *s, const struct message *m)
558{
559 const char *id = astman_get_header(m, "ActionID");
560 const char *bridge_uniqueid = astman_get_header(m, "BridgeUniqueid");
561 RAII_VAR(struct ast_str *, bridge_info, NULL, ast_free);
562 RAII_VAR(struct ast_bridge_snapshot *, snapshot, NULL, ao2_cleanup);
563 struct bridge_list_data list_data = { 0 };
564
565 if (ast_strlen_zero(bridge_uniqueid)) {
566 astman_send_error(s, m, "BridgeUniqueid must be provided");
567 return 0;
568 }
569
570 snapshot = ast_bridge_get_snapshot_by_uniqueid(bridge_uniqueid);
571 if (!snapshot) {
572 astman_send_error(s, m, "Specified BridgeUniqueid not found");
573 return 0;
574 }
575
576 bridge_info = ast_manager_build_bridge_state_string(snapshot);
577 if (!bridge_info) {
578 astman_send_error(s, m, "Internal error");
579 return -1;
580 }
581
582 list_data.id_text = ast_str_create(128);
583 if (!list_data.id_text) {
584 astman_send_error(s, m, "Internal error");
585 return -1;
586 }
587
588 if (!ast_strlen_zero(id)) {
589 ast_str_set(&list_data.id_text, 0, "ActionID: %s\r\n", id);
590 }
591
592 astman_send_listack(s, m, "Bridge channel listing will follow", "start");
593
594 ao2_callback_data(snapshot->channels, OBJ_NODATA, send_bridge_info_item_cb, s, &list_data);
595
596 astman_send_list_complete_start(s, m, "BridgeInfoComplete", list_data.count);
597 if (!ast_strlen_zero(ast_str_buffer(bridge_info))) {
598 astman_append(s, "%s", ast_str_buffer(bridge_info));
599 }
601 ast_free(list_data.id_text);
602
603 return 0;
604}
605
606static int manager_bridge_destroy(struct mansession *s, const struct message *m)
607{
608 const char *bridge_uniqueid = astman_get_header(m, "BridgeUniqueid");
609 struct ast_bridge *bridge;
610
611 if (ast_strlen_zero(bridge_uniqueid)) {
612 astman_send_error(s, m, "BridgeUniqueid must be provided");
613 return 0;
614 }
615
616 bridge = ast_bridge_find_by_id(bridge_uniqueid);
617 if (!bridge) {
618 astman_send_error(s, m, "Specified BridgeUniqueid not found");
619 return 0;
620 }
621 ast_bridge_destroy(bridge, 0);
622
623 astman_send_ack(s, m, "Bridge has been destroyed");
624
625 return 0;
626}
627
628static int manager_bridge_kick(struct mansession *s, const struct message *m)
629{
630 const char *bridge_uniqueid = astman_get_header(m, "BridgeUniqueid");
631 const char *channel_name = astman_get_header(m, "Channel");
632 RAII_VAR(struct ast_bridge *, bridge, NULL, ao2_cleanup);
633 RAII_VAR(struct ast_channel *, channel, NULL, ao2_cleanup);
634
635 if (ast_strlen_zero(channel_name)) {
636 astman_send_error(s, m, "Channel must be provided");
637 return 0;
638 }
639
640 channel = ast_channel_get_by_name(channel_name);
641 if (!channel) {
642 astman_send_error(s, m, "Channel does not exist");
643 return 0;
644 }
645
646 if (ast_strlen_zero(bridge_uniqueid)) {
647 /* get the bridge from the channel */
648 ast_channel_lock(channel);
649 bridge = ast_channel_get_bridge(channel);
650 ast_channel_unlock(channel);
651 if (!bridge) {
652 astman_send_error(s, m, "Channel is not in a bridge");
653 return 0;
654 }
655 } else {
656 bridge = ast_bridge_find_by_id(bridge_uniqueid);
657 if (!bridge || ast_test_flag(&bridge->feature_flags, AST_BRIDGE_FLAG_INVISIBLE)) {
658 astman_send_error(s, m, "Bridge not found");
659 return 0;
660 }
661 }
662
663 if (ast_bridge_kick(bridge, channel)) {
664 astman_send_error(s, m, "Channel kick from bridge failed");
665 return 0;
666 }
667
668 astman_send_ack(s, m, "Channel has been kicked");
669 return 0;
670}
671
673{
676
677 ast_manager_unregister("BridgeList");
678 ast_manager_unregister("BridgeInfo");
679 ast_manager_unregister("BridgeDestroy");
680 ast_manager_unregister("BridgeKick");
681}
682
684{
685 int ret = 0;
687 struct stasis_topic *bridge_topic;
688
690 /* Already initialized */
691 return 0;
692 }
693
695
697 if (!manager_topic) {
698 return -1;
699 }
700
701 bridge_topic = ast_bridge_topic_all();
702 if (!bridge_topic) {
703 return -1;
704 }
705
707 if (!topic_forwarder) {
708 return -1;
709 }
710
712 if (!bridge_state_router) {
713 return -1;
714 }
715
718
721
724
727
729 ret |= ast_manager_register_xml_core("BridgeInfo", 0, manager_bridge_info);
730 ret |= ast_manager_register_xml_core("BridgeDestroy", 0, manager_bridge_destroy);
731 ret |= ast_manager_register_xml_core("BridgeKick", 0, manager_bridge_kick);
732
733 /* If somehow we failed to add any routes, just shut down the whole
734 * thing and fail it.
735 */
736 if (ret) {
738 return -1;
739 }
740
741 return 0;
742}
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:123
struct ao2_container * ast_bridges(void)
Returns the global bridges container.
Definition: bridge.c:174
int ast_bridge_destroy(struct ast_bridge *bridge, int cause)
Destroy a bridge.
Definition: bridge.c:944
int ast_bridge_kick(struct ast_bridge *bridge, struct ast_channel *chan)
Kick a channel from a bridge.
Definition: bridge.c:1979
struct ast_bridge * ast_bridge_find_by_id(const char *bridge_id)
Find bridge by id.
Definition: bridge.c:5012
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:3951
@ AST_BRIDGE_VIDEO_MODE_NONE
Definition: bridge.h:100
@ AST_BRIDGE_FLAG_INVISIBLE
@ AST_CHAN_TP_INTERNAL
Channels with this particular technology are an implementation detail of Asterisk and should generall...
Definition: channel.h:991
#define ast_channel_lock(chan)
Definition: channel.h:2968
struct ast_bridge * ast_channel_get_bridge(const struct ast_channel *chan)
Get the bridge associated with a channel.
Definition: channel.c:10556
struct ast_channel * ast_channel_get_by_name(const char *name)
Find a channel by name.
Definition: channel.c:1473
#define ast_channel_unlock(chan)
Definition: channel.h:2969
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:2011
void astman_send_error(struct mansession *s, const struct message *m, char *error)
Send error in manager transaction.
Definition: manager.c:1969
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:2047
struct stasis_message_router * ast_manager_get_message_router(void)
Get the stasis_message_router for AMI.
Definition: manager.c:458
struct stasis_topic * ast_manager_get_topic(void)
Get the Stasis Message Bus API topic for AMI.
Definition: manager.c:453
void astman_send_ack(struct mansession *s, const struct message *m, char *msg)
Send ack in manager transaction.
Definition: manager.c:2001
const char * astman_get_header(const struct message *m, char *var)
Get header from manager transaction.
Definition: manager.c:1630
void astman_send_list_complete_end(struct mansession *s)
End the list complete event.
Definition: manager.c:2055
void astman_append(struct mansession *s, const char *fmt,...)
Definition: manager.c:1890
static struct stasis_topic * manager_topic
A stasis_topic that all topics AMI cares about will be forwarded to.
Definition: manager.c:185
int ast_manager_unregister(const char *action)
Unregister a registered manager command.
Definition: manager.c:7606
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:202
#define manager_event(category, event, contents,...)
External routines may send asterisk manager events this way.
Definition: manager.h:253
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:533
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:10126
#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:1549
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:1579
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:314
enum ast_bridge_video_mode_type video_mode
Definition: bridge.h:341
const ast_string_field video_source_id
Definition: bridge.h:328
const ast_string_field creator
Definition: bridge.h:328
const ast_string_field uniqueid
Definition: bridge.h:328
unsigned int num_channels
Definition: bridge.h:337
const ast_string_field technology
Definition: bridge.h:328
const ast_string_field name
Definition: bridge.h:328
const ast_string_field subclass
Definition: bridge.h:328
Structure that contains information about a bridge.
Definition: bridge.h:349
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:502
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:326
Forwarding information.
Definition: stasis.c:1532
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