1451 Commits

Author SHA1 Message Date
Jef Driesen
91f5b34ae5 Enable some useful compiler warnings by default
Because some of those compiler warnings are GCC specific, they should
only be enabled if the compiler actually supports them. This is take
care of with some macros from the autoconf-archive.

To avoid breaking the build on systems that don't have those macros
installed (e.g. Mac OS X), they are included in the project.
2017-11-24 23:45:11 +01:00
Jef Driesen
cbaebc777d Generate html documentation from the manpages 2017-11-23 10:33:31 +01:00
Jef Driesen
4ccfa51faf Fix the decoding of the ndl/deco information
With the new APOS4 firmware, both the tts and the duration of the first
deco stop are recorded while in deco. But compared with the older
firmware, the tts field has moved to a slightly different offset. And
contrary to the new documentation, it seems that the value for invalid
or infinite has also changed from 0xFFFF to 0x7FFF,

Note that for dives recorded with an older firmware version, the
duration of the first deco stop isn't available, and libdivecomputer
reports the tts instead. This is the same behaviour as before.

Reported-by: Janice McLaughlin <janice@moremobilesoftware.com>
2017-11-19 23:07:38 +01:00
Jef Driesen
93fc2f1c79 Decode the firmware version for the iDive series
For the older iDive series, the firmware is stored at a slightly
different offset.
2017-11-19 23:07:38 +01:00
Jef Driesen
4ffd514f76 Add support for the Suunto Eon Core
The Suunto Eon Core uses a different USB PID, but otherwise it's
compatible with the Eon Steel. It's probably an Eon Steel internally,
but with a smaller form factor.

To be able to distinguish between the two models and use the correct USB
PID, each model is assigned a different (artificial) model number.

Reported-by: Nick Shore <support@mac-dive.com>
2017-11-19 23:05:23 +01:00
Jef Driesen
812db650d4 Locate the most recent dive
The Suunto Eon Steel seems to have a limit of maximum 400 dives. Once
that limit is reached, the oldest dives get overwritten with newer
dives. But the order in which the dive entries are downloaded isn't
changed, and thus the most recent dive is no longer the last entry.

For the first 400 dives, the order is always straightforward:

   D001 D002  ... D399 D400

The most recent dive is always the last entry, and no special processing
is necessary. But once the limit is reached, the next few dives will
start to overwrite the oldest dives, but the order remains unchanged:

   D401 D402 ... D399 D400

Thus in order to return the dives in the correct order (newest first),
we can no longer assume the most recent dive is the last entry, and thus
we need to locate it manually.

The new algorithm is based on the assumption that the most recent dive
will have the hightest timestamp. And to be able to walk backwards
through all the entries, the list is assumed to be a circular list.
2017-11-19 23:05:23 +01:00
Linus Torvalds
f5df265300 Add EON Steel time sync capability
The EON Steel can use the new 'timesync' interface to set the time
automatically from the computer it is connected to.

This also regularizes the EON Steel command names a bit, and adds a few
new commands (you can also read the time etc, which this doesn't
actually use).

[Jef Driesen: Modified to follow the existing naming conventions, return
the correct error code and avoid arithmetic operations with signed
integers.]

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2017-11-19 23:05:23 +01:00
Jef Driesen
2ced18870d Improve the progress events
At the moment the progress events are reported for each download
operation separately. Combined with the fact that the size of the dives
isn't known in advance, and thus the progress events are based on a
worst case value, the user experience is far from optimal. In practice,
the progress goes from 0 to 100% for every manifest, and it stays close
to zero while downloading the dives.

This is improved by combining the individual progress events into a
single progress for the entire download. This global progress simply
counts the number of individual download operations. Since each
operation is now subdivided into a fixed number of steps, regardless of
the size of the transfer, the perceived speed is no longer constant.
2017-11-19 19:51:59 +01:00
Jef Driesen
2d7d5152b4 Detect the model number using the hardware type
The model number is stored in the final block of each dive. But for an
efficient implementation of the fingerprint feature, the devinfo event
should be emitted before downloading the manifests or the dives. Thus
reporting the correct model number is problematic.

