AristoChen / usb-proxy

A USB proxy based on raw-gadget and libusb
Apache License 2.0
152 stars 29 forks source link

error Proxing a keyboard: ioctl(USB_RAW_IOCTL_EP0_WRITE): Cannot send after transport endpoint shutdown #4

Closed Alphadan28 closed 1 year ago

Alphadan28 commented 1 year ago

first of all thanks for sharing your work, I successfuly proxied a ethernet adapter but fails with all HID i have

pi@raspberrypi:~/usb-proxy $ sudo ./usb-proxy --device=fe980000.usb --driver=fe980000.usb --vendor_id=1997 --product_id=2433 Device is: fe980000.usb Driver is: fe980000.usb vendor_id is: 6551 product_id is: 9267 Device opened successfully Start hotplug_monitor thread, thread id(2326) Setup USB config successfully Start for EP0, thread id(2324) event: connect, length: 0 event: control, length: 8 bRequestType: 0x80 (IN), bRequest: 0x06, wValue: 0x0100, wIndex: 0x0000, wLength: 64 type = USB_TYPE_STANDARD req = USB_REQ_GET_DESCRIPTOR desc = USB_DT_DEVICE ep0: transferred 18 bytes (in) event: control, length: 8 bRequestType: 0x80 (IN), bRequest: 0x06, wValue: 0x0100, wIndex: 0x0000, wLength: 18 type = USB_TYPE_STANDARD req = USB_REQ_GET_DESCRIPTOR desc = USB_DT_DEVICE ep0: transferred 18 bytes (in) event: control, length: 8 bRequestType: 0x80 (IN), bRequest: 0x06, wValue: 0x0200, wIndex: 0x0000, wLength: 255 type = USB_TYPE_STANDARD req = USB_REQ_GET_DESCRIPTOR desc = USB_DT_CONFIG ioctl(USB_RAW_IOCTL_EP0_WRITE): Cannot send after transport endpoint shutdown

Any idea whats causing this?

Alphadan28 commented 1 year ago

I noticed in this block: ` setup_host_usb_desc(); printf("Setup USB config successfully\n");

int fd = usb_raw_open();
usb_raw_init(fd, USB_SPEED_HIGH, driver, device);
usb_raw_run(fd);

` that the USB_SPEED_HIGH mode is hard-coded changed that to low speed and seems better at least tries to transfer data but sill the target machine doesn't identifies the device. (this test was made with a mini wireless keyboard i suspect it uses USB LOW SPEED)

AristoChen commented 1 year ago

Hi,

Thank you for spending time playing around with this project!

Could you please provide the output of the following command?

Alphadan28 commented 1 year ago

the project is unique, and have learn a lot about USB thanks to this project

lsusb -t /: Bus 03.Port 1: Dev 1, Class=root_hub, Driver=dwc2/1p, 480M /: Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/4p, 5000M /: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/1p, 480M | Port 1: Dev 2, If 0, Class=Hub, Driver=hub/4p, 480M < ------------------------- this is the mini keyboard | Port 3: Dev 4, If 0, Class=Human Interface Device, Driver=usbhid, 12M |__ Port 3: Dev 4, If 1, Class=Human Interface Device, Driver=usbhid, 12M

the mini keyboard shows as 2 devices, I guess the first is a internal hub then the keyboard itself and the touch pad as a mouse.

lsusb -v -d 1997:2433

Bus 001 Device 004: ID 1997:2433 Shenzhen Riitek Technology Co., Ltd wireless mini keyboard with touchpad Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 1.10 bDeviceClass 0 bDeviceSubClass 0 bDeviceProtocol 0 bMaxPacketSize0 32 idVendor 0x1997 Shenzhen Riitek Technology Co., Ltd idProduct 0x2433 wireless mini keyboard with touchpad bcdDevice 1.10 iManufacturer 1
iProduct 2 mini keyboard iSerial 0 bNumConfigurations 1 Configuration Descriptor: bLength 9 bDescriptorType 2 wTotalLength 0x003b bNumInterfaces 2 bConfigurationValue 1 iConfiguration 0 bmAttributes 0xa0 (Bus Powered) Remote Wakeup MaxPower 100mA Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 0 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 3 Human Interface Device bInterfaceSubClass 1 Boot Interface Subclass bInterfaceProtocol 1 Keyboard iInterface 0 HID Device Descriptor: bLength 9 bDescriptorType 33 bcdHID 1.01 bCountryCode 0 Not supported bNumDescriptors 1 bDescriptorType 34 Report wDescriptorLength 77 Report Descriptors: UNAVAILABLE Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x81 EP 1 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0020 1x 32 bytes bInterval 8 Interface Descriptor: bLength 9 bDescriptorType 4 bInterfaceNumber 1 bAlternateSetting 0 bNumEndpoints 1 bInterfaceClass 3 Human Interface Device bInterfaceSubClass 1 Boot Interface Subclass bInterfaceProtocol 2 Mouse iInterface 0 HID Device Descriptor: bLength 9 bDescriptorType 33 bcdHID 1.01 bCountryCode 0 Not supported bNumDescriptors 1 bDescriptorType 34 Report wDescriptorLength 116 Report Descriptors: UNAVAILABLE Endpoint Descriptor: bLength 7 bDescriptorType 5 bEndpointAddress 0x82 EP 2 IN bmAttributes 3 Transfer Type Interrupt Synch Type None Usage Type Data wMaxPacketSize 0x0020 1x 32 bytes bInterval 1

