From b9a3606f379c3c9f57bbf561bdcb52fb76b711db Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Tue, 19 Nov 2019 22:16:09 +0100 Subject: [PATCH] Add a workaround for the hwOS ppO2 firmware bug Due to a bug in the hwOS Tech firmware v3.03 to v3.07, and the hwOS Sport firmware v10.57 to v10.63, the ppO2 divisor is sometimes not correctly reset to zero when no ppO2 samples are being recorded. Usually this condition can be detected by the fact that the length of the extended sample will not have enough space left for the ppO2 sample (9 bytes). As a workaround, reset the divisor back to zero to manually disable the ppO2 samples. In theory this detection method is not 100% reliable. There can still be other sample types present in the extended sample. If their total size is larger than 9 bytes, the bug will not be detected at all. Instead, those bytes will get interpreted as the ppO2 sample, resulting in bogus ppO2 values. Additionally, one of the other sample types will now run out of space and cause the parsing to fail with an error. However, in practice this risk is relative low. Most of the other samples are relative small (1 or 2 bytes), so you would need many of them. That's rather unlikely in most configurations. The only exception is the large deco plan sample (15 bytes). --- src/hw_ostc_parser.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/hw_ostc_parser.c b/src/hw_ostc_parser.c index 4a348b8..0f96b90 100644 --- a/src/hw_ostc_parser.c +++ b/src/hw_ostc_parser.c @@ -880,6 +880,17 @@ hw_ostc_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t call for (unsigned int i = 0; i < nconfig; ++i) { if (info[i].divisor && (nsamples % info[i].divisor) == 0) { if (length < info[i].size) { + // Due to a bug in the hwOS Tech firmware v3.03 to v3.07, and + // the hwOS Sport firmware v10.57 to v10.63, the ppO2 divisor + // is sometimes not correctly reset to zero when no ppO2 + // samples are being recorded. + if (info[i].type == PPO2 && parser->hwos && parser->model != OSTC4 && + ((firmware >= OSTC3FW(3,3) && firmware <= OSTC3FW(3,7)) || + (firmware >= OSTC3FW(10,57) && firmware <= OSTC3FW(10,63)))) { + WARNING (abstract->context, "Reset invalid ppO2 divisor to zero."); + info[i].divisor = 0; + continue; + } ERROR (abstract->context, "Buffer overflow detected!"); return DC_STATUS_DATAFORMAT; }