[asterisk-commits] dlee: branch dlee/ari-async-bridge r395883 - in /team/dlee/ari-async-bridge: ...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Jul 31 10:38:58 CDT 2013


Author: dlee
Date: Wed Jul 31 10:38:56 2013
New Revision: 395883

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=395883
Log:
Holding bridge, and playing into a holding bridge, works as expected

Modified:
    team/dlee/ari-async-bridge/include/asterisk/bridge_features.h
    team/dlee/ari-async-bridge/include/asterisk/bridge_internal.h
    team/dlee/ari-async-bridge/include/asterisk/stasis_app_impl.h
    team/dlee/ari-async-bridge/res/res_stasis.c
    team/dlee/ari-async-bridge/res/res_stasis_bridge.c
    team/dlee/ari-async-bridge/res/res_stasis_playback.c
    team/dlee/ari-async-bridge/res/stasis/control.c
    team/dlee/ari-async-bridge/res/stasis/control.h

Modified: team/dlee/ari-async-bridge/include/asterisk/bridge_features.h
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ari-async-bridge/include/asterisk/bridge_features.h?view=diff&rev=395883&r1=395882&r2=395883
==============================================================================
--- team/dlee/ari-async-bridge/include/asterisk/bridge_features.h (original)
+++ team/dlee/ari-async-bridge/include/asterisk/bridge_features.h Wed Jul 31 10:38:56 2013
@@ -24,6 +24,8 @@
 
 #ifndef _ASTERISK_BRIDGING_FEATURES_H
 #define _ASTERISK_BRIDGING_FEATURES_H
+
+#include "asterisk/channel.h"
 
 #if defined(__cplusplus) || defined(c_plusplus)
 extern "C" {

Modified: team/dlee/ari-async-bridge/include/asterisk/bridge_internal.h
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ari-async-bridge/include/asterisk/bridge_internal.h?view=diff&rev=395883&r1=395882&r2=395883
==============================================================================
--- team/dlee/ari-async-bridge/include/asterisk/bridge_internal.h (original)
+++ team/dlee/ari-async-bridge/include/asterisk/bridge_internal.h Wed Jul 31 10:38:56 2013
@@ -36,6 +36,7 @@
 
 struct ast_bridge;
 struct ast_bridge_channel;
+struct ast_bridge_methods;
 
 /*!
  * \brief Register the new bridge with the system.

Modified: team/dlee/ari-async-bridge/include/asterisk/stasis_app_impl.h
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ari-async-bridge/include/asterisk/stasis_app_impl.h?view=diff&rev=395883&r1=395882&r2=395883
==============================================================================
--- team/dlee/ari-async-bridge/include/asterisk/stasis_app_impl.h (original)
+++ team/dlee/ari-async-bridge/include/asterisk/stasis_app_impl.h Wed Jul 31 10:38:56 2013
@@ -87,17 +87,6 @@
 
 /*!
  * \since 12
- * \brief Changes the bridge currently associated with a control object.
- *
- * \param control Control object for the channel to query.
- * \param bridge New bridge to set on the control object. Or \c NULL to clear
- *               the association.
- */
-void stasis_app_set_bridge(struct stasis_app_control *control,
-	struct ast_bridge *bridge);
-
-/*!
- * \since 12
  * \brief Gets the bridge currently associated with a control object.
  *
  * \param control Control object for the channel to query.
@@ -106,4 +95,17 @@
  */
 struct ast_bridge *stasis_app_get_bridge(struct stasis_app_control *control);
 
+
+/*!
+ * \since 12
+ * \brief Imparts the associated channel into the bridge.
+ *
+ * \param control Control object for the channel to query.
+ * \param bridge New bridge to set on the control object.
+ */
+void stasis_app_add_to_bridge(struct stasis_app_control *control,
+	struct ast_bridge *bridge);
+
+void stasis_app_remove_from_bridge(struct stasis_app_control *control);
+
 #endif /* _ASTERISK_RES_STASIS_H */

Modified: team/dlee/ari-async-bridge/res/res_stasis.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ari-async-bridge/res/res_stasis.c?view=diff&rev=395883&r1=395882&r2=395883
==============================================================================
--- team/dlee/ari-async-bridge/res/res_stasis.c (original)
+++ team/dlee/ari-async-bridge/res/res_stasis.c Wed Jul 31 10:38:56 2013
@@ -594,6 +594,13 @@
 		int r;
 		int command_count;
 
+		if (stasis_app_get_bridge(control)) {
+			/* Bridge is handling channel frames */
+			control_wait(control);
+			control_dispatch_all(control, chan);
+			continue;
+		}
+
 		r = ast_waitfor(chan, MAX_WAIT_MS);
 
 		if (r < 0) {
@@ -614,10 +621,6 @@
 			continue;
 		}
 
-		if (stasis_app_get_bridge(control)) {
-			/* Bridge is handling channel frames */
-			continue;
-		}
 
 		f = ast_read(chan);
 		if (!f) {

Modified: team/dlee/ari-async-bridge/res/res_stasis_bridge.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ari-async-bridge/res/res_stasis_bridge.c?view=diff&rev=395883&r1=395882&r2=395883
==============================================================================
--- team/dlee/ari-async-bridge/res/res_stasis_bridge.c (original)
+++ team/dlee/ari-async-bridge/res/res_stasis_bridge.c Wed Jul 31 10:38:56 2013
@@ -40,23 +40,12 @@
 	struct stasis_app_control *control,
 	struct ast_channel *chan, void *data)
 {
-	struct ast_bridge_features *features;
 	struct ast_bridge *bridge = data;
 
 	ast_debug(3, "%s: Adding to bridge\n",
 			stasis_app_control_get_channel_id(control));
 
-	features = ast_bridge_features_new();
-	if (!features) {
-		ast_log(LOG_ERROR,
-			"Failed to allocate bridge features; proceeding without.\n");
-	}
-
-	ast_bridge_impart(bridge,
-		chan,
-		NULL, /* swap channel */
-		features,
-		0); /* independent - false allows us to ast_bridge_depart() */
+	stasis_app_add_to_bridge(control, bridge);
 
 	return NULL;
 }
@@ -85,7 +74,8 @@
 		return NULL;
 	}
 
