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;
        }
 


--
_____________________________________________________________________
-- Bandwidth and Colocation Provided by http://www.api-digital.com --

svn-commits mailing list
To UNSUBSCRIBE or update options visit:
   http://lists.digium.com/mailman/listinfo/svn-commits

Reply via email to