47 Commits

Author SHA1 Message Date
Jef Driesen
00033e4af0 Rename the 32-bit CRC functions
The new names make it easier to identify the normal and reflected
variant of the CRC function.
2023-03-23 19:30:23 +01:00
Jef Driesen
187f8d625b Move the snprintf functions to the platform module
Moving the implementation of the snprintf wrapper functions to the
platform module allows to re-use the same implementation throughout the
entire codebase.
2023-01-25 13:32:14 +01: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
afff8b450f Add BLE support for the Suunto Eon Steel devices
The main difference with the USB HID communication is that the BLE data
stream is encoded using HDLC framing with a 32 bit CRC checksum. Due to
this encoding, the data packets can no longer be processed one by one
(as is done for the USB HID packets). The entire HDLC encoded stream
needs to be received before it can be processed. This requires some
additional buffering.
2018-04-03 21:52:20 +02:00
Jef Driesen
ef2402eff5 Integrate the new I/O interface in the public api
Currently the dive computer backends are responsible for opening (and
closing) the underlying I/O stream internally. The consequence is that
each backend is hardwired to a specific transport type (e.g. serial,
irda or usbhid). In order to remove this dependency and support more
than one transport type in the same backend, the opening (and closing)
of the I/O stream is moved to the application.

The dc_device_open() function is modified to accept a pointer to the I/O
stream, instead of a string with the device node (which only makes sense
for serial communication). The dive computer backends only depend on the
common I/O interface.
2018-04-03 21:11:06 +02:00
Jef Driesen
7d48cffc0d Simplify the packet send/receive code
Re-organize the packet sending and receiving code to eliminate the need
for different code paths for the init command and all other commands.
2018-04-03 21:10:04 +02:00
Jef Driesen
43f196b804 Remove the code to purge the input buffer
Trying to purge the input buffer by reading and discarding data packets,
results in an annoying and confusing error message if no data packet is
received. To avoid this error, the functionality should be integrated in
the USB HID code, either automatically during initialization or by
implementing the purge function.

But since there seems to be no evidence that this is actually necessary,
let's remove this code.
2018-04-03 21:10:04 +02:00
Jef Driesen
5344f3926a Abort with an error if the buffer is too small
Silently truncating the data packet if the buffer is too small will
result in a corrupt data stream.
2018-04-03 21:10:04 +02:00
Jef Driesen
38c3f289b5 Improve the error reporting
The error codes from the I/O layer are now correctly returned to the
upper layers.
2018-04-03 21:10:04 +02:00
Jef Driesen
755b52febc Improve the fingerprint matching
Check the fingerprint before downloading the dive. If a match is found,
this avoids some unnecessary communication and thus makes the download a
little bit faster.
2018-04-03 21:10:04 +02:00
Jef Driesen
01ccb7ce4b Fix a few memory leaks
The file list isn't freed when an error occurs, and the strings returned
from the lookup_enum function are dynamically allocated and thus should
be freed as well.
2018-04-03 21:10:04 +02:00
Linus Torvalds
c15d422f75 Suunto EON Steel: set date too when doing device timesync
I'd never noticed this before, since my date had always been already set
correctly, but the timesync with the EON Steel only set the time, not
the date.

The fix is trivial, since the code already filled in the datetime data,
it just didn't do the SET_DATE command.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2018-04-03 21:01:39 +02:00
Jef Driesen
0ae9e355f8 Check for memory allocation errors
Appending data to the buffer may fail if a memory allocation is
necessary to enlarge the buffer. Hence the return value of the
dc_buffer_append() call should always be checked, unless the memory was
already pre-allocated or the check is deferred after the last operation.
2018-01-29 15:06:58 +01:00
Dirk Hohndel
4144e0c7ff Cleanup: bail on error
Coverity CID 207809

Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2018-01-04 19:46:54 +01:00
Jef Driesen
cf9626efc3 Port the USB HID code to the new I/O interface 2017-11-25 10:26:49 +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
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
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
bdf69ce1ec Remove unused parameters 2017-04-24 13:05:20 +02:00
Jef Driesen
d1a06e784c Remove deprecated functions from the public api
The vendor_product_parser_create() and vendor_product_device_open()
functions should be called indirectly, through the generic
dc_device_open() and dc_parser_new() functions. And the
vendor_product_extract_dives() functions are internal functions that
should never have been part of the public api in the first place.
2017-04-18 08:41:10 +02:00
Jef Driesen
c5fac27bc8 Fix some compiler warnings 2017-03-08 08:54:42 +01:00
Jef Driesen
417ee6e619 Use the new USB HID backend for the Eon Steel. 2016-09-19 15:04:48 +02:00
Jef Driesen
4ba92e24ef Fix a crash when no dives are present.
To guard applications from divisions by zero, the progress event code
asserts the maximum value should always be non-zero. The eonsteel does
trigger this assert when there are no dives present.
2016-07-11 13:14:15 +02:00
Jef Driesen
d40cdb4755 Add the devinfo event.
The devinfo event with the device serial number is required for the
fingerprint feature. Without this event, applications won't be able to
load (or save) the correct fingerprint. All necessary information is
already available in the initial handshake packet.
2016-04-26 10:59:02 +02:00
Jef Driesen
76c52b582a Add support for the fingerprint feature. 2016-04-26 10:56:52 +02:00
Jef Driesen
ce82829284 Fix a memory leak.
A new buffer is allocated for each dive, but only the last one is freed.
Since the code is already prepared to simply re-use the same buffer,
there is no need to allocate those extra buffers.
2016-04-26 10:56:48 +02:00
Jef Driesen
ff29d218bb Use helper functions to allocate and free objects.
Both the allocation and initialization of the object data structure is
now moved to a single function. The corresponding deallocation function
is intended to free objects that have been allocated, but are not fully
initialized yet. The public cleanup function shouldn't be used in such
case, because it may try to release resources that haven't been
initialized yet.
2016-01-05 20:40:21 +01:00
Jef Driesen
9bc14dca10 Remove some boilerplate code from the cleanup functions.
Instead of freeing the object data structure in the backend specific
cleanup function, the memory is now freed automatically in the base
class function. This reduces the amount of boilerplate code in the
backends. Backends that don't allocate any additional resources, do no
longer require a cleanup function at all.
2016-01-05 20:40:21 +01:00
Jef Driesen
18d4d5dcc0 Switch to goto style error handling.
With the goto error handling, all cleanup code can be moved to a central
location and no longer needs to be duplicated multiple times.
2016-01-05 20:40:21 +01:00
Linus Torvalds
9eef4d6cec suunto eon steel: clean up size limits and error reporting
This is some small cleanup after the whole reply size rewrite.  It
further improves on the error log reporting a bit, and it undoes the
"read exact size" thing introduced in "suunto eon steel: fix file
reading special case", because it is no longer necessary.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2015-07-04 08:44:54 +02:00
Linus Torvalds
e73dcdacae suunto eon steel: be more explicit about transfer sizes
When reading data from the EON Steel, we'd generally continue reading
until we saw that a response was done by seeing a packet that wasn't
full.

