From ae503626ae8d43d57a8a6ffed79e3ff0e4860ffb Mon Sep 17 00:00:00 2001 From: Dirk Hohndel Date: Fri, 7 Sep 2018 16:15:21 -0700 Subject: [PATCH] Shearwater: detect which logbook format is support The Log Upload RDBI (Read Data by Identifier) response tells us which format the dive computer supports. Shearwater recommends to use the 'Petrel Native Format' for all dive computers which support it, even those pre-Teric models which (depending on firmware) might support both PNF and the older 'Predator-Like Format'. They also recommend to ignore the 0x90000000 format which is very similar to PNF but without the final record and to use the older Predator Like Format in that case. The 0xDD000000 format is never an option by the time you got here, but in the old code (prior to the PNF addition) we would have fallen back to 0xC0000000, so let's do the same here. Any other value is actually an unknown format and should be treated as such. Which format we use is determined by the base address used to download the logbook entries. Signed-off-by: Dirk Hohndel --- src/shearwater_common.h | 7 ++++--- src/shearwater_petrel.c | 39 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 41 insertions(+), 5 deletions(-) diff --git a/src/shearwater_common.h b/src/shearwater_common.h index 8798853..35a0d01 100644 --- a/src/shearwater_common.h +++ b/src/shearwater_common.h @@ -30,9 +30,10 @@ extern "C" { #endif /* __cplusplus */ -#define ID_SERIAL 0x8010 -#define ID_FIRMWARE 0x8011 -#define ID_HARDWARE 0x8050 +#define ID_SERIAL 0x8010 +#define ID_FIRMWARE 0x8011 +#define ID_LOGUPLOAD 0x8021 +#define ID_HARDWARE 0x8050 #define PREDATOR 2 #define PETREL 3 diff --git a/src/shearwater_petrel.c b/src/shearwater_petrel.c index e6b6a59..a8b1995 100644 --- a/src/shearwater_petrel.c +++ b/src/shearwater_petrel.c @@ -26,6 +26,7 @@ #include "shearwater_common.h" #include "context-private.h" #include "device-private.h" +#include "platform.h" #include "array.h" #define ISINSTANCE(device) dc_device_isinstance((device), &shearwater_petrel_device_vtable) @@ -33,7 +34,6 @@ #define MANIFEST_ADDR 0xE0000000 #define MANIFEST_SIZE 0x600 -#define DIVE_ADDR 0xC0000000 #define DIVE_SIZE 0xFFFFFF #define RECORD_SIZE 0x20 @@ -243,6 +243,41 @@ shearwater_petrel_device_foreach (dc_device_t *abstract, dc_dive_callback_t call devinfo.serial = array_uint32_be (serial); device_event_emit (abstract, DC_EVENT_DEVINFO, &devinfo); + // Read the logbook type + rc = shearwater_common_identifier (&device->base, buffer, ID_LOGUPLOAD); + if (rc != DC_STATUS_SUCCESS) { + ERROR (abstract->context, "Failed to read the logbook type."); + dc_buffer_free (buffer); + dc_buffer_free (manifests); + return rc; + } + + if (dc_buffer_get_size (buffer) != 9) { + ERROR (abstract->context, "Unexpected packet size (" DC_PRINTF_SIZE " bytes).", dc_buffer_get_size(buffer)); + dc_buffer_free (buffer); + dc_buffer_free (manifests); + return DC_STATUS_DATAFORMAT; + } + + unsigned int base_addr = array_uint32_be (dc_buffer_get_data (buffer) + 1); + switch (base_addr) { + case 0xDD000000: // Predator - we shouldn't get here, we could give up or we can try 0xC0000000 + case 0xC0000000: // Predator-Like Format (what we used to call the Petrel format) + case 0x90000000: // some firmware versions supported an earlier version of PNF without final record + // use the Predator-Like Format instead + base_addr = 0xC0000000; + break; + case 0x80000000: // new Petrel Native Format with final record + // that's the correct address + break; + default: // unknown format + ERROR (abstract->context, "Unknown logbook format %08x", base_addr); + dc_buffer_free (buffer); + dc_buffer_free (manifests); + return DC_STATUS_DATAFORMAT; + } + + // Read the manifest pages while (1) { // Update the progress state. // Assume the worst case scenario of a full manifest, and adjust the @@ -327,7 +362,7 @@ shearwater_petrel_device_foreach (dc_device_t *abstract, dc_dive_callback_t call // Download the dive. progress.current = NSTEPS * current; progress.maximum = NSTEPS * maximum; - rc = shearwater_common_download (&device->base, buffer, DIVE_ADDR + address, DIVE_SIZE, 1, &progress); + rc = shearwater_common_download (&device->base, buffer, base_addr + address, DIVE_SIZE, 1, &progress); if (rc != DC_STATUS_SUCCESS) { ERROR (abstract->context, "Failed to download the dive."); dc_buffer_free (buffer);