diff --git a/include/asterisk/bridge_basic.h b/include/asterisk/bridge_basic.h index 4db1429469c2c80513e6dad3be9ed5a6e6201149..d048762353e2cf2864fab42cc5829e5b4ff418e7 100644 --- a/include/asterisk/bridge_basic.h +++ b/include/asterisk/bridge_basic.h @@ -88,6 +88,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 diff --git a/main/bridge_basic.c b/main/bridge_basic.c index 10c4efb575b39ac5f3d1e1baa7ab8e5e5e2edce8..35782de285eff3f6b20b361dd115b4ce4a6b85bc 100644 --- a/main/bridge_basic.c +++ b/main/bridge_basic.c @@ -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; diff --git a/main/features.c b/main/features.c index 043ed591f58e2efce4ef394a31d851b2affb33f9..e2d668426ae681a97d36240fd0599d0b61296e0a 100644 --- a/main/features.c +++ b/main/features.c @@ -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) {