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: <jmejul13@gmail.com>
Link: https://groups.google.com/d/msgid/subsurface-divelog/5d653bbd-5cad-4522-bb46-9e0319e465bbn%40googlegroups.com
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Linus Torvalds 2022-11-02 10:06:20 -07:00
parent 43a503f6f0
commit 28c27e2392

View File

@ -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);