Skip to content

Commit

Permalink
Don't try stalling non-0-length control OUT requests
Browse files Browse the repository at this point in the history
Raw Gadget doesn't support it: see [1] for details.

With this change, I'm able to proxy another Logitech web camera.

[1] https://lore.kernel.org/linux-usb/CA+fCnZeLRqk-FOkJ81qMY0NMZC7YnW=beTw=w_DVA=OhOnywRw@mail.gmail.com/T/#u
  • Loading branch information
xairy committed Jun 15, 2024
1 parent 5bef5cb commit 5f2857a
Showing 1 changed file with 54 additions and 12 deletions.
66 changes: 54 additions & 12 deletions proxy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -476,10 +476,14 @@ void ep0_loop(int fd) {
printData(io, 0x00, "control", "in");

rv = usb_raw_ep0_write(fd, (struct usb_raw_ep_io *)&io);
printf("ep0: transferred %d bytes (in)\n", rv);
if (rv < 0)
printf("ep0: ack failed: %d\n", rv);
else
printf("ep0: transferred %d bytes (in)\n", rv);
}
else {
usb_raw_ep0_stall(fd);
continue;
}
}
else {
Expand Down Expand Up @@ -528,6 +532,10 @@ void ep0_loop(int fd) {

// Ack request after spawning endpoint threads.
rv = usb_raw_ep0_read(fd, (struct usb_raw_ep_io *)&io);
if (rv < 0)
printf("ep0: ack failed: %d\n", rv);
else
printf("ep0: request acked\n");
}
else if ((event.ctrl.bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD &&
event.ctrl.bRequest == USB_REQ_SET_INTERFACE) {
Expand Down Expand Up @@ -583,6 +591,10 @@ void ep0_loop(int fd) {

// Ack request after spawning endpoint threads.
rv = usb_raw_ep0_read(fd, (struct usb_raw_ep_io *)&io);
if (rv < 0)
printf("ep0: ack failed: %d\n", rv);
else
printf("ep0: request acked\n");
}
else {
if (injection_enabled) {
Expand All @@ -603,20 +615,50 @@ void ep0_loop(int fd) {
}
}

// Retrieve data for sending request to proxied device.
rv = usb_raw_ep0_read(fd, (struct usb_raw_ep_io *)&io);
if (event.ctrl.wLength == 0) {
// For 0-length request, we can ack or stall the request via
// Raw Gadget, depending on what the proxied device does.

if (verbose_level >= 2)
printData(io, 0x00, "control", "out");

result = control_request(&event.ctrl, &nbytes, &control_data, USB_REQUEST_TIMEOUT);
if (result == 0) {
// Ack the request.
rv = usb_raw_ep0_read(fd, (struct usb_raw_ep_io *)&io);
if (rv < 0)
printf("ep0: ack failed: %d\n", rv);
else
printf("ep0: request acked\n");
}
else {
// Stall the request.
usb_raw_ep0_stall(fd);
continue;
}
}
else {
// For non-0-length requests, we have to trieve the data and
// thus ack the request due to a Raw Gadget and libusb limitations.
// We cannot stall the request.

// Retrieve data for sending request to proxied device
// (and ack the request).
rv = usb_raw_ep0_read(fd, (struct usb_raw_ep_io *)&io);
if (rv < 0) {
printf("ep0: ack failed: %d\n", rv);
continue;
}

memcpy(control_data, io.data, event.ctrl.wLength);
if (verbose_level >= 2)
printData(io, 0x00, "control", "out");

if (verbose_level >= 2)
printData(io, 0x00, "control", "out");
memcpy(control_data, io.data, event.ctrl.wLength);

result = control_request(&event.ctrl, &nbytes, &control_data, USB_REQUEST_TIMEOUT);
if (result == 0) {
printf("ep0: transferred %d bytes (out)\n", rv);
}
else {
usb_raw_ep0_stall(fd);
result = control_request(&event.ctrl, &nbytes, &control_data, USB_REQUEST_TIMEOUT);
if (result == 0) {
printf("ep0: transferred %d bytes (out)\n", rv);
}
}
}
}
Expand Down

0 comments on commit 5f2857a

Please sign in to comment.