libusb icon indicating copy to clipboard operation
libusb copied to clipboard

libusb_interrupt_transfer() Blocks Until All `length` Bytes Received

Open ewhac opened this issue 3 years ago • 6 comments

The documentation for libusb_interrupt_transfer() states the following:

For interrupt reads, the length field indicates the maximum length of data you are expecting to receive. If less data arrives than expected, this function will return that data, so be sure to check the transferred output parameter.

In my mind, the implication of this is that, the moment any data arrives before the timeout expires, libusb_interrupt_transfer() will return success and fill in transferred with the quantity of bytes actually received.

This is not what happens. Consider the following pseudo-code:

	/*  sizeof (struct dev_input_report) < sizeof (readbuf)  */
	struct dev_input_report *rep;
	int retval, retsiz;
	uint8_t readbuf[256];

	retval = libusb_interrupt_transfer (g_handle, LIBUSB_ENDPOINT_IN | DEV_ENDPOINT,
	                                    readbuf, sizeof (readbuf),
	                                    &retsiz, 0);
	if (!retval  &&  retsiz == sizeof (struct dev_input_report)) {
		rep = (struct dev_input_report *) readbuf;
		handle_report (rep);
	}

Based on the docs, the expectation is that libusb_interrupt_transfer() will block forever (timeout = 0) until something arrives. The first transferred bytes of readbuf will be filled with the report, and the function returns.

What actually happens is that libusb_interrupt_transfer() blocks until length bytes have been collected, which may require multiple reports -- not what you want when dealing with an interactive input device.

So either I'm misunderstanding something, or it would appear the docs are incorrect.

ewhac avatar Aug 24 '22 19:08 ewhac

Please provide debug logs.

tormodvolden avatar Aug 29 '22 22:08 tormodvolden

Is output from LIBUSB_DEBUG=4 sufficient?

ewhac avatar Sep 01 '22 18:09 ewhac

Yes, that is good, max output.

tormodvolden avatar Sep 01 '22 20:09 tormodvolden

Test program. This program attempts to locate a Logitech G13 "Gameboard" and get events from it. Compile with gcc libusbtest.c $(pkg-config --cflags --libs libusb-1.0)

#include <fcntl.h>
#include <linux/input.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <err.h>

#include <libusb.h>


#define	USB_VENDOR_ID_LOGITECH		0x046d
#define	USB_DEVICE_ID_LOGITECH_G13	(0xc21c)

#define	G13_ENDPOINT_KEY		1
#define	G13_ENDPOINT_LCD		2
#define	G13_REPORT_SIZE_KEY		8
#define	G13_REPORT_SIZE_LCD		0x3c0


struct g13_input_report {
	uint8_t	report_id;
	uint8_t	joy_x, joy_y;
	uint8_t	keybits[5];
};

libusb_context			*g_usbctx;
struct libusb_device_handle	*g_handle;


int
connect_g13 (void)
{
	libusb_device	**usbdevs;
	ssize_t		ndevs;
	int		retval;

	retval = libusb_init (&g_usbctx);
	if (retval < 0) {
		warn ("libusb init failed");
		return -1;
	}
	ndevs = libusb_get_device_list (g_usbctx, &usbdevs);
	if (ndevs < 0) {
		warn ("libusb_get_device_list failed");
		return -1;
	}

	for (int i = 0;  i < ndevs;  ++i) {
		struct libusb_device_descriptor desc;

		retval = libusb_get_device_descriptor (usbdevs[i], &desc);
		if (retval < 0) {
			warn ("failed to get descriptor %d", i);
			return -1;
		}
		printf ("Checking index %d:\n", i);
		printf ("   idVendor  = 0x%04hx\n", desc.idVendor);
		printf ("   idProduct = 0x%04hx\n", desc.idProduct);
		printf ("   bcdDevice = 0x%04hx\n", desc.bcdDevice);
		if (    desc.idVendor == USB_VENDOR_ID_LOGITECH
		    &&  desc.idProduct == USB_DEVICE_ID_LOGITECH_G13)
		{
			retval = libusb_open (usbdevs[i], &g_handle);
			if (retval < 0) {
				warn ("usb device open failed");
				return -1;
			}

			/*
			 * This seems a bit racy to me...
			 */
			if (libusb_set_auto_detach_kernel_driver (g_handle, 1) < 0) {
				if (libusb_kernel_driver_active (g_handle, 0)) {
					if (!libusb_detach_kernel_driver (g_handle, 0)) {
						warnx ("Kernel driver detached");
					}
				} else {
					printf ("no kernel driver attached.\n");
				}
			}
			retval = libusb_claim_interface (g_handle, 0);
			if (retval < 0) {
				warn ("Failed to claim usb device");
				return -1;
			}
		}
	}

	libusb_free_device_list (usbdevs, 1);

	return 0;
}