Currently the model number is simply hardcoded to the value of the
Petrel. This is sufficient for the parser, because there the model
number is only used to distinguish the Predator from all the other
models. Now, because the petrel backend doesn't support the Predator,
and the predator backend (which supports both the Predator and Petrel)
can obtain the correct model number from the final block, the hardcoded
value works fine. Except of course for identifying the actual model!

Allthough there doesn't seems to be a command to retrieve the model
number directly, we can retrieve the hardware type and map that to the
model number.
2017-11-19 19:48:55 +01:00
Dirk Hohndel
63d6af8c41 Shearwater: add support for remaining gas time
[Jef Driesen: Update to the latest documentation.]

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2017-11-19 18:04:21 +01:00
Dirk Hohndel
7f22f4ac86 Shearwater: extract tank sensor data for log version 7
The first dive computer to support this is the Perdix AI. Interestingly,
this keeps track of two sensors at all times. I haven't seen data with
two sensors active, yet.

[Jef Driesen: Update to the latest documentation.]

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2017-11-19 18:04:21 +01:00
Dirk Hohndel
9f754dc563 Shearwater: extract log version from header
The earliest document I have references log version 6. There are
apparently older versions, but I don't know what the differences
are. Before version 7, the log version wasn't always reliably
stored, so we assume 6 is the minimum and use 7 (or later) if we
find it.

[Jef Driesen: Initialize and reset the cache correctly.]

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2017-11-19 18:04:21 +01:00
Jef Driesen
428704b538 Add support for the Scubapro Aladin Square
The communication protocol is identical to the G2 protocol, but with a
different USB VID/PID (c251:2006).

Note that unlike the G2, the Aladin Square seems to support only 33 byte
USB HID packets (1 byte report id and 32 bytes payload), even when the
actual command is much smaller. Without padding the commands, the dive
computer doesn't reply at all. Because the padding is already there, to
support the Windows api, no further changes are necessary.
2017-11-16 16:33:11 +01:00
Jan Mulder
20d7d03a0d OSTC: initialize initial CNS from header
As the OSTC does not report a CNS value on the first sample, we need to
initialize it differently. This can be solved by using the initial CNS
value form the dive header, and storing that value in the first sample.
The resulting patch is very similar to 44f629f03a91a3b3.

Signed-off-by: Jan Mulder <jlmulder@xs4all.nl>
2017-11-14 13:51:04 +01:00
Jef Driesen
e786b0b0b6 Use an out-of-range value as undefined
The main purpose of the magic value UNDEFINED, is to indicate that a
value isn't present in the data. But since the value 0xFF can actually
be stored in the data, we can't distinguish between those two cases.
This ambiguity can be avoided by using a magic value that lies outside
the valid range for 8 and 16 bit fields.

Note that an initial gas mix value of 0xFF remains interpreted as
UNDEFINED, but this is now made explicit.
2017-11-14 13:21:21 +01:00
Berthold Stoeger
d0d4c7b994 Support for the Scubapro Aladin Sport Matrix.
The protocol is identical to the G2 protocol, with the exception of a
missing handshake.

Signed-off-by: Berthold Stoeger <bstoeger@mail.tuwien.ac.at>
2017-11-01 20:53:48 +01:00
Jef Driesen
a196255841 Replace the clock calibration with a fixed epoch
Currently the date/time parsing assumes the reference time (epoch) of
the device clock is unknown. Hence we retrieve the current time of the
device (devtime) and the host system (systime) during the download.
Since both timestamps represent the same instant in time, but with a
different reference time, we can calibrate the device clock as follows:

    ticks = parser->systime - (parser->devtime - timestamp) / 2

But this produces wrong results once the device clock has been adjusted
manually. Adjusting the device clock will suddenly increase (or
decrease) the devtime, while the systime continues ticking forwards
normally. Hence all dives recorded before the time adjustment will get
an incorrect date/time value.

Fortunately all devices appear to use a fixed epoch (2000-01-01 00:00:00
UTC) and we can simply replace the calibration with a hardcoded value.

Reported-By: Linus Torvalds <torvalds@linux-foundation.org>
2017-10-23 15:02:38 +02:00
Jef Driesen
7f2384d665 Merge branch 'usbhid' 2017-10-09 16:27:44 +02:00
Jef Driesen
f708eadcfd Make the initialization thread-safe
Perform the initialization inside a critical section.