Alphadan28 commented 1 year ago

update: ran it with level 2 verbose and this is the output

Device is: fe980000.usb Driver is: fe980000.usb vendor_id is: 0x1997 product_id is: 0x2433 verbose_level: 2 5 Devices in list Target device not found Device opened successfully Setup USB config successfully Start hotplug_monitor thread, thread id(2697) Start for EP0, thread id(2695) ep #0: name: ep1in addr: 1 type: iso blk int dir : in _ maxpacket_limit: 1024 maxstreams: 0 ep #1: name: ep1out addr: 1 type: iso blk int dir : out maxpacket_limit: 1024 max_streams: 0 ep #2: name: ep2in addr: 2 type: iso blk int dir : in _ maxpacket_limit: 1024 maxstreams: 0 ep #3: name: ep2out addr: 2 type: iso blk int dir : out maxpacket_limit: 1024 max_streams: 0 ep #4: name: ep3in addr: 3 type: iso blk int dir : in _ maxpacket_limit: 1024 maxstreams: 0 ep #5: name: ep3out addr: 3 type: iso blk int dir : out maxpacket_limit: 1024 max_streams: 0 ep #6: name: ep4in addr: 4 type: iso blk int dir : in _ maxpacket_limit: 1024 maxstreams: 0 ep #7: name: ep4out addr: 4 type: iso blk int dir : out maxpacket_limit: 1024 max_streams: 0 ep #8: name: ep5in addr: 5 type: iso blk int dir : in _ maxpacket_limit: 1024 maxstreams: 0 ep #9: name: ep5out addr: 5 type: iso blk int dir : out maxpacket_limit: 1024 max_streams: 0 ep #10: name: ep6in addr: 6 type: iso blk int dir : in _ maxpacket_limit: 1024 maxstreams: 0 ep #11: name: ep6out addr: 6 type: iso blk int dir : out maxpacket_limit: 1024 max_streams: 0 ep #12: name: ep7in addr: 7 type: iso blk int dir : in _ maxpacket_limit: 1024 maxstreams: 0 ep #13: name: ep7out addr: 7 type: iso blk int dir : out maxpacket_limit: 1024 max_streams: 0 event: connect, length: 0 event: control, length: 8 bRequestType: 0x80 (IN), bRequest: 0x06, wValue: 0x0100, wIndex: 0x0000, wLength: 64 type = USB_TYPE_STANDARD req = USB_REQ_GET_DESCRIPTOR desc = USB_DT_DEVICE Control transfer succeed Sending data to EP0(control_in): 12 01 10 01 00 00 00 20 97 19 33 24 10 01 01 02 00 01 ep0: transferred 18 bytes (in) event: control, length: 8 bRequestType: 0x80 (IN), bRequest: 0x06, wValue: 0x0100, wIndex: 0x0000, wLength: 18 type = USB_TYPE_STANDARD req = USB_REQ_GET_DESCRIPTOR desc = USB_DT_DEVICE Control transfer succeed Sending data to EP0(control_in): 12 01 10 01 00 00 00 20 97 19 33 24 10 01 01 02 00 01 ep0: transferred 18 bytes (in) event: control, length: 8 bRequestType: 0x80 (IN), bRequest: 0x06, wValue: 0x0200, wIndex: 0x0000, wLength: 255 type = USB_TYPE_STANDARD req = USB_REQ_GET_DESCRIPTOR desc = USB_DT_CONFIG Control transfer succeed Sending data to EP0(control_in): 09 02 3b 00 02 01 00 a0 32 09 04 00 00 01 03 01 01 00 09 21 01 01 00 01 22 4d 00 07 05 81 03 20 00 08 09 04 01 00 01 03 01 02 00 09 21 01 01 00 01 22 74 00 07 05 82 03 20 00 01 ioctl(USB_RAW_IOCTL_EP0_WRITE): Cannot send after transport endpoint shutdown

the error comes from proxy.cpp > void ep0_loop(int fd) >rv = usb_raw_ep0_write(fd, (struct usb_raw_ep_io *)&io); //line: 379

seems like somehow host or device closes fd, i been doing tests with USBPCAP and Wireshark and in the capture taken from the target host machine doesn't even get any device request.

would you point me were to look at?

if helps this is the traffic of the device conected directly to the host (no proxy) in PCAP format. https://www.sendspace.com/file/7pguoa

this is the usb traffic recived in the target host with proxy enabled, only 6 interrupt packets, but no device request or response or anything. https://www.sendspace.com/file/f5rm2s

AristoChen commented 1 year ago