void
disconnect_g13 (void)
{
	if (g_handle) {
		libusb_release_interface (g_handle, 0);
		libusb_close (g_handle);
		g_handle = NULL;
	}
	if (g_usbctx) {
		libusb_exit (g_usbctx);
		g_usbctx = NULL;
	}
}



int
main (int ac, char **av)
{
	struct g13_input_report	*rep;
	int			uif;
	int			retval;
	int			retsiz;
	uint8_t			buf[256];

	retval = connect_g13();
	if (retval < 0) {
		errx (EXIT_FAILURE, "g13 connect failed");
	}

	for (;;) {
		retval = libusb_interrupt_transfer (g_handle, LIBUSB_ENDPOINT_IN | G13_ENDPOINT_KEY,
		                                    buf, sizeof (buf),
		                                    &retsiz, 0);
		if (retval) {
			warnx ("interrupt transfer returned %d", retval);
			if (retval == LIBUSB_ERROR_TIMEOUT)
				continue;
		}

		if (retsiz >= sizeof (*rep)) {
			rep = (struct g13_input_report *) buf;
			printf ("nbytes: %d, keybits = [ %02hhx %02hhx %02hhx %02hhx %02hhx ]\n",
				retsiz,
				rep->keybits[0], 
				rep->keybits[1], 
				rep->keybits[2], 
				rep->keybits[3], 
				rep->keybits[4]);
		}
	}

	disconnect_g13 ();
}

Output, after pressing/releasing a key on the G13 gameboard 16 times:

