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:
+7
-6
@@ -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;
|
||||
@@ -287,7 +287,7 @@ bool PIUSB::openDevice() {
|
||||
} // else piCoutObj << "ok";
|
||||
// usb_reset(hdev);
|
||||
|
||||
// usb_set_configuration(hdev, 1);
|
||||
// usb_set_configuration(hdev, 1);
|
||||
// usb_set_altinterface(hdev, 0);
|
||||
|
||||
# ifndef WINDOWS
|
||||
@@ -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;
|
||||
@@ -442,7 +443,7 @@ PICout operator<<(PICout s, const PIUSB::Endpoint & v) {
|
||||
PIString PIUSB::constructFullPathDevice() const {
|
||||
PIString ret;
|
||||
ret = PIString::fromNumber(vendorID(), 16).toLowerCase() + ":" + PIString::fromNumber(productID(), 16).toLowerCase() + ":" +
|
||||
deviceNumber() + ":" + endpointRead().address + ":" + endpointWrite().address;
|
||||
deviceNumber() + ":" + endpointRead().address + ":" + endpointWrite().address;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user