Add a function to query the underlying transport type. This allows the
dive computer backends to implement transport specific behaviour where
necessary.
For the built-in I/O implementations, the transport type is obviously
always hardcoded, but for a custom I/O implementation the application
needs to provide the correct type. Hence the transport type can't be
hardcoded in the vtable and needs to be passed as a parameter.
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.
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.
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.
The descriptor strings are dynamically allocated and owned by the
struct. The const qualifiers are a bit misleading here, and result in
warnings when trying to free the pointers again.
The multiplication is evaluated using 32bit arithmetic, and then stored
in a 64bit integer. The 32bit integer overflow can be avoided by casting
to a 64bit type first.
The write function is modified to always fill the buffer completely
before sending out the data. For escaped characters, the previous
implementation needed to append two bytes at once. Thus, if there was
only space left for a single byte, the buffer got flushed early with one
byte still unused. This can be avoid by appending one byte at a time.
The read function is modified to use a simple state machine with only a
single read call. This is mainly preparation to support reading and
processing larger data packets instead of just single bytes.
I received a bug report complaining that the most recent dives did not
get downloaded. It turns out that the internal dive number in the
logbook entries got reset back to zero somehow:
Logbook 0: empty
...
Logbook 209: empty
Logbook 210: 1
Logbook 211: 2
...
Logbook 235: 26
Logbook 236: 27
Logbook 237: 0
Logbook 238: 1
...
Logbook 254: 17
Logbook 255: 18
This confuses the logic to locate the most recent dive. Because that
logic assumes that the entry with the highest internal dive number is
always the most recent dive, it finds logbook entry #236 instead of the
correct entry #255. Now, when processing the logbook entries backwards,
it stops at those empty entries, and thus never reaches then newest
entries #237 to #255.
The workaround is based on the fact that the OSTC4, unlike the other
hwos based models, already re-orders the logbook entries and always
sends the most recent logbook entry last. So we can ignore the dive
number and simply use the last non-empty entry.
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>
The Dive Rite NiTek Q supports OC and CC samples. For reporting the dive
mode, any dive containing at least one CC sample is considered to be a
CCR dive.
The half-duplex emulation is basically a workaround for a timing problem
in the vyper2 backend. Since no other dive computer backend uses or
needs this feature, it makes no sense to support this at the I/O layer.
It can be implemented directly in the vyper2 backend instead.
Replace the gettimeofday() based implementation with the new monotonic
timers. This makes the implementation more robust against unexpected
adjustments of the clock.
The new timer module provides an cross-platform interface for a high
resolution monotonic clock. The timestamps are always relative to the
creation of the timer and their unit is one microseconds.
The timers can be used for logging, measuring elapsed time and
implementing timeouts.
Unfortunately there are several devices where an invalid logbook begin
pointer occurs relative frequently. Typical examples are the Oceanic VT
4.1 and the Sherwood Wisdom 2. In such cases, the strict validation of
the pointer causes the download to fail, without being able to download
any dives at all.
Since the begin pointer is only needed to detect the oldest logbook
entry, we can fall back to downloading the entire logbook ringbuffer. If
we're lucky (and we usually are), we can detect the oldest entry by
inspecting the logbook entries once they are downloaded (e.g. presence
of uninitialized entries) and then the download will finish succesfully.
In the worst case scenario, we'll be able to download at least some
dives before hitting another error.
The ringbuffer_distance() function has a parameter to specify whether a
ringbuffer with identical begin/end pointers should be considered an
empty or a full ringbuffer. Hence there is no need to handle the case of
a full ringbuffer manually.
The warning about disabling the O2 sensors due to factory default
calibration values, applies only if there is at least one calibrated O2
sensor present.
This has no effect on the calibration bits, because those are already
zero if there are no calibrated O2 sensors present.
There is no need to expose the two step connection setup of the
underlying socket interface in the public api. Doing so may complicate
the implementation on platforms where the native api is not based on the
socket interface (e.g. Mac OS X).
Note that the function to connect based on the IrDA service name is
removed. It's not used anywhere in libdivecomputer and since IrDA is an
outdated technology nowadays, it's unlikely we'll need it in the future.
The device descriptors are extended with a filter function. During the
device discovery, this filter function is used to return only devices
that match a known dive computer.
The filtering is optional, and can be disabled by passing a NULL pointer
for the device descriptor when creating the iterator with one of the
dc_xxx_iterator_new() functions.
Replacing the callback based interface with an iterator based interface,
results in a more extensible abstraction with a common interface for
each of the built-in I/O implementations (serial, usbhid, irda and
bluetooth).
When the port number is set to zero (which is an invalid value), detect
the port number automatically. On Windows, we can simply supply the UUID
of the serial port service, and the Windows api will take care of the
discovery. On Linux (bluez), the SDP discovery needs to be performed
manually to retrieve the port number.
If all (calibrated) sensors still have their factory default calibration
values (2100), they are probably not calibrated properly. To avoid
returning incorrect ppO2 values to the application, they are manually
disabled (e.g. marked as uncalibrated).
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.
Unlike the Shearwater Petrel, the Shearwater Nerd 2 appears to have a
distinct model number from the Nerd.
Reported-by: Janice McLaughlin <janice@moremobilesoftware.com>
Shifting a 32bit value by 32 is undefined.
Instead of using shifts to create the mask, explicitly create it by
subtracting 1 from the signbit value (and using bitwise NOT to fill all
the higher bits).
This commit looks confusing because Jef wanted me to not have two places
where I use the bitwise not. So instead of creating an equivalent mask
variable and not having to change the return statements we end up with a
mask that is the bitwise invert of what was there before this commit and
therefore the return statements need to change as well.
Coverity CID 207769
Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
The Linux kernel uses the sir_name as a standard C string (in one
instance copying it into a 60 char buffer using kstrncpy with a length
limit of 60), we therefore need to ensure that it is 0 terminated.
Since the existing code didn't notify the caller if we were truncating
the string at 25 characters, I didn't add such a warning/error for
truncating at 24 characters.
I was not able to find documentation on how Windows uses irdaServiceName
but since this is implementing the same standard, the same change was
made to the Windows code.
In both cases I replaced the hardcoded length of 25 with a sizeof()
argument (but both Linux and Windows hard code that length in their
headers, so it seems unlikely this would ever change).
Coverity CID 207790
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>