From a5bbc790e7ee1417bc03f5c529a73f2604a58cdb Mon Sep 17 00:00:00 2001 From: Kinsey Moore Date: Mon, 10 Jun 2013 13:07:11 +0000 Subject: Stasis-HTTP: Flesh out bridge-related capabilities This adds support for Stasis applications to receive bridge-related messages when the application shows interest in a given bridge. To supplement this work and test it, this also adds support for the following bridge-related Stasis-HTTP functionality: * GET stasis/bridges * GET stasis/bridges/{bridgeId} * POST stasis/bridges * DELETE stasis/bridges/{bridgeId} * POST stasis/bridges/{bridgeId}/addChannel * POST stasis/bridges/{bridgeId}/removeChannel Review: https://reviewboard.asterisk.org/r/2572/ (closes issue ASTERISK-21711) (closes issue ASTERISK-21621) (closes issue ASTERISK-21622) (closes issue ASTERISK-21623) (closes issue ASTERISK-21624) (closes issue ASTERISK-21625) (closes issue ASTERISK-21626) git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@391199 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- res/stasis/app.c | 38 ++++++++++++++++++++++++++++++++++++++ res/stasis/app.h | 28 ++++++++++++++++++++++++++++ res/stasis/control.c | 9 +++++++++ 3 files changed, 75 insertions(+) (limited to 'res/stasis') diff --git a/res/stasis/app.c b/res/stasis/app.c index 229f4bb20..31e15c221 100644 --- a/res/stasis/app.c +++ b/res/stasis/app.c @@ -38,6 +38,12 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") */ #define APP_CHANNELS_BUCKETS 7 +/*! + * \brief Number of buckets for the bridges container for app instances. Remember + * to keep it a prime number! + */ +#define APP_BRIDGES_BUCKETS 7 + struct app { /*! Callback function for this application. */ stasis_app_cb handler; @@ -45,6 +51,8 @@ struct app { void *data; /*! List of channel identifiers this app instance is interested in */ struct ao2_container *channels; + /*! List of bridge identifiers this app instance owns */ + struct ao2_container *bridges; /*! Name of the Stasis application */ char name[]; }; @@ -57,6 +65,8 @@ static void app_dtor(void *obj) app->data = NULL; ao2_cleanup(app->channels); app->channels = NULL; + ao2_cleanup(app->bridges); + app->bridges = NULL; } struct app *app_create(const char *name, stasis_app_cb handler, void *data) @@ -84,6 +94,11 @@ struct app *app_create(const char *name, stasis_app_cb handler, void *data) return NULL; } + app->bridges = ast_str_container_alloc(APP_BRIDGES_BUCKETS); + if (!app->bridges) { + return NULL; + } + ao2_ref(app, +1); return app; } @@ -106,6 +121,22 @@ void app_remove_channel(struct app* app, const struct ast_channel *chan) ao2_find(app->channels, ast_channel_uniqueid(chan), OBJ_KEY | OBJ_NODATA | OBJ_UNLINK); } +int app_add_bridge(struct app *app, const char *uniqueid) +{ + ast_assert(uniqueid != NULL); + ast_assert(app != NULL); + + return ast_str_container_add(app->bridges, uniqueid) ? -1 : 0; +} + +void app_remove_bridge(struct app* app, const char *uniqueid) +{ + ast_assert(uniqueid != NULL); + ast_assert(app != NULL); + + ao2_find(app->bridges, uniqueid, OBJ_KEY | OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE); +} + /*! * \brief Send a message to the given application. * \param app App to send the message to. @@ -137,3 +168,10 @@ int app_is_watching_channel(struct app *app, const char *uniqueid) found = ao2_find(app->channels, uniqueid, OBJ_KEY); return found != NULL; } + +int app_is_watching_bridge(struct app *app, const char *uniqueid) +{ + RAII_VAR(char *, found, NULL, ao2_cleanup); + found = ao2_find(app->bridges, uniqueid, OBJ_KEY); + return found != NULL; +} diff --git a/res/stasis/app.h b/res/stasis/app.h index c9e63502d..7a5405a89 100644 --- a/res/stasis/app.h +++ b/res/stasis/app.h @@ -135,4 +135,32 @@ int app_add_channel(struct app *app, const struct ast_channel *chan); */ void app_remove_channel(struct app *app, const struct ast_channel *chan); +/*! + * \brief Add a bridge to an application's watch list by uniqueid. + * + * \param app Application. + * \param bridge Bridge to watch. + * \return 0 on success. + * \return Non-zero on error. + */ +int app_add_bridge(struct app *app, const char *uniqueid); + +/*! + * \brief Remove a bridge from an application's watch list by uniqueid. + * + * \param app Application. + * \param bridge Bridge to remove. + */ +void app_remove_bridge(struct app* app, const char *uniqueid); + +/*! + * \brief Checks if an application is watching a given bridge. + * + * \param app Application. + * \param uniqueid Uniqueid of the bridge to check. + * \return True (non-zero) if \a app is watching bridge with given \a uniqueid + * \return False (zero) if \a app isn't. + */ +int app_is_watching_bridge(struct app *app, const char *uniqueid); + #endif /* _ASTERISK_RES_STASIS_APP_H */ diff --git a/res/stasis/control.c b/res/stasis/control.c index 1663dd8a6..06f36728f 100644 --- a/res/stasis/control.c +++ b/res/stasis/control.c @@ -31,6 +31,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "command.h" #include "control.h" +#include "asterisk/bridging.h" +#include "asterisk/bridging_features.h" struct stasis_app_control { /*! Queue of commands to dispatch on the channel */ @@ -200,3 +202,10 @@ int control_dispatch_all(struct stasis_app_control *control, ao2_iterator_destroy(&i); return count; } + +/* Must be defined here since it must operate on the channel outside of the queue */ +int stasis_app_control_remove_channel_from_bridge( + struct stasis_app_control *control, struct ast_bridge *bridge) +{ + return ast_bridge_remove(bridge, control->channel); +} -- cgit v1.2.3