Unfortunately Windows critical sections, which are the simplest
synchronization mechanism available on Windows, do not support static
initialization. A call to InitializeCriticalSection is required.
Therefore a simple spinlock, with an implementation based on atomic
operations, is used as a workaround.
2017-10-09 14:35:36 +02:00
Jef Driesen
7b920f5c42 Initialize the usb library only once
Initializing the hidapi library more than once is tricky. The hid_init()
function can be called multiple times, but the the hid_exit() function
will free the resources unconditionally, regardless of how many times
the hid_init() function has been called. The consequence is a premature
termination of the library.

To avoid this problem, the calls are reference counted. Note that this
workaround can't protect against calls made outside the libdivecomputer
code!

The libusb library doesn't suffer from this problem, because each
initialization returns a new context pointer. But for consistency, we
now also use a single reference counted libusb context.
2017-10-09 14:35:36 +02:00
Jef Driesen
efe2edd83c Merge branch 'g2' 2017-09-28 22:22:16 +02:00
Jef Driesen
bcb64b3297 Workaround for a Windows libusb issue
When libusb uses the Windows HID api internally, it does automatically
prepend a zero report ID to the data for devices which support only a
single report. But apparently it also returns a size of one byte extra!
As a workaround, the number of bytes is limited to the actual size.

See commit c9ed92d3f55c259931527a27d018eb5791a176dd for a similar issue
in the hidapi library.
2017-09-28 22:19:11 +02:00
Jef Driesen
ddb7276bf0 Use a fixed size packet for sending
The Windows HID api always expects to receive a fixed size buffer
(corresponding to the largest report supported by the device). But
unlike the hidapi library, the libusb library doesn't automatically pad
the buffer to the expected size when trying to send less bytes. Thus
when trying to submit the transfer, the underlying Windows api call
immediately fails with ERROR_INVALID_PARAMETER.

To workaround this problem, pad the data packet with zeros manually and
always send the entire packet (1 byte report ID and 32 bytes payload).
2017-09-28 22:06:21 +02:00
Jef Driesen
a28d2feb4f Replace the size macro with the sizeof operator 2017-09-28 22:06:14 +02:00
Jef Driesen
94f739ab52 Merge branch 'platform' 2017-09-28 22:04:47 +02:00
Jef Driesen
5a00224c93 Use the correct printf format for the size_t type 2017-09-28 22:02:53 +02:00
Jef Driesen
52e03944c0 Move platform specific macros to a common header file 2017-09-28 22:02:53 +02:00
Jef Driesen
b683eca5c8 Use the correct data type for the return value 2017-09-28 22:01:58 +02:00
Jef Driesen
87adab39d7 Rename the DiveSystem vendor to Ratio
At the time support for the Orca and iDive series was implemented, they
were being sold under the "DiveSystem" brand. But nowadays, the newer
iDive and iX3M series are being sold under the "Ratio" brand. Since this
frequently confuses end-users, let's rename the libdivecomputer vendor
name as well.

The Orca and the original iDive series remain under the DiveSystem
brand.
2017-09-28 22:00:09 +02:00
Jef Driesen
fa53d1351b Fix the Sherwood Insight temperature 2017-09-12 22:34:55 +02:00
Jef Driesen
50c4f18cf6 Implement the ndl/deco sample 2017-09-12 22:34:55 +02:00
Jef Driesen
38366ef8ed Merge branch 'cochran' 2017-09-12 19:59:56 +02:00
John Van Ostrand
0220782aa8 Change communication parameter to work better with FTDI
The parameters used with the FTDI USB serial port drivers didn't work
well with directly with libftdi1. The new baud rate results in the same
effective baud rates for both.

The rbstream block size was reduced to help with the unreliability of
the libftdi communications.
2017-09-12 11:08:54 +02:00
John Van Ostrand
ca4c261f6e Retry read operations on failure
Using FTDI for custom I/O resulted in very unrealible reads. This patch
allows more reliable use of FTDI custom I/O, like what might be needed
when used on a mobile device like Android.

