From 28c27e23921e61264538ebba37baedc27af0a0f6 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Wed, 2 Nov 2022 10:06:20 -0700 Subject: [PATCH] uwatec smart: allow bigger BLE packets It looks like the Scubapro G2 firmware update to v2.0 ended up increasing the BLE packet size, which broke our downloader. The logic is shared with the USB HID code, and the way USB HID works is that the packet is fixed at 64 bytes, and the first byte contains the actual payload size. So you could have up to 63 bytes of actual data per packet, and that used to be the limit for the BLE side too. However, now that the BLE side has bigger packets, using a 64-byte packet buffer broke horribly, and caused the new 101-byte BLE packets (one byte of odd data, and 100 bytes of actual payload) to be read as a 64-byte packet followed by a 37-byte one, and that just didn't work at all. At the same time, we cannot just increase the receive packet size, because that makes src/usbhid.c very unhappy at least for the USE_LIBUSB case, because using a bigger buffer for "libusb_interrupt_transfer()" will then wait for more than one packet to arrive. Which obviously doesn't happen when you only get a small reply, and so it all goes south. Fixing src/usbhid.c to only ever ask for 64 bytes at a time is probably the right thing to do, but this instead just makes the Uwatec downloader look at what protocol it uses instead. So if it's USB HID, we use a 64-bit buffer, and for BLE we use a maximum buffer size that then gets filled in with whatever the actual packet size was. Reported-by: Link: https://groups.google.com/d/msgid/subsurface-divelog/5d653bbd-5cad-4522-bb46-9e0319e465bbn%40googlegroups.com Signed-off-by: Linus Torvalds --- src/uwatec_smart.c | 27 ++++++++++++++++++++++----- 1 file changed, 22 insertions(+), 5 deletions(-) diff --git a/src/uwatec_smart.c b/src/uwatec_smart.c index d5d7ab0..fd8a906 100644 --- a/src/uwatec_smart.c +++ b/src/uwatec_smart.c @@ -32,6 +32,7 @@ #define ISINSTANCE(device) dc_device_isinstance((device), &uwatec_smart_device_vtable) #define DATASIZE 254 +#define MAX_PACKETSIZE 256 #define PACKETSIZE_USBHID_RX 64 #define PACKETSIZE_USBHID_TX 32 @@ -308,12 +309,26 @@ uwatec_smart_usbhid_receive (uwatec_smart_device_t *device, dc_event_progress_t { dc_status_t rc = DC_STATUS_SUCCESS; dc_device_t *abstract = (dc_device_t *) device; - unsigned char buf[PACKETSIZE_USBHID_RX]; + unsigned char buf[MAX_PACKETSIZE]; + dc_transport_t transport; + unsigned int pktsize; + + /* + * USB HID uses 64-byte packets, BLE uses variable sized ones. + * + * BLE used to be limited to 64 bytes too, but firmware 2.0 + * seems to have increased that to at least 101 bytes (one odd + * byte header and 100 bytes of data). + */ + transport = dc_iostream_get_transport(device->iostream); + pktsize = sizeof(buf); + if (transport == DC_TRANSPORT_USBHID) + pktsize = PACKETSIZE_USBHID_RX; size_t nbytes = 0; while (nbytes < size) { size_t transferred = 0; - rc = dc_iostream_read (device->iostream, buf, sizeof(buf), &transferred); + rc = dc_iostream_read (device->iostream, buf, pktsize, &transferred); if (rc != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the packet."); return rc; @@ -362,9 +377,11 @@ uwatec_smart_usbhid_receive (uwatec_smart_device_t *device, dc_event_progress_t * * It may be just an oddly implemented sequence number. Whatever. */ - unsigned int len = buf[0]; - if (len + 1 > transferred) - len = transferred-1; + unsigned int len = transferred-1; + if (transport == DC_TRANSPORT_USBHID) { + if (len > buf[0]) + len = buf[0]; + } HEXDUMP (abstract->context, DC_LOGLEVEL_DEBUG, "rcv", buf + 1, len);