Commits

Jérôme Vuarand committed 9a02e72

Binding for some of the async API.

  • Participants
  • Parent commits 8bf4dd9

Comments (0)

Files changed (1)

 	return luausb_transfer_gc(L);
 }
 
+void luausb_transfer_cb(struct libusb_transfer* transfer)
+{
+	lua_State* L;
+	
+	L = transfer->user_data; /* buffer, callback, transfer */
+	
+	lua_pushvalue(L, -2); /* buffer, callback, transfer, callback */
+	lua_pushvalue(L, -2); /* buffer, callback, transfer, callback, transfer */
+	if (transfer->endpoint & LIBUSB_ENDPOINT_IN)
+		lua_pushlstring(L, transfer->buffer, transfer->actual_length);
+	else
+		lua_pushnumber(L, transfer->actual_length);
+	if (lua_pcall(L, 2, 0, 0))
+	{
+		fprintf(stderr, "%s\n", lua_tostring(L, -1));
+		lua_pop(L, 1);
+	}
+}
+
+BINDING(fill_interrupt_transfer)
+{
+	struct libusb_transfer* transfer;
+	libusb_device_handle* dev_handle;
+	unsigned char endpoint;
+	unsigned char* buffer;
+	int length;
+	libusb_transfer_cb_fn callback;
+	void* user_data;
+	unsigned int timeout;
+	lua_State* thread;
+	
+	transfer = luausb_check_transfer(L, 1);
+	dev_handle = luausb_check_device_handle(L, 2);
+	endpoint = (unsigned char)luaL_checknumber(L, 3); /* :FIXME: handle overflow */
+	if (endpoint & LIBUSB_ENDPOINT_IN)
+		luaL_checknumber(L, 4);
+	else
+		luaL_checkstring(L, 4);
+	luaL_checktype(L, 5, LUA_TFUNCTION);
+	timeout = (unsigned int)luaL_optnumber(L, 6, 0); /* :FIXME: handle overflow */
+	
+	thread = lua_newthread(L);
+	lua_pushlightuserdata(L, thread);
+	lua_insert(L, -2);
+	lua_settable(L, LUA_REGISTRYINDEX);
+	
+	/* extract actual arg 4 value into a buffer on the thread stack */
+	if (endpoint & LIBUSB_ENDPOINT_IN)
+	{
+		/* in endpoint */
+		length = (int)lua_tonumber(L, 4); /* :FIXME: handle overflow */
+		buffer = (unsigned char*)lua_newuserdata(thread, length);
+	}
+	else
+	{
+		/* out endpoint */
+		size_t len;
+		const char* str;
+		str = lua_tolstring(L, 4, &len);
+		length = (int)len; /* :FIXME: handle overflow */
+		buffer = (unsigned char*)lua_newuserdata(thread, length);
+		memcpy(buffer, str, len);
+	}
+	
+	/* copy the callback function onto the thread stack */
+	lua_pushvalue(L, 5);
+	lua_xmove(L, thread, 1);
+	
+	/* copy the transfer object onto the thread stack */
+	lua_pushvalue(L, 1);
+	lua_xmove(L, thread, 1);
+	
+	user_data = thread;
+	callback = luausb_transfer_cb;
+	
+	libusb_fill_interrupt_transfer(transfer, dev_handle, endpoint, buffer, length, callback, user_data, timeout);
+	
+	return 0;
+}
+
+BINDING(submit_transfer)
+{
+	struct libusb_transfer* transfer;
+	int result;
+	
+	transfer = luausb_check_transfer(L, 1);
+	
+	result = libusb_submit_transfer(transfer);
+	if (result != LIBUSB_SUCCESS)
+		return lua__usberror(L, result);
+	
+	lua_pushboolean(L, 1);
+	return 1;
+}
+
+BINDING(handle_events_completed)
+{
+	libusb_context* ctx;
+	int result;
+	
+	ctx = luausb_check_context(L, 1);
+	
+	result = libusb_handle_events_completed(ctx, NULL);
+	if (result != LIBUSB_SUCCESS)
+		return lua__usberror(L, result);
+	
+	lua_pushboolean(L, 1);
+	return 1;
+}
+
 /****************************************************************************/
 
 int luausb_get_interface_descriptor_endpoint(lua_State* L)
 	BIND(exit)
 	BIND(get_device_list)
 	BIND(open_device_with_vid_pid)
+	BIND(handle_events_completed)
 	{0, 0},
 };
 /*
 
 struct luaL_Reg libusb_transfer__methods[] = {
 	{"free", lua__libusb_free_transfer},
+	{"fill_interrupt", lua__libusb_fill_interrupt_transfer},
+	{"submit", lua__libusb_submit_transfer},
 	{0, 0},
 };