xairy/raw-gadget

can not receive URB_INTERRUPT OUT data from pc to hid device

imatespl opened this issue · 16 comments

hi,@xairy I have a atm cardreader,which is a hid device, and I use usb-proxy proxy to windows 10 , windows 10 need send URB_INTERRUPT OUT to atm cardreader, to drive motor rotation,but the endpoint 0x02 can not received any data,ep0 and
0x81 work good,it may usb_raw_ep_read(fd, (struct usb_raw_ep_io *)&io); can not work with URB_INTERRUPT OUT? I test on
raspberrypi4 and orangepi pc. thank you very much.

this is the data send, report id is 04, data is 000443303131

HID Data: 040004433031310000000000000000000000000000000000000000000000000000000000…

0000   1b 00 a0 79 3d 99 0a e7 ff ff 00 00 00 00 09 00   ...y=...........
0010   00 02 00 13 00 02 01 40 00 00 00 04 00 04 43 30   .......@......C0
0020   31 31 00 00 00 00 00 00 00 00 00 00 00 00 00 00   11..............
0030   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
0040   00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
0050   00 00 00 00 00 00 00 00 00 00 00                  ...........

the hid report response is this in wireshark

0x06 0xa0 0xff  //Usage Page (Vendor)
0x09 0x01 		//Usage (Vendor)
//Collection (Application)
0xa1 0x01 		//header Collection type: Application (0x01)
0x09 0x01 		//Usage (Vendor)
	//Collection (Physical)
	0xa1 0x00 		//header Collection type: Physical (0x00)
	0x85 0x04 		//Report ID (0x04)
	0x09 0x02 		//Usage (Vendor)
	0x15 0x00		//Logical Minimum (0) 
	0x26 0xff 0x00 	//Logical Maximum (255)
	0x75 0x08 		//Report Size (8)
	0x95 0x3f 		//Report Count (63)
	0x82 0x02 0x01 	//Input (Data,Var,Abs)
	0x85 0x04 		//Report ID (0x04)
	0x09 0x04 		//Usage (Vendor)
	0x75 0x08 		//Report Size (8)
	0x95 0x3f 		//Report Count (63)
	0x92 0x02 0x01 	//Output (Data,Var,Abs)
	0x85 0xff 		//Report ID (0xff)
	0x09 0x03 		//Usage (Vendor)
	0x75 0x08 		//Report Size (8)
	0x95 0x3f 		//Report Count (63)
	0x92 0x02 0x01 	//Output (Data,Var,Abs)
	0x85 0xff 		//Report ID (0xff)
	0x09 0x05 		//Usage (Vendor)
	0x75 0x08 		//Report Size (8)
	0x95 0x3f 		//Report Count (63)
	0x82 0x02 0x01       //Input (Data,Var,Abs)
	0xc0 		       //End Collection
0xc0			//End Collection
xairy commented

Hi! I never specifically tested OUT interrupt transfers, but I believe they should work in Raw Gadget. Perhaps, the issue is on the proxy side. Not sure I can help with this, at least not without acquiring the device the debugging the issue myself. Thanks!

Thank you very much,I look the Raw Gadget source, use gadget usb_ep_queue to write or read data from host. I use AristoChen/usb-proxy, and the read endpoint 0x02 loop already start, but can not read any data, is the udc driver bug? musb-hdrc or fe980000.usb

There the pcap and device monitor studio, it can send data. I change the raw_gadget/examples keyboard.c usb_hid_report to the atm card read, the device monitor studio always dead in no response.
pcap
device monitor studio

xairy commented

Which USB smart card reader are you trying to proxy? I'll see if I can get the device and test it myself.

Thank you very much, the card reader like this Sankyo Seiki ATM card reader,but I have old product which is stop production

xairy commented

Looks like this particular device will be hard to get :(

Do I understand correctly, that now you have a C program that uses Raw Gadget to emulate this device (without using the device itself and usb-proxy), and then you see that the Windows host sends an OUT request, but Raw Gadget never gets it?

yes,I change the example keyboard.c,just change the char usb_hid_report[] to the pcap's hid report response. and in ep_int_in_loop change usb_raw_ep_write to usb_raw_ep_read. I will try change all device、config and strings,to see if can received the OUT request. Thank you very much.

I have change the keyborad.c to the atm cardreader and test the OUT request, can not receive on orangepi pc, the source is here keyboard.c

xairy commented

Do you this OUT request being sent on the host side?

Yes,I test use device monitor studio,can't received the OUT request send from host.

In the hid /drivers/usb/gadget/function/f_hid.c, use hid out need config, is the ploblem?

struct f_hidg {
	/* configuration */
	unsigned char			bInterfaceSubClass;
	unsigned char			bInterfaceProtocol;
	unsigned char			protocol;
	unsigned char			idle;
	unsigned short			report_desc_length;
	char				*report_desc;
	unsigned short			report_length;
	/*
	 * use_out_ep - if true, the OUT Endpoint (interrupt out method)
	 *              will be used to receive reports from the host
	 *              using functions with the "intout" suffix.
	 *              Otherwise, the OUT Endpoint will not be configured
	 *              and the SETUP/SET_REPORT method ("ssreport" suffix)
	 *              will be used to receive reports.
	 */
	bool				use_out_ep;

	/* recv report */
	spinlock_t			read_spinlock;
	wait_queue_head_t		read_queue;
	/* recv report - interrupt out only (use_out_ep == 1) */
	struct list_head		completed_out_req;
	unsigned int			qlen;
	/* recv report - setup set_report only (use_out_ep == 0) */
	char				*set_report_buf;
	unsigned int			set_report_length;

	/* send report */
	spinlock_t			write_spinlock;
	bool				write_pending;
	wait_queue_head_t		write_queue;
	struct usb_request		*req;

	struct device			dev;
	struct cdev			cdev;
	struct usb_function		func;

	struct usb_ep			*in_ep;
	struct usb_ep			*out_ep;
};
xairy commented

I tried running your modified keyboard.c while connected to a Windows PC, but the device never receives HID_REQ_SET_REPORT/HID_REQ_SET_PROTOCOL, so it never reaches ep_int_out_loop. Thus, I don't see any failures. I also never get the USB_REQ_SET_CONFIGURATION request from Windows.

Could you double-check that it works for you? Is so, please share the log printed by keyboard.c.

xairy commented

Wrt f_hid.c: this file is a part of the Composite Gadget framework and it's not related to Raw Gadget. However, looking at the amount of code in f_hid.c, it's totally possible that both keyboard.c and usb-proxy don't implement some crucial part of the HID protocol required for handling certain devices (e.g. ones with an OUT endpoint). However, I don't know much about HID and won't be able to help if this is the case.

Thank you very much,I found a patch https://patchwork.kernel.org/project/linux-usb/patch/20210821134004.363217-1-mdevaev@gmail.com/#24400695 description,hid out causes a number of compatibility problems with various host drivers,this may be the reason. may orangepi pc and raspberry4 may not support hit out. I change usb-proxy not proxy the hid out endpoint to pc, then pc will use SETUP/SETUP_REPORT send data to ep0,and in proxy send this data to cart reader hid out,now work good. Thank you for helping me.