1849 Commits

Author SHA1 Message Date
Linus Torvalds
c889348583 Remove stale workarounds for MVC from Suunto EON Steel parser
They were for the string field handling, but we now use the generic code
that has those workarounds there. No need for them in the Suunto downloader.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2020-05-07 13:23:19 -07:00
Linus Torvalds
761089c8f2 Remove stale declaration for dc_iostream_get_name()
This function no longer exists, it was subsumed by the new
DC_IOCTL_BLE_GET_NAME ioctl instead.  The declaration for it had just
not been removed when the definition went away.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2020-05-07 13:12:21 -07:00
Linus Torvalds
8b53c70950 Merge branch 'master' of git://github.com/libdivecomputer/libdivecomputer into Subsurface-NG
Pull updatream updates from Jef Driesen:

 - work around Pelagic BLE oddity (Oceanic Pro Plus X and Aqualung i770R)

 - OSTC3 firmware update improvements

* 'master' of git://github.com/libdivecomputer/libdivecomputer:
  Use a more robust command to write flash memory
  Read and cache the firmware version information
  Add an extra delay after writing to the flash memory
  Add an extra delay after erasing a flash memory page
  Send the service init command one byte at a time
  Fix some typos in the comments
  Ignore excess bytes in the BLE version packet
2020-05-07 11:34:33 -07:00
Jef Driesen
82f298febd Merge branch 'ostc3-fwupdate-improvements' 2020-03-24 18:48:56 +01:00
Jef Driesen
9e92381be4 Use a more robust command to write flash memory
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>
2020-03-24 18:32:13 +01:00
Jef Driesen
dff6d0c514 Read and cache the firmware version information
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.
2020-03-24 18:32:13 +01:00
Jef Driesen
da4a8a90c7 Add an extra delay after writing to the flash memory
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>
2020-03-24 18:32:13 +01:00
Jef Driesen
7b9b6b4005 Add an extra delay after erasing a flash memory page
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>
2020-03-24 18:32:13 +01:00
Jef Driesen
d1b865d192 Send the service init command one byte at a time
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>
2020-03-24 18:32:13 +01:00
Ralph Lembcke
94cd864dba Fix some typos in the comments 2020-03-24 18:32:13 +01:00
Jef Driesen
ffa9e0aa3c Ignore excess bytes in the BLE version packet
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.
2020-03-17 14:33:56 +01:00
Linus Torvalds
7882ba423c iostream: protect write side against bad custom IO interfaces too
This is the same as the previous commit, just for the write side error
handling.

If we have a bad custom IO low-level driver that returns
DC_STATUS_SUCCESS with zero bytes written, and we have a write() user
that isn't ready for partial writes, we just consider that an IO error.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
v4.9.4
2020-03-13 11:48:35 -07:00
Linus Torvalds
b77e7b6b21 iostream: protect against bad custom interfaces
Jef Driesen points out that the subsurface custom iostream read function
for legacy bluetooth can return a "success" with zero bytes actually
read.  That makes the loop we have to fill up the whole buffer very unhappy.

That's definitely a bug on the subsurface side, but let's also be
defensive about it in the iostream layer.

