[svn-commits] rmudgett: branch rmudgett/bridge_tasks r383630 - in /team/rmudgett/bridge_tas...
SVN commits to the Digium repositories
svn-commits at lists.digium.com
Fri Mar 22 15:41:29 CDT 2013
Author: rmudgett
Date: Fri Mar 22 15:41:27 2013
New Revision: 383630
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=383630
Log:
* Remove marked feature hooks when a channel is pulled from the bridge.
* Add ability to specify if a hook is removed if the channel is pulled
from the bridge.
Modified:
team/rmudgett/bridge_tasks/apps/app_bridgewait.c
team/rmudgett/bridge_tasks/apps/confbridge/conf_config_parser.c
team/rmudgett/bridge_tasks/bridges/bridge_builtin_features.c
team/rmudgett/bridge_tasks/bridges/bridge_builtin_interval_features.c
team/rmudgett/bridge_tasks/include/asterisk/bridging_features.h
team/rmudgett/bridge_tasks/main/bridging.c
team/rmudgett/bridge_tasks/main/features.c
Modified: team/rmudgett/bridge_tasks/apps/app_bridgewait.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/bridge_tasks/apps/app_bridgewait.c?view=diff&rev=383630&r1=383629&r2=383630
==============================================================================
--- team/rmudgett/bridge_tasks/apps/app_bridgewait.c (original)
+++ team/rmudgett/bridge_tasks/apps/app_bridgewait.c Fri Mar 22 15:41:27 2013
@@ -140,7 +140,7 @@
/* Limits struct holds time as milliseconds, so muliply 1000x */
hold_limits.duration *= 1000;
- ast_bridge_features_set_limits(features, &hold_limits);
+ ast_bridge_features_set_limits(features, &hold_limits, 1);
ast_bridge_features_limits_destroy(&hold_limits);
return 0;
Modified: team/rmudgett/bridge_tasks/apps/confbridge/conf_config_parser.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/bridge_tasks/apps/confbridge/conf_config_parser.c?view=diff&rev=383630&r1=383629&r2=383630
==============================================================================
--- team/rmudgett/bridge_tasks/apps/confbridge/conf_config_parser.c (original)
+++ team/rmudgett/bridge_tasks/apps/confbridge/conf_config_parser.c Fri Mar 22 15:41:27 2013
@@ -2053,7 +2053,8 @@
ao2_ref(menu, +1);
pvt->menu = menu;
- ast_bridge_dtmf_hook(&user->features, pvt->menu_entry.dtmf, menu_hook_callback, pvt, menu_hook_destroy);
+ ast_bridge_dtmf_hook(&user->features, pvt->menu_entry.dtmf, menu_hook_callback,
+ pvt, menu_hook_destroy, 0);
}
ao2_unlock(menu);
Modified: team/rmudgett/bridge_tasks/bridges/bridge_builtin_features.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/bridge_tasks/bridges/bridge_builtin_features.c?view=diff&rev=383630&r1=383629&r2=383630
==============================================================================
--- team/rmudgett/bridge_tasks/bridges/bridge_builtin_features.c (original)
+++ team/rmudgett/bridge_tasks/bridges/bridge_builtin_features.c Fri Mar 22 15:41:27 2013
@@ -279,19 +279,19 @@
/* Setup a DTMF menu to control the transfer. */
if (ast_bridge_features_init(&caller_features)
|| ast_bridge_hangup_hook(&caller_features,
- attended_transfer_complete, &transfer_code, NULL)
+ attended_transfer_complete, &transfer_code, NULL, 0)
|| ast_bridge_dtmf_hook(&caller_features,
attended_transfer && !ast_strlen_zero(attended_transfer->abort)
? attended_transfer->abort : "*1",
- attended_transfer_abort, &transfer_code, NULL)
+ attended_transfer_abort, &transfer_code, NULL, 0)
|| ast_bridge_dtmf_hook(&caller_features,
attended_transfer && !ast_strlen_zero(attended_transfer->complete)
? attended_transfer->complete : "*2",
- attended_transfer_complete, &transfer_code, NULL)
+ attended_transfer_complete, &transfer_code, NULL, 0)
|| ast_bridge_dtmf_hook(&caller_features,
attended_transfer && !ast_strlen_zero(attended_transfer->threeway)
? attended_transfer->threeway : "*3",
- attended_transfer_threeway, &transfer_code, NULL)) {
+ attended_transfer_threeway, &transfer_code, NULL, 0)) {
ast_bridge_features_cleanup(&caller_features);
ast_hangup(peer);
/* BUGBUG beeperr needs to be configurable from features.conf */
Modified: team/rmudgett/bridge_tasks/bridges/bridge_builtin_interval_features.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/bridge_tasks/bridges/bridge_builtin_interval_features.c?view=diff&rev=383630&r1=383629&r2=383630
==============================================================================
--- team/rmudgett/bridge_tasks/bridges/bridge_builtin_interval_features.c (original)
+++ team/rmudgett/bridge_tasks/bridges/bridge_builtin_interval_features.c Fri Mar 22 15:41:27 2013
@@ -140,7 +140,7 @@
ast_string_field_set(dst, connect_sound, src->connect_sound);
}
-static int bridge_builtin_set_limits(struct ast_bridge_features *features, struct ast_bridge_features_limits *limits)
+static int bridge_builtin_set_limits(struct ast_bridge_features *features, struct ast_bridge_features_limits *limits, int remove_on_pull)
{
struct ast_bridge_features_limits *feature_limits;
@@ -167,7 +167,7 @@
/* BUGBUG feature interval hooks need to be reimplemented to be more stand alone. */
if (ast_bridge_interval_hook(features, feature_limits->duration,
- bridge_features_duration_callback, feature_limits, NULL)) {
+ bridge_features_duration_callback, feature_limits, NULL, remove_on_pull)) {
ast_log(LOG_ERROR, "Failed to schedule the duration limiter to the bridge channel.\n");
return -1;
}
@@ -176,14 +176,14 @@
if (!ast_strlen_zero(feature_limits->connect_sound)) {
if (ast_bridge_interval_hook(features, 1,
- bridge_features_connect_callback, feature_limits, NULL)) {
+ bridge_features_connect_callback, feature_limits, NULL, remove_on_pull)) {
ast_log(LOG_WARNING, "Failed to schedule connect sound to the bridge channel.\n");
}
}
if (feature_limits->warning && feature_limits->warning < feature_limits->duration) {
if (ast_bridge_interval_hook(features, feature_limits->duration - feature_limits->warning,
- bridge_features_warning_callback, feature_limits, NULL)) {
+ bridge_features_warning_callback, feature_limits, NULL, remove_on_pull)) {
ast_log(LOG_WARNING, "Failed to schedule warning sound playback to the bridge channel.\n");
}
}
Modified: team/rmudgett/bridge_tasks/include/asterisk/bridging_features.h
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/bridge_tasks/include/asterisk/bridging_features.h?view=diff&rev=383630&r1=383629&r2=383630
==============================================================================
--- team/rmudgett/bridge_tasks/include/asterisk/bridging_features.h (original)
+++ team/rmudgett/bridge_tasks/include/asterisk/bridging_features.h Fri Mar 22 15:41:27 2013
@@ -165,7 +165,7 @@
unsigned int seqno;
};
-/* BUGBUG ast_bridge_hook needs to be turned into ao2 objects so bridge push/pulls can add/remove hooks */
+/* BUGBUG Need to be able to selectively remove DTMF, hangup, and interval hooks. */
/*! \brief Structure that is the essence of a feature hook. */
struct ast_bridge_hook {
/*! Linked list information */
@@ -176,6 +176,8 @@
ast_bridge_hook_pvt_destructor destructor;
/*! Unique data that was passed into us */
void *hook_pvt;
+ /*! TRUE if the hook is removed when the channel is pulled from the bridge. */
+ unsigned int remove_on_pull:1;
/*! Extra hook parameters. */
union {
/*! Extra parameters for a DTMF feature hook. */
@@ -306,6 +308,18 @@
int ast_bridge_features_unregister(enum ast_bridge_builtin_feature feature);
/*!
+ * \brief Attach interval hooks to a bridge features structure
+ *
+ * \param features Bridge features structure
+ * \param limits Configured limits applicable to the channel
+ * \param remove_on_pull TRUE if remove the hook when the channel is pulled from the bridge.
+ *
+ * \retval 0 on success
+ * \retval -1 on failure
+ */
+typedef int (*ast_bridge_builtin_set_limits_fn)(struct ast_bridge_features *features, struct ast_bridge_features_limits *limits, int remove_on_pull);
+
+/*!
* \brief Register a handler for a built in interval feature
*
* \param interval The interval feature that the handler will be responsible for
@@ -323,7 +337,7 @@
* This registers the function bridge_builtin_set_limits as the function responsible for the built in
* duration limit feature.
*/
-int ast_bridge_interval_register(enum ast_bridge_builtin_interval interval, void *callback);
+int ast_bridge_interval_register(enum ast_bridge_builtin_interval interval, ast_bridge_builtin_set_limits_fn callback);
/*!
* \brief Unregisters a handler for a built in interval feature
@@ -350,16 +364,17 @@
* \param callback Function to execute upon activation
* \param hook_pvt Unique data
* \param destructor Optional destructor callback for hook_pvt data
- *
- * \retval 0 on success
- * \retval -1 on failure
- *
- * Example usage:
- *
- * \code
- * struct ast_bridge_features features;
- * ast_bridge_features_init(&features);
- * ast_bridge_hangup_hook(&features, hangup_callback, NULL, NULL);
+ * \param remove_on_pull TRUE if remove the hook when the channel is pulled from the bridge.
+ *
+ * \retval 0 on success
+ * \retval -1 on failure
+ *
+ * Example usage:
+ *
+ * \code
+ * struct ast_bridge_features features;
+ * ast_bridge_features_init(&features);
+ * ast_bridge_hangup_hook(&features, hangup_callback, NULL, NULL, 0);
* \endcode
*
* This makes the bridging core call hangup_callback if a
@@ -369,7 +384,8 @@
int ast_bridge_hangup_hook(struct ast_bridge_features *features,
ast_bridge_hook_callback callback,
void *hook_pvt,
- ast_bridge_hook_pvt_destructor destructor);
+ ast_bridge_hook_pvt_destructor destructor,
+ int remove_on_pull);
/*!
* \brief Attach a DTMF hook to a bridge features structure
@@ -379,16 +395,17 @@
* \param callback Function to execute upon activation
* \param hook_pvt Unique data
* \param destructor Optional destructor callback for hook_pvt data
- *
- * \retval 0 on success
- * \retval -1 on failure
- *
- * Example usage:
- *
- * \code
- * struct ast_bridge_features features;
- * ast_bridge_features_init(&features);
- * ast_bridge_dtmf_hook(&features, "#", pound_callback, NULL, NULL);
+ * \param remove_on_pull TRUE if remove the hook when the channel is pulled from the bridge.
+ *
+ * \retval 0 on success
+ * \retval -1 on failure
+ *
+ * Example usage:
+ *
+ * \code
+ * struct ast_bridge_features features;
+ * ast_bridge_features_init(&features);
+ * ast_bridge_dtmf_hook(&features, "#", pound_callback, NULL, NULL, 0);
* \endcode
*
* This makes the bridging core call pound_callback if a channel that has this
@@ -399,7 +416,8 @@
const char *dtmf,
ast_bridge_hook_callback callback,
void *hook_pvt,
- ast_bridge_hook_pvt_destructor destructor);
+ ast_bridge_hook_pvt_destructor destructor,
+ int remove_on_pull);
/*!
* \brief attach an interval hook to a bridge features structure
@@ -409,14 +427,15 @@
* \param callback Function to execute upon activation
* \param hook_pvt Unique data
* \param destructor Optional destructor callback for hook_pvt data
- *
- * \retval 0 on success
- * \retval -1 on failure
- *
- * \code
- * struct ast_bridge_features features;
- * ast_bridge_features_init(&features);
- * ast_bridge_interval_hook(&features, 1000, playback_callback, NULL, NULL);
+ * \param remove_on_pull TRUE if remove the hook when the channel is pulled from the bridge.
+ *
+ * \retval 0 on success
+ * \retval -1 on failure
+ *
+ * \code
+ * struct ast_bridge_features features;
+ * ast_bridge_features_init(&features);
+ * ast_bridge_interval_hook(&features, 1000, playback_callback, NULL, NULL, 0);
* \endcode
*
* This makes the bridging core call playback_callback every second. A pointer to useful
@@ -426,7 +445,8 @@
unsigned int interval,
ast_bridge_hook_callback callback,
void *hook_pvt,
- ast_bridge_hook_pvt_destructor destructor);
+ ast_bridge_hook_pvt_destructor destructor,
+ int remove_on_pull);
/*!
* \brief Set a callback on the features structure to receive talking notifications on.
@@ -451,23 +471,29 @@
* \param dtmf Optionally the DTMF stream to trigger the feature, if not specified it will be the default
* \param config Configuration structure unique to the built in type
* \param destructor Optional destructor callback for config data
- *
- * \retval 0 on success
- * \retval -1 on failure
- *
- * Example usage:
- *
- * \code
- * struct ast_bridge_features features;
- * ast_bridge_features_init(&features);
- * ast_bridge_features_enable(&features, AST_BRIDGE_BUILTIN_ATTENDEDTRANSFER, NULL, NULL);
+ * \param remove_on_pull TRUE if remove the hook when the channel is pulled from the bridge.
+ *
+ * \retval 0 on success
+ * \retval -1 on failure
+ *
+ * Example usage:
+ *
+ * \code
+ * struct ast_bridge_features features;
+ * ast_bridge_features_init(&features);
+ * ast_bridge_features_enable(&features, AST_BRIDGE_BUILTIN_ATTENDEDTRANSFER, NULL, NULL, 0);
* \endcode
*
* This enables the attended transfer DTMF option using the default DTMF string. An alternate
* string may be provided using the dtmf parameter. Internally this is simply setting up a hook
* to a built in feature callback function.
*/
-int ast_bridge_features_enable(struct ast_bridge_features *features, enum ast_bridge_builtin_feature feature, const char *dtmf, void *config, ast_bridge_hook_pvt_destructor destructor);
+int ast_bridge_features_enable(struct ast_bridge_features *features,
+ enum ast_bridge_builtin_feature feature,
+ const char *dtmf,
+ void *config,
+ ast_bridge_hook_pvt_destructor destructor,
+ int remove_on_pull);
/*!
* \brief Constructor function for ast_bridge_features_limits
@@ -494,6 +520,7 @@
*
* \param features Bridge features structure
* \param limits Configured limits applicable to the channel
+ * \param remove_on_pull TRUE if remove the hook when the channel is pulled from the bridge.
*
* \retval 0 on success
* \retval -1 on failure
@@ -505,7 +532,7 @@
* struct ast_bridge_features_limits limits;
* ast_bridge_features_init(&features);
* ast_bridge_features_limits_construct(&limits);
- * ast_bridge_features_set_limits(&features, &limits);
+ * ast_bridge_features_set_limits(&features, &limits, 0);
* ast_bridge_features_limits_destroy(&limits);
* \endcode
*
@@ -514,7 +541,7 @@
* \note This API call can only be used on a features structure that will be used in association with a bridge channel.
* \note The ast_bridge_features_limits structure must remain accessible for the lifetime of the features structure.
*/
-int ast_bridge_features_set_limits(struct ast_bridge_features *features, struct ast_bridge_features_limits *limits);
+int ast_bridge_features_set_limits(struct ast_bridge_features *features, struct ast_bridge_features_limits *limits, int remove_on_pull);
/*!
* \brief Set a flag on a bridge features structure
Modified: team/rmudgett/bridge_tasks/main/bridging.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/bridge_tasks/main/bridging.c?view=diff&rev=383630&r1=383629&r2=383630
==============================================================================
--- team/rmudgett/bridge_tasks/main/bridging.c (original)
+++ team/rmudgett/bridge_tasks/main/bridging.c Fri Mar 22 15:41:27 2013
@@ -66,6 +66,7 @@
static void cleanup_video_mode(struct ast_bridge *bridge);
static int bridge_make_compatible(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel);
+static void bridge_features_remove_on_pull(struct ast_bridge_features *features);
/*! Default DTMF keys for built in features */
static char builtin_features_dtmf[AST_BRIDGE_BUILTIN_END][MAXIMUM_DTMF_FEATURE_STRING];
@@ -74,7 +75,7 @@
static void *builtin_features_handlers[AST_BRIDGE_BUILTIN_END];
/*! Function handlers for built in interval features */
-static void *builtin_interval_handlers[AST_BRIDGE_BUILTIN_INTERVAL_END];
+static ast_bridge_builtin_set_limits_fn builtin_interval_handlers[AST_BRIDGE_BUILTIN_INTERVAL_END];
/*! Bridge manager service request */
struct bridge_manager_request {
@@ -393,6 +394,7 @@
if (bridge->personality && bridge->personality->pull) {
bridge->personality->pull(bridge_channel);
}
+ bridge_features_remove_on_pull(bridge_channel->features);
bridge->reconfigured = 1;
}
@@ -2583,7 +2585,7 @@
return 0;
}
-int ast_bridge_interval_register(enum ast_bridge_builtin_interval interval, void *callback)
+int ast_bridge_interval_register(enum ast_bridge_builtin_interval interval, ast_bridge_builtin_set_limits_fn callback)
{
if (ARRAY_LEN(builtin_interval_handlers) <= interval
|| builtin_interval_handlers[interval]) {
@@ -2635,11 +2637,16 @@
* \param callback Function to execute upon activation
* \param hook_pvt Unique data
* \param destructor Optional destructor callback for hook_pvt data
+ * \param remove_on_pull TRUE if remove the hook when the channel is pulled from the bridge.
*
* \retval hook on success.
* \retval NULL on error.
*/
-static struct ast_bridge_hook *bridge_hook_generic(size_t size, ast_bridge_hook_callback callback, void *hook_pvt, ast_bridge_hook_pvt_destructor destructor)
+static struct ast_bridge_hook *bridge_hook_generic(size_t size,
+ ast_bridge_hook_callback callback,
+ void *hook_pvt,
+ ast_bridge_hook_pvt_destructor destructor,
+ int remove_on_pull)
{
struct ast_bridge_hook *hook;
@@ -2649,6 +2656,7 @@
hook->callback = callback;
hook->destructor = destructor;
hook->hook_pvt = hook_pvt;
+ hook->remove_on_pull = remove_on_pull;
}
return hook;
@@ -2658,13 +2666,15 @@
const char *dtmf,
ast_bridge_hook_callback callback,
void *hook_pvt,
- ast_bridge_hook_pvt_destructor destructor)
+ ast_bridge_hook_pvt_destructor destructor,
+ int remove_on_pull)
{
struct ast_bridge_hook *hook;
int res;
/* Allocate new hook and setup it's various variables */
- hook = bridge_hook_generic(sizeof(*hook), callback, hook_pvt, destructor);
+ hook = bridge_hook_generic(sizeof(*hook), callback, hook_pvt, destructor,
+ remove_on_pull);
if (!hook) {
return -1;
}
@@ -2680,13 +2690,15 @@
int ast_bridge_hangup_hook(struct ast_bridge_features *features,
ast_bridge_hook_callback callback,
void *hook_pvt,
- ast_bridge_hook_pvt_destructor destructor)
+ ast_bridge_hook_pvt_destructor destructor,
+ int remove_on_pull)
{
struct ast_bridge_hook *hook;
int res;
/* Allocate new hook and setup it's various variables */
- hook = bridge_hook_generic(sizeof(*hook), callback, hook_pvt, destructor);
+ hook = bridge_hook_generic(sizeof(*hook), callback, hook_pvt, destructor,
+ remove_on_pull);
if (!hook) {
return -1;
}
@@ -2712,7 +2724,8 @@
unsigned int interval,
ast_bridge_hook_callback callback,
void *hook_pvt,
- ast_bridge_hook_pvt_destructor destructor)
+ ast_bridge_hook_pvt_destructor destructor,
+ int remove_on_pull)
{
struct ast_bridge_hook *hook;
int res;
@@ -2730,7 +2743,8 @@
}
/* Allocate new hook and setup it's various variables */
- hook = bridge_hook_generic(sizeof(*hook), callback, hook_pvt, destructor);
+ hook = bridge_hook_generic(sizeof(*hook), callback, hook_pvt, destructor,
+ remove_on_pull);
if (!hook) {
return -1;
}
@@ -2751,7 +2765,12 @@
return res ? -1 : 0;
}
-int ast_bridge_features_enable(struct ast_bridge_features *features, enum ast_bridge_builtin_feature feature, const char *dtmf, void *config, ast_bridge_hook_pvt_destructor destructor)
+int ast_bridge_features_enable(struct ast_bridge_features *features,
+ enum ast_bridge_builtin_feature feature,
+ const char *dtmf,
+ void *config,
+ ast_bridge_hook_pvt_destructor destructor,
+ int remove_on_pull)
{
if (ARRAY_LEN(builtin_features_handlers) <= feature
|| !builtin_features_handlers[feature]) {
@@ -2773,7 +2792,8 @@
* The rest is basically pretty easy. We create another hook
* using the built in feature's DTMF callback. Easy as pie.
*/
- return ast_bridge_dtmf_hook(features, dtmf, builtin_features_handlers[feature], config, destructor);
+ return ast_bridge_dtmf_hook(features, dtmf, builtin_features_handlers[feature],
+ config, destructor, remove_on_pull);
}
int ast_bridge_features_limits_construct(struct ast_bridge_features_limits *limits)
@@ -2793,13 +2813,13 @@
ast_string_field_free_memory(limits);
}
-int ast_bridge_features_set_limits(struct ast_bridge_features *features, struct ast_bridge_features_limits *limits)
+int ast_bridge_features_set_limits(struct ast_bridge_features *features, struct ast_bridge_features_limits *limits, int remove_on_pull)
{
if (builtin_interval_handlers[AST_BRIDGE_BUILTIN_INTERVAL_LIMITS]) {
- int (*bridge_features_set_limits_callback)(struct ast_bridge_features *features, struct ast_bridge_features_limits *limits);
+ ast_bridge_builtin_set_limits_fn bridge_features_set_limits_callback;
bridge_features_set_limits_callback = builtin_interval_handlers[AST_BRIDGE_BUILTIN_INTERVAL_LIMITS];
- return bridge_features_set_limits_callback(features, limits);
+ return bridge_features_set_limits_callback(features, limits, remove_on_pull);
}
ast_log(LOG_ERROR, "Attempted to set limits without an AST_BRIDGE_BUILTIN_INTERVAL_LIMITS callback registered.\n");
@@ -2810,6 +2830,101 @@
{
ast_set_flag(&features->feature_flags, flag);
features->usable = 1;
+}
+
+/*!
+ * \internal
+ * \brief ao2 object match remove_on_pull hooks.
+ * \since 12.0.0
+ *
+ * \param obj Feature hook object.
+ * \param arg Not used
+ * \param flags Not used
+ *
+ * \retval CMP_MATCH if hook has remove_on_pull set.
+ * \retval 0 if not match.
+ */
+static int hook_remove_on_pull_match(void *obj, void *arg, int flags)
+{
+ struct ast_bridge_hook *hook = obj;
+
+ if (hook->remove_on_pull) {
+ return CMP_MATCH;
+ } else {
+ return 0;
+ }
+}
+
+/*!
+ * \internal
+ * \brief Remove all remove_on_pull hooks in the container.
+ * \since 12.0.0
+ *
+ * \param hooks Hooks container to work on.
+ *
+ * \return Nothing
+ */
+static void hooks_remove_on_pull_container(struct ao2_container *hooks)
+{
+ if (hooks) {
+ ao2_callback(hooks, OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE,
+ hook_remove_on_pull_match, NULL);
+ }
+}
+
+/*!
+ * \internal
+ * \brief Remove all remove_on_pull hooks in the heap.
+ * \since 12.0.0
+ *
+ * \param hooks Hooks heap to work on.
+ *
+ * \return Nothing
+ */
+static void hooks_remove_on_pull_heap(struct ast_heap *hooks)
+{
+ struct ast_bridge_hook *hook;
+ int changed;
+
+ if (!hooks) {
+ return;
+ }
+
+ ast_heap_wrlock(hooks);
+ do {
+ int idx;
+
+ changed = 0;
+ for (idx = ast_heap_size(hooks); idx; --idx) {
+ hook = ast_heap_peek(hooks, idx);
+ if (hook->remove_on_pull) {
+ ast_heap_remove(hooks, hook);
+ ao2_ref(hook, -1);
+ changed = 1;
+ }
+ }
+ } while (changed);
+ ast_heap_unlock(hooks);
+}
+
+/*!
+ * \internal
+ * \brief Remove marked bridge channel feature hooks.
+ * \since 12.0.0
+ *
+ * \param features Bridge featues structure
+ *
+ * \return Nothing
+ */
+static void bridge_features_remove_on_pull(struct ast_bridge_features *features)
+{
+ if (!features) {
+ return;
+ }
+
+ hooks_remove_on_pull_container(features->dtmf_hooks);
+ hooks_remove_on_pull_container(features->hangup_hooks);
+ hooks_remove_on_pull_heap(features->interval_hooks);
}
static int interval_hook_time_cmp(void *a, void *b)
Modified: team/rmudgett/bridge_tasks/main/features.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/bridge_tasks/main/features.c?view=diff&rev=383630&r1=383629&r2=383630
==============================================================================
--- team/rmudgett/bridge_tasks/main/features.c (original)
+++ team/rmudgett/bridge_tasks/main/features.c Fri Mar 22 15:41:27 2013
@@ -4259,12 +4259,12 @@
dtmf = ast_find_call_feature("blindxfer");
if (dtmf && !ast_strlen_zero(dtmf->exten)) {
/* BUGBUG need to supply a blind transfer structure and destructor to use other than defaults */
- res |= ast_bridge_features_enable(features, AST_BRIDGE_BUILTIN_BLINDTRANSFER, dtmf->exten, NULL, NULL);
+ res |= ast_bridge_features_enable(features, AST_BRIDGE_BUILTIN_BLINDTRANSFER, dtmf->exten, NULL, NULL, 0);
}
dtmf = ast_find_call_feature("atxfer");
if (dtmf && !ast_strlen_zero(dtmf->exten)) {
/* BUGBUG need to supply an attended transfer structure and destructor to use other than defaults */
- res |= ast_bridge_features_enable(features, AST_BRIDGE_BUILTIN_ATTENDEDTRANSFER, dtmf->exten, NULL, NULL);
+ res |= ast_bridge_features_enable(features, AST_BRIDGE_BUILTIN_ATTENDEDTRANSFER, dtmf->exten, NULL, NULL, 0);
}
ast_rwlock_unlock(&features_lock);
}
@@ -4272,7 +4272,7 @@
ast_rwlock_rdlock(&features_lock);
dtmf = ast_find_call_feature("disconnect");
if (dtmf && !ast_strlen_zero(dtmf->exten)) {
- res |= ast_bridge_features_enable(features, AST_BRIDGE_BUILTIN_HANGUP, dtmf->exten, NULL, NULL);
+ res |= ast_bridge_features_enable(features, AST_BRIDGE_BUILTIN_HANGUP, dtmf->exten, NULL, NULL, 0);
}
ast_rwlock_unlock(&features_lock);
}
@@ -4280,7 +4280,7 @@
ast_rwlock_rdlock(&features_lock);
dtmf = ast_find_call_feature("parkcall");
if (dtmf && !ast_strlen_zero(dtmf->exten)) {
- res |= ast_bridge_features_enable(features, AST_BRIDGE_BUILTIN_PARKCALL, dtmf->exten, NULL, NULL);
+ res |= ast_bridge_features_enable(features, AST_BRIDGE_BUILTIN_PARKCALL, dtmf->exten, NULL, NULL, 0);
}
ast_rwlock_unlock(&features_lock);
}
@@ -4288,7 +4288,7 @@
ast_rwlock_rdlock(&features_lock);
dtmf = ast_find_call_feature("automon");
if (dtmf && !ast_strlen_zero(dtmf->exten)) {
- res |= ast_bridge_features_enable(features, AST_BRIDGE_BUILTIN_AUTOMON, dtmf->exten, NULL, NULL);
+ res |= ast_bridge_features_enable(features, AST_BRIDGE_BUILTIN_AUTOMON, dtmf->exten, NULL, NULL, 0);
}
ast_rwlock_unlock(&features_lock);
}
@@ -4296,7 +4296,7 @@
ast_rwlock_rdlock(&features_lock);
dtmf = ast_find_call_feature("automixmon");
if (dtmf && !ast_strlen_zero(dtmf->exten)) {
- res |= ast_bridge_features_enable(features, AST_BRIDGE_BUILTIN_AUTOMIXMON, dtmf->exten, NULL, NULL);
+ res |= ast_bridge_features_enable(features, AST_BRIDGE_BUILTIN_AUTOMIXMON, dtmf->exten, NULL, NULL, 0);
}
ast_rwlock_unlock(&features_lock);
}
@@ -4518,10 +4518,10 @@
bridge_config_set_limits(config, &call_duration_limits_chan, &call_duration_limits_peer);
- if (ast_bridge_features_set_limits(&chan_features, &call_duration_limits_chan)) {
+ if (ast_bridge_features_set_limits(&chan_features, &call_duration_limits_chan, 0)) {
abandon_call = 1;
}
- if (ast_bridge_features_set_limits(peer_features, &call_duration_limits_peer)) {
+ if (ast_bridge_features_set_limits(peer_features, &call_duration_limits_peer, 0)) {
abandon_call = 1;
}
More information about the svn-commits
mailing list