From 38bd51e63aed576805eb82370867e826d3de3806 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Sun, 25 Jul 2021 23:13:28 +0200 Subject: [PATCH 1/5] Exclude the surface time from the dive time Like most dive commputers, the Mares Genius uses a surface timeout to detect the end of the dive. But since there is no explicit dive time field stored, the total dive time is based on the number of samples, which includes this surface time at the end of the dive. However, the dive time displayed by the dive computer (and also the Mares DiveOrganizer application) does not include this surface time. For older firmware versions the value is hardcoded to 3 minutes, but starting with the newer v01.02.00 firmware the value is configurable and stored in the settings. To detect whether the setting is available, we need to check the profile version instead of the header version. That's because the header appears to be generated on-the-fly during the download, and thus the header version also changes for dives recorded prior to the firmware update. For all other models, also take into account a hardcoded timeout of 3 minutes. --- src/mares_iconhd_parser.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/src/mares_iconhd_parser.c b/src/mares_iconhd_parser.c index 34d39c7..a9ca390 100644 --- a/src/mares_iconhd_parser.c +++ b/src/mares_iconhd_parser.c @@ -143,6 +143,7 @@ struct mares_iconhd_parser_t { unsigned int samplesize; unsigned int headersize; unsigned int settings; + unsigned int surftime; unsigned int interval; unsigned int samplerate; unsigned int ntanks; @@ -347,6 +348,7 @@ mares_iconhd_cache (mares_iconhd_parser_t *parser) parser->samplesize = samplesize; parser->headersize = headersize; parser->settings = settings; + parser->surftime = 3 * 60; parser->interval = interval; parser->samplerate = samplerate; parser->ntanks = ntanks; @@ -425,6 +427,22 @@ mares_genius_cache (mares_iconhd_parser_t *parser) return DC_STATUS_DATAFORMAT; } + // Get the profile type and version. + unsigned int profile_type = array_uint16_le (data + headersize); + unsigned int profile_minor = data[headersize + 2]; + unsigned int profile_major = data[headersize + 3]; + + // Get the surface timeout setting (in minutes). + // For older firmware versions the value is hardcoded to 3 minutes, but + // starting with the newer v01.02.00 firmware the value is configurable and + // stored in the settings. To detect whether the setting is available, we + // need to check the profile version instead of the header version. + unsigned int surftime = 3; + if (profile_type == 0 && + OBJVERSION(profile_major,profile_minor) >= OBJVERSION(1,0)) { + surftime = (settings >> 13) & 0x3F; + } + // Gas mixes and tanks. unsigned int ntanks = 0; unsigned int ngasmixes = 0; @@ -476,6 +494,7 @@ mares_genius_cache (mares_iconhd_parser_t *parser) parser->samplesize = samplesize; parser->headersize = headersize; parser->settings = settings; + parser->surftime = surftime * 60; parser->interval = 5; parser->samplerate = 1; parser->ntanks = ntanks; @@ -529,6 +548,7 @@ mares_iconhd_parser_create (dc_parser_t **out, dc_context_t *context, unsigned i parser->samplesize = 0; parser->headersize = 0; parser->settings = 0; + parser->surftime = 0; parser->interval = 0; parser->samplerate = 0; parser->ntanks = 0; @@ -563,6 +583,7 @@ mares_iconhd_parser_set_data (dc_parser_t *abstract, const unsigned char *data, parser->samplesize = 0; parser->headersize = 0; parser->settings = 0; + parser->surftime = 0; parser->interval = 0; parser->samplerate = 0; parser->ntanks = 0; @@ -672,7 +693,7 @@ mares_iconhd_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi switch (type) { case DC_FIELD_DIVETIME: if (parser->model == GENIUS || parser->model == HORIZON) { - *((unsigned int *) value) = parser->nsamples * parser->interval; + *((unsigned int *) value) = parser->nsamples * parser->interval - parser->surftime; } else if (parser->model == SMARTAPNEA) { *((unsigned int *) value) = array_uint16_le (p + 0x24); } else if (parser->mode == ICONHD_FREEDIVE) { @@ -684,7 +705,7 @@ mares_iconhd_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi } *((unsigned int *) value) = divetime; } else { - *((unsigned int *) value) = parser->nsamples * parser->interval; + *((unsigned int *) value) = parser->nsamples * parser->interval - parser->surftime; } break; case DC_FIELD_MAXDEPTH: From 58d410b1a217bbc1f03d5c7a5a203c139a92616c Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Sun, 8 Aug 2021 20:20:31 +0200 Subject: [PATCH 2/5] Add BLE support for the Aqualung i750TC The Aqualung i750TC supports BLE, but the BLE handshaking fails and needs to be disabled. --- src/descriptor.c | 3 ++- src/oceanic_atom2.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/descriptor.c b/src/descriptor.c index c21cefe..cd04e67 100644 --- a/src/descriptor.c +++ b/src/descriptor.c @@ -251,7 +251,7 @@ static const dc_descriptor_t g_descriptors[] = { {"Sherwood", "Vision", DC_FAMILY_OCEANIC_ATOM2, 0x4556, DC_TRANSPORT_SERIAL, NULL}, {"Oceanic", "VTX", DC_FAMILY_OCEANIC_ATOM2, 0x4557, DC_TRANSPORT_SERIAL, NULL}, {"Aqualung", "i300", DC_FAMILY_OCEANIC_ATOM2, 0x4559, DC_TRANSPORT_SERIAL, NULL}, - {"Aqualung", "i750TC", DC_FAMILY_OCEANIC_ATOM2, 0x455A, DC_TRANSPORT_SERIAL, NULL}, + {"Aqualung", "i750TC", DC_FAMILY_OCEANIC_ATOM2, 0x455A, DC_TRANSPORT_SERIAL | DC_TRANSPORT_BLE, NULL}, {"Aqualung", "i450T", DC_FAMILY_OCEANIC_ATOM2, 0x4641, DC_TRANSPORT_SERIAL, NULL}, {"Aqualung", "i550", DC_FAMILY_OCEANIC_ATOM2, 0x4642, DC_TRANSPORT_SERIAL, NULL}, {"Aqualung", "i200", DC_FAMILY_OCEANIC_ATOM2, 0x4646, DC_TRANSPORT_SERIAL, NULL}, @@ -666,6 +666,7 @@ static int dc_filter_oceanic (dc_transport_t transport, const void *userdata, vo { static const unsigned int model[] = { 0x4552, // Oceanic Pro Plus X + 0x455A, // Aqualung i750TC 0x4647, // Sherwood Sage 0x4648, // Aqualung i300C 0x4649, // Aqualung i200C diff --git a/src/oceanic_atom2.c b/src/oceanic_atom2.c index 63fdd64..fdd0e70 100644 --- a/src/oceanic_atom2.c +++ b/src/oceanic_atom2.c @@ -36,6 +36,7 @@ #define ISINSTANCE(device) dc_device_isinstance((device), &oceanic_atom2_device_vtable.base) #define PROPLUSX 0x4552 +#define I750TC 0x455A #define VTX 0x4557 #define I750TC 0x455A #define SAGE 0x4647 @@ -907,7 +908,7 @@ oceanic_atom2_device_open (dc_device_t **out, dc_context_t *context, dc_iostream } if (dc_iostream_get_transport (device->iostream) == DC_TRANSPORT_BLE && - model != PROPLUSX && model != SAGE && model != BEACON) { + model != PROPLUSX && model != I750TC && model != SAGE && model != BEACON) { status = oceanic_atom2_ble_handshake(device); if (status != DC_STATUS_SUCCESS) { goto error_free; From 03974481b0f29d432aea41ebeb9d75291097dfde Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Mon, 9 Aug 2021 10:04:17 +0200 Subject: [PATCH 3/5] Remove duplicate macro definition --- src/oceanic_atom2.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/oceanic_atom2.c b/src/oceanic_atom2.c index fdd0e70..060a1cc 100644 --- a/src/oceanic_atom2.c +++ b/src/oceanic_atom2.c @@ -36,7 +36,6 @@ #define ISINSTANCE(device) dc_device_isinstance((device), &oceanic_atom2_device_vtable.base) #define PROPLUSX 0x4552 -#define I750TC 0x455A #define VTX 0x4557 #define I750TC 0x455A #define SAGE 0x4647 From 70d3cdcc08b0dfb7bf53ebed964d14469fde6261 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Sun, 18 Jul 2021 23:38:38 +0200 Subject: [PATCH 4/5] Use symbolic constant for invalid value --- src/divesystem_idive_parser.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/divesystem_idive_parser.c b/src/divesystem_idive_parser.c index b8d103d..a6375a0 100644 --- a/src/divesystem_idive_parser.c +++ b/src/divesystem_idive_parser.c @@ -322,7 +322,7 @@ divesystem_idive_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, water->density = 0.0; break; case DC_FIELD_DIVEMODE: - if (parser->divemode == 0xFFFFFFFF) + if (parser->divemode == INVALID) return DC_STATUS_UNSUPPORTED; switch (parser->divemode) { case OC: @@ -367,8 +367,8 @@ divesystem_idive_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callba unsigned int ntanks = 0; divesystem_idive_gasmix_t gasmix[NGASMIXES] = {0}; divesystem_idive_tank_t tank[NTANKS] = {0}; - unsigned int o2_previous = 0xFFFFFFFF; - unsigned int he_previous = 0xFFFFFFFF; + unsigned int o2_previous = INVALID; + unsigned int he_previous = INVALID; unsigned int mode_previous = INVALID; unsigned int divemode = INVALID; unsigned int tank_previous = INVALID; From e0409a9496ec53cfa4cd0bef55db6437d5c3d727 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Tue, 17 Aug 2021 17:53:16 +0200 Subject: [PATCH 5/5] Add support for the Cressi Neon The Cressi Neon appears to be compatible with the Goa and Cartesio, with just a different model number. --- src/descriptor.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/descriptor.c b/src/descriptor.c index cd04e67..06b0243 100644 --- a/src/descriptor.c +++ b/src/descriptor.c @@ -328,6 +328,7 @@ static const dc_descriptor_t g_descriptors[] = { /* Cressi Goa */ {"Cressi", "Cartesio", DC_FAMILY_CRESSI_GOA, 1, DC_TRANSPORT_SERIAL, NULL}, {"Cressi", "Goa", DC_FAMILY_CRESSI_GOA, 2, DC_TRANSPORT_SERIAL, NULL}, + {"Cressi", "Neon", DC_FAMILY_CRESSI_GOA, 9, DC_TRANSPORT_SERIAL, NULL}, /* Zeagle N2iTiON3 */ {"Zeagle", "N2iTiON3", DC_FAMILY_ZEAGLE_N2ITION3, 0, DC_TRANSPORT_SERIAL, NULL}, {"Apeks", "Quantum X", DC_FAMILY_ZEAGLE_N2ITION3, 0, DC_TRANSPORT_SERIAL, NULL},