From 0ac15dffd37075c902f2b59da6fb49008142e236 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Mon, 5 Feb 2018 20:16:48 +0100 Subject: [PATCH] Add a workaround for invalid logbook begin pointers Unfortunately there are several devices where an invalid logbook begin pointer occurs relative frequently. Typical examples are the Oceanic VT 4.1 and the Sherwood Wisdom 2. In such cases, the strict validation of the pointer causes the download to fail, without being able to download any dives at all. Since the begin pointer is only needed to detect the oldest logbook entry, we can fall back to downloading the entire logbook ringbuffer. If we're lucky (and we usually are), we can detect the oldest entry by inspecting the logbook entries once they are downloaded (e.g. presence of uninitialized entries) and then the download will finish succesfully. In the worst case scenario, we'll be able to download at least some dives before hitting another error. --- src/oceanic_common.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/oceanic_common.c b/src/oceanic_common.c index f6f78d6..9f7341a 100644 --- a/src/oceanic_common.c +++ b/src/oceanic_common.c @@ -208,13 +208,10 @@ oceanic_common_device_logbook (dc_device_t *abstract, dc_event_progress_t *progr // Get the logbook pointers. unsigned int rb_logbook_first = array_uint16_le (pointers + 4); unsigned int rb_logbook_last = array_uint16_le (pointers + 6); - if (rb_logbook_first < layout->rb_logbook_begin || - rb_logbook_first >= layout->rb_logbook_end || - rb_logbook_last < layout->rb_logbook_begin || + if (rb_logbook_last < layout->rb_logbook_begin || rb_logbook_last >= layout->rb_logbook_end) { - ERROR (abstract->context, "Invalid logbook pointer detected (0x%04x 0x%04x).", - rb_logbook_first, rb_logbook_last); + ERROR (abstract->context, "Invalid logbook end pointer detected (0x%04x).", rb_logbook_last); return DC_STATUS_DATAFORMAT; } @@ -232,7 +229,17 @@ oceanic_common_device_logbook (dc_device_t *abstract, dc_event_progress_t *progr // full ringbuffer. We always consider the ringbuffer full in that // case, because an empty ringbuffer can be detected by inspecting // the logbook entries once they are downloaded. - unsigned int rb_logbook_size = RB_LOGBOOK_DISTANCE (rb_logbook_first, rb_logbook_end, layout); + unsigned int rb_logbook_size = 0; + if (rb_logbook_first < layout->rb_logbook_begin || + rb_logbook_first >= layout->rb_logbook_end) + { + // Fall back to downloading the entire logbook ringbuffer as + // workaround for an invalid logbook begin pointer! + ERROR (abstract->context, "Invalid logbook begin pointer detected (0x%04x).", rb_logbook_first); + rb_logbook_size = layout->rb_logbook_end - layout->rb_logbook_begin; + } else { + rb_logbook_size = RB_LOGBOOK_DISTANCE (rb_logbook_first, rb_logbook_end, layout); + } // Update and emit a progress event. progress->current += PAGESIZE;