diff options
-rw-r--r-- | src/host/layer23/include/osmocom/bb/common/osmocom_data.h | 3 | ||||
-rw-r--r-- | src/host/layer23/include/osmocom/bb/mobile/app_mobile.h | 4 | ||||
-rw-r--r-- | src/host/layer23/src/mobile/Makefile.am | 8 | ||||
-rw-r--r-- | src/host/layer23/src/mobile/script_lua.c | 146 | ||||
-rw-r--r-- | src/host/layer23/src/mobile/script_nolua.c | 36 | ||||
-rw-r--r-- | src/host/layer23/src/mobile/settings.c | 3 | ||||
-rw-r--r-- | src/host/layer23/src/mobile/vty_interface.c | 28 |
7 files changed, 227 insertions, 1 deletions
diff --git a/src/host/layer23/include/osmocom/bb/common/osmocom_data.h b/src/host/layer23/include/osmocom/bb/common/osmocom_data.h index 7a935f97..8f5cdc33 100644 --- a/src/host/layer23/include/osmocom/bb/common/osmocom_data.h +++ b/src/host/layer23/include/osmocom/bb/common/osmocom_data.h @@ -85,6 +85,9 @@ struct osmocom_ms { struct gsm48_cclayer cclayer; struct osmomncc_entity mncc_entity; struct llist_head trans_list; + + void *lua_state; + char *lua_script; }; enum osmobb_sig_subsys { diff --git a/src/host/layer23/include/osmocom/bb/mobile/app_mobile.h b/src/host/layer23/include/osmocom/bb/mobile/app_mobile.h index 7abfda1f..c2ab3c88 100644 --- a/src/host/layer23/include/osmocom/bb/mobile/app_mobile.h +++ b/src/host/layer23/include/osmocom/bb/mobile/app_mobile.h @@ -6,6 +6,7 @@ extern char *config_dir; struct osmocom_ms; +struct vty; int l23_app_init(int (*mncc_recv)(struct osmocom_ms *ms, int, void *), const char *config_file, const char *vty_ip, uint16_t vty_port); @@ -20,6 +21,9 @@ int mobile_stop(struct osmocom_ms *ms, int force); void mobile_set_started(struct osmocom_ms *ms, bool state); void mobile_set_shutdown(struct osmocom_ms *ms, int state); +int script_lua_load(struct vty *vty, struct osmocom_ms *ms, const char *filename); +int script_lua_close(struct osmocom_ms *ms); + /* Internal code. Don't call directly */ int mobile_exit(struct osmocom_ms *ms, int force); diff --git a/src/host/layer23/src/mobile/Makefile.am b/src/host/layer23/src/mobile/Makefile.am index 47870e56..4e80e4ea 100644 --- a/src/host/layer23/src/mobile/Makefile.am +++ b/src/host/layer23/src/mobile/Makefile.am @@ -12,4 +12,10 @@ bin_PROGRAMS = mobile mobile_SOURCES = main.c app_mobile.c mobile_LDADD = libmobile.a $(LDADD) - +# lua support +if BUILD_LUA +AM_CPPFLAGS += -DWITH_LUA=1 +libmobile_a_SOURCES += script_lua.c +else +libmobile_a_SOURCES += script_nolua.c +endif diff --git a/src/host/layer23/src/mobile/script_lua.c b/src/host/layer23/src/mobile/script_lua.c new file mode 100644 index 00000000..b3b9c99c --- /dev/null +++ b/src/host/layer23/src/mobile/script_lua.c @@ -0,0 +1,146 @@ +/* (C) 2017 by Holger Hans Peter Freyther + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include <lua.h> +#include <lualib.h> +#include <lauxlib.h> + +#include <osmocom/bb/common/osmocom_data.h> +#include <osmocom/bb/common/logging.h> + +#include <osmocom/vty/misc.h> + +static int lua_osmo_do_log(lua_State *L, int loglevel) +{ + int argc = lua_gettop(L); + lua_Debug ar = { 0, }; + int i; + + lua_getstack(L, 1, &ar); + lua_getinfo(L, "nSl", &ar); + + for (i = 1; i <= argc; ++i) { + if (!lua_isstring(L, i)) + continue; + LOGPSRC(DLUA, loglevel, ar.source, ar.currentline, + "%s%s", i > 1 ? "\t" : "", lua_tostring(L, i)); + } + LOGPC(DLUA, loglevel, "\n"); + return 0; +} + +static int lua_osmo_print(lua_State *L) +{ + return lua_osmo_do_log(L, LOGL_NOTICE); +} + +static int lua_osmo_debug(lua_State *L) +{ + return lua_osmo_do_log(L, LOGL_DEBUG); +} + +static int lua_osmo_error(lua_State *L) +{ + return lua_osmo_do_log(L, LOGL_ERROR); +} + +static int lua_osmo_fatal(lua_State *L) +{ + return lua_osmo_do_log(L, LOGL_FATAL); +} + +static const struct luaL_Reg global_runtime[] = { + { "print", lua_osmo_print }, + { "log_notice", lua_osmo_print }, + { "log_debug", lua_osmo_debug }, + { "log_error", lua_osmo_error }, + { "log_fatal", lua_osmo_fatal }, + { NULL, NULL }, +}; + +/* + * Add functions to the global lua scope. Technically these are + * included in the _G table. The following lua code can be used + * to inspect it. + * + * > for n in pairs(_G) do print(n) end + */ +static void add_globals(lua_State *L) +{ + lua_getglobal(L, "_G"); + luaL_setfuncs(L, global_runtime, 0); + lua_pop(L, 1); +} + +static void add_runtime(lua_State *L, struct osmocom_ms *ms) +{ + add_globals(L); +} + +static void *talloc_lua_alloc(void *ctx, void *ptr, size_t osize, size_t nsize) +{ + if (nsize == 0) { + talloc_free(ptr); + return NULL; + } + return talloc_realloc_size(ctx, ptr, nsize); +} + +int script_lua_close(struct osmocom_ms *ms) +{ + if (!ms->lua_state) + return 0; + + lua_close(ms->lua_state); + ms->lua_state = NULL; + return 0; +} + +int script_lua_load(struct vty *vty, struct osmocom_ms *ms, const char *filename) +{ + int err; + + if (ms->lua_state) + lua_close(ms->lua_state); + ms->lua_state = lua_newstate(talloc_lua_alloc, ms); + if (!ms->lua_state) + return -1; + + luaL_openlibs(ms->lua_state); + err = luaL_loadfilex(ms->lua_state, filename, NULL); + if (err) { + vty_out(vty, "%% LUA load error: %s%s", + lua_tostring(ms->lua_state, -1), VTY_NEWLINE); + lua_pop(ms->lua_state, 1); + return -2; + } + + add_runtime(ms->lua_state, ms); + + err = lua_pcall(ms->lua_state, 0, 0, 0); + if (err) { + vty_out(vty, "%% LUA execute error: %s%s", + lua_tostring(ms->lua_state, -1), VTY_NEWLINE); + lua_pop(ms->lua_state, 1); + return 3; + } + + return 0; +} diff --git a/src/host/layer23/src/mobile/script_nolua.c b/src/host/layer23/src/mobile/script_nolua.c new file mode 100644 index 00000000..61466f77 --- /dev/null +++ b/src/host/layer23/src/mobile/script_nolua.c @@ -0,0 +1,36 @@ +/* (C) 2017 by Holger Hans Peter Freyther + * + * All Rights Reserved + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + * + */ + +#include <osmocom/bb/common/osmocom_data.h> +#include <osmocom/bb/common/logging.h> + +#include <osmocom/vty/misc.h> + + +int script_lua_load(struct vty *vty, struct osmocom_ms *ms, const char *filename) +{ + vty_out(vty, "%% No LUA support compiled into mobile!%s", VTY_NEWLINE); + return -1; +} + +int script_lua_close(struct osmocom_ms *ms) +{ + return 0; +} diff --git a/src/host/layer23/src/mobile/settings.c b/src/host/layer23/src/mobile/settings.c index 2b518379..6d50c6b3 100644 --- a/src/host/layer23/src/mobile/settings.c +++ b/src/host/layer23/src/mobile/settings.c @@ -24,6 +24,7 @@ #include <string.h> #include <osmocom/core/talloc.h> +#include <osmocom/bb/mobile/app_mobile.h> #include <osmocom/bb/common/logging.h> #include <osmocom/bb/common/osmocom_data.h> #include <osmocom/bb/common/networks.h> @@ -143,6 +144,8 @@ int gsm_settings_exit(struct osmocom_ms *ms) talloc_free(abbrev); } + script_lua_close(ms); + return 0; } diff --git a/src/host/layer23/src/mobile/vty_interface.c b/src/host/layer23/src/mobile/vty_interface.c index 81c20fe9..87679855 100644 --- a/src/host/layer23/src/mobile/vty_interface.c +++ b/src/host/layer23/src/mobile/vty_interface.c @@ -1531,6 +1531,8 @@ static void config_write_ms(struct vty *vty, struct osmocom_ms *ms) /* no shutdown must be written to config, because shutdown is default */ vty_out(vty, " %sshutdown%s", (ms->shutdown != MS_SHUTDOWN_NONE) ? "" : "no ", VTY_NEWLINE); + if (ms->lua_script) + vty_out(vty, " lua-script %s%s", ms->lua_script, VTY_NEWLINE); vty_out(vty, "!%s", VTY_NEWLINE); } @@ -2740,6 +2742,30 @@ DEFUN(cfg_shutdown_force, cfg_ms_shutdown_force_cmd, "shutdown force", return CMD_SUCCESS; } +DEFUN(cfg_ms_script_load_run, cfg_ms_script_load_run_cmd, "lua-script FILENAME", + "Load and execute a LUA script\nFilename for lua script") +{ + struct osmocom_ms *ms = vty->index; + + osmo_talloc_replace_string(ms, &ms->lua_script, argv[0]); + if (!ms->lua_script) + return CMD_WARNING; + + script_lua_load(vty, ms, ms->lua_script); + return CMD_SUCCESS; +} + +DEFUN(cfg_ms_no_script_load_run, cfg_ms_no_script_load_run_cmd, "no lua-script", + NO_STR "Load and execute LUA script") +{ + struct osmocom_ms *ms = vty->index; + + script_lua_close(ms); + talloc_free(ms->lua_script); + ms->lua_script = NULL; + return CMD_SUCCESS; +} + int ms_vty_go_parent(struct vty *vty) { switch (vty->node) { @@ -2931,6 +2957,8 @@ int ms_vty_init(void) install_element(MS_NODE, &cfg_ms_shutdown_cmd); install_element(MS_NODE, &cfg_ms_shutdown_force_cmd); install_element(MS_NODE, &cfg_ms_no_shutdown_cmd); + install_element(MS_NODE, &cfg_ms_script_load_run_cmd); + install_element(MS_NODE, &cfg_ms_no_script_load_run_cmd); /* Register the talloc context introspection command */ osmo_talloc_vty_add_cmds(); |