On Tue, Jun 20, 2017 at 11:59 PM, Jef Driesen jef@libdivecomputer.org wrote:
You are right that the USB HID packets are vendor specific, and we can't incorporate that in the usbhid code. But that's not really what the I/O refactoring is about. It only handles how those packets are being send/received, not their content.
Ok. That will work. In fact, it's what I'm doing for the BLE support to make USB HID and BLE be real choices.
But it almost certainly has to be integrated with the "custom serial" kind of model that allows the *outside* to set the packet sending details, rather than being something internal to libdivecomputer.
And that's because libdivecomputer almost certainly will never be able to do BLE sanely. Sending packets over GATT a very complex and nasty protocol, not anything like the fairly straightforward "serial line over bluetooth" that rfcomm is.
We're using QtConnectivity in subsurface for BLE (well, in my experimental patches), and while I'm making some progress, we've actually found two major issues in QtConnectivity already exactly because BLE is very complex. And that was after I found some issues in Bluez earlier just to pair the Suunto EON Steel in the first place.
So I do have a set of three patches that does this, and turns the "custom_serial" thing into a "custom_io" thing (that allows both a serial _and_ a packet interface), and lets devices use that.
I then made a simpe helper to say "if no custom IO has been defined, create a custom IO definition for this USB HID device", and converted both the Suunto EON Steel and the Scubapro G2 profile over to that helper.
That actually allows me to feed in a custom packet handling set of routines, and I'm now experimenting with BLE, but am hitting QtConnectivity issues.
You can see my libdvicecomputer work at
git://github.com/torvalds/libdc-for-dirk.git Subsurface-branch
where the top three commits do that packet interface (it needs a subsurface patch to then work with subsurface, which is why those three patches haven't been pushed out to the real repo yet - I'll need to synchronize with Dirk).
NOTE! It should be *trivial* to do the same kind of thing for a serial line as I did for USB HID, ie a dive computer backend that sends "packets" over a serial line could do a very similar "open serial line with these settings" and then create a packet-sending custom_io handler for that. So long-term, I'd actually like to remove the "serial" part of the custom_io struct entirely. But I left it alone for now, just to minimize the churn, and because I really just want to work on the BLE side.
Note: if we're lucky and the Bluetooth Low Energy (BLE) uses the same type of packetization as their USB HID implementation, then we just need to swap the I/O layer, and we're done.
From what I've seen, they are very similar at least for both the EON
Steel and the Scubapro G2.
But there is one big difference: the packet sizes are different for BLE than from USB HID.
USB HID uses 64-byte packets, while BLE uses 32-byte packets but has various other BLE headers.
In fact, I think there's only really 20 bytes of payload per packet in GATT, and that the packetization is entirely different - it looks like BLE over GATT acts more like a "stream" than the very obvious HID packetization that at least the Suunto EON Steel is very obviously very aware of.
So at a minimum, the divecomputer-specific download code needs to know the packetization boundaries, in order to handle that correctly. Which is why my custom_io definition has five fields: one field for the packet size, and four fields for open/close/read/write functions respectively.
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.
Linus