I'm hoping to add a new bluetooth dive computer to libdivecomputer. I've spent a fair amount of time reverse engineering the sync protocol between it and the android app that it uses, and have a general idea of how it communicates.
I'm primarily on a mac - looking at the source for it, when I do my normal configure operation it claims:
Transports:
Serial : yes
USB : yes
USBHID : yes
IrDA : no
Bluetooth : no
BLE : no
It looks like it uses bluez or windows bluetooth apis - is there something I need to do to get it to work with bluetooth on OS X? I can work on an older linux machine as well - but it will take a bit longer to get it set up to do development on.
Ryan
On 6/05/2021 00:36, Ryan Gardner wrote:
I'm hoping to add a new bluetooth dive computer to libdivecomputer. I've spent a fair amount of time reverse engineering the sync protocol between it and the android app that it uses, and have a general idea of how it communicates.
I'm primarily on a mac - looking at the source for it, when I do my normal configure operation it claims:
Transports:
Serial: yes USB : yes USBHID: yes IrDA: no Bluetooth : no BLE : no
It looks like it uses bluez or windows bluetooth apis - is there something I need to do to get it to work with bluetooth on OS X? I can work on an older linux machine as well - but it will take a bit longer to get it set up to do development on.
That's correct. Unfortunately libdivecomputer does not have a built-in bluetooth transport on Mac. That's mainly because I'm not a Mac developer. I simply do not have any experience with the Mac apis to write such a transport. For other transports this wasn't a problem because the api is standard unix (serial) or there are cross-platform libraries available (usb and usbhid).
Applications can always use a custom I/O implementation to work around this limitation. That means implementing the low-level communication in the application (using the native api for your platform), and wrap it inside a libdivecomputer transport using dc_custom_open.
Does Mac supports serial port emulation? Because in that case you could also use the serial transport, and let the OS take care of the bluetooth part.
Jef
Thanks for the info. I'm not an expert mac developer either - so I switched to using a linux box for what I'm trying to do. (A raspberry pi with built in bluetooth is acting in that role now)
The device I'm working on uses BLE - it looks like the configure.ac always marks the bluetooth_le transport as being unsupported.
What do you think is the easiest way to test / debug adding a new BLE device? I was hoping to use the simple dctool as a way to test things as I implemented it - but maybe there's a better approach? Do I need to build my own simple test app that sets up the ble connection and then hands things over to libdivecomputer?
On Thu, May 6, 2021 at 4:32 AM Jef Driesen jef@libdivecomputer.org wrote:
On 6/05/2021 00:36, Ryan Gardner wrote:
I'm hoping to add a new bluetooth dive computer to libdivecomputer. I've
spent a
fair amount of time reverse engineering the sync protocol between it and
the
android app that it uses, and have a general idea of how it communicates.
I'm primarily on a mac - looking at the source for it, when I do my
normal
configure operation it claims:
Transports:
Serial: yes USB : yes USBHID: yes IrDA: no Bluetooth : no BLE : no
It looks like it uses bluez or windows bluetooth apis - is there
something I
need to do to get it to work with bluetooth on OS X? I can work on an
older
linux machine as well - but it will take a bit longer to get it set up
to do
development on.
That's correct. Unfortunately libdivecomputer does not have a built-in bluetooth transport on Mac. That's mainly because I'm not a Mac developer. I simply do not have any experience with the Mac apis to write such a transport. For other transports this wasn't a problem because the api is standard unix (serial) or there are cross-platform libraries available (usb and usbhid).
Applications can always use a custom I/O implementation to work around this limitation. That means implementing the low-level communication in the application (using the native api for your platform), and wrap it inside a libdivecomputer transport using dc_custom_open.
Does Mac supports serial port emulation? Because in that case you could also use the serial transport, and let the OS take care of the bluetooth part.
Jef
On Thu, May 6, 2021, 07:43 Ryan Gardner ryebrye@gmail.com wrote:
What do you think is the easiest way to test / debug adding a new BLE device? I was hoping to use the simple dctool as a way to test things as I implemented it - but maybe there's a better approach? Do I need to build my own simple test app that sets up the ble connection and then hands things over to libdivecomputer?
Most of the libdivecomputer BLE code has been developer using Subsurface (and a lot of BLE packet traces).
It's not some small convenient simple test app, but it does work.
I've done everything on Linux, but Mac should work too at that point - although Mac had it's own BLE headaches.
Linus
Hi Linus,
Thanks for the suggestion.
I actually started out using subsurface as a test app - I actually started out by reading through all of your commits on the deepblu cosmiq to get an idea of what's required to add a new BLE computer - I did get subsurface to see the computer and initiate the pairing (the icon on the sync screen on the dive computer switches to the plugs being connected) - so the BLE part worked, and it's just the communication part that will take me a lot of iterations to work through.
I ran into a few issues that are entirely my fault and not the fault of subsurface - namely I couldn't figure out a way to get my IDE to launch the built subsurface app and attach to it and hit breakpoints inside of libdivecomputer (again - totally my "not normally a c/c++ application developer" problem) - but after spinning my wheels for a while I figured I'd try to see if the dctool from libdivecomputer could be a faster path to "can I get code to communicate with this thing?"
Some of the notes I was working through are up here: https://github.com/ryangardner/excursion-decompiling/blob/master/Protocol%20... (it's a combination of examining a decompiled android app that syncs with the computer and the captured hci packet logs, looking at how the android app parses the responses / communicates with the computer and comparing it with the hci logs)
I can take another stab at the subsurface route. (or some of the suggestions that Jef replied to after this - replaying communications logs etc). (and I can take basic subsurface build questions over to their list or irc channel if I get really stuck)
On Thu, May 6, 2021 at 11:00 AM Linus Torvalds torvalds@linuxfoundation.org wrote:
On Thu, May 6, 2021, 07:43 Ryan Gardner ryebrye@gmail.com wrote:
What do you think is the easiest way to test / debug adding a new BLE device? I was hoping to use the simple dctool as a way to test things as I implemented it - but maybe there's a better approach? Do I need to build my own simple test app that sets up the ble connection and then hands things over to libdivecomputer?
Most of the libdivecomputer BLE code has been developer using Subsurface (and a lot of BLE packet traces).
It's not some small convenient simple test app, but it does work.
I've done everything on Linux, but Mac should work too at that point - although Mac had it's own BLE headaches.
Linus
On Thu, May 6, 2021 at 8:43 AM Ryan Gardner ryebrye@gmail.com wrote:
I ran into a few issues that are entirely my fault and not the fault of subsurface - namely I couldn't figure out a way to get my IDE to launch the built subsurface app and attach to it and hit breakpoints inside of libdivecomputer (again - totally my "not normally a c/c++ application developer" problem) - but after spinning my wheels for a while I figured I'd try to see if the dctool from libdivecomputer could be a faster path to "can I get code to communicate with this thing?"
Yeah, I have worked almost entirely from just BLE packet dumps, and just the debug output (both the subsurface debug output and the libdivecomputer logs).
One thing to look out for is to make sure that it all works with some other dive computer if you have one available - just to check that everything works.
The fact that you pair is already a good sign, but usually the pain point is the initial connection, and sometimes it's the GATT descriptors that aren't set up the way most other serial emulation things are.
It's all non-standard. As you may have noticed if you've been looking at the subsurface core/qt-ble.cpp file. We have a number of "we know this dive computer uses this BLE GATT service UUID for rx/tx", with default fallbacks for the common situation.
Worst case, some dive computers want to do flow control. So far we've only seen one that does that (the magic "terminal IO" stuff for the OSTC), but if that's the case things can get quite nasty.
You do seem to have the proper packet logs, so you're probably aware of all this already.
Linus
On 6/05/2021 16:43, Ryan Gardner wrote:
Thanks for the info. I'm not an expert mac developer either - so I switched to using a linux box for what I'm trying to do. (A raspberry pi with built in bluetooth is acting in that role now)
The device I'm working on uses BLE - it looks like the configure.ac configure.ac always marks the bluetooth_le transport as being unsupported.
For BLE there is no implementation for any of the supported platforms.
What do you think is the easiest way to test / debug adding a new BLE device? I was hoping to use the simple dctool as a way to test things as I implemented it
- but maybe there's a better approach? Do I need to build my own simple test app
that sets up the ble connection and then hands things over to libdivecomputer?
I also mainly use dctool for development and debugging. But for testing the actual BLE communication, you'll need a host application like subsurface so you can use their BLE implementation.
If you have some capture files, you can also simulate and replay the communication. I have a small tool to replay libdivecomputer logs (after some postprocessing) over pty's. So if you can easily extract the actual I/O data from the capture files, that may also be an option. It's certainly not for everything, but it can help to try things without any hardware.
There is also a simulator to simulate the device end of the communication. But that's mainly useful afterwards, because it also needs to be implemented of course.
Jef