Holger Freyther has uploaded this change for review. ( 
https://gerrit.osmocom.org/10439


Change subject: WIP: Allow lua code to register a fd for reading with the 
runtime
......................................................................

WIP: Allow lua code to register a fd for reading with the runtime

To have bi-directional communication we can pass credentials to the
registry server and now we can register a callback when the registry
is sending data to us.

Change-Id: I8254bdda1df2f8fe0a5eac894b931e7de5b426df
---
M src/host/layer23/src/mobile/script_lua.c
1 file changed, 96 insertions(+), 0 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmocom-bb refs/changes/39/10439/1

diff --git a/src/host/layer23/src/mobile/script_lua.c 
b/src/host/layer23/src/mobile/script_lua.c
index 4cfe55a..1cfa812 100644
--- a/src/host/layer23/src/mobile/script_lua.c
+++ b/src/host/layer23/src/mobile/script_lua.c
@@ -28,6 +28,7 @@

 #include <osmocom/bb/mobile/primitives.h>

+#include <osmocom/core/select.h>
 #include <osmocom/vty/misc.h>

 #include <sys/types.h>
@@ -37,6 +38,12 @@
        int cb_ref;
 };

+struct fd_userdata {
+       struct lua_State *state;
+       struct osmo_fd fd;
+       int cb_ref;
+};
+
 static char lua_prim_key[] = "osmocom.org-mobile-prim";

 static struct mobile_prim_intf *get_primitive(lua_State *L)
@@ -430,6 +437,93 @@
        return 1;
 }

+static int lua_fd_cb(struct osmo_fd *fd, unsigned int what) {
+       struct fd_userdata *fdu;
+       lua_State *L;
+       int cb_ref;
+       int err;
+
+       if (!fd->data) {
+               LOGP(DLUA, LOGL_ERROR,
+                       "fd callback for fd(%d) but no lua callback\n", fd->fd);
+               return 0;
+       }
+
+       fdu = fd->data;
+       L = fdu->state;
+       cb_ref = fdu->cb_ref;
+       lua_rawgeti(L, LUA_REGISTRYINDEX, cb_ref);
+       luaL_unref(L, LUA_REGISTRYINDEX, cb_ref);
+
+       lua_pushinteger(L, fd->fd);
+
+       err = lua_pcall(L, 1, 0, 0);
+       if (err) {
+               LOGP(DLUA, LOGL_ERROR, "lua error: %s\n", lua_tostring(L, -1));
+               lua_pop(L, 1);
+       }
+
+       return 0;
+}
+
+/* Register the fd */
+static int lua_register_fd(lua_State *L)
+{
+       struct fd_userdata *fdu;
+
+       /* fd, cb */
+       luaL_argcheck(L, lua_isnumber(L, -2), 1, "needs to be a 
filedescriptor");
+       luaL_argcheck(L, lua_isfunction(L, -1), 2, "Callback needs to be a 
function");
+
+       /* Cretae a table so a user can unregister (and unregister on GC) */
+       fdu = lua_newuserdata(L, sizeof(*fdu));
+       fdu->state = L;
+       fdu->fd.fd = -1;
+       luaL_getmetatable(L, "Fd");
+       lua_setmetatable(L, -2);
+
+       /* Set the filedescriptor */
+       fdu->fd.fd = (int) lua_tonumber(L, -3);
+       fdu->fd.cb = lua_fd_cb;
+       fdu->fd.when = BSC_FD_READ;
+       fdu->fd.data = fdu;
+
+       /* Assuming that an error here will lead to a GC */
+       if (osmo_fd_register(&fdu->fd) != 0) {
+               fdu->cb_ref = LUA_NOREF;
+               lua_pushliteral(L, "Can't register the fd");
+               lua_error(L);
+               return 0;
+       }
+
+       /* Take the callback and keep a reference to it */
+       lua_pushvalue(L, -2);
+       fdu->cb_ref = luaL_ref(L, LUA_REGISTRYINDEX);
+
+       return 1;
+}
+
+static int lua_fd_unregister(lua_State *L) {
+       struct fd_userdata *fdu;
+
+       luaL_argcheck(L, lua_isuserdata(L, -1), 1, "No userdata");
+       fdu = lua_touserdata(L, -1);
+
+       /* Unregister the fd and forget about the callback */
+       osmo_fd_unregister(&fdu->fd);
+       if (fdu->cb_ref != LUA_NOREF) {
+               luaL_unref(L, LUA_REGISTRYINDEX, fdu->cb_ref);
+               fdu->cb_ref = LUA_NOREF;
+       }
+       return 0;
+}
+
+
+static const struct luaL_Reg fd_funcs[] = {
+       { "unregister", lua_fd_unregister },
+       { "__gc", lua_fd_unregister },
+};
+
 static const struct luaL_Reg ms_funcs[] = {
        { "imsi", lua_ms_imsi },
        { "imei", lua_ms_imei },
@@ -447,6 +541,7 @@
 static const struct luaL_Reg osmo_funcs[] = {
        { "timeout",    lua_osmo_timeout },
        { "unix_passcred", lua_unix_passcred },
+       { "register_fd", lua_register_fd },
        { "ms", lua_osmo_ms },
        { NULL, NULL },
 };
@@ -510,6 +605,7 @@
        /* Create metatables so we can GC objects... */
        create_meta_table(L, "Timer", timer_funcs);
        create_meta_table(L, "MS", ms_funcs);
+       create_meta_table(L, "Fd", fd_funcs);

        /* Remember the primitive pointer... store it in the registry */
        lua_pushlightuserdata(L, lua_prim_key);

--
To view, visit https://gerrit.osmocom.org/10439
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings

Gerrit-Project: osmocom-bb
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: I8254bdda1df2f8fe0a5eac894b931e7de5b426df
Gerrit-Change-Number: 10439
Gerrit-PatchSet: 1
Gerrit-Owner: Holger Freyther <[email protected]>

Reply via email to