Hi,

Thanks for sharing the info, sorry that I don't have time recently because I am on a business trip in Europe, I will check this out when I am back to my hometown

Alphadan28 commented 1 year ago

don't worry bro, good luck in your travel, I feel this project is unique and has future there are only 2 proxy USB projects with this one included available, just remember to throw a hand to the project when you have time.

Alphadan28 commented 1 year ago

update: The problem happens when the descriptor to send by this function: usb_raw_ep0_write is bigger than the max packet size for EP0 In this particular case with the mini keyboard the device responds with usb.bMaxPacketSize0=32 (sniffed from windows with USBPCAP) and the descriptor usb_raw_ep0_write is trying to send is 59 bytes when this condition happens:

Configuration descriptor > usb.bMaxPacketSize0

we get this error: ioctl(USB_RAW_IOCTL_EP0_WRITE): Cannot send after transport endpoint shutdown it feels like the endpoint is expecting the configuration descriptor in 2 parts one of the full packet size and other with the rest but when it tries to send all the 59 at once it fails. i tested with other devices and this issue repeats when such conditions meet.

all devices that work on high speed have 64 bytes in ep0, haven't found a device that fails for having a configuration descriptor bigger than 64bytes but I'm guessing it could happen too.

but most high speed devices pass this part then fail somewhere else but I'm trying to solve this issue first but i lack of the knowledge YET to complete this.

AristoChen commented 1 year ago

Hi,

May I know where did you get the mini keyboard? I am thinking that if it is not too expensive, I might buy one to debug this issue

For the bMaxPacketSize0 that you mentioned, maybe you can try to manually set this value higher https://github.com/AristoChen/usb-proxy/blob/6aecd455b2ef3d6734ab92105ca00c01464d4030/usb-proxy.cpp#L65

BTW, I am not a USB expert as well, and AFAIK there are some buggy USB devices that might require special driver to work, or possibly need to setup some USB quirks in kernel module, which means that this project might not be able to handle that special case

Alphadan28 commented 1 year ago

this is the mini keyboard: https://www.amazon.es/Rii-K12-Mini-touchpad-inoxidable/dp/B00ZCFTT00/

but may be you don't need to buy it, I can run any tests for you and provide logs or pcaps.

My mouse has a issue that looked like the same problem but now i made deeper tests.

The mouse is a death adder V2 which has a bMaxPacketSize0 of 64 bytes but its configuration descriptor is 84 bytes but in this case it manages to send the descriptor even though is bigger than the bMaxPacketSize0.

so after running it with verbose level 2: event: control, length: 8 bRequestType: 0x21 (OUT), bRequest: 0x09, wValue: 0x0300, wIndex: 0x0000, wLength: 90 type = USB_TYPE_CLASS req = unknown = 0x9 Sending data to EP0(control_out): 00 1f 00 00 00 08 0f 03 00 00 00 00 00 00 00 ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 fb 00 Control transfer succeed ep0: transferred 90 bytes (out)

it seems to be sending the descriptor without problem...

but crashes only after I move the mouse

in this case crashes when trying to send a interrupt with the movement data:

EP81(int_in): enqueued 8 bytes to queue Sending data to EP81(int_in): 00 fe 00 00 fe ff 00 00 ioctl(USB_RAW_IOCTL_EP_WRITE): Cannot send after transport endpoint shutdown.

now this makes me wonder if the problem is the size of the descriptor or if is something else because in this case the descriptor is also bigger than the bMaxPacketSize0 but it sends the descriptor.

.bMaxPacketSize0 = device_device_desc.bMaxPacketSize0, about this line i tried that already harcoded it to 64 bytes and also hardcoded usb.bcdDevice = 0x0200 but it gives the same result.

I made this test because this project: https://github.com/nesto-software/USBProxy manages to proxy that mini keyboard just fine but that project fails with every other device I have, it uses GadgetFS instead of Raw Gadget, Proxied using that project to see whats different and how it sends the descriptor and what I found in the pcap was that the mini keyboard shows in the device descriptor MaxPacketSize0 = 64 which is weird because that device conected directly reports its MaxPacketSize0 = 32 and also usb.bcdDevice = 0x0200 instead of usb.bcdDevice = 0x0110 (which is its original value) its like that other proxy somehow changes these values.

This problems are interesting every time I get a hypothesis it always results in something else after few days.

xairy commented 1 year ago

@Alphadan28 Could you change USB_SPEED_HIGH to USB_SPEED_FULL in the arguments of usb_raw_init and see if that makes any difference (for the device that fails because of bMaxPacketSize0 being 32)?

Alphadan28 commented 1 year ago

sure this is the result: connecting as USB_SPEED_FULL instead of USB_SPEED_HIGH

