[asterisk-commits] dlee: branch dlee/stasis-http r380571 - in /team/dlee/stasis-http: include/as...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Jan 30 14:57:10 CST 2013
Author: dlee
Date: Wed Jan 30 14:57:06 2013
New Revision: 380571
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=380571
Log:
The makings of an app
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/res/stasis_http_channels.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=380571&r1=380570&r2=380571
==============================================================================
--- team/dlee/stasis-http/include/asterisk/stasis.h (original)
+++ team/dlee/stasis-http/include/asterisk/stasis.h Wed Jan 30 14:57:06 2013
@@ -19,6 +19,8 @@
#ifndef _ASTERISK_STASIS_H
#define _ASTERISK_STASIS_H
+#include "asterisk/json.h"
+
/*! \file
*
* \brief Stasis message bus.
@@ -36,4 +38,8 @@
*/
int stasis_app_invoke(const char *app_name, struct ast_channel *chan, int argc, char *argv[]);
+typedef void (*stasis_app_handler)(void *data, struct ast_json *message);
+
+int stasis_app_register(const char *app_name, stasis_app_handler handler, void *data);
+
#endif /* _ASTERISK_STASIS_H */
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=380571&r1=380570&r2=380571
==============================================================================
--- team/dlee/stasis-http/res/res_stasis_core.c (original)
+++ team/dlee/stasis-http/res/res_stasis_core.c Wed Jan 30 14:57:06 2013
@@ -32,7 +32,9 @@
ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/astobj2.h"
+#include "asterisk/channel.h"
#include "asterisk/hashtab.h"
+#include "asterisk/logger.h"
#include "asterisk/module.h"
#include "asterisk/stasis.h"
#include "asterisk/utils.h"
@@ -43,6 +45,8 @@
/*! Stasis application ref */
struct stasis_app {
const char *name;
+ stasis_app_handler handler;
+ void *data;
};
/*! Stasis application container */
@@ -52,7 +56,9 @@
static int hash_app(const void *obj, const int flags)
{
const struct stasis_app *app = obj;
- return ast_hashtab_hash_string(app->name);
+ const char *name = flags & OBJ_KEY ? obj : app->name;
+
+ return ast_hashtab_hash_string(name);
}
/*! Comparison function for stasis_app */
@@ -60,26 +66,81 @@
{
const struct stasis_app *lhs_app = lhs;
const struct stasis_app *rhs_app = rhs;
- if (strcmp(lhs_app->name, rhs_app->name) == 0) {
+ 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 *app)
+{
+ /* No-op */
+}
+
int stasis_app_invoke(const char *app_name, struct ast_channel *chan, int argc, char *argv[])
{
- struct stasis_app needle = {.name = app_name};
- struct stasis_app *app = ao2_find(stasis_apps, &needle, OBJ_POINTER);
+ RAII_VAR(struct ao2_container *, apps, stasis_apps, ao2_cleanup);
+ RAII_VAR(struct stasis_app *, app, NULL, ao2_cleanup);
+ RAII_VAR(struct ast_json *, msg, NULL, ast_json_unref);
+ struct ast_json *json_args;
+ int i;
+
+ ao2_ref(apps, 1);
+ app = ao2_find(apps, app_name, OBJ_KEY);
if (!app) {
ast_log(LOG_WARNING, "Stasis app '%s' not registered\n", app_name);
return -1;
}
- ast_log(LOG_WARNING, "TODO: unimplemented\n");
- ao2_ref(app, -1);
- return -1;
+ msg = ast_json_pack("{s: s, s: s, s: []}",
+ "command", "invoke",
+ "channel", ast_channel_name(chan),
+ "args");
+ if (!msg) {
+ ast_log(LOG_ERROR, "Couldn't create message for %s\n", app_name);
+ return -1;
+ }
+ json_args = ast_json_object_get(msg, "args");
+ ast_assert(json_args != NULL);
+ for (i = 0; i < argc; ++i) {
+ ast_json_array_append(json_args, ast_json_string_create(argv[i]));
+ }
+
+ app->handler(app->data, msg);
+
+ return 0;
+}
+
+int stasis_app_register(const char *app_name, stasis_app_handler handler, void *data)
+{
+ RAII_VAR(struct ao2_container *, apps, stasis_apps, ao2_cleanup);
+
+ ao2_ref(apps, 1);
+ {
+ RAII_VAR(struct stasis_app *, app, ao2_find(apps, app_name, OBJ_KEY | OBJ_NOLOCK), ao2_cleanup);
+ SCOPED_LOCK(apps_lock, apps, ao2_lock, ao2_unlock);
+
+ 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);
+ } else {
+ app = ao2_alloc(sizeof(*app), app_dtor);
+ }
+
+ if (!app) {
+ ast_log(LOG_ERROR, "Failed to allocate stasis_app\n");
+ return -1;
+ }
+
+ app->handler = handler;
+ app->data = data;
+ }
+ return 0;
}
static int load_module(void)
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=380571&r1=380570&r2=380571
==============================================================================
--- team/dlee/stasis-http/res/res_stasis_http.c (original)
+++ team/dlee/stasis-http/res/res_stasis_http.c Wed Jan 30 14:57:06 2013
@@ -334,7 +334,8 @@
* \return 0 on success.
* \return -1 on error.
*/
-static int ast_websocket_write_json(struct ast_websocket *session, struct ast_json *message) {
+static int ast_websocket_write_json(struct ast_websocket *session, struct ast_json *message)
+{
RAII_VAR(char *, str, ast_json_dump_string(message), ast_free);
if (str == NULL) {
@@ -343,6 +344,58 @@
}
return ast_websocket_write(session, AST_WEBSOCKET_OPCODE_TEXT, str, strlen(str));
+}
+
+static struct ast_json *build_err(int id, const char *msg_format, ...) __attribute__((format(printf, 2, 3)));
+struct ast_json *build_err(int id, const char *msg_format, ...)
+{
+ va_list args;
+ struct ast_json *err;
+
+ va_start(args, msg_format);
+ err = ast_json_pack("{ s: { s: o }, s: i }",
+ "error",
+ "message", ast_json_vstringf(msg_format, args),
+ "id", id);
+ va_end(args);
+
+ return err;
+}
+
+static struct ast_json *stasis_websocket_process_req(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");
+ intmax_t id;
+
+ if (!id_json || ast_json_typeof(id_json) != AST_JSON_INTEGER) {
+ return ast_json_pack("{ s: { s: s, s: o }}",
+ "error",
+ "message", "Integer id field required",
+ "request", req);
+ }
+
+ id = ast_json_integer_get(id_json);
+
+ if (ast_strlen_zero(command)) {
+ return build_err(id, "Missing command");
+ }
+
+ if (strcmp("ActivateApplication", command) == 0) {
+ const char *app_name = ast_json_string_get(ast_json_object_get(req, "name"));
+ if (ast_strlen_zero(app_name)) {
+ return build_err(id, "Missing application name");
+ }
+ return build_err(id, "TODO");
+ } else if (strcmp("DeactivateApplication", command) == 0) {
+ const char *app_name = ast_json_string_get(ast_json_object_get(req, "name"));
+ if (ast_strlen_zero(app_name)) {
+ return build_err(id, "Missing application name");
+ }
+ return build_err(id, "TODO");
+ } else {
+ return build_err(id, "Unrecognized command: %s", command);
+ }
}
/*!
@@ -376,25 +429,29 @@
if (opcode == AST_WEBSOCKET_OPCODE_TEXT) {
RAII_VAR(struct ast_json *, req, NULL, ast_json_unref);
+ RAII_VAR(struct ast_json *, resp, NULL, ast_json_unref);
struct ast_json_error err = {};
req = ast_json_load_buf(payload, payload_len, &err);
if (req == NULL) {
/* Parse error */
- RAII_VAR(struct ast_json *, resp, NULL, ast_json_unref);
- resp = ast_json_pack("{ s: o, s: i, s: i, s: s }",
- "error", ast_json_stringf("Error parsing message: %s", err.text),
+ resp = ast_json_pack("{ s: { s: o, s: i, s: i, s: o } }",
+ "error",
+ "message", ast_json_stringf("Error parsing message: %s", err.text),
"line", err.line,
"column", err.column,
- "message", err.text);
- if (resp) {
- ast_websocket_write_json(session, resp);
- } else {
- ast_log(LOG_ERROR, "Error sending error message. That's just messed up.\n");
+ "request", ast_json_stringf("%.*s", (int)payload_len, payload));
+ if (!resp) {
+ ast_log(LOG_ERROR, "Error building error message. That's just messed up.\n");
}
+ } else {
+ resp = stasis_websocket_process_req(req);
}
- ast_log(LOG_ERROR, "TODO\n");
+
+ if (resp) {
+ ast_websocket_write_json(session, resp);
+ }
ast_json_unref(req);
} else if (opcode == AST_WEBSOCKET_OPCODE_CLOSE) {
break;
Modified: team/dlee/stasis-http/res/stasis_http_channels.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/stasis-http/res/stasis_http_channels.c?view=diff&rev=380571&r1=380570&r2=380571
==============================================================================
--- team/dlee/stasis-http/res/stasis_http_channels.c (original)
+++ team/dlee/stasis-http/res/stasis_http_channels.c Wed Jan 30 14:57:06 2013
@@ -66,6 +66,11 @@
void stasis_http_get_channels(struct ast_variable *headers, struct ast_get_channels_args *args, struct stasis_http_response *response) {
ast_log(LOG_ERROR, "TODO: stasis_http_get_channels\n");
}
+
void stasis_http_originate(struct ast_variable *headers, struct ast_originate_args *args, struct stasis_http_response *response) {
- ast_log(LOG_ERROR, "TODO: stasis_http_originate\n");
+ if (args->endpoint) {
+ ast_log(LOG_DEBUG, "Dialing specific endpoint %s\n", args->endpoint);
+ }
+
+ ast_log(LOG_DEBUG, "Dialing %s@%s\n", args->extension, args->context);
}
More information about the asterisk-commits
mailing list