$ sudo LIBUSB_DEBUG=4 ./a.out 
[timestamp] [threadID] facility level [function call] <message>
--------------------------------------------------------------------------------
[ 0.000038] [000c280c] libusb: debug [libusb_init] libusb v1.0.26.11724
[ 0.000076] [000c280c] libusb: debug [usbi_add_event_source] add fd 3 events 1
[ 0.000088] [000c280c] libusb: debug [usbi_io_init] using timer for timeouts
[ 0.000092] [000c280c] libusb: debug [usbi_add_event_source] add fd 4 events 1
[ 0.000102] [000c280c] libusb: debug [get_kernel_version] reported kernel version is 5.18.0-4-amd64
[ 0.000130] [000c280c] libusb: debug [op_init] found usbfs at /dev/bus/usb
[ 0.000134] [000c280c] libusb: debug [op_init] max iso packet length is (likely) 98304 bytes
[ 0.000140] [000c280c] libusb: debug [op_init] sysfs is available
[ 0.000326] [000c280d] libusb: debug [linux_udev_event_thread_main] udev event thread entering
[ 0.010607] [000c280c] libusb: debug [linux_get_device_address] getting address for device: usb1 detached: 0
[ 0.010618] [000c280c] libusb: debug [linux_get_device_address] scan usb1
[ 0.010648] [000c280c] libusb: debug [linux_get_device_address] bus=1 dev=1
[ 0.010653] [000c280c] libusb: debug [linux_enumerate_device] busnum 1 devaddr 1 session_id 257
[ 0.010656] [000c280c] libusb: debug [linux_enumerate_device] allocating new device for 1/1 (session 257)
[ 0.010743] [000c280c] libusb: debug [linux_get_device_address] getting address for device: 1-10 detached: 0
[ 0.010750] [000c280c] libusb: debug [linux_get_device_address] scan 1-10
[ 0.010774] [000c280c] libusb: debug [linux_get_device_address] bus=1 dev=5
[ 0.010778] [000c280c] libusb: debug [linux_enumerate_device] busnum 1 devaddr 5 session_id 261
[ 0.010782] [000c280c] libusb: debug [linux_enumerate_device] allocating new device for 1/5 (session 261)
[ 0.010810] [000c280c] libusb: debug [linux_get_parent_info] dev 0x563aaa6e6360 (1-10) has parent 0x563aaa6e7b10 (usb1) port 10
[ 0.010879] [000c280c] libusb: debug [linux_get_device_address] getting address for device: 1-10.3 detached: 0
[ 0.010884] [000c280c] libusb: debug [linux_get_device_address] scan 1-10.3
[ 0.010909] [000c280c] libusb: debug [linux_get_device_address] bus=1 dev=9
[ 0.010912] [000c280c] libusb: debug [linux_enumerate_device] busnum 1 devaddr 9 session_id 265
[ 0.010914] [000c280c] libusb: debug [linux_enumerate_device] allocating new device for 1/9 (session 265)
[ 0.010941] [000c280c] libusb: debug [linux_get_parent_info] dev 0x563aaa6e5e30 (1-10.3) has parent 0x563aaa6e6360 (1-10) port 3
[ 0.011011] [000c280c] libusb: debug [linux_get_device_address] getting address for device: 1-10.4 detached: 0
[ 0.011016] [000c280c] libusb: debug [linux_get_device_address] scan 1-10.4
[ 0.011040] [000c280c] libusb: debug [linux_get_device_address] bus=1 dev=12
[ 0.011045] [000c280c] libusb: debug [linux_enumerate_device] busnum 1 devaddr 12 session_id 268
[ 0.011052] [000c280c] libusb: debug [linux_enumerate_device] allocating new device for 1/12 (session 268)
[ 0.011079] [000c280c] libusb: debug [linux_get_parent_info] dev 0x563aaa6e7bc0 (1-10.4) has parent 0x563aaa6e6360 (1-10) port 4
[ 0.011139] [000c280c] libusb: debug [linux_get_device_address] getting address for device: 1-11 detached: 0
[ 0.011144] [000c280c] libusb: debug [linux_get_device_address] scan 1-11
[ 0.011166] [000c280c] libusb: debug [linux_get_device_address] bus=1 dev=7
[ 0.011171] [000c280c] libusb: debug [linux_enumerate_device] busnum 1 devaddr 7 session_id 263
[ 0.011178] [000c280c] libusb: debug [linux_enumerate_device] allocating new device for 1/7 (session 263)
[ 0.011217] [000c280c] libusb: debug [linux_get_parent_info] dev 0x563aaa699ae0 (1-11) has parent 0x563aaa6e7b10 (usb1) port 11
[ 0.011286] [000c280c] libusb: debug [linux_get_device_address] getting address for device: 1-13 detached: 0
[ 0.011292] [000c280c] libusb: debug [linux_get_device_address] scan 1-13
[ 0.011315] [000c280c] libusb: debug [linux_get_device_address] bus=1 dev=10
[ 0.011319] [000c280c] libusb: debug [linux_enumerate_device] busnum 1 devaddr 10 session_id 266
[ 0.011323] [000c280c] libusb: debug [linux_enumerate_device] allocating new device for 1/10 (session 266)
[ 0.011346] [000c280c] libusb: debug [linux_get_parent_info] dev 0x563aaa6e6990 (1-13) has parent 0x563aaa6e7b10 (usb1) port 13
[ 0.011412] [000c280c] libusb: debug [linux_get_device_address] getting address for device: 1-13.1 detached: 0
[ 0.011417] [000c280c] libusb: debug [linux_get_device_address] scan 1-13.1
[ 0.011440] [000c280c] libusb: debug [linux_get_device_address] bus=1 dev=14
[ 0.011444] [000c280c] libusb: debug [linux_enumerate_device] busnum 1 devaddr 14 session_id 270
[ 0.011447] [000c280c] libusb: debug [linux_enumerate_device] allocating new device for 1/14 (session 270)
[ 0.011471] [000c280c] libusb: debug [linux_get_parent_info] dev 0x563aaa69a110 (1-13.1) has parent 0x563aaa6e6990 (1-13) port 1
[ 0.011533] [000c280c] libusb: debug [linux_get_device_address] getting address for device: 1-14 detached: 0
[ 0.011538] [000c280c] libusb: debug [linux_get_device_address] scan 1-14
[ 0.011573] [000c280c] libusb: debug [linux_get_device_address] bus=1 dev=13
[ 0.011577] [000c280c] libusb: debug [linux_enumerate_device] busnum 1 devaddr 13 session_id 269
[ 0.011580] [000c280c] libusb: debug [linux_enumerate_device] allocating new device for 1/13 (session 269)
[ 0.011602] [000c280c] libusb: debug [linux_get_parent_info] dev 0x563aaa69a1a0 (1-14) has parent 0x563aaa6e7b10 (usb1) port 14
[ 0.011661] [000c280c] libusb: debug [linux_get_device_address] getting address for device: 1-5 detached: 0
[ 0.011665] [000c280c] libusb: debug [linux_get_device_address] scan 1-5
[ 0.011690] [000c280c] libusb: debug [linux_get_device_address] bus=1 dev=2
[ 0.011695] [000c280c] libusb: debug [linux_enumerate_device] busnum 1 devaddr 2 session_id 258
[ 0.011697] [000c280c] libusb: debug [linux_enumerate_device] allocating new device for 1/2 (session 258)
[ 0.011720] [000c280c] libusb: debug [linux_get_parent_info] dev 0x563aaa69a230 (1-5) has parent 0x563aaa6e7b10 (usb1) port 5
[ 0.011778] [000c280c] libusb: debug [linux_get_device_address] getting address for device: 1-6 detached: 0
[ 0.011783] [000c280c] libusb: debug [linux_get_device_address] scan 1-6
[ 0.011807] [000c280c] libusb: debug [linux_get_device_address] bus=1 dev=16
[ 0.011811] [000c280c] libusb: debug [linux_enumerate_device] busnum 1 devaddr 16 session_id 272
[ 0.011813] [000c280c] libusb: debug [linux_enumerate_device] allocating new device for 1/16 (session 272)
[ 0.011837] [000c280c] libusb: debug [linux_get_parent_info] dev 0x563aaa69a9d0 (1-6) has parent 0x563aaa6e7b10 (usb1) port 6
[ 0.011895] [000c280c] libusb: debug [linux_get_device_address] getting address for device: 1-9 detached: 0
[ 0.011900] [000c280c] libusb: debug [linux_get_device_address] scan 1-9
[ 0.011924] [000c280c] libusb: debug [linux_get_device_address] bus=1 dev=4
[ 0.011928] [000c280c] libusb: debug [linux_enumerate_device] busnum 1 devaddr 4 session_id 260
[ 0.011930] [000c280c] libusb: debug [linux_enumerate_device] allocating new device for 1/4 (session 260)
[ 0.011954] [000c280c] libusb: debug [linux_get_parent_info] dev 0x563aaa69a500 (1-9) has parent 0x563aaa6e7b10 (usb1) port 9
[ 0.012015] [000c280c] libusb: debug [linux_get_device_address] getting address for device: 1-9.3 detached: 0
[ 0.012020] [000c280c] libusb: debug [linux_get_device_address] scan 1-9.3
[ 0.012044] [000c280c] libusb: debug [linux_get_device_address] bus=1 dev=6
[ 0.012048] [000c280c] libusb: debug [linux_enumerate_device] busnum 1 devaddr 6 session_id 262
[ 0.012051] [000c280c] libusb: debug [linux_enumerate_device] allocating new device for 1/6 (session 262)
[ 0.012074] [000c280c] libusb: debug [linux_get_parent_info] dev 0x563aaa69ac00 (1-9.3) has parent 0x563aaa69a500 (1-9) port 3
[ 0.012135] [000c280c] libusb: debug [linux_get_device_address] getting address for device: 1-9.4 detached: 0
[ 0.012140] [000c280c] libusb: debug [linux_get_device_address] scan 1-9.4
[ 0.012164] [000c280c] libusb: debug [linux_get_device_address] bus=1 dev=8
[ 0.012168] [000c280c] libusb: debug [linux_enumerate_device] busnum 1 devaddr 8 session_id 264
[ 0.012170] [000c280c] libusb: debug [linux_enumerate_device] allocating new device for 1/8 (session 264)
[ 0.012194] [000c280c] libusb: debug [linux_get_parent_info] dev 0x563aaa69aae0 (1-9.4) has parent 0x563aaa69a500 (1-9) port 4
[ 0.012258] [000c280c] libusb: debug [linux_get_device_address] getting address for device: 1-9.4.1 detached: 0
[ 0.012263] [000c280c] libusb: debug [linux_get_device_address] scan 1-9.4.1
[ 0.012287] [000c280c] libusb: debug [linux_get_device_address] bus=1 dev=11
[ 0.012291] [000c280c] libusb: debug [linux_enumerate_device] busnum 1 devaddr 11 session_id 267
[ 0.012294] [000c280c] libusb: debug [linux_enumerate_device] allocating new device for 1/11 (session 267)
[ 0.012330] [000c280c] libusb: debug [linux_get_parent_info] dev 0x563aaa69ae10 (1-9.4.1) has parent 0x563aaa69aae0 (1-9.4) port 1
[ 0.012389] [000c280c] libusb: debug [linux_get_device_address] getting address for device: usb2 detached: 0
[ 0.012394] [000c280c] libusb: debug [linux_get_device_address] scan usb2
[ 0.012418] [000c280c] libusb: debug [linux_get_device_address] bus=2 dev=1
[ 0.012422] [000c280c] libusb: debug [linux_enumerate_device] busnum 2 devaddr 1 session_id 513
[ 0.012424] [000c280c] libusb: debug [linux_enumerate_device] allocating new device for 2/1 (session 513)
[ 0.012505] [000c280c] libusb: debug [linux_get_device_address] getting address for device: 2-1 detached: 0
[ 0.012510] [000c280c] libusb: debug [linux_get_device_address] scan 2-1
[ 0.012535] [000c280c] libusb: debug [linux_get_device_address] bus=2 dev=2
[ 0.012539] [000c280c] libusb: debug [linux_enumerate_device] busnum 2 devaddr 2 session_id 514
[ 0.012541] [000c280c] libusb: debug [linux_enumerate_device] allocating new device for 2/2 (session 514)
[ 0.012566] [000c280c] libusb: debug [linux_get_parent_info] dev 0x563aaa69a710 (2-1) has parent 0x563aaa69bfd0 (usb2) port 1
[ 0.012625] [000c280c] libusb: debug [linux_get_device_address] getting address for device: 2-5 detached: 0
[ 0.012630] [000c280c] libusb: debug [linux_get_device_address] scan 2-5
[ 0.012651] [000c280c] libusb: debug [linux_get_device_address] bus=2 dev=3
[ 0.012655] [000c280c] libusb: debug [linux_enumerate_device] busnum 2 devaddr 3 session_id 515
[ 0.012657] [000c280c] libusb: debug [linux_enumerate_device] allocating new device for 2/3 (session 515)
[ 0.012680] [000c280c] libusb: debug [linux_get_parent_info] dev 0x563aaa69c1c0 (2-5) has parent 0x563aaa69bfd0 (usb2) port 5
[ 0.012742] [000c280c] libusb: debug [linux_get_device_address] getting address for device: 2-5.1 detached: 0
[ 0.012747] [000c280c] libusb: debug [linux_get_device_address] scan 2-5.1
[ 0.012769] [000c280c] libusb: debug [linux_get_device_address] bus=2 dev=5
[ 0.012773] [000c280c] libusb: debug [linux_enumerate_device] busnum 2 devaddr 5 session_id 517
[ 0.012775] [000c280c] libusb: debug [linux_enumerate_device] allocating new device for 2/5 (session 517)
[ 0.012798] [000c280c] libusb: debug [linux_get_parent_info] dev 0x563aaa69c0a0 (2-5.1) has parent 0x563aaa69c1c0 (2-5) port 1
[ 0.012859] [000c280c] libusb: debug [linux_get_device_address] getting address for device: 2-5.4 detached: 0
[ 0.012864] [000c280c] libusb: debug [linux_get_device_address] scan 2-5.4
[ 0.012886] [000c280c] libusb: debug [linux_get_device_address] bus=2 dev=6
[ 0.012889] [000c280c] libusb: debug [linux_enumerate_device] busnum 2 devaddr 6 session_id 518
[ 0.012892] [000c280c] libusb: debug [linux_enumerate_device] allocating new device for 2/6 (session 518)
[ 0.012916] [000c280c] libusb: debug [linux_get_parent_info] dev 0x563aaa69c130 (2-5.4) has parent 0x563aaa69c1c0 (2-5) port 4
[ 0.012974] [000c280c] libusb: debug [linux_get_device_address] getting address for device: 2-6 detached: 0
[ 0.012979] [000c280c] libusb: debug [linux_get_device_address] scan 2-6
[ 0.013001] [000c280c] libusb: debug [linux_get_device_address] bus=2 dev=4
[ 0.013005] [000c280c] libusb: debug [linux_enumerate_device] busnum 2 devaddr 4 session_id 516
[ 0.013009] [000c280c] libusb: debug [linux_enumerate_device] allocating new device for 2/4 (session 516)
[ 0.013031] [000c280c] libusb: debug [linux_get_parent_info] dev 0x563aaa69c2d0 (2-6) has parent 0x563aaa69bfd0 (usb2) port 6
[ 0.013089] [000c280c] libusb: debug [linux_get_device_address] getting address for device: usb3 detached: 0
[ 0.013094] [000c280c] libusb: debug [linux_get_device_address] scan usb3
[ 0.013118] [000c280c] libusb: debug [linux_get_device_address] bus=3 dev=1
[ 0.013122] [000c280c] libusb: debug [linux_enumerate_device] busnum 3 devaddr 1 session_id 769
[ 0.013126] [000c280c] libusb: debug [linux_enumerate_device] allocating new device for 3/1 (session 769)
[ 0.013199] [000c280c] libusb: debug [linux_get_device_address] getting address for device: usb4 detached: 0
[ 0.013205] [000c280c] libusb: debug [linux_get_device_address] scan usb4
[ 0.013227] [000c280c] libusb: debug [linux_get_device_address] bus=4 dev=1
[ 0.013230] [000c280c] libusb: debug [linux_enumerate_device] busnum 4 devaddr 1 session_id 1025
[ 0.013233] [000c280c] libusb: debug [linux_enumerate_device] allocating new device for 4/1 (session 1025)
[ 0.013428] [000c280c] libusb: warning [libusb_init] installing new context as implicit default
[ 0.013436] [000c280c] libusb: debug [libusb_get_device_list]  
[ 0.013445] [000c280c] libusb: debug [discovered_devs_append] need to increase capacity
[ 0.013454] [000c280c] libusb: debug [libusb_get_device_descriptor]  
Checking index 0:
   idVendor  = 0x1d6b
   idProduct = 0x0003
   bcdDevice = 0x0518
