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.
Apparantly there are also two different type of serial numbers present,
and their interpretation depends on the application. The Windows Dive
Organizer application shows both a serial number (byte offset 0x04) and
a warranty number (byte offset 0x0C). However, the Mac OS X Divers'
Diary application shows the number at byte offset 0x0C as the serial
number. Very confusing. For now, we just stick to the number at byte
offset 0x0C, because that's the number that is shown by the device
itself.
The Matrix uses the same communication protocol as the Nemo Wide 2,
except that the sending the request packets with just a single write
operation doesn't seem to work. That's very surprising because it
caused no problems for the Nemo Wide 2 or the Icon HD!
The first two bytes of each request packet are probably some kind of
command type. These two bytes are answerred immediately with an ACK
byte (0xAA). Once this ACK byte has been received, the payload of the
command (if any) can be sent, and finally the response packet can be
received.
I suspect that when trying to send the entire command at once, the
device somehow doesn't receive the payload bytes correctly. Maybe it's
still busy processing those first two bytes, which causes the remainder
of the packet to get dropped? That might explain why the version
commands is not affected, because it doesn't have any payload bytes!
The new vendor event provides a mechanism to deliver auxiliary data,
which is automatically retrieved during the data transfer, but not
accessible through the library interface otherwise. Possible examples
include handshake data and/or device identification data.
This event is mainly intended for diagnostic purposes, in combination
with the memory dumping support. Very few applications will actually
need it for anything else.
The Nemo Wide 2 uses the same communication protocol as the Icon HD,
except for two differences:
The Nemo Wide 2 requires a different baudrate and parity setting.
Unfortunately it doesn't seem possible to autodetect the correct
protocol variant at runtime. Attempting to proceed with incorrect
settings will render the device unresponsive and requires a battery
reset to recover.Therefore the model code needs to be provided as an
extra parameter, when opening the connection.
The Nemo Wide 2 also appears to have trouble downloading the entire
memory with a single request. Therefore the single large request is
split into many smaller ones. The offical Mares application uses 256
byte packets, and so do we. The Icon HD keeps using the large packets
because they are significant faster.
The extra model parameter breaks backwards compatibility!
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.
It looks like the Icon HD erases old dives partially with 0xFF bytes
before overwriting them with new dives. If the head of the oldest dive
has been erased, the length field which is stored in the first 4 bytes
is erased as well, and we can use it to detect the last dive.
The linux USB CDC-ACM driver, which is used by the Mares Icon HD
interface, doesn't support the ioctl's to configure a custom baudrate.
But since the actual baudrate doesn't seem to matter at all, we revert
back to the nearest standard baudrate.
Because custom baudrates are confirmed to be supported on Windows and
Mac OS X, those platforms can keep using the non-standard baudrate.
We received data from an Icon HD Net Ready with a model code equal to
0xFF, which is an invalid value. Fortunately we can figure out the
correct model code from the data in the version packet.
Correctly skip the 4 byte length in front of the sample data. The
previous code happened to work by accident, because the header after the
sample data was assumed to be 4 bytes larger, and thus those two errors
cancelled each other out.
With the support for custom baudrates on all systems, there is no need
anymore to use the nearest standard baudrate. Using the exact baudrate
should make the communication more reliable on Unix systems.
With the knowledge of the end of profile pointer and the number of
samples, the ringbuffer can be traversed backwards and the start of the
ringbuffer doesn't have to be fixed anymore.
Note that this implementation will fail if the ringbuffer doesn't start
at the fixed address 0xA000. This is very likely to occur once the
ringbuffer is filled completely and the device starts to overwrite old
data.