-	ast_bridge_depart(chan);
+	stasis_app_remove_from_bridge(control);
+
 	return NULL;
 }
 

Modified: team/dlee/ari-async-bridge/res/res_stasis_playback.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ari-async-bridge/res/res_stasis_playback.c?view=diff&rev=395883&r1=395882&r2=395883
==============================================================================
--- team/dlee/ari-async-bridge/res/res_stasis_playback.c (original)
+++ team/dlee/ari-async-bridge/res/res_stasis_playback.c Wed Jul 31 10:38:56 2013
@@ -34,6 +34,8 @@
 
 #include "asterisk/app.h"
 #include "asterisk/astobj2.h"
+#include "asterisk/bridge.h"
+#include "asterisk/bridge_internal.h"
 #include "asterisk/file.h"
 #include "asterisk/logger.h"
 #include "asterisk/module.h"
@@ -200,6 +202,7 @@
 	RAII_VAR(char *, file, NULL, ast_free);
 	int res;
 	long offsetms;
+	struct ast_bridge *bridge;
 
 	/* Even though these local variables look fairly pointless, the avoid
 	 * having a bunch of NULL's passed directly into
@@ -248,8 +251,19 @@
 		return NULL;
 	}
 
-	res = ast_control_streamfile_lang(chan, file, fwd, rev, stop, pause,
-		restart, playback->skipms, playback->language, &offsetms);
+	bridge = stasis_app_get_bridge(control);
+	if (bridge) {
+		struct ast_bridge_channel *bridge_chan;
+		ast_bridge_lock(bridge);
+		bridge_chan = bridge_find_channel(bridge, chan);
+		if (bridge_chan) {
+			res = ast_bridge_channel_queue_playfile(bridge_chan, NULL, file, NULL);
+		}
+		ast_bridge_unlock(bridge);
+	} else {
+		res = ast_control_streamfile_lang(chan, file, fwd, rev, stop, pause,
+			restart, playback->skipms, playback->language, &offsetms);
+	}
 
 	playback_final_update(playback, offsetms, res,
 		ast_channel_uniqueid(chan));

Modified: team/dlee/ari-async-bridge/res/stasis/control.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ari-async-bridge/res/stasis/control.c?view=diff&rev=395883&r1=395882&r2=395883
==============================================================================
--- team/dlee/ari-async-bridge/res/stasis/control.c (original)
+++ team/dlee/ari-async-bridge/res/stasis/control.c Wed Jul 31 10:38:56 2013
@@ -40,6 +40,7 @@
 #include "asterisk/musiconhold.h"
 
 struct stasis_app_control {
+	ast_cond_t wait_cond;
 	/*! Queue of commands to dispatch on the channel */
 	struct ao2_container *command_queue;
 	/*!
@@ -53,17 +54,37 @@
 	 */
 	struct ast_bridge *bridge;
 	/*!
+	 * Holding place for channel's PBX while imparted to a bridge.
+	 */
+	struct ast_pbx *pbx;
+	/*!
 	 * When set, /c app_stasis should exit and continue in the dialplan.
 	 */
 	int is_done:1;
 };
 
