Prefer hardcoded PN533 descriptors to the real ones

PN533 easily corrupts its USB descriptors. We know that and we
already try to detect and even repair them.

However there are situations where lower software layers get
confused before libnfc can help. On Windows, libusb may set
dev->config to NULL, but we can also have a non NULL dev->config
referencing corrupted data.

In order to get more robust, let us replace the Windows libusb
specific (dev->config == NULL) test by an inconditionnal use of
hardcoded descriptors when they are available.
This commit is contained in:
Emmanuel Dreyfus 2018-11-12 15:26:43 +00:00 committed by Romuald Conty
parent ddfe2e648a
commit 85100c0aae

View file

@ -236,7 +236,7 @@ pn53x_usb_get_device_model(uint16_t vendor_id, uint16_t product_id)
return UNKNOWN; return UNKNOWN;
} }
static void static bool
pn53x_usb_get_end_points_default(struct usb_device *dev, struct pn53x_usb_data *data) pn53x_usb_get_end_points_default(struct usb_device *dev, struct pn53x_usb_data *data)
{ {
for (size_t n = 0; n < sizeof(pn53x_usb_supported_devices) / sizeof(struct pn53x_usb_supported_device); n++) { for (size_t n = 0; n < sizeof(pn53x_usb_supported_devices) / sizeof(struct pn53x_usb_supported_device); n++) {
@ -246,13 +246,13 @@ pn53x_usb_get_end_points_default(struct usb_device *dev, struct pn53x_usb_data *
data->uiEndPointIn = pn53x_usb_supported_devices[n].uiEndPointIn; data->uiEndPointIn = pn53x_usb_supported_devices[n].uiEndPointIn;
data->uiEndPointOut = pn53x_usb_supported_devices[n].uiEndPointOut; data->uiEndPointOut = pn53x_usb_supported_devices[n].uiEndPointOut;
data->uiMaxPacketSize = pn53x_usb_supported_devices[n].uiMaxPacketSize; data->uiMaxPacketSize = pn53x_usb_supported_devices[n].uiMaxPacketSize;
}
return; return true;
}
} }
} }
return; return false;
} }
int pn53x_usb_ack(nfc_device *pnd); int pn53x_usb_ack(nfc_device *pnd);
@ -305,13 +305,12 @@ pn53x_usb_scan(const nfc_context *context, nfc_connstring connstrings[], const s
if ((pn53x_usb_supported_devices[n].vendor_id == dev->descriptor.idVendor) && if ((pn53x_usb_supported_devices[n].vendor_id == dev->descriptor.idVendor) &&
(pn53x_usb_supported_devices[n].product_id == dev->descriptor.idProduct)) { (pn53x_usb_supported_devices[n].product_id == dev->descriptor.idProduct)) {
// Make sure there are 2 endpoints available // Make sure there are 2 endpoints available
// with libusb-win32 we got some null pointers so be robust before looking at endpoints: // libusb-win32 may return a NULL dev->config,
if (dev->config == NULL) { // or the descriptoes may be corrupted, hence
// We tolerate null config if we have defaults // let us assume we will use hardcoded defaults
if (pn53x_usb_supported_devices[n].uiMaxPacketSize == 0) // from n53x_usb_supported_devices if available.
// Nope, we maybe want the next one, let's try to find another // otherwise get data from the descriptors.
continue; if (pn53x_usb_supported_devices[n].uiMaxPacketSize == 0) {
} else {
if (dev->config->interface == NULL || dev->config->interface->altsetting == NULL) { if (dev->config->interface == NULL || dev->config->interface->altsetting == NULL) {
// Nope, we maybe want the next one, let's try to find another // Nope, we maybe want the next one, let's try to find another
continue; continue;
@ -422,11 +421,9 @@ pn53x_usb_open(const nfc_context *context, const nfc_connstring connstring)
// Open the USB device // Open the USB device
if ((data.pudh = usb_open(dev)) == NULL) if ((data.pudh = usb_open(dev)) == NULL)
continue; continue;
// Retrieve end points, using default if dev->config is broken // Retrieve end points, using hardcoded defaults if available
if (dev->config == NULL) { // or using the descriptors otherwise.
pn53x_usb_get_end_points_default(dev, &data); if (pn53x_usb_get_end_points_default(dev, &data) == false) {
data.possibly_corrupted_usbdesc = true;
} else {
pn53x_usb_get_end_points(dev, &data); pn53x_usb_get_end_points(dev, &data);
} }
// Set configuration // Set configuration