2148 Commits

Author SHA1 Message Date
Michael Keller
d37cb91734 Merge remote-tracking branch 'libdivecomputer/master' into update_libdivecomputer_202402 2024-02-02 17:40:41 +13:00
Michael Keller
78710ab2f1
Merge pull request #55 from subsurface/add_garmin_descent_mk3_parsing_support 2024-01-23 11:08:37 +13:00
Michael Keller
76170009b4 Garmin: Add Support for Parsing of Garmin Descent Mk3 FIT files.
Add support for FIT files generated by the Garmin Descent Mk3.
This just fixes a field number limitation, it has not yet been
verified that the Mk3 file format is properly interpreted by Subsurface.

Signed-off-by: Michael Keller <mikeller@042.ch>
2024-01-22 12:54:02 +13:00
Jef Driesen
1d0aeecf65 Fix the React Pro White memory layout 2024-01-18 10:53:08 +01:00
Jef Driesen
de6696bc7f Add support for the Shearwater Tern 2024-01-17 07:48:54 +01:00
Jef Driesen
cfe345aa8e Exclude O2 sensors without calibration data
O2 sensor for which no calibration data is available will always result
in a ppO2 value of zero for all samples, which isn't very useful.
2024-01-12 09:15:12 +01:00
Jef Driesen
d47e1ce02b Add support for the Scubapro G3 and Luna 2.0
The new models appear to be compatible with the previous G2, but with
new model numbers and bluetooth names. The USB VID/PID for the G3 is
still unknown.

Reported-by: Greg McLaughlin <support@moremobilesoftware.com>
2024-01-10 09:01:59 +01:00
Jef Driesen
08d8c3e132 Add support for parsing the compass bearings
When no compass bearing is set on the dive computer, the stored value is
initialized to zero. Since this can also be a valid value, those zero
values are only ignored untill another non-zero value is present.

In later firmware versions, the value will get initialized to 0xFFFF
instead.
2023-11-23 11:42:23 +01:00
Jef Driesen
2d9008aff7 Remove disabled gas mixes
Returning disabled gas mixes to the application mainly results in lots
of unnecessary information. Therefore, remove all disabled gas mixes,
unless they are actively used. Many other dive computers do not even
include disabled gas mixes in the data.

Unlike previously assumed, the on/off state of each gas mix is actually
available in the PNF data format (opening record 4). For the older
Predator data format, this info isn't available and all gas mixes are
manually marked as enabled.
2023-11-15 11:08:21 +01:00
Jef Driesen
e1762fc8bd Skip all non-sample records
The IX3M 2 with the APOS5 firmware supports a new info record containing
the GPS coordinates. To be able to identify this new record type, the
previously reserved field at byte offset 52 is now used to store the
record type: zero for the existing sample record and one for the new
info record.

This also fixes the underlying problem of the zero timestamp in commit
3c50e91a1096332df66b2d33d64e5a8dc9136ab9, because the zero timestamp was
the result of incorrectly interpreting the first info record as a sample
record.
2023-11-02 15:45:24 +01:00
Jef Driesen
3c50e91a10 Allow a zero timestamp for the first sample
Previously the timestamp of the first sample was always a non-zero
value, but the IX3M 2 with the APOS5 firmware now appears to record a
timestamp of zero. This was incorrectly detected as a backwards time
jump because the time is also initialized to zero.
2023-10-29 21:31:40 +01:00
Jef Driesen
cb0164150e Merge branch 'bluelinkpro' 2023-10-19 10:34:26 +02:00
Jef Driesen
e83732e200 Fix the Mares Bluelink Pro communication
Sending the two byte command header and then waiting for the ack byte
before sending the remainder of the command payload causes problems for
some (but not all) users. Most likely the extra roundtrip time due to
waiting for the ack byte results in a delay that sometimes exceeds a
timeout in the dive computer while it's waiting for the payload data.

On the other hand, sending both the command header and the payload data
in one single packet is also not an option, because it causes problems
for some models, like the Mares Matrix. See commit
59bfb0f3189b14ae858650b851539d59e3fefe86 for details.