[ 0.013475] [000c280c] libusb: debug [libusb_get_device_descriptor]  
Checking index 1:
   idVendor  = 0x1d6b
   idProduct = 0x0002
   bcdDevice = 0x0518
[ 0.013483] [000c280c] libusb: debug [libusb_get_device_descriptor]  
Checking index 2:
   idVendor  = 0x174c
   idProduct = 0x3074
   bcdDevice = 0x0001
[ 0.013494] [000c280c] libusb: debug [libusb_get_device_descriptor]  
Checking index 3:
   idVendor  = 0x0bda
   idProduct = 0x0412
   bcdDevice = 0x0119
[ 0.013506] [000c280c] libusb: debug [libusb_get_device_descriptor]  
Checking index 4:
   idVendor  = 0x1e4e
   idProduct = 0x7102
   bcdDevice = 0x0100
[ 0.013519] [000c280c] libusb: debug [libusb_get_device_descriptor]  
Checking index 5:
   idVendor  = 0x0bda
   idProduct = 0x0411
   bcdDevice = 0x0119
[ 0.013528] [000c280c] libusb: debug [libusb_get_device_descriptor]  
Checking index 6:
   idVendor  = 0x0bda
   idProduct = 0x0301
   bcdDevice = 0x0124
[ 0.013537] [000c280c] libusb: debug [libusb_get_device_descriptor]  
Checking index 7:
   idVendor  = 0x1d6b
   idProduct = 0x0003
   bcdDevice = 0x0518
