From 9df5e29375d8c231eb3b03ef28cb6c1c534044a3 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Thu, 13 Aug 2026 19:11:27 +0200 Subject: [PATCH 1/2] Fix the detection of the info record Since APOS5 firmware 5.2.11, the record type field is no longer a simple record type. The higher bits are re-used to store additional info. For backwards compatibility, these new features are only present on the sample records and at least one of the higher bits will be set to indicate their presence. Hence the info record with the GPS coordinates can still be detected with the legacy value 1. --- src/divesystem_idive_parser.c | 21 ++++++--------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/src/divesystem_idive_parser.c b/src/divesystem_idive_parser.c index e913968d..a42aae55 100644 --- a/src/divesystem_idive_parser.c +++ b/src/divesystem_idive_parser.c @@ -58,9 +58,7 @@ #define IX3M2_ZHL16C 2 #define IX3M2_VPM 3 -#define REC_SAMPLE 0 #define REC_INFO 1 -#define REC_SAMPLE_APOS5_COMPAT 0x8006 typedef struct divesystem_idive_parser_t divesystem_idive_parser_t; @@ -450,19 +448,12 @@ divesystem_idive_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callba // Get the record type. unsigned int type = ISIX3M(parser->model) ? array_uint16_le (data + offset + 52) : - REC_SAMPLE; - // AI-generated (Claude) - // APOS5 uses 0x8006 for ordinary profile samples. Keep this alias - // narrow until the record type is confirmed by the vendor. - if (firmware_major >= 5 && type == REC_SAMPLE_APOS5_COMPAT) - type = REC_SAMPLE; - if (type != REC_SAMPLE) { - if (type == REC_INFO) { - altitude = (signed int) array_uint32_le (data + offset + 40); - longitude = (signed int) array_uint32_le (data + offset + 44); - latitude = (signed int) array_uint32_le (data + offset + 48); - have_location = 1; - } + 0; + if (type == REC_INFO) { + altitude = (signed int) array_uint32_le (data + offset + 40); + longitude = (signed int) array_uint32_le (data + offset + 44); + latitude = (signed int) array_uint32_le (data + offset + 48); + have_location = 1; // Skip non-sample records. offset += samplesize; From 07cf8df4a7fca1a432e78c23189d0ae8f69ed641 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Tue, 18 Aug 2026 19:31:03 +0200 Subject: [PATCH 2/2] Parse the new higher type bits Since APOS5 firmware 5.2.11, the higher bits store new tank related information: - An extra 9th bit for the tank pressure data to support high pressure (300 bar) tanks without reduced resolution. The new firmware no longer sets the legacy 300 bar bit. - The transmitter RF channel. Currently unused because the transmitter index is still present to identify the active tank and is also available with older firmware versions. --- src/divesystem_idive_parser.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/divesystem_idive_parser.c b/src/divesystem_idive_parser.c index a42aae55..724206e9 100644 --- a/src/divesystem_idive_parser.c +++ b/src/divesystem_idive_parser.c @@ -60,6 +60,10 @@ #define REC_INFO 1 +#define TANK_VALID 0x8000 +#define TANK_RFCHANNEL 0x001F +#define TANK_PRESSURE_MSB 0x0020 + typedef struct divesystem_idive_parser_t divesystem_idive_parser_t; typedef struct divesystem_idive_gasmix_t { @@ -579,6 +583,14 @@ divesystem_idive_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callba unsigned int id = data[offset + 47] & 0x0F; unsigned int flags = data[offset + 47] & 0xF0; unsigned int pressure = data[offset + 49]; + unsigned int DC_ATTR_UNUSED rfchannel = 0; + + if (type & TANK_VALID) { + rfchannel = type & TANK_RFCHANNEL; + if (type & TANK_PRESSURE_MSB) { + pressure |= 0x100; + } + } if (flags & 0x20) { // 300 bar transmitter.