As an alternative solution, send the packet payload immediately after
the header, without waiting for the ack byte. This eliminates the extra
roundtrip time, while still sending out two separate bluetooth packets.
2023-09-27 10:10:40 +02:00
Jef Driesen
a7e7439cab Setup the 2 byte command header internally
Instead of setting up the two byte command header in every function,
move this logic to a central place.
2023-09-15 09:23:58 +02:00
Jef Driesen
072f0d4242 Fix a potential buffer overflow 2023-09-08 16:10:45 +02:00
Jef Driesen
baa1c494c1 Use a symbolic constant for the header size 2023-09-08 16:10:45 +02:00
Jef Driesen
330cb88952 Use plain ascii text in the code comments 2023-09-08 16:10:38 +02:00
Jef Driesen
37421a1b9a Merge branch 'filter-function' 2023-08-24 17:18:46 +02:00
Jef Driesen
fe9b47f4bd Document the device descriptor functions 2023-08-24 17:18:24 +02:00
Jef Driesen
ed871137b1 Export the filter function in the public api
The functionality provided by the filter function is not only useful for
the built-in transports, but also for the applications. For example in
combination with a custom transport.
2023-08-24 17:18:24 +02:00
Jef Driesen
4a9be44afd Use separate data structures for USB and USB HID
Using separate data structures for the filtering allows to keep the USB
and USB HID backends completely independent from each other.
2023-08-24 17:18:24 +02:00
Jef Driesen
a985b11859 Replace the filter parameters with an alternative
The USB I/O backend needs some additional information (e.g. interface
number and in/out endpoints) to setup the USB connection. This info is
currently maintained inside the descriptor filter function and gets
passed to the USB backend by means of the filter parameters.

This approach is not only unnecessary complex, but also makes it very
difficult to expose the filter function in the public api because the
data structures for those parameters are private.

Therefore, this data exchange is replaced with a direct mapping between
the USB VID/PID and the configuration info in the USB backend itself.
2023-08-24 17:18:24 +02:00
Jef Driesen
b2310e62d6 Pass the descriptor to the filter function
Passing the descriptor for which the filter function is being called is
a good practice and will also allow to implement some more specific
filtering in the future.
2023-08-24 17:18:22 +02:00
Jef Driesen
301fdbe364 Remove support for the Tusa TC1
Apparantly the Tusa TC1 does not support downloading dives at all. The
bluetooth communication is probably disabled in the firmware.
2023-08-16 13:17:55 +02:00
Jef Driesen
beb348dbf6 Merge branch 'ostc-remove-disabled-gasmixes' 2023-08-14 10:23:55 +02:00
Jef Driesen
5d36cc0798 Remove disabled gas mixes
Returning disabled gas mixes to the application mainly results in lots
of unnecessary information. Therefore, remove all disabled gas mixes,
unless they are actively used. Many other dive computers do not even
include disabled gas mixes in the data.

The removal of the disabled gas mixes requires a two pass approach for
parsing the profile data. The first pass is only used to discover which
gas mixes are actively used during the dive. Next, all disabled and not
actively used gas mixes are removed from the list. Since removing one or
more gas mixes also invalidates the index of the remaining gas mixes,
the profile needs to be parsed again to report the new index in the gas
switch samples.

The original one based index is used as the stable gas mix id, used for
looking up the new gas mix index.
2023-08-11 12:39:39 +02:00
Jef Driesen
993283d1c8 Store the original one based gas mix index 2023-08-10 14:04:52 +02:00
Jef Driesen
323804d5e6 Keep track of the actively used gas mixes
The hwOS models support switching to a disabled gas mix. Therefore, the
disabled state is not always a good indication whether a gas mix is used
or not. Look for gas switches during the parsing step instead to keep
track of the actively used gas mixes.
2023-08-10 14:04:20 +02:00
Jef Driesen
ecc9e0b09b Limit the lookup function to the manual gas mixes
Looking up the gasmix by oxygen and helium content is only needed for
the manual gas mixes. For gas switches to a fixed gas mix, the index is
stored directly in the data.
2023-08-02 15:43:19 +02:00
Michael Keller
577b694087
Merge pull request #54 from mikeller/improve_cressi_leonardo_ascent_warnings 2023-08-01 21:43:41 +12:00
Michael Keller
58ea31e62e Cressi Leonardo: Turn ascent warnings into info events.
According to user feedback the ascent warnings on the Cressi Leonardo
are very sensitive. They come in 3 different levels.
This change turns levels 1 and 2 into info events, leaving only 3 as a
warning.
Fixes https://groups.google.com/g/subsurface-divelog/c/qBXF0wmyjKg/m/5qA0_KABCQAJ

