This is merely a historical archive of years 2008-2021, before the migration to mailman3.
A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.
Holger Freyther gerrit-no-reply at lists.osmocom.orgReview at https://gerrit.osmocom.org/4772 WIP: First invocation of a primitive and callback into lua.. local timer = osmo.timeout(5, function() print("After timeout!!!") end) print("Timer", timer, type(timer)) <0011> @foo.lua:18 Timer<0011> @foo.lua:18 userdata Connection to layer 1 failed! Using configuration from ../../../doc/examples/mobile/default.cfg VTY available on 127.0.0.1 4247 <0011> @foo.lua:16 After timeout!!! Change-Id: I55603f71a1d2426622e3b601d2686903cb74a8e1 --- M src/host/layer23/include/osmocom/bb/mobile/primitives.h M src/host/layer23/src/mobile/primitives.c M src/host/layer23/src/mobile/script_lua.c 3 files changed, 138 insertions(+), 2 deletions(-) git pull ssh://gerrit.osmocom.org:29418/osmocom-bb refs/changes/72/4772/1 diff --git a/src/host/layer23/include/osmocom/bb/mobile/primitives.h b/src/host/layer23/include/osmocom/bb/mobile/primitives.h index 0ba0cac..c5bceb5 100644 --- a/src/host/layer23/include/osmocom/bb/mobile/primitives.h +++ b/src/host/layer23/include/osmocom/bb/mobile/primitives.h @@ -16,6 +16,9 @@ struct mobile_prim_intf { struct osmocom_ms *ms; void (*indication)(struct mobile_prim_intf *, struct osmo_prim_hdr *hdr); + + /* Internal state */ + struct llist_head timers; }; /** @@ -31,3 +34,4 @@ struct mobile_prim_intf *mobile_prim_intf_alloc(struct osmocom_ms *ms); int mobile_prim_intf_req(struct mobile_prim_intf *intf, struct osmo_prim_hdr *hdr); +void mobile_prim_intf_free(struct mobile_prim_intf *intf); diff --git a/src/host/layer23/src/mobile/primitives.c b/src/host/layer23/src/mobile/primitives.c index bdfbabb..71e4b63 100644 --- a/src/host/layer23/src/mobile/primitives.c +++ b/src/host/layer23/src/mobile/primitives.c @@ -25,6 +25,7 @@ #include <osmocom/core/talloc.h> struct timer_closure { + struct llist_head entry; struct mobile_prim_intf *intf; struct osmo_timer_list timer; uint64_t id; @@ -36,7 +37,21 @@ intf = talloc_zero(ms, struct mobile_prim_intf); intf->ms = ms; + + INIT_LLIST_HEAD(&intf->timers); return intf; +} + +void mobile_prim_intf_free(struct mobile_prim_intf *intf) +{ + struct timer_closure *timer, *tmp; + + llist_for_each_entry_safe(timer, tmp, &intf->timers, entry) { + osmo_timer_del(&timer->timer); + llist_del(&timer->entry); + talloc_free(timer); + } + talloc_free(intf); } static void timer_expired_cb(void *_closure) @@ -47,6 +62,7 @@ intf = closure->intf; prim.timer_id = closure->id; + llist_del(&closure->entry); talloc_free(closure); osmo_prim_init(&prim.hdr, 0, PRIM_MOB_TIMER, PRIM_OP_INDICATION, NULL); @@ -64,6 +80,7 @@ closure->id = prim->timer_id; closure->timer.cb = timer_expired_cb; closure->timer.data = closure; + llist_add_tail(&closure->entry, &intf->timers); osmo_timer_schedule(&closure->timer, prim->seconds, 0); return 0; } diff --git a/src/host/layer23/src/mobile/script_lua.c b/src/host/layer23/src/mobile/script_lua.c index 1cf9050..5e9859e 100644 --- a/src/host/layer23/src/mobile/script_lua.c +++ b/src/host/layer23/src/mobile/script_lua.c @@ -25,7 +25,26 @@ #include <osmocom/bb/common/osmocom_data.h> #include <osmocom/bb/common/logging.h> +#include <osmocom/bb/mobile/primitives.h> + #include <osmocom/vty/misc.h> + +struct timer_userdata { + int cb_ref; +}; + +static char lua_prim_key[] = "osmocom.org-mobile-prim"; + +static struct mobile_prim_intf *get_primitive(lua_State *L) +{ + struct mobile_prim_intf *intf; + + lua_pushlightuserdata(L, lua_prim_key); + lua_gettable(L, LUA_REGISTRYINDEX); + intf = (void *) lua_topointer(L, -1); + lua_pop(L, 1); + return intf; +} static int lua_osmo_do_log(lua_State *L, int loglevel) { @@ -75,6 +94,77 @@ { NULL, NULL }, }; +static void handle_timeout(struct mobile_prim_intf *intf, struct mobile_timer_prim *prim) +{ + struct timer_userdata *timer = (void *)(intptr_t) prim->timer_id; + lua_State *L = intf->ms->lua_state; + + lua_rawgeti(L, LUA_REGISTRYINDEX, timer->cb_ref); + luaL_unref(L, LUA_REGISTRYINDEX, timer->cb_ref); + lua_pcall(L, 0, 0, 0); +} + +static int lua_osmo_timeout(lua_State *L) +{ + struct mobile_timer_prim prim = { 0, }; + struct timer_userdata *timer; + + if(lua_gettop(L) != 2) { + lua_pushliteral(L, "Need two arguments"); + lua_error(L); + return 0; + } + + luaL_argcheck(L, lua_isnumber(L, -2), 1, "Timeout needs to be a number"); + luaL_argcheck(L, lua_isfunction(L, -1), 2, "Callback needs to be a function"); + + /* + * Create a handle to prevent the function to be GCed while we run the + * timer. Add a metatable to the object so itself will be GCed properly. + */ + timer = lua_newuserdata(L, sizeof(*timer)); + luaL_getmetatable(L, "Timer"); + lua_setmetatable(L, -2); + + lua_pushvalue(L, -2); + timer->cb_ref = luaL_ref(L, LUA_REGISTRYINDEX); + + /* Take the address of the user data... */ + osmo_prim_init(&prim.hdr, 0, PRIM_MOB_TIMER, PRIM_OP_REQUEST, NULL); + prim.timer_id = (intptr_t) timer; + prim.seconds = lua_tonumber(L, -3); + mobile_prim_intf_req(get_primitive(L), &prim.hdr); + + return 1; +} + +static int lua_timer_gc(lua_State *L) +{ + printf("GC...\n"); + return 0; +} + +static const struct luaL_Reg timer_funcs[] = { + { "__gc", lua_timer_gc }, + { NULL, NULL }, +}; + +static const struct luaL_Reg osmo_funcs[] = { + { "timeout", lua_osmo_timeout }, + { NULL, NULL }, +}; + +static void lua_prim_ind(struct mobile_prim_intf *intf, struct osmo_prim_hdr *hdr) +{ + switch (OSMO_PRIM_HDR(hdr)) { + case OSMO_PRIM(PRIM_MOB_TIMER, PRIM_OP_INDICATION): + return handle_timeout(intf, (struct mobile_timer_prim *)hdr); + break; + default: + LOGP(DLUA, LOGL_ERROR, "Unknown primitive: %d\n", OSMO_PRIM_HDR(hdr)); + }; +} + /* * Add functions to the global lua scope. Technically these are * included in the _G table. The following lua code can be used @@ -89,9 +179,29 @@ lua_pop(state, 1); } -static void add_runtime(lua_State *state, struct osmocom_ms *ms) +static void add_runtime(lua_State *state, struct mobile_prim_intf *intf) { add_globals(state); + + /* Add a osmo module/table. Seems an oldschool module? */ + lua_newtable(state); + luaL_setfuncs(state, osmo_funcs, 0); + lua_setglobal(state, "osmo"); + + /* Create metatables so we can GC objects... */ + luaL_newmetatable(state, "Timer"); + lua_pushliteral(state, "__index"); + lua_pushvalue(state, -2); + lua_rawset(state, -3); + luaL_setfuncs(state, timer_funcs, 0); + lua_pop(state, 1); + + + /* Remember the primitive pointer... store it in the registry */ + lua_pushlightuserdata(state, lua_prim_key); + lua_pushlightuserdata(state, intf); + lua_settable(state, LUA_REGISTRYINDEX); + } static void *talloc_lua_alloc(void *ctx, void *ptr, size_t osize, size_t nsize) @@ -115,6 +225,7 @@ int script_lua_load(struct vty *vty, struct osmocom_ms *ms, const char *filename) { + struct mobile_prim_intf *intf; int err; if (ms->lua_state) @@ -124,6 +235,11 @@ return -1; luaL_openlibs(ms->lua_state); + + intf = mobile_prim_intf_alloc(ms); + intf->indication = lua_prim_ind; + add_runtime(ms->lua_state, intf); + err = luaL_loadfilex(ms->lua_state, filename, NULL); if (err) { vty_out(vty, "%% LUA load error: %s%s", @@ -132,7 +248,6 @@ return -2; } - add_runtime(ms->lua_state, ms); err = lua_pcall(ms->lua_state, 0, 0, 0); if (err) { -- To view, visit https://gerrit.osmocom.org/4772 To unsubscribe, visit https://gerrit.osmocom.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I55603f71a1d2426622e3b601d2686903cb74a8e1 Gerrit-PatchSet: 1 Gerrit-Project: osmocom-bb Gerrit-Branch: master Gerrit-Owner: Holger Freyther <holger at freyther.de>