Pull upstream libdivecomputer updates from Jef Driesen:
- fix lack of "end of deco" on DiveSystem iDive computers by reporting
long NDL values
- clean up handling of Oceanic empty logbugger
- fix BLE download for Oceanic Pro Plus X that doesn't like the serial
number handshake.
* 'master' of git://github.com/libdivecomputer/libdivecomputer:
Pass infinite NDL values to the application
Clear the buffer if no dives are present
Report an error for invalid ringbuffer pointers
Improve the empty logbook ringbuffer detection
Skip the BLE handshake for the Pro Plus X
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.
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).
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Merge upstream changes from Jef Driesen:
- fix Oceanic VT Pro date parsing
- add Sherwood Wisdom 4 and Scubapro Aladin A1 IDs from Janice McLaughlin
- fix Cressi gasmix index and depth parsing (the gasmix index bit had
been misparsed as very deep depth)
* 'master' of git://github.com/libdivecomputer/libdivecomputer:
Implement the gas mix sample
Limit the depth value to 11 bits
Add support for the Scubapro A1
Add support for the Sherwood Wisdom 4
Fix the vtpro datetime parsing
This converts most of the cached data to the field cache, leaving some
garmin-specific fields alone (but removing them from the "cache"
structure in the process).
This means that all of the users of the string fields have been
converted, and we don't have the duplicate string interfaces any more.
Some of the other "dc_field_cache_t" fields could easily be used by
other backends (including some of the partial conversions like the
Shearwater one, but also backends that don't do any string fields at
all), but this conversion was a fairly minimal "set up the
infrastructure, and convert the easy parts".
Considering that the string field stuff still isn't upstream, I'm not
going to push any other backends to do more conversions.
On the whole, the string code de-duplication was a fairly nice cleanup:
8 files changed, 340 insertions(+), 484 deletions(-)
and perhaps more importantly will make it easier to do new backends in
the future with smaller diffs against upstream.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This only converts the string fields and the divemode field.
Why? Those were the only ones that were in the proper libdivecomputer
type format: a lot of the other fields are kept in the Shearwater
internal format, and then converted at get_field() time.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
The only real changes here are some interface updates: several traversal
routines are changed to return 'dc_status_t' which makes more sense in
the libdivecomputer world anyway, and that matches the generic field
cache string routines.
The other changes are also a direct result of the generic code using
slightly different names for the cache fields: they use the same names
as the DC_FIELD_xyz enum to fetch them.
This is not a full conversion to the generic wrappers, and the EON Steel
parser accesses the cache structure directly in several places because
of how the code was written. That's fine. Not pretty, but this is all
totally internal to libdivecomputer.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This adds a few misc fields that the EON Steel wants, and changes the
string insertion interface to return a 'dc_status_t', which will be used
by that back-end.
The existing deepblu users don't care.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This starts with the deepblu code, which is the last one I touched.
The next step is to try to make some of the other backends use this too,
and see where the interface isn't quite generic enough.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
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.
I had sprinkled "ERROR()" statements around in various callchains during
early Deepblu development, and not removed all of them.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
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.
Merge Jef's upstream changes:
- some stream IO abstraction updates: poll() support, but also a new
ioctl() interface to query the BLE name of the stream instead of our
own 'get_name()' function.
This will require corresponding changes on the subsurface side.
- Jef merged the Oceanic BLE support from me, with changes, and some
general atom2 backend cleanups.
- misc small fixups like the 3s Mares BLE timeout we already had.
* git://github.com/libdivecomputer/libdivecomputer:
Install the ioctl header file
Advertise the BLE support in the device descriptors
Fix the BLE device detection for the i770R and Pro Plus X
Implement the BLE handshaking
Implement the BLE packet sending and receiving
Read the entire data packet in a single operation
Remove the trailing zero byte from all commands
Fix a bug in the ACK/NAK handling
Remove an unnecessary function
Add an ioctl to retrieve the remote device name
Re-implement the set_latency function as an ioctl
Add an ioctl function to the I/O interface
Integrate the new poll function
Add a poll function to the I/O interface
Add support for the Oceanic Veo 4.0
Increase the timeout to 3 seconds
The bluetooth device filtering is based on the fact that the format of
the bluetooth device name is something like 'FQ001124', where the two
first letters are the ASCII representation of the model number (e.g.
'FQ' or 0x4651 for the i770R), and the six digits are the serial number.
It seems that the BLE communication protocol is somewhat different from
the serial one in the version string: while the serial version tends to
show the memory size, the BLE version string has some other numeric
pattern.
Linus Torvalds reports the BLE pattern for the i770R is normally just
"0001", allthough he once also observed "0090" with the same dive
computer. A communication trace from a Pro Plus X also showed "0001".
We don't have enough information to guess the meaning of the number.
Regardless, for those two dive computers supporting BLE, make the
pattern simply ignore the last four digits, since they clearly vary.
Based-on-code-by: Linus Torvalds <torvalds@linux-foundation.org>
The BLE communication sends a handshake packet containing a passphrase
based on the serial number of the device. Sadly, we can't actually read
the serial number from the device until after this handshake has
successfully completed, which makes it a bit of a chicken-and-egg
problem from a communication standpoint. However, the serial number is
also exposed in the bluetooth device name the device advertizes, which
is the reason for the newly added DC_IOCTL_BLE_GET_NAME ioctl.
Thanks to Janice McLaughlin for pointing out the logic of this magic
handshake.
Based-on-code-by: Linus Torvalds <torvalds@linux-foundation.org>
Refactor the packet receiving code to read the ack byte, the payload
data and the checksum all at once, with just a single read operation.
This is not only a bit more efficient, but will also simplify the BLE
support.
The trailing zero byte is present for historic reasons only. At the time
the Oceanic protocol was implemented, the Oceanic application send this
extra zero byte too, and we simply copied this behaviour. But more
recent versions no longer send it. Probably a small (harmless) bug that
was fixed.
The write command is send as two separate packets. The first packet
contains the B2 command and the page number, and the second packet
contains the payload and checksum. Because the payload can contain
arbitrary data, the first byte of a packet is not necessary a command
byte. But the code to select the correct ack byte is based on this
assumption. Fixed by passing the expected ack byte.
The set_latency function is the perfect example of a feature that should
be implemented as an ioctl: it's only implemented by a single driver,
and the functionality is also highly platform specific.
This new ioctl function allows to perform I/O stream specific requests
through a generic interface. This provides an easy way to extend the I/O
interface with some driver specific features, without having to modify
the public api.
Replace the manual polling, implemented using a combination of the
dc_iostream_get_available and dc_iostream_sleep functions, with the new
and more efficient poll function.
The Linux implementation is very straighforward and just a lightweight
wrapper around the select function. But the Windows implementation is
much more complex, because the Windows event notification mechanism
behaves very different:
The WaitCommEvent function does not support a timeout and is always a
blocking call. The only way to implement a timeout is to use
asynchronous I/O (or overlapped I/O as it's called in the Windows API),
to run the operation in the background. This requires some additional
book keeping to keep track of the pending background operation.
The event mechanism is also edge triggered instead of level triggered,
and reading the event with the WaitCommEvent function clears the pending
event. Therefore, the state of the input buffer needs to be checked with
the ClearCommError function before and after the WaitCommEvent call.
The check before is necessary in case the event is already cleared by a
previous WaitCommEvent call, while there is still data present in the
input buffer. In this case, WaitCommEvent should not be called at all,
because it would wait until more data arrives.
The check afterwards is necessary in case WaitCommEvent reports a
pending event, while the data in the input buffer has already been
consumed. In this case, the current event must be ignored and
WaitCommEvent needs to be called again, to wait for the next event.
I'm not sure why it wasn't there originally, but it definitely should
be on that list of ignored files, to keep 'git status' happy.
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 Mares Bluetooth dongle is some seriously messed up stuff, and takes
forever to answer anything. I'm not sure what we do wrong, because the
Mares mobile App seems to be able to work with it without the excessive
delays, but it is really incredibly slow when we talk to it.
I suspect the dongle has has some "wait until buffer is half full"
timeout, and it then triggers for every command and short reply in both
directions, and there's likely some way to flush it, but I didn't see
anything back when I had one for testing.
Anyway, as a result, one second is just about the latency that the
dongle itself adds regardless of anything else, so when the dive
computer itself needs a timeout to think about things, the overall
timeout needs to be noticeably more than one second.
Three seconds seems to be a somewhat reasonable compromise, and we do
have documentation for it being the right value:
"Then shalt thou count to three, no more, no less. Three shall be the
number thou shalt count, and the number of the counting shall be
three. Four shalt thou not count, neither count thou two, excepting
that thou then proceed to three. Five is right out."
because we do have strong reasons to believe that the Mares Bluetooth
dongle is a beast from hell. Everybody who has ecver met it has
certainly gone "Arrrghhh" at some point.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Merge with upstream Jef.
This is mainly just the (already merged as a separate patch) support for
th eOceanic Pro Plus 4, Jef committed the identical patch but without
marking it as BLE-capable (which is kind of pointless, since it doesn't
seem to work over anything _but_ BLE).
And a couple of trivial fixlets.
* git://github.com/libdivecomputer/libdivecomputer:
Fix the Aeris Manta memory layout
Add support for the Oceanic Pro Plus 4
Strip the source directory from file names
The BLE communication is significant slower than usb-serial. The first
BLE data packet of each response often takes longer than one second to
arrive. This causes the first attempt to fail with a timeout. The second
attempt will appear to succeed, because it actually receives the
response of the first attempt. But now the next command will fail,
because it will receive the response of the second attempt of the
previous command.
Increasing the timeout and adding an extra delay before retrying, avoids
this problem.
Reported-by: Linus Torvalds <torvalds@linux-foundation.org>
For the Aeris Manta, the end of the profile ringbuffer appears to depend
on the firmware version. For older firmware versions (1x), the end of
the ringbuffer is at address 0xFFF0, while for the newer versions (2x),
it's 0xFE00.
The code checks for firmware version 2B, because that's the lowest known
version in the 2x range.
Reported-by: Nick Shore <support@mac-dive.com>
This is _partial_ support for the Oceanic Pro Plus 4 from Jef, based on
a partial dump by John Clark. Quoting Jef in the email thread:
"I'm not sure why downloading the memory dump fails. All 4 attempts
fail around the same memory address (0x3140), but not exactly the
same. Strange, but the good news that there is already enough
information to figure some things out.
Linus and Dirk: Attached is a patch with the things I figured out so
far. Can you make a build for John to try?
Most of the info looks reasonable, but there are probably still a few
things missing or wrong. I don't have any ground truth data to compare
against for things like the temperature sign"
This is that patch for testing.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Merge upstream libdivecomputer updates from Jef.
Misc small updates all over, the biggest thing (code wise) is probably
the Ratio firmware update support.
* 'master' of git://github.com/libdivecomputer/libdivecomputer:
Fix the Oceanic Geo 4.0 memory layout
Ignore all empty logbook entries
Add a workaround for the hwOS ppO2 firmware bug
Use macros to encode the firmware version
Use symbolic constants for the sample types
Remove the obsolete hwos parameter
Limit the tank pressure workaround to hwOS devices
Fix the OSTC tank pressure decoding
Fix the Scubapro G2 HUD udev rule
Add the Mares Genius to the bluetooth filter
Add firmware upgrade support for the Ratio computers