fix(piusb): fix 4 bugs in USB read/write/enumeration/close

1. Missing break in readDevice() Bulk case: Bulk read result was
   overwritten by interrupt read, silently corrupting all bulk reads.

2. Wrong variable in writeDevice(): switch checked ep_read instead
   of ep_write; Interrupt case used ep_read.address for writes.

3. Interface mismatch in closeDevice(): always released interface 0
   (intefrace_) instead of the actually claimed interface
   (interface_claimed), leaking non-zero interface claims.

4. Wrong index in interface enumeration: used outer loop variable c
   (configuration index) instead of i (interface index), reading
   wrong interface descriptors or causing OOB access.
This commit is contained in:
2026-08-10 16:26:30 +03:00
parent 69673ff7c6
commit ace5960e70
+5 -4
View File
@@ -239,7 +239,7 @@ bool PIUSB::openDevice() {
for (int i = 0; i < dc.bNumInterfaces; ++i) {
conf.interfaces << Interface();
Interface & infc(conf.interfaces.back());
struct usb_interface_descriptor * di(dc.interface[c].altsetting);
struct usb_interface_descriptor * di(dc.interface[i].altsetting);
infc.index = i;
infc.value_to_select = di->bAlternateSetting;
infc.class_code = di->bInterfaceClass;
@@ -320,7 +320,7 @@ bool PIUSB::openDevice() {
bool PIUSB::closeDevice() {
#ifdef PIP_USB
if (hdev == 0) return true;
usb_release_interface(hdev, intefrace_);
if (interface_claimed >= 0) usb_release_interface(hdev, interface_claimed);
usb_close(hdev);
hdev = 0;
interface_claimed = -1;
@@ -340,6 +340,7 @@ ssize_t PIUSB::readDevice(void * read_to, ssize_t max_size) {
case Endpoint::Bulk:
/*piCoutObj << "bulk read" << max_size;*/
ret = usb_bulk_read(hdev, ep_read.address, (char *)read_to, max_size, timeout_r);
break;
case Endpoint::Interrupt: ret = usb_interrupt_read(hdev, ep_read.address, (char *)read_to, max_size, timeout_r);
default: break;
}
@@ -354,11 +355,11 @@ ssize_t PIUSB::readDevice(void * read_to, ssize_t max_size) {
ssize_t PIUSB::writeDevice(const void * data, ssize_t max_size) {
#ifdef PIP_USB
if (isClosed() || ep_write.isNull()) return -1;
switch (ep_read.transfer_type) {
switch (ep_write.transfer_type) {
case Endpoint::Bulk:
/*piCoutObj << "bulk write" << max_size;*/
return usb_bulk_write(hdev, ep_write.address, (char *)const_cast<void *>(data), max_size, timeout_w);
case Endpoint::Interrupt: return usb_interrupt_write(hdev, ep_read.address, (char *)data, max_size, timeout_w);
case Endpoint::Interrupt: return usb_interrupt_write(hdev, ep_write.address, (char *)data, max_size, timeout_w);
default: break;
}
return -1;