Scubapro Galileo 2 (G2)

Linus Torvalds torvalds at linux-foundation.org
Mon Jun 26 23:37:32 PDT 2017


On Mon, Jun 26, 2017 at 10:06 PM, Jef Driesen <jef at libdivecomputer.org> wrote:
>
> I don't think it's that easy to completely get rid of the serial
> communication stuff. There are several backends that need to change the
> serial line settings and DTR/RTS lines during the communication. That's why
> those functions are present in the abstract I/O interface, even if they only
> apply to serial communication. My reasoning was those functions can be
> implemented as stubs for I/O implementations where they don't make sense.

Yeah, I guess having empty stubs that you can just leave as NULL isn't
that painful.

It's effectively what the current "custom_io_t" does for the serial side.

Pretty much any modern equipment that will do something that looks
serial over a modern line won't be caring about any of the low-level
traditional serial details (ie break, dtr/rts, baud speed, parity
etc).

>> But there is one big difference: the packet sizes are different for
>> BLE than from USB HID.
>>
>> But that *may* be the only real difference. Due to my lack of success
>> in getting BLE working yet, I can't guarantee there aren't other
>> issues.

There definitely are other issues, having now gotten BLE to work with
three different dive computers.

In fact, the last one (Shearwater Perdix) uses BLE in a rather odd
way, and actually avoids some of the packet size limits that way.

Instead of treating the BLE GATT protocol as a way of sending a
packet, the Perdix actually uses it differently, and sends the streams
of data as "descriptor value changes" and let's the GATT protocol
itself actually re-assemble multiple packets into bigger data. So even
though each packet has a payload in the 20-byte range, I see single
updates as multiple packets that then show up in user space as one big
change.

So the 20-byte packet limit doesn't end up being a hard limit, it is
related to a particular choice of BLE GATT interface use.

> If the differences are bigger than just a difference in the packet size,
> then we can probably still deal with that with a minimal amount of transport
> specific knowledge in the backend.

Some of the nastiest differences end up being things that the front
end has to know about.

The one I hit with the Shearwater Perdix was that the way you connect
to it is different than the EON Steel or the Scubapro G2, because the
Perdix ends up using a "Random Device Address" rather than a normal
public address. And while nobody sane should care, they technically
are different address spaces entirely, and the Linux Bluez layer
*does* care. So even though you know the device address, you also have
to know whether to connect to it using the random device address flag
or not.

I have *no* idea why Shearwater did that. But I guess it means that
they don't have to register a company ID for the address.

But it does mean that for BLE GATT, I need to know "does this device
use a random device address or not".

I can make various hacks up (for example, I can just look at the
address and say "I don't recognize the top 24 bits as a company that
makes dive gear, so maybe it's a random address"), but what I think I
will do is to just trigger on the name (ie "Perdix") during bluetooth
scanning, and save away the quirk that "this device needs to be
connected to using the random device address flag".

And since I'm pretty sure that libdivecomputer does *not* want to do
the whole "scan for bluetooth devices" and also does *not* want to
know about things like crazy protocol details that have absolutely no
impact on libdivecomputer anyway, I need the custom IO model to be
able to just add its own information to its own info block.

That's what the "custom_io_t" is meant for, and libdivecomputer
doesn't even need to know about the details.

The older "customserial" protocol made the big mistake of not passing
its own IO data descriptor around, just passing that "fill in this
'void **userdata' thing", and it works as long as you really *just*
look like serial (which rfcomm does).

But immediately when you need to add your own transport quirks in
there, you need something more.

> Take for example again the three uwatec variants: smart (IrDA), meridian
> (usb-serial with some additional framing) and g2 (USB HID and BLE GATT with
> their own packetization). Since the high level parts of the protocol are the
> same, we could implement this as a single backend with some function pointer
> for the transfer function:

That's pretty much what I do for the G2 right now.

Note in particular how I use the "custom_io_t" not only as a way to
pass in the IO function from outside (which, as mentioned, is pretty
much required for BLE - I seriously doubt you want to handle all the
different OS details yourself, when something like Qt has it
reasonably well abstracted)..

I also actually use that "custom_io_t" inside of libdivecomputer
itself, creating a new one dynamically and making it use the USB HID
code that libdivecomputer already has:

        if (io && io->packet_open)
                status = io->packet_open(io, context, name);
        else
                status = dc_usbhid_custom_io(context, 0x2e6c, 0x3201);

in other words, either that code gets passed an IO descrpiptor from
outside, or it just generates its own custom IO descriptor using the
usbhid code and that USB vendor ID.

It should be possible to extend that to other models too (for example,
the non-HID USB transport that the Atomic Cobalt does), but right now
the dive computers I care about are all either BLE or USB HID, so
those are the two things I have worried about.

Anyway, right now that "custom_io_t" only has the packet size as a way
to discriminate with, but that clearly is not sufficient. But neither
is it good enough to say what type it is - it's also not sufficient to
say "USB vs USB HID vs BLE". Because it turns out that within BLE
there are variations, and obviously within USB there are certainly
possibilities for variations way past just the USBHID vs "random
vendor-specific USB" case.

                 Linus


More information about the devel mailing list