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

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


Author: dlee
Date: Wed Jul 31 12:43:06 2013
New Revision: 395899

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=395899
Log:
Playback controls work while in an async bridge

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

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=395899&r1=395898&r2=395899
==============================================================================
--- 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 12:43:06 2013
@@ -106,6 +106,12 @@
 void stasis_app_add_to_bridge(struct stasis_app_control *control,
 	struct ast_bridge *bridge);
 
+/*!
+ * \since 12
+ * \brief Departs the associated channel from its bridge.
+ *
+ * \param control Control object for the channel to query.
+ */
 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_playback.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ari-async-bridge/res/res_stasis_playback.c?view=diff&rev=395899&r1=395898&r2=395899
==============================================================================
--- team/dlee/ari-async-bridge/res/res_stasis_playback.c (original)
+++ team/dlee/ari-async-bridge/res/res_stasis_playback.c Wed Jul 31 12:43:06 2013
@@ -75,6 +75,10 @@
 	/*! Number of milliseconds to skip for forward/reverse operations */
 	int skipms;
 
+	/*! Set when playback has been completed */
+	int done;
+	/*! Condition for waiting on done to be set */
+	ast_cond_t done_cond;
 	/*! Number of milliseconds of media that has been played */
 	long playedms;
 	/*! Current playback state */
@@ -193,16 +197,22 @@
 	playback_publish(playback);
 }
 
-static void *play_uri(struct stasis_app_control *control,
-	struct ast_channel *chan, void *data)
-{
-	RAII_VAR(struct stasis_app_playback *, playback, NULL,
-		playback_cleanup);
+static void mark_as_done(struct stasis_app_playback *playback)
+{
+	SCOPED_AO2LOCK(lock, playback);
+	playback->done = 1;
+	ast_cond_broadcast(&playback->done_cond);
+}
+
+static void play_on_channel(struct stasis_app_playback *playback,
+	struct ast_channel *chan)
+{
+	RAII_VAR(struct stasis_app_playback *, mark_when_done, playback,
+		mark_as_done);
 	RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
 	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
@@ -213,7 +223,6 @@
 	const char *pause = NULL;
 	const char *restart = NULL;
 
-	playback = data;
 	ast_assert(playback != NULL);
 
 	offsetms = playback->offsetms;
@@ -221,7 +230,7 @@
 	res = playback_first_update(playback, ast_channel_uniqueid(chan));
 
 	if (res != 0) {
-		return NULL;
+		return;
 	}
 
 	if (ast_channel_state(chan) != AST_STATE_UP) {
@@ -244,10 +253,48 @@
 	} else {
 		/* Play URL */
 		ast_log(LOG_ERROR, "Unimplemented\n");
-		return NULL;
+		return;
 	}
 
 	if (!file) {
+		return;
+	}
+
+	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));
+
+	return;
+}
+
+static void play_on_channel_in_bridge(struct ast_bridge_channel *bridge_channel,
+	const char *playback_id)
+{
+	RAII_VAR(struct stasis_app_playback *, playback, NULL, ao2_cleanup);
+
+	playback = stasis_app_playback_find_by_id(playback_id);
+	if (!playback) {
+		ast_log(LOG_ERROR, "Couldn't find playback %s\n",
+			playback_id);
+		return;
+	}
+
+	play_on_channel(playback, bridge_channel->chan);
+}
+
+static void *play_uri(struct stasis_app_control *control,
+	struct ast_channel *chan, void *data)
+{
+	RAII_VAR(struct stasis_app_playback *, playback, NULL,
+		playback_cleanup);
+	struct ast_bridge *bridge;
+	int res;
+
+	playback = data;
+
+	if (!control) {
 		return NULL;
 	}
 
@@ -257,16 +304,28 @@
 		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_channel_queue_playfile(
+				bridge_chan,
+				play_on_channel_in_bridge,
+				playback->id,
+				NULL); /* moh_class */
 		}
 		ast_bridge_unlock(bridge);
+
+		ao2_lock(playback);
+		while (!playback->done) {
+			res = ast_cond_wait(&playback->done_cond,
+				ao2_object_get_lockaddr(playback));
+			if (res != 0) {
+				ast_log(LOG_ERROR,
+					"Error waiting for playback to complete: %s\n",
+					strerror(errno));
+			}
+		}
+		ao2_unlock(playback);
 	} 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));
+		play_on_channel(playback, chan);
+	}
 
 	return NULL;
 }
@@ -306,6 +365,7 @@
 {
 	RAII_VAR(struct stasis_app_playback *, playback, NULL, ao2_cleanup);
 	char id[AST_UUID_STR_LEN];
+	int res;
 
 	if (skipms < 0 || offsetms < 0) {
 		return NULL;
@@ -316,6 +376,13 @@
 
 	playback = ao2_alloc(sizeof(*playback), playback_dtor);
 	if (!playback || ast_string_field_init(playback, 128)) {
+		return NULL;
+	}
+
+	res = ast_cond_init(&playback->done_cond, NULL);
+	if (res != 0) {
+		ast_log(LOG_ERROR, "Error creating done condition: %s\n",
+			strerror(errno));
 		return NULL;
 	}
 
@@ -360,15 +427,7 @@
 
 struct stasis_app_playback *stasis_app_playback_find_by_id(const char *id)
 {
-	RAII_VAR(struct stasis_app_playback *, playback, NULL, ao2_cleanup);
-
-	playback = ao2_find(playbacks, id, OBJ_KEY);
-	if (playback == NULL) {
-		return NULL;
-	}
-
-	ao2_ref(playback, +1);
-	return playback;
+	return ao2_find(playbacks, id, OBJ_KEY);
 }
 
 struct ast_json *stasis_app_playback_to_json(

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=395899&r1=395898&r2=395899
==============================================================================
--- team/dlee/ari-async-bridge/res/stasis/control.c (original)
+++ team/dlee/ari-async-bridge/res/stasis/control.c Wed Jul 31 12:43:06 2013
@@ -547,7 +547,8 @@
 
 void stasis_app_remove_from_bridge(struct stasis_app_control *control)
 {
-	if (!control) {
+	/* We should only depart from our own bridge */
+	if (!control || !control->bridge) {
 		return;
 	}
 




More information about the asterisk-commits mailing list