]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Bridging: introduce "invisible" bridges. 89/2789/3
authorMark Michelson <mmichelson@digium.com>
Mon, 9 May 2016 19:27:53 +0000 (14:27 -0500)
committerMark Michelson <mmichelson@digium.com>
Mon, 23 May 2016 18:18:18 +0000 (13:18 -0500)
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

include/asterisk/bridge_features.h
main/bridge.c
main/manager_bridges.c
main/stasis_bridges.c
main/stasis_channels.c

index df01a0dca8c248673e9699f7317a25a62eeab668..7fcb85bd20be1fb07498e1b7e42fe7452074d6b1 100644 (file)
@@ -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 */
index ce6b9601bef5480e72a84b495c32b567c531fd78..68ac24bba544b118d79bb8ac956e48473163767c 100644 (file)
@@ -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;
        }
index dd3e98b8d5ec346855ea7da978fe7a3156830725..2069d507cd74fd0eace1f8f38a7ae07c6b3d6e61 100644 (file)
@@ -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;
                }
index d06ee14a7a699122178caae94e6cafd0436466f6..0e46edbea3b75b2f5b689975fbe4b3403963581f 100644 (file)
@@ -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;
index eb1f1bc6229a92b7449593f1d7fad8500f88dfa5..e56d1b928b216fd1ad3e44f37733df4ddf1ae7de 100644 (file)
@@ -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);
        }