kasparsd / sensor-pilot

Progressive web app for connecting to Bluetooth Low Energy sensors via Web Bluetooth API
https://kasparsd.github.io/sensor-pilot/
52 stars 13 forks source link

NotSupportedError: GATT operation failed for unknown reason. #23

Open ariccio opened 3 years ago

ariccio commented 3 years ago

I can't open my own aranet4 device, and neither can a few other people. We're hitting this error:

NotSupportedError: GATT operation failed for unknown reason.

Any idea what's going on? I want to pair with aranet devices in my own app, but I'd like to experiment with it in your sample first 👍

ariccio commented 3 years ago

FYI, a fix is in the works: https://chromium-review.googlesource.com/c/chromium/src/+/2841104 https://bugs.chromium.org/p/chromium/issues/detail?id=960258#c40

ariccio commented 3 years ago

It's partially working in canary. There's some weird behavior going on and I'm not sure who's at fault yet. When that's resolved, I'll look at a patch!

kasparsd commented 3 years ago

Thanks for keeping this issue updated @ariccio!

Could it be related to the initial pairing request that requires entering a 4-digit code? I only have a browser that is already associated with the device so it doesn't ask to re-pair again.

ariccio commented 3 years ago

You can always "forget"/remove the device from your browser/computer! I know I expect to be doing that like a billion times in development :)

Yes, the whole problem is the 4 (now 6) digit code, as reading from the device is a "Secure characteristic". When I filed the bug, mainline chrome had no way of requesting the code on Windows, Linux, and Android... I dunno why they only built it for OSX. And chromium (despite being some of the highest quality C++ I've ever read) is an immensely complex bit of software. It's way harder that just popping up a dialog.

Now, in the latest canary, on the first pairing attempt, calling the readValue triggers chrome to attempt on-the-fly re-pairing for the secure characteristic (this has to do with Bluetooth Low Energy?), but chrome raises an exception in the promise. I'm not quite sure yet if this is the correct or most reasonable behavior - should the promise wait until the user enters the PIN? should the promise raise a more specific exception? - or whether the best way is to patch this sample code. I'm going to fork and try in a bit!

ariccio commented 3 years ago

Ok, the problem does seem to be that the behavior is just underspecified. I filed a bug with the Web Bluetooth spec.

The most reasonable way that I can think of is ugly and I'm not happy about it, but it works well enough: https://github.com/ariccio/sensor-pilot/commit/767aae4cadd73825ac7d22f724427d5c486c70cd

...that is, to just wait a bit and do a recursive retry. I'll clean it up, and will submit a patch if you're interested.

ariccio commented 3 years ago

We got to the root of the problem. It turns out I was wrong, and the readValue calls need to be serialized.

https://github.com/WebBluetoothCG/web-bluetooth/issues/563#issuecomment-942766637