]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
ARI: Ensure managing application receives ChannelEnteredBridge messages
authorKinsey Moore <kmoore@digium.com>
Thu, 13 Mar 2014 19:33:22 +0000 (19:33 +0000)
committerKinsey Moore <kmoore@digium.com>
Thu, 13 Mar 2014 19:33:22 +0000 (19:33 +0000)
This fixes an issue where a Stasis application running over ARI and
subscribed to ari/events could miss the ChannelEnteredBridge event
because it did not subscribe to the new bridge fast enough.

To accomplish this, it subscribes the application controlling the
channel to the new bridge before adding it to that bridge which
required the stasis_app_control structure to maintain a reference to
the stasis_app.

(closes issue ASTERISK-23295)
Review: https://reviewboard.asterisk.org/r/3336/
........

Merged revisions 410527 from http://svn.asterisk.org/svn/asterisk/branches/12

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@410528 65c4cc65-6c06-0410-ace0-fbb531ad65f3

res/res_stasis.c
res/stasis/control.c
res/stasis/control.h

index 3a9297139a6abd5af1b4511e1285655c4b78c83e..e7a8d983a4cb7272ca96a77d67594075ccfeb192 100644 (file)
@@ -258,7 +258,7 @@ static void cleanup(void)
 
 struct stasis_app_control *stasis_app_control_create(struct ast_channel *chan)
 {
-       return control_create(chan);
+       return control_create(chan, NULL);
 }
 
 struct stasis_app_control *stasis_app_control_find_by_channel(
@@ -742,7 +742,7 @@ int stasis_app_exec(struct ast_channel *chan, const char *app_name, int argc,
                return -1;
        }
 
-       control = control_create(chan);
+       control = control_create(chan, app);
        if (!control) {
                ast_log(LOG_ERROR, "Allocated failed\n");
                return -1;
index d813a24434c68ec63767b9ac3f80e6e88818f5c4..d91a9f8d00476445d3f1873e44501e885a52e4e5 100644 (file)
@@ -31,6 +31,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 
 #include "command.h"
 #include "control.h"
+#include "app.h"
 #include "asterisk/dial.h"
 #include "asterisk/bridge.h"
 #include "asterisk/bridge_after.h"
@@ -72,6 +73,10 @@ struct stasis_app_control {
         * Silence generator, when silence is being generated.
         */
        struct ast_silence_generator *silgen;
+       /*!
+        * The app for which this control was created
+        */
+       struct stasis_app *app;
        /*!
         * When set, /c app_stasis should exit and continue in the dialplan.
         */
@@ -91,9 +96,10 @@ static void control_dtor(void *obj)
 
        ao2_cleanup(control->command_queue);
        ast_cond_destroy(&control->wait_cond);
+       ao2_cleanup(control->app);
 }
 
-struct stasis_app_control *control_create(struct ast_channel *channel)
+struct stasis_app_control *control_create(struct ast_channel *channel, struct stasis_app *app)
 {
        RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
        int res;
@@ -103,6 +109,8 @@ struct stasis_app_control *control_create(struct ast_channel *channel)
                return NULL;
        }
 
+       control->app = ao2_bump(app);
+
        res = ast_cond_init(&control->wait_cond, NULL);
        if (res != 0) {
                ast_log(LOG_ERROR, "Error initializing ast_cond_t: %s\n",
@@ -798,6 +806,8 @@ static void bridge_after_cb(struct ast_channel *chan, void *data)
        ast_channel_pbx_set(control->channel, control->pbx);
        control->pbx = NULL;
 
+       app_unsubscribe_bridge(control->app, control->bridge);
+
        /* No longer in the bridge */
        control->bridge = NULL;
 
@@ -865,6 +875,12 @@ static int app_control_add_channel_to_bridge(
                 */
                SCOPED_AO2LOCK(lock, control);
 
+               /* Ensure the controlling application is subscribed early enough
+                * to receive the ChannelEnteredBridge message. This works in concert
+                * with the subscription handled in the Stasis application execution
+                * loop */
+               app_subscribe_bridge(control->app, bridge);
+
                /* Save off the channel's PBX */
                ast_assert(control->pbx == NULL);
                if (!control->pbx) {
index 042fc67bb9a267309f2938c93b26eb29e8754f33..6b602e770e1849b42018315635dab9ccc5da5810 100644 (file)
  * \brief Create a control object.
  *
  * \param channel Channel to control.
+ * \param app stasis_app for which this control is being created.
+ *
  * \return New control object.
  * \return \c NULL on error.
  */
-struct stasis_app_control *control_create(struct ast_channel *channel);
+struct stasis_app_control *control_create(struct ast_channel *channel, struct stasis_app *app);
 
 /*!
  * \brief Dispatch all commands enqueued to this control.