[asterisk-commits] rmudgett: branch rmudgett/bridge_tasks r383654 - in /team/rmudgett/bridge_tas...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Mar 22 19:37:23 CDT 2013


Author: rmudgett
Date: Fri Mar 22 19:37:19 2013
New Revision: 383654

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=383654
Log:
Replace bridge personality with a class hierarchy of ast_bridge.

Now derive ast_bridge_basic, ast_bridge_parking, and ast_bridge_confbridge
from the ast_bridge base class.

struct ast_bridge_basic *ast_bridge_basic_new()
  void *bridge
  bridge = ast_bridge_alloc(sizeof(struct ast_bridge_basic), &ast_bridge_basic_v_table)
  bridge = ast_bridge_base_init(bridge, ...)
  bridge = ast_bridge_basic_init(bridge, ...)
  return bridge

Modified:
    team/rmudgett/bridge_tasks/apps/app_bridgewait.c
    team/rmudgett/bridge_tasks/apps/app_confbridge.c
    team/rmudgett/bridge_tasks/bridges/bridge_builtin_features.c
    team/rmudgett/bridge_tasks/include/asterisk/bridging.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=383654&r1=383653&r2=383654
==============================================================================
--- team/rmudgett/bridge_tasks/apps/app_bridgewait.c (original)
+++ team/rmudgett/bridge_tasks/apps/app_bridgewait.c Fri Mar 22 19:37:19 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, 1);
+	ast_bridge_features_set_limits(features, &hold_limits, 1 /* remove_on_pull */);
 	ast_bridge_features_limits_destroy(&hold_limits);
 
 	return 0;
