[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