It turns out that Windows is more of a PoC than I ever imagined. The
system headers will have something like this in it:
#define __STRUCT__ struct
#define interface __STRUCT__
which means that using the identifier "interface" will result in
completely indecipherable error messages from a Windows compiler.
That's some truly broken stinking garbage. It's not like "interface" is
even a bad identifier.
Let's just #undef this crazy feature.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
When Jef added a filter parameter in commit 57f0ce6 ("Add support for
filter parameters") he didn't do the HIDAPI case, because who uses
HIDAPI?
Windows and OS X, it would seem.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Merge upstream changes by Jef Driesen:
- add support for Liquivision dive computers
- add support for the Aqualung i470TC
- extract out Atomic Aquatics Cobalt USB support as a iostream
- misc fixes
* git://github.com/libdivecomputer/libdivecomputer:
Fix the OSTC4 firmware upgrade
Handle a negative number of bytes as an error
Update the example application
Use the new USB transport for the Atomic Aquatics Cobalt
Add an I/O implementation for USB communication
Add support for filter parameters
Disable direct access to the filter function
Increase the receive timeout to 5 seconds
Fix the McLean Extreme bluetooth name
Add support for Liquivision dive computers
Add support for the Aqualung i470TC
Commit d1b865d192afc9efde337b5cff8a239366f15565 breaks the OSTC4
firmware upgrade because the OSTC4 expects to receive the service init
command and the service key all at once, before sending any response.
The hwOS firmware still reads the service init command one byte at a
time, and sends the echo immediately after each byte. But in the
meantime, the hwos firmware has also been optimized. The processing time
for an incoming byte is now always faster then the time it takes for the
next byte to physically arrive via the serial line between the USB/BT
chip and the processor. Thus, even without any buffering, sending all
bytes at once should no longer be a problem.
This partially reverts commit d1b865d192afc9efde337b5cff8a239366f15565.
Reported-by: Anton Lundin <glance@acc.umu.se>
Suggested-by: Ralph Lembcke <mail@ralph-lembcke.de>
There is no reason for libusb to ever return a negative number of bytes,
but due to the use of a signed integer, it's technically possible. And
because libdivecomputer returns an unsigned integer, such a negative
number would be reported as a very large size.
Replace the hardcoded libusb based code with the new USB I/O transport.
This enables the use of a custom I/O on platforms where libusb is not
available.
The USB communication is now also implemented as an I/O stream
transport. Unlike most I/O devices, USB communication supports multiple
interfaces and endpoints. This requires some some special care:
In the general case, autodetection isn't really possible without
additional knowledge. Hence the need for the filter parameters to pass
this kind of information.
The implementation assumes two bulk endpoints for the standard
read/write interface. Communication with the control endpoint is
supported through the new DC_IOCTL_USB_CONTROL_{READ,WRITE} ioctl's.
Replace the small helper function to retrieve the function pointer and
then call the function, with another helper function to call the filter
function directly. This way the function pointer doesn't need to be
exposed at all.
When the fingerprint feature isn't used (or with a timestamp of zero),
the response to the SIZE (0xC6) and DATA (0xC4) commands is received
almost instantly:
[0.302704] W: C60000000010270000
[0.366727] R: DCF90F00
[0.367829] W: C40000000010270000
[0.394812] R: E0F90F00
But when the fingerprint feature is used (with a non-zero timestamp),
there is a noticable delay:
[0.341218] W: C64CEB204D10270000
[1.927905] R: FE0B0000
[1.931610] W: C44CEB204D10270000
[5.092081] R: 020C0000
In this particular case, the total amount of dive data was close to 1M
bytes, which pushed the delay over the 3 second timeout, and caused the
download to fail. Increasing the timeout to 5 seconds fixed the problem.
The most likely explanation is that the dive computer needs to scan its
internal logbook to determine which dives and how many bytes to send.
Because that involves reading relative slow flash memory, this can take
up to a few seconds, especially if there are many dives present.
The duration of the delay also depends on the value of the fingerprint
timestamp: the less dives we try to download, the longer the delay! I
suspect that's because the most recent dives are located near the end of
the logbook. Hence, the less dives we request, the more dives the dive
computer needs to skip.
Below are some timings for downloading espectively 792410, 531856 and
270850 bytes from the same dive computer, but with a different
fingerprint value:
[0.216305] W: C6F8D5C84510270000
[0.373511] R: 56170C00
[0.378929] W: C4F8D5C84510270000
[0.661388] R: 5A170C00
[0.236246] W: C620D80F4810270000
[0.559608] R: 8C1D0800
[0.563755] W: C420D80F4810270000
[1.171631] R: 901D0800
[0.246193] W: C654E6434A10270000
[0.826365] R: FE210400
[0.831760] W: C454E6434A10270000
[1.974351] R: 02220400
Add initial support for the Oceans S1.
This expands a bit on the generic functions for the field-cache code,
and uses that to then add a fairly minimal Oceans S1 downloader.
And while it's minimal, it downloads about everything the S1 offers,
which is mainly just depth and temperature.
There are a few fields that it currently doesn't use, notably the
events and NDL information that the dive computer presumably reports in
the auxiliary data that comes in the sample, but without documentation
and more testing I'm not comfortable parsing that.
There's also some "current dive computer state" that isn't imported,
like the battery status. I know how to read it, but it's not per-dive
data that could be added as extra fields: it's literally just the
current dive computer battery state at the time of the download.
The Oceans team said they'll provide more information about the
download, so this might be expanded in the future, but it seems fairly
usable even in this form.
Thanks to Dhaval Giani for sending me his Oceans S1 as a loaner, and to
Seth Garrison for doing the initial BLE packet dumps that made me think
it was fairly easily doable.
* Oceans-S1:
Oceans S1: polish up the downloading logic for usability
Oceans S1: actually download all dives and parse them
Oceans S1: fill out core download protocol details
Oceans S1: start filling in protocol details
Oceans S1: start documenting the download format and first packets
Add skeleton for Oceans S1 downloader
Add generic dc_field_get() helper
Merge upstream libdivecomputer updates from Jef Driesen:
- Jef merged the EON Steel dive sorting fix we had in our branch: one
less difference to upstream
- Jef merged the McLean Extreme support with some updates and cleanups,
this just takes all his changes.
- manual pages for iostream
- various minor fixes and updates from Jef
* git://github.com/libdivecomputer/libdivecomputer:
Update the gitignore file
Update the man pages for the new iostream functions
Purge the serial port buffer during initialization
Add support for the McLean Extreme
Suunto Eon Steel: sort the dive list properly
Remove the salinity compensation
Fix the hwOS ppO2 bug for firmware v3.08
This adds a few finishing touches to actually download dives in the
expected order (newest first), which fixes the handling of already
downloaded dives.
It also adds the fingerprinting code to optimize the downloading a bit.
Finally, it handles cancellation in the middle.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This isn't perfect - we don't do the whole dive fingerprint etc, so
right now it always downloads all dives.
To make matters worse, it downloads dives oldest first, which then
confuses the subsurface downloader that expects newest first.
So there's stuff to clean up, but the basic profile data is all there.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
All of the Oceans S1 protocol seems to be basically ASCII data, but the
bigger chunks of data (the dive list, and the actual dive profiles) are
chunked in 512-byte pieces with sequence numbers and what looks like
some checksum.
This doesn't check the checksum yet, but the basic "download data" seems
to work.
Note that the code doesn't actually _parse_ said data yet, nor create an
actual dive list. So this is very much only very incremental progress,
but this seems to have been the nastiest part of the actual protocol.
Knock wood.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
The communication seems to be mainly ASCII strings, with the main
complexity probably being that the Nordic Semi UART has some side
channel for switching between line-buffered and "bulk data" modes.
That part might end up being painful and needing more interfaces to the
Subsurface BLE code.
We'll likely need to add more special BLE code. The Bluetooth SIG
really is a horrible disgrace.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This generic helper just gets everything from the field cache.
Dive computers can do their own things for any field they handle
differently, and then at the end fall back to this for all of the common
cases that are purely described by the field cache structure.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
- Added missing man pages for the new functions.
- Updated the main libdivecomputer man page to reflect the new flow.
- Fixed minor typos in the dc_parser_get_field and
dc_parser_samples_foreach functions.
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>
In recent hwos firmware versions, the depth is no longer stored as
pressure (in millibar), but directly as depth (in meters) with the
salinity and gravity factor already applied.
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>