IanHarvey / bluepy

Python interface to Bluetooth LE on Linux
Other
1.59k stars 491 forks source link

Authenticating a Connection (SensorBug) #381

Closed shadetree01010100 closed 4 years ago

shadetree01010100 commented 4 years ago

I've been using this library for a few years now, mostly with the TI SensorTag, and have recently picked up a SensorBug from BLEHome, hoping to migrate to this hardware. I was unable to find any real Python implementations, so I set out to make my own implementation of the Peripheral class, and of course it's been easy to get as far as I am.

The device manual is here: http://www.blehome.com/SensorBug%20Interface%20Specification%20v1.3.0.0a.pdf

I am currently blocked by my inability to authenticate to the device. While I can read the advertising data, of course, and even connect to the device, it does not recognize my connection as "authenticated". I am testing this by referencing section "5.10 BR Pairing Management Service" of the above manual (page 39). The Control/Status characteristic (5.10.1.1) requires no auth to read, and therefore characteristic.read() is successful:

b'\x00\x00\xff\xff\xff\xff\xff\xff\x00\x00\x00\x08\x00' According to 5.10.1.2, this decodes as below, bold emphasis added to suspicious values:

The Data characteristic (5.10.2), by contrast, does require at least User auth (5.10.2.1), and when I call read() it blocks indefinitely. I see similar behavior when trying to read it using bluetoothctl on my Raspberry Pi 3B. It seems that without authenticating, trying to read anything without the proper auth causes this behavior.

So I'm missing a step: I need to gain authentication to the device.

After fooling around in bluetoothctl for a while, without any new results, I tried connecting my Android phone to the SensorBug and it paired without issue (note that there is only an iOS app from the manufacturer for this device). I put the SensorBug back into pairing mode (button press), my restarted Python application picked it up, and suddenly things changed!

For the first time, the SensorBug's advertising (manufacturer-specific, static data) now included a Config Counter value of 1 (from 0), and the Control/Status characteristic contained new data: b'\x00\x00\xff\xff\xff\xff\xff\xff\x10\x00\x01\x08\x00'

As explained in 4.1.3.4.2, the Config Counter "value will increments each time the device’s configuration is changed and rolls over automatically from 255 to 1 ... if theAccel Config, Light Config, or Temp Config characteristic values change, this value will be incremented."

In the Manufactuer-specific section of the advertised data, there is now temperature data. From random blog posts using this sensor for temp data, I think this is expected: once paired to any device the SensorBug will (by default) begin advertising temp data.

While my Pi is still not authenticated, the phone was apparently successful, from which I infer it must have authenticated to at least User level. More likely Admin level since that is the required level to enable sensors. I didn't have to enter a code or anything, my understanding is that both the Pi and SensorBug are BLE 4.1 and should Just Work ™

I'm stumped, what is my phone doing that my Pi isn't, and how can I implement that?

shadetree01010100 commented 4 years ago

I forgot to update this, so here we go. The SensorBug's firmware will only authenticate iOS and Android devices to Admin. I tried a few different ways to trick it into authenticating my Pi, and was not successful. Ultimately, since the manufacturer designed it this way, it is not suitable for my application.

I hope this note helps any future readers trying to do something similar. Cheers.