From 812db650d42dd57f9681469330bad7d459dca6a9 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Fri, 17 Nov 2017 23:02:46 +0100 Subject: [PATCH] Locate the most recent dive The Suunto Eon Steel seems to have a limit of maximum 400 dives. Once that limit is reached, the oldest dives get overwritten with newer dives. But the order in which the dive entries are downloaded isn't changed, and thus the most recent dive is no longer the last entry. For the first 400 dives, the order is always straightforward: D001 D002 ... D399 D400 The most recent dive is always the last entry, and no special processing is necessary. But once the limit is reached, the next few dives will start to overwrite the oldest dives, but the order remains unchanged: D401 D402 ... D399 D400 Thus in order to return the dives in the correct order (newest first), we can no longer assume the most recent dive is the last entry, and thus we need to locate it manually. The new algorithm is based on the assumption that the most recent dive will have the hightest timestamp. And to be able to walk backwards through all the entries, the list is assumed to be a circular list. --- src/suunto_eonsteel.c | 48 +++++++++++++++++++++++++++++-------------- 1 file changed, 33 insertions(+), 15 deletions(-) diff --git a/src/suunto_eonsteel.c b/src/suunto_eonsteel.c index 063716d..cf36184 100644 --- a/src/suunto_eonsteel.c +++ b/src/suunto_eonsteel.c @@ -592,16 +592,6 @@ error_free: return status; } -static int count_dir_entries(struct directory_entry *de) -{ - int count = 0; - while (de) { - count++; - de = de->next; - } - return count; -} - static dc_status_t suunto_eonsteel_device_set_fingerprint (dc_device_t *abstract, const unsigned char data[], unsigned int size) { @@ -630,9 +620,6 @@ suunto_eonsteel_device_foreach(dc_device_t *abstract, dc_dive_callback_t callbac unsigned int count = 0; dc_event_progress_t progress = EVENT_PROGRESS_INITIALIZER; - if (get_file_list(eon, &de) < 0) - return DC_STATUS_IO; - // Emit a device info event. dc_event_devinfo_t devinfo; devinfo.model = 0; @@ -640,16 +627,47 @@ suunto_eonsteel_device_foreach(dc_device_t *abstract, dc_dive_callback_t callbac devinfo.serial = array_convert_str2num(eon->version + 0x10, 16); device_event_emit (abstract, DC_EVENT_DEVINFO, &devinfo); - count = count_dir_entries(de); - if (count == 0) { + if (get_file_list(eon, &de) < 0) + return DC_STATUS_IO; + + if (de == NULL) { return DC_STATUS_SUCCESS; } + // Locate the most recent dive. + // The filename represent the time of the dive, encoded as a hexadecimal + // number. Thus the most recent dive can be found by simply sorting the + // filenames alphabetically. + struct directory_entry *head = de, *tail = de, *latest = de; + while (de) { + if (strcmp (de->name, latest->name) > 0) { + latest = de; + } + tail = de; + count++; + de = de->next; + } + + // Make the most recent dive the head of the list. + // The linked list is made circular, by attaching the head to the tail and + // then cut open again just before the most recent dive. + de = head; + while (de) { + if (de->next == latest) { + de->next = NULL; + tail->next = head; + break; + } + + de = de->next; + } + file = dc_buffer_new(0); progress.maximum = count; progress.current = 0; device_event_emit(abstract, DC_EVENT_PROGRESS, &progress); + de = latest; while (de) { int len; struct directory_entry *next = de->next;