[ 0.013546] [000c280c] libusb: debug [libusb_get_device_descriptor]  
Checking index 8:
   idVendor  = 0x046d
   idProduct = 0x082d
   bcdDevice = 0x0011
[ 0.013557] [000c280c] libusb: debug [libusb_get_device_descriptor]  
Checking index 9:
   idVendor  = 0x0bda
   idProduct = 0x5412
   bcdDevice = 0x0119
[ 0.013565] [000c280c] libusb: debug [libusb_get_device_descriptor]  
Checking index 10:
   idVendor  = 0x0bda
   idProduct = 0x5400
   bcdDevice = 0x0107
[ 0.013575] [000c280c] libusb: debug [libusb_get_device_descriptor]  
Checking index 11:
   idVendor  = 0x0bda
   idProduct = 0x5411
   bcdDevice = 0x0119
[ 0.013595] [000c280c] libusb: debug [libusb_get_device_descriptor]  
Checking index 12:
   idVendor  = 0x067b
   idProduct = 0x2303
   bcdDevice = 0x0300
[ 0.013607] [000c280c] libusb: debug [libusb_get_device_descriptor]  
Checking index 13:
   idVendor  = 0x046d
   idProduct = 0xc21c
   bcdDevice = 0x0203
[ 0.013621] [000c280c] libusb: debug [libusb_open] open 1.2
[ 0.013645] [000c280c] libusb: debug [usbi_add_event_source] add fd 7 events 4
[ 0.013655] [000c280c] libusb: debug [libusb_claim_interface] interface 0
[ 0.013671] [000c280c] libusb: debug [libusb_get_device_descriptor]  
Checking index 14:
   idVendor  = 0x1b1c
   idProduct = 0x1b14
   bcdDevice = 0x0302
