[asterisk-commits] dlee: branch dlee/stasis-http r380675 - in /team/dlee/stasis-http: include/as...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Thu Jan 31 13:08:38 CST 2013
Author: dlee
Date: Thu Jan 31 13:08:35 2013
New Revision: 380675
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=380675
Log:
Apps can register, and receive notifications if they've been replaced
Modified:
team/dlee/stasis-http/include/asterisk/stasis.h
team/dlee/stasis-http/res/res_stasis_core.c
team/dlee/stasis-http/res/res_stasis_http.c
team/dlee/stasis-http/tests/test_stasis_core.c
Modified: team/dlee/stasis-http/include/asterisk/stasis.h
URL: http://svnview.digium.com/svn/asterisk/team/dlee/stasis-http/include/asterisk/stasis.h?view=diff&rev=380675&r1=380674&r2=380675
==============================================================================
--- team/dlee/stasis-http/include/asterisk/stasis.h (original)
+++ team/dlee/stasis-http/include/asterisk/stasis.h Thu Jan 31 13:08:35 2013
@@ -48,7 +48,7 @@
* \param data Data ptr given when registered
* \param message Message to handle. (borrowed copy)
*/
-typedef void (*stasis_app_handler)(void *data, struct ast_json *message);
+typedef void (*stasis_app_handler)(void *data, const char *app_name, struct ast_json *message);
/*!
* \brief Register a new Stasis application.
Modified: team/dlee/stasis-http/res/res_stasis_core.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/stasis-http/res/res_stasis_core.c?view=diff&rev=380675&r1=380674&r2=380675
==============================================================================
--- team/dlee/stasis-http/res/res_stasis_core.c (original)
+++ team/dlee/stasis-http/res/res_stasis_core.c Thu Jan 31 13:08:35 2013
@@ -120,7 +120,7 @@
ast_json_array_append(json_args, ast_json_string_create(argv[i]));
}
- app->handler(app->data, msg);
+ app->handler(app->data, app_name, msg);
return 0;
}
@@ -136,8 +136,8 @@
if (app) {
RAII_VAR(struct ast_json *, msg, NULL, ast_json_unref);
- msg = ast_json_pack("{s: s}", "event", "replaced");
- app->handler(app->data, msg);
+ msg = ast_json_pack("{s: s}", "event", "application-replaced");
+ app->handler(app->data, app_name, msg);
} else {
app = ao2_alloc(sizeof(*app), app_dtor);
app->name = ast_strdup(app_name);
Modified: team/dlee/stasis-http/res/res_stasis_http.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/stasis-http/res/res_stasis_http.c?view=diff&rev=380675&r1=380674&r2=380675
==============================================================================
--- team/dlee/stasis-http/res/res_stasis_http.c (original)
+++ team/dlee/stasis-http/res/res_stasis_http.c Thu Jan 31 13:08:35 2013
@@ -34,11 +34,14 @@
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
-#include "asterisk/module.h"
+#include "asterisk/astobj2.h"
+#include "asterisk/hashtab.h"
#include "asterisk/http.h"
#include "asterisk/http_websocket.h"
#include "asterisk/json.h"
+#include "asterisk/module.h"
#include "asterisk/paths.h"
+#include "asterisk/stasis.h"
#include "asterisk/stasis_http.h"
#include <string.h>
@@ -362,7 +365,75 @@
return err;
}
-static struct ast_json *stasis_websocket_process_req(struct ast_json *req)
+static struct ast_json *build_success(int id, const char *msg_format, ...) __attribute__((format(printf, 2, 3)));
+struct ast_json *build_success(int id, const char *msg_format, ...)
+{
+ va_list args;
+ struct ast_json *err;
+
+ va_start(args, msg_format);
+ err = ast_json_pack("{ s: o, s: i }",
+ "success", ast_json_vstringf(msg_format, args),
+ "id", id);
+ va_end(args);
+
+ return err;
+}
+
+/*! Number of buckets for the Stasis application hash table. Remember to keep it a prime number! */
+#define APPS_NUM_BUCKETS 7
+
+struct stasis_app {
+ char *name;
+};
+
+/*! Hash function for stasis_app */
+static int hash_app(const void *obj, const int flags)
+{
+ const struct stasis_app *app = obj;
+ const char *name = flags & OBJ_KEY ? obj : app->name;
+
+ return ast_hashtab_hash_string(name);
+}
+
+/*! Comparison function for stasis_app */
+static int compare_app(void *lhs, void *rhs, int flags)
+{
+ const struct stasis_app *lhs_app = lhs;
+ const struct stasis_app *rhs_app = rhs;
+ const char *rhs_name = flags & OBJ_KEY ? rhs : rhs_app->name;
+
+ if (strcmp(lhs_app->name, rhs_name) == 0) {
+ return CMP_MATCH | CMP_STOP;
+ } else {
+ return 0;
+ }
+}
+
+static void app_dtor(void *obj)
+{
+ struct stasis_app *app = obj;
+ ast_free(app->name);
+}
+
+struct stasis_ws_session_info {
+ struct ast_websocket *ws_session;
+ struct ao2_container *stasis_apps;
+};
+
+static void app_handler(void *data, const char *app_name, struct ast_json *message)
+{
+ struct stasis_ws_session_info *session = data;
+ int res;
+
+ res = ast_json_object_set(message, "application", ast_json_string_create(app_name));
+ ast_assert(res == 0);
+
+ ast_websocket_write_json(session->ws_session, message);
+}
+
+
+static struct ast_json *stasis_websocket_process_req(struct stasis_ws_session_info *session, struct ast_json *req)
{
const char *command = ast_json_string_get(ast_json_object_get(req, "command"));
struct ast_json *id_json = ast_json_object_get(req, "id");
@@ -383,16 +454,41 @@
if (strcmp("ActivateApplication", command) == 0) {
const char *app_name = ast_json_string_get(ast_json_object_get(req, "name"));
+ RAII_VAR(struct stasis_app *, app, NULL, ao2_cleanup);
if (ast_strlen_zero(app_name)) {
return build_err(id, "Missing application name");
}
- return build_err(id, "TODO");
+
+ app = ao2_find(session->stasis_apps, app_name, OBJ_KEY);
+ if (app) {
+ return build_err(id, "Application '%s' already registered", app_name);
+ }
+
+ app = ao2_alloc(sizeof(*app), app_dtor);
+ if (!app) {
+ ast_log(LOG_ERROR, "Failed to construct stasis_app");
+ return build_err(id, "Internal error");
+ }
+ app->name = ast_strdup(app_name);
+ ao2_link(session->stasis_apps, app);
+
+ stasis_app_register(app_name, app_handler, session);
+
+ return build_success(id, "Application activated");
} else if (strcmp("DeactivateApplication", command) == 0) {
const char *app_name = ast_json_string_get(ast_json_object_get(req, "name"));
+ RAII_VAR(struct stasis_app *, app, NULL, ao2_cleanup);
if (ast_strlen_zero(app_name)) {
return build_err(id, "Missing application name");
}
- return build_err(id, "TODO");
+ app = ao2_find(session->stasis_apps, app_name, OBJ_KEY | OBJ_UNLINK);
+ if (app == NULL) {
+ return build_err(id, "Application '%s' not activated", app_name);
+ }
+
+ stasis_app_unregister(app_name);
+
+ return build_success(id, "Application deactivated");
} else {
return build_err(id, "Unrecognized command: %s", command);
}
@@ -407,6 +503,9 @@
*/
static void stasis_websocket_callback(struct ast_websocket *session, struct ast_variable *parameters, struct ast_variable *headers)
{
+ struct stasis_ws_session_info stasis_session = {};
+ struct ao2_iterator i;
+ struct stasis_app *app;
int res;
ast_debug(3, "Stasis web socket connection\n");
@@ -415,6 +514,9 @@
ast_log(LOG_ERROR, "Stasis web socket failed to set nonblock; closing\n");
goto end;
}
+
+ stasis_session.stasis_apps = ao2_container_alloc(APPS_NUM_BUCKETS, hash_app, compare_app);
+ stasis_session.ws_session = session;
while ((res = ast_wait_for_input(ast_websocket_fd(session), -1)) > 0) {
char *payload;
@@ -447,7 +549,7 @@
ast_log(LOG_ERROR, "Error building error message. That's just messed up.\n");
}
} else {
- resp = stasis_websocket_process_req(req);
+ resp = stasis_websocket_process_req(&stasis_session, req);
}
if (resp) {
@@ -459,6 +561,12 @@
}
end:
+ i = ao2_iterator_init(stasis_session.stasis_apps, 0);
+ while ((app = ao2_iterator_next(&i))) {
+ stasis_app_unregister(app->name);
+ }
+ ao2_cleanup(stasis_session.stasis_apps);
+
ast_websocket_unref(session);
}
Modified: team/dlee/stasis-http/tests/test_stasis_core.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/stasis-http/tests/test_stasis_core.c?view=diff&rev=380675&r1=380674&r2=380675
==============================================================================
--- team/dlee/stasis-http/tests/test_stasis_core.c (original)
+++ team/dlee/stasis-http/tests/test_stasis_core.c Thu Jan 31 13:08:35 2013
@@ -79,7 +79,7 @@
}
}
-static void test_handler(void *data, struct ast_json *message)
+static void test_handler(void *data, const char *app_name, struct ast_json *message)
{
struct app_data *actual = data;
int res;
More information about the asterisk-commits
mailing list