Garmin Descent: clear dive data in between dives
This actually got broken long ago (and before the new "Subsurface-DS9" branch: when I converted the Garmin parser to use the generic field cache, I missed the fact that the parser now cleared _only_ that generic part of the per-dive cache in between different dives. The GPS information, and the general dive information would be left alone in between dives, and could leak from one dive to the next. Most of the time you don't notice, because dives tend to all have the same information, so the stale data would get overwritten when parsing the next dive. But that isn't _always_ true - particularly for the GPS information, not all the data necessarily always exists. So clear all the per-dive data when starting to parse a new dive. This puts the non-gps data all in one sub-structure, so that it's easy to clear that too in one go - even though that part of the data probably always does get opverwritten by the new dive data. Reported-by: @brysconsulting Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
d52dfb002d
commit
0ebd5d3879
@ -97,15 +97,16 @@ typedef struct garmin_parser_t {
|
||||
struct type_desc type_desc[MAXTYPE];
|
||||
|
||||
// Field cache
|
||||
unsigned int initialized;
|
||||
unsigned int sub_sport;
|
||||
unsigned int serial;
|
||||
unsigned int product;
|
||||
unsigned int firmware;
|
||||
unsigned int protocol;
|
||||
unsigned int profile;
|
||||
unsigned int time;
|
||||
int utc_offset, time_offset;
|
||||
struct {
|
||||
unsigned int sub_sport;
|
||||
unsigned int serial;
|
||||
unsigned int product;
|
||||
unsigned int firmware;
|
||||
unsigned int protocol;
|
||||
unsigned int profile;
|
||||
unsigned int time;
|
||||
int utc_offset, time_offset;
|
||||
} dive;
|
||||
|
||||
// I count nine (!) different GPS fields Hmm.
|
||||
// Reporting all of them just to try to figure
|
||||
@ -214,9 +215,9 @@ static void flush_pending_record(struct garmin_parser_t *garmin)
|
||||
}
|
||||
}
|
||||
if (pending & RECORD_DEVICE_INFO && record->device_index == 0) {
|
||||
garmin->firmware = record->firmware;
|
||||
garmin->serial = record->serial;
|
||||
garmin->product = record->product;
|
||||
garmin->dive.firmware = record->firmware;
|
||||
garmin->dive.serial = record->serial;
|
||||
garmin->dive.product = record->product;
|
||||
}
|
||||
if (pending & RECORD_DECO_MODEL)
|
||||
dc_field_add_string_fmt(&garmin->cache, "Deco model", "Buhlmann ZHL-16C %u/%u", record->gf_low, record->gf_high);
|
||||
@ -358,9 +359,9 @@ DECLARE_FIELD(ANY, timestamp, UINT32)
|
||||
dc_sample_value_t sample = {0};
|
||||
|
||||
// Turn the timestamp relative to the beginning of the dive
|
||||
if (data < garmin->time)
|
||||
if (data < garmin->dive.time)
|
||||
return;
|
||||
data -= garmin->time;
|
||||
data -= garmin->dive.time;
|
||||
|
||||
// Did we already do this?
|
||||
if (data < garmin->record_data.time)
|
||||
@ -385,7 +386,7 @@ DECLARE_FIELD(FILE, number, UINT16) { }
|
||||
DECLARE_FIELD(FILE, other_time, UINT32) { }
|
||||
|
||||
// SESSION msg
|
||||
DECLARE_FIELD(SESSION, start_time, UINT32) { garmin->time = data; }
|
||||
DECLARE_FIELD(SESSION, start_time, UINT32) { garmin->dive.time = data; }
|
||||
DECLARE_FIELD(SESSION, start_pos_lat, SINT32) { garmin->gps.SESSION.entry.lat = data; }
|
||||
DECLARE_FIELD(SESSION, start_pos_long, SINT32) { garmin->gps.SESSION.entry.lon = data; }
|
||||
DECLARE_FIELD(SESSION, nec_pos_lat, SINT32) { garmin->gps.SESSION.NE.lat = data; }
|
||||
@ -474,8 +475,8 @@ DECLARE_FIELD(RECORD, cns_load, UINT8)
|
||||
DECLARE_FIELD(RECORD, n2_load, UINT16) { } // percent
|
||||
|
||||
// DEVICE_SETTINGS
|
||||
DECLARE_FIELD(DEVICE_SETTINGS, utc_offset, UINT32) { garmin->utc_offset = (SINT32) data; } // wrong type in FIT
|
||||
DECLARE_FIELD(DEVICE_SETTINGS, time_offset, UINT32) { garmin->time_offset = (SINT32) data; } // wrong type in FIT
|
||||
DECLARE_FIELD(DEVICE_SETTINGS, utc_offset, UINT32) { garmin->dive.utc_offset = (SINT32) data; } // wrong type in FIT
|
||||
DECLARE_FIELD(DEVICE_SETTINGS, time_offset, UINT32) { garmin->dive.time_offset = (SINT32) data; } // wrong type in FIT
|
||||
|
||||
// DEVICE_INFO
|
||||
// collect the data and then use the record if it is for device_index 0
|
||||
@ -501,7 +502,7 @@ DECLARE_FIELD(DEVICE_INFO, firmware, UINT16)
|
||||
}
|
||||
|
||||
// SPORT
|
||||
DECLARE_FIELD(SPORT, sub_sport, ENUM) { garmin->sub_sport = (ENUM) data; }
|
||||
DECLARE_FIELD(SPORT, sub_sport, ENUM) { garmin->dive.sub_sport = (ENUM) data; }
|
||||
|
||||
// DIVE_GAS - uses msg index
|
||||
DECLARE_FIELD(DIVE_GAS, helium, UINT8)
|
||||
@ -1102,8 +1103,8 @@ traverse_data(struct garmin_parser_t *garmin)
|
||||
if (hdrsize < 12 || datasize > len || datasize + hdrsize + 2 > len)
|
||||
return DC_STATUS_IO;
|
||||
|
||||
garmin->protocol = protocol;
|
||||
garmin->profile = profile;
|
||||
garmin->dive.protocol = protocol;
|
||||
garmin->dive.profile = profile;
|
||||
|
||||
data += hdrsize;
|
||||
time = 0;
|
||||
@ -1188,11 +1189,11 @@ garmin_parser_is_dive (dc_parser_t *abstract, const unsigned char *data, unsigne
|
||||
garmin_parser_t *garmin = (garmin_parser_t *) abstract;
|
||||
|
||||
if (devinfo_p) {
|
||||
devinfo_p->firmware = garmin->firmware;
|
||||
devinfo_p->serial = garmin->serial;
|
||||
devinfo_p->model = garmin->product;
|
||||
devinfo_p->firmware = garmin->dive.firmware;
|
||||
devinfo_p->serial = garmin->dive.serial;
|
||||
devinfo_p->model = garmin->dive.product;
|
||||
}
|
||||
switch (garmin->sub_sport) {
|
||||
switch (garmin->dive.sub_sport) {
|
||||
case 53: // Single-gas
|
||||
case 54: // Multi-gas
|
||||
case 55: // Gauge
|
||||
@ -1218,6 +1219,8 @@ garmin_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsign
|
||||
/* Walk the data once without a callback to set up the core fields */
|
||||
garmin->callback = NULL;
|
||||
garmin->userdata = NULL;
|
||||
memset(&garmin->gps, 0, sizeof(garmin->gps));
|
||||
memset(&garmin->dive, 0, sizeof(garmin->dive));
|
||||
memset(&garmin->cache, 0, sizeof(garmin->cache));
|
||||
|
||||
traverse_data(garmin);
|
||||
@ -1243,10 +1246,10 @@ static dc_status_t
|
||||
garmin_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime)
|
||||
{
|
||||
garmin_parser_t *garmin = (garmin_parser_t *) abstract;
|
||||
dc_ticks_t time = 631065600 + (dc_ticks_t) garmin->time;
|
||||
dc_ticks_t time = 631065600 + (dc_ticks_t) garmin->dive.time;
|
||||
|
||||
// Show local time (time_offset)
|
||||
dc_datetime_gmtime(datetime, time + garmin->time_offset);
|
||||
dc_datetime_gmtime(datetime, time + garmin->dive.time_offset);
|
||||
datetime->timezone = DC_TIMEZONE_NONE;
|
||||
|
||||
return DC_STATUS_SUCCESS;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user