1736 Commits

Author SHA1 Message Date
Jef Driesen
8a10e545d4 Fix a bug in the salt and fresh water parsing
The original Mares Genius support was based on Mares Dive Organizer
2.25, which has a bug in the salinity parsing. The latest version 2.26
has this bug fixed.

Reported-by: Greg McLaughlin <gregm@somemore.com>
2020-09-18 17:29:52 +02:00
Jef Driesen
2909863573 Fix the sample interval
The McLean Extreme records a sample every 10 seconds instead of every 20
seconds. This resulted in dive durations that were twice as long as
expected.

Reported-by: David Carron <david_de_carron@hotmail.com>
2020-09-15 15:06:12 +02:00
Jef Driesen
3e89e1b871 Add support for parsing info events 2020-08-22 00:27:11 +02:00
Jef Driesen
e2ecd96daa Add support for the Shearwater Peregrine 2020-08-22 00:05:32 +02:00
Jef Driesen
7a4c5e919f Fix a conflict with the Windows header files
In one of the Windows system header files, an "interface" macro is
defined as:

  #define interface struct

This results in some very strange build errors when also including the
descriptor-private.h header file. That's because the dc_usb_params_t
struct has a member field named "interface":

  typedef struct dc_usb_params_t {
      unsigned int interface;
      unsigned char endpoint_in;
      unsigned char endpoint_out;
  } dc_usb_params_t;

As a workaround, define the WIN32_LEAN_AND_MEAN macro before including
the windows.h header file. This excludes some less common Windows API
declarations, including the above one.
2020-08-21 23:56:52 +02:00
Jef Driesen
51b1ae925c Add a missing parameter for the USB HID filter
In commit 57f0ce6d7902117cfc4d0d6b401b516fc93ca488, an extra parameter
was added to the dc_descriptor_filter() function. But I only updated the
libusb code path and forgot to do the same for the hidapi variant.
2020-08-21 17:57:47 +02:00
Jef Driesen
9dace57814 Fix the OSTC4 firmware upgrade
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>
2020-08-20 15:29:15 +02:00
Jef Driesen
c77551b366 Handle a negative number of bytes as an error
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.
2020-08-11 15:22:31 +02:00
Jef Driesen
33a20bd2b8 Merge branch 'iostream-usb' 2020-08-11 15:22:07 +02:00
Jef Driesen
5380b247af Update the example application
The application is now responsible for setting up the USB based I/O
stream.
2020-08-11 15:16:36 +02:00
Jef Driesen
c72dc4aa73 Use the new USB transport for the Atomic Aquatics Cobalt
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.
2020-08-11 15:16:36 +02:00
Jef Driesen
c84bbd93a3 Add an I/O implementation for USB communication
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.
2020-08-11 15:16:36 +02:00
Jef Driesen
57f0ce6d79 Add support for filter parameters
The filter parameter provides a mechanism to pass some additional
information, needed to configure the I/O stream, back to the caller.
2020-08-03 11:51:59 +02:00
Jef Driesen
edacbb2f13 Disable direct access to the filter function
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.
2020-08-03 11:51:59 +02:00
Jef Driesen
6986840c0d Increase the receive timeout to 5 seconds
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
2020-08-03 11:48:33 +02:00
Jef Driesen
cdd618e683 Fix the McLean Extreme bluetooth name 2020-07-26 17:27:49 +02:00
Jef Driesen
71a149d776 Add support for Liquivision dive computers 2020-07-09 17:02:32 +02:00
Jef Driesen
91acd9bb2d Add support for the Aqualung i470TC 2020-06-19 11:47:46 +02:00
Vincent Hagen
c065a78402 Update the gitignore file 2020-06-15 11:42:22 +02:00
Vincent Hagen
21742bd2ec Update the man pages for the new iostream functions
- 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.
2020-06-15 11:36:26 +02:00
Jef Driesen
85074dba40 Purge the serial port buffer during initialization 2020-06-08 13:45:43 +02:00
David Carron
8d35ee6978 Add support for the McLean Extreme 2020-06-08 13:45:43 +02:00
Linus Torvalds
9e6035f98a Suunto Eon Steel: sort the dive list properly
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>
2020-06-08 13:38:45 +02:00
Jef Driesen
cac0eb7d81 Remove the salinity compensation
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.
2020-06-03 14:08:02 +02:00
Jef Driesen
9525bc8047 Fix the hwOS ppO2 bug for firmware v3.08
The hwOS ppO2 firmware bug is also present in firmware 3.08. See commit
b9a3606f379c3c9f57bbf561bdcb52fb76b711db for more details.
2020-05-13 16:45:53 +02: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
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
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
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
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