With a time based sample interval, the maximum number of samples for a
single timestamp should be constant. However in practice some devices
occasionally store one or more additional samples with the same
timestamp.
Ignoring those excess samples, allows the parser to proceed, while still
preserving the strict time based interval for the application.
The example applications may not always be needed. An option to disable
them might be useful.
Signed-off-by: Venkatesh Shukla <venkatesh.shukla.eee11@iitbhu.ac.in>
Commit d414da70a42afca0096e0402a426c4ac8d2a2881 added support for a
second Aeris Elite T3 variant. But the parser wasn't updated to take
into account this second model number.
For the Aeris Manta and Sherwood Insight, the header size should be 16
bytes smaller. Due to this mistake not only two samples were missing,
but also the byte offset for the gas mixes were wrong. This resulted in
invalid gas mixes, with oxygen percentages exceeding 100%.
For the older models, gas mixes are disabled by setting their oxygen
percentage byte to 0x00 or 0xFF. Trying to parse such a byte as a valid
percentage results in an invalid gas mix.
Because the device doesn't allow you to enable a gas mix if the previous
gas mix has already been disabled, we can simply stop parsing the gas
mixes once the first disabled gas mix has been found.
The gas mode should not only be taken into account for parsing the gas
mix definitions, but also for the initial gas mix. Because the logic
needs to be kept in sync, it's convenient to have all related code in a
single place, and cache the value.
Because the gas mode takes precedence over the individual gas mix
definitions, we can simplify the code by taking the gas mode into
account immediately when parsing the gas mixes.
In commit 886884ab606def1183d99eca7dec8affefee635e, the custom log
function in the example applications has already been modified to use
high resolution timestamps. But I forgot about the built-in default log
function. So this is basically the same change, but now applied to the
built-in log function.
The extra memcmp check after the tcsetattr call is intended to verify
whether all the changes to the termios structure have been applied
correctly.
But for pty's, some of the termios settings make no sense at all, and
therefore the Linux kernel always does:
tty->termios.c_cflag &= ~(CSIZE | PARENB);
tty->termios.c_cflag |= (CS8 | CREAD);
Thus, instead of ignoring such nonsense termios settings, the kernel
changes the termios structure to reflect what pty's actually do. The
consequence is that these settings will not stick, and cause the memcmp
check to fail.
An example where this affects libdivecomputer, are the two backends that
require odd or even parity (e.g. vyper and iconhd). Here, the kernel
will clear the PARENB flag, and thus cause the memcmp check to fail.
Since this check appears to causes more trouble than it solves, let's
just remove it completely!
The previous commit exposed another issue. The termios structure may
contain padding bytes. Because the content of those padding bytes is
unspecified, they may contain some random data, which causes the memcmp
to fail.
Explicitly initializing the termios structure with memset, will also set
the padding bytes to zero.
Due to a minor mistake, only the first byte was being checked for
equality. Fixed it by changing position of parenthesis.
Signed-off-by: Venkatesh Shukla <venkatesh.shukla.eee11@iitbhu.ac.in>
The Cressi Leonardo does store an indicator for the ascent rate (e.g.
the number of arrows) in the upper two bits. This results in 4 possible
values, ranging from 0 to 3, with the following interpretation:
0.0 - 3.9 m/min No signal
4.0 - 7.9 m/min 1 Arrow
8.0 - 11.9 m/min 2 Arrows
12.0+ m/min 3 Arrows (with STOP icon)
Reported-By: Nick Shore <support@mac-dive.com>
With the exception of the different event mask (single byte 0x80 vs two
byte 0x0100), the OSTC3 bailout event is identical to the OSTC2 variant.
Just as before, the new bailout event is reported to the application as
a normal gas change event.
Currently, the buffer overflow checks take into account the size of the
entire dive. But since the length of the extended sample is stored in
the data, we can actually check for overflows in each sample. The main
benefit is that errors will be caught much earlier now.
An additional advantage is that we can now easily skip any remaining
sample bytes. Normally such bytes are not present, unless a firmware
update introduces a new feature which our parser doesn't support yet.
The Mares Nemo Wide 2 appears to have a slightly larger profile
ringbuffer, which extends to the end of the internal memory. It remains
to be seen whether this is also true for some of the other models. The
Mares Matrix is currently the only model where this is definitely not
the case.
The Hollis TX1 has several new features compared to the other models. It
supports trimix and up to 6 different gas mixes can be configured. It
also has twice the amount of memory, which requires an extra bit for the
ringbuffer pointers.
The initial gas mix index has been confirmed for the D6i only. For the
other two models, it's an educated guess that the byte offset will be
identical.
Normally, the last valid dive is followed by an empty entry with all
0xFF bytes. However, we received data from a device where a few of those
bytes are not equal to 0xFF. This causes the entry to be processed
incorrectly as a valid dive.
As a workaround, we now check the internal dive number for 0xFFFF.
This makes libdivecomputer build via Android NDK. Its currently unusable
due to the fact that Android usually doesn't provide any kernel serial
drivers.
Signed-off-by: Anton Lundin <glance@acc.umu.se>
On some systems a small delay is required between receiving the response
of a packet and sending the request for the next packet. Without this
delay, almost every request fails with either a NAK or a timeout.
Retrying usually works, but also causes the download to slow down
considerable.
The root of the problem appears to be related to the FTDI low latency
setting. On Windows and Mac OS X systems, the default setting for the
latency is 16ms, while Linux defaults to a low latency setting of only
1ms. This higher latency on Windows and Mac automatically introduces a
small delay while reading the packet, and that probably happens to be
just enough to make the transfer succeed without any problems. But on
Linux, due to the low latency setting, the next request is send almost
immediately, and that causes the transfer to fail. I suspect the dive
computer may still be busy with the previous request and needs a bit
more time before it's ready to accept a new request.
To mitigate this problem, we introduce a adaptive inter packet delay.
Initially this adaptive delay is set to zero. This is to make sure we
don't affect those systems that don't need a delay at all. Now, every
time a packet fails, that's an indication the inter packet delay is too
small, and we slightly increase the value. After a few attempts we'll
automatically reach the minimal required value. To avoid that the delay
grows out of control in the case of serious trouble, it's limited at
16ms.
Note that the fixed 100ms delay before retrying a failed packet remains
in place. That's on purpose, to make sure the next attempt will always
be successful, regardless of whether the adaptive delay has already
reached its minimal value or not.
Currently this isn't used or needed anywhere, but the research has been
done, and it would be silly to drop the knowledge. We may need it in the
future.
The Suunto dive computers record gas change events in the profile data.
But because there is no gas change event stored on the first sample, the
application doesn't know which gas mix is in use, until the very first
gas change event occurs.
For the Suunto HelO2, the index of the initial gas mix is stored in the
dive header. This is most likely also the case for the other models, but
I haven't found yet where exactly it is stored. As a temporary solution,
we simply assume the initial gas mix is the first gas in the list with
available gas mixes. This should be a reasonable assumption for most
dives.
Fixes ticket #2
The gas mix data is used from multiple functions, and the code to parse
that data is duplicated in each function. Because this is error prone,
the code is moved to a single place, and the data cached in the parser.
The resolution of the GetTickCount function is limited to the resolution
of the system timer, which is typically in the range of 10 to 16
milliseconds. This is unsufficient for measuring very short time
intervals in the milliseconds range. The QueryPerformanceCounter
function provides much higher resolution timestamps. We already use it
for the half-duplex workaround.