Initial support for McLean Extreme
Signed-off by: David McLean Carron <david_de_carron@hotmail.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This adds the string field interface to the Shearwater family of dive
computers.
That includes proper serial number formatting, but it also has a lot of
new fields for battery information (both the dive computer itself and
the transmitter) but also deco model information.
Much of the deco model cases come from Anton Lundin in the original
subsurface branch, and Dirk Hohndel added the battery type and serial
number and firmware version data. And I ended up massaging it even in
that original branch, so it blamed me for all these lines even back
there.
The sign-offs from Dirk and Anton are from the original commits.
Signed-off-by: Anton Lundin <glance@acc.umu.se>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This re-applied commit 902dbf4d6d24 ("shearwater: Fallback to
average/voted ppo2") which got lost in the last merge with upstream when
I synced with Jef's rewrite of the PNF parser.
Reported-by: Martin Long <martin@longhome.co.uk>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This logs every INFO_EVENT record and provides a SAMPLE_EVENT_BOOKMARK
event for the only INFO_EVENT we can parse so far, the TAG event.
Three bits in the flag value in that event structure are now used to
hold the tag type, and if a non-zero type has been set, then the value
is the heading in degress.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Dirk seems to have some documentation about the different ID's, plus it
just makes sense to order the switch statement by number.
This is partly based on Dirk's original commit to do the different model
numbers, with various changes over time due to merge conflict
resolution. Dirk's sign-off comes from Dirks commit in the original
subsurface branch.
As of firmware 11, Teric identifies as 0x1F0A.
Also, just like libdivecomputer upstream, don't assume that an unknown
model is a Petrel - that was a stupid thing to do and caused downloads
with the Teric to break.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Shearwater parser: add new harware model nr for Teric
As of firmware 11 at least my Teric identifies as 0x1F0A.
Also, just like libdivecomputer upstream, don't assume that an unknown
model is a Petrel - that was a stupid thing to do and caused downloads
with the Teric to break.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
They don't actually have any native BLE capabilities, but there's a "HAL
9000" docking station with bluetooth capability (and a USB cable for
wired connectivity).
This will need more work, the BLE communication is packetized
differently from the regular serial one. But I'm keeping this
difference from Jef's upstream for posterity.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
There is also an i300C that is Bluetooth capable, but I don't know if
that's the same model as the i300 or a different variation.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This needs to be checked. I'm not sure why Jef has different code here,
but I'm keeping our Subsurface branch differences around.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This is purely to make things easier to debug when new devices show up.
The version string technically ends up being visible in the HEX dump of
the download too, but that's just not very convenient.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This adds the string field interface to the Oceanic Atom2 family,
including the proper serial number handling.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This adds the string field interface to the Suunto D9 family.
It's really just the proper serial number handling. From Dirk's
original commit:
"We have the correct firmware in the devinfo, but that's the firmware
the dive computer is on NOW, not necessarily the firmware it was using
when recording the dive"
so thus just serial number.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This adds the string field interface to the HW OSTC family, including
the proper serial number handling.
The deco model information was done by Anton Lundin in the original
subsurface branch, and the salinity, serial number, battery voltage and
desat information was added by Dirk Hohndel. Jan Mulder added the
battery percentage.
[ The sign-offs have been taken from the original commits in that old
subsurface branch, and I'm marking Dirk as the main author because on
the whole most of the lines come from him - Linus ]
Signed-off-by: Anton Lundin <glance@acc.umu.se>
Signed-off-by: Jan Mulder <jlmulder@xs4all.nl>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
These backends want the serial number for reporting, and can't get it
any other way.
We really should re-organize this. It's a nasty source of pointless
changes wrt upstream libdivecomputer, and I'm not convinced it's worth
the pain.
We also don't even have a consistent ordering for the arguments. Oh well.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
The Mares BlueLink Pro BLE dongle is the beast from hell, and introduces
lots of extra slowdowns into the Mares communication protocol.
In particular, it turns out that we really can't send the command bytes,
then wait for the ACK byte, and then send the command argument data as a
separate packet. Because of the delays that the dongle adds, the dive
computer will have given up on the command arguments by the time it sees
them.
At the same time we don't want to always pass the command and arguments
as one single packet in all situations, because at least the Mares
Matrix really seems to want that "wait for ACK before sending
arguments". See commit 59bfb0f3189b ("Add support for the Mares
Matrix") for details.
So introduce a new "splitcommand" flag, which is set by default, but
gets disabled for the BLE transport case.
Also, because bluetooth is slow, we don't want to ask for big packets of
data. It seems to cause a buffer overflow on the BlueLink Pro when the
serial data from the dive computer arrives faster than the bluetooth
data can be sent to the downloading side.
So when using the BLE transport, we also limit the packet size to 128
bytes in addition to disabling the command splitting.
With this, I can download hundreds of kB of data from the Mares Quad Air
successfully over BLE. It's *slow*, but it works.
This is a re-application of commit 5be8c17ea1 ("Mares bluetooth support
tweaks"), with small changes for how the libdivecomputer IO interfaces
have changed in the meantime.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
The dc_iostream_{read,write}() implementation had multiple issues:
- it would return DC_STATUS_SUCCESS even if no iostream implementation
existed.
Yes, it would also return a zero "actual" bytes, but most backends
don't even pass an "actual" pointer, so returning success was still
completely insane.
This one probably didn't matter, because all iostreams should have
read and write members, but the return value was completely wrong if
that ever were to happen.
- If the user passed in a NULL 'actual' pointer, the wrapper would
ignore that, and pass in its own pointer instead, in order to know
how many bytes to print for the debug message.
But that means that the low-level read/write functions cannot know
whether the user actually is able to handle a partial read or not.
This one _definitely_ matters, because some protocols need to have a
buffer for the whole incoming packet, but packerts may not always be
full-size. The low-level protocol needs to know whether to wait for
further packets (in order to fill the buffer) or to just return the
partial data.
This fixes these issues. If the user passes in a NULL actual pointer
(indicating that it needs all-or-nothing and is not ready to handle a
partial success), just loop over the IO until the buffer is fully
exhausted.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Not a lot of fields, but give the serial number in the proper format,
and other version information (Software version and bootloader version).
And the Nofly time that the dive computer reports.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This takes advantage of the field cache and string interfaces, and
reports TTS with the new TTS sample.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Instead of assuming that the dive list is presented in a sorted circular
list, sort it properly alphabetically (which also ends up being a
numerical sort for the HEX ascii dive names).
The "search for most recent dive, then splice the list around" case
doesn't work in the general case. It happens to work if you don't
delete any dives, and dives only disappear as they are being overwritten
by new dives when the storage overflows.
But if you delete dives and then create new ones, the dive list will not
be sorted at all, and we should sort it properly when downloading.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This uses pretty much all of our new infrastructure: the USB storage
iostream for the actual IO, the field-cache for the divecomputer fields,
and the string interface for the events.
It's also a very fast downloader.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This ends up being just a file interface for dive computers that expose
their data as a filesystem that can be mounted.
Right now that's only the Garmin Descent Mk1, although technically the
Uemis Zurich also did that (but oddly, and the backend was never merged
into libdivecomputer).
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
The libdivecomputer sample flag field for events is fairly useless,
traditionally just having a "begin/end" bit.
This extends the flags field with a severity marker ("state", "info",
"warning", "alarm") so that subsurface can report the event with the
proper kind of notice (ie big red error marker for an alarm, but not
show divecomputer state changes by default, for example).
For Shearwater events we can also add the type of event ("interest",
"navpoint", "danger", "animal", "injury").
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
A lot of dive computers have fairly arbitrary events that are not really
amenable to the simplistic static enumerated values that libdivecomputer
traditionally uses.
In fact, some dive computers (particularly the newer Suunto ones) very
explicitly report strings natively, with events literally being
described with a string like "Below Wet Activation Depth".
So instead of trying to turn these strings into one of the enumerated
values (and have the dive log software try to turn them back into some
random string when showing the user), just report the string itself.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This adds the ability to report time to surface (TTS) as a sample, which
a number of backends will want.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This adds the infrastructure for the "field cache", which is just
various helpers for the dc_get_field() interface.
This includes the 'dc_field_cache_t' structure that a libdivecomputer
backend can just add to its parser data structure, and a few macros to
make it very easy to initialize the fields and then return them in the
'get_field()' callback.
And part of it is the infrastructure support for the 'dc_field_string_t'
type, which adds the support for string fields. That will be used to
return various string-formatted data from the dive computer, like deco
models, serial numbers, etc.
And no, a serial number is most definitely not a "number". It's a string.
Right now there are no users of this yet, that comes next.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
The dc_tankvolume_t type had information about metric vs imperial
volume, but we actually want other things too, like the actual usage of
the cylinder.
So rename it to 'dc_tankinfo_t' and extend the semantics from an
enumeration of volume units, to be a bitmap of information flags.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
We have a slightly different set of flags for mthe subsurface build, and
we want the version to also say that this is our Subsurface-specific
branch of libdc, not the upstream one.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
The S_BLOCK_WRITE (0x30) command sends a stream of bytes to the dive
computer. Because the payload has no fixed length and there is no length
field included, the hwOS firmware detects the end of the stream by means
of a 400ms timeout. The main disadvantage of this approach is that a
short hiccup in the communication will be incorrectly detected as the
end of the stream. Hence only a part of the data will get written to
the flash memory, and the remainder of the data will get interpreted as
the next commands.
To avoid this problem, the hwOS firmware v3.09 and later supports a new
S_BLOCK_WRITE2 (0x31) command, which uses a fixed size payload of 256
bytes.
Reported-by: Ralph Lembcke <mail@ralph-lembcke.de>
By reading the firmware version information immediately after entering
download or service mode, we can identify the specific firmware version
and adapt to minor differences in the communication protocol.
The S_BLOCK_WRITE (0x30) command sends a stream of bytes to the dive
computer. Because the payload has no fixed length and there is no length
field included, the hwOS firmware detects the end of the stream by means
of a 400ms timeout. Therefore the ready byte is always delayed by this
400ms timeout.
The same remark applies to the DISPLAY (0x6E) and CUSTOMTEXT (0x63)
commands. But because libdivecomputer always pad the text with zeros and
sends the maximum payload size, we won't hit the timeout.
Reported-by: Ralph Lembcke <mail@ralph-lembcke.de>
Erasing a flash memory page is a relative slow operation and takes a
significant amount of time. Therefore, the ready byte is delayed, and
the standard timeout is no longer sufficient. Estimate the required
delay and wait.
Reported-by: Ralph Lembcke <mail@ralph-lembcke.de>
The hwOS firmware reads the service init command one byte at a time, and
sends the echo immediately after each byte.
Reported-by: Ralph Lembcke <mail@ralph-lembcke.de>
For the Oceanic Pro Plus X and the Aqualung i770R, downloading over BLE
often fails because the version packet contains one or more unexpected
bytes.
For a successful download, the correct structure for the version packet
is as follows:
5A 4F4345414E4F43582031432030303032 C6
That's the start byte, the payload "OCEANOCX 1C 0002" and the checksum.
For all the failed packets, there are one or more bytes extra present
between the payload and the checksum:
5A 4F4345414E4F43582031432030303032 9F02 67
5A 4F4345414E4F43582031432030303032 3603 FF
5A 4F4345414E4F43582031432030303032 64 2A
5A 4F4345414E4F43582031432030303032 9202 5A
5A 4F4345414E4F43582031432030303032 08 CE
5A 4F4345414E4F43582031432030303032 2C01 F3
The amount of extra bytes, and their content appears to be pretty
random. The strangest part is that the checksum of the packet is
actually correct and includes those extra bytes!
As workaround, accept extra bytes in the BLE packet, verify the checksum
as usual, and finally strip the excess bytes and only pass the actual
content to the next layer. To avoid false positives, the workaround is
limited to packets with a payload and checksum, and only enabled for the
two affected models.
When the last deco stop is cleared, the dive computer switches to NDL
mode with an infinite time (0x7FFF for APOS4 and 0xFFFF for APOS3). But
because libdivecomputer does not report those infinite values to the
application, detecting the end of the deco phase is not very intuitive.
This issue is fixed by passing those infinite NDL values as-is to the
application, despite the relative large values (respectively 9.1 and
18.2 hours). For reference, the finite NDL values reported by the ratio
dive computers can be large as well, with values up to 0x4000 (4.55
hours).
Due to how the Oceanic ringbuffer is implemented, the ringbuffer always
contains at least one entry. If there are no dives recorded yet, the
content of that entry will be empty. Such entries are already ignored
during processing, but instead of returning this empty entry to the
caller, simply clear the logbook buffer, and return no entries at all.
Previously, invalid ringbuffer pointers were always handled during the
second pass. But that changed after the previous commit. If the invalid
pointer is located in the first logbook entry, this is now handled as
"no dives present". Fixed by returning the correct error code instead.
If all the entries in the logbook ringbuffer happen to be empty, the
ringbuffer end pointer will not have a valid value. Creating the
ringbuffer stream will fail, and an error will be returned to the
caller. Fixed by adding an extra check, and exit if there are no dives.
The depth value is encoded with only 11 bits instead of 12 bits. The
extra bit contains the gas mix index. This resulted in wrong depths,
with values larger than 204.8m.
For the BCD encoded day field (range 1-31), two bits are sufficient to
represent the upper digit (range 0-3). The purpose of the highest bit is
unknown, but it's certainly not part of the day field, and needs to be
masked off.