<p>Holger Freyther has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/10439">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">WIP: Allow lua code to register a fd for reading with the runtime<br><br>To have bi-directional communication we can pass credentials to the<br>registry server and now we can register a callback when the registry<br>is sending data to us.<br><br>Change-Id: I8254bdda1df2f8fe0a5eac894b931e7de5b426df<br>---<br>M src/host/layer23/src/mobile/script_lua.c<br>1 file changed, 96 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/osmocom-bb refs/changes/39/10439/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/src/host/layer23/src/mobile/script_lua.c b/src/host/layer23/src/mobile/script_lua.c</span><br><span>index 4cfe55a..1cfa812 100644</span><br><span>--- a/src/host/layer23/src/mobile/script_lua.c</span><br><span>+++ b/src/host/layer23/src/mobile/script_lua.c</span><br><span>@@ -28,6 +28,7 @@</span><br><span> </span><br><span> #include <osmocom/bb/mobile/primitives.h></span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/select.h></span><br><span> #include <osmocom/vty/misc.h></span><br><span> </span><br><span> #include <sys/types.h></span><br><span>@@ -37,6 +38,12 @@</span><br><span>        int cb_ref;</span><br><span> };</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+struct fd_userdata {</span><br><span style="color: hsl(120, 100%, 40%);">+   struct lua_State *state;</span><br><span style="color: hsl(120, 100%, 40%);">+      struct osmo_fd fd;</span><br><span style="color: hsl(120, 100%, 40%);">+    int cb_ref;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static char lua_prim_key[] = "osmocom.org-mobile-prim";</span><br><span> </span><br><span> static struct mobile_prim_intf *get_primitive(lua_State *L)</span><br><span>@@ -430,6 +437,93 @@</span><br><span>     return 1;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static int lua_fd_cb(struct osmo_fd *fd, unsigned int what) {</span><br><span style="color: hsl(120, 100%, 40%);">+     struct fd_userdata *fdu;</span><br><span style="color: hsl(120, 100%, 40%);">+      lua_State *L;</span><br><span style="color: hsl(120, 100%, 40%);">+ int cb_ref;</span><br><span style="color: hsl(120, 100%, 40%);">+   int err;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if (!fd->data) {</span><br><span style="color: hsl(120, 100%, 40%);">+           LOGP(DLUA, LOGL_ERROR,</span><br><span style="color: hsl(120, 100%, 40%);">+                        "fd callback for fd(%d) but no lua callback\n", fd->fd);</span><br><span style="color: hsl(120, 100%, 40%);">+         return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   fdu = fd->data;</span><br><span style="color: hsl(120, 100%, 40%);">+    L = fdu->state;</span><br><span style="color: hsl(120, 100%, 40%);">+    cb_ref = fdu->cb_ref;</span><br><span style="color: hsl(120, 100%, 40%);">+      lua_rawgeti(L, LUA_REGISTRYINDEX, cb_ref);</span><br><span style="color: hsl(120, 100%, 40%);">+    luaL_unref(L, LUA_REGISTRYINDEX, cb_ref);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   lua_pushinteger(L, fd->fd);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      err = lua_pcall(L, 1, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+  if (err) {</span><br><span style="color: hsl(120, 100%, 40%);">+            LOGP(DLUA, LOGL_ERROR, "lua error: %s\n", lua_tostring(L, -1));</span><br><span style="color: hsl(120, 100%, 40%);">+             lua_pop(L, 1);</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Register the fd */</span><br><span style="color: hsl(120, 100%, 40%);">+static int lua_register_fd(lua_State *L)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    struct fd_userdata *fdu;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* fd, cb */</span><br><span style="color: hsl(120, 100%, 40%);">+  luaL_argcheck(L, lua_isnumber(L, -2), 1, "needs to be a filedescriptor");</span><br><span style="color: hsl(120, 100%, 40%);">+   luaL_argcheck(L, lua_isfunction(L, -1), 2, "Callback needs to be a function");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* Cretae a table so a user can unregister (and unregister on GC) */</span><br><span style="color: hsl(120, 100%, 40%);">+  fdu = lua_newuserdata(L, sizeof(*fdu));</span><br><span style="color: hsl(120, 100%, 40%);">+       fdu->state = L;</span><br><span style="color: hsl(120, 100%, 40%);">+    fdu->fd.fd = -1;</span><br><span style="color: hsl(120, 100%, 40%);">+   luaL_getmetatable(L, "Fd");</span><br><span style="color: hsl(120, 100%, 40%);">+ lua_setmetatable(L, -2);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* Set the filedescriptor */</span><br><span style="color: hsl(120, 100%, 40%);">+  fdu->fd.fd = (int) lua_tonumber(L, -3);</span><br><span style="color: hsl(120, 100%, 40%);">+    fdu->fd.cb = lua_fd_cb;</span><br><span style="color: hsl(120, 100%, 40%);">+    fdu->fd.when = BSC_FD_READ;</span><br><span style="color: hsl(120, 100%, 40%);">+        fdu->fd.data = fdu;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Assuming that an error here will lead to a GC */</span><br><span style="color: hsl(120, 100%, 40%);">+   if (osmo_fd_register(&fdu->fd) != 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+         fdu->cb_ref = LUA_NOREF;</span><br><span style="color: hsl(120, 100%, 40%);">+           lua_pushliteral(L, "Can't register the fd");</span><br><span style="color: hsl(120, 100%, 40%);">+            lua_error(L);</span><br><span style="color: hsl(120, 100%, 40%);">+         return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Take the callback and keep a reference to it */</span><br><span style="color: hsl(120, 100%, 40%);">+    lua_pushvalue(L, -2);</span><br><span style="color: hsl(120, 100%, 40%);">+ fdu->cb_ref = luaL_ref(L, LUA_REGISTRYINDEX);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    return 1;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int lua_fd_unregister(lua_State *L) {</span><br><span style="color: hsl(120, 100%, 40%);">+  struct fd_userdata *fdu;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    luaL_argcheck(L, lua_isuserdata(L, -1), 1, "No userdata");</span><br><span style="color: hsl(120, 100%, 40%);">+  fdu = lua_touserdata(L, -1);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        /* Unregister the fd and forget about the callback */</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_fd_unregister(&fdu->fd);</span><br><span style="color: hsl(120, 100%, 40%);">+  if (fdu->cb_ref != LUA_NOREF) {</span><br><span style="color: hsl(120, 100%, 40%);">+            luaL_unref(L, LUA_REGISTRYINDEX, fdu->cb_ref);</span><br><span style="color: hsl(120, 100%, 40%);">+             fdu->cb_ref = LUA_NOREF;</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+     return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static const struct luaL_Reg fd_funcs[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ { "unregister", lua_fd_unregister },</span><br><span style="color: hsl(120, 100%, 40%);">+        { "__gc", lua_fd_unregister },</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static const struct luaL_Reg ms_funcs[] = {</span><br><span>        { "imsi", lua_ms_imsi },</span><br><span>   { "imei", lua_ms_imei },</span><br><span>@@ -447,6 +541,7 @@</span><br><span> static const struct luaL_Reg osmo_funcs[] = {</span><br><span>    { "timeout",  lua_osmo_timeout },</span><br><span>  { "unix_passcred", lua_unix_passcred },</span><br><span style="color: hsl(120, 100%, 40%);">+     { "register_fd", lua_register_fd },</span><br><span>        { "ms",       lua_osmo_ms },</span><br><span>       { NULL, NULL },</span><br><span> };</span><br><span>@@ -510,6 +605,7 @@</span><br><span>  /* Create metatables so we can GC objects... */</span><br><span>      create_meta_table(L, "Timer", timer_funcs);</span><br><span>        create_meta_table(L, "MS", ms_funcs);</span><br><span style="color: hsl(120, 100%, 40%);">+       create_meta_table(L, "Fd", fd_funcs);</span><br><span> </span><br><span>  /* Remember the primitive pointer... store it in the registry */</span><br><span>     lua_pushlightuserdata(L, lua_prim_key);</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/10439">change 10439</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/10439"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: osmocom-bb </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>
<div style="display:none"> Gerrit-Change-Id: I8254bdda1df2f8fe0a5eac894b931e7de5b426df </div>
<div style="display:none"> Gerrit-Change-Number: 10439 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Holger Freyther <holger@freyther.de> </div>