[svn-commits] rmudgett: branch rmudgett/bridge_phase r395238 - in /team/rmudgett/bridge_pha...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Tue Jul 23 18:24:50 CDT 2013


Author: rmudgett
Date: Tue Jul 23 18:24:48 2013
New Revision: 395238

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=395238
Log:
Merge the talk detection hook into the other_hooks.

Modified:
    team/rmudgett/bridge_phase/apps/app_confbridge.c
    team/rmudgett/bridge_phase/include/asterisk/bridging_features.h
    team/rmudgett/bridge_phase/main/bridging.c

Modified: team/rmudgett/bridge_phase/apps/app_confbridge.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/bridge_phase/apps/app_confbridge.c?view=diff&rev=395238&r1=395237&r2=395238
==============================================================================
--- team/rmudgett/bridge_phase/apps/app_confbridge.c (original)
+++ team/rmudgett/bridge_phase/apps/app_confbridge.c Tue Jul 23 18:24:48 2013
@@ -1402,25 +1402,26 @@
 	ast_free(pvt_data);
 }
 
-static void conf_handle_talker_cb(struct ast_bridge_channel *bridge_channel, void *pvt_data, int talking)
+static int conf_handle_talker_cb(struct ast_bridge_channel *bridge_channel, void *pvt_data, int talking)
 {
 	const char *conf_name = pvt_data;
 	struct confbridge_conference *conference = ao2_find(conference_bridges, conf_name, OBJ_KEY);
 	struct ast_json *talking_extras;
 
 	if (!conference) {
-		return;
+		/* Remove the hook since the conference does not exist. */
+		return -1;
 	}
 
 	talking_extras = ast_json_pack("{s: s}",
-					 "talking_status", talking ? "on" : "off");
-
+		"talking_status", talking ? "on" : "off");
 	if (!talking_extras) {
-		return;
+		return 0;
 	}
 
 	send_conf_stasis(conference, bridge_channel->chan, confbridge_talking_type(), talking_extras, 0);
 	ast_json_unref(talking_extras);
+	return 0;
 }
 
 static int conf_get_pin(struct ast_channel *chan, struct confbridge_user *user)