+static void control_dtor(void *obj)
+{
+	struct stasis_app_control *control = obj;
+
+	ao2_cleanup(control->command_queue);
+	ast_cond_destroy(&control->wait_cond);
+}
+
 struct stasis_app_control *control_create(struct ast_channel *channel)
 {
-	struct stasis_app_control *control;
-
-	control = ao2_alloc(sizeof(*control), NULL);
+	RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
+	int res;
+
+	control = ao2_alloc(sizeof(*control), control_dtor);
 	if (!control) {
+		return NULL;
+	}
+
+	res = ast_cond_init(&control->wait_cond, NULL);
+	if (res != 0) {
+		ast_log(LOG_ERROR, "Error initializing ast_cond_t: %s\n",
+			strerror(errno));
 		return NULL;
 	}
 
@@ -71,12 +92,12 @@
 		AO2_ALLOC_OPT_LOCK_MUTEX, 0, NULL, NULL);
 
 	if (!control->command_queue) {
-		ao2_cleanup(control);
 		return NULL;
 	}
 
 	control->channel = channel;
 
+	ao2_ref(control, +1);
 	return control;
 }
 
@@ -93,7 +114,10 @@
 	}
 
 	/* command_queue is a thread safe list; no lock needed */
-	ao2_link(control->command_queue, command);
+	ao2_lock(control->command_queue);
+	ao2_link_flags(control->command_queue, command, OBJ_NOLOCK);
+	ast_cond_signal(&control->wait_cond);
+	ao2_unlock(control->command_queue);
 
 	ao2_ref(command, +1);
 	return command;
@@ -421,21 +445,55 @@
 	return 0;
 }
 
-void stasis_app_set_bridge(struct stasis_app_control *control,
+struct ast_bridge *stasis_app_get_bridge(struct stasis_app_control *control)
+{
+	if (!control) {
+		return NULL;
+	}
+	return control->bridge;
+}
+
+void stasis_app_add_to_bridge(struct stasis_app_control *control,
 	struct ast_bridge *bridge)
+{
+	int res;
+
+	if (!control || !bridge) {
+		return;
+	}
+
+	/* Save off the channel's PBX */
+	ast_assert(!control->pbx || !ast_channel_pbx(control->channel));
+	if (!control->pbx) {
+		control->pbx = ast_channel_pbx(control->channel);
+		ast_channel_pbx_set(control->channel, NULL);
+	}
+
+	res = ast_bridge_impart(bridge,
+		control->channel,
+		NULL, /* swap channel */
+		NULL, /* features */
+		0); /* independent - false allows us to ast_bridge_depart() */
+
+	if (res != 0) {
+		ast_log(LOG_ERROR, "Error adding channel to bridge\n");
+		ast_channel_pbx_set(control->channel, control->pbx);
+		control->pbx = NULL;
+		return;
+	}
+
+	control->bridge = bridge;
+}
+
+void stasis_app_remove_from_bridge(struct stasis_app_control *control)
 {
 	if (!control) {
 		return;
 	}
-	control->bridge = bridge;
-}
-
-struct ast_bridge *stasis_app_get_bridge(struct stasis_app_control *control)
-{
-	if (!control) {
-		return NULL;
-	}
-	return control->bridge;
+
+	ast_bridge_depart(control->channel);
+	ast_channel_pbx_set(control->channel, control->pbx);
+	control->pbx = NULL;
 }
 
 const char *stasis_app_control_get_channel_id(
@@ -479,3 +537,24 @@
 	ao2_iterator_destroy(&i);
 	return count;
 }
+
+void control_wait(struct stasis_app_control *control)
+{
+	ast_mutex_t *queue_lock;
+	if (!control) {
+		return;
+	}
+
+	ast_assert(control->command_queue != NULL);
+
+	queue_lock = ao2_object_get_lockaddr(control->command_queue);
+	ao2_lock(control->command_queue);
+	while (ao2_container_count(control->command_queue) == 0) {
+		int r = ast_cond_wait(&control->wait_cond, queue_lock);
+		if (r < 0) {
+			ast_log(LOG_ERROR, "Error waiting on command queue\n");
+			break;
+		}
+	}
+	ao2_unlock(control->command_queue);
+}

Modified: team/dlee/ari-async-bridge/res/stasis/control.h
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ari-async-bridge/res/stasis/control.h?view=diff&rev=395883&r1=395882&r2=395883
==============================================================================
--- team/dlee/ari-async-bridge/res/stasis/control.h (original)
+++ team/dlee/ari-async-bridge/res/stasis/control.h Wed Jul 31 10:38:56 2013
@@ -48,6 +48,8 @@
 int control_dispatch_all(struct stasis_app_control *control,
 	struct ast_channel *chan);
 
+void control_wait(struct stasis_app_control *control);
+
 int control_is_done(struct stasis_app_control *control);
 
 void control_continue(struct stasis_app_control *control);




More information about the asterisk-commits mailing list