From bda5fb5db8e370db95925720ec4b9edb8de4f74f Mon Sep 17 00:00:00 2001 From: Krisztian Litkey Date: Mon, 4 Nov 2013 02:36:56 +0200 Subject: [PATCH] system-controller: basic plugin, Lua bindings and dispatching infra. Change-Id: Ic915a2e3ced65e3053ff6808f1ddff455f2cd1b9 --- configure.ac | 2 + src/Makefile.am | 22 + src/daemon/murphy.lua | 6 + src/plugins/system-controller/Makefile | 7 + .../system-controller/plugin-system-controller.c | 731 +++++++++++++++++++++ src/plugins/system-controller/system-controller.h | 35 + 6 files changed, 803 insertions(+) create mode 100644 src/plugins/system-controller/Makefile create mode 100644 src/plugins/system-controller/plugin-system-controller.c create mode 100644 src/plugins/system-controller/system-controller.h diff --git a/configure.ac b/configure.ac index a781c38..cadb449 100644 --- a/configure.ac +++ b/configure.ac @@ -648,6 +648,7 @@ AM_CONDITIONAL(DISABLED_PLUGIN_DOMAIN_CONTROL, AM_CONDITIONAL(DISABLED_PLUGIN_SYSTEMD, [check_if_disabled systemd]) AM_CONDITIONAL(DISABLED_PLUGIN_TELEPHONY, [check_if_disabled telephony]) AM_CONDITIONAL(DISABLED_PLUGIN_RESOURCE_ASM, [check_if_disabled resource-asm]) +AM_CONDITIONAL(DISABLED_PLUGIN_SYSTEMCTL, [check_if_disabled system-controller]) AM_CONDITIONAL(BUILTIN_PLUGIN_TEST, [check_if_internal test]) AM_CONDITIONAL(BUILTIN_PLUGIN_DBUS, [check_if_internal dbus]) @@ -663,6 +664,7 @@ AM_CONDITIONAL(BUILTIN_PLUGIN_LUA, [check_if_internal lua]) AM_CONDITIONAL(BUILTIN_PLUGIN_SYSTEMD, [check_if_internal systemd]) AM_CONDITIONAL(BUILTIN_PLUGIN_TELEPHONY, [check_if_internal telephony]) AM_CONDITIONAL(BUILTIN_PLUGIN_RESOURCE_ASM, [check_if_internal resource-asm]) +AM_CONDITIONAL(BUILTIN_PLUGIN_SYSTEMCTL, [check_if_internal system-controller]) # Check for Check (unit test framework). PKG_CHECK_MODULES(CHECK, diff --git a/src/Makefile.am b/src/Makefile.am index bcb1a98..91d17f0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1517,6 +1517,28 @@ endif endif endif +# system-controller +if SYSTEMCTL_ENABLED +SYSTEMCTL_PLUGIN_SOURCES = plugins/system-controller/plugin-system-controller.c +SYSTEMCTL_PLUGIN_CFLAGS = $(WEBSOCKETS_CFLAGS) +SYSTEMCTL_PLUGIN_LIBS = + +if !DISABLED_PLUGIN_SYSTEMCTL +if BUILTIN_PLUGIN_SYSTEMCTL +BUILTIN_PLUGINS += $(SYSTEMCTL_PLUGIN_SOURCES) +BUILTIN_CFLAGS += $(SYSTEMCTL_PLUGIN_CFLAGS) +BUILTIN_LIBS += $(SYSTEMCTL_PLUGIN_LIBS) +else +plugin_system_controller_la_SOURCES = $(SYSTEMCTL_PLUGIN_SOURCES) +plugin_system_controller_la_CFLAGS = $(SYSTEMCTL_PLUGIN_CFLAGS) \ + $(MURPHY_CFLAGS) $(AM_CFLAGS) +plugin_system_controller_la_LDFLAGS = -module -avoid-version +plugin_system_controller_la_LIBADD = $(SYSTEMCTL_PLUGIN_LIBS) +plugin_LTLIBRARIES += plugin-system-controller.la +endif +endif +endif + # telephony plugin diff --git a/src/daemon/murphy.lua b/src/daemon/murphy.lua index 03112e8..00cb92b 100644 --- a/src/daemon/murphy.lua +++ b/src/daemon/murphy.lua @@ -101,6 +101,12 @@ else m:info("No domain-control plugin found...") end +if m:plugin_exists('system-controller') then + m:load_plugin('system-controller') +else + m:info("No system-controller plugin found...") +end + -- load IVI resource manager plugin if exists if m:plugin_exists('ivi-resource-manager') then diff --git a/src/plugins/system-controller/Makefile b/src/plugins/system-controller/Makefile new file mode 100644 index 0000000..2c0a593 --- /dev/null +++ b/src/plugins/system-controller/Makefile @@ -0,0 +1,7 @@ +ifneq ($(strip $(MAKECMDGOALS)),) +%: + $(MAKE) -C .. $(MAKECMDGOALS) +else +all: + $(MAKE) -C .. all +endif diff --git a/src/plugins/system-controller/plugin-system-controller.c b/src/plugins/system-controller/plugin-system-controller.c new file mode 100644 index 0000000..ccdd69e --- /dev/null +++ b/src/plugins/system-controller/plugin-system-controller.c @@ -0,0 +1,731 @@ +/* + * Copyright (c) 2012, 2013, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "system-controller.h" + + +#define DEFAULT_ADDRESS "wsck:127.0.0.1:18081/ico_syc_protocol" + +/* + * plugin argument ids/indices + */ + +enum { + ARG_ADDRESS, /* transport address to use */ +}; + + +/* + * system-controller context + */ + +typedef struct sysctl_lua_s sysctl_lua_t; + +typedef struct { + mrp_context_t *ctx; /* murphy context */ + mrp_transport_t *lt; /* transport we listen on */ + const char *addr; /* address we listen on */ + mrp_list_hook_t clients; /* connected clients */ + int id; /* next client id */ + sysctl_lua_t *scl; /* singleton Lua object */ + lua_State *L; /* murphy Lua state */ + struct { + mrp_funcbridge_t *client; + mrp_funcbridge_t *generic; + mrp_funcbridge_t *window; + mrp_funcbridge_t *input; + mrp_funcbridge_t *user; + mrp_funcbridge_t *resource; + mrp_funcbridge_t *inputdev; + } handler; +} sysctl_t; + + +/* + * a system-controller client + */ + +typedef struct { + int id; /* client id */ + pid_t pid; /* client pid */ + char *app; /* client app id */ + sysctl_t *sc; /* system controller context */ + mrp_transport_t *t; /* client transport */ + mrp_list_hook_t hook; /* to list of clients */ +} client_t; + + +struct sysctl_lua_s { + sysctl_t *sc; /* system controller */ +}; + +typedef enum { + SYSCTL_IDX_CLIENT = 1, + SYSCTL_IDX_GENERIC, + SYSCTL_IDX_WINDOW, + SYSCTL_IDX_INPUT, + SYSCTL_IDX_USER, + SYSCTL_IDX_RESOURCE, + SYSCTL_IDX_INPUTDEV, +} sysctl_lua_index_t; + + +static int sysctl_lua_create(lua_State *L); +static void sysctl_lua_destroy(void *data); +static int sysctl_lua_getfield(lua_State *L); +static int sysctl_lua_setfield(lua_State *L); +static int sysctl_lua_stringify(lua_State *L); +static int sysctl_lua_send(lua_State *L); + +#define SYSCTL_LUA_CLASS MRP_LUA_CLASS(sysctl, lua) + +MRP_LUA_METHOD_LIST_TABLE(sysctl_lua_methods, + MRP_LUA_METHOD_CONSTRUCTOR(sysctl_lua_create) + MRP_LUA_METHOD(send_message, sysctl_lua_send)); + +MRP_LUA_METHOD_LIST_TABLE(sysctl_lua_overrides, + MRP_LUA_OVERRIDE_CALL (sysctl_lua_create) + MRP_LUA_OVERRIDE_GETFIELD (sysctl_lua_getfield) + MRP_LUA_OVERRIDE_SETFIELD (sysctl_lua_setfield) + MRP_LUA_OVERRIDE_STRINGIFY(sysctl_lua_stringify)); + +MRP_LUA_CLASS_DEF(sysctl, lua, sysctl_lua_t, + sysctl_lua_destroy, sysctl_lua_methods, sysctl_lua_overrides); + + + + +static sysctl_t *scptr; /* singleton native object */ + + +static client_t *create_client(sysctl_t *sc, mrp_transport_t *lt) +{ + client_t *c; + + c = mrp_allocz(sizeof(*c)); + + if (c != NULL) { + mrp_list_init(&c->hook); + + c->sc = sc; + c->t = mrp_transport_accept(lt, c, MRP_TRANSPORT_REUSEADDR); + + if (c->t != NULL) { + mrp_list_append(&sc->clients, &c->hook); + c->id = sc->id++; + + return c; + } + + mrp_free(c); + } + + return NULL; +} + + +static void destroy_client(client_t *c) +{ + if (c != NULL) { + mrp_list_delete(&c->hook); + + mrp_transport_disconnect(c->t); + mrp_transport_destroy(c->t); + + mrp_free(c); + } +} + + +static client_t *find_client_by_id(sysctl_t *sc, int id) +{ + mrp_list_hook_t *p, *n; + client_t *c; + + mrp_list_foreach(&sc->clients, p, n) { + c = mrp_list_entry(p, typeof(*c), hook); + + if (c->id == id) + return c; + } + + return NULL; +} + + +static client_t *find_client_by_pid(sysctl_t *sc, pid_t pid) +{ + mrp_list_hook_t *p, *n; + client_t *c; + + mrp_list_foreach(&sc->clients, p, n) { + c = mrp_list_entry(p, typeof(*c), hook); + + if (c->pid == pid) + return c; + } + + return NULL; +} + + +static client_t *find_client_by_app(sysctl_t *sc, const char *app) +{ + mrp_list_hook_t *p, *n; + client_t *c; + + mrp_list_foreach(&sc->clients, p, n) { + c = mrp_list_entry(p, typeof(*c), hook); + + if (c->app != NULL && !strcmp(c->app, app)) + return c; + } + + return NULL; +} + + +static void connection_evt(mrp_transport_t *lt, void *user_data) +{ + sysctl_t *sc = (sysctl_t *)user_data; + client_t *c; + + c = create_client(sc, lt); + + if (c != NULL) + mrp_log_info("Accepted system controller client connection."); + else + mrp_log_error("Failed to accept system controller client connection."); +} + + +static void closed_evt(mrp_transport_t *t, int error, void *user_data) +{ + client_t *c = (client_t *)user_data; + + MRP_UNUSED(t); + + if (error != 0) + mrp_log_error("System controller connection closed with error %d (%s).", + error, strerror(error)); + else + mrp_log_info("System controller client #%d closed connection.", c->id); + + destroy_client(c); +} + + +static int send_message(client_t *c, mrp_json_t *msg) +{ + const char *s; + + s = mrp_json_object_to_string(msg); + + mrp_debug("sending system controller message to client #%d:", c->id); + mrp_debug(" %s", s); + + return mrp_transport_sendcustom(c->t, msg); +} + + +static const char *message_name(int code) +{ +#define MAX_CLASS 0x08 +#define MAX_TYPE 0x30 +#define CLASS(code) (((code) & 0xf0000) >> 16) +#define TYPE(code) (((code) & 0x0ffff)) + static char *names[MAX_CLASS + 1][MAX_TYPE + 1]; + static int setup = 1; + + int c = CLASS(code), t = TYPE(code); + char *n; + + if (setup) { + memset(names, 0, sizeof(names)); + +#define MAP(msg, code) names[CLASS(code)][TYPE(code)] = #msg; + MAP(MSG_CMD_SEND_APPID , 0x00000001); + MAP(MSG_CMD_CREATE , 0x00010001); + MAP(MSG_CMD_DESTROY , 0x00010002); + MAP(MSG_CMD_SHOW , 0x00010003); + MAP(MSG_CMD_HIDE , 0x00010004); + MAP(MSG_CMD_MOVE , 0x00010005); + MAP(MSG_CMD_CHANGE_ACTIVE , 0x00010006); + MAP(MSG_CMD_CHANGE_LAYER , 0x00010007); + MAP(MSG_CMD_CHANGE_ATTR , 0x00010008); + MAP(MSG_CMD_NAME , 0x00010009); + MAP(MSG_CMD_MAP_THUMB , 0x00010011); + MAP(MSG_CMD_UNMAP_THUMB , 0x00010012); + MAP(MSG_CMD_SHOW_LAYER , 0x00010020); + MAP(MSG_CMD_HIDE_LAYER , 0x00010021); + MAP(MSG_CMD_CHANGE_LAYER_ATTR , 0x00010022); + MAP(MSG_CMD_ADD_INPUT , 0x00020001); + MAP(MSG_CMD_DEL_INPUT , 0x00020002); + MAP(MSG_CMD_SEND_INPUT , 0x00020003); + MAP(MSG_CMD_CHANGE_USER , 0x00030001); + MAP(MSG_CMD_GET_USERLIST , 0x00030002); + MAP(MSG_CMD_GET_LASTINFO , 0x00030003); + MAP(MSG_CMD_SET_LASTINFO , 0x00030004); + MAP(MSG_CMD_ACQUIRE_RES , 0x00040001); + MAP(MSG_CMD_RELEASE_RES , 0x00040002); + MAP(MSG_CMD_DEPRIVE_RES , 0x00040003); + MAP(MSG_CMD_WAITING_RES , 0x00040004); + MAP(MSG_CMD_REVERT_RES , 0x00040005); + MAP(MSG_CMD_SET_REGION , 0x00050001); + MAP(MSG_CMD_UNSET_REGION , 0x00050002); + MAP(MSG_CMD_CREATE_RES , 0x00040011); + MAP(MSG_CMD_DESTORY_RES , 0x00040012); + MAP(MSG_CMD_NOTIFY_CHANGED_STATE, 0x00060001); +#undef MAP + + setup = false; + } + + if (c > MAX_CLASS || t > MAX_TYPE || (n = names[c][t]) == NULL) + return ""; + else + return n; +} + + +static void recv_evt(mrp_transport_t *t, void *data, void *user_data) +{ + client_t *c = (client_t *)user_data; + sysctl_t *sc = c->sc; + mrp_json_t *req = (mrp_json_t *)data; + int cmd, type, pid; + const char *app; + mrp_funcbridge_t *handlers[] = { + [0] = sc->handler.client, + [1] = sc->handler.window, + [2] = sc->handler.input, + [3] = sc->handler.user, + [4] = sc->handler.resource, + [5] = sc->handler.inputdev + }, *h; + mrp_funcbridge_value_t args[4]; + mrp_funcbridge_value_t ret; + char rt; + + MRP_UNUSED(t); + + { + const char *s = mrp_json_object_to_string(req); + mrp_debug("system controller received message from client #%d:", c->id); + mrp_debug(" %s", s); + } + + /* + * emit a connection message if this is the fist message with an appid + */ + + if (mrp_json_get_integer(req, "pid", &pid)) + c->pid = pid; + + if (mrp_json_get_string(req, "appid", &app) && c->app == NULL) { + mrp_free(c->app); + c->app = mrp_strdup(app); + + mrp_debug("client #%d: pid %u, appid '%s'", c->id, c->pid, + c->app ? c->app : ""); + + h = sc->handler.client; + + if (h != NULL) { + args[0].pointer = sc->scl; + args[1].integer = c->id; + args[2].pointer = mrp_json_lua_wrap(sc->L, req); + + if (!mrp_funcbridge_call_from_c(sc->L, h, "odo", &args[0], + &rt, &ret)) { + mrp_log_error("Failed to dispatch client-connection (%s).", + ret.string ? ret.string : ""); + mrp_free((void *)ret.string); + } + } + } + + + if (!mrp_json_get_integer(req, "command", &cmd)) { + h = sc->handler.generic; + type = 0; + } + else { + type = (cmd & 0xffff0000) >> 16; + + if (0 <= type && type <= 5) + h = handlers[type]; + else + h = NULL; + } + + if (h != NULL || (h = sc->handler.generic) != NULL) { + args[0].pointer = sc->scl; + args[1].integer = c->id; + args[2].pointer = mrp_json_lua_wrap(sc->L, req); + + mrp_json_add_string(req, "MESSAGE", message_name(cmd)); + + if (!mrp_funcbridge_call_from_c(sc->L, h, "odo", &args[0], &rt, &ret)) { + mrp_log_error("Failed to dispatch system-controller message (%s).", + ret.string ? ret.string : ""); + mrp_free((void *)ret.string); + } + } + else + mrp_debug("No handler for system-controller message of type 0x%x.", + type); +} + + +static int transport_create(sysctl_t *sc) +{ + static mrp_transport_evt_t evt = { + { .recvcustom = recv_evt }, + { .recvcustomfrom = NULL }, + .connection = connection_evt, + .closed = closed_evt, + }; + + mrp_mainloop_t *ml = sc->ctx->ml; + mrp_sockaddr_t addr; + socklen_t len; + const char *type, *opt, *val; + int flags; + + len = mrp_transport_resolve(NULL, sc->addr, &addr, sizeof(addr), &type); + + if (len > 0) { + flags = MRP_TRANSPORT_REUSEADDR | MRP_TRANSPORT_MODE_CUSTOM; + sc->lt = mrp_transport_create(ml, type, &evt, sc, flags); + + if (sc->lt != NULL) { + if (mrp_transport_bind(sc->lt, &addr, len) && + mrp_transport_listen(sc->lt, 0)) { + mrp_log_info("Listening on transport '%s'...", sc->addr); + + opt = MRP_WSCK_OPT_SENDMODE; + val = MRP_WSCK_SENDMODE_TEXT; + mrp_transport_setopt(sc->lt, opt, val); + + return TRUE; + } + + mrp_transport_destroy(sc->lt); + sc->lt = NULL; + } + } + else + mrp_log_error("Failed to resolve transport address '%s'.", sc->addr); + + return FALSE; +} + + +static void transport_destroy(sysctl_t *sc) +{ + mrp_transport_destroy(sc->lt); + sc->lt = NULL; +} + + +static int sysctl_lua_create(lua_State *L) +{ + static sysctl_lua_t *scl = NULL; + + if (scl == NULL) + scl = (sysctl_lua_t *)mrp_lua_create_object(L, SYSCTL_LUA_CLASS, + NULL, 0); + scl->sc = scptr; + scptr->scl = scl; + + mrp_lua_push_object(L, scl); + + return 1; +} + + +static void sysctl_lua_destroy(void *data) +{ + MRP_UNUSED(data); +} + + +static sysctl_lua_t *sysctl_lua_check(lua_State *L, int idx) +{ + return (sysctl_lua_t *)mrp_lua_check_object(L, SYSCTL_LUA_CLASS, idx); +} + + +static int name_to_index(const char *name) +{ +#define MAP(_name, _idx) if (!strcmp(name, _name)) return SYSCTL_IDX_##_idx; + MAP("client_handler" , CLIENT); + MAP("generic_handler" , GENERIC); + MAP("window_handler" , WINDOW); + MAP("input_handler" , INPUT); + MAP("user_handler" , USER); + MAP("resource_handler", RESOURCE); + MAP("inputdev_handler", INPUTDEV); + return 0; +#undef MAP +} + + +static int sysctl_lua_getfield(lua_State *L) +{ + sysctl_lua_t *scl = sysctl_lua_check(L, 1); + sysctl_lua_index_t idx = name_to_index(lua_tolstring(L, 2, NULL)); + + lua_pop(L, 1); + + switch (idx) { + case SYSCTL_IDX_CLIENT: + mrp_funcbridge_push(L, scl->sc->handler.client); + break; + case SYSCTL_IDX_GENERIC: + mrp_funcbridge_push(L, scl->sc->handler.generic); + break; + case SYSCTL_IDX_WINDOW: + mrp_funcbridge_push(L, scl->sc->handler.window); + break; + case SYSCTL_IDX_INPUT: + mrp_funcbridge_push(L, scl->sc->handler.input); + break; + case SYSCTL_IDX_USER: + mrp_funcbridge_push(L, scl->sc->handler.user); + break; + case SYSCTL_IDX_RESOURCE: + mrp_funcbridge_push(L, scl->sc->handler.resource); + break; + case SYSCTL_IDX_INPUTDEV: + mrp_funcbridge_push(L, scl->sc->handler.inputdev); + break; + default: + lua_pushnil(L); + } + + return 1; +} + + +static int sysctl_lua_setfield(lua_State *L) +{ + sysctl_lua_t *scl = sysctl_lua_check(L, 1); + const char *name = lua_tostring(L, 2); + sysctl_lua_index_t idx = name_to_index(name); + mrp_funcbridge_t **hptr = NULL; + + switch (idx) { + case SYSCTL_IDX_CLIENT: hptr = &scl->sc->handler.client; break; + case SYSCTL_IDX_GENERIC: hptr = &scl->sc->handler.generic; break; + case SYSCTL_IDX_WINDOW: hptr = &scl->sc->handler.window; break; + case SYSCTL_IDX_INPUT: hptr = &scl->sc->handler.input; break; + case SYSCTL_IDX_USER: hptr = &scl->sc->handler.user; break; + case SYSCTL_IDX_RESOURCE: hptr = &scl->sc->handler.resource; break; + case SYSCTL_IDX_INPUTDEV: hptr = &scl->sc->handler.inputdev; break; + default: + luaL_error(L, "unknown system-controller handler '%s'", name); + } + + if (lua_type(L, -1) != LUA_TNIL) + *hptr = mrp_funcbridge_create_luafunc(L, -1); + else + *hptr = NULL; + + mrp_debug("handler %s (#%d) of %p set to %p", name, idx, scl, *hptr); + + return 0; +} + + +static int sysctl_lua_stringify(lua_State *L) +{ + sysctl_lua_t *scl = sysctl_lua_check(L, 1); + + if (scl != NULL) + lua_pushfstring(L, "", scl); + else + lua_pushstring(L, ""); + + return 1; +} + + +static int sysctl_lua_send(lua_State *L) +{ + sysctl_lua_t *scl = sysctl_lua_check(L, 1); + client_t *c; + mrp_json_t *msg; + int success; + + switch (lua_type(L, 2)) { + case LUA_TSTRING: + c = find_client_by_app(scl->sc, lua_tostring(L, 2)); + break; + + case LUA_TNUMBER: + c = find_client_by_id(scl->sc, lua_tointeger(L, 2)); + break; + + default: + return luaL_error(L, "invalid argument, client id or name expected"); + } + + msg = mrp_json_lua_get(L, 3); + + lua_pop(L, 3); + + if (c != NULL && msg != NULL) { + mrp_debug("sending message %s to client #%d", + mrp_json_object_to_string(msg), c->id); + success = send_message(c, msg); + } + else + success = FALSE; + + mrp_json_unref(msg); + lua_pushboolean(L, success); + + return 1; +} + + +static int sc_lua_get(lua_State *L) +{ + sysctl_lua_t *scl = mrp_lua_create_object(L, SYSCTL_LUA_CLASS, NULL, 0); + + scl->sc = scptr; + + mrp_lua_push_object(L, scl); + + return 1; +} + + +static int register_lua_bindings(sysctl_t *sc) +{ + static luaL_reg methods[] = { + { "get_system_controller", sc_lua_get }, + { NULL, NULL } + }; + static mrp_lua_bindings_t bindings = { + .meta = "murphy", + .methods = methods, + }; + + if ((sc->L = mrp_lua_get_lua_state()) == NULL) + return FALSE; + + mrp_lua_create_object_class(sc->L, SYSCTL_LUA_CLASS); + + return mrp_lua_register_murphy_bindings(&bindings); +} + + +static int plugin_init(mrp_plugin_t *plugin) +{ + sysctl_t *sc; + + MRP_UNUSED(find_client_by_pid); + + sc = mrp_allocz(sizeof(*sc)); + + if (sc != NULL) { + mrp_list_init(&sc->clients); + + sc->id = 1; + sc->ctx = plugin->ctx; + sc->addr = plugin->args[ARG_ADDRESS].str; + + if (!transport_create(sc)) + goto fail; + + if (!register_lua_bindings(sc)) + goto fail; + + scptr = sc; + + return TRUE; + } + + + fail: + if (sc != NULL) { + transport_destroy(sc); + + mrp_free(sc); + } + + return FALSE; +} + + +static void plugin_exit(mrp_plugin_t *plugin) +{ + sysctl_t *sc = (sysctl_t *)plugin->data; + + scptr = NULL; + + transport_destroy(sc); + + mrp_free(sc); +} + + + +#define PLUGIN_DESCRIPTION "Murphy system controller plugin." +#define PLUGIN_HELP "Murphy system controller plugin." +#define PLUGIN_AUTHORS "Krisztian Litkey " +#define PLUGIN_VERSION MRP_VERSION_INT(0, 0, 1) + +static mrp_plugin_arg_t plugin_args[] = { + MRP_PLUGIN_ARGIDX(ARG_ADDRESS, STRING, "address", DEFAULT_ADDRESS) +}; + +MURPHY_REGISTER_PLUGIN("system-controller", + PLUGIN_VERSION, PLUGIN_DESCRIPTION, PLUGIN_AUTHORS, + PLUGIN_HELP, MRP_SINGLETON, plugin_init, plugin_exit, + plugin_args, MRP_ARRAY_SIZE(plugin_args), + NULL, 0, + NULL, 0, + NULL); diff --git a/src/plugins/system-controller/system-controller.h b/src/plugins/system-controller/system-controller.h new file mode 100644 index 0000000..8c31bb5 --- /dev/null +++ b/src/plugins/system-controller/system-controller.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2012, 2013, Intel Corporation + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of Intel Corporation nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __MURPHY_PLUGIN_SYSTEM_CONTROLLER_H__ +#define __MURPHY_PLUGIN_SYSTEM_CONTROLLER_H__ + + + +#endif /* __MURPHY_PLUGIN_SYSTEM_CONTROLLER_H__ */ -- 2.7.4