Device is: fe980000.usb Driver is: fe980000.usb vendor_id is: 6551 product_id is: 9267 Device opened successfully Start hotplug_monitor thread, thread id(2631) Setup USB config successfully Start for EP0, thread id(2629) event: connect, length: 0 event: control, length: 8 bRequestType: 0x80 (IN), bRequest: 0x06, wValue: 0x0100, wIndex: 0x0000, wLength: 64 type = USB_TYPE_STANDARD req = USB_REQ_GET_DESCRIPTOR desc = USB_DT_DEVICE ep0: transferred 18 bytes (in) event: control, length: 8 bRequestType: 0x80 (IN), bRequest: 0x06, wValue: 0x0100, wIndex: 0x0000, wLength: 18 type = USB_TYPE_STANDARD req = USB_REQ_GET_DESCRIPTOR desc = USB_DT_DEVICE ep0: transferred 18 bytes (in) event: control, length: 8 bRequestType: 0x80 (IN), bRequest: 0x06, wValue: 0x0200, wIndex: 0x0000, wLength: 255 type = USB_TYPE_STANDARD req = USB_REQ_GET_DESCRIPTOR desc = USB_DT_CONFIG ioctl(USB_RAW_IOCTL_EP0_WRITE): Cannot send after transport endpoint shutdown

and dmesg output:

[ 3458.920575] hwmon hwmon1: Undervoltage detected! [ 3467.240672] hwmon hwmon1: Voltage normalised [ 3471.400790] hwmon hwmon1: Undervoltage detected! [ 3483.880773] hwmon hwmon1: Voltage normalised [ 3603.254003] dwc2 fe980000.usb: bound driver raw-gadget.0 [ 3603.433015] dwc2 fe980000.usb: new device is full-speed [ 3603.487987] dwc2 fe980000.usb: new device is full-speed [ 3603.522760] dwc2 fe980000.usb: new address 45 [ 3604.042229] raw-gadget.0 gadget: Gadget Disconect [ 3604.047030] dwc2 fe980000.usb: new device is full-speed [ 3604.047062] raw-gadget.0 gadget: Gadget Disconect

xairy commented 1 year ago

Alphadan28, could you please try proxying the device with the Dummy HCD controller instead of dwc2 (you need to build and load dummy_hcd from the Raw Gadget repository and provide no --device/driver arguments to USB-Proxy)? And if it fails, could you please share the PCAP of the USB traffic?

xairy commented 1 year ago

And also, could you apply the following patch to raw_gadget.c and share dmesg output (there will be a lot of WARNINGs printed, please include them all):

diff --git a/raw_gadget/raw_gadget.c b/raw_gadget/raw_gadget.c
index 5eedee5..d79b690 100644
--- a/raw_gadget/raw_gadget.c
+++ b/raw_gadget/raw_gadget.c
@@ -7,6 +7,8 @@
  * Author: Andrey Konovalov <andreyknvl@gmail.com>
  */

+#define DEBUG
+
 #include <linux/compiler.h>
 #include <linux/ctype.h>
 #include <linux/debugfs.h>
@@ -365,10 +367,26 @@ out:
 }

 /* These are currently unused but present in case UDC driver requires them. */
-static void gadget_disconnect(struct usb_gadget *gadget) { }
-static void gadget_suspend(struct usb_gadget *gadget) { }
-static void gadget_resume(struct usb_gadget *gadget) { }
-static void gadget_reset(struct usb_gadget *gadget) { }
+static void gadget_disconnect(struct usb_gadget *gadget)
+{
+       dev_dbg(&gadget->dev, "gadget disconnected\n");
+       WARN_ON(1);
+}
+static void gadget_suspend(struct usb_gadget *gadget)
+{
+       dev_dbg(&gadget->dev, "gadget suspended\n");
+       WARN_ON(1);
+}
+static void gadget_resume(struct usb_gadget *gadget)
+{
+       dev_dbg(&gadget->dev, "gadget resumed\n");
+       WARN_ON(1);
+}
+static void gadget_reset(struct usb_gadget *gadget)
+{
+       dev_dbg(&gadget->dev, "gadget reset\n");
+       WARN_ON(1);
+}

 /*----------------------------------------------------------------------*/
xairy commented 1 year ago

I got the K12+ keyboard, and it's being proxied perfectly with Dummy HCD. So I suspect the issue is either with the dwc2 driver or with Raw Gadget. I don't have a full-size Raspberry Pie to debug further, but I'll try to get my hands on one.

KernelKrusha commented 1 year ago

This project https://github.com/patryk4815/usb-proxy manages to proxy my logitech mouse without issues. This usb-proxy project results in the error described above.

RandomOnlineName commented 1 year ago

I have experienced the same issue with a wireless mouse & keyboard. It works perfectly with dummy driver but not with the project by patryk4815. I ran the patch above. dmesg. This was done on kernel 5.15.89, rasbarian (bullseye), Raspberry Pi 4B.

imatespl commented 1 year ago

