From ea051578e61f336e997995c7edf431cc9842a66f Mon Sep 17 00:00:00 2001 From: Michael Andreen Date: Sun, 24 Apr 2022 23:20:04 +0200 Subject: [PATCH] Garmin: Handle file names in short format When downloading heart rate data from a chest strap the Descent MK2i uses a more compact format, like C4ND0302.fit. If any such dives have been downloaded then newer dives in long format won't be detected and requires downloading all dives and picking the right ones. Instead parse this short format and ensure that these dives end up in the correct order. Format information found here: https://gist.github.com/waywardone/fa8cb01462790aa8a26fab97477b80e1 Signed-off-by: Michael Andreen --- src/garmin.c | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/src/garmin.c b/src/garmin.c index 1a635a7..d8b47ee 100644 --- a/src/garmin.c +++ b/src/garmin.c @@ -141,13 +141,53 @@ struct file_list { struct fit_file *array; }; +static int +char_to_int(char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'z') + return c - 'a' + 10; + if (c >= 'A' && c <= 'Z') + return c - 'A' + 10; + return 0; +} + +/* C4ND0302.fit -> 2022-04-23-13-03-02.fit */ +static void +parse_short_name(const char *name, char *output) +{ + sprintf(output, "%d-%02d-%02d-%02d-%02d-%02d.fit", char_to_int(name[0]) + 2010, // Year + char_to_int(name[1]), // Month + char_to_int(name[2]), // Day + char_to_int(name[3]), // Hour + char_to_int(name[4]) * 10 + char_to_int(name[5]), // Minute + char_to_int(name[6]) * 10 + char_to_int(name[7])); // Second +} + static int name_cmp(const void *_a, const void *_b) { const struct fit_file *a = _a; const struct fit_file *b = _b; + const char *a_name = a->name; + const char *b_name = b->name; + + char a_buffer[FIT_NAME_SIZE]; + char b_buffer[FIT_NAME_SIZE]; + + if (strlen(a_name) == 12) { + parse_short_name(a_name, a_buffer); + a_name = a_buffer; + } + + if (strlen(b_name) == 12) { + parse_short_name(b_name, b_buffer); + b_name = b_buffer; + } + // Sort reverse string ordering (newest first), so use 'b,a' - return strcmp(b->name, a->name); + return strcmp(b_name, a_name); } /*