From 8cc8ec82a733ac545195ce5d6f04e8939cd706b1 Mon Sep 17 00:00:00 2001 From: Michael Keller Date: Tue, 13 Oct 2026 17:07:09 +1300 Subject: [PATCH] shearwater_predator_parser: gate GTR-mode sidemount detection by log version In LOG_RECORD_OPENING_4, the GTR (Gas Time Remaining) mode byte at offset 29 was read unconditionally, while the adjacent AI (Air Integration) mode byte at offset 28 is read only for logversion >= 7. For logversion < 7 (pre-Perdix AI logs), offset 29 is not part of any documented field and could contain arbitrary data, risking a spurious DC_TANK_USAGE_SIDEMOUNT classification from popcount(gtrmode) >= 2. Evidence for the gate: - Shearwater's "SRIAppLayer - Log File Formats" document (log upload protocol spec) describes GTR Mode's "prior to Log Version 13" value set (0 = disabled, 1 = T1, 2 = T2) as structurally identical to AI Mode's pre-13 value set, and GTR is explicitly computed from the T1/T2 wireless air-integration transmitters, so it cannot be meaningful before AI support exists. - libdc's own code consistently gates every AI-dependent field (aimode at offset 28, dive-sample tank pressure, battery type reporting) with `logversion >= 7`, with the tank-pressure gate commented "introduced for Perdix AI". No source states in so many words "GTR Mode introduced in log version 7"; the conclusion is inferred from the matching pre-13 value scheme and GTR's dependency on AI transmitter data, which is the same reasoning basis used for the existing aimode gate. Given that, this change reuses the same `logversion >= 7` condition that already guards the aimode read, rather than inventing a separate threshold. Behaviour is unchanged for logversion >= 7 (including all versions that can actually produce a sidemount configuration, which needs the multi-bit combinations introduced in version 13). Logs with logversion < 7 (and the logversion == 0 default used before the opening record is seen) no longer read offset 29 or assign DC_TANK_USAGE_SIDEMOUNT from it. No change to the popcount(gtrmode) >= 2 rule, tank indexing, or any other backend. Signed-off-by: Michael Keller --- src/shearwater_predator_parser.c | 21 ++++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/shearwater_predator_parser.c b/src/shearwater_predator_parser.c index c39400aa..ff1174d8 100644 --- a/src/shearwater_predator_parser.c +++ b/src/shearwater_predator_parser.c @@ -746,11 +746,22 @@ shearwater_predator_parser_cache (shearwater_predator_parser_t *parser) gasmix[i].enabled = (state & (1 << i)) != 0; } - unsigned int gtrmode = data[offset + 29]; - if (popcount(gtrmode) >= 2) { - for (unsigned int i = 0; i < 4; ++i) { - if (gtrmode & (1 << i)) { - tank[i].usage = DC_TANK_USAGE_SIDEMOUNT; + // GTR (Gas Time Remaining) mode, used here only to detect + // sidemount tanks. This byte immediately follows the AI + // mode byte and, like it, requires the wireless air + // integration transmitters, so it is only meaningful once + // AI support appears (logversion >= 7). Before log version + // 13 the only defined values were 0/1/2 (off/T1/T2), which + // never satisfy the sidemount popcount check below; from + // version 13 onward, multiple transmitter bits can be + // combined to flag sidemount configurations. + if (logversion >= 7) { + unsigned int gtrmode = data[offset + 29]; + if (popcount(gtrmode) >= 2) { + for (unsigned int i = 0; i < 4; ++i) { + if (gtrmode & (1 << i)) { + tank[i].usage = DC_TANK_USAGE_SIDEMOUNT; + } } } }