Note that this happens only when the reader is not able to handle
partial packets (doesn't pass in an "actual" pointer), and we haven't
gotten a full packet yet.

So we'll turn it into a DC_STATUS_TIMEOUT, which is debatable, but the
real fix is for subsurface to not do this in its rfcomm iostream
implementation, and instead return the proper error code.

Reported-by: linuxcrash <albin@mrty.ch>
Debugged-by: Jef Driesen <jef@libdivecomputer.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2020-03-13 09:34:00 -07:00
Linus Torvalds
0714e327b7 Merge branch 'master' of git://github.com/libdivecomputer/libdivecomputer into Subsurface-NG
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
2020-02-27 16:25:31 -08:00
Jef Driesen
8a1d32d319 Pass infinite NDL values to the application
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).
2020-02-28 00:14:31 +01:00
Jef Driesen
416022f3cc Merge branch 'oceanic-empty-logbook-ringbuffer' 2020-02-24 09:21:33 +01:00
Jef Driesen
8fb0f1ca94 Clear the buffer if no dives are present
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.
2020-02-24 09:21:33 +01:00
Jef Driesen
39aad6bb52 Report an error for invalid ringbuffer pointers
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.
2020-02-24 09:21:33 +01:00
Jef Driesen
f93b2afcc8 Improve the empty logbook ringbuffer detection
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.
2020-02-24 08:54:44 +01:00
Jef Driesen
1d235daf30 Skip the BLE handshake for the Pro Plus X
The Oceanic Pro Plus X does not seem to understand the BLE handshake
command. It just fails with a NAK byte (0xA5) as response.
2020-02-21 13:48:11 +01:00
Linus Torvalds
4e809aefd8 Cressi: mark Cartesio and Goa as supporting BLE
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>
2020-02-16 08:50:38 -08:00
Linus Torvalds
ebbb911427 Merge git://github.com/libdivecomputer/libdivecomputer into Subsurface-NG
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
2020-02-13 13:03:21 -08:00
Linus Torvalds
ae36b89118 Garmin Descent Mk1: convert to generic field cache
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>
2020-02-13 12:53:33 -08:00
Linus Torvalds
752bfaab3d Shearwater: convert predator parser to use generic field interface
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>
2020-02-13 12:52:11 -08:00
Linus Torvalds
0638482209 Suunto EON Steel: use the generic field cache infrastructure
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>
2020-02-13 12:52:11 -08:00
Linus Torvalds
842592fb55 Extend field-cache infrastructure to support the Suunto EON Steel
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>
2020-02-13 12:52:11 -08:00
Linus Torvalds
f73b6836ad Begin making the string interface and "field cache" generic
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>
2020-02-13 12:51:57 -08:00
Jef Driesen
ebb8715e2c Merge branch 'goa' 2020-02-13 11:10:35 +01:00
Jef Driesen
5dc7e54596 Implement the gas mix sample
The current gas mix index is stored in the 11th bit of the sample value.
2020-02-13 11:07:24 +01:00
Jef Driesen
59d9791446 Limit the depth value to 11 bits
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.
2020-02-13 11:05:25 +01:00
Janice McLaughlin
a01b9bc9b9 Add support for the Scubapro A1 2020-02-04 08:41:55 +01:00
Janice McLaughlin
4a60f89f4a Add support for the Sherwood Wisdom 4 2020-02-04 08:30:33 +01:00
Linus Torvalds
820a797c67 Deepblu Cosmiq+: remove debug error statements
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>
2020-01-28 09:17:14 -08:00
Nick Shore
ba96b3092d Fix the vtpro datetime parsing
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.
2020-01-28 10:59:22 +01:00
Linus Torvalds
f2f775b9aa Merge git://github.com/libdivecomputer/libdivecomputer into Subsurface-NG
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
2020-01-26 11:25:54 -08:00
Jef Driesen
f65e3cf39e Install the ioctl header file 2020-01-17 08:12:14 +01:00
Jef Driesen
4fe1b96689 Merge branch 'oceanic-ble' 2020-01-06 23:26:55 +01:00
Jef Driesen
cfd54ff80e Advertise the BLE support in the device descriptors
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.
2020-01-06 23:26:55 +01:00
Jef Driesen
4bc5ee90ef Fix the BLE device detection for the i770R and Pro Plus X
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>
2020-01-06 23:26:55 +01:00
Jef Driesen
4baf140d25 Implement the BLE handshaking
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>
2020-01-06 23:26:42 +01:00
Jef Driesen
6ba0726a42 Implement the BLE packet sending and receiving
Based-on-code-by: Linus Torvalds <torvalds@linux-foundation.org>
2020-01-06 21:29:24 +01:00
Jef Driesen
4923d3761e Read the entire data packet in a single operation
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.
2020-01-06 21:29:24 +01:00
Jef Driesen
437db813d5 Remove the trailing zero byte from all commands
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.
2020-01-06 21:29:24 +01:00
Jef Driesen
4b2156d378 Fix a bug in the ACK/NAK handling
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.
2020-01-06 21:29:24 +01:00
Jef Driesen
91309a3d54 Remove an unnecessary function 2020-01-06 21:29:24 +01:00
Jef Driesen
a67bab58ca Merge branch 'ioctl' 2020-01-06 21:27:38 +01:00
Jef Driesen
e71278a13f Add an ioctl to retrieve the remote device name 2020-01-06 21:24:58 +01:00
Jef Driesen
c205299c02 Re-implement the set_latency function as an ioctl
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.
2020-01-06 21:24:58 +01:00
Jef Driesen
0359a57fdc Add an ioctl function to the I/O interface
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.
2020-01-06 21:21:50 +01:00
Jef Driesen
be0e32b43b Merge branch 'poll' 2020-01-06 21:21:31 +01:00