[ 0.013688] [000c280c] libusb: debug [libusb_get_device_descriptor]  
Checking index 15:
   idVendor  = 0x1b1c
   idProduct = 0x1b3b
   bcdDevice = 0x0102
[ 0.013702] [000c280c] libusb: debug [libusb_get_device_descriptor]  
Checking index 16:
   idVendor  = 0x0000
   idProduct = 0x0000
   bcdDevice = 0x3298
[ 0.013718] [000c280c] libusb: debug [libusb_get_device_descriptor]  
Checking index 17:
   idVendor  = 0x1b1c
   idProduct = 0x0c0b
   bcdDevice = 0x000a
[ 0.013733] [000c280c] libusb: debug [libusb_get_device_descriptor]  
Checking index 18:
   idVendor  = 0x1b1c
   idProduct = 0x1b11
   bcdDevice = 0x0308
[ 0.013751] [000c280c] libusb: debug [libusb_get_device_descriptor]  
Checking index 19:
   idVendor  = 0x0ac8
   idProduct = 0x3420
   bcdDevice = 0x0413
[ 0.013765] [000c280c] libusb: debug [libusb_get_device_descriptor]  
Checking index 20:
   idVendor  = 0x174c
   idProduct = 0x2074
   bcdDevice = 0x0001
[ 0.013782] [000c280c] libusb: debug [libusb_get_device_descriptor]  
Checking index 21:
   idVendor  = 0x1d6b
   idProduct = 0x0002
   bcdDevice = 0x0518