I have this issue too,with a wireless mouse. on orangepipc,I change the MaxPackageSize0,and change connect_device

        //result = libusb_set_auto_detach_kernel_driver(dev_handle, 1);
        //if (result != LIBUSB_SUCCESS) {
        //      fprintf(stderr, "libusb_set_auto_detach_kernel_driver() failed: %s\n",
        //                      libusb_strerror((libusb_error)result));
        //      return result;
        //}
        for (int i = 0; i < device_device_desc.bNumConfigurations; i++) {
                for (int j = 0; j < device_config_desc[i]->bNumInterfaces; j++) {
                         if(libusb_detach_kernel_driver(dev_handle, j) == 0)
                                 fprintf(stdout, "detach devivce ok interface is %d\n", j);
                }
        }

when ctrl event set interface 1, control_request failed

event: control, length: 8
  bRequestType: 0x21 (OUT), bRequest: 0x0a, wValue: 0x0000, wIndex: 0x0000, wLength: 0
  type = USB_TYPE_CLASS
  req = unknown = 0xa
ep0: transferred 0 bytes (out)
event: control, length: 8
  bRequestType: 0x81  (IN), bRequest: 0x06, wValue: 0x2200, wIndex: 0x0000, wLength: 123
  type = USB_TYPE_STANDARD
  req = USB_REQ_GET_DESCRIPTOR
  desc = unknown = 0x22
Sending data to EP0(control_in): 05 01 09 06 a1 01 05 07 19 e0 29 e7 15 00 25 01 75 01 95 08 81 02 81 03 95 05 05 08 19 01 29 05 91 02 95 01 75 03 91 01 95 06 75 08 15 00 26 a4 00 05 07 19 00 2a a4 00 81 00 c0
ep0: transferred 59 bytes (in)
event: control, length: 8
  bRequestType: 0x21 (OUT), bRequest: 0x0a, wValue: 0x0000, **wIndex: 0x0001**, wLength: 0
  type = USB_TYPE_CLASS
  req = unknown = 0xa
**ep0: stalling**
event: control, length: 8
  bRequestType: 0x81  (IN), bRequest: 0x06, wValue: 0x2200, **wIndex: 0x0001**, wLength: 241
  type = USB_TYPE_STANDARD
  req = USB_REQ_GET_DESCRIPTOR
  desc = unknown = 0x22
Sending data to EP0(control_in): 05 01 09 02 a1 01 85 02 09 01 a1 00 05 09 19 01 29 10 15 00 25 01 95 10 75 01 81 02 05 01 16 01 f8 26 ff 07 75 0c 95 02 09 30 09 31 81 06 15 81 25 7f 75 08 95 01 09 38 81 06 05 0c 0a 38 02 95 01 81 06 c0 c0 05 0c 09 01 a1 01 85 03 75 10 95 02 15 01 26 8c 02 19 01 2a 8c 02 81 00 c0 05 01 09 80 a1 01 85 04 75 02 95 01 15 01 25 03 09 82 09 81 09 83 81 60 75 06 81 03 c0 06 00 ff 09 01 a1 01 85 10 75 08 95 06 15 00 26 ff 00 09 01 81 00 09 01 91 00 c0 06 00 ff 09 02 a1 01 85 11 75 08 95 13 15 00 26 ff 00 09 02 81 00 09 02 91 00 c0
**ioctl(USB_RAW_IOCTL_EP0_WRITE): Device or resource busy**

dmesg output has a gadget raw-gadget.0 gadget: fail, wrong direction