Signed-off-by: Michael Keller <github@ike.ch>
2023-07-28 00:02:14 +12:00
Michael Keller
97b2c89aaa
Merge pull request #52 from mikeller/hw_ostc_mark_inactive_gases 2023-07-23 15:43:32 +12:00
Jef Driesen
8bfbb94087 Include the command byte in the hexdump
The hexdump only includes the command parameters, but not the main
command byte. Since there are many commands without parameters, that's
not very useful.
2023-07-20 23:40:02 +02:00
Jef Driesen
9cde393e5f Merge branch 'shearwater-tank-usage' 2023-07-18 00:30:22 +02:00
Jef Driesen
9bc742d3ac Use the HP CCR data for the oxygen/diluent usage
For dives in HP CCR mode, the oxygen and diluent tanks are stored at a
fixed index. This information is more reliable than using the tank name,
and also prevents the incorrect labeling of one of the other tanks as an
oxygen or diluent tank.
2023-07-18 00:30:06 +02:00
Jef Driesen
a4cd21b811 Use the GTR mode to detect sidemount tanks
Firmware v84 introduced support for sidemount diving. Users can now
configure the two sidemount tanks as the source for the GTR (Gas Time
Remaining) estimations. We can take advantage of this feature to detect
the sidemount tanks. This is more reliable than using the tank name.
2023-07-18 00:30:06 +02:00
Jef Driesen
f77e9c03fc Restrict the oxygen/diluent usage to CCR dives
For open-circuit dives, the oxygen and diluent usage doesn't make any
sense at all. But when an open-circuit diver uses the letter 'D' to
indicate a tank for decompression use, it will get incorrectly labeled
as a diluent tank.

Fixed by restricting the oxygen/diluent usage to CCR dives only.
2023-07-18 00:30:06 +02:00
Jef Driesen
f818a5a92a Add a function for detecting CCR dives 2023-07-18 00:30:06 +02:00
Linus Torvalds
3e39cb427a garmin: fix up some leftovers
When importing FIT files, we may not have serial numbers or firmware
versions in the result, so don't report them when they don't exist.

Also, add the product name to the FILE message field list, which can
contain relevant information.  Not that we report it right now, but now
we *could* do so.

This concludes the Suunto FIT file export saga.  It's not great, but it
looks like it should be usable.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2023-07-16 11:28:33 -07:00
Linus Torvalds
e81eca685a garmin: add a _third_ time offset field
So FIT files seem to have many many different ways to describe time
offsets.  And I'm not talking about the overall Garmin time offset of
631065600, which is the conversion from the "Unix Epoch" (Jan 1, 1970)
to the "Garmin Epoch" (Dec 31, 1989).

No, I'm talking just about "device time" to "local time" to "UTC"
conversions.

The DEVICE_SETTINGS message has two different fields for time offsets:
there's a "UTC offset" (presumably this is the timezone the device is
set to), and a "time offset" which we actually use to transform the
recorded time of the dive into the local time that we report.

But the Suunto FIT export doesn't seem to use either of those, and
instead Nick Clark points outthe Suunto FAQ:

 "Timestamp fields are deliberately defined as UTC time so that they may
  be conveniently displayed in the local time if so desired.

  In some instances it is useful to know the UTC offset when the file
  was generated (possibly different from when it is decoded). This can
  be accomplished by logging a single message containing both a
  local_timestamp and a timestamp field. This will establish the UTC
  offset of the file.

  Presently these fields are predefined for activity and monitoring
  messages"

so to get the actual local time, instead of getting it from the
DEVICE_SETTINGS message, we now have to parse the ACTIVITY message, and
take the difference between the regular timestamp and the
"local_timestamp" field.

The great thing about standards is that there are so many to choose
from.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2023-07-16 11:17:32 -07:00
Linus Torvalds
dc8f32609e garmin: add 'FIELD_DESCRIPTION' message definitions
We don't use them, but they seem to be trying to describe what the
developer fields are used for.  We may now parse the developer fields
enough to skip over them gracefully, but it looks like we migth some day
want to _really_ parse them, and while I haven't figured it out (at
all!) yet, this may some day help.

For example, we get things like this:

  FIELD_DESCRIPTION_name (STRING): "Depth"
  FIELD_DESCRIPTION_unit (STRING): "feet"
  FIELD_DESCRIPTION_original_mesg (UINT16): 20
  FIELD_DESCRIPTION_data_index (UINT8): 0
  FIELD_DESCRIPTION_field_definition (UINT8): 0
  FIELD_DESCRIPTION_base_type (UINT8): 136

which doesn't tell me anything at all right now, but looks like maybe it
should some day.

