Even if there are no O2 sensors connected (for example in auto or fixed
setpoint mode), the device records a ppO2 sample with all three values
set to zero. Such samples are now ignored, as if there was no ppO2
sample present.
Reported-by: Anton Lundin <glance@acc.umu.se>
When the PPO2 sample was introduced, we didn't take into account the
fact that rebreathers usually support multiple O2 sensors. The HW OSTC
supports for example three sensors. In order to support multiple values,
without having to introduce a new data structure with an additional
sensor id field, we simply relax the assumption of allowing only one
DC_SAMPLE_PPO2 value per sample. Applications that are not prepared for
multiple values, will automatically use only one of them (probably the
last one).
The DC_FIELD_GASMIX api doesn't support the 6th manual gas very well.
Manual gas mixes are either not taken into account at all (OSTC3), or
only the last value is returned (OSTC2).
We now parse the profile data in order to retrieve all the manual gas
mixes too. Note that manual gas mixes are only included when they are
actively used during the dive. This is a small change in behaviour for
the OSTC2.
To simplify the implementation, there is an upper limit of 10 manual gas
mixes (or 15 gas mixes in total). This is an arbitrary choice, which
should be more than sufficient in practice. If it turns out to be too
small, we can always increase the number, or even make it truely
unlimited.
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.
In the OSTC3 data format, the 7th bit of the event byte is used to
indicate whether another event byte is present or not. For the OSTC2,
this 7th bit remained unused, and I assumed it would eventually get used
in the same way as the OSTC3 does. But that assumption turns out to be
wrong. Starting with firmware v2.66 the 7th bit is used for a new
bailout event.
This patch leaves the existing logic intact, but except for the OSTC3
format (version 0x23), the maximum number of events bytes is now limited
to just one byte.
Although the communication protocol of the OSTC3 is nearly identical to
that of the Frog, the different size parameters make it hard to share
the code easily. On top of that, if we ever implement native bluetooth
communication support, we'll need a completely separate backend anyway.
Therefore the Frog backend is simply duplicated, with a few OSTC3
specific changes applied here and there.
The existing ostc parser is upgraded to support the new OSTC3 data
format.
The Frog stores the index of the initial gas mix at the same location
as the OSTC, but the gas mix percentages are at a different offset, and
the number of gas mixes is different too. Parsing all the gas mixes in
advance makes the code easier to read and more future proof.
With the layout descriptors, most hardcoded constants are now in a
central place, which will make it easier to add support for new data
format variants.
Currently, each backend has it's own function to verify whether the
object vtable pointer is the expected one. All these functions can be
removed in favor of a single isintance function in the base class,
which takes the expected vtable pointer as a parameter.
Functions which are called through the vtable, don't need to verify the
vtable pointer, and those checks are removed.
The term "backend" can be confusing because it can refer to both the
virtual function table and the device/parser backends. The use of the
term "vtable" avoids this.
Two issues:
- the OSTC counts its gases 1-based, not 0-based
- dives don't always start with the first gas. Simply create a gas change
event right after the first time sample that informs the application what
the first gas mix is
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
The recently introduced CNS support caused a regression for older
firmware versions. If a firmware doesn't support a certain sample
yet, the corresponding sample divisor and size are both equal to
zero (the default value for unused bytes). However, because the
size was always checked, regardless of whether the sample is
actually present or not, this zero size caused the parsing to fail.
To fix the regression, the size is now only checked when the
divisor indicates the sample is actually present.
Having these as events seems less useful since for many dive computers
there are data with every sample - so it makes much more sense to have
these as part of the sample.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
So far only OSTC and Shearwater Predator are supported. For the OSTC we
support CNS and setpoint changes in the samples (the current hardware
doesn't actually support ppO2 sensors and for the older hw that does I
don't have the correct encoding information).
For the Predator we support only the "average ppO2 during the sample".
The Predator also gives us a CNS value at the end of the dive - I don't
quite know yet how to deliver that back to the consumer. Possibly as CNS
value in the very last sample? That would at least be consistent.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
Apparently some older firmware versions don't support the salinity
setting. Because unused bytes are initialized with zero, the salinity
value will be reported as being zero.
To fix this unexpected value, the salinity factor is first checked for
valid values. If the value is out of range, a DC_STATUS_UNSUPPORTED
error is returned to indicate the absence of the value.
Apparently some older firmware versions don't support the salinity
setting. Because unused bytes are initialized with zero, the salinity
adjustment results in a division by zero, which converts all depth
values to infinity.
To fix this regression, the salinity factor is first checked for valid
values. If the value is out of range, no salinity adjustment is done,
and the previous behaviour is retained.
- PO2 warnings (high and low both mapped to the same SAMPLE_EVENT_PO2
event)
- SPEED warning (which according to hw isn't emitted at this point)
- Deco stop violations (both deep and regular mapped to same
SAMPLE_EVENT_CEILING event)
- Deco ceiling and time (this is reported as a series of
SAMPLE_EVENT_DECOSTOP events with packed deco stop depth (in m) and
time (in seconds)
A SAMPLE_EVENT_NDL event (with an optional value indicating the non-stop
time remaining) indicates that the ceiling has been resolved
- Gas change (reported as SAMPLE_EVENT_GASCHANGE2, using another
unfortunate O2% / He% semantic that is used in the
SAMPLE_EVENT_GASCHANGE
This also covers the manual gas set event of the OSTC
- Manual Marker (reported as SAMPLE_EVENT_BOOKMARK)
The two new events (SAMPLE_EVENT_GASCHANGE2 and SAMPLE_EVENT_NDL are added
to the universal app as well.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
This now uses the same formula as the OSTC uses internally which will get
the values reported by libdivecomputer to be consistent with what is
displayed on the OSTC.
Signed-off-by: Dirk Hohndel <dirk@hohndel.org>
I forgot to update the device and parser initialization functions to
store the context pointer into the objects. As a result, the internal
context pointers were always NULL.
The public api is changed to require a context object for all
operations. Because other library objects store the context pointer
internally, only the constructor functions need an explicit context
object as a parameter.
Adding the "dc_" namespace prefix (which is of course an abbreviation
for libdivecomputer) should avoid conflicts with other libraries. For
the time being, only the high-level device and parser layers are
changed.
The public header files are moved to a new subdirectory, to separate
the definition of the public interface from the actual implementation.
Using an identical directory layout as the final installation has the
advantage that the example code can be build outside the project tree
without any modifications to the #include statements.
The OSTC doesn't store the start of the dive, but the exit time. Hence
the dive time needs to be substracted.
For dives with format version 0x21, we prefer the total dive time in
seconds stored in the extended header. This time value also includes the
shallow parts of the dive, and therefore yields the most accurate start
time. The dive time is rounded down towards the nearest minute, to match
the value displayed by the ostc. For dives with the older format version
0x20, this value isn't available and we default to the normal dive time.