@@ -1599,14 +1600,17 @@
 	/* Set a talker indicate call back if talking detection is requested */
 	if (ast_test_flag(&user.u_profile, USER_OPT_TALKER_DETECT)) {
 		char *conf_name = ast_strdup(args.conf_name); /* this is freed during feature cleanup */
-		if (!(conf_name)) {
+
+		if (!conf_name) {
 			res = -1; /* invalid PIN */
 			goto confbridge_cleanup;
 		}
-		ast_bridge_features_set_talk_detector(&user.features,
-			conf_handle_talker_cb,
-			conf_handle_talker_destructor,
-			conf_name);
+		if (ast_bridge_talk_detector_hook(&user.features, conf_handle_talker_cb,
+			conf_name, conf_handle_talker_destructor, AST_BRIDGE_HOOK_REMOVE_ON_PULL)) {
+			ast_free(conf_name);
+			res = -1;
+			goto confbridge_cleanup;
+		}
 	}
 
 	/* Look for a conference bridge matching the provided name */

Modified: team/rmudgett/bridge_phase/include/asterisk/bridging_features.h
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/bridge_phase/include/asterisk/bridging_features.h?view=diff&rev=395238&r1=395237&r2=395238
==============================================================================
--- team/rmudgett/bridge_phase/include/asterisk/bridging_features.h (original)
+++ team/rmudgett/bridge_phase/include/asterisk/bridging_features.h Tue Jul 23 18:24:48 2013
@@ -149,12 +149,10 @@
  * \param bridge_channel Channel executing the feature
  * \param talking TRUE if the channel is now talking
  *
- * \retval 0 success
- * \retval -1 failure
- */
-typedef void (*ast_bridge_talking_indicate_callback)(struct ast_bridge_channel *bridge_channel, void *pvt_data, int talking);
-
-typedef void (*ast_bridge_talking_indicate_destructor)(void *pvt_data);
+ * \retval 0 Keep the callback hook.
+ * \retval -1 Remove the callback hook.
+ */
+typedef int (*ast_bridge_talking_indicate_callback)(struct ast_bridge_channel *bridge_channel, void *pvt_data, int talking);
 
 enum ast_bridge_hook_remove_flags {
 	/*! The hook is removed when the channel is pulled from the bridge. */
@@ -171,6 +169,7 @@
 	AST_BRIDGE_HOOK_TYPE_HANGUP,
 	AST_BRIDGE_HOOK_TYPE_JOIN,
 	AST_BRIDGE_HOOK_TYPE_LEAVE,
+	AST_BRIDGE_HOOK_TYPE_TALK,
 };
 
 /* BUGBUG Need to be able to selectively remove DTMF, hangup, and interval hooks. */
@@ -229,15 +228,6 @@
 
 #define BRIDGE_FEATURES_INTERVAL_RATE 10
 
-struct talker_detection_hook {
-	/*! Callback to indicate when a bridge channel has started and stopped talking */
-	ast_bridge_talking_indicate_callback callback;
-	/*! Callback to destroy any pvt data stored for the talker. */
-	ast_bridge_talking_indicate_destructor destructor;
-	/*! Talker callback pvt data */
-	void *pvt_data;
-};
-
 /*!
  * \brief Structure that contains features information
  */
@@ -252,8 +242,6 @@
 	struct ast_timer *interval_timer;
 	/*! Limits feature data */
 	struct ast_bridge_features_limits *limits;
-	/*! Start/stop talking detection hook. */
-	struct talker_detection_hook talker_hook;
 	/*! Feature flags that are enabled */
 	struct ast_flags feature_flags;
 	/*! Used to assign the sequence number to the next interval hook added. */
@@ -594,19 +582,37 @@
 	enum ast_bridge_hook_remove_flags remove_flags);
 
 /*!
- * \brief Set a callback on the features structure to receive talking notifications on.
- *
- * \param features Bridge features structure
- * \param talker_cb Callback function to execute when talking events occur in the bridge core.
- * \param pvt_data Optional unique data that will be passed with the talking events.
- * \param talker_destructor Optional destructor callback for pvt data.
- *
- * \return Nothing
- */
-void ast_bridge_features_set_talk_detector(struct ast_bridge_features *features,
-	ast_bridge_talking_indicate_callback talker_cb,
-	ast_bridge_talking_indicate_destructor talker_destructor,
-	void *pvt_data);
+ * \brief Attach a bridge channel talk detection hook to a bridge features structure
+ *
+ * \param features Bridge features structure
+ * \param callback Function to execute upon activation
+ * \param hook_pvt Unique data
+ * \param destructor Optional destructor callback for hook_pvt data
+ * \param remove_flags Dictates what situations the hook should be removed.
+ *
+ * \retval 0 on success
+ * \retval -1 on failure (The caller must cleanup any hook_pvt resources.)
+ *
+ * Example usage:
+ *
+ * \code
+ * struct ast_bridge_features features;
+ * ast_bridge_features_init(&features);
+ * ast_bridge_talk_hook(&features, talk_callback, NULL, NULL, 0);
+ * \endcode
+ *
+ * This makes the bridging technology call talk_callback when a
+ * channel is recognized as starting and stopping talking.  A
+ * pointer to useful data may be provided to the hook_pvt
+ * parameter.
+ *
+ * \note This hook is currently only supported by softmix.
+ */
+int ast_bridge_talk_detector_hook(struct ast_bridge_features *features,
+	ast_bridge_talking_indicate_callback callback,
+	void *hook_pvt,
+	ast_bridge_hook_pvt_destructor destructor,
+	enum ast_bridge_hook_remove_flags remove_flags);
 
 /*!
  * \brief Enable a built in feature on a bridge features structure

Modified: team/rmudgett/bridge_phase/main/bridging.c
URL: http://svnview.digium.com/svn/asterisk/team/rmudgett/bridge_phase/main/bridging.c?view=diff&rev=395238&r1=395237&r2=395238
==============================================================================
--- team/rmudgett/bridge_phase/main/bridging.c (original)
+++ team/rmudgett/bridge_phase/main/bridging.c Tue Jul 23 18:24:48 2013
@@ -2581,10 +2581,27 @@
 static void bridge_channel_talking(struct ast_bridge_channel *bridge_channel, int talking)
 {
 	struct ast_bridge_features *features = bridge_channel->features;
-
-	if (features->talker_hook.callback) {
-		features->talker_hook.callback(bridge_channel, features->talker_hook.pvt_data, talking);
-	}
+	struct ast_bridge_hook *hook;
+	struct ao2_iterator iter;
+
+	/* Run any talk detection hooks. */
+	iter = ao2_iterator_init(features->other_hooks, 0);
+	for (; (hook = ao2_iterator_next(&iter)); ao2_ref(hook, -1)) {
+		int remove_me;
+		ast_bridge_talking_indicate_callback talk_cb;
+
+		if (hook->type != AST_BRIDGE_HOOK_TYPE_TALK) {
+			continue;
+		}
+		talk_cb = (ast_bridge_talking_indicate_callback) hook->callback;
+		remove_me = talk_cb(bridge_channel, hook->hook_pvt, talking);
+		if (remove_me) {
+			ast_debug(1, "Talk detection hook %p is being removed from %p(%s)\n",
+				hook, bridge_channel, ast_channel_name(bridge_channel->chan));
+			ao2_unlink(features->other_hooks, hook);
+		}
+	}
+	ao2_iterator_destroy(&iter);
 }
 
 /*! \brief Internal function that plays back DTMF on a bridge channel */
@@ -5373,14 +5390,16 @@
 		AST_BRIDGE_HOOK_TYPE_LEAVE);
 }
 
-void ast_bridge_features_set_talk_detector(struct ast_bridge_features *features,
-	ast_bridge_talking_indicate_callback talker_cb,
-	ast_bridge_talking_indicate_destructor talker_destructor,
-	void *pvt_data)
-{
-	features->talker_hook.callback = talker_cb;
-	features->talker_hook.destructor = talker_destructor;
-	features->talker_hook.pvt_data = pvt_data;
+int ast_bridge_talk_detector_hook(struct ast_bridge_features *features,
+	ast_bridge_talking_indicate_callback callback,
+	void *hook_pvt,
+	ast_bridge_hook_pvt_destructor destructor,
+	enum ast_bridge_hook_remove_flags remove_flags)
+{
+	ast_bridge_hook_callback hook_cb = (ast_bridge_hook_callback) callback;
+
+	return bridge_other_hook(features, hook_cb, hook_pvt, destructor, remove_flags,
+		AST_BRIDGE_HOOK_TYPE_TALK);
 }
 
 int ast_bridge_interval_hook(struct ast_bridge_features *features,
@@ -5688,11 +5707,6 @@
 		ast_bridge_features_limits_destroy(features->limits);
 		ast_free(features->limits);
 		features->limits = NULL;
-	}
-
-	if (features->talker_hook.destructor && features->talker_hook.pvt_data) {
-		features->talker_hook.destructor(features->talker_hook.pvt_data);
-		features->talker_hook.pvt_data = NULL;
 	}
 
 	/* Destroy the miscellaneous other hooks container. */




More information about the svn-commits mailing list