diff --git a/src/garmin.c b/src/garmin.c index 0d9d71f..32a5936 100644 --- a/src/garmin.c +++ b/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; } diff --git a/src/garmin.h b/src/garmin.h index fd1f504..bd09ed4 100644 --- a/src/garmin.h +++ b/src/garmin.h @@ -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. diff --git a/src/garmin_parser.c b/src/garmin_parser.c index d965e76..51ba677 100644 --- a/src/garmin_parser.c +++ b/src/garmin_parser.c @@ -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; }