From 060cc95d5ce5945d2e7d4c3ce9d54090436509ee Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Fri, 30 Mar 2012 21:24:48 +0200 Subject: [PATCH] Substract the dive time from the date/time value. The OSTC doesn't store the start of the dive, but the exit time. Hence the dive time needs to be substracted. For dives with format version 0x21, we prefer the total dive time in seconds stored in the extended header. This time value also includes the shallow parts of the dive, and therefore yields the most accurate start time. The dive time is rounded down towards the nearest minute, to match the value displayed by the ostc. For dives with the older format version 0x20, this value isn't available and we default to the normal dive time. --- src/hw_ostc_parser.c | 56 ++++++++++++++++++++++++++++++++++++-------- 1 file changed, 46 insertions(+), 10 deletions(-) diff --git a/src/hw_ostc_parser.c b/src/hw_ostc_parser.c index dff32bf..4ab1436 100644 --- a/src/hw_ostc_parser.c +++ b/src/hw_ostc_parser.c @@ -113,20 +113,56 @@ hw_ostc_parser_set_data (parser_t *abstract, const unsigned char *data, unsigned static parser_status_t hw_ostc_parser_get_datetime (parser_t *abstract, dc_datetime_t *datetime) { - if (abstract->size < 8) + const unsigned char *data = abstract->data; + unsigned int size = abstract->size; + + if (size < 3) return PARSER_STATUS_ERROR; - const unsigned char *p = abstract->data; - - if (datetime) { - datetime->year = p[5] + 2000; - datetime->month = p[3]; - datetime->day = p[4]; - datetime->hour = p[6]; - datetime->minute = p[7]; - datetime->second = 0; + // Check the profile version + unsigned int version = data[2]; + unsigned int header = 0; + switch (version) { + case 0x20: + header = 47; + break; + case 0x21: + header = 57; + break; + default: + return PARSER_STATUS_ERROR; } + if (size < header) + return PARSER_STATUS_ERROR; + + unsigned int divetime = 0; + if (version == 0x21) { + // Use the dive time stored in the extended header, rounded down towards + // the nearest minute, to match the value displayed by the ostc. + divetime = (array_uint16_le (data + 47) / 60) * 60; + } else { + // Use the normal dive time (excluding the shallow parts of the dive). + divetime = array_uint16_le (data + 10) * 60 + data[12]; + } + + dc_datetime_t dt; + dt.year = data[5] + 2000; + dt.month = data[3]; + dt.day = data[4]; + dt.hour = data[6]; + dt.minute = data[7]; + dt.second = 0; + + dc_ticks_t ticks = dc_datetime_mktime (&dt); + if (ticks == (dc_ticks_t) -1) + return PARSER_STATUS_ERROR; + + ticks -= divetime; + + if (!dc_datetime_localtime (datetime, ticks)) + return PARSER_STATUS_ERROR; + return PARSER_STATUS_SUCCESS; }