[ 0.013801] [000c280c] libusb: debug [libusb_submit_transfer] transfer 0x563aaa6ce420
[ 0.013809] [000c280c] libusb: debug [submit_bulk_transfer] need 1 urbs for new transfer with length 256
[ 0.013829] [000c280c] libusb: debug [libusb_handle_events_timeout_completed] doing our own event handling
[ 0.013835] [000c280c] libusb: debug [handle_events] event sources modified, reallocating event data
[ 0.013843] [000c280c] libusb: debug [usbi_wait_for_events] poll() 3 fds with timeout in 60000ms
[ ==== Press/release key on G13 16 times here ==== ]
[ 7.643531] [000c280c] libusb: debug [usbi_wait_for_events] poll() returned 1
[ 7.643565] [000c280c] libusb: debug [reap_for_handle] urb type=1 status=0 transferred=256
[ 7.643575] [000c280c] libusb: debug [handle_bulk_completion] handling completion status 0 of bulk urb 1/1
[ 7.643584] [000c280c] libusb: debug [handle_bulk_completion] all URBs in transfer reaped --> complete!
[ 7.643590] [000c280c] libusb: debug [usbi_handle_transfer_completion] transfer 0x563aaa6ce420 has callback 0x7fa53bda89d0
[ 7.643597] [000c280c] libusb: debug [sync_transfer_cb] actual_length=256
[ 7.643613] [000c280c] libusb: debug [libusb_free_transfer] transfer 0x563aaa6ce420
nbytes: 256, keybits = [ 00 00 82 00 80 ]
[ 7.643636] [000c280c] libusb: debug [libusb_submit_transfer] transfer 0x563aaa6e1850
[ 7.643644] [000c280c] libusb: debug [submit_bulk_transfer] need 1 urbs for new transfer with length 256
[ 7.643665] [000c280c] libusb: debug [libusb_handle_events_timeout_completed] doing our own event handling
[ 7.643674] [000c280c] libusb: debug [usbi_wait_for_events] poll() 3 fds with timeout in 60000ms
^C

