From 88d997913faabe81f8b9e7bdaa56742be0d669b9 Mon Sep 17 00:00:00 2001 From: Mark Michelson Date: Mon, 9 May 2016 14:48:51 -0500 Subject: ARI: Re-implement the ARI dial command, allowing for early bridging. ARI dial had been implemented using the Dial API. This made great sense when dialing was 100% separate from bridging. However, if a channel were to be added to a bridge during the dial attempt, there would be a conflict between the dialing thread and the bridging thread. Each would be attempting to read frames from the dialed channel and act on them. The initial attempt to make the two play nice was to have the Dial API suspend the channel in the bridge and stay in charge of the channel until the dial was complete. The problem with this was that it was riddled with potential race conditions. It also was not well-suited for the case where the channel changed which bridge it was in during the dial. This new approach removes the use of the Dial API altogether. Instead, the channel we are dialing is placed into an invisible ARI dialing bridge. The bridge channel thread handles incoming frames from the channel. If the channel is added to a real bridge, it is departed from the invisible bridge and then added to the real bridge. Similarly, if the channel is removed from the real bridge, it is automatically added back to the invisible bridge if the dial attempt is still active. This approach keeps the threading simple by always having the channel being handled by bridge channel threads. ASTERISK-25925 Change-Id: I7750359ddf45fcd45eaec749c5b3822de4a8ddbb --- include/asterisk/stasis_app.h | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) (limited to 'include/asterisk') diff --git a/include/asterisk/stasis_app.h b/include/asterisk/stasis_app.h index 0863f9f98..a73461547 100644 --- a/include/asterisk/stasis_app.h +++ b/include/asterisk/stasis_app.h @@ -672,6 +672,18 @@ int stasis_app_control_queue_control(struct stasis_app_control *control, */ struct ast_bridge *stasis_app_bridge_create(const char *type, const char *name, const char *id); +/*! + * \brief Create an invisible bridge of the specified type. + * + * \param type The type of bridge to be created + * \param name Optional name to give to the bridge + * \param id Optional Unique ID to give to the bridge + * + * \return New bridge. + * \return \c NULL on error. + */ +struct ast_bridge *stasis_app_bridge_create_invisible(const char *type, const char *name, const char *id); + /*! * \brief Returns the bridge with the given id. * \param bridge_id Uniqueid of the bridge. @@ -855,20 +867,23 @@ int stasis_app_channel_unreal_set_internal(struct ast_channel *chan); */ int stasis_app_channel_set_internal(struct ast_channel *chan); -struct ast_dial; - /*! * \brief Dial a channel * \param control Control for \c res_stasis. - * \param dial The ast_dial for the outbound channel + * \param dialstring The dialstring to pass to the channel driver + * \param timeout Optional timeout in milliseconds */ -int stasis_app_control_dial(struct stasis_app_control *control, struct ast_dial *dial); +int stasis_app_control_dial(struct stasis_app_control *control, + const char *dialstring, unsigned int timeout); /*! - * \brief Get dial structure on a control + * \brief Let Stasis app internals shut down + * + * This is called when res_stasis is unloaded. It ensures that + * the Stasis app internals can free any resources they may have + * allocated during the time that res_stasis was loaded. */ -struct ast_dial *stasis_app_get_dial(struct stasis_app_control *control); - +void stasis_app_control_shutdown(void); /*! @} */ #endif /* _ASTERISK_STASIS_APP_H */ -- cgit v1.2.3