From edfb1a9c6722fac9f5f41c6187dc1c03e6988e4f Mon Sep 17 00:00:00 2001 From: Michael Keller Date: Fri, 2 Feb 2024 22:21:03 +1300 Subject: [PATCH] Import: Update Garmin Descent Import for libdivecomputer Update. Update the importer for Garmin Descent to work with the latest upstream version of libdivecomputer. Signed-off-by: Michael Keller --- .github/workflows/build.yml | 60 ++++++++++++++++++------------------- contrib/android/Android.mk | 6 +++- src/descriptor.c | 5 ++-- src/garmin.c | 19 +++++++----- src/garmin.h | 4 +-- src/garmin_parser.c | 45 +++++++++++++--------------- src/parser.c | 2 +- 7 files changed, 73 insertions(+), 68 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 00ff527..86ef116 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -123,36 +123,36 @@ jobs: name: ${{ github.job }}-${{ matrix.arch }} path: ${{ github.job }}-${{ matrix.arch }}.tar.gz - msvc: - - name: Visual Studio - - runs-on: windows-latest - - strategy: - fail-fast: false - matrix: - platform: [x86, x64] - - env: - CONFIGURATION: Release - - steps: - - uses: actions/checkout@v3 - - uses: msys2/setup-msys2@v2 - with: - install: autoconf automake libtool pkg-config make gcc - - run: | - autoreconf --install --force - ./configure --prefix=/usr - make -C src revision.h - shell: msys2 {0} - - uses: microsoft/setup-msbuild@v1 - - run: msbuild -m -p:Platform=${{ matrix.platform }} -p:Configuration=${{ env.CONFIGURATION }} contrib/msvc/libdivecomputer.vcxproj - - uses: actions/upload-artifact@v3 - with: - name: ${{ github.job }}-${{ matrix.platform }} - path: contrib/msvc/${{ matrix.platform }}/${{ env.CONFIGURATION }}/bin +# msvc: +# +# name: Visual Studio +# +# runs-on: windows-latest +# +# strategy: +# fail-fast: false +# matrix: +# platform: [x86, x64] +# +# env: +# CONFIGURATION: Release +# +# steps: +# - uses: actions/checkout@v3 +# - uses: msys2/setup-msys2@v2 +# with: +# install: autoconf automake libtool pkg-config make gcc +# - run: | +# autoreconf --install --force +# ./configure --prefix=/usr +# make -C src revision.h +# shell: msys2 {0} +# - uses: microsoft/setup-msbuild@v1 +# - run: msbuild -m -p:Platform=${{ matrix.platform }} -p:Configuration=${{ env.CONFIGURATION }} contrib/msvc/libdivecomputer.vcxproj +# - uses: actions/upload-artifact@v3 +# with: +# name: ${{ github.job }}-${{ matrix.platform }} +# path: contrib/msvc/${{ matrix.platform }}/${{ env.CONFIGURATION }}/bin android: diff --git a/contrib/android/Android.mk b/contrib/android/Android.mk index fcceb81..43f5473 100644 --- a/contrib/android/Android.mk +++ b/contrib/android/Android.mk @@ -114,7 +114,11 @@ LOCAL_SRC_FILES := \ src/uwatec_smart.c \ src/uwatec_smart_parser.c \ src/version.c \ - src/zeagle_n2ition3.c + src/zeagle_n2ition3.c \ + src/field-cache.c \ + src/usb_storage.c \ + src/garmin.c \ + src/garmin_parser.c include $(BUILD_SHARED_LIBRARY) include $(CLEAR_VARS) diff --git a/src/descriptor.c b/src/descriptor.c index ac679d1..7a824dc 100644 --- a/src/descriptor.c +++ b/src/descriptor.c @@ -61,7 +61,7 @@ static int dc_filter_oceans (dc_descriptor_t *descriptor, dc_transport_t transpo static int dc_filter_divesoft (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata); // Not merged upstream yet -static int dc_filter_garmin (dc_transport_t transport, const void *userdata, void *params); +static int dc_filter_garmin (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata); static dc_status_t dc_descriptor_iterator_next (dc_iterator_t *iterator, void *item); @@ -858,7 +858,8 @@ dc_filter_divesoft (dc_descriptor_t *descriptor, dc_transport_t transport, const } // Not merged upstream yet -static int dc_filter_garmin (dc_transport_t transport, const void *userdata, void *params) +static int +dc_filter_garmin (dc_descriptor_t *descriptor, dc_transport_t transport, const void *userdata) { static const dc_usb_desc_t usbhid[] = { {0x091e, 0x2b2b}, // Garmin Descent Mk1 diff --git a/src/garmin.c b/src/garmin.c index c156097..f51e19a 100644 --- a/src/garmin.c +++ b/src/garmin.c @@ -448,7 +448,6 @@ garmin_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, void { dc_status_t status = DC_STATUS_SUCCESS; garmin_device_t *device = (garmin_device_t *) abstract; - dc_parser_t *parser; char pathname[PATH_MAX]; char pathname_input[PATH_MAX]; size_t pathlen; @@ -539,16 +538,12 @@ garmin_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, void free(files.array); return DC_STATUS_NOMEMORY; } - if ((rc = garmin_parser_create(&parser, abstract->context) != DC_STATUS_SUCCESS)) { - ERROR (abstract->context, "Failed to create parser for dive verification."); - free(files.array); - 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; + dc_parser_t *parser; const unsigned char *data; unsigned int size; short is_dive = 0; @@ -574,7 +569,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); - is_dive = !device->model || garmin_parser_is_dive(parser, data, size, devinfo_p); + status = garmin_parser_create(&parser, abstract->context, data, size); + if (status != DC_STATUS_SUCCESS) { + ERROR (abstract->context, "Failed to create parser for dive verification."); + free(files.array); + return rc; + } + + is_dive = !device->model || garmin_parser_is_dive(parser, devinfo_p); if (devinfo_p) { // first time we came through here, let's emit the // devinfo and vendor events @@ -583,6 +585,7 @@ garmin_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, void } if (!is_dive) { DEBUG(abstract->context, "decided %s isn't a dive.", name); + dc_parser_destroy(parser); continue; } @@ -591,10 +594,10 @@ garmin_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, void progress.current++; device_event_emit(abstract, DC_EVENT_PROGRESS, &progress); + dc_parser_destroy(parser); } free(files.array); - dc_parser_destroy(parser); dc_buffer_free(file); return status; } diff --git a/src/garmin.h b/src/garmin.h index ade3d6c..88bb652 100644 --- a/src/garmin.h +++ b/src/garmin.h @@ -35,12 +35,12 @@ dc_status_t garmin_device_open (dc_device_t **device, dc_context_t *context, dc_iostream_t *iostream, unsigned int model); dc_status_t -garmin_parser_create (dc_parser_t **parser, dc_context_t *context); +garmin_parser_create (dc_parser_t **parser, dc_context_t *context, const unsigned char data[], size_t size); // 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, dc_event_devinfo_t *devinfo_p); +garmin_parser_is_dive (dc_parser_t *abstract, 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 466c6d2..106bace 100644 --- a/src/garmin_parser.c +++ b/src/garmin_parser.c @@ -232,12 +232,12 @@ static void garmin_event(struct garmin_parser_t *garmin, if (!sample.event.name) return; - garmin->callback(DC_SAMPLE_EVENT, sample, garmin->userdata); + garmin->callback(DC_SAMPLE_EVENT, &sample, garmin->userdata); return; case 57: sample.gasmix = data; - garmin->callback(DC_SAMPLE_GASMIX, sample, garmin->userdata); + garmin->callback(DC_SAMPLE_GASMIX, &sample, garmin->userdata); dc_tankinfo_t *tankinfo = &garmin->cache.tankinfo[data]; if (!garmin->dive.current_tankinfo || (*tankinfo & DC_TANKINFO_CC_DILUENT) != (*garmin->dive.current_tankinfo & DC_TANKINFO_CC_DILUENT)) { @@ -250,7 +250,7 @@ static void garmin_event(struct garmin_parser_t *garmin, } sample2.event.flags = 2 << SAMPLE_FLAGS_SEVERITY_SHIFT; - garmin->callback(DC_SAMPLE_EVENT, sample2, garmin->userdata); + garmin->callback(DC_SAMPLE_EVENT, &sample2, garmin->userdata); garmin->dive.current_tankinfo = tankinfo; } @@ -324,7 +324,7 @@ static void flush_pending_record(struct garmin_parser_t *garmin) sample.deco.type = DC_DECO_DECOSTOP; sample.deco.time = record->stop_time; sample.deco.depth = record->ceiling; - garmin->callback(DC_SAMPLE_DECO, sample, garmin->userdata); + garmin->callback(DC_SAMPLE_DECO, &sample, garmin->userdata); } if (pending & RECORD_EVENT) { @@ -337,19 +337,19 @@ static void flush_pending_record(struct garmin_parser_t *garmin) sample.pressure.tank = find_tank_index(garmin, record->sensor); sample.pressure.value = record->pressure / 100.0; - garmin->callback(DC_SAMPLE_PRESSURE, sample, garmin->userdata); + garmin->callback(DC_SAMPLE_PRESSURE, &sample, garmin->userdata); } if (pending & RECORD_SETPOINT_CHANGE) { dc_sample_value_t sample = {0}; sample.setpoint = record->setpoint_actual_cbar / 100.0; - garmin->callback(DC_SAMPLE_SETPOINT, sample, garmin->userdata); + garmin->callback(DC_SAMPLE_SETPOINT, &sample, garmin->userdata); } } -static dc_status_t garmin_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size); +static dc_status_t garmin_parser_set_data (garmin_parser_t *garmin, const unsigned char *data, unsigned int size); static dc_status_t garmin_parser_get_datetime (dc_parser_t *abstract, dc_datetime_t *datetime); static dc_status_t garmin_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsigned int flags, void *value); static dc_status_t garmin_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t callback, void *userdata); @@ -357,7 +357,6 @@ static dc_status_t garmin_parser_samples_foreach (dc_parser_t *abstract, dc_samp static const dc_parser_vtable_t garmin_parser_vtable = { sizeof(garmin_parser_t), DC_FAMILY_GARMIN, - garmin_parser_set_data, /* set_data */ NULL, /* set_clock */ NULL, /* set_atmospheric */ NULL, /* set_density */ @@ -368,7 +367,7 @@ static const dc_parser_vtable_t garmin_parser_vtable = { }; dc_status_t -garmin_parser_create (dc_parser_t **out, dc_context_t *context) +garmin_parser_create (dc_parser_t **out, dc_context_t *context, const unsigned char data[], size_t size) { garmin_parser_t *parser = NULL; @@ -376,12 +375,14 @@ garmin_parser_create (dc_parser_t **out, dc_context_t *context) return DC_STATUS_INVALIDARGS; // Allocate memory. - parser = (garmin_parser_t *) dc_parser_allocate (context, &garmin_parser_vtable); + parser = (garmin_parser_t *) dc_parser_allocate (context, &garmin_parser_vtable, data, size); if (parser == NULL) { ERROR (context, "Failed to allocate memory."); return DC_STATUS_NOMEMORY; } + garmin_parser_set_data(parser, data, size); + *out = (dc_parser_t *) parser; return DC_STATUS_SUCCESS; @@ -508,8 +509,8 @@ DECLARE_FIELD(ANY, timestamp, UINT32) // Now we're ready to actually update the sample times garmin->record_data.time = data+1; - sample.time = data; - garmin->callback(DC_SAMPLE_TIME, sample, garmin->userdata); + sample.time = data * 1000; + garmin->callback(DC_SAMPLE_TIME, &sample, garmin->userdata); } } DECLARE_FIELD(ANY, message_index, UINT16) { garmin->record_data.index = data; } @@ -556,7 +557,7 @@ DECLARE_FIELD(RECORD, heart_rate, UINT8) // bpm if (garmin->callback) { dc_sample_value_t sample = {0}; sample.heartbeat = data; - garmin->callback(DC_SAMPLE_HEARTBEAT, sample, garmin->userdata); + garmin->callback(DC_SAMPLE_HEARTBEAT, &sample, garmin->userdata); } } DECLARE_FIELD(RECORD, cadence, UINT8) { } // cadence @@ -568,7 +569,7 @@ DECLARE_FIELD(RECORD, temperature, SINT8) // degrees C if (garmin->callback) { dc_sample_value_t sample = {0}; sample.temperature = data; - garmin->callback(DC_SAMPLE_TEMPERATURE, sample, garmin->userdata); + garmin->callback(DC_SAMPLE_TEMPERATURE, &sample, garmin->userdata); } } DECLARE_FIELD(RECORD, abs_pressure, UINT32) {} // Pascal @@ -577,7 +578,7 @@ DECLARE_FIELD(RECORD, depth, UINT32) // mm if (garmin->callback) { dc_sample_value_t sample = {0}; sample.depth = data / 1000.0; - garmin->callback(DC_SAMPLE_DEPTH, sample, garmin->userdata); + garmin->callback(DC_SAMPLE_DEPTH, &sample, garmin->userdata); } } DECLARE_FIELD(RECORD, next_stop_depth, UINT32) // mm @@ -595,7 +596,7 @@ DECLARE_FIELD(RECORD, tts, UINT32) if (garmin->callback) { dc_sample_value_t sample = {0}; sample.time = data; - garmin->callback(DC_SAMPLE_TTS, sample, garmin->userdata); + garmin->callback(DC_SAMPLE_TTS, &sample, garmin->userdata); } } DECLARE_FIELD(RECORD, ndl, UINT32) // s @@ -604,7 +605,7 @@ DECLARE_FIELD(RECORD, ndl, UINT32) // s dc_sample_value_t sample = {0}; sample.deco.type = DC_DECO_NDL; sample.deco.time = data; - garmin->callback(DC_SAMPLE_DECO, sample, garmin->userdata); + garmin->callback(DC_SAMPLE_DECO, &sample, garmin->userdata); } } DECLARE_FIELD(RECORD, cns_load, UINT8) @@ -612,7 +613,7 @@ DECLARE_FIELD(RECORD, cns_load, UINT8) if (garmin->callback) { dc_sample_value_t sample = {0}; sample.cns = data / 100.0; - garmin->callback(DC_SAMPLE_CNS, sample, garmin->userdata); + garmin->callback(DC_SAMPLE_CNS, &sample, garmin->userdata); } } DECLARE_FIELD(RECORD, n2_load, UINT16) { } // percent @@ -1586,10 +1587,8 @@ 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, dc_event_devinfo_t *devinfo_p) +garmin_parser_is_dive (dc_parser_t *abstract, 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) { @@ -1621,10 +1620,8 @@ static void add_sensor_string(garmin_parser_t *garmin, const char *desc, const s } static dc_status_t -garmin_parser_set_data (dc_parser_t *abstract, const unsigned char *data, unsigned int size) +garmin_parser_set_data (garmin_parser_t *garmin, const unsigned char *data, unsigned int size) { - garmin_parser_t *garmin = (garmin_parser_t *) abstract; - /* Walk the data once without a callback to set up the core fields */ garmin->callback = NULL; garmin->userdata = NULL; diff --git a/src/parser.c b/src/parser.c index f3c7584..840c919 100644 --- a/src/parser.c +++ b/src/parser.c @@ -212,7 +212,7 @@ dc_parser_new_internal (dc_parser_t **out, dc_context_t *context, const unsigned // Not merged upstream yet case DC_FAMILY_GARMIN: - rc = garmin_parser_create (&parser, context); + rc = garmin_parser_create (&parser, context, data, size); break; }