[ 1718.228210] CPU: 0 PID: 0 Comm: swapper/0 Tainted: G        WC  E     5.15.93-sunxi #23.02.2
[ 1718.228238] Hardware name: Allwinner sun8i Family
[ 1718.228257] [<c010cd21>] (unwind_backtrace) from [<c01095f5>] (show_stack+0x11/0x14)
[ 1718.228300] [<c01095f5>] (show_stack) from [<c09e3d59>] (dump_stack_lvl+0x2b/0x34)
[ 1718.228347] [<c09e3d59>] (dump_stack_lvl) from [<c011c4c9>] (__warn+0xad/0xb0)
[ 1718.228392] [<c011c4c9>] (__warn) from [<c09dda4b>] (warn_slowpath_fmt+0x43/0x7c)
[ 1718.228433] [<c09dda4b>] (warn_slowpath_fmt) from [<c0798c77>] (usb_gadget_udc_reset+0xf/0x28)
[ 1718.228477] [<c0798c77>] (usb_gadget_udc_reset) from [<c0797ddb>] (musb_g_reset+0x15f/0x168)
[ 1718.228520] [<c0797ddb>] (musb_g_reset) from [<c07903c5>] (musb_interrupt+0x6f1/0xa64)
[ 1718.228559] [<c07903c5>] (musb_interrupt) from [<bf817721>] (sunxi_musb_interrupt+0x59/0xd0 [sunxi])
[ 1718.228608] [<bf817721>] (sunxi_musb_interrupt [sunxi]) from [<c01685c1>] (__handle_irq_event_percpu+0x41/0x12c)
[ 1718.228663] [<c01685c1>] (__handle_irq_event_percpu) from [<c01686cf>] (handle_irq_event_percpu+0x23/0x4c)
[ 1718.228710] [<c01686cf>] (handle_irq_event_percpu) from [<c0168731>] (handle_irq_event+0x39/0x50)
[ 1718.228755] [<c0168731>] (handle_irq_event) from [<c016bb6f>] (handle_fasteoi_irq+0x67/0xbc)
[ 1718.228799] [<c016bb6f>] (handle_fasteoi_irq) from [<c01680af>] (handle_domain_irq+0x43/0x58)
[ 1718.228839] [<c01680af>] (handle_domain_irq) from [<c05cca3b>] (gic_handle_irq+0x63/0x74)
[ 1718.228882] [<c05cca3b>] (gic_handle_irq) from [<c0100b97>] (__irq_svc+0x57/0x80)
[ 1718.228917] Exception stack(0xc0f01f00 to 0xc0f01f48)
[ 1718.228945] 1f00: 002d9c22 00000000 00000001 c0115601 ffffe000 00000000 c0f05068 00000001
[ 1718.228971] 1f20: c0f04fc8 00000000 c0e9aab0 00000000 c0f05130 c0f01f50 c0106dc7 c0106dc8
[ 1718.228988] 1f40: 600f0033 ffffffff
[ 1718.229003] [<c0100b97>] (__irq_svc) from [<c0106dc8>] (arch_cpu_idle+0x28/0x2c)
[ 1718.229044] [<c0106dc8>] (arch_cpu_idle) from [<c09ef27d>] (default_idle_call+0x29/0x8c)
[ 1718.229084] [<c09ef27d>] (default_idle_call) from [<c0146811>] (do_idle+0x189/0x1cc)
[ 1718.229120] [<c0146811>] (do_idle) from [<c0146ab5>] (cpu_startup_entry+0x19/0x1c)
[ 1718.229155] [<c0146ab5>] (cpu_startup_entry) from [<c0e00f5d>] (start_kernel+0x59f/0x5c6)
[ 1718.229197] ---[ end trace 5cfb5255e5748863 ]---
[ 1718.391880] raw-gadget.0 gadget: fail, wrong direction
[ 1718.393715] raw-gadget.0 gadget: gadget reset
[ 1718.393747] ------------[ cut here ]------------
[ 1718.393757] WARNING: CPU: 0 PID: 0 at drivers/usb/gadget/legacy/raw_gadget.c:388 usb_gadget_udc_reset+0xf/0x28
[ 1718.393800] Modules linked in: raw_gadget(E) hid_logitech_hidpp joydev input_leds hid_logitech_dj rfkill sunrpc lz4hc lz4 sun9i_hdmi_audio sunxi_cir snd_soc_hdmi_codec sun4i_gpadc_iio industrialio sun8i_thermal sunxi_cedrus(C) v4l2_mem2mem videobuf2_dma_contig videobuf2_memops videobuf2_v4l2 videobuf2_common evdev uio_pdrv_genirq uio cpufreq_dt zram sch_fq_codel ramoops pstore_blk reed_solomon pstore_zone ip_tables x_tables autofs4 sy8106a_regulator lima dw_hdmi_i2s_audio dw_hdmi_cec gpu_sched sunxi phy_generic gpio_keys display_connector
[ 1718.394110] CPU: 0 PID: 0 Comm: swapper/0 Tainted: G        WC  E     5.15.93-sunxi #23.02.2
[ 1718.394130] Hardware name: Allwinner sun8i Family
[ 1718.394150] [<c010cd21>] (unwind_backtrace) from [<c01095f5>] (show_stack+0x11/0x14)
[ 1718.394187] [<c01095f5>] (show_stack) from [<c09e3d59>] (dump_stack_lvl+0x2b/0x34)
[ 1718.394224] [<c09e3d59>] (dump_stack_lvl) from [<c011c4c9>] (__warn+0xad/0xb0)
[ 1718.394260] [<c011c4c9>] (__warn) from [<c09dda4b>] (warn_slowpath_fmt+0x43/0x7c)
[ 1718.394291] [<c09dda4b>] (warn_slowpath_fmt) from [<c0798c77>] (usb_gadget_udc_reset+0xf/0x28)
[ 1718.394326] [<c0798c77>] (usb_gadget_udc_reset) from [<c0797ddb>] (musb_g_reset+0x15f/0x168)
[ 1718.394359] [<c0797ddb>] (musb_g_reset) from [<c07903c5>] (musb_interrupt+0x6f1/0xa64)
[ 1718.394389] [<c07903c5>] (musb_interrupt) from [<bf817721>] (sunxi_musb_interrupt+0x59/0xd0 [sunxi])
[ 1718.394424] raw-gadget.0 gadget: gadget disconnected
[ 1718.394444] ------------[ cut here ]------------
[ 1718.394432] [<bf817721>] (sunxi_musb_interrupt [sunxi]) from [<c01685c1>] (__handle_irq_event_percpu+0x41/0x12c)
[ 1718.394452] WARNING: CPU: 2 PID: 1624 at drivers/usb/gadget/legacy/raw_gadget.c:373 usb_gadget_disconnect+0x87/0x90
[ 1718.394485] Modules linked in:
[ 1718.394475] [<c01685c1>] (__handle_irq_event_percpu) from [<c01686cf>] (handle_irq_event_percpu+0x23/0x4c)
[ 1718.394495]  raw_gadget(E) hid_logitech_hidpp joydev input_leds hid_logitech_dj
[ 1718.394511] [<c01686cf>] (handle_irq_event_percpu) from [<c0168731>] (handle_irq_event+0x39/0x50)
[ 1718.394531]  rfkill sunrpc lz4hc lz4 sun9i_hdmi_audio
[ 1718.394546] [<c0168731>] (handle_irq_event) from [<c016bb6f>] (handle_fasteoi_irq+0x67/0xbc)
[ 1718.394563]  sunxi_cir snd_soc_hdmi_codec sun4i_gpadc_iio industrialio sun8i_thermal
[ 1718.394581] [<c016bb6f>] (handle_fasteoi_irq) from [<c01680af>] (handle_domain_irq+0x43/0x58)
[ 1718.394599]  sunxi_cedrus(C) v4l2_mem2mem videobuf2_dma_contig videobuf2_memops
[ 1718.394612] [<c01680af>] (handle_domain_irq) from [<c05cca3b>] (gic_handle_irq+0x63/0x74)
[ 1718.394626]  videobuf2_v4l2
[ 1718.394634]  videobuf2_common evdev uio_pdrv_genirq uio
[ 1718.394651] [<c05cca3b>] (gic_handle_irq) from [<c0100b97>] (__irq_svc+0x57/0x80)
[ 1718.394663]  cpufreq_dt zram sch_fq_codel
[ 1718.394678] Exception stack(0xc0f01f00 to 0xc0f01f48)
[ 1718.394683]  ramoops pstore_blk reed_solomon
[ 1718.394703] 1f00: 002d9e78 00000000 00000001 c0115601 ffffe000 00000000 c0f05068 00000001
[ 1718.394724] 1f20: c0f04fc8 00000000 c0e9aab0 00000000 c0f03d00 c0f01f50 c0106dc7 c0106dc8
[ 1718.394735]  pstore_zone
[ 1718.394738] 1f40: 600b0033 ffffffff
[ 1718.394749]  ip_tables x_tables
[ 1718.394749] [<c0100b97>] (__irq_svc) from [<c0106dc8>] (arch_cpu_idle+0x28/0x2c)
[ 1718.394763]  autofs4 sy8106a_regulator lima dw_hdmi_i2s_audio
[ 1718.394779] [<c0106dc8>] (arch_cpu_idle) from [<c09ef27d>] (default_idle_call+0x29/0x8c)
[ 1718.394792]  dw_hdmi_cec gpu_sched sunxi phy_generic gpio_keys
[ 1718.394813] [<c09ef27d>] (default_idle_call) from [<c0146811>] (do_idle+0x189/0x1cc)
[ 1718.394826]  display_connector
[ 1718.394840] [<c0146811>] (do_idle) from [<c0146ab5>] (cpu_startup_entry+0x19/0x1c)
[ 1718.394868] [<c0146ab5>] (cpu_startup_entry) from [<c0e00f5d>] (start_kernel+0x59f/0x5c6)
[ 1718.394901] ---[ end trace 5cfb5255e5748864 ]---
[ 1718.394902] CPU: 2 PID: 1624 Comm: usb-proxy Tainted: G        WC  E     5.15.93-sunxi #23.02.2
[ 1718.394923] Hardware name: Allwinner sun8i Family
[ 1718.394935] [<c010cd21>] (unwind_backtrace) from [<c01095f5>] (show_stack+0x11/0x14)
[ 1718.394969] [<c01095f5>] (show_stack) from [<c09e3d59>] (dump_stack_lvl+0x2b/0x34)
[ 1718.395002] [<c09e3d59>] (dump_stack_lvl) from [<c011c4c9>] (__warn+0xad/0xb0)
[ 1718.395036] [<c011c4c9>] (__warn) from [<c09dda4b>] (warn_slowpath_fmt+0x43/0x7c)
[ 1718.395066] [<c09dda4b>] (warn_slowpath_fmt) from [<c0798b27>] (usb_gadget_disconnect+0x87/0x90)
[ 1718.395102] [<c0798b27>] (usb_gadget_disconnect) from [<c0799791>] (usb_gadget_remove_driver+0x21/0x90)
[ 1718.395138] [<c0799791>] (usb_gadget_remove_driver) from [<c0799907>] (usb_gadget_unregister_driver+0x73/0x9c)
[ 1718.395174] [<c0799907>] (usb_gadget_unregister_driver) from [<bf970aeb>] (raw_release+0x3f/0xdc [raw_gadget])
[ 1718.395229] [<bf970aeb>] (raw_release [raw_gadget]) from [<c0296993>] (__fput+0x4f/0x1b0)
[ 1718.395272] [<c0296993>] (__fput) from [<c0134785>] (task_work_run+0x7d/0xa0)
[ 1718.395304] [<c0134785>] (task_work_run) from [<c0120825>] (do_exit+0x359/0x86c)
[ 1718.395333] [<c0120825>] (do_exit) from [<c0120deb>] (do_group_exit+0x2f/0x84)
[ 1718.395359] [<c0120deb>] (do_group_exit) from [<c012a29d>] (get_signal+0x159/0x7c4)
[ 1718.395388] [<c012a29d>] (get_signal) from [<c010919d>] (do_work_pending+0x369/0x454)
[ 1718.395415] [<c010919d>] (do_work_pending) from [<c01000c7>] (slow_work_pending+0x9/0x16)
[ 1718.395440] Exception stack(0xc1635fb0 to 0xc1635ff8)
[ 1718.395458] 5fa0:                                     00000000 00000000 b639dc30 b639dc28
[ 1718.395478] 5fc0: 00000000 b639dc80 00000000 00000109 b639e380 00000001 00000000 00000000
[ 1718.395495] 5fe0: 00000109 b639dc18 b6c53a87 b6bedb04 80000030 00000000
[ 1718.395508] ---[ end trace 5cfb5255e5748865 ]---
imatespl commented 1 year ago

