[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