bluekitchen / btstack

Dual-mode Bluetooth stack, with small memory footprint.
http://bluekitchen-gmbh.com
Other
1.68k stars 605 forks source link

Classic HID host: unreliable pairing to some Android devices #607

Closed Slion closed 2 months ago

Slion commented 2 months ago

Pico W SDK 1.5.1

Various Android devices are pairing successfully and auto reconnect just fine through Interface, no issue for instance on Huawei P30 Pro (Android 10), HONOR Magic V2 (Android 14) or F(x)tec Pro¹ (Android 11).

However neither Samsung Galaxy Tab S6 (Android 12) nor Tab S8 Ultra (Android 14) could be paired through Interface. Both tablets exhibited slightly different behaviour. The S6 would not show a pairing confirmation prompt but it would still connect without pairing. The S8 would show a pairing confirmation and would connect successfully even though pairing actually failed. Both tablets having failed to pair with the Pico W are not able to auto reconnect once the connection is lost.

If I go through Android system Bluetooth settings to initiate the pairing it eventually succeeds. On both tablets, the first pairing attempt fails but a second attempt, shortly after the first one, hangs for a suspiciously long time and then succeeds. However at least the S8 still manages to lose the pairing after all and eventually keeps prompting to confirm pairing. Trying to pair from Honor Magic V2 Android Bluetooth settings also fails so I guess you are not suppose to do that, you need BluetoothHidDevice to be up and running.


Can the HID host somehow request different kind of pairing method? Thus I could try different ones see if some work better than others.

I'm getting those logs as usual:

16:52:24:087 -> SSP User Confirmation Request with numeric value '879295'
16:52:24:092 -> SSP User Confirmation Auto accept

When the host initiate the connection it fails straight away with L2CAP_CONNECTION_RESPONSE_RESULT_REFUSED_SECURITY. That seems to be the case for all Android devices running BluetoothHidDevice or not.

Came across raspberrypi/pico-sdk#1457 so I reset the flash but it did not help.

Slion commented 2 months ago

Could you send me 3 more logs where pairing fails for you?

I'm afraid not, it looks like they all succeed today 🥳 I modified the Android app Bluetooth menu to make it clear when the bonding actually worked. Maybe I was seeing false negative yesterday cause the Android Bluetooth settings don't always show the newly bond devices immediately. 3-tries-100%-success.zip

mringwal commented 2 months ago

I was able to identify a bug in the key distribution, which was responsible for the incorrect behaviour in the "S8 dc3e24965" case.

While comparing the behaviour of iOS and Android, I've realized that for both OS, the device in Central Role at the time of the Encryption Change event initiates the CTKD. That's great as BTstack didn't use the current role at this point and it's easy to do so - without implementing any work arounds. Please try the version on develop.

I'm closing this issue as CTKD works even if there are role changes for iOS and Android. Feel free to open a new issue if needed.

Slion commented 2 months ago

Please try the version on develop.

One quick try and it works great so far.

I was able to identify a bug in the key distribution

Awesome work, thank you.

Also the Bluetooth stack on the tablet is somehow messed up after that failed pairing, discovery ain't working until I turn Bluetooth off and back on.

That's still an issue apparently but out of the scope of this ticket and possibly not worth investigating anyway. Also somehow it fixes itself after a few minutes.

Slion commented 2 months ago

Shall I keep using ENABLE_CROSS_TRANSPORT_KEY_DERIVATION and ENABLE_LE_SECURE_CONNECTIONS knowing that I still want to support both BLE and Classic? I only defined them when I started investigating that issue. They were not defined in the HID example.

mringwal commented 2 months ago

Yes. If the other side supports CTKD it's tricky (= I haven't figured it out yet) how to properly avoid it. If the peer starts it and we don't support it, the pairing fails.