From 26a04477f4eee1d8a15c9fd29da4b2b2e6a7b58f Mon Sep 17 00:00:00 2001 From: Ben Ford <bford@digium.com> Date: Tue, 29 Jan 2019 10:48:49 -0600 Subject: [PATCH] res_stasis: Auto-create context and extens on Stasis app launch. At AstriCon, there was a strong desire for the ability to completely bypass dialplan when using ARI. This is possible through the automatic creation of a context and a couple of extensions whenever an application is started. For example, if you have an application named 'ari-example', a context named 'stasis-ari-example' will be automatically created whenever this application is started as long as one does not already exist. Two extensions (a match-all extension for Stasis and a 'h' extension) are created within this context. Any endpoint that registers to Asterisk within this context will send all calls to the corresponding Stasis application. When the application is destroyed, the context is removed. ASTERISK-28104 #close Change-Id: Ie35bd93075e05b05e3ae129a83c9426931b7ebac --- CHANGES | 8 ++++++++ res/stasis/app.c | 25 +++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/CHANGES b/CHANGES index da58f2995a..1c79b81a35 100644 --- a/CHANGES +++ b/CHANGES @@ -12,6 +12,14 @@ --- Functionality changes from Asterisk 13.24.0 to Asterisk 13.25.0 ---------- ------------------------------------------------------------------------------ +ARI +------------------ + * Whenever an ARI application is started, a context will be created for it + automatically as long as one does not already exist, following the format + 'stasis-<app_name>'. Two extensions are also added to this context: a match-all + extension, and the 'h' extension. Any phone that registers under this context + will place all calls to the corresponding Stasis application. + res_pjsip ------------------ * Added "send_contact_status_on_update_registration" global configuration option diff --git a/res/stasis/app.c b/res/stasis/app.c index ccb93bc4dd..887e8f1c60 100644 --- a/res/stasis/app.c +++ b/res/stasis/app.c @@ -299,6 +299,8 @@ static int forwards_sort(const void *obj_left, const void *obj_right, int flags) static void app_dtor(void *obj) { struct stasis_app *app = obj; + size_t size = strlen("stasis-") + strlen(app->name) + 1; + char context_name[size]; ast_verb(1, "Destroying Stasis app %s\n", app->name); @@ -306,6 +308,11 @@ static void app_dtor(void *obj) ast_assert(app->bridge_router == NULL); ast_assert(app->endpoint_router == NULL); + /* If we created a context for this application, remove it */ + strcpy(context_name, "stasis-"); + strcat(context_name, app->name); + ast_context_destroy_by_name(context_name, "res_stasis"); + ao2_cleanup(app->topic); app->topic = NULL; ao2_cleanup(app->forwards); @@ -934,6 +941,8 @@ struct stasis_app *app_create(const char *name, stasis_app_cb handler, void *dat RAII_VAR(struct stasis_app *, app, NULL, ao2_cleanup); size_t size; int res = 0; + size_t context_size = strlen("stasis-") + strlen(name) + 1; + char context_name[context_size]; ast_assert(name != NULL); ast_assert(handler != NULL); @@ -1009,6 +1018,22 @@ struct stasis_app *app_create(const char *name, stasis_app_cb handler, void *dat app->handler = handler; app->data = ao2_bump(data); + /* Create a context, a match-all extension, and a 'h' extension for this application. Note that + * this should only be done if a context does not already exist. */ + strcpy(context_name, "stasis-"); + strcat(context_name, name); + if (!ast_context_find(context_name)) { + if (!ast_context_find_or_create(NULL, NULL, context_name, "res_stasis")) { + ast_log(LOG_WARNING, "Could not create context '%s' for Stasis application '%s'\n", context_name, name); + } else { + ast_add_extension(context_name, 0, "_.", 1, NULL, NULL, "Stasis", ast_strdup(name), ast_free_ptr, "res_stasis"); + ast_add_extension(context_name, 0, "h", 1, NULL, NULL, "NoOp", NULL, NULL, "res_stasis"); + } + } else { + ast_log(LOG_WARNING, "Not creating context '%s' for Stasis application '%s' because it already exists\n", + context_name, name); + } + ao2_ref(app, +1); return app; } -- GitLab