diff --git a/include/asterisk/bridge_features.h b/include/asterisk/bridge_features.h index df01a0dca8..7fcb85bd20 100644 --- a/include/asterisk/bridge_features.h +++ b/include/asterisk/bridge_features.h @@ -53,6 +53,8 @@ enum ast_bridge_feature_flags { AST_BRIDGE_FLAG_TRANSFER_PROHIBITED = (1 << 8), /*! Bridge transfers require transfer of entire bridge rather than individual channels */ 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 */ diff --git a/main/bridge.c b/main/bridge.c index ce6b9601be..68ac24bba5 100644 --- a/main/bridge.c +++ b/main/bridge.c @@ -759,11 +759,13 @@ struct ast_bridge *bridge_base_init(struct ast_bridge *self, uint32_t capabiliti ast_set_flag(&self->feature_flags, flags); self->allowed_capabilities = capabilities; - if (bridge_topics_init(self) != 0) { - ast_log(LOG_WARNING, "Bridge %s: Could not initialize topics\n", - self->uniqueid); - ao2_ref(self, -1); - return NULL; + if (!(flags & AST_BRIDGE_FLAG_INVISIBLE)) { + if (bridge_topics_init(self) != 0) { + ast_log(LOG_WARNING, "Bridge %s: Could not initialize topics\n", + self->uniqueid); + ao2_ref(self, -1); + return NULL; + } } /* 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; } - if (!ast_bridge_topic(self)) { - ao2_ref(self, -1); - return NULL; + if (!(flags & AST_BRIDGE_FLAG_INVISIBLE)) { + if (!ast_bridge_topic(self)) { + ao2_ref(self, -1); + return NULL; + } } return self; @@ -4321,8 +4325,8 @@ static struct ast_bridge *acquire_bridge(struct ast_channel *chan) bridge = ast_channel_get_bridge(chan); ast_channel_unlock(chan); - if (bridge - && ast_test_flag(&bridge->feature_flags, AST_BRIDGE_FLAG_MASQUERADE_ONLY)) { + if (bridge && ast_test_flag(&bridge->feature_flags, + (AST_BRIDGE_FLAG_MASQUERADE_ONLY | AST_BRIDGE_FLAG_INVISIBLE))) { ao2_ref(bridge, -1); bridge = NULL; } diff --git a/main/manager_bridges.c b/main/manager_bridges.c index dd3e98b8d5..2069d507cd 100644 --- a/main/manager_bridges.c +++ b/main/manager_bridges.c @@ -572,7 +572,7 @@ static int manager_bridge_kick(struct mansession *s, const struct message *m) } } else { 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"); return 0; } diff --git a/main/stasis_bridges.c b/main/stasis_bridges.c index d06ee14a7a..0e46edbea3 100644 --- a/main/stasis_bridges.c +++ b/main/stasis_bridges.c @@ -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); 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, AO2_ALLOC_OPT_LOCK_NOLOCK); 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(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); 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 ast_json *, blob, NULL, ast_json_unref); + if (ast_test_flag(&bridge->feature_flags, AST_BRIDGE_FLAG_INVISIBLE)) { + return; + } + if (swap) { blob = ast_json_pack("{s: s}", "swap", ast_channel_uniqueid(swap)); 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); + 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); if (!msg) { return; diff --git a/main/stasis_channels.c b/main/stasis_channels.c index eb1f1bc622..e56d1b928b 100644 --- a/main/stasis_channels.c +++ b/main/stasis_channels.c @@ -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)); 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); }