4 #include <aura/private.h>
9 #define REF_NODE_CONTAINER (1<<0)
10 #define REF_STATUS_CB (1<<1)
11 #define REF_ETABLE_CB (1<<2)
12 #define REF_EVENT_CB (1<<3)
17 #define TRACE() slog(4, SLOG_DEBUG, "Bindings call: %s", __func__)
22 #define aura_check_args(L, need) aura_do_check_args(L, __FUNCTION__, need)
24 #define laura_eventloop_type "laura_eventloop"
25 #define laura_node_type "laura_node"
27 extern int lua_stackdump(lua_State *L);
30 #if LUA_VERSION_NUM < 502
31 #warning Building with lua-5.1-compat hacks
34 #define luaL_setmetatable(L, name) \
35 luaL_getmetatable(L, name); \
36 lua_setmetatable(L, -2)
38 #define setfuncs(L, l) luaL_setfuncs(L, l, 0)
40 static void luaL_setfuncs (lua_State *L,
const luaL_Reg *l,
int nup) {
41 luaL_checkstack(L, nup+1,
"too many upvalues");
42 for (; l->name != NULL; l++) {
44 lua_pushstring(L, l->name);
45 for (i = 0; i < nup; i++)
46 lua_pushvalue(L, -(nup+1));
47 lua_pushcclosure(L, l->func, nup);
48 lua_settable(L, -(nup + 3));
53 #define luaL_newlib(L, l) \
54 (lua_newtable((L)),luaL_setfuncs((L), (l), 0))
66 struct aura_node *node;
67 const char *current_call;
70 int status_changed_ref;
71 int status_changed_arg_ref;
72 int inbound_event_ref;
73 int inbound_event_arg_ref;
76 struct laura_eventloop
78 struct aura_eventloop *loop;
81 static inline int check_node_and_push(lua_State *L,
struct aura_node *node)
84 struct laura_node *bdata = lua_newuserdata(L,
sizeof(*bdata));
86 return luaL_error(L,
"Memory allocation error");
87 bzero(bdata,
sizeof(*bdata));
91 luaL_setmetatable(L, laura_node_type);
99 #define PREPARE_ARG(n) \
100 const void *arg ## n ##_ptr; \
101 const int arg ## n ##_int; \
102 if (lua_gettop(L) > (1 + n)) { \
103 if (lua_isstring(L, (1 + n))) \
104 arg ## n ## _ptr = lua_tostring(L, (1 + n)); \
105 else if (lua_isnumber(L, (1 + n))) \
106 arg ## n ## _int = lua_tonumber(L, (1 + n)); \
110 #define ARG(n) (lua_isstring(L, 1 + n) ? arg ## n ## _ptr : arg ## n ## _int)
113 static int aura_typeerror (lua_State *L,
int narg,
const char *tname)
115 const char *msg = lua_pushfstring(L,
"%s expected, got %s",
116 tname, luaL_typename(L, narg));
117 return luaL_argerror(L, narg, msg);
120 static struct laura_node *lua_fetch_node(lua_State *L,
int idx) {
122 struct laura_node *lnode = NULL;
124 if (lua_isuserdata(L, idx))
125 lnode = lua_touserdata(L, idx);
126 else if (lua_istable(L, idx)) {
127 lua_pushstring(L,
"__node");
128 lua_gettable(L, idx);
129 lnode = lua_touserdata(L, -1);
135 static void aura_do_check_args (lua_State *L,
const char *func,
int need)
137 int got = lua_gettop(L);
139 luaL_error(L,
"%s expects %d args, %d given",
145 static void lua_setfield_string(lua_State *L,
const char *key,
const char *value)
147 lua_pushstring(L, key);
148 lua_pushstring(L, value);
152 static void lua_setfield_int(lua_State *L,
const char *key,
long value)
154 lua_pushstring(L, key);
155 lua_pushnumber(L, value);
159 static void lua_setfield_bool(lua_State *L,
const char *key,
bool value)
161 lua_pushstring(L, key);
162 lua_pushboolean(L, value);
166 static int lua_push_etable(lua_State *L,
struct aura_export_table *tbl)
175 for (i=0; i<tbl->next; i++) {
176 struct aura_object *o = &tbl->objects[i];
177 lua_pushinteger(L, i);
180 lua_setfield_string(L,
"name", o->name);
181 lua_setfield_bool(L,
"valid", o->valid);
182 lua_setfield_int(L,
"id", o->id);
184 lua_setfield_string(L,
"arg", o->arg_fmt);
186 lua_setfield_string(L,
"ret", o->ret_fmt);
188 lua_setfield_string(L,
"arg_pprint", o->arg_pprinted);
190 lua_setfield_string(L,
"ret_pprint", o->arg_pprinted);
197 static int buffer_to_lua(lua_State *L,
struct aura_node *node,
const struct aura_object *o,
struct aura_buffer *buf)
199 const char *fmt = o->ret_fmt;
207 lua_pushnumber(L, tmp);
211 lua_pushnumber(L, tmp);
215 lua_pushnumber(L, tmp);
219 lua_pushnumber(L, tmp);
223 lua_pushnumber(L, tmp);
227 lua_pushnumber(L, tmp);
231 lua_pushnumber(L, tmp);
235 lua_pushnumber(L, tmp);
244 BUG(node,
"Internal deserilizer bug processing: %s", fmt);
245 udata = lua_newuserdata(L, len);
247 BUG(node,
"Failed to allocate userdata");
249 memcpy(udata, srcdata, len);
250 while (*fmt && (*fmt++ !=
'.'));
254 BUG(node,
"Unexpected format token: %s", --fmt);
262 static struct aura_buffer *lua_to_buffer(lua_State *L,
struct aura_node *node,
int stackpos,
struct aura_object *o)
269 if (lua_gettop(L) - stackpos + 1 != o->num_args) {
270 slog(0, SLOG_ERROR,
"Invalid argument count for %s: %d / %d",
271 o->name, lua_gettop(L) - stackpos, o->num_args);
277 slog(0, SLOG_ERROR,
"Epic fail during buffer allocation");
285 for (i=stackpos; i<=lua_gettop(L); i++) {
290 tmp = lua_tonumber(L, i);
294 tmp = lua_tonumber(L, i);
298 tmp = lua_tonumber(L, i);
302 tmp = lua_tonumber(L, i);
306 tmp = lua_tonumber(L, i);
310 tmp = lua_tonumber(L, i);
314 tmp = lua_tonumber(L, i);
318 tmp = lua_tonumber(L, i);
325 const char *srcbuf = NULL;
328 if (lua_isstring(L, i)) {
329 srcbuf = lua_tostring(L, i);
330 len = strlen(srcbuf);
331 }
else if (lua_isuserdata(L, i)) {
332 srcbuf = lua_touserdata(L, i);
338 slog(0, SLOG_ERROR,
"Internal serilizer bug processing: %s", fmt);
343 slog(0, SLOG_ERROR,
"Internal bug fetching src pointer");
352 while (*fmt && (*fmt++ !=
'.'));
357 BUG(node,
"Unknown token: %c\n", *(--fmt));
368 static int l_open_node(lua_State *L)
370 struct aura_node *node;
373 aura_check_args(L, 2);
374 node =
aura_open(lua_tostring(L, 1), lua_tostring(L, 2));
376 return luaL_error(L,
"Failed to open node");
378 return check_node_and_push(L, node);
382 static int l_close_node(lua_State *L)
384 struct laura_node *lnode = lua_fetch_node(L, -1);
385 struct aura_node *node = lnode->node;
394 if (lnode->refs & REF_NODE_CONTAINER)
395 luaL_unref(L, LUA_REGISTRYINDEX, lnode->node_container);
397 if (lnode->refs & REF_STATUS_CB) {
398 luaL_unref(L, LUA_REGISTRYINDEX, lnode->status_changed_ref);
399 luaL_unref(L, LUA_REGISTRYINDEX, lnode->status_changed_arg_ref);
414 static int l_node_gc(lua_State *L)
416 return l_close_node(L);
419 static int laura_do_sync_call(lua_State *L){
421 struct laura_node *lnode = lua_fetch_node(L, 1);
423 struct aura_object *o;
427 o = aura_etable_find(lnode->node->tbl, lnode->current_call);
429 return luaL_error(L,
"Attempt to call non-existend method");
431 buf = lua_to_buffer(L, lnode->node, 2, o);
433 return luaL_error(L,
"Serializer failed!");
437 return luaL_error(L,
"Call for %s failed", o->name);
439 ret = buffer_to_lua(L, lnode->node, o, retbuf);
445 static void calldone_cb(
struct aura_node *node,
int status,
struct aura_buffer *retbuf,
void *arg)
447 struct laura_node *lnode;
449 const struct aura_object *o;
457 lua_rawgeti(L, LUA_REGISTRYINDEX, (
long) arg);
458 lua_pushnumber(L, 1);
461 lua_rawgeti(L, LUA_REGISTRYINDEX, lnode->node_container);
463 lua_pushnumber(L, status);
465 lua_pushnumber(L, 2);
468 buffer_to_lua(L, lnode->node, o, retbuf);
472 lua_call(L, 3 + o->num_rets, 0);
474 luaL_unref(L, LUA_REGISTRYINDEX, (
long) arg);
477 static int laura_do_async_call(lua_State *L){
478 struct laura_node *lnode = NULL;
481 struct aura_object *o;
488 lnode=lua_fetch_node(L, 1);
491 return aura_typeerror(L, 1,
"userdata (node)");
494 if (!lua_isstring(L, 2)) {
496 return aura_typeerror(L, 2,
"string (object name)");
499 if (!lua_isfunction(L, 3)) {
501 return aura_typeerror(L, 3,
"function (callback)");
504 name = lua_tostring(L, 2);
506 o = aura_etable_find(lnode->node->tbl, name);
508 return luaL_error(L,
"Attempt to call non-existend method");
510 if (!object_is_method(o)) {
512 return luaL_error(L,
"Attempt to call an event");
518 buf = lua_to_buffer(L, lnode->node, 5, o);
520 luaL_error(L,
"Serializer failed!");
526 lua_pushnumber(L, 1);
531 lua_pushnumber(L, 2);
536 callback_ref = luaL_ref(L, LUA_REGISTRYINDEX);
537 slog(4, SLOG_DEBUG,
"Callback tbl reference: %d", callback_ref);
542 return luaL_error(L,
"Async call for %s failed: %d:%s", o->name, ret, strerror(ret));
548 static int l_node_index(lua_State *L)
550 struct laura_node *lnode = lua_touserdata(L, 1);
551 const char *name = lua_tostring(L, -1);
552 struct aura_object *o;
556 lnode->current_call = name;
558 o = aura_etable_find(lnode->node->tbl, lnode->current_call);
560 if (strcmp(
"__", name)==0)
561 lua_pushcfunction(L, laura_do_async_call);
562 else if (object_is_method(o))
563 lua_pushcfunction(L, laura_do_sync_call);
571 static int l_etable_get(lua_State *L)
573 struct laura_node *lnode = NULL;
574 struct aura_node *node = NULL;
577 aura_check_args(L, 1);
579 if (lua_islightuserdata(L, 1)) {
580 node = lua_touserdata(L, 1);
582 lnode = lua_fetch_node(L, 1);
588 return luaL_error(L,
"Failed to fetch node");
590 return lua_push_etable(L, node->tbl);
594 static int l_etable_create (lua_State *L)
596 struct aura_node *node;
598 struct aura_export_table *tbl;
601 aura_check_args(L, 2);
602 if (!lua_islightuserdata(L, 1)) {
603 aura_typeerror(L, 1,
"ludata");
605 if (!lua_isnumber(L, 2)) {
606 aura_typeerror(L, 1,
"number");
609 node = lua_touserdata(L, 1);
610 count = lua_tonumber(L, 2);
611 tbl = aura_etable_create(node, count);
613 return luaL_error(L,
"error creating etable for %d elements", count);
615 lua_pushlightuserdata(L, tbl);
619 static int l_etable_add (lua_State *L)
621 struct aura_export_table *tbl;
622 const char *name, *arg, *ret;
625 aura_check_args(L, 4);
627 if (!lua_islightuserdata(L, 1)) {
628 aura_typeerror(L, 1,
"ludata");
630 if (!lua_isstring(L, 2)) {
631 aura_typeerror(L, 1,
"string");
633 if (!lua_isstring(L, 3)) {
634 aura_typeerror(L, 1,
"string");
636 if (!lua_isstring(L, 4)) {
637 aura_typeerror(L, 1,
"string");
640 tbl = lua_touserdata(L, 1);
641 name = lua_tostring(L, 2);
642 arg = lua_tostring(L, 3);
643 ret = lua_tostring(L, 4);
645 aura_etable_add(tbl, name, arg, ret);
649 static int l_etable_activate(lua_State *L)
651 struct aura_export_table *tbl;
654 aura_check_args(L, 1);
656 if (!lua_islightuserdata(L, 1)) {
657 aura_typeerror(L, 1,
"ludata");
660 tbl = lua_touserdata(L, 1);
661 aura_etable_activate(tbl);
666 static int l_eventloop_create(lua_State *L)
668 struct laura_node *lnode;
669 struct laura_eventloop *lloop;
673 lnode = lua_fetch_node(L, 1);
675 return luaL_error(L,
"Failed to fetch node");
677 lloop = lua_newuserdata(L,
sizeof(*lloop));
679 return luaL_error(L,
"Userdata allocation failed");
680 luaL_setmetatable(L, laura_eventloop_type);
689 static int l_eventloop_add(lua_State *L)
691 struct laura_node *lnode;
692 struct laura_eventloop *lloop;
695 aura_check_args(L, 2);
697 if (!lua_isuserdata(L, 1)) {
698 aura_typeerror(L, 1,
"ludata (eventloop)");
700 lnode = lua_fetch_node(L, 2);
702 lloop = lua_touserdata(L, 1);
703 if (!lloop || !lnode)
704 return luaL_error(L,
"Failed to retrive arguments");
711 static int l_eventloop_del(lua_State *L)
713 struct laura_node *lnode;
716 aura_check_args(L, 1);
718 lnode = lua_fetch_node(L, 1);
721 return luaL_error(L,
"Failed to retrive arguments");
727 static int l_eventloop_destroy(lua_State *L)
729 struct laura_eventloop *lloop;
732 aura_check_args(L, 1);
734 if (!lua_isuserdata(L, 1)) {
735 aura_typeerror(L, 2,
"ludata (eventloop)");
738 lloop = lua_touserdata(L, 1);
740 return luaL_error(L,
"Failed to retrive arguments");
751 static int l_slog_init(lua_State *L)
757 aura_check_args(L, 2);
758 fname = lua_tostring(L, 1);
759 level = lua_tonumber(L, 2);
760 slog_init(fname, level);
764 static int l_wait_status(lua_State *L)
766 struct laura_node *lnode;
768 aura_check_args(L, 2);
769 lnode = lua_fetch_node(L, 1);
774 static void event_cb(
struct aura_node *node,
struct aura_buffer *buf,
void *arg)
776 struct laura_node *lnode = arg;
777 lua_State *L = lnode->L;
783 lua_rawgeti(L, LUA_REGISTRYINDEX, lnode->node_container);
784 lua_pushstring(L, o->name);
787 if (!lua_isfunction(L, -1)) {
788 slog(0, SLOG_WARN,
"Dropping unhandled event: %s", o->name);
792 lua_rawgeti(L, LUA_REGISTRYINDEX, lnode->node_container);
794 nargs = buffer_to_lua(L, lnode->node, o, buf);
795 lua_call(L, nargs + 1, 0);
798 static int l_set_node_container(lua_State *L)
800 struct laura_node *lnode;
803 aura_check_args(L, 2);
804 if (!lua_isuserdata(L, 1)) {
805 aura_typeerror(L, 1,
"udata");
808 if (!lua_istable(L, 2)) {
809 aura_typeerror(L, 2,
"table");
812 lnode = lua_touserdata(L, 1);
813 lnode->node_container = luaL_ref(L, LUA_REGISTRYINDEX);
814 lnode->refs |= REF_NODE_CONTAINER;
821 static int l_status(lua_State *L)
823 struct laura_node *lnode;
826 aura_check_args(L, 1);
827 lnode = lua_fetch_node(L, 1);
829 return luaL_error(L,
"Failed to retrieve lnode");
835 static void status_cb(
struct aura_node *node,
int newstatus,
void *arg)
837 struct laura_node *lnode = arg;
838 lua_State *L = lnode->L;
839 lua_rawgeti(L, LUA_REGISTRYINDEX, lnode->status_changed_ref);
840 lua_rawgeti(L, LUA_REGISTRYINDEX, lnode->node_container);
841 lua_pushnumber(L, newstatus);
842 lua_rawgeti(L, LUA_REGISTRYINDEX, lnode->status_changed_arg_ref);
846 static int l_set_status_change_cb(lua_State *L)
848 struct laura_node *lnode;
849 struct aura_node *node;
852 aura_check_args(L, 3);
854 lnode = lua_fetch_node(L, 1);
856 return luaL_error(L,
"Failed to retrieve node");
860 if (!lua_isfunction(L, 2)) {
861 aura_typeerror(L, 2,
"function");
864 if (lnode->refs & REF_STATUS_CB)
866 luaL_unref(L, LUA_REGISTRYINDEX, lnode->status_changed_arg_ref);
867 luaL_unref(L, LUA_REGISTRYINDEX, lnode->status_changed_ref);
870 lnode->refs |= REF_STATUS_CB;
871 lnode->status_changed_arg_ref = luaL_ref(L, LUA_REGISTRYINDEX);
872 lnode->status_changed_ref = luaL_ref(L, LUA_REGISTRYINDEX);
878 static int l_handle_events(lua_State *L)
880 struct laura_eventloop *lloop;
884 aura_check_args(L, 1);
886 if (!lua_isuserdata(L, 1)) {
887 aura_typeerror(L, 1,
"ludata");
890 lloop = lua_touserdata(L, 1);
892 if (lua_gettop(L) == 2) {
893 timeout = lua_tonumber(L, 2);
902 static const luaL_Reg libfuncs[] = {
903 {
"slog_init", l_slog_init },
904 {
"etable_create", l_etable_create },
905 {
"etable_get", l_etable_get },
906 {
"etable_add", l_etable_add },
907 {
"etable_activate", l_etable_activate },
908 {
"core_open", l_open_node },
909 {
"core_close", l_close_node },
910 {
"wait_status", l_wait_status },
912 {
"status", l_status },
913 {
"status_cb", l_set_status_change_cb },
915 {
"set_node_containing_table", l_set_node_container },
916 {
"eventloop_create", l_eventloop_create },
917 {
"eventloop_add", l_eventloop_add },
918 {
"eventloop_del", l_eventloop_del },
919 {
"eventloop_destroy", l_eventloop_destroy },
921 {
"handle_events", l_handle_events },
932 static const struct luaL_Reg node_meta[] = {
933 {
"__gc", l_node_gc },
934 {
"__index", l_node_index },
939 static int l_loop_gc(lua_State *L)
941 slog(0, SLOG_WARN,
"GC on a evtloop: This shouldn't normally happen, but we'll close the node anyway");
942 return l_eventloop_destroy(L);
946 static const struct luaL_Reg loop_meta[] = {
947 {
"__gc", l_loop_gc },
952 LUALIB_API
int luaopen_auracore (lua_State *L)
954 luaL_newmetatable(L, laura_node_type);
955 luaL_setfuncs(L, node_meta, 0);
957 luaL_newmetatable(L, laura_eventloop_type);
958 luaL_setfuncs(L, loop_meta, 0);
960 luaL_newlib(L, libfuncs);
961 lua_setfield_int(L,
"STATUS_OFFLINE", AURA_STATUS_OFFLINE);
962 lua_setfield_int(L,
"STATUS_ONLINE", AURA_STATUS_ONLINE);
964 lua_setfield_int(L,
"CALL_COMPLETED", AURA_CALL_COMPLETED);
965 lua_setfield_int(L,
"CALL_TIMEOUT", AURA_CALL_TIMEOUT);
966 lua_setfield_int(L,
"CALL_TRANSPORT_FAIL", AURA_CALL_TRANSPORT_FAIL);
void aura_buffer_put_s16(struct aura_buffer *buf, int16_t value)
Put a signed 16 bit integer to aura buffer.
struct aura_buffer * aura_buffer_request(struct aura_node *nd, int size)
void aura_buffer_put_s32(struct aura_buffer *buf, int32_t value)
Put a signed 32 bit integer to aura buffer.
int aura_core_call(struct aura_node *node, struct aura_object *o, struct aura_buffer **retbuf, struct aura_buffer *argbuf)
#define aura_eventloop_create(...)
void aura_handle_events_forever(struct aura_eventloop *loop)
int64_t aura_buffer_get_s64(struct aura_buffer *buf)
Get a signed 64 bit integer from aura buffer.
void aura_buffer_put_u16(struct aura_buffer *buf, uint16_t value)
Put an unsigned 16 bit integer to aura buffer.
void aura_buffer_put_bin(struct aura_buffer *buf, const void *data, int len)
Copy data of len bytes to aura buffer from a buffer pointed by data.
void aura_eventloop_add(struct aura_eventloop *loop, struct aura_node *node)
void aura_wait_status(struct aura_node *node, int status)
int32_t aura_buffer_get_s32(struct aura_buffer *buf)
Get a signed 32 bit integer from aura buffer.
void aura_handle_events_timeout(struct aura_eventloop *loop, int timeout_ms)
int8_t aura_buffer_get_s8(struct aura_buffer *buf)
Get a signed 8 bit integer from aura buffer.
void aura_buffer_put_s8(struct aura_buffer *buf, int8_t value)
Put a signed 8 bit integer to aura buffer.
void aura_buffer_put_u32(struct aura_buffer *buf, uint32_t value)
Put an unsigned 32 bit integer to aura buffer.
void aura_buffer_put_u8(struct aura_buffer *buf, uint8_t value)
Put an unsigned 8 bit integer to aura buffer.
static int aura_get_status(struct aura_node *node)
static void aura_set_userdata(struct aura_node *node, void *udata)
uint32_t aura_buffer_get_u32(struct aura_buffer *buf)
Get an unsigned 32 bit integer from aura buffer.
uint16_t aura_buffer_get_u16(struct aura_buffer *buf)
Get an unsigned 16 bit integer from aura buffer.
void aura_buffer_put_u64(struct aura_buffer *buf, uint64_t value)
Put an unsigned 64 bit integer to aura buffer.
void aura_eventloop_destroy(struct aura_eventloop *loop)
uint8_t aura_buffer_get_u8(struct aura_buffer *buf)
Get an unsigned 8 bit integer from aura buffer.
struct aura_node * aura_open(const char *name, const char *opts)
const void * aura_buffer_get_bin(struct aura_buffer *buf, int len)
Get a pointer to the binary data block within buffer and advance internal pointer by len bytes...
void aura_buffer_put_s64(struct aura_buffer *buf, int64_t value)
Put a signed 64 bit integer to aura buffer.
void aura_eventloop_del(struct aura_node *node)
uint64_t aura_buffer_get_u64(struct aura_buffer *buf)
Get an unsigned 64 bit integer from aura buffer.
int aura_core_start_call(struct aura_node *node, struct aura_object *o, void(*calldonecb)(struct aura_node *dev, int status, struct aura_buffer *ret, void *arg), void *arg, struct aura_buffer *buf)
const struct aura_object * aura_get_current_object(struct aura_node *node)
Obtain the pointer to the current aura_object.
void aura_status_changed_cb(struct aura_node *node, void(*cb)(struct aura_node *node, int newstatus, void *arg), void *arg)
static void * aura_get_userdata(struct aura_node *node)
void aura_unhandled_evt_cb(struct aura_node *node, void(*cb)(struct aura_node *node, struct aura_buffer *buf, void *arg), void *arg)
int16_t aura_buffer_get_s16(struct aura_buffer *buf)
Get a signed 16 bit integer from aura buffer.
void aura_buffer_release(struct aura_buffer *buf)
void aura_close(struct aura_node *node)