From 7de3a549ee588fef4702ee9d894e390aca43950d Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 3 Nov 2017 10:58:10 -0700 Subject: [PATCH] EON Steel: explicitly sort the dive directory listing The code relied on the dives being ordered by date in the directory listing, which is normally true. But once the dive computer fills up (after 400 dives or so), it starts re-using entries in the dive list, and the dive directory is no longer ordered by date. This matters because we want to download the latest dives first, since subsurface will generally stop downloading once it finds an existing dive. NOTE! If you screw up the date on the dive computer, the old behavior was possibly more to your liking, since - as long as the dive list hadn't filled up - it wouldn't really order by date, but by dive creation. However, I don't see any way to get that information once the dive list has filled up, so "order by dive date" is as good as it gets. If you do screw up dates, and you want to download new dives that are "older" than the dives you already have, you will need to basically set the "download all dives" flag, and then select the new dives manually. Signed-off-by: Linus Torvalds --- src/suunto_eonsteel.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/suunto_eonsteel.c b/src/suunto_eonsteel.c index 11e1e28..0c78359 100644 --- a/src/suunto_eonsteel.c +++ b/src/suunto_eonsteel.c @@ -612,6 +612,20 @@ static int read_file(suunto_eonsteel_device_t *eon, const char *filename, dc_buf * with the last dirent first. That's intentional: for dives, * we will want to look up the last dive first. */ +static struct directory_entry *add_dirent(struct directory_entry *new, struct directory_entry *list) +{ + struct directory_entry **pp = &list, *p; + + /* Skip any entries that are later than the new one */ + while ((p = *pp) != NULL && strcmp(p->name, new->name) > 0) + pp = &p->next; + + /* Add the new one to that location and return the new list pointer */ + new->next = p; + *pp = new; + return list; +} + static struct directory_entry *parse_dirent(suunto_eonsteel_device_t *eon, int nr, const unsigned char *p, int len, struct directory_entry *old) { while (len > 8) { @@ -633,8 +647,7 @@ static struct directory_entry *parse_dirent(suunto_eonsteel_device_t *eon, int n ERROR(eon->base.context, "out of memory"); break; } - entry->next = old; - old = entry; + old = add_dirent(entry, old); } return old; }