Very thanks, I also make my mouse work, but i think @xairy code is good, i will test the code. i have a ic card reader, which have a bEndpointAddress 0x85, but raw_gadget use driver musb-hdrc max bEndpointAddress 0x84, this make raw_gadget ep addr enable failed in process_eps ep->thread_info.ep_num = usb_raw_ep_enable(fd, &ep->thread_info.endpoint);

Is there a good solution?

AristoChen commented 1 year ago

Hi @imatespl, thanks for confirm that the fix works for you! could you please open another issue to discuss your question? we may discuss there further, because I think it is not related to this issue

Just a quick reply to your question, I guess your hardware only support endopoints address from 0x01 to 0x04, and from 0x81 to 0x84. Your IC card reader uses 0x85, which may not be supported on your hardware. There may be 2 solutions

  1. Use other hardware that supports address 0x85, such as raspberry pi 4, or IIRC, Bananapi M1 should support as well
  2. Previously, I was planning to allow users to manually mapping endpoint addresses to some other addresses by themselves if this issue happen, but I don't have a plan to implement it in near future, and IMO it is highly possible that the driver from the host may not be able to work normally since the address is different.
imatespl commented 1 year ago

very thanks,I will open a new issue,my ic card reader have three endpoints, 0x01 0x82 0x85, I hard code map 0x85 to 0x81, in usb_raw_ep_enable(fd, &ep->thread_info.endpoint), and injection USB_DT_CONFIG response set 0x85 to 0x81, it work good

