diff --git a/res/res_stasis.c b/res/res_stasis.c index 3a9297139a..e7a8d983a4 100644 --- a/res/res_stasis.c +++ b/res/res_stasis.c @@ -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; diff --git a/res/stasis/control.c b/res/stasis/control.c index d813a24434..d91a9f8d00 100644 --- a/res/stasis/control.c +++ b/res/stasis/control.c @@ -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) { diff --git a/res/stasis/control.h b/res/stasis/control.h index 042fc67bb9..6b602e770e 100644 --- a/res/stasis/control.h +++ b/res/stasis/control.h @@ -33,10 +33,12 @@ * \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.