With the model number in the version table, the version string can be
mapped to the corresponding model number. This allows to implement some
model specific behaviour already before being able to read the model
number.
In most cases, there is a simple one to one relationship between the
version string and the model number, but there are also a few
exceptions:
* For the Sherwood Wisdom 2 and 3, and the Beuchat Mundial 2 and 3,
each variant has a different model number, but the first part of the
version string is identical. The difference is in the firmware
version part. Handling this correctly requires two entries in the
table.
* For the Oceanic OC1 there are 3 different model numbers, and only 2
different version strings. That means there is no correct mapping
possible.
With just a single table, the version string matching not only becomes
simpler, but adding new layouts also requires no code changes anymore.
For devices that need different layouts depending on the firmware
version (e.g. Oceanic Atom 2.0 and Aeris Manta), the table may contain
multiple entries with the different firmware versions. The only
requirement is that the entry with the highest firmware version must be
listed first.
The Oceanic Pro Plus X is quite different from the previous models. The
profile data is now stored in a dedicated memory area, and hence there
are a few important differences:
Reading data from the new profile memory area is done with a new F6
command. This new command is very similar to the existing B8 command,
but accesses a completely different memory area. In order to integrate
those two memory areas as transparantly as possible into the existing
infrastructure, a virtual memory space is introduced. The lower part of
the virtual memory is mapped onto the main memory area, while the upper
part is mapped onto the new profile memory area.
The page size of the new profile memory area also increased from 16 to
256 bytes. If the profile size is not an exact multiple of 256 bytes,
the dive computer pads the profile data with 0xFF bytes.
The other changes are the usual Oceanic device specific changes.
At the moment, the encoding of the serial number is tied to the global
pointer mode. To support devices where this is no longer the case, a new
entry for the serial number encoding is added.
By adding the logbook and profile functions to the vtable, a dive
computer backend can now easily replace the default implementation with
a custom one, without having to duplicate the common code.
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.
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.
The hardcoded version strings are now grouped into arrays, according to
their corresponding layout descriptor. The main advantage of using
arrays is that new versions strings can now easily be added, without
having to modify any code.
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.
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 logbook ringbuffer is now considered empty if any of the pointers is
outside the valid ringbuffer area. Compared to checking only against a
special empty value, this approach makes the code more robust against
invalid pointers.
Introducing a common base class allows to share more code between the
backends. Sharing the fingerprint data eliminates the need to pass it
with a function parameter.
The memory layout of all Oceanic devices is very similar, which allows
to share the parsing code between the different backends. Differences in
the layout are passed by means of a new layout descriptor structure.
Memory buffers are now allocated dynamically to support devices with
different amounts of memory.