mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-19 19:52:48 +00:00
Bridging: introduce "invisible" bridges.
Invisible bridges function the same as normal bridges, but they have the following restrictions: * They never show up in CLI, AMI, or ARI queries. * They do not have Stasis messages published about them. Invisible bridges' main use is for when use of the bridging system is desired, but the bridge should not be known to users of the Asterisk system. ASTERISK-25925 Change-Id: I804a209d3181d7c54e3d61a60eb462e7ce0e3670
This commit is contained in:
@@ -53,6 +53,8 @@ enum ast_bridge_feature_flags {
|
|||||||
AST_BRIDGE_FLAG_TRANSFER_PROHIBITED = (1 << 8),
|
AST_BRIDGE_FLAG_TRANSFER_PROHIBITED = (1 << 8),
|
||||||
/*! Bridge transfers require transfer of entire bridge rather than individual channels */
|
/*! Bridge transfers require transfer of entire bridge rather than individual channels */
|
||||||
AST_BRIDGE_FLAG_TRANSFER_BRIDGE_ONLY = (1 << 9),
|
AST_BRIDGE_FLAG_TRANSFER_BRIDGE_ONLY = (1 << 9),
|
||||||
|
/*! Bridge is invisible to AMI/CLI/ARI/etc. */
|
||||||
|
AST_BRIDGE_FLAG_INVISIBLE = (1 << 10),
|
||||||
};
|
};
|
||||||
|
|
||||||
/*! \brief Flags used for per bridge channel features */
|
/*! \brief Flags used for per bridge channel features */
|
||||||
|
@@ -759,11 +759,13 @@ struct ast_bridge *bridge_base_init(struct ast_bridge *self, uint32_t capabiliti
|
|||||||
ast_set_flag(&self->feature_flags, flags);
|
ast_set_flag(&self->feature_flags, flags);
|
||||||
self->allowed_capabilities = capabilities;
|
self->allowed_capabilities = capabilities;
|
||||||
|
|
||||||
if (bridge_topics_init(self) != 0) {
|
if (!(flags & AST_BRIDGE_FLAG_INVISIBLE)) {
|
||||||
ast_log(LOG_WARNING, "Bridge %s: Could not initialize topics\n",
|
if (bridge_topics_init(self) != 0) {
|
||||||
self->uniqueid);
|
ast_log(LOG_WARNING, "Bridge %s: Could not initialize topics\n",
|
||||||
ao2_ref(self, -1);
|
self->uniqueid);
|
||||||
return NULL;
|
ao2_ref(self, -1);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Use our helper function to find the "best" bridge technology. */
|
/* Use our helper function to find the "best" bridge technology. */
|
||||||
@@ -793,9 +795,11 @@ struct ast_bridge *bridge_base_init(struct ast_bridge *self, uint32_t capabiliti
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ast_bridge_topic(self)) {
|
if (!(flags & AST_BRIDGE_FLAG_INVISIBLE)) {
|
||||||
ao2_ref(self, -1);
|
if (!ast_bridge_topic(self)) {
|
||||||
return NULL;
|
ao2_ref(self, -1);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
@@ -4321,8 +4325,8 @@ static struct ast_bridge *acquire_bridge(struct ast_channel *chan)
|
|||||||
bridge = ast_channel_get_bridge(chan);
|
bridge = ast_channel_get_bridge(chan);
|
||||||
ast_channel_unlock(chan);
|
ast_channel_unlock(chan);
|
||||||
|
|
||||||
if (bridge
|
if (bridge && ast_test_flag(&bridge->feature_flags,
|
||||||
&& ast_test_flag(&bridge->feature_flags, AST_BRIDGE_FLAG_MASQUERADE_ONLY)) {
|
(AST_BRIDGE_FLAG_MASQUERADE_ONLY | AST_BRIDGE_FLAG_INVISIBLE))) {
|
||||||
ao2_ref(bridge, -1);
|
ao2_ref(bridge, -1);
|
||||||
bridge = NULL;
|
bridge = NULL;
|
||||||
}
|
}
|
||||||
|
@@ -572,7 +572,7 @@ static int manager_bridge_kick(struct mansession *s, const struct message *m)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
bridge = ast_bridge_find_by_id(bridge_uniqueid);
|
bridge = ast_bridge_find_by_id(bridge_uniqueid);
|
||||||
if (!bridge) {
|
if (!bridge || ast_test_flag(&bridge->feature_flags, AST_BRIDGE_FLAG_INVISIBLE)) {
|
||||||
astman_send_error(s, m, "Bridge not found");
|
astman_send_error(s, m, "Bridge not found");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@@ -232,6 +232,10 @@ struct ast_bridge_snapshot *ast_bridge_snapshot_create(struct ast_bridge *bridge
|
|||||||
RAII_VAR(struct ast_bridge_snapshot *, snapshot, NULL, ao2_cleanup);
|
RAII_VAR(struct ast_bridge_snapshot *, snapshot, NULL, ao2_cleanup);
|
||||||
struct ast_bridge_channel *bridge_channel;
|
struct ast_bridge_channel *bridge_channel;
|
||||||
|
|
||||||
|
if (ast_test_flag(&bridge->feature_flags, AST_BRIDGE_FLAG_INVISIBLE)) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
snapshot = ao2_alloc_options(sizeof(*snapshot), bridge_snapshot_dtor,
|
snapshot = ao2_alloc_options(sizeof(*snapshot), bridge_snapshot_dtor,
|
||||||
AO2_ALLOC_OPT_LOCK_NOLOCK);
|
AO2_ALLOC_OPT_LOCK_NOLOCK);
|
||||||
if (!snapshot || ast_string_field_init(snapshot, 128)) {
|
if (!snapshot || ast_string_field_init(snapshot, 128)) {
|
||||||
@@ -371,6 +375,8 @@ void ast_bridge_publish_merge(struct ast_bridge *to, struct ast_bridge *from)
|
|||||||
|
|
||||||
ast_assert(to != NULL);
|
ast_assert(to != NULL);
|
||||||
ast_assert(from != NULL);
|
ast_assert(from != NULL);
|
||||||
|
ast_assert(ast_test_flag(&to->feature_flags, AST_BRIDGE_FLAG_INVISIBLE) == 0);
|
||||||
|
ast_assert(ast_test_flag(&from->feature_flags, AST_BRIDGE_FLAG_INVISIBLE) == 0);
|
||||||
|
|
||||||
merge_msg = bridge_merge_message_create(to, from);
|
merge_msg = bridge_merge_message_create(to, from);
|
||||||
if (!merge_msg) {
|
if (!merge_msg) {
|
||||||
@@ -447,6 +453,10 @@ void ast_bridge_publish_enter(struct ast_bridge *bridge, struct ast_channel *cha
|
|||||||
RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
|
RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
|
||||||
RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
|
RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
|
||||||
|
|
||||||
|
if (ast_test_flag(&bridge->feature_flags, AST_BRIDGE_FLAG_INVISIBLE)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (swap) {
|
if (swap) {
|
||||||
blob = ast_json_pack("{s: s}", "swap", ast_channel_uniqueid(swap));
|
blob = ast_json_pack("{s: s}", "swap", ast_channel_uniqueid(swap));
|
||||||
if (!blob) {
|
if (!blob) {
|
||||||
@@ -468,6 +478,9 @@ void ast_bridge_publish_leave(struct ast_bridge *bridge, struct ast_channel *cha
|
|||||||
{
|
{
|
||||||
RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
|
RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup);
|
||||||
|
|
||||||
|
if (ast_test_flag(&bridge->feature_flags, AST_BRIDGE_FLAG_INVISIBLE)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
msg = ast_bridge_blob_create(ast_channel_left_bridge_type(), bridge, chan, NULL);
|
msg = ast_bridge_blob_create(ast_channel_left_bridge_type(), bridge, chan, NULL);
|
||||||
if (!msg) {
|
if (!msg) {
|
||||||
return;
|
return;
|
||||||
|
@@ -256,7 +256,9 @@ struct ast_channel_snapshot *ast_channel_snapshot_create(struct ast_channel *cha
|
|||||||
ast_string_field_set(snapshot, language, ast_channel_language(chan));
|
ast_string_field_set(snapshot, language, ast_channel_language(chan));
|
||||||
|
|
||||||
if ((bridge = ast_channel_get_bridge(chan))) {
|
if ((bridge = ast_channel_get_bridge(chan))) {
|
||||||
ast_string_field_set(snapshot, bridgeid, bridge->uniqueid);
|
if (!ast_test_flag(&bridge->feature_flags, AST_BRIDGE_FLAG_INVISIBLE)) {
|
||||||
|
ast_string_field_set(snapshot, bridgeid, bridge->uniqueid);
|
||||||
|
}
|
||||||
ao2_cleanup(bridge);
|
ao2_cleanup(bridge);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user