18 #include <libubox/blobmsg.h>
19 #include <libubox/blobmsg_json.h>
23 #define MODNAME "ubus"
24 #define METANAME MODNAME ".meta"
60 struct blob_attr *pos;
64 __blob_for_each_attr(pos, attr, rem)
71 lua_rawseti(L, -2, idx++);
84 if (!blobmsg_check_attr(attr,
false))
87 if (table && blobmsg_name(attr)[0])
89 lua_pushstring(L, blobmsg_name(attr));
93 data = blobmsg_data(attr);
94 len = blobmsg_data_len(attr);
96 switch (blob_id(attr))
98 case BLOBMSG_TYPE_BOOL:
99 lua_pushboolean(L, *(uint8_t *)data);
102 case BLOBMSG_TYPE_INT16:
103 lua_pushinteger(L, be16_to_cpu(*(uint16_t *)data));
106 case BLOBMSG_TYPE_INT32:
107 lua_pushinteger(L, be32_to_cpu(*(uint32_t *)data));
110 case BLOBMSG_TYPE_INT64:
111 lua_pushnumber(L, (
double) be64_to_cpu(*(uint64_t *)data));
114 case BLOBMSG_TYPE_DOUBLE:
120 v.u64 = be64_to_cpu(*(uint64_t *)data);
121 lua_pushnumber(L, v.d);
125 case BLOBMSG_TYPE_STRING:
126 lua_pushstring(L, data);
129 case BLOBMSG_TYPE_ARRAY:
133 case BLOBMSG_TYPE_TABLE:
153 for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1))
156 if (lua_type(L, -2) != LUA_TNUMBER && lua_type(L, -2) != LUA_TINT)
158 if (lua_type(L, -2) != LUA_TNUMBER)
165 cur = lua_tointeger(L, -2);
167 if ((cur - 1) != prv)
187 const char *key = table ? lua_tostring(L, -2) : NULL;
189 switch (lua_type(L, -1))
192 blobmsg_add_u8(
b, key, (uint8_t)lua_toboolean(L, -1));
199 if ((uint64_t)lua_tonumber(L, -1) > INT_MAX)
200 blobmsg_add_u64(
b, key, (uint64_t)lua_tonumber(L, -1));
202 blobmsg_add_u32(
b, key, (uint32_t)lua_tointeger(L, -1));
207 case LUA_TLIGHTUSERDATA:
208 blobmsg_add_string(
b, key, lua_tostring(L, -1));
214 c = blobmsg_open_array(
b, key);
216 blobmsg_close_array(
b, c);
220 c = blobmsg_open_table(
b, key);
222 blobmsg_close_table(
b, c);
237 for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1))
254 const char *sockpath = luaL_optstring(L, 1, NULL);
255 int timeout = luaL_optint(L, 2, 30);
257 if ((c = lua_newuserdata(L,
sizeof(*c))) != NULL &&
262 memset(&c->
buf, 0,
sizeof(c->
buf));
264 lua_setmetatable(L, -2);
278 lua_State *L = (lua_State *)p;
280 lua_pushstring(L, o->
path);
281 lua_rawseti(L, -2, lua_objlen(L, -2) + 1);
289 const char *
path = (lua_gettop(L) >= 2) ? luaL_checkstring(L, 2) : NULL;
298 lua_pushinteger(L, rv);
308 struct blob_attr *msg)
313 lua_getglobal(
state,
"__ubus_cb");
314 lua_rawgeti(
state, -1,
o->r);
315 lua_getfield(
state, -1, method);
316 lua_remove(
state, -2);
317 lua_remove(
state, -2);
319 if (lua_isfunction(
state, -1)) {
320 lua_pushlightuserdata(
state, req);
325 lua_call(
state, 2, 1);
326 if (lua_isnumber(
state, -1))
327 rv = lua_tonumber(
state, -1);
341 while (lua_next(L, index) != 0) {
354 luaL_checktype(L, 3, LUA_TTABLE);
355 blob_buf_init(&c->
buf, 0);
364 req = lua_touserdata(L, 2);
384 int ret = luaL_checkinteger(L, 3);
392 struct blobmsg_policy *p;
397 lua_pushinteger(L, 1);
401 lua_pushinteger(L, 2);
405 if ((lua_type(L, -2) != LUA_TFUNCTION) ||
406 (lua_type(L, -1) != LUA_TTABLE) ||
413 lua_pushvalue(L, -2);
414 lua_setfield(L, -6, lua_tostring(L, -5));
416 m->
name = lua_tostring(L, -4);
428 p = calloc(plen,
sizeof(
struct blobmsg_policy));
434 while (lua_next(L, -2) != 0) {
435 int val = lua_tointeger(L, -1);
438 if ((lua_type(L, -2) != LUA_TSTRING) ||
439 (lua_type(L, -1) != LUA_TNUMBER) ||
441 (val > BLOBMSG_TYPE_LAST)) {
445 p[pidx].name = lua_tostring(L, -2);
464 lua_getglobal(
state,
"__ubus_cb_publisher");
466 lua_remove(
state, -2);
468 if (lua_isfunction(
state, -1)) {
470 lua_call(
state, 1, 0);
480 lua_getglobal(L,
"__ubus_cb_publisher");
481 lua_pushvalue(L, -2);
502 obj->
o.
name = lua_tostring(L, -2);
520 lua_createtable(L, 1, 0);
521 lua_getglobal(L,
"__ubus_cb");
522 lua_pushvalue(L, -2);
523 obj->
r = luaL_ref(L, -2);
528 while (lua_next(L, -3) != 0) {
530 if( lua_type( L, -2 ) == LUA_TSTRING &&
531 lua_type( L, -1 ) == LUA_TFUNCTION ){
532 if( !strcmp( lua_tostring( L, -2 ),
"__subscriber_cb" ) )
537 if ((lua_type(L, -2) != LUA_TSTRING) ||
538 (lua_type(L, -1) != LUA_TTABLE) ||
539 !lua_objlen(L, -1)) {
562 if (lua_istable(L, 1)) {
563 lua_pushstring(L,
"you need to pass a table");
569 while (lua_next(L, -2) != 0) {
573 if ((lua_type(L, -2) == LUA_TSTRING) && (lua_type(L, -1) == LUA_TTABLE)) {
580 lua_pushstring(
state,
"__ubusobj");
581 lua_pushlightuserdata(
state, obj);
582 lua_settable(
state,-3);
598 c = luaL_checkudata(L, 1,
METANAME);
599 method = luaL_checkstring(L, 3);
600 luaL_checktype(L, 4, LUA_TTABLE);
602 if( !lua_islightuserdata( L, 2 ) ){
603 lua_pushfstring( L,
"Invald 2nd parameter, expected ubus obj ref" );
604 return lua_error( L );
606 obj = lua_touserdata( L, 2 );
609 blob_buf_init(&c->
buf, 0);
611 lua_pushfstring( L,
"Invalid 4th parameter, expected table of arguments" );
612 return lua_error( L );
622 lua_State *L = (lua_State *)p;
635 const char *
path = luaL_checkstring(L, 2);
643 lua_pushinteger(L, rv);
654 lua_State *L = (lua_State *)req->
priv;
669 const char *
path = luaL_checkstring(L, 2);
670 const char *func = luaL_checkstring(L, 3);
672 luaL_checktype(L, 4, LUA_TTABLE);
673 blob_buf_init(&c->
buf, 0);
687 lua_pushinteger(L, rv);
698 lua_pushinteger(L, rv);
702 return lua_gettop(L) - top;
707 const char *
type,
struct blob_attr *msg)
711 lua_getglobal(
state,
"__ubus_cb_event");
712 lua_rawgeti(
state, -1, listener->
r);
713 lua_remove(
state, -2);
715 if (lua_isfunction(
state, -1)) {
717 lua_call(
state, 1, 0);
735 lua_getglobal(L,
"__ubus_cb_event");
736 lua_pushvalue(L, -2);
737 event->r = luaL_ref(L, -2);
738 lua_setfield(L, -1, lua_tostring(L, -3));
748 luaL_checktype(L, 2, LUA_TTABLE);
752 while (lua_next(L, -2) != 0) {
756 if ((lua_type(L, -2) == LUA_TSTRING) && (lua_type(L, -1) == LUA_TFUNCTION)) {
758 if(listener != NULL) {
775 lua_getglobal(
state,
"__ubus_cb_subscribe");
777 lua_remove(
state, -2);
779 if (lua_isfunction(
state, -1)) {
780 lua_call(
state, 0, 0);
789 struct blob_attr *msg)
797 lua_getglobal(
state,
"__ubus_cb_subscribe");
799 lua_remove(
state, -2);
801 if (lua_isfunction(
state, -1)) {
807 lua_pushstring(
state, method);
808 lua_call(
state, 2, 0);
820 int idxnotify,
int idxremove )
827 lua_pushfstring( L,
"Unable find target, status=%d", status );
828 return lua_error( L );
833 lua_pushstring( L,
"Out of memory" );
834 return lua_error( L );
838 lua_getglobal(L,
"__ubus_cb_subscribe");
839 lua_pushvalue(L, idxnotify);
840 sub->
rnotify = luaL_ref(L, -2);
846 lua_getglobal(L,
"__ubus_cb_subscribe");
847 lua_pushvalue(L, idxremove);
848 sub->
rremove = luaL_ref(L, -2);
854 lua_pushfstring( L,
"Failed to register subscriber, status=%d", status );
855 return lua_error( L );
859 lua_pushfstring( L,
"Failed to register subscriber, status=%d", status );
860 return lua_error( L );
868 int idxnotify, idxremove, stackstart;
872 idxnotify = idxremove = 0;
873 stackstart = lua_gettop( L );
876 c = luaL_checkudata(L, 1,
METANAME);
877 target = luaL_checkstring(L, 2);
878 luaL_checktype(L, 3, LUA_TTABLE);
881 lua_pushstring( L,
"notify");
882 lua_gettable( L, 3 );
883 if( lua_type( L, -1 ) == LUA_TFUNCTION ){
884 idxnotify = lua_gettop( L );
889 lua_pushstring( L,
"remove");
890 lua_gettable( L, 3 );
891 if( lua_type( L, -1 ) == LUA_TFUNCTION ){
892 idxremove = lua_gettop( L );
900 if( lua_gettop( L ) > stackstart )
901 lua_pop( L, lua_gettop( L ) - stackstart );
910 const char *
event = luaL_checkstring(L, 2);
913 return luaL_argerror(L, 2,
"no event name");
916 luaL_checktype(L, 3, LUA_TTABLE);
917 blob_buf_init(&c->
buf, 0);
938 blob_buf_free(&c->
buf);
942 memset(c, 0,
sizeof(*c));
948 static const luaL_Reg
ubus[] = {
976 lua_pushvalue(L, -1);
977 lua_setfield(L, -2,
"__index");
980 luaL_register(L, NULL,
ubus);
987 lua_pushinteger(L, BLOBMSG_TYPE_ARRAY);
988 lua_setfield(L, -2,
"ARRAY");
989 lua_pushinteger(L, BLOBMSG_TYPE_TABLE);
990 lua_setfield(L, -2,
"TABLE");
991 lua_pushinteger(L, BLOBMSG_TYPE_STRING);
992 lua_setfield(L, -2,
"STRING");
993 lua_pushinteger(L, BLOBMSG_TYPE_INT64);
994 lua_setfield(L, -2,
"INT64");
995 lua_pushinteger(L, BLOBMSG_TYPE_INT32);
996 lua_setfield(L, -2,
"INT32");
997 lua_pushinteger(L, BLOBMSG_TYPE_INT16);
998 lua_setfield(L, -2,
"INT16");
999 lua_pushinteger(L, BLOBMSG_TYPE_INT8);
1000 lua_setfield(L, -2,
"INT8");
1001 lua_pushinteger(L, BLOBMSG_TYPE_DOUBLE);
1002 lua_setfield(L, -2,
"DOUBLE");
1003 lua_pushinteger(L, BLOBMSG_TYPE_BOOL);
1004 lua_setfield(L, -2,
"BOOLEAN");
1010 lua_createtable(L, 1, 0);
1011 lua_setglobal(L,
"__ubus_cb");
1014 lua_createtable(L, 1, 0);
1015 lua_setglobal(L,
"__ubus_cb_event");
1018 lua_createtable(L, 1, 0);
1019 lua_setglobal(L,
"__ubus_cb_subscribe");
1022 lua_createtable(L, 1, 0);
1023 lua_setglobal(L,
"__ubus_cb_publisher");
static struct ubus_context * ctx
int ubus_add_object(struct ubus_context *ctx, struct ubus_object *obj)
void ubus_complete_deferred_request(struct ubus_context *ctx, struct ubus_request_data *req, int ret)
int ubus_notify(struct ubus_context *ctx, struct ubus_object *obj, const char *type, struct blob_attr *msg, int timeout)
int ubus_send_reply(struct ubus_context *ctx, struct ubus_request_data *req, struct blob_attr *msg)
int ubus_subscribe(struct ubus_context *ctx, struct ubus_subscriber *obj, uint32_t id)
int ubus_register_subscriber(struct ubus_context *ctx, struct ubus_subscriber *s)
struct ubus_context * ubus_connect(const char *path)
int ubus_lookup(struct ubus_context *ctx, const char *path, ubus_lookup_handler_t cb, void *priv)
int ubus_send_event(struct ubus_context *ctx, const char *id, struct blob_attr *data)
void ubus_free(struct ubus_context *ctx)
int ubus_lookup_id(struct ubus_context *ctx, const char *path, uint32_t *id)
int ubus_register_event_handler(struct ubus_context *ctx, struct ubus_event_handler *ev, const char *pattern)
static void ubus_defer_request(struct ubus_context *ctx, struct ubus_request_data *req, struct ubus_request_data *new_req)
static void ubus_add_uloop(struct ubus_context *ctx)
static int ubus_invoke(struct ubus_context *ctx, uint32_t obj, const char *method, struct blob_attr *msg, ubus_data_handler_t cb, void *priv, int timeout)
struct ubus_context * ctx
struct ubus_event_handler e
const struct blobmsg_policy * policy
struct blob_attr * signature
const struct ubus_method * methods
struct ubus_object_type * type
const struct ubus_method * methods
ubus_state_handler_t subscribe_cb
ubus_remove_handler_t remove_cb
static void ubus_event_handler(struct ubus_context *ctx, struct ubus_event_handler *ev, const char *type, struct blob_attr *msg)
static void ubus_lua_signatures_cb(struct ubus_context *c, struct ubus_object_data *o, void *p)
static void ubus_sub_remove_handler(struct ubus_context *ctx, struct ubus_subscriber *s, uint32_t id)
static int ubus_lua_do_subscribe(struct ubus_context *ctx, lua_State *L, const char *target, int idxnotify, int idxremove)
static int ubus_lua_subscribe(lua_State *L)
static int ubus_lua_connect(lua_State *L)
static bool ubus_lua_format_blob_is_array(lua_State *L)
static void ubus_lua_load_newsub_cb(lua_State *L, struct ubus_lua_object *obj)
static const luaL_Reg ubus[]
static struct ubus_object * ubus_lua_load_object(lua_State *L)
static int ubus_lua_signatures(lua_State *L)
static int ubus_lua_format_blob(lua_State *L, struct blob_buf *b, bool table)
static int ubus_lua_send(lua_State *L)
static int ubus_lua_format_blob_array(lua_State *L, struct blob_buf *b, bool table)
static int ubus_lua_defer_request(lua_State *L)
static void ubus_new_sub_cb(struct ubus_context *ctx, struct ubus_object *obj)
static int ubus_sub_notify_handler(struct ubus_context *ctx, struct ubus_object *obj, struct ubus_request_data *req, const char *method, struct blob_attr *msg)
static int ubus_lua_complete_deferred_request(lua_State *L)
static int ubus_lua_reply(lua_State *L)
static int ubus_lua_load_methods(lua_State *L, struct ubus_method *m)
static int ubus_lua__gc(lua_State *L)
static void ubus_lua_call_cb(struct ubus_request *req, int type, struct blob_attr *msg)
int luaopen_ubus(lua_State *L)
static void ubus_lua_objects_cb(struct ubus_context *c, struct ubus_object_data *o, void *p)
static int ubus_lua_listen(lua_State *L)
static struct ubus_event_handler * ubus_lua_load_event(lua_State *L)
static int ubus_lua_objects(lua_State *L)
static int ubus_lua_parse_blob_array(lua_State *L, struct blob_attr *attr, size_t len, bool table)
static int lua_gettablelen(lua_State *L, int index)
static int ubus_method_handler(struct ubus_context *ctx, struct ubus_object *obj, struct ubus_request_data *req, const char *method, struct blob_attr *msg)
static int ubus_lua_call(lua_State *L)
static int ubus_lua_parse_blob(lua_State *L, struct blob_attr *attr, bool table)
static int ubus_lua_notify(lua_State *L)
static int ubus_lua_add(lua_State *L)
@ UBUS_STATUS_INVALID_ARGUMENT
@ UBUS_STATUS_UNKNOWN_ERROR