bridge features: Dial and Queue add features instead of replace them.
authorJonathan Rose <jrose@digium.com>
Mon, 5 Aug 2013 20:18:54 +0000 (20:18 +0000)
committerJonathan Rose <jrose@digium.com>
Mon, 5 Aug 2013 20:18:54 +0000 (20:18 +0000)
Dial and Queue would previously apply a new set of features whenever
bridging. These options would be based purely on the options supplied
to the dial/queue applications. This patch changes the function those
applications use to bridge calls so that the features will be added
to the set of existing features for each channel rather than having
them override the existing features.

(closes issue ASTERISK-22209)
Reported by: Jonathan Rose
Review: https://reviewboard.asterisk.org/r/2713/

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@396245 65c4cc65-6c06-0410-ace0-fbb531ad65f3

include/asterisk/bridge_basic.h
main/bridge_basic.c
main/features.c

index 4db1429..d048762 100644 (file)
@@ -89,6 +89,22 @@ struct ast_flags *ast_bridge_features_ds_get(struct ast_channel *chan);
 int ast_bridge_features_ds_set(struct ast_channel *chan, struct ast_flags *flags);
 
 /*!
+ * \brief Append basic bridge DTMF feature flags on the channel.
+ * \since 12.0.0
+ *
+ * \param chan Channel to append DTMF features datastore.
+ * \param flags Builtin DTMF feature flags. (ast_bridge_config flags)
+ *
+ * \note The channel must be locked before calling this function.
+ * \note This function differs from ast_bridge_features_ds_set only in that it won't
+ *       remove features already set on the channel.
+ *
+ * \retval 0 on success.
+ * \retval -1 on error.
+ */
+int ast_bridge_features_ds_append(struct ast_channel *chan, struct ast_flags *flags);
+
+/*!
  * \brief Setup DTMF feature hooks using the channel features datastore property.
  * \since 12.0.0
  *
index 10c4efb..35782de 100644 (file)
@@ -220,7 +220,7 @@ int ast_bridge_features_ds_get_string(struct ast_channel *chan, char *buffer, si
        return dtmf_features_flags_to_string(&held_copy, buffer, buf_size);
 }
 
-int ast_bridge_features_ds_set(struct ast_channel *chan, struct ast_flags *flags)
+static int bridge_features_ds_set_full(struct ast_channel *chan, struct ast_flags *flags, int replace)
 {
        struct ast_datastore *datastore;
        struct ast_flags *ds_flags;
@@ -228,7 +228,12 @@ int ast_bridge_features_ds_set(struct ast_channel *chan, struct ast_flags *flags
        datastore = ast_channel_datastore_find(chan, &dtmf_features_info, NULL);
        if (datastore) {
                ds_flags = datastore->data;
-               *ds_flags = *flags;
+               if (replace) {
+                       *ds_flags = *flags;
+               } else {
+                       flags->flags = flags->flags | ds_flags->flags;
+                       *ds_flags = *flags;
+               }
                return 0;
        }
 
@@ -249,6 +254,16 @@ int ast_bridge_features_ds_set(struct ast_channel *chan, struct ast_flags *flags
        return 0;
 }
 
+int ast_bridge_features_ds_set(struct ast_channel *chan, struct ast_flags *flags)
+{
+       return bridge_features_ds_set_full(chan, flags, 1);
+}
+
+int ast_bridge_features_ds_append(struct ast_channel *chan, struct ast_flags *flags)
+{
+       return bridge_features_ds_set_full(chan, flags, 0);
+}
+
 struct ast_flags *ast_bridge_features_ds_get(struct ast_channel *chan)
 {
        struct ast_datastore *datastore;
index 043ed59..e2d6684 100644 (file)
@@ -953,10 +953,10 @@ static int pre_bridge_setup(struct ast_channel *chan, struct ast_channel *peer,
 
        res = 0;
        ast_channel_lock(chan);
-       res |= ast_bridge_features_ds_set(chan, &config->features_caller);
+       res |= ast_bridge_features_ds_append(chan, &config->features_caller);
        ast_channel_unlock(chan);
        ast_channel_lock(peer);
-       res |= ast_bridge_features_ds_set(peer, &config->features_callee);
+       res |= ast_bridge_features_ds_append(peer, &config->features_callee);
        ast_channel_unlock(peer);
 
        if (res) {