From 57cd11fffe4c44d6323a4d5b2bfd04e9e0f5a7a4 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Tue, 15 Sep 2020 21:24:45 +0200 Subject: [PATCH] Add the extra 5 bytes containing the divemode The logbook header has 5 bytes extra, which are not present in the dive header. Those 5 extra bytes contain the dive mode, which is required for parsing the dive data. Therefore, insert all 5 bytes again and update the parser. The remaining 4 bytes appear to be some 32 bit address. They are not used for anything right now, but are preserved as well in case they are needed in the future. --- src/cressi_goa.c | 14 +++++++++++++- src/cressi_goa_parser.c | 43 +++++++++++++++++++++++++++++++---------- 2 files changed, 46 insertions(+), 11 deletions(-) diff --git a/src/cressi_goa.c b/src/cressi_goa.c index f6df023..e414743 100644 --- a/src/cressi_goa.c +++ b/src/cressi_goa.c @@ -485,7 +485,19 @@ cressi_goa_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, v goto error_free_dive; } - if (callback && !callback(dive_data, dive_size, dive_data + FP_OFFSET - 5, sizeof(device->fingerprint), userdata)) + // Those 5 extra bytes contain the dive mode, which is required for + // parsing the dive data. Therefore, insert all 5 bytes again. The + // remaining 4 bytes appear to be some 32 bit address. + if (!dc_buffer_insert (dive, 2, logbook_data + offset + 2, 5)) { + ERROR (abstract->context, "Out of memory."); + status = DC_STATUS_NOMEMORY; + goto error_free_dive; + } + + dive_data = dc_buffer_get_data (dive); + dive_size = dc_buffer_get_size (dive); + + if (callback && !callback(dive_data, dive_size, dive_data + FP_OFFSET, sizeof(device->fingerprint), userdata)) break; } diff --git a/src/cressi_goa_parser.c b/src/cressi_goa_parser.c index d7599dc..579d662 100644 --- a/src/cressi_goa_parser.c +++ b/src/cressi_goa_parser.c @@ -28,11 +28,16 @@ #define ISINSTANCE(parser) dc_device_isinstance((parser), &cressi_goa_parser_vtable) -#define SZ_HEADER 0x5C +#define SZ_HEADER 0x61 #define DEPTH 0 #define TEMPERATURE 3 +#define SCUBA 0 +#define NITROX 1 +#define FREEDIVE 2 +#define GAUGE 3 + typedef struct cressi_goa_parser_t cressi_goa_parser_t; struct cressi_goa_parser_t { @@ -100,14 +105,14 @@ cressi_goa_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime) if (abstract->size < SZ_HEADER) return DC_STATUS_DATAFORMAT; - const unsigned char *p = abstract->data; + const unsigned char *p = abstract->data + 0x11; if (datetime) { - datetime->year = array_uint16_le(p + 0x0C); - datetime->month = p[0x0E]; - datetime->day = p[0x0F]; - datetime->hour = p[0x10]; - datetime->minute = p[0x11]; + datetime->year = array_uint16_le(p); + datetime->month = p[2]; + datetime->day = p[3]; + datetime->hour = p[4]; + datetime->minute = p[5]; datetime->second = 0; datetime->timezone = DC_TIMEZONE_NONE; } @@ -119,10 +124,12 @@ static dc_status_t cressi_goa_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned int flags, void *value) { cressi_goa_parser_t *parser = (cressi_goa_parser_t *) abstract; + const unsigned char *data = abstract->data; + if (abstract->size < SZ_HEADER) return DC_STATUS_DATAFORMAT; - const unsigned char *data = abstract->data; + unsigned int divemode = data[2]; if (!parser->cached) { sample_statistics_t statistics = SAMPLE_STATISTICS_INITIALIZER; @@ -140,7 +147,7 @@ cressi_goa_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsign if (value) { switch (type) { case DC_FIELD_DIVETIME: - *((unsigned int *) value) = array_uint16_le (data + 0x14); + *((unsigned int *) value) = array_uint16_le (data + 0x19); break; case DC_FIELD_MAXDEPTH: *((double *) value) = parser->maxdepth; @@ -150,9 +157,25 @@ cressi_goa_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsign break; case DC_FIELD_GASMIX: gasmix->helium = 0.0; - gasmix->oxygen = data[0x1B + 2 * flags] / 100.0; + gasmix->oxygen = data[0x20 + 2 * flags] / 100.0; gasmix->nitrogen = 1.0 - gasmix->oxygen - gasmix->helium; break; + case DC_FIELD_DIVEMODE: + switch (divemode) { + case SCUBA: + case NITROX: + *((dc_divemode_t *) value) = DC_DIVEMODE_OC; + break; + case GAUGE: + *((dc_divemode_t *) value) = DC_DIVEMODE_GAUGE; + break; + case FREEDIVE: + *((dc_divemode_t *) value) = DC_DIVEMODE_FREEDIVE; + break; + default: + return DC_STATUS_DATAFORMAT; + } + break; default: return DC_STATUS_UNSUPPORTED; }