Skip to content

BLE HID paired connections not working on some Windows 10 peripherals #62

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
dhalbert opened this issue Jan 14, 2020 · 23 comments · Fixed by #63
Closed

BLE HID paired connections not working on some Windows 10 peripherals #62

dhalbert opened this issue Jan 14, 2020 · 23 comments · Fixed by #63

Comments

@dhalbert
Copy link
Collaborator

Copied from adafruit/circuitpython#1050.

@urish:

Windows 10 does see the device (even though not always - I had to remove the scan_response part from the advertising so that it show it on the list of pairable devices), but disconnects about one second after pairing with a "Driver error" message:

image

Android works well

@mscosti:

@urish I'm seeing the same thing as you. At first I thought this was related to changes I have made in an attempt to implement a different HID device incorrectly / missing something (Microsoft Radial Controller / Surface Dial) , But after seeing your report I loaded up this BLE HID Keyboard example verbatim and am seeing the same behavior on Windows 10. Same thing, where it takes a second or two for it to settle with "Driver error".

image

Android Recognizes the keyboard and am able to type on it as expected

@dhalbert
Copy link
Collaborator Author

@dhalbert:

I have been working on BLE bonding over the past couple of weeks (see adafruit/circuitpython#2510), and just tested on Windows 10 with a BLE-capable dongle, and did not have this problem. But it also worked before without bonding. So it may be particular to the Bluetooth hardware on your Windows machine(s).@mscosti and @urish, what is your hardware?

@mscosti:

@dhalbert I'm using a MS Surfacebook 2, which has Bluetooth built in (no dongle)

@dhalbert:

@mscosti hmm, some kind of pairing issue mentioned here: https://social.technet.microsoft.com/Forums/en-US/31e39461-0b8b-4daa-86d0-010f0bd2feed/microsoft-surface-and-ble-issue?forum=win10itprohardware. The OP said it works with a dongle, but not with the builtin Bluetooth hardware. I assume you're up to date on drivers and the latest version of Windows 10, but if not, that might be worth trying.

I did not find many similar reports, but very few people are trying to use BLE HID with Windows. It was only fairly recently it started to be better supported.

@dhalbert
Copy link
Collaborator Author

@mscosti:

The issue mentioned here sounds very similiar to the one I'm experiencing. https://answers.microsoft.com/en-us/windows/forum/all/problem-with-bluetooth-low-energy-gatt-compliant/ec845657-d885-47e8-a796-cd3ff83a7698

Unfortunately, the suggested solution that others confirmed working for them (uninstalling Microsoft Bluetooth LE Enumerator and restarting) did not seem to work for me. @urish , I am curious if this works for you, though.

I'm not sure if its relevant/true/meaningful, but when I look at the device in device manager / HID -> Bluetooth Low Energy Gatt compliant HID device, it says error code 10 in status like in the reported issue above, and the first response says

According to the error code, the cause of the issue: the device's hardware key contains a "FailReasonString" value, and the value string is displays an error message defined by the hardware manufacturer. If the hardware key does not contain a “FailReasonString” value the message above is displayed.

As far as I can tell i'm up to date on my drivers. I have 2 other Bluetooth HID devices (Pen digitizer, granted its a MS device), and a PS4 game pad, both of which are able to pair and function just fine.

@dhalbert:

According to the error code, the cause of the issue: the device's hardware key contains a "FailReasonString" value, and the value string is displays an error message defined by the hardware manufacturer. If the hardware key does not contain a “FailReasonString” value the message above is displayed.

I think that is just saying that it's failing and we didn't supply a reason string ??

As far as I can tell i'm up to date on my drivers. I have 2 other Bluetooth HID devices (Pen digitizer, granted its a MS device), and a PS4 game pad, both of which are able to pair and function just fine.

Are those other devices BLE or classic Bluetooth (it might be hard to tell from the specs)?

@dhalbert
Copy link
Collaborator Author

@mscosti:

hmm. Not sure about the PS4 game pad, I think that's older, but the Surface Pen is listed as using Bluetooth 4.0, and in device manager shows up in HID section as Bluetooth Low Energy GATT compliant HID. So, still not 100% sure, but most likely?

Is there perhaps some arduino BLE HID code I could try on the CPB instead to see if I get the same issue?

@dhalbert:

How about https://github.com/adafruit/Adafruit_nRF52_Arduino/blob/master/libraries/Bluefruit52Lib/examples/Peripheral/hid_keyboard/hid_keyboard.ino ? You'll need to install the Adafruit nRF52 BSP if you haven't already.
image

@dhalbert
Copy link
Collaborator Author

@mscosti asked out-of-band which Bluetooth/BLE dongle is working for me. I am using this one: https://www.adafruit.com/product/1327.

@mscosti
Copy link

mscosti commented Jan 16, 2020

Managed to get another couple datapoints today.

  • Tried the same circuit python BLE keyboard code on a co workers windows machine (different manufacturer, different Bluetooth chipset even) with built in bluetooth and got the same error (driver error)
  • Loaded up the Arduino BLE keyboard demo and was able to successfully connect and have windows recognize and treat it as a keyboard.

image

This rules out my laptop not having BLE support or out of date drivers.

It seems there must be something different with how Arduino and Circuit python BLE libraries are advertising? (my terminology might be wrong, I'm not very familiar with the Bluetooth/BLE protocol). Or, at least different enough where Windows is being finicky in this particular scenario.

@dhalbert Do you have access to a windows 10 machine with BLE built in and so you don't need to use a dongle? I'm getting the feeling that that might be a consistent way to reproduce the issue.

@mscosti
Copy link

mscosti commented Jan 16, 2020

Did a little bit of digging. Used the nRF connect android app to scan so I could log what if any differences there was in advertisement data between the advertisement sent while using this arduino sketch vs using this circuitpython example . I kept the device name the same between the 2 so the 2 could be more easily comparable.

Here are some screenshots of what nRF Connect was seeing.

Arduino Sketch Advertisement (parsed)

image

Arduino Sketch Advertisement (raw data)

0x020106020A040319C103030312180C094D79204B6579626F617264
image

Circuit Python Code Advertisement (parsed)

image

Circuit Python Code Advertisement (raw data)

0x030212180319C1030C094D79204B6579626F617264
image

Looking at the Raw data of each, It seems like the only difference between the two is that the python example code is not sending type 0x01 (flags), and 0x0A (TX power levels), and associated values for those types.

It looks like we are setting the default flags in the Advertisement class here to be General Discoverability and LE Only (brEdrNotSupported) , and I confirmed the field is set to those two on the ProvideServicesAdvertisement Object, but it appears that for some reason it isn't making its way out in the actual Advertisement payload?

My guess is that MS is pickier than most and since it isn't getting those flags it incorrectly makes assumptions about what kind of device it is.

@dhalbert
Copy link
Collaborator Author

dhalbert commented Jan 16, 2020

This is really odd because I did pretty much the same thing as you, and am seeing the flags field (0x01 with value 0x06) in the advertisement. Below is my screenshot. I am using the code below as a test: it's a slightly modified version of examples/ble_hid_periph.py. I'm using https://github.com/adafruit/Adafruit_CircuitPython_BLE/releases/tag/3.1.2 (not 4.0.0). I'm using a very recent build off master of CircuitPython. Do these versions differ from what you are using?

ble_hid_periph.py.txt (renamed to .txt to be able to upload to github)

Screenshot_20200116-000734_nRF Connect

@dhalbert
Copy link
Collaborator Author

dhalbert commented Jan 16, 2020

I am seeing the "no flags" problem with 4.0.0. Will investigate further.

@mscosti
Copy link

mscosti commented Jan 17, 2020

CIrcuit Python firmware version: 5.0.0 beta 3: https://github.com/adafruit/circuitpython/releases/tag/5.0.0-beta.3

Not 100% sure what version of Circuitpython_BLE i'm on; whatever is the version that came precompiled in this bundle (and used the bundle for 5.x.x): https://github.com/adafruit/Adafruit_CircuitPython_Bundle/releases/tag/20200111

Looking at the releases of CIrcuitpython_BLE though, I would assume it would have to be https://github.com/adafruit/Adafruit_CircuitPython_BLE/releases/tag/3.1.2 since that was the most recent release when that bundle was released?

So I think we might have been on the same versions?

@dhalbert dhalbert transferred this issue from adafruit/circuitpython Jan 17, 2020
@mscosti
Copy link

mscosti commented Jan 17, 2020

ok, so, weird. Used 3.1.2 from the release page of the BLE lib instead of from the bundle and i am getting flags (but sometimes not TX power? maybe a fluke).

I was still getting the same driver issue unfortunately, but on the plus, the devices was showing up in the scans from my laptop much more reliably.

So, maybe the win10 driver issue isn't only advertisement related? I looked into the services data from nRF mobile app that i'm getting from arduino vs CPy and the difference at a glance is that with Cpy i'm seeing an 'unknown' service with a really long UUID that begins with adaf (coincidence, or is it actually adafruit shortened for some reason?). Screenshot below of top level view, I can get more screenshots of the details of the service if that is also useful

Python services after connecting to phone from nRF mobile app
image

Arduino services after connecting to phone from nRF mobile app
image

@dhalbert
Copy link
Collaborator Author

This was a confluence of two separate bugs: see #63. The flags were not included in advertisements, except that if you printed the advertisement (which the code I was using did, for debugging purposes), another bug cause the flags to be included.

@mscosti
Copy link

mscosti commented Jan 17, 2020

That explains why running your code on 3.1.2 had advertisements for me.

Thoughts on above finding about the unknown service?

@dhalbert
Copy link
Collaborator Author

@mscosti if you'd like to test, try PR #63 (you can use https://github.com/dhalbert/Adafruit_CircuitPython_BLE/tree/fix-lazy-advertising-fields, which is my PR branch, if you want).

The CircuitPython boards now advertise an Adafruit-specific service that is the beginning of supporting remote editing via BLE from host computers, such as tablets. You can ignore that. (The ADAF... service ID is a little hint it's an Adafruit service.

@mscosti
Copy link

mscosti commented Jan 17, 2020

Just loaded it up and used my example file that doesn't have the same logging as you.

✅ am now seeing flags and tx power being sent in Advertisement
✅ no issue getting windows to see the device (before would take several reboots of board + luck)
⛔️ My machine running windows 10 still shows driver error after connecting.

Hmmm. Do you think its possible Windows is really picky and not liking the fact that an unknown service (to it) is being sent? Since its an HID profile, it may be expecting to only have known services sent? I'm just making guesses, since its the only visible difference to me between the BLE data being sent from Arduino vs Cpy.

Since you said 'CircuitPython boards' i'm assuming the code for that lives in the firmware itself? If we think its a valid assumption that the adafruit service is causing the issue, would it be possible to get a test build that doesn't send that out?

@dhalbert
Copy link
Collaborator Author

dhalbert commented Jan 17, 2020

Hmm. I'm not sure why it's still complaining. Did you remove the device in Windows before re-pairing? I don't think it should care about the extra service: I wouldn't expect it to give such a low-level error; at worst I'd expect it to refuse to do HID. I'll check among my laptops to see if I have one with builtin BLE.

If you use my example, do you not get an error? Could you post your own code? Never mind, I forgot you were using the Arduino example.

@dhalbert
Copy link
Collaborator Author

Which board are you using? I'll give you a build with it turned off.

@dhalbert
Copy link
Collaborator Author

Also, could you give more details of the exact builtin Bluetooth device by looking it up in Device Manager?

@mscosti
Copy link

mscosti commented Jan 17, 2020

  • Yeah, I have been making sure to remove it before attempting to repair again. and yeah, it does not get an error with the arduino example
  • I'm using the CircuitPlayground Bluefruit
  • I think the name of my Bluetooth device is 'Marvel AVASTAR'. Screenshot dump below, since i'm not sure what is most helpful

image

image

image

@mscosti
Copy link

mscosti commented Jan 17, 2020

Not sure if relevant, but computer OS specs:

  • Windows 10 Pro
  • Version 1909
  • OS version: 18363.535

@dhalbert
Copy link
Collaborator Author

Here are two CPB builds. One is the latest tip of master, the other is the same, but with the ADAF services turned off. Not tested with HID.
cpb-8b6133393.uf2.zip
cpb-8b6133393-dirty-no-adaf-service.uf2.zip

@dhalbert
Copy link
Collaborator Author

This is interesting: https://winbuzzer.com/2019/11/19/microsoft-sends-out-driver-update-for-older-surface-products-xcxwbn/
In particular, there's an update for the Marvell AVASTAR Bluetooth Radio Adapter.

Also zephyr was having trouble re-pairing with the Marvell: zephyrproject-rtos/zephyr#14044.

@mscosti
Copy link

mscosti commented Jan 17, 2020

First, I tried cpb-8b6133393-dirty-no-adaf-service.uf2.zip . I think there might be an issue with the build. After attempting to pair from pc or android, it was hanging and failing, and CPB code crashed. Weird thing is the USB device seemed to also crash and it d/c itself.

Then, I tried the master build cpb-8b6133393.uf2.zip, and, that seems to be working! Must mean that something between beta 3 and master fixed it 🤷‍♂ ? Glad its seems to be fixed in latest, but now I'm just more curious as to what's going on here 😅 Not knowing makes me a little nervous of it popping up again in the future.

When I get some more time i'll try out some more BLE examples, like trying out more HID profiles/reports

@dhalbert
Copy link
Collaborator Author

Then, I tried the master build cpb-8b6133393.uf2.zip, and, that seems to be working! Must mean that something between beta 3 and master fixed it ?

I implemented bonding between beta.3 and master, and changed some internal state-keeping very slightly. The zephyr issue I mentioned above seems to have something to do with connection negotiation, so it may have to do with that rather the the advertisement specifically. But the advertisements definitely were buggy.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants