ARI: Ability to inhibit COLP frames when adding channels to a bridge
authorJean Aunis <jean.aunis@prescom.fr>
Fri, 22 Nov 2019 14:32:42 +0000 (15:32 +0100)
committerJoshua C. Colp <jcolp@sangoma.com>
Thu, 2 Jan 2020 15:06:15 +0000 (15:06 +0000)
This patch adds a new flag "inhibitConnectedLineUpdates" to the 'addChannel'
operation in the Bridges REST API. When set, this flag avoids generating COLP
frames when the specified channels enter the bridge.

ASTERISK-28629

Change-Id: Ib995d4f0c6106279aa448b34b042b68f0f2ca5dc

doc/CHANGES-staging/ari-bridges-inhibit-colp.txt [new file with mode: 0644]
include/asterisk/bridge_features.h
include/asterisk/stasis_app.h
res/ari/resource_bridges.c
res/ari/resource_bridges.h
res/res_ari_bridges.c
res/stasis/control.c
rest-api/api-docs/bridges.json

diff --git a/doc/CHANGES-staging/ari-bridges-inhibit-colp.txt b/doc/CHANGES-staging/ari-bridges-inhibit-colp.txt
new file mode 100644 (file)
index 0000000..cdc9ffb
--- /dev/null
@@ -0,0 +1,5 @@
+Subject: ARI
+
+A new parameter 'inhibitConnectedLineUpdates' is now available in the
+'bridges.addChannel' call. This prevents the identity of the newly connected
+channel from being presented to other bridge members.
index f9af8fb..9b5f70f 100644 (file)
@@ -277,6 +277,8 @@ struct ast_bridge_features {
        unsigned int mute:1;
        /*! TRUE if DTMF should be passed into the bridge tech.  */
        unsigned int dtmf_passthrough:1;
+       /*! TRUE to avoid generating COLP frames when joining the bridge */
+       unsigned int inhibit_colp:1;
 };
 
 /*!
index 01c7ff4..285d54a 100644 (file)
@@ -838,6 +838,16 @@ void stasis_app_control_mute_in_bridge(
        struct stasis_app_control *control, int mute);
 
 /*!
+ * \since 18
+ * \brief Set whether COLP frames should be generated when joining the bridge
+ *
+ * \param control Control whose channel should have its COLP frames inhibited when bridged
+ * \param mute Whether COLP frames should be generated (0) or not (1).
+ */
+void stasis_app_control_inhibit_colp_in_bridge(
+       struct stasis_app_control *control, int inhibit_colp);
+
+/*!
  * \since 12
  * \brief Gets the bridge currently associated with a control object.
  *
index 33e4cd1..e4e7064 100644 (file)
@@ -221,6 +221,7 @@ void ast_ari_bridges_add_channel(struct ast_variable *headers,
                if (!stasis_app_control_bridge_features_init(list->controls[i])) {
                        stasis_app_control_absorb_dtmf_in_bridge(list->controls[i], args->absorb_dtmf);
                        stasis_app_control_mute_in_bridge(list->controls[i], args->mute);
+                       stasis_app_control_inhibit_colp_in_bridge(list->controls[i], args->inhibit_connected_line_updates);
                }
        }
 
index 0d0286c..83a3532 100644 (file)
@@ -154,6 +154,8 @@ struct ast_ari_bridges_add_channel_args {
        int absorb_dtmf;
        /*! Mute audio from this channel, preventing it to pass through to the bridge */
        int mute;
+       /*! Do not present the identity of the newly connected channel to other bridge members */
+       int inhibit_connected_line_updates;
 };
 /*!
  * \brief Body parsing function for /bridges/{bridgeId}/addChannel.
index 7ef0f68..0f0f22b 100644 (file)
@@ -440,6 +440,10 @@ int ast_ari_bridges_add_channel_parse_body(
        if (field) {
                args->mute = ast_json_is_true(field);
        }
+       field = ast_json_object_get(body, "inhibitConnectedLineUpdates");
+       if (field) {
+               args->inhibit_connected_line_updates = ast_json_is_true(field);
+       }
        return 0;
 }
 
@@ -515,6 +519,9 @@ static void ast_ari_bridges_add_channel_cb(
                if (strcmp(i->name, "mute") == 0) {
                        args.mute = ast_true(i->value);
                } else
+               if (strcmp(i->name, "inhibitConnectedLineUpdates") == 0) {
+                       args.inhibit_connected_line_updates = ast_true(i->value);
+               } else
                {}
        }
        for (i = path_vars; i; i = i->next) {
index 96ddf39..584e60e 100644 (file)
@@ -1285,6 +1285,7 @@ int control_swap_channel_in_bridge(struct stasis_app_control *control, struct as
 {
        int res;
        struct ast_bridge_features *features;
+       int flags = AST_BRIDGE_IMPART_CHAN_DEPARTABLE;
 
        if (!control || !bridge) {
                return -1;
@@ -1332,6 +1333,9 @@ int control_swap_channel_in_bridge(struct stasis_app_control *control, struct as
        /* Pull bridge features from the control */
        features = control->bridge_features;
        control->bridge_features = NULL;
+       if (features && features->inhibit_colp) {
+               flags |= AST_BRIDGE_IMPART_INHIBIT_JOIN_COLP;
+       }
 
        ast_assert(stasis_app_get_bridge(control) == NULL);
        /* We need to set control->bridge here since bridge_after_cb may be run
@@ -1349,7 +1353,7 @@ int control_swap_channel_in_bridge(struct stasis_app_control *control, struct as
                chan,
                swap,
                features, /* features */
-               AST_BRIDGE_IMPART_CHAN_DEPARTABLE);
+               flags);
        if (res != 0) {
                /* ast_bridge_impart failed before it could spawn the depart
                 * thread.  The callbacks aren't called in this case.
@@ -1469,6 +1473,12 @@ void stasis_app_control_mute_in_bridge(
        control->bridge_features->mute = mute;
 }
 
+void stasis_app_control_inhibit_colp_in_bridge(
+       struct stasis_app_control *control, int inhibit_colp)
+{
+       control->bridge_features->inhibit_colp = inhibit_colp;
+}
+
 void control_flush_queue(struct stasis_app_control *control)
 {
        struct ao2_iterator iter;
index 22743c3..a465137 100644 (file)
                                                        "allowMultiple": false,
                                                        "dataType": "boolean",
                                                        "defaultValue": false
+                                               },
+                                               {
+                                                       "name": "inhibitConnectedLineUpdates",
+                                                       "description": "Do not present the identity of the newly connected channel to other bridge members",
+                                                       "paramType": "query",
+                                                       "required": false,
+                                                       "allowMultiple": false,
+                                                       "dataType": "boolean",
+                                                       "defaultValue": false
                                                }
                                        ],
                                        "errorResponses": [