garmin: extract the devinfo from the first FIT file we parse
A typical FIT file contains several DEVICE_INFO messages. We need to identify the one(s) for the creator (i.e. the actual device, not a sub-component). Note, Garmin identifies the Descent Mk1 as product 2859. I think we should use this as the model number (instead of currently using 0. Also, the vendor event is not to send the vendor name of the device, but in order to send vendor specific events :-) Signed-off-by: Dirk Hohndel <dirk@hohndel.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
parent
ac25976258
commit
e02037bf84
27
src/garmin.c
27
src/garmin.c
@ -248,21 +248,6 @@ garmin_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, void
|
||||
progress.current = 0;
|
||||
device_event_emit (abstract, DC_EVENT_PROGRESS, &progress);
|
||||
|
||||
#if 0
|
||||
// Emit a device info event.
|
||||
dc_event_devinfo_t devinfo;
|
||||
devinfo.model = 0;
|
||||
devinfo.firmware = 0;
|
||||
devinfo.serial = 0;
|
||||
device_event_emit (abstract, DC_EVENT_DEVINFO, &devinfo);
|
||||
|
||||
// Emit a vendor event.
|
||||
dc_event_vendor_t vendor;
|
||||
vendor.data = "Garmin";
|
||||
vendor.size = 6;
|
||||
device_event_emit (abstract, DC_EVENT_VENDOR, &vendor);
|
||||
#endif
|
||||
|
||||
file = dc_buffer_new (16384);
|
||||
if (file == NULL) {
|
||||
ERROR (abstract->context, "Insufficient buffer space available.");
|
||||
@ -275,10 +260,13 @@ garmin_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, void
|
||||
return rc;
|
||||
}
|
||||
|
||||
dc_event_devinfo_t devinfo;
|
||||
dc_event_devinfo_t *devinfo_p = &devinfo;
|
||||
for (int i = 0; i < files.nr; i++) {
|
||||
const char *name = files.array[i].name;
|
||||
const unsigned char *data;
|
||||
unsigned int size;
|
||||
short is_dive = 0;
|
||||
|
||||
if (device_is_cancelled(abstract)) {
|
||||
status = DC_STATUS_CANCELLED;
|
||||
@ -296,7 +284,14 @@ garmin_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, void
|
||||
data = dc_buffer_get_data(file);
|
||||
size = dc_buffer_get_size(file);
|
||||
|
||||
if (!garmin_parser_is_dive(parser, data, size)) {
|
||||
is_dive = garmin_parser_is_dive(parser, data, size, devinfo_p);
|
||||
if (devinfo_p) {
|
||||
// first time we came through here, let's emit the
|
||||
// devinfo and vendor events
|
||||
device_event_emit (abstract, DC_EVENT_DEVINFO, devinfo_p);
|
||||
devinfo_p = NULL;
|
||||
}
|
||||
if (!is_dive) {
|
||||
DEBUG (abstract->context, "decided %s isn't a dive.", name);
|
||||
continue;
|
||||
}
|
||||
|
||||
@ -40,7 +40,7 @@ garmin_parser_create (dc_parser_t **parser, dc_context_t *context);
|
||||
// we need to be able to call into the parser to check if the
|
||||
// files that we find are actual dives
|
||||
int
|
||||
garmin_parser_is_dive (dc_parser_t *abstract, const unsigned char *data, unsigned int size);
|
||||
garmin_parser_is_dive (dc_parser_t *abstract, const unsigned char *data, unsigned int size, dc_event_devinfo_t *devinfo_p);
|
||||
|
||||
// The dive names are of the form "2018-08-20-10-23-30.fit"
|
||||
// With the terminating zero, that's 24 bytes.
|
||||
|
||||
@ -91,6 +91,9 @@ typedef struct garmin_parser_t {
|
||||
struct {
|
||||
unsigned int initialized;
|
||||
unsigned int sub_sport;
|
||||
unsigned int serial_nr;
|
||||
unsigned int product;
|
||||
unsigned int firmware;
|
||||
unsigned int protocol;
|
||||
unsigned int profile;
|
||||
unsigned int time;
|
||||
@ -489,6 +492,21 @@ DECLARE_FIELD(RECORD, n2_load, UINT16) { } // percent
|
||||
DECLARE_FIELD(DEVICE_SETTINGS, utc_offset, UINT32) { garmin->cache.utc_offset = (SINT32) data; } // wrong type in FIT
|
||||
DECLARE_FIELD(DEVICE_SETTINGS, time_offset, UINT32) { garmin->cache.time_offset = (SINT32) data; } // wrong type in FIT
|
||||
|
||||
// DEVICE_INFO
|
||||
// We just pick the first data we see
|
||||
DECLARE_FIELD(DEVICE_INFO, product, UINT16)
|
||||
{
|
||||
if (!garmin->cache.product) garmin->cache.product = data;
|
||||
}
|
||||
DECLARE_FIELD(DEVICE_INFO, serial_nr, UINT32Z)
|
||||
{
|
||||
if (!garmin->cache.serial_nr) garmin->cache.serial_nr = data;
|
||||
}
|
||||
DECLARE_FIELD(DEVICE_INFO, firmware, UINT16)
|
||||
{
|
||||
if (!garmin->cache.firmware) garmin->cache.firmware = data;
|
||||
}
|
||||
|
||||
// SPORT
|
||||
DECLARE_FIELD(SPORT, sub_sport, ENUM) { garmin->cache.sub_sport = (ENUM) data; }
|
||||
|
||||
@ -673,7 +691,15 @@ DECLARE_MESG(EVENT) = {
|
||||
}
|
||||
};
|
||||
|
||||
DECLARE_MESG(DEVICE_INFO) = { };
|
||||
DECLARE_MESG(DEVICE_INFO) = {
|
||||
.maxfield = 6,
|
||||
.field = {
|
||||
SET_FIELD(DEVICE_INFO, 3, serial_nr, UINT32Z),
|
||||
SET_FIELD(DEVICE_INFO, 4, product, UINT16),
|
||||
SET_FIELD(DEVICE_INFO, 5, firmware, UINT16),
|
||||
}
|
||||
};
|
||||
|
||||
DECLARE_MESG(ACTIVITY) = { };
|
||||
DECLARE_MESG(FILE_CREATOR) = { };
|
||||
DECLARE_MESG(DIVE_SETTINGS) = { };
|
||||
@ -1090,12 +1116,17 @@ static void add_gps_string(garmin_parser_t *garmin, const char *desc, struct pos
|
||||
}
|
||||
|
||||
int
|
||||
garmin_parser_is_dive (dc_parser_t *abstract, const unsigned char *data, unsigned int size)
|
||||
garmin_parser_is_dive (dc_parser_t *abstract, const unsigned char *data, unsigned int size, dc_event_devinfo_t *devinfo_p)
|
||||
{
|
||||
// set up the parser and extract data
|
||||
dc_parser_set_data(abstract, data, size);
|
||||
garmin_parser_t *garmin = (garmin_parser_t *) abstract;
|
||||
|
||||
if (devinfo_p) {
|
||||
devinfo_p->firmware = garmin->cache.firmware;
|
||||
devinfo_p->serial = garmin->cache.serial_nr;
|
||||
devinfo_p->model = garmin->cache.product;
|
||||
}
|
||||
return garmin->cache.sub_sport >= 53 && garmin->cache.sub_sport <= 57;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user