[Jef Driesen: Modified to retry only for non-fatal errors. This simply
restores the code from commit b3d2c603ddec9758fb36706bbde46ce23ca9f0ed,
which was removed in commit 55e8f83eb5d934e65fbf587d427de267f174c651.]
2017-09-12 11:06:38 +02:00
Jef Driesen
c839134130 Add support for the Suunto D4f 2017-09-11 08:25:51 +02:00
Jef Driesen
be8b95fdf9 Implement the tank pressure
With the new APOS4 firmware, the latest ix3m and idive models support a
wireless tank sensor. For dives without a tank pressure sensor, the
pressure field in the sample is zero. Thus the first non-zero value
indicates the presence of a tank sensor.
2017-09-07 10:26:07 +02:00
Jef Driesen
45af27734e Merge branch 'uwatec' 2017-09-05 19:04:43 +02:00
Jef Driesen
cb2a4f4a72 Use more descriptive names
Those two samples are no longer unknown. The first one contains some
freedive related data, and the second one contains some additional data
with several sub types. At the moment only the tank and gas mix info is
used.
2017-09-02 10:34:23 +02:00
Jef Driesen
ce590b5bc9 Use two passes to parse the profile data
In the trimix data format, the tank and gas mix information is no longer
stored in the header, but in a special sample. Because this sample is
usually located at the end of the profile, the info isn't available yet
during the first pass. Hence the need for a second pass.

Without this change, the tank and gas mix samples will be missing unless
the caller calls the dc_parser_get_field() function before calling the
dc_parser_samples_foreach() function.
2017-09-02 10:12:44 +02:00
Jef Driesen
6b88bc1b8b Fix the Uwatec trimix data format
The trimix dive header is only 84 bytes large, instead of 0xB1 bytes.
The difference is quite hard to notice, because compared to the normal
Galileo data format, the majority of the fields are located at exactly
the same offset. But there are also some subtle differences, like the
settings field containing the freedive and gauge bits.

To fix this bug, a new header table is added. The rest of the code is
updated to use this new table instead of the old trimix flag. The only
place where the old flag is still used is for the decoding of the tank
and pressure sample.
2017-09-01 15:00:10 +02:00
Jef Driesen
26f5925c05 Implement the ndl/deco, rbt and bookmark samples 2017-08-25 21:25:21 +02:00
Jef Driesen
d954a500f6 Implement the setpoint sample for the iDive and iX3M 2017-08-22 08:40:55 +02:00
Jef Driesen
abab44a74c Implement the ndl/deco sample for the Aqualung i300 2017-08-20 21:29:18 +02:00
Jef Driesen
4aac63ea00 Update the msvc project file 2017-08-19 22:32:48 +02:00
Jef Driesen
156f54302d Add basic timezone support
Allthough most dive computers always use local time and don't support
timezones at all, there are a few exceptions. There are two different
sources of timezone information:

 - Some of the newer Uwatec/Scubapro devices use UTC internally and also
   support a timezone setting. This UTC offset is currently taken into
   account to obtain the dive date/time, but the UTC offset itself is
   lost.

 - Uwatec/Scubapro and Reefnet devices rely on the clock of the host
   system to synchronize the internal device clock and calculate the
   dive date/time. The consequence is that the resulting date/time is
   always in the timezone of the host system.

In order to preserve this timezone information, the dc_datetime_t
structure is extended with a new "timezone" field, containing the UTC
offset in seconds. Devices without timezone support will set the field
to the special value DC_TIMEZONE_NONE.

The dc_datetime_localtime() and dc_datetime_gmtime() functions will
automatically populate the new field with respectively the local
timezone offset and zero. The dc_datetime_mktime() function will take
into account the new timezone field for the conversion to UTC. The
special value DC_TIMEZONE_NONE is interpreted as zero.
2017-08-18 23:26:45 +02:00
Jef Driesen
838f730fb2 Merge branch 'timesync' 2017-08-18 23:23:36 +02:00
Jef Driesen
215d1155f8 Add time synchronization to the example application 2017-08-18 23:17:33 +02:00
Jef Driesen
22e0ab3d2b Implement the new api for the HW devices
The Heinrichs-Weikamp devices already supported clock synchronization by
means of a device specific function. This is now replaced with the new
api.
2017-08-18 23:17:33 +02:00
Jef Driesen
acb4a187fb Add support for synchronizing the device clock
Being able to synchronize the dive computer clock with the host system
is a very useful feature. Add the infrastructure to support this feature
through the public api.
2017-08-18 23:17:33 +02:00
Jef Driesen
db0e1691cc Merge branch 'hidapi' 2017-08-18 23:16:26 +02:00