imatespl commented 1 year ago

I test @xairy https://github.com/AristoChen/usb-proxy/pull/6, and should change the MaxPackageSize0 from 0x08 to 0x40, 0x08 make the raw_gadget which use device musb-hdrc.4.auto dead loop, and ignore usb_raw_ep0_stall when SET_IDLE request to interface 1, it like in linux libusb don't support this request, in proxy.cpp:499 event: control, length: 8 bRequestType: 0x21 (OUT), bRequest: 0x0a, wValue: 0x0000, wIndex: 0x0001, wLength: 0 type = USB_TYPE_CLASS req = unknown = 0xa ep0: stalling I add this code in ep0_loop

index e3dbd57..d703445 100644
--- a/proxy.cpp
+++ b/proxy.cpp
@@ -368,6 +368,12 @@ void ep0_loop(int fd) {
                                                break;
                                        }
                                }
+                               if ((event.ctrl.bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD &&
+                                       event.ctrl.bRequest == USB_REQ_GET_DESCRIPTOR &&
+                                       (event.ctrl.wValue >> 8) == USB_DT_DEVICE) {
+                                       struct usb_device_descriptor* pdata = (struct usb_device_descriptor*)&io.data;
+                                       pdata->bMaxPacketSize0 = 64;
+                               }

                                if (verbose_level >= 2)
                                        printData(io, 0x00, "control", "in");
@@ -495,7 +501,14 @@ void ep0_loop(int fd) {
                                        printf("ep0: transferred %d bytes (out)\n", rv);
                                }
                                else {
-                                       usb_raw_ep0_stall(fd);
+                                       if (event.ctrl.bRequestType == 0x21
+                                               && event.ctrl.bRequest == 0x0a
+                                               && event.ctrl.wIndex != 0) {
+                                               continue;
+                                       }
+                                       else {
+                                               usb_raw_ep0_stall(fd);
+                                       }
                                }
                        }
                }
AristoChen commented 1 year ago

Hi @imatespl , thanks for reviewing the code! if the issue you have mentioned is introduced by #6, could you please leave a comment there instead of here? I think it will be easier for us to discuss the code changes in a single place, thanks!

imatespl commented 1 year ago

Ok, I add to https://github.com/AristoChen/usb-proxy/pull/6, thanks!