diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8fa7569..161c2f3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -81,8 +81,37 @@ jobs: - uses: actions/checkout@v2 - name: Install dependencies run: sudo apt-get install gcc-mingw-w64 binutils-mingw-w64 mingw-w64-tools + - name: Install libusb + env: + LIBUSB_VERSION: 1.0.24 + run: | + wget -c https://github.com/libusb/libusb/archive/refs/tags/v${LIBUSB_VERSION}.tar.gz + tar xzf v${LIBUSB_VERSION}.tar.gz + pushd libusb-${LIBUSB_VERSION} + autoreconf --install --force + ./configure --host=${{ matrix.arch }}-w64-mingw32 --prefix=/usr + make + make install DESTDIR=$PWD/../artifacts + popd + - name: Install hidapi + env: + HIDAPI_VERSION: 0.10.1 + run: | + wget -c https://github.com/libusb/hidapi/archive/refs/tags/hidapi-${HIDAPI_VERSION}.tar.gz + tar xzf hidapi-${HIDAPI_VERSION}.tar.gz + pushd hidapi-hidapi-${HIDAPI_VERSION} + autoreconf --install --force + ./configure --host=${{ matrix.arch }}-w64-mingw32 --prefix=/usr + make + make install DESTDIR=$PWD/../artifacts + popd - run: autoreconf --install --force - run: ./configure --host=${{ matrix.arch }}-w64-mingw32 --prefix=/usr + env: + PKG_CONFIG_LIBDIR: ${{ github.workspace }}/artifacts/usr/lib/pkgconfig + PKG_CONFIG_SYSROOT_DIR: ${{ github.workspace }}/artifacts + PKG_CONFIG_ALLOW_SYSTEM_CFLAGS: 1 + PKG_CONFIG_ALLOW_SYSTEM_LIBS: 1 - run: make - run: make distcheck - name: Package artifacts @@ -93,3 +122,33 @@ jobs: with: 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@v2 + - uses: msys2/setup-msys2@v2 + with: + install: autoconf automake libtool pkg-config make gcc + - run: | + autoreconf --install --force + ./configure --prefix=/usr + shell: msys2 {0} + - uses: microsoft/setup-msbuild@v1.0.2 + - run: msbuild -m -p:Platform=${{ matrix.platform }} -p:Configuration=${{ env.CONFIGURATION }} msvc/libdivecomputer.vcxproj + - uses: actions/upload-artifact@v2 + with: + name: ${{ github.job }}-${{ matrix.platform }} + path: msvc/${{ matrix.platform }}/${{ env.CONFIGURATION }}/bin diff --git a/.gitignore b/.gitignore index aa31142..6e5b5a3 100644 --- a/.gitignore +++ b/.gitignore @@ -47,11 +47,10 @@ Makefile.in /m4/ltsugar.m4 /m4/ltversion.m4 -/msvc/Debug/ -/msvc/Release/ +/msvc/x64/ +/msvc/x86/ /msvc/*.ncb /msvc/*.suo -/msvc/*.vcproj.*.user /src/libdivecomputer.exp /src/libdivecomputer.la diff --git a/Makefile.am b/Makefile.am index c3ae858..9ae4414 100644 --- a/Makefile.am +++ b/Makefile.am @@ -16,4 +16,5 @@ pkgconfig_DATA = libdivecomputer.pc EXTRA_DIST = \ libdivecomputer.pc.in \ - msvc/libdivecomputer.vcproj + msvc/libdivecomputer.vcxproj \ + msvc/libdivecomputer.vcxproj.filters diff --git a/configure.ac b/configure.ac index 718f95b..1ac86db 100644 --- a/configure.ac +++ b/configure.ac @@ -1,8 +1,8 @@ # Versioning. m4_define([dc_version_major],[0]) -m4_define([dc_version_minor],[7]) +m4_define([dc_version_minor],[8]) m4_define([dc_version_micro],[0]) -m4_define([dc_version_suffix],[Subsurface-NG]) +m4_define([dc_version_suffix],[devel-Subsurface-NG]) m4_define([dc_version],dc_version_major.dc_version_minor.dc_version_micro[]m4_ifset([dc_version_suffix],-[dc_version_suffix])) # Libtool versioning. diff --git a/msvc/libdivecomputer.vcproj b/msvc/libdivecomputer.vcproj deleted file mode 100644 index 0e689a1..0000000 --- a/msvc/libdivecomputer.vcproj +++ /dev/null @@ -1,1011 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/msvc/libdivecomputer.vcxproj b/msvc/libdivecomputer.vcxproj new file mode 100644 index 0000000..2f99a43 --- /dev/null +++ b/msvc/libdivecomputer.vcxproj @@ -0,0 +1,374 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Release + Win32 + + + Release + x64 + + + + {CEA7215A-D6B5-4840-8086-3C854F371997} + libdivecomputer + Win32Proj + + + + DynamicLibrary + true + $(DefaultPlatformToolset) + Unicode + + + DynamicLibrary + true + $(DefaultPlatformToolset) + Unicode + + + DynamicLibrary + false + $(DefaultPlatformToolset) + Unicode + true + + + DynamicLibrary + false + $(DefaultPlatformToolset) + Unicode + true + + + + + + + + + + + + + + + + + + + true + $(SolutionDir)$(PlatformTarget)\$(Configuration)\bin\ + $(PlatformTarget)\$(Configuration)\obj\ + + + true + $(SolutionDir)$(PlatformTarget)\$(Configuration)\bin\ + $(PlatformTarget)\$(Configuration)\obj\ + + + false + $(SolutionDir)$(PlatformTarget)\$(Configuration)\bin\ + $(PlatformTarget)\$(Configuration)\obj\ + + + false + $(SolutionDir)$(PlatformTarget)\$(Configuration)\bin\ + $(PlatformTarget)\$(Configuration)\obj\ + + + + Disabled + ..\include;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBDIVECOMPUTER_EXPORTS;ENABLE_LOGGING;HAVE_AF_IRDA_H;HAVE_WS2BTH_H;%(PreprocessorDefinitions) + + Level3 + true + + + ws2_32.lib;%(AdditionalDependencies) + $(OutDir)libdivecomputer.def + true + Windows + + + + + Disabled + ..\include;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_WINDOWS;_USRDLL;LIBDIVECOMPUTER_EXPORTS;ENABLE_LOGGING;HAVE_AF_IRDA_H;HAVE_WS2BTH_H;%(PreprocessorDefinitions) + + + Level3 + true + + + ws2_32.lib;%(AdditionalDependencies) + $(OutDir)libdivecomputer.def + true + Windows + + + + + MaxSpeed + true + ..\include;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBDIVECOMPUTER_EXPORTS;ENABLE_LOGGING;HAVE_AF_IRDA_H;HAVE_WS2BTH_H;%(PreprocessorDefinitions) + true + + Level3 + true + + + ws2_32.lib;%(AdditionalDependencies) + $(OutDir)libdivecomputer.def + true + Windows + true + true + + + + + MaxSpeed + true + ..\include;%(AdditionalIncludeDirectories) + _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_WINDOWS;_USRDLL;LIBDIVECOMPUTER_EXPORTS;ENABLE_LOGGING;HAVE_AF_IRDA_H;HAVE_WS2BTH_H;%(PreprocessorDefinitions) + true + + + Level3 + true + + + ws2_32.lib;%(AdditionalDependencies) + $(OutDir)libdivecomputer.def + true + Windows + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + echo EXPORTS > "$(OutDir)libdivecomputer.def" && type "%(FullPath)" >> "$(OutDir)libdivecomputer.def" + echo EXPORTS > "$(OutDir)libdivecomputer.def" && type "%(FullPath)" >> "$(OutDir)libdivecomputer.def" + $(OutDir)libdivecomputer.def;%(Outputs) + $(OutDir)libdivecomputer.def;%(Outputs) + echo EXPORTS > "$(OutDir)libdivecomputer.def" && type "%(FullPath)" >> "$(OutDir)libdivecomputer.def" + echo EXPORTS > "$(OutDir)libdivecomputer.def" && type "%(FullPath)" >> "$(OutDir)libdivecomputer.def" + $(OutDir)libdivecomputer.def;%(Outputs) + $(OutDir)libdivecomputer.def;%(Outputs) + + + + + + diff --git a/msvc/libdivecomputer.vcxproj.filters b/msvc/libdivecomputer.vcxproj.filters new file mode 100644 index 0000000..e5cb0c5 --- /dev/null +++ b/msvc/libdivecomputer.vcxproj.filters @@ -0,0 +1,17 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;hm;inl;inc;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + diff --git a/src/atomics_cobalt_parser.c b/src/atomics_cobalt_parser.c index 7d30ca3..4c56825 100644 --- a/src/atomics_cobalt_parser.c +++ b/src/atomics_cobalt_parser.c @@ -46,7 +46,6 @@ typedef struct atomics_cobalt_parser_t atomics_cobalt_parser_t; struct atomics_cobalt_parser_t { dc_parser_t base; // Depth calibration. - double atmospheric; double hydrostatic; }; @@ -82,7 +81,6 @@ atomics_cobalt_parser_create (dc_parser_t **out, dc_context_t *context) } // Set the default values. - parser->atmospheric = 0.0; parser->hydrostatic = 1025.0 * GRAVITY; *out = (dc_parser_t*) parser; @@ -106,7 +104,6 @@ atomics_cobalt_parser_set_calibration (dc_parser_t *abstract, double atmospheric if (!ISINSTANCE (abstract)) return DC_STATUS_INVALIDARGS; - parser->atmospheric = atmospheric; parser->hydrostatic = hydrostatic; return DC_STATUS_SUCCESS; @@ -151,15 +148,10 @@ atomics_cobalt_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, un dc_gasmix_t *gasmix = (dc_gasmix_t *) value; dc_tank_t *tank = (dc_tank_t *) value; - double atmospheric = 0.0; + unsigned int atmospheric = array_uint16_le (p + 0x26); char buf[BUFLEN]; dc_field_string_t *string = (dc_field_string_t *) value; - if (parser->atmospheric) - atmospheric = parser->atmospheric; - else - atmospheric = array_uint16_le (p + 0x26) * BAR / 1000.0; - unsigned int workpressure = 0; if (value) { @@ -168,7 +160,7 @@ atomics_cobalt_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, un *((unsigned int *) value) = array_uint16_le (p + 0x58) * 60; break; case DC_FIELD_MAXDEPTH: - *((double *) value) = (array_uint16_le (p + 0x56) * BAR / 1000.0 - atmospheric) / parser->hydrostatic; + *((double *) value) = (signed int)(array_uint16_le (p + 0x56) - atmospheric) * (BAR / 1000.0) / parser->hydrostatic; break; case DC_FIELD_GASMIX_COUNT: case DC_FIELD_TANK_COUNT: @@ -220,6 +212,9 @@ atomics_cobalt_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, un return DC_STATUS_DATAFORMAT; } break; + case DC_FIELD_ATMOSPHERIC: + *((double *) value) = atmospheric / 1000.0; + break; case DC_FIELD_STRING: switch(flags) { case 0: // Serialnr @@ -274,11 +269,7 @@ atomics_cobalt_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback if (size < header + SZ_SEGMENT * nsegments) return DC_STATUS_DATAFORMAT; - double atmospheric = 0.0; - if (parser->atmospheric) - atmospheric = parser->atmospheric; - else - atmospheric = array_uint16_le (data + 0x26) * BAR / 1000.0; + unsigned int atmospheric = array_uint16_le (data + 0x26); // Previous gas mix - initialize with impossible value unsigned int gasmix_previous = 0xFFFFFFFF; @@ -309,7 +300,7 @@ atomics_cobalt_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback // Depth (1/1000 bar). unsigned int depth = array_uint16_le (data + offset + 0); - sample.depth = (depth * BAR / 1000.0 - atmospheric) / parser->hydrostatic; + sample.depth = (signed int)(depth - atmospheric) * (BAR / 1000.0) / parser->hydrostatic; if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata); // Pressure (1 psi). diff --git a/src/hw_ostc3.c b/src/hw_ostc3.c index 3ed6bc7..119af09 100644 --- a/src/hw_ostc3.c +++ b/src/hw_ostc3.c @@ -33,6 +33,10 @@ #define ISINSTANCE(device) dc_device_isinstance((device), &hw_ostc3_device_vtable) +#define OSTC3FW(major,minor) ( \ + (((major) & 0xFF) << 8) | \ + ((minor) & 0xFF)) + #define SZ_DISPLAY 16 #define SZ_CUSTOMTEXT 60 #define SZ_VERSION (SZ_CUSTOMTEXT + 4) @@ -1282,10 +1286,13 @@ hw_ostc3_firmware_block_write2 (hw_ostc3_device_t *device, unsigned int address, static dc_status_t hw_ostc3_firmware_block_write (hw_ostc3_device_t *device, unsigned int address, const unsigned char data[], unsigned int size) { - if (device->firmware >= 0x0309) { - return hw_ostc3_firmware_block_write2 (device, address, data, size); - } else { + // Support for the S_BLOCK_WRITE2 command is only available since the + // hwOS Tech firmware v3.09 and the hwOS Sport firmware v10.64. + if ((device->firmware < OSTC3FW(3,9)) || + (device->firmware >= OSTC3FW(10,0) && device->firmware < OSTC3FW(10,64))) { return hw_ostc3_firmware_block_write1 (device, address, data, size); + } else { + return hw_ostc3_firmware_block_write2 (device, address, data, size); } } diff --git a/src/mares_iconhd_parser.c b/src/mares_iconhd_parser.c index 5d26d13..34d39c7 100644 --- a/src/mares_iconhd_parser.c +++ b/src/mares_iconhd_parser.c @@ -31,6 +31,10 @@ #define ISINSTANCE(parser) dc_parser_isinstance((parser), &mares_iconhd_parser_vtable) +#define OBJVERSION(major,minor) ( \ + (((major) & 0xFF) << 8) | \ + ((minor) & 0xFF)) + #define SMART 0x000010 #define SMARTAPNEA 0x010010 #define ICONHD 0x14 @@ -374,7 +378,7 @@ mares_genius_cache (mares_iconhd_parser_t *parser) unsigned int type = array_uint16_le (data); unsigned int minor = data[2]; unsigned int major = data[3]; - if (type != 1 || major != 0 || minor > 1) { + if (type != 1 || OBJVERSION(major,minor) > OBJVERSION(1,1)) { ERROR (abstract->context, "Unsupported object type (%u) or version (%u.%u).", type, major, minor); return DC_STATUS_DATAFORMAT; @@ -389,8 +393,14 @@ mares_genius_cache (mares_iconhd_parser_t *parser) extra = 8; } + // The Genius header (v1.x) has 10 bytes more at the end. + unsigned int more = 0; + if (major == 1) { + more = 16; + } + // Get the header size. - unsigned int headersize = 0xB8 + extra; + unsigned int headersize = 0xB8 + extra + more; if (headersize > size) { ERROR (abstract->context, "Buffer overflow detected!"); return DC_STATUS_DATAFORMAT; @@ -869,7 +879,9 @@ mares_iconhd_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t unsigned int type = array_uint16_le (data); unsigned int minor = data[2]; unsigned int major = data[3]; - if (type > 1 || major != 0 || minor != 2) { + if (type > 1 || + (type == 0 && OBJVERSION(major,minor) > OBJVERSION(1,0)) || + (type == 1 && OBJVERSION(major,minor) > OBJVERSION(0,2))) { ERROR (abstract->context, "Unsupported object type (%u) or version (%u.%u).", type, major, minor); return DC_STATUS_DATAFORMAT; diff --git a/src/mclean_extreme_parser.c b/src/mclean_extreme_parser.c index f053986..5fef8aa 100644 --- a/src/mclean_extreme_parser.c +++ b/src/mclean_extreme_parser.c @@ -22,6 +22,8 @@ #include #include +#include + #include "mclean_extreme.h" #include "context-private.h" #include "parser-private.h" @@ -152,19 +154,19 @@ mclean_extreme_parser_get_field(dc_parser_t *abstract, dc_field_type_t type, uns dc_gasmix_t *gasmix = (dc_gasmix_t *)value; dc_salinity_t *salinity = (dc_salinity_t *)value; - const unsigned int psurf = array_uint16_le(abstract->data + 0x001E); + const unsigned int atmospheric = array_uint16_le(abstract->data + 0x001E); const unsigned int density_index = abstract->data[0x0023]; double density = 0; switch (density_index) { case 0: - density = 1.000; + density = 1000.0; break; case 1: - density = 1.020; + density = 1020.0; break; case 2: - density = 1.030; + density = 1030.0; break; default: ERROR(abstract->context, "Corrupt density index in dive data"); @@ -177,17 +179,17 @@ mclean_extreme_parser_get_field(dc_parser_t *abstract, dc_field_type_t type, uns *((unsigned int *)value) = array_uint32_le(abstract->data + SZ_CFG + 0x000C) - array_uint32_le(abstract->data + SZ_CFG + 0x0000); break; case DC_FIELD_MAXDEPTH: - *((double *)value) = 0.01 * (array_uint16_le(abstract->data + SZ_CFG + 0x0016) - psurf) / density; + *((double *)value) = (signed int)(array_uint16_le(abstract->data + SZ_CFG + 0x0016) - atmospheric) * (BAR / 1000.0) / (density * GRAVITY); break; case DC_FIELD_AVGDEPTH: - *((double *)value) = 0.01 * (array_uint16_le(abstract->data + SZ_CFG + 0x0018) - psurf) / density; + *((double *)value) = (signed int)(array_uint16_le(abstract->data + SZ_CFG + 0x0018) - atmospheric) * (BAR / 1000.0) / (density * GRAVITY); break; case DC_FIELD_SALINITY: - salinity->density = density * 1000.0; + salinity->density = density; salinity->type = density_index == 0 ? DC_WATER_FRESH : DC_WATER_SALT; break; case DC_FIELD_ATMOSPHERIC: - *((double *)value) = 0.001 * array_uint16_le(abstract->data + 0x001E); + *((double *)value) = atmospheric / 1000.0; break; case DC_FIELD_TEMPERATURE_MINIMUM: *((double *)value) = (double)abstract->data[SZ_CFG + 0x0010]; diff --git a/src/shearwater_predator_parser.c b/src/shearwater_predator_parser.c index fc7abc4..348ad28 100644 --- a/src/shearwater_predator_parser.c +++ b/src/shearwater_predator_parser.c @@ -925,7 +925,7 @@ shearwater_predator_parser_samples_foreach (dc_parser_t *abstract, dc_sample_cal // Depth (absolute pressure in millibar) unsigned int depth = array_uint16_be (data + idx + 1); - sample.depth = (depth - parser->atmospheric) * (BAR / 1000.0) / (parser->density * GRAVITY); + sample.depth = (signed int)(depth - parser->atmospheric) * (BAR / 1000.0) / (parser->density * GRAVITY); if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata); // Temperature (1/10 °C). diff --git a/src/sporasub_sp2.c b/src/sporasub_sp2.c index c0f6b49..4593f6d 100644 --- a/src/sporasub_sp2.c +++ b/src/sporasub_sp2.c @@ -342,22 +342,14 @@ sporasub_sp2_device_read (dc_device_t *abstract, unsigned int address, unsigned static dc_status_t sporasub_sp2_device_dump (dc_device_t *abstract, dc_buffer_t *buffer) { + sporasub_sp2_device_t *device = (sporasub_sp2_device_t *) abstract; + // Allocate the required amount of memory. if (!dc_buffer_resize (buffer, SZ_MEMORY)) { ERROR (abstract->context, "Insufficient buffer space available."); return DC_STATUS_NOMEMORY; } - return device_dump_read (abstract, dc_buffer_get_data (buffer), - dc_buffer_get_size (buffer), SZ_READ); -} - -static dc_status_t -sporasub_sp2_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, void *userdata) -{ - dc_status_t status = DC_STATUS_SUCCESS; - sporasub_sp2_device_t *device = (sporasub_sp2_device_t *) abstract; - // Emit a device info event. dc_event_devinfo_t devinfo; devinfo.model = 0; @@ -371,6 +363,16 @@ sporasub_sp2_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, vendor.size = sizeof (device->version); device_event_emit (abstract, DC_EVENT_VENDOR, &vendor); + return device_dump_read (abstract, dc_buffer_get_data (buffer), + dc_buffer_get_size (buffer), SZ_READ); +} + +static dc_status_t +sporasub_sp2_device_foreach (dc_device_t *abstract, dc_dive_callback_t callback, void *userdata) +{ + dc_status_t status = DC_STATUS_SUCCESS; + sporasub_sp2_device_t *device = (sporasub_sp2_device_t *) abstract; + dc_buffer_t *buffer = dc_buffer_new (SZ_MEMORY); if (buffer == NULL) { status = DC_STATUS_NOMEMORY; diff --git a/src/sporasub_sp2_parser.c b/src/sporasub_sp2_parser.c index e036dd2..e041495 100644 --- a/src/sporasub_sp2_parser.c +++ b/src/sporasub_sp2_parser.c @@ -112,9 +112,13 @@ sporasub_sp2_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi const unsigned char *data = abstract->data; unsigned int size = abstract->size; + dc_salinity_t *water = (dc_salinity_t *) value; + if (size < SZ_HEADER) return DC_STATUS_DATAFORMAT; + unsigned int settings = data[0x1A]; + if (value) { switch (type) { case DC_FIELD_DIVETIME: @@ -132,6 +136,10 @@ sporasub_sp2_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi case DC_FIELD_TEMPERATURE_MAXIMUM: *((double *) value) = array_uint16_le (data + 0x16) / 10.0; break; + case DC_FIELD_SALINITY: + water->type = settings & 0x08 ? DC_WATER_FRESH : DC_WATER_SALT; + water->density = 0.0; + break; default: return DC_STATUS_UNSUPPORTED; } @@ -151,9 +159,10 @@ sporasub_sp2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t return DC_STATUS_DATAFORMAT; unsigned int nsamples = array_uint16_le(data); + unsigned int settings = data[0x1A]; // Get the sample interval. - unsigned int interval_idx = data[0x1A]; + unsigned int interval_idx = settings & 0x03; const unsigned int intervals[] = {1, 2, 5, 10}; if (interval_idx >= C_ARRAY_SIZE(intervals)) { ERROR (abstract->context, "Invalid sample interval index %u", interval_idx); @@ -170,8 +179,7 @@ sporasub_sp2_parser_samples_foreach (dc_parser_t *abstract, dc_sample_callback_t unsigned int value = array_uint32_le (data + offset); unsigned int heartrate = (value & 0xFF000000) >> 24; unsigned int temperature = (value & 0x00FFC000) >> 14; - unsigned int unknown = (value & 0x00003000) >> 12; - unsigned int depth = (value & 0x00000FFF) >> 0; + unsigned int depth = (value & 0x00003FFF) >> 0; // Time (seconds) time += interval; diff --git a/src/uwatec_smart_parser.c b/src/uwatec_smart_parser.c index be74b1c..7a12a4e 100644 --- a/src/uwatec_smart_parser.c +++ b/src/uwatec_smart_parser.c @@ -62,8 +62,8 @@ #define HEADER 1 #define PROFILE 2 -#define FRESH 1.000 -#define SALT 1.025 +#define FRESH 1000.0 +#define SALT 1025.0 #define FREEDIVE 0x00000080 #define GAUGE 0x00001000 @@ -789,7 +789,7 @@ uwatec_smart_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi const uwatec_smart_header_info_t *table = parser->header; const unsigned char *data = abstract->data; - double salinity = (parser->watertype == DC_WATER_SALT ? SALT : FRESH); + double density = (parser->watertype == DC_WATER_SALT ? SALT : FRESH); dc_gasmix_t *gasmix = (dc_gasmix_t *) value; dc_tank_t *tank = (dc_tank_t *) value; @@ -801,7 +801,7 @@ uwatec_smart_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi *((unsigned int *) value) = array_uint16_le (data + table->divetime) * 60; break; case DC_FIELD_MAXDEPTH: - *((double *) value) = array_uint16_le (data + table->maxdepth) / 100.0 / salinity; + *((double *) value) = array_uint16_le (data + table->maxdepth) * (BAR / 1000.0) / (density * GRAVITY); break; case DC_FIELD_GASMIX_COUNT: *((unsigned int *) value) = parser->ngasmixes; @@ -844,7 +844,7 @@ uwatec_smart_parser_get_field (dc_parser_t *abstract, dc_field_type_t type, unsi if (table->settings == UNSUPPORTED) return DC_STATUS_UNSUPPORTED; water->type = parser->watertype; - water->density = salinity * 1000.0; + water->density = density; break; default: return DC_STATUS_UNSUPPORTED; @@ -940,9 +940,9 @@ uwatec_smart_parse (uwatec_smart_parser_t *parser, dc_sample_callback_t callback unsigned int rbt = 99; unsigned int tank = 0; unsigned int gasmix = 0; - double depth = 0, depth_calibration = 0; - double temperature = 0; - double pressure = 0; + unsigned int depth = 0, depth_calibration = 0; + int temperature = 0; + unsigned int pressure = 0; unsigned int heartrate = 0; unsigned int bearing = 0; unsigned int bookmark = 0; @@ -950,7 +950,7 @@ uwatec_smart_parse (uwatec_smart_parser_t *parser, dc_sample_callback_t callback // Previous gas mix - initialize with impossible value unsigned int gasmix_previous = 0xFFFFFFFF; - double salinity = (parser->watertype == DC_WATER_SALT ? SALT : FRESH); + double density = (parser->watertype == DC_WATER_SALT ? SALT : FRESH); unsigned int interval = 4; if (parser->divemode == DC_DIVEMODE_FREEDIVE) { @@ -1026,8 +1026,8 @@ uwatec_smart_parse (uwatec_smart_parser_t *parser, dc_sample_callback_t callback const uwatec_smart_event_info_t *events = NULL; switch (table[id].type) { case PRESSURE_DEPTH: - pressure += ((signed char) ((svalue >> NBITS) & 0xFF)) / 4.0; - depth += ((signed char) (svalue & 0xFF)) / 50.0; + pressure += (signed char) ((svalue >> NBITS) & 0xFF); + depth += (signed char) (svalue & 0xFF); complete = 1; break; case RBT: @@ -1040,37 +1040,37 @@ uwatec_smart_parse (uwatec_smart_parser_t *parser, dc_sample_callback_t callback break; case TEMPERATURE: if (table[id].absolute) { - temperature = svalue / 2.5; + temperature = svalue; have_temperature = 1; } else { - temperature += svalue / 2.5; + temperature += svalue; } break; case PRESSURE: if (table[id].absolute) { if (parser->trimix) { tank = (value & 0xF000) >> 12; - pressure = (value & 0x0FFF) / 4.0; + pressure = (value & 0x0FFF); } else { tank = table[id].index; - pressure = value / 4.0; + pressure = value; } have_pressure = 1; gasmix = tank; } else { - pressure += svalue / 4.0; + pressure += svalue; } break; case DEPTH: if (table[id].absolute) { - depth = value / 50.0; + depth = value; if (!calibrated) { calibrated = 1; depth_calibration = depth; } have_depth = 1; } else { - depth += svalue / 50.0; + depth += svalue; } complete = 1; break; @@ -1195,7 +1195,7 @@ uwatec_smart_parse (uwatec_smart_parser_t *parser, dc_sample_callback_t callback } if (have_temperature) { - sample.temperature = temperature; + sample.temperature = temperature / 2.5; if (callback) callback (DC_SAMPLE_TEMPERATURE, sample, userdata); } @@ -1216,7 +1216,7 @@ uwatec_smart_parse (uwatec_smart_parser_t *parser, dc_sample_callback_t callback idx = uwatec_smart_find_tank(parser, tank); if (idx < parser->ntanks) { sample.pressure.tank = idx; - sample.pressure.value = pressure; + sample.pressure.value = pressure / 4.0; if (callback) callback (DC_SAMPLE_PRESSURE, sample, userdata); } } @@ -1233,7 +1233,7 @@ uwatec_smart_parse (uwatec_smart_parser_t *parser, dc_sample_callback_t callback } if (have_depth) { - sample.depth = (depth - depth_calibration) / salinity; + sample.depth = (signed int)(depth - depth_calibration) * (2.0 * BAR / 1000.0) / (density * GRAVITY); if (callback) callback (DC_SAMPLE_DEPTH, sample, userdata); }