From ba4a119a4f2bb45d97d0c31adbbd1fa6e1b635f4 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Thu, 7 Oct 2021 19:56:52 +0200 Subject: [PATCH 1/2] Detect NAK response packets When the dive computer receives a command it doesn't support, it sends back a single byte NAK (0xA5) packet instead of the expected ACK byte (0x5A) at the start of the packet. Retrying is pointless in this case, because the next attempt will also fail. Instead, return immediately with an appropriate error code, and let the upper layers handle the unsupported command. Note that the detection is currently only enabled for BLE communication. --- src/oceanic_atom2.c | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/src/oceanic_atom2.c b/src/oceanic_atom2.c index 060a1cc..c327ceb 100644 --- a/src/oceanic_atom2.c +++ b/src/oceanic_atom2.c @@ -682,6 +682,22 @@ oceanic_atom2_packet (oceanic_atom2_device_t *device, const unsigned char comman return status; } + // Verify the number of bytes. + if (nbytes < 1) { + ERROR (abstract->context, "Invalid packet size (%u).", nbytes); + return DC_STATUS_PROTOCOL; + } + + // Verify the ACK byte of the answer. + if (packet[0] != ack) { + ERROR (abstract->context, "Unexpected answer start byte(s)."); + if (packet[0] == (unsigned char) ~ack) { + return DC_STATUS_UNSUPPORTED; + } else { + return DC_STATUS_PROTOCOL; + } + } + // Verify the number of bytes. if (nbytes < 1 + asize + crc_size) { ERROR (abstract->context, "Unexpected number of bytes received (%u %u).", nbytes, 1 + asize + crc_size); @@ -690,12 +706,6 @@ oceanic_atom2_packet (oceanic_atom2_device_t *device, const unsigned char comman nbytes -= 1 + crc_size; - // Verify the ACK byte of the answer. - if (packet[0] != ack) { - ERROR (abstract->context, "Unexpected answer start byte(s)."); - return DC_STATUS_PROTOCOL; - } - if (asize) { // Verify the checksum of the answer. unsigned short crc, ccrc; From cd0f42804af70845c08e6b0d589b45feaef53f1c Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Thu, 7 Oct 2021 19:57:23 +0200 Subject: [PATCH 2/2] Ignore unsupported BLE handshake For some BLE enabled models, like the Oceanic Pro Plus X, Aqualung i750TC, Sherwood Sage and Sherwood Beacon, the BLE handshake command is not supported and therefore disabled. However, based on a bug report by a user with two Aqualung i770R dive computers, this detection mechanism based on the dive computer model number isn't sufficient. Allthough the two devices have the exact same firmware version (2A), the handshake command only works on the newest unit, and fails with a NAK response on the oldest unit. Remove the model based detection and always try to send the handshake command and rely on the NAK response to ignore the failure instead. An additional advantage is that we no longer have to (manually) maintain a list with the model numbers where the handshaking is known to fail. --- src/oceanic_atom2.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/oceanic_atom2.c b/src/oceanic_atom2.c index c327ceb..16cf43e 100644 --- a/src/oceanic_atom2.c +++ b/src/oceanic_atom2.c @@ -819,8 +819,14 @@ oceanic_atom2_ble_handshake(oceanic_atom2_device_t *device) // Send the command to the dive computer. rc = oceanic_atom2_transfer (device, handshake, sizeof(handshake), ACK, NULL, 0, 0); - if (rc != DC_STATUS_SUCCESS) - return rc; + if (rc != DC_STATUS_SUCCESS) { + if (rc == DC_STATUS_UNSUPPORTED) { + WARNING (abstract->context, "Bluetooth handshake not supported."); + return DC_STATUS_SUCCESS; + } else { + return rc; + } + } return DC_STATUS_SUCCESS; } @@ -916,8 +922,7 @@ oceanic_atom2_device_open (dc_device_t **out, dc_context_t *context, dc_iostream goto error_free; } - if (dc_iostream_get_transport (device->iostream) == DC_TRANSPORT_BLE && - model != PROPLUSX && model != I750TC && model != SAGE && model != BEACON) { + if (dc_iostream_get_transport (device->iostream) == DC_TRANSPORT_BLE) { status = oceanic_atom2_ble_handshake(device); if (status != DC_STATUS_SUCCESS) { goto error_free;