@@ -195,9 +195,8 @@
 
 	ast_mutex_lock(&bridgewait_lock);
 	if (!holding_bridge) {
-/* BUGBUG this holding bridge needs a personality to manage the timeout. Otherwise, the timer will move to the next bridge which is likely not desireable. */
-		holding_bridge = ast_bridge_new(AST_BRIDGE_CAPABILITY_HOLDING,
-			AST_BRIDGE_FLAG_MERGE_INHIBIT_TO | AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM, NULL);
+		holding_bridge = ast_bridge_base_new(AST_BRIDGE_CAPABILITY_HOLDING,
+			AST_BRIDGE_FLAG_MERGE_INHIBIT_TO | AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM);
 	}
 	ast_mutex_unlock(&bridgewait_lock);
 	if (!holding_bridge) {

Modified: team/rmudgett/bridge_tasks/apps/app_confbridge.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/bridge_tasks/apps/app_confbridge.c?view=diff&rev=383654&r1=383653&r2=383654
==============================================================================
--- team/rmudgett/bridge_tasks/apps/app_confbridge.c (original)
+++ team/rmudgett/bridge_tasks/apps/app_confbridge.c Fri Mar 22 19:37:19 2013
@@ -1285,8 +1285,9 @@
 		conf_bridge_profile_copy(&conference->b_profile, &user->b_profile);
 
 		/* Create an actual bridge that will do the audio mixing */
-		if (!(conference->bridge = ast_bridge_new(AST_BRIDGE_CAPABILITY_MULTIMIX,
-			AST_BRIDGE_FLAG_MASQUERADE_ONLY, NULL))) {
+		conference->bridge = ast_bridge_base_new(AST_BRIDGE_CAPABILITY_MULTIMIX,
+			AST_BRIDGE_FLAG_MASQUERADE_ONLY);
+		if (!conference->bridge) {
 			ao2_ref(conference, -1);
 			conference = NULL;
 			ao2_unlock(conference_bridges);

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=383654&r1=383653&r2=383654
==============================================================================
--- team/rmudgett/bridge_tasks/bridges/bridge_builtin_features.c (original)
+++ team/rmudgett/bridge_tasks/bridges/bridge_builtin_features.c Fri Mar 22 19:37:19 2013
@@ -300,8 +300,9 @@
 	}
 
 	/* Create a bridge to use to talk to the person we are calling */
-	attended_bridge = ast_bridge_new(AST_BRIDGE_CAPABILITY_NATIVE | AST_BRIDGE_CAPABILITY_1TO1MIX,
-		AST_BRIDGE_FLAG_DISSOLVE_HANGUP, NULL);
+	attended_bridge = ast_bridge_base_new(
+		AST_BRIDGE_CAPABILITY_NATIVE | AST_BRIDGE_CAPABILITY_1TO1MIX,
+		AST_BRIDGE_FLAG_DISSOLVE_HANGUP);
 	if (!attended_bridge) {
 		ast_bridge_features_cleanup(&caller_features);
 		ast_hangup(peer);

Modified: team/rmudgett/bridge_tasks/include/asterisk/bridging.h
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/bridge_tasks/include/asterisk/bridging.h?view=diff&rev=383654&r1=383653&r2=383654
==============================================================================
--- team/rmudgett/bridge_tasks/include/asterisk/bridging.h (original)
+++ team/rmudgett/bridge_tasks/include/asterisk/bridging.h Fri Mar 22 19:37:19 2013
@@ -114,85 +114,71 @@
 	unsigned int drop_silence:1;
 };
 
-/*!
- * \brief Create the bridge personality.
+/* BUGBUG move these declarations to before struct ast_bridge declared. --v */
+/*!
+ * \brief Destroy the bridge.
  *
  * \param self Bridge to operate upon.
  *
+ * \return Nothing
+ */
+typedef void (*ast_bridge_destructor_fn)(struct ast_bridge *self);
+
+/*!
+ * \brief Can this channel be pushed into the bridge.
+ *
+ * \param self Bridge to operate upon.
+ * \param bridge_channel Bridge channel wanting to push.
+ * \param swap Bridge channel to swap places with if not NULL.
+ *
+ * \note On entry, self is already locked.
+ *
+ * \retval TRUE if can push this channel into the bridge.
+ */
+typedef int (*ast_bridge_can_push_channel_fn)(struct ast_bridge *self, struct ast_bridge_channel *bridge_channel, struct ast_bridge_channel *swap);
+
+/*!
+ * \brief Push this channel into the bridge.
+ *
+ * \param self Bridge to operate upon.
+ * \param bridge_channel Bridge channel to push.
+ * \param swap Bridge channel to swap places with if not NULL.
+ *
  * \details
- * Allocate and setup the self->personality_pvt.
+ * Setup any channel hooks controlled by the bridge.  Allocate
+ * bridge_channel->bridge_pvt and initialize any resources put
+ * in bridge_channel->bridge_pvt if needed.  If there is a swap
+ * channel, use it as a guide to setting up the bridge_channel.
  *
  * \note On entry, self is already locked.
  *
  * \retval 0 on success
  * \retval -1 on failure
  */
-typedef int (*ast_personality_create_fn)(struct ast_bridge *self);
-
-/*!
- * \brief Destroy the bridge personality.
+typedef int (*ast_bridge_push_channel_fn)(struct ast_bridge *self, struct ast_bridge_channel *bridge_channel, struct ast_bridge_channel *swap);
+
+/*!
+ * \brief Pull this channel from the bridge.
  *
  * \param self Bridge to operate upon.
+ * \param bridge_channel Bridge channel to pull.
  *
  * \details
- * Release any resources held by self->personality_pvt and
- * release self->personality_pvt.
- *
- * \return Nothing
- */
-typedef void (*ast_personality_destroy_fn)(struct ast_bridge *self);
-
-/*!
- * \brief Can this channel be pushed into its bridge.
- *
- * \param self Bridge channel to operate upon.
- * \param swap Bridge channel to swap places with if not NULL.
- *
- * \note On entry, self->bridge is already locked.
- *
- * \retval TRUE if can push this channel into its bridge.
- */
-typedef int (*ast_personality_channel_can_push_fn)(struct ast_bridge_channel *self, struct ast_bridge_channel *swap);
-
-/*!
- * \brief Push this channel into its bridge.
- *
- * \param self Bridge channel to operate upon.
- * \param swap Bridge channel to swap places with if not NULL.
- *
- * \details
- * Setup any channel hooks controlled by the personality,
- * allocate and setup the self->personality_pvt.  If there is a
- * swap channel, use it as a guide to setting up the self
- * channel.
- *
- * \note On entry, self->bridge is already locked.
- *
- * \retval 0 on success
- * \retval -1 on failure
- */
-typedef int (*ast_personality_channel_push_fn)(struct ast_bridge_channel *self, struct ast_bridge_channel *swap);
-
-/*!
- * \brief Pull this channel from its bridge.
- *
- * \param self Bridge channel to operate upon.
- *
- * \details
- * Remove any channel hooks controlled by the personality.
- * Release any resources held by self->personality_pvt and
- * release self->personality_pvt.
- *
- * \note On entry, self->bridge is already locked.
- *
- * \return Nothing
- */
-typedef void (*ast_personality_channel_pull_fn)(struct ast_bridge_channel *self);
-
-/*!
- * \brief Masquerade push this channel into its bridge.
- *
- * \param self Bridge channel to operate upon.
+ * Remove any channel hooks controlled by the bridge.  Release
+ * any resources held by bridge_channel->bridge_pvt and release
+ * bridge_channel->bridge_pvt.
+ *
+ * \note On entry, self is already locked.
+ *
+ * \return Nothing
+ */
+typedef void (*ast_bridge_pull_channel_fn)(struct ast_bridge *self, struct ast_bridge_channel *bridge_channel);
+
+/*!
+ * \brief Masquerade push this channel into the bridge.
+ *
+ * \param self Bridge to operate upon.
+ * \param bridge_channel Bridge channel to virtually push.
  *
  * \note This is a virtual push into the bridge because a
  * masquerade swaps the guts of the channel to give it a new
@@ -201,12 +187,13 @@
  *
  * \return Nothing
  */
-typedef void (*ast_personality_channel_push_masquerade_fn)(struct ast_bridge_channel *self);
-
-/*!
- * \brief Masquerade pull this channel from its bridge.
- *
- * \param self Bridge channel to operate upon.
+typedef void (*ast_bridge_push_channel_masquerade_fn)(struct ast_bridge *self, struct ast_bridge_channel *bridge_channel);
+
+/*!
+ * \brief Masquerade pull this channel from the bridge.
+ *
+ * \param self Bridge to operate upon.
+ * \param bridge_channel Bridge channel to virtually pull.
  *
  * \note This is a virtual pull from the bridge because a
  * masquerade swaps the guts of the channel to give it a new
@@ -215,32 +202,31 @@
  *
  * \return Nothing
  */
-typedef void (*ast_personality_channel_pull_masquerade_fn)(struct ast_bridge_channel *self);
-
-/*! Bridge personality virtual methods table definition. */
-struct ast_personality_methods {
-	/*! Bridge personality name for log messages. */
+typedef void (*ast_bridge_pull_channel_masquerade_fn)(struct ast_bridge *self, struct ast_bridge_channel *bridge_channel);
+
+/*! Bridge virtual methods table definition. */
+struct ast_bridge_methods {
+	/*! Bridge class name for log messages. */
 	const char *name;
-	/*! Create the bridge personality. */
-	ast_personality_create_fn create;
-	/*! Destroy the bridge personality. */
-	ast_personality_destroy_fn destroy;
-	/*! TRUE if can push the bridge channel into its bridge. */
-	ast_personality_channel_can_push_fn can_push;
-	/*! Push the bridge channel into its bridge. */
-	ast_personality_channel_push_fn push;
-	/*! Pull the bridge channel from its bridge. */
-	ast_personality_channel_pull_fn pull;
+	/*! Destroy the bridge. */
+	ast_bridge_destructor_fn destroy;
+	/*! TRUE if can push the bridge channel into the bridge. */
+	ast_bridge_can_push_channel_fn can_push;
+	/*! Push the bridge channel into the bridge. */
+	ast_bridge_push_channel_fn push;
+	/*! Pull the bridge channel from the bridge. */
+	ast_bridge_pull_channel_fn pull;
 /*
  * BUGBUG push_masquerade may just have to change into masquerade_complete so the bridge will need to check compatibility again.
  * Otherwise, the bridge channel will have to constantly check if the set formats have changed before reading frames.
  * Race conditions may force the bridge channel to constantly check anyway.                                                                                                                            .
  */
-	/*! Virtually push the bridge channel into its bridge. */
-	ast_personality_channel_push_masquerade_fn push_masquerade;
-	/*! Virtually pull the bridge channel from its bridge. */
-	ast_personality_channel_pull_masquerade_fn pull_masquerade;
+	/*! Virtually push the bridge channel into the bridge. */
+	ast_bridge_push_channel_masquerade_fn push_masquerade;
+	/*! Virtually pull the bridge channel from the bridge. */
+	ast_bridge_pull_channel_masquerade_fn pull_masquerade;
 };
+/* BUGBUG move these declarations to before struct ast_bridge declared. --^ */
 
 /*!
  * \brief Structure that contains information regarding a channel in a bridge
@@ -258,13 +244,13 @@
 	/*! Bridge this channel is participating in */
 	struct ast_bridge *bridge;
 	/*!
-	 * \brief Bridge personality private bridge channel data.
+	 * \brief Bridge class private channel data.
 	 *
 	 * \note This information is added when the channel is pushed
 	 * into the bridge and removed when it is pulled from the
 	 * bridge.
 	 */
-	void *personality_pvt;
+	void *bridge_pvt;
 	/*!
 	 * \brief Private information unique to the bridge technology.
 	 *
@@ -360,14 +346,8 @@
  * \brief Structure that contains information about a bridge
  */
 struct ast_bridge {
-	/*! Bridge personality virtual method table. */
-	const struct ast_personality_methods *personality;
-	/*!
-	 * \brief Bridge personality private bridge data.
-	 *
-	 * \note This information is added when the bridge is created.
-	 */
-	void *personality_pvt;
+	/*! Bridge virtual method table. */
+	const struct ast_bridge_methods *v_table;
 	/*! Bridge technology that is handling the bridge */
 	struct ast_bridge_technology *technology;
 	/*! Private information unique to the bridge technology */
@@ -407,11 +387,49 @@
 };
 
 /*!
- * \brief Create a new bridge
- *
+ * \internal
+ * \brief Allocate the bridge class object memory.
+ * \since 12.0.0
+ *
+ * \param size Size of the bridge class structure to allocate.
+ * \param v_table Bridge class virtual method table.
+ *
+ * \retval bridge on success.
+ * \retval NULL on error.
+ */
+struct ast_bridge *ast_bridge_alloc(size_t size, const struct ast_bridge_methods *v_table);
+
+/*! \brief Bridge base class virtual method table. */
+extern struct ast_bridge_methods ast_bridge_base_v_table;
+
+/*!
+ * \brief Initialize the base class of the bridge.
+ *
+ * \param self Bridge to operate upon. (Tollerates a NULL pointer)
  * \param capabilities The capabilities that we require to be used on the bridge
  * \param flags Flags that will alter the behavior of the bridge
- * \param personality Personality of the new bridge (NULL if none)
+ *
+ * \retval self on success
+ * \retval NULL on failure, self is already destroyed
+ *
+ * Example usage:
+ *
+ * \code
+ * struct ast_bridge *bridge;
+ * bridge = ast_bridge_alloc(sizeof(*bridge), &ast_bridge_base_v_table);
+ * bridge = ast_bridge_base_init(bridge, AST_BRIDGE_CAPABILITY_1TO1MIX, AST_BRIDGE_FLAG_DISSOLVE_HANGUP);
+ * \endcode
+ *
+ * This creates a no frills two party bridge that will be
+ * destroyed once one of the channels hangs up.
+ */
+struct ast_bridge *ast_bridge_base_init(struct ast_bridge *self, uint32_t capabilities, int flags);
+
+/*!
+ * \brief Create a new base class bridge
+ *
+ * \param capabilities The capabilities that we require to be used on the bridge
+ * \param flags Flags that will alter the behavior of the bridge
  *
  * \retval a pointer to a new bridge on success
  * \retval NULL on failure
@@ -420,13 +438,13 @@
  *
  * \code
  * struct ast_bridge *bridge;
- * bridge = ast_bridge_new(AST_BRIDGE_CAPABILITY_1TO1MIX, AST_BRIDGE_FLAG_DISSOLVE_HANGUP);
- * \endcode
- *
- * This creates a simple two party bridge that will be destroyed once one of
- * the channels hangs up.
- */
-struct ast_bridge *ast_bridge_new(uint32_t capabilities, int flags, const struct ast_personality_methods *personality);
+ * bridge = ast_bridge_base_new(AST_BRIDGE_CAPABILITY_1TO1MIX, AST_BRIDGE_FLAG_DISSOLVE_HANGUP);
+ * \endcode
+ *
+ * This creates a no frills two party bridge that will be
+ * destroyed once one of the channels hangs up.
+ */
+struct ast_bridge *ast_bridge_base_new(uint32_t capabilities, int flags);
 
 /*!
  * \brief Try locking the bridge.
@@ -501,7 +519,7 @@
  * ast_bridge_destroy(bridge);
  * \endcode
  *
- * This destroys a bridge that was previously created using ast_bridge_new.
+ * This destroys a bridge that was previously created.
  */
 int ast_bridge_destroy(struct ast_bridge *bridge);
 

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=383654&r1=383653&r2=383654
==============================================================================
--- team/rmudgett/bridge_tasks/main/bridging.c (original)
+++ team/rmudgett/bridge_tasks/main/bridging.c Fri Mar 22 19:37:19 2013
@@ -391,10 +391,7 @@
 	}
 	--bridge->num_channels;
 	AST_LIST_REMOVE(&bridge->channels, bridge_channel, entry);
-	if (bridge->personality && bridge->personality->pull) {
-		bridge->personality->pull(bridge_channel);
-	}
-	bridge_features_remove_on_pull(bridge_channel->features);
+	bridge->v_table->pull(bridge, bridge_channel);
 
 	bridge->reconfigured = 1;
 }
@@ -422,8 +419,8 @@
 	bridge_channel->swap = NULL;
 
 	chan_leaving = bridge->dissolved
-		|| (bridge->personality && bridge->personality->can_push
-			&& !bridge->personality->can_push(bridge_channel, swap));
+		|| (bridge->v_table->can_push
+			&& !bridge->v_table->can_push(bridge, bridge_channel, swap));
 
 	ast_bridge_channel_lock(bridge_channel);
 	if (chan_leaving) {
@@ -450,8 +447,8 @@
 	}
 
 	/* Add channel to the bridge */
-	if (bridge->personality && bridge->personality->push
-		&& bridge->personality->push(bridge_channel, swap)) {
+	if (bridge->v_table->push
+		&& bridge->v_table->push(bridge, bridge_channel, swap)) {
 /* BUGBUG need to use bridge id in the diagnostic message */
 		ast_log(LOG_ERROR, "Pushing channel %s into bridge %p failed\n",
 			ast_channel_name(bridge_channel->chan), bridge);
@@ -824,7 +821,7 @@
 		.tech_pvt = deferred->tech_pvt,
 		};
 
-	ast_debug(1, "Giving bridge technology %s the bridge structure %p (really %p) to destroy (deferred)\n",
+	ast_debug(1, "Calling bridge technology %s destructor for bridge %p (really %p) (deferred)\n",
 		dummy_bridge.technology->name, &dummy_bridge, bridge);
 	dummy_bridge.technology->destroy(&dummy_bridge);
 	ast_module_unref(dummy_bridge.technology->mod);
@@ -896,7 +893,8 @@
 {
 	struct ast_bridge *bridge = obj;
 
-	ast_debug(1, "Actually destroying bridge %p, nobody wants it anymore\n", bridge);
+	ast_debug(1, "Actually destroying %s bridge %p, nobody wants it anymore\n",
+		bridge->v_table->name, bridge);
 
 	/* Do any pending actions in the context of destruction. */
 	ast_bridge_lock(bridge);
@@ -906,20 +904,23 @@
 	/* There should not be any channels left in the bridge. */
 	ast_assert(AST_LIST_EMPTY(&bridge->channels));
 
+	if (bridge->v_table->destroy) {
+		ast_debug(1, "Calling %s bridge destructor for bridge %p\n",
+			bridge->v_table->name, bridge);
+		if (bridge->v_table->destroy) {
+			bridge->v_table->destroy(bridge);
+		}
+	}
+
 	/* Pass off the bridge to the technology to destroy if needed */
-	ast_debug(1, "Giving bridge technology %s the bridge structure %p to destroy\n",
-		bridge->technology->name, bridge);
-	if (bridge->technology->destroy) {
-		bridge->technology->destroy(bridge);
-	}
-	ast_module_unref(bridge->technology->mod);
-
-	if (bridge->personality) {
-		ast_debug(1, "Giving bridge personality %s the bridge structure %p to destroy\n",
-			bridge->personality->name, bridge);
-		if (bridge->personality->destroy) {
-			bridge->personality->destroy(bridge);
-		}
+	if (bridge->technology) {
+		ast_debug(1, "Calling bridge technology %s destructor for bridge %p\n",
+			bridge->technology->name, bridge);
+		if (bridge->technology->destroy) {
+			bridge->technology->destroy(bridge);
+		}
+		ast_module_unref(bridge->technology->mod);
+		bridge->technology = NULL;
 	}
 
 	if (bridge->callid) {
@@ -929,15 +930,36 @@
 	cleanup_video_mode(bridge);
 }
 
-struct ast_bridge *ast_bridge_new(uint32_t capabilities, int flags, const struct ast_personality_methods *personality)
+struct ast_bridge *ast_bridge_alloc(size_t size, const struct ast_bridge_methods *v_table)
 {
 	struct ast_bridge *bridge;
-	struct ast_bridge_technology *bridge_technology;
+
+	/* Check v_table for required methods. */
+	if (!v_table || !v_table->name || !v_table->pull) {
+		ast_assert(0);
+		return NULL;
+	}
+
+	bridge = ao2_alloc(size, destroy_bridge);
+	if (bridge) {
+		bridge->v_table = v_table;
+	}
+	return bridge;
+}
+
+struct ast_bridge *ast_bridge_base_init(struct ast_bridge *self, uint32_t capabilities, int flags)
+{
+	if (!self) {
+		return NULL;
+	}
+
+	ast_set_flag(&self->feature_flags, flags);
 
 	/* If we need to be a smart bridge see if we can move between 1to1 and multimix bridges */
 	if (flags & AST_BRIDGE_FLAG_SMART) {
 		if (!ast_bridge_check((capabilities & AST_BRIDGE_CAPABILITY_1TO1MIX)
 			? AST_BRIDGE_CAPABILITY_MULTIMIX : AST_BRIDGE_CAPABILITY_1TO1MIX)) {
+			ao2_ref(self, -1);
 			return NULL;
 		}
 	}
@@ -947,48 +969,55 @@
 	 * the "best" bridge technology, otherwise we can just look for
 	 * the most basic capability needed, single 1to1 mixing.
 	 */
-	bridge_technology = capabilities
+	self->technology = capabilities
 		? find_best_technology(capabilities)
 		: find_best_technology(AST_BRIDGE_CAPABILITY_1TO1MIX);
-
-	/* If no bridge technology was found we can't possibly do bridging so fail creation of the bridge */
-	if (!bridge_technology) {
+	if (!self->technology) {
+		ao2_ref(self, -1);
 		return NULL;
 	}
 
-	/* We have everything we need to create this bridge... so allocate the memory, link things together, and fire her up! */
-	bridge = ao2_alloc(sizeof(*bridge), destroy_bridge);
-	if (!bridge) {
-		ast_module_unref(bridge_technology->mod);
+	/* Pass off the bridge to the technology to manipulate if needed */
+	ast_debug(1, "Calling bridge technology %s constructor for bridge %p\n",
+		self->technology->name, self);
+	if (self->technology->create && self->technology->create(self)) {
+		ast_debug(1, "Bridge technology %s failed to setup on bridge %p\n",
+			self->technology->name, self);
+		ao2_ref(self, -1);
 		return NULL;
 	}
 
-	bridge->personality = personality;
-	bridge->technology = bridge_technology;
-
-	ast_set_flag(&bridge->feature_flags, flags);
-
-	if (bridge->personality) {
-		ast_debug(1, "Giving bridge personality %s the bridge structure %p to setup\n",
-			bridge->personality->name, bridge);
-		if (bridge->personality->create && bridge->personality->create(bridge)) {
-			ast_debug(1, "Bridge personality %s failed to setup bridge structure %p\n",
-				bridge->personality->name, bridge);
-			ao2_ref(bridge, -1);
-			return NULL;
-		}
-	}
-
-	/* Pass off the bridge to the technology to manipulate if needed */
-	ast_debug(1, "Giving bridge technology %s the bridge structure %p to setup\n",
-		bridge->technology->name, bridge);
-	if (bridge->technology->create && bridge->technology->create(bridge)) {
-		ast_debug(1, "Bridge technology %s failed to setup bridge structure %p\n",
-			bridge->technology->name, bridge);
-		ao2_ref(bridge, -1);
-		return NULL;
-	}
-
+	return self;
+}
+
+/*!
+ * \internal
+ * \brief ast_bridge base pull method.
+ * \since 12.0.0
+ *
+ * \param self Bridge to operate upon.
+ * \param bridge_channel Bridge channel to pull.
+ *
+ * \note On entry, self is already locked.
+ *
+ * \return Nothing
+ */
+static void bridge_base_pull(struct ast_bridge *self, struct ast_bridge_channel *bridge_channel)
+{
+	bridge_features_remove_on_pull(bridge_channel->features);
+}
+
+struct ast_bridge_methods ast_bridge_base_v_table = {
+	.name = "base",
+	.pull = bridge_base_pull,
+};
+
+struct ast_bridge *ast_bridge_base_new(uint32_t capabilities, int flags)
+{
+	void *bridge;
+
+	bridge = ast_bridge_alloc(sizeof(struct ast_bridge), &ast_bridge_base_v_table);
+	bridge = ast_bridge_base_init(bridge, capabilities, flags);
 	return bridge;
 }
 
@@ -1193,7 +1222,7 @@
 	bridge->technology = new_technology;
 
 	/* Setup the new bridge technology. */
-	ast_debug(1, "Giving bridge technology %s the bridge structure %p to setup\n",
+	ast_debug(1, "Calling bridge technology %s constructor for bridge %p\n",
 		new_technology->name, bridge);
 	if (new_technology->create && new_technology->create(bridge)) {
 /* BUGBUG need to output the bridge id for tracking why. */
@@ -1243,11 +1272,11 @@
 	 * around.
 	 */
 	if (old_technology->destroy) {
-		ast_debug(1, "Deferring bridge technology %s bridge structure %p destruction\n",
+		ast_debug(1, "Deferring bridge technology %s destructor for bridge %p\n",
 			old_technology->name, bridge);
 		ast_bridge_queue_action_nodup(bridge, deferred_action);
 	} else {
-		ast_debug(1, "Giving bridge technology %s the bridge structure %p (really %p) to destroy\n",
+		ast_debug(1, "Calling bridge technology %s destructor for bridge %p (really %p)\n",
 			old_technology->name, &dummy_bridge, bridge);
 		ast_module_unref(old_technology->mod);
 	}

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=383654&r1=383653&r2=383654
==============================================================================
--- team/rmudgett/bridge_tasks/main/features.c (original)
+++ team/rmudgett/bridge_tasks/main/features.c Fri Mar 22 19:37:19 2013
@@ -4539,9 +4539,10 @@
 	}
 
 	/* Create bridge */
-/* BUGBUG need to create the basic bridge personality that will manage the DTMF feature hooks. */
-	bridge = ast_bridge_new(AST_BRIDGE_CAPABILITY_NATIVE | AST_BRIDGE_CAPABILITY_1TO1MIX | AST_BRIDGE_CAPABILITY_MULTIMIX,
-		AST_BRIDGE_FLAG_DISSOLVE_HANGUP | AST_BRIDGE_FLAG_SMART, NULL);
+/* BUGBUG need to create the basic bridge class that will manage the DTMF feature hooks. */
+	bridge = ast_bridge_base_new(
+		AST_BRIDGE_CAPABILITY_NATIVE | AST_BRIDGE_CAPABILITY_1TO1MIX | AST_BRIDGE_CAPABILITY_MULTIMIX,
+		AST_BRIDGE_FLAG_DISSOLVE_HANGUP | AST_BRIDGE_FLAG_SMART);
 	if (!bridge) {
 		ast_bridge_features_destroy(peer_features);
 		ast_bridge_features_cleanup(&chan_features);




More information about the asterisk-commits mailing list