AristoChen / usb-proxy

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

Support devices with multiple interfaces #6

Closed xairy closed 1 year ago

xairy commented 1 year ago

A few fixes that should hopefully resolve #4, see the last patch. Devices with multiple interfaces should now work properly.

With these changes, I'm able to proxy the K12 keyboard without issues.

I think devices that switch between configurations/alt settings will still glitch: endpoint handling threads are not joined properly as they are blocked on receive_data(). But this issue is present in the current code and will require another fix.

AristoChen commented 1 year ago

Hi @xairy, thank you very much for the PR! I just came back from a business trip, will try to find some time to review it, thanks again!

imatespl commented 1 year ago

hi @xairy I test the code https://github.com/AristoChen/usb-proxy/pull/6, there two issues.

  1. my mouse is a low speed device, and it response the MaxPageSize0 is 0x08, it should change the MaxPackageSize0 0x40, 0x08 make the raw_gadget which use device musb-hdrc.4.auto dead loop,
  2. ignore usb_raw_ep0_stall when SET_IDLE request to interface 1,it like in linux 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);
+                                       }
                                }
                        }
                }
xairy commented 1 year ago

Hi @imatespl,

Are these issues reproducible with Dummy HCD?

Which device are you trying to proxy? Please share an Amazon link or something like that.

Which Linux board do you use for proxying?

I'll be busy until June, but after that I can try to look into this.

Thanks for testing!

imatespl commented 1 year ago

Hi @xairy,

My mouse is logitech m170 https://www.amazon.com/Logitech-Wireless-Mouse-M170-Grey/dp/B019RPOZLI/ref=sr_1_2?keywords=logitech%2Bmouse%2Bm170%2Bwireless&qid=1684203813&sprefix=logitech%2Bmouse%2Bm170%2Caps%2C450&sr=8-2&th=1, and test on orangepc. I'm not test Dummy HCD, I'm not sure. I will try it, and response here.

imatespl commented 1 year ago

Hi @xairy,

I test the Dummy HCD, it work ok, I think musb-hdrc make the bug, when I change usb_raw_init(fd, USB_SPEED_LOW, driver, device) orusb_raw_init(fd, USB_SPEED_FULL, driver, device), use driver musb-hdrc and device musb-hdrc.4.auto, return ioctl(USB_RAW_IOCTL_RUN): Invalid argument, and dmesg has error udc musb-hdrc.4.auto: failed to start USB Raw Gadget: -22 misc raw-gadget: fail, usb_gadget_probe_driver returned -22
when use Dummy HCD it work ok,

KernelKrusha commented 1 year ago

With the changes proposed by @imatespl (https://github.com/AristoChen/usb-proxy/pull/6#issuecomment-1545455139) my Logitech Superlight mouse now proxies without issues :-)

AristoChen commented 1 year ago

Thanks @imatespl and @KernelKrusha for spending time testing this PR!