Reading the data packet in multiple smaller chunks greatly improves the
progress events. Instead of just two events, before and after the
download, there are now many intermediate events. This change also
allows to significantly reduce the timeout, from 30 seconds to just one
second, which avoids blocking for too long in case the device doesn't
respond at all.
An infinite timeout causes major problems, because if the device doesn't
respond at all, the read call will block forever. With the eon serial
line settings (1200 8N2), the total time to read the 2305 byte packet is
about 21.129 seconds. A timeout of 30 seconds should be plenty of time.
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.
The serial numbers were not decoded at all. The raw bytes where simply
converted into an arbitrary 32 bit integer. Now the serial number
matches the real serial number as shown by the device.
The version function requires device specific knowledge to use it (at
least the required buffer size), it is already called internally when
necessary, and only a few backends support it. Thus there is no good
reason to keep it in the high-level public api.
These macros are used internally and don't need to be exposed. In some
cases, the actual values are not even constant, but dependant on the
model and/or the firmware version.
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.
Using a resizable memory buffer allows to allocate the right amount of
memory inside the backend, avoiding having to know the required buffer
size in advance.
The memory layout of the Suunto Eon and Vyper devices is very similar,
which allows to share the parsing code between the backends. Differences
in the layout are passed by means of a new layout descriptor structure
and a common base class is introduced to share the fingerprint data.
Memory buffers are now allocated dynamically to support devices with
different amounts of memory.
Moved the initialization of the backend pointers to the beginning of the
source file. Without the need for a tentative definition, the library
can be compiled with a C++ compiler.
When necessary, an output parameter is added to provide the size
information. Status codes are strictly reserved for providing status
information only.