It looks like this is defining a developer field for depth in feet
(duh), and the data format may be the same as a RECORD message (20),
which does indeed normally contain the depth (but in mm as an UINT32,
and it's field number 92, so..)

End result: not useful right now, because I'm much too confused about
it.  But the debug printout looks interesting.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2023-07-16 11:01:00 -07:00
Linus Torvalds
196cfdf4df garmin: add names for a few RECORD message fields
Not because we use them, but because it makes it clearer from the debug
output that we know what they are and that they aren't interesting..

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2023-07-16 11:01:00 -07:00
Linus Torvalds
503afc1a5f garmin: improve on the debug formatting for field printouts
This also gets the passing of string values right, even if we don't
actually use this right now.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2023-07-16 11:00:52 -07:00
Linus Torvalds
e02df46a2b garmin: remove some left-over verbose hexdump debugging
This was part of me trying to figure out the compressed formats and the
developer fields, it's just noise now.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2023-07-16 09:56:12 -07:00
Linus Torvalds
2879bd69a5 Garmin: parse the ACTIVITY message record
The ACTIVITY message contains a "local timestamp" in addition to the
regular timestamp. That gives us the timezone information.

Or rather, it would give us the timezone info if we actually used it.
But now we at least parse it, so that we *could* use it.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2023-07-15 10:11:04 -07:00
Linus Torvalds
4a2dec531e garmin: relax file name length rules
We end up using the FIT file name as the "fingerprint" for the dive, and
include it at the beginning of the dive data as such.  And because of
how Garmin encoded the FIT files, we ended up having a fixed 24-byte
length for this, which is normally the date encoding:

    YYYY-MM-DD-HH-MM-SS.FIT

with the terminating NUL character.

Of course, then Garmin started using a short-form encoding too
(presumably due to FAT filesystem limits), and we have magic code to
sort the dates properly, using the name format

    YMDHMMSS.FIT

with the numbers encoded in a shorter format (eg "C4ND0302.fit" is
equivalent to "2022-04-23-13-03-02.fit").  See name_cmp() and
parse_short_name() for details.

Anyway, because we use the (zero-padded) 24 characters of the name as
the fingerprint, we used a fixed-size buffer for the filename that was
limited to that maximum size Garmin creates.

But then you download those things, and have multiple vendors, and
suddenly that 24-character limit on the filename is very annoying.

Instead of fixing this in some clean and generic way, let's just raise
the namelength limit to something bigger, and continue to use the first
24 characters of the name for the fingerprint.

Pretty it isn't, but it makes it slightly easier to import random FIT
files that don't conform exactly to the traditional Garmin format.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2023-07-14 12:31:33 -07:00
Linus Torvalds
67cd1cc0fd Expose FIT file parsing as its own "vendor"
Since we can now parse FIT files from other vendors than Garmin (ie the
Suunto FIT file export), let's expose this as a generic "FIT file
import" in the dive computer list.

It's all still very much using the Garmin parser, but uses a model ID
that is zero.  The only difference that makes is that it also tells the
parser to treat the result as a dive even if it cannot find the actual
dive markers that Garmin uses, since those won't exist in the limited
FIT file export.

This is still somewhat inconvenient, in that you cannot point to the
file itself, you can just point to the directory that contains FIT
files.  And right now we have an artifical length limitation on the
filenames, but I'll fix that next.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2023-07-14 12:07:30 -07:00
Linus Torvalds
929ce47155 garmin_parser: add support for developer fields
This was the _actual_ reason why the Suunto FIT file import fell flat on
its face: it adds records with developer fields in them, and I just had
no idea how to parse them.

It turns out that they aren't all *that* horrible to parse: they are
kind of like a special case of the regular FIT event fields.

And no, this does not really parse them: it only parses the layout, and
using that it can then skip the developer fields without causing the
decoder to go all wonky and lose stream synchronization.

At least it works for the specific case of the Suunto FIT files, and the
code makes some amount of sense.  The FIT format may be odd, but at the
same time it's most definitely designed for pretty simplistic devices,
so it's not some kind of crazy XML thing.

This gets us parsing those Suunto FIT files at least partially.

That said, it is all very rough indeed, since you have to lie and claim
you're downloading from a Garmin, and have to set up the whole magic
'Garmin/Activity/' directory structure and limit the file size to the 24
characters that Garmin uses.

So this is by no means the real solution.

Considering that Jef doesn't want the Garmin parser in libdivecomputer
anyway, the proper solution might be to move this all to subsurface, and
make it be a "FIT file import" thing instead.  Annoying, but on the
other hand it has also been a bit awkward to have it in libdivecomputer.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2023-07-13 14:01:58 -07:00
Linus Torvalds
147d3df635 garmin_parser: add support for compressed records and more debug output
This turns out to have been another false turn: mis-parsing the FIT file
caused us to think it had compressed records.

So I spent much too much time trying to figure out how those compressed
records actually work.  This is the result.

It looks like the only difference between a compressed record and a
regular one is that the compressed record has a single-byte "this is the
record type and the time offset" field at the start.  That basically
avoids the need of then having a full 4-byte absolute time for such a
record.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2023-07-13 13:58:44 -07:00
Linus Torvalds
4aa70c9e2a garmin_parser: add a HRM profile message stub
This is an empty stub for the HRM profile message, which isn't actually
used by anything I know of, but came up as a result of some mis-parsing
of odd FIT files generated by the Suunto mobile app.

Losing synchronization in the FIT file then caused the parser to think
it needed this message type, and not having it then caused an early
abort.

While it's not actually needed once parsing things correctly, since I
looked up the message number and name for this message type, let's just
keep it around.  It won't hurt, and maybe it avoids me having to look it
up in the future.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2023-07-13 13:53:15 -07:00