From f7db538ad661ce33c1cf8f378809f7d7cec0fb4c Mon Sep 17 00:00:00 2001 From: Michael Keller Date: Sun, 6 Sep 2026 11:48:53 +1200 Subject: [PATCH] Cressi GOA: cap BLE read target to remaining bytes on last packet On the final outer iteration of cressi_goa_device_download the remaining data may be fewer than SZ_DATA (512) bytes. The inner BLE accumulation loop was still asking dc_iostream_read for a full SZ_DATA block, so the BLE layer received the 16-byte EOT end-of-transfer GATT notification in response, rejected it because its length exceeded the requested size, and returned DC_STATUS_IO -- aborting the download with zero dives reported even though all payload data had already been received. Fix: compute a target byte count for the inner loop. On the first outer iteration (nbytes == 0) size has not yet been updated from the packet header, so keep target == SZ_DATA. From the second iteration onward, if (size - nbytes) < SZ_DATA, cap target to the exact number of remaining bytes. The inner loop and the dc_iostream_read call both use target instead of SZ_DATA. The EOT end-marker read that follows the outer loop is unaffected: with the capped target the inner loop exits before consuming the EOT packet, so the existing post-loop read at line 312 receives it correctly. Buffer bounds are unchanged: packetsize never exceeds target <= SZ_DATA, so writes into packet + 3 + packetsize stay within the declared packet[3 + SZ_DATA + 2] buffer. Signed-off-by: Michael Keller --- src/cressi_goa.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/cressi_goa.c b/src/cressi_goa.c index 0fe88519..c9b7fcc7 100644 --- a/src/cressi_goa.c +++ b/src/cressi_goa.c @@ -233,10 +233,20 @@ cressi_goa_device_download (cressi_goa_device_t *device, dc_buffer_t *buffer, dc if (transport == DC_TRANSPORT_BLE) { // Read the data packet. + // On the first outer iteration (nbytes == 0) size has not yet been + // updated from the packet header, so always read a full SZ_DATA + // block. On subsequent iterations cap the target to the number of + // remaining bytes so the BLE layer is not asked to read past the + // last partial packet into the 16-byte EOT end-of-transfer marker. + unsigned int target = SZ_DATA; + if (nbytes > 0 && (size - nbytes) < SZ_DATA) { + target = size - nbytes; + } + unsigned int packetsize = 0; - while (packetsize < SZ_DATA) { + while (packetsize < target) { size_t len = 0; - status = dc_iostream_read (device->iostream, packet + 3 + packetsize, SZ_DATA - packetsize, &len); + status = dc_iostream_read (device->iostream, packet + 3 + packetsize, target - packetsize, &len); if (status != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to receive the answer."); return status;