ewhac avatar Sep 02 '22 03:09 ewhac

If you are working with a HID device, maybe you should consider using HIDAPI instead: https://github.com/libusb/libusb/wiki/FAQ#does-libusb-support-usb-hid-devices I don't know if that would solve this issue though.

tormodvolden avatar Sep 03 '22 10:09 tormodvolden

The HID descriptor reported by the G13 is essentially meaningless, so it has to be parsed "by hand:"

0x06, 0x00, 0xFF,  // Usage Page (Vendor Defined 0xFF00)
0x09, 0x00,        // Usage (0x00)
0xA1, 0x01,        // Collection (Application)
0x15, 0x00,        //   Logical Minimum (0)
0x26, 0xFF, 0x00,  //   Logical Maximum (255)
0x09, 0x01,        //   Usage (0x01)
0x85, 0x01,        //   Report ID (1)
0x95, 0x07,        //   Report Count (7)
0x75, 0x08,        //   Report Size (8)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x85, 0x03,        //   Report ID (3)
0x09, 0x02,        //   Usage (0x02)
0x96, 0xDF, 0x03,  //   Report Count (991)
0x91, 0x02,        //   Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x07,        //   Report ID (7)
0x09, 0x03,        //   Usage (0x03)
0x95, 0x04,        //   Report Count (4)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x04,        //   Report ID (4)
0x09, 0x04,        //   Usage (0x04)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x05,        //   Report ID (5)
0x09, 0x05,        //   Usage (0x05)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x85, 0x06,        //   Report ID (6)
0x09, 0x06,        //   Usage (0x06)
0x96, 0x01, 0x01,  //   Report Count (257)
0xB1, 0x02,        //   Feature (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              // End Collection

// 61 bytes

ewhac avatar Sep 04 '22 09:09 ewhac