That broke for the case of the data boundary matching the packet
boundary, fixed by the commit "suunto eon steel: fix file reading
special case".

However, that commit only fixed it for the case of reading a file, where
the result has a size that is known up-front.  And most other situations
really don't matter, because the result size is fixed and fits in a
single packet, so it all works.

However, there are still a few cases that could trigger the problem,
notably reading the directory contents.

So change the send_receive() logic to actually read the expected size
from the receive header in the first packet of the reply.  This means
that we need to re-organize the packet reception code a bit, but the end
result is that we are much more careful about data sizes,

This also changes the packet logging to be much more readable, by
logging just the actual data, and not the (uninteresting) per-packet
header, or the stale data at the end of the packet.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2015-07-04 08:44:54 +02:00
Linus Torvalds
8e3cb0542f suunto eon steel: fix file reading special case
The "receive_data()" function would continue to try to read packets as
long as the previous packet was full-sized, but with just the right size
of file and the right chunking, the file might end at a packet boundary.
Then receive_data() would try to read more data, which fails - there are
no more packets, despite the last packet being full.

This never triggered for me, but Robert Helling forwarded a data dump of
a filure to read a dive due to this.

Since I don't trigger this case, I can't really test it, but I did check
that the new "stop early" logic works for me (ie never triggers ;).

Reported-by: Robert C. Helling <helling@atdotde.de>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
2015-07-04 08:44:54 +02:00
Jef Driesen
d1121d174c Fix a few memory leaks. 2014-11-24 11:37:24 +01:00
Jef Driesen
6df4f00822 Fix a NULL pointer dereference. 2014-11-24 11:37:24 +01:00
Jef Driesen
0b0acf7336 Use the non-standard _snprintf() function for msvc. 2014-11-24 11:37:24 +01:00
Jef Driesen
dbcaa6946a Add explicit casts for the msvc C++ compiler. 2014-11-24 11:37:24 +01:00
Jef Driesen
f228a5f9fc Replace string literals with arrays.
This avoids some more compiler warnings regarding incompatible pointer
types (e.g. signed vs unsigned char pointers). Arrays have the
additional advantage of the sizeof operator. This eliminates an
unnecessary strlen() call, and the strcpy() call can be replaced with
memcpy().
2014-11-24 11:37:24 +01:00
Jef Driesen
d5933d59fb Replace zero length strings with NULL pointers.
This avoids some compiler warnings. The type of the string literal is a
const char pointer, while the send_cmd() function expects an unsigned
char pointer.
2014-11-24 11:37:24 +01:00
Jef Driesen
4120b2f0e9 Replace void pointers with unsigned char pointers.
Since we're dealing with byte arrays, there's no need to use void
pointers. Using unsigned char pointers also eliminates some compiler
warnings for pointer arithmetic on void pointers.
2014-11-24 11:37:24 +01:00
Jef Driesen
e8c2e87919 Remove the custom logging functions.
There is no need for custom logging functions, because libdivecomputer
already has an extensive logging infrastructure, featuring conditional
compilation, multiple loglevels, customization by the application, etc.
2014-11-24 11:37:24 +01:00
Jef Driesen
1fa054b409 Use the libusb autodetach functionality only if available.
The libusb autodetach kernel driver functionality is only available in
recent versions.
2014-11-24 11:37:24 +01:00
Jef Driesen
6bc6e58d3b Fix a redefinition warning for the ERROR macro.
See commit 113d2e4706698f7086e5499282ec958aa2de044f for more details.
2014-11-24 11:37:24 +01:00
Jef Driesen
686500d51b Follow the libdivecomputer naming conventions.
All entry point functions (e.g. public functions or functions called
through the vtable) use the backend name as the prefix. The same applies
to the main device and parser structures.
2014-11-24 11:37:24 +01:00
Linus Torvalds
5c967f3382 Suunto EON Steel: support downloading of core dive profile data
Basic Suunto EON Steel downloading copied from my test application.
This parses all the core dive data, including sample data (time, depth,
cylinder pressure, deco information etc).

The deco information returns ceiling and TTS rather than ceiling and
"time at ceiling", because that's what the dive computer has, and I
don't see any other way to return the information.

We don't report any events yet, though.

Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2014-11-24 11:37:23 +01:00