Even after removing the pages padded with 0xFF bytes, there are still
some invalid sample pages present at the end of the profile. But it
turns out the number of valid profile pages is stored in the logbook
entry.
The only caveat is that the number of pages appears to be stored as a 12
bit number, which limits the total profile size to only 64Kb. We don't
known what happens for larger dives.
The libusb and hidapi pkg-config files already add the subdirectory to
the header search path with:
-I/usr/include/libusb-1.0
-I/usr/include/hidapi
Therefore, using the subdirectory in the include statement is wrong. In
practice, this usualy works fine by accident, because the base directory
(/usr/include) is typically listed in the default search path of the
compiler. But that's not always true. For example when cross-compiling
or when using the PKG_CONFIG_LIBDIR environment variable.
The Smart Air uses almost the same data format as the Quad Air. Only the
4 bytes containing the dive mode and number of samples moved from the
beginning of the header to the end. This is a change adopted from the
regular Smart.
For older OSTC dives, using logbook format version 0x20, the average
depth is not available in the dive header. It's only available since
version 0x21, which increased the header size from 47 to 57 bytes.
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.
The memcpy and related functions expects a valid pointer, even if the
size is zero. Most libc implementations will handle a NULL pointer just
fine, but that's not guaranteed.
Simply skip the call when there is nothing to copy.
In the error handling code, the dc_buffer_free() function can be called
with an unitialized "buffer" variable as parameter. Fixed by adding an
extra label.
Reported-By: Linus Torvalds <torvalds@linux-foundation.org>
On Windows, the WSAStartup() function needs to be called, to initialize
the socket library, before using any of the other WSA socket functions.
This includes the functions used for the bluetooth device discovery.
The Mac OS X timer implementation returned timestamps with nanoseconds
as unit instead of microseconds.
Reported-by: Rick Balsano <rick.balsano@gmail.com>
The Scubapro LogTrak application doesn't send the handshake commands for
BLE communication. Also the Aladin Sport Matrix, which supports only
BLE, responds with a 0x01 byte instead of the expected 0x01 byte and
that causes the handshaking to fail. Thus simply omit the handshaking
for BLE communication.
Reported-by: Berthold Stöger <berthold.stoeger@tuwien.ac.at>
The Uwatec Smart, Meridian and G2 backends are almost identical, except
for the low-level packet sending and receiving code. With the new I/O
layer, those three backends can easily be unified in a single backend.
The Meridian and G2 are completely removed, only the family types are
kept for backwards compatibility.
The Aladin Tec (and Tec 2G) sample descriptor table supports up to two
event bytes, but there is only a single event descriptor. This missing
descriptor causes a fatal error during parsing. Add a dummy descriptor
to avoid the error.
Instead of reading data packets, the code is actually sending some
random data to the dive computer! A small typo with bad consequences!
This is a critical bug because it not only causes the download to fail,
but also appears to change random settings on the dive computer. I
suspect that the garbage data that gets send to the dive computer
happens to contain some valid write settings commands.
For most I/O stream implementations the serial communication specific
functions are meaningless. Implementing them as no-ops allows the dive
computer backends the call the I/O stream functions unconditionally.
However, implementing the no-op with a dummy function returning
DC_STATUS_SUCCESS, does not only add some (small) overhead at runtime,
but also requires many such functions. This is inconvenient and the same
result can easily be obtained by using a NULL pointer instead.
The consequence is that the logic is reversed now. To obtain the
previous behaviour of returning the DC_STATUS_UNSUPPORTED error code
again, you'll need to implement a dummy function. But that's fine
because it's the less common case.
I/O functions with output parameters, should always initialize those
output parameters, even when an error is returned. This prevents the
(accidental) use of uninitialized variables, whenever the caller forgets
to check the return code.
As a nice side effect, the use of a local variable guarantees that the
underlying I/O implementation will always receive a valid pointer.
When two or more identical (or very similar) dive computers are
connected, the USB VID/PID can be ambiguous. That's because the VID/PID
identifies the type of the USB device, and not the individual device.
But each USB HID device descriptor returned by the device discovery
represents a single connected device, and thus guarantees to open the
correct USB device.
To obtain the same behaviour as before, an application can simply open
the first discovered device.
Replace the global USB library context with a reference counted session
to manage the lifetime of the USB library context. For the libusb based
implementation, this is actually a much better match for the underlying
libusb api, and allows to eliminate the global state. For the hidapi
based implementation, the global state is unavoidable because the hidapi
doesn't support multiple sessions. Therefore we use a singleton session.
The main difference with the serial communication is that the BLE
communication transmits each SLIP encoded data packet as one or more BLE
data packets. The BLE packets have an extra two byte header with the
total number of packets and the current packet number.
The main difference with the serial communication is that the BLE
communication uses data packets (with a maximum size of 20 bytes)
instead of a continuous data stream.
The main difference with the USB HID communication is that the BLE data
packets have a variable size and are no longer padded to the full 32
(Tx) or 64 (Rx) bytes.
The main difference with the USB HID communication is that the BLE data
stream is encoded using HDLC framing with a 32 bit CRC checksum. Due to
this encoding, the data packets can no longer be processed one by one
(as is done for the USB HID packets). The entire HDLC encoded stream
needs to be received before it can be processed. This requires some
additional buffering.
Setting a default transport type avoids the need to explicitely set a
transport using the the new --transport command-line option. This also
preserves backwards compatibility with previous versions where the
option didn't exist yet.
The dctool example application is updated to the latest changes:
- The I/O stream is opened and closed by the application.
- A new (mandatory) option is added to select the desired transport
type. This is nessecary because several dive computers support
multiple transport types now.