Skip to content
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

BLE can't pair to new host after initial pairing #1817

Open
Kakiharu opened this issue Nov 14, 2023 · 3 comments
Open

BLE can't pair to new host after initial pairing #1817

Kakiharu opened this issue Nov 14, 2023 · 3 comments
Assignees

Comments

@Kakiharu
Copy link

Kakiharu commented Nov 14, 2023

After messing around with the auruino-pico I thought I was doing something weird, however I found that if you pair it everything will work as intended. But if you unpair it from the same device and try to pair with something else it completely stops outputting. You have to turn off the pico unpair then turn it on and pair to the new device. I figure this is not a intended function. I tried this on multiple versions. They basic code I was using to find that out is as follows:

#include <KeyboardBLE.h>

const int pin = 2; // GPIO pin number
char key = 'w'; // Key to send

void setup() {
  pinMode(pin, INPUT_PULLUP);
  KeyboardBLE.begin();
}

void loop() {
  if (digitalRead(pin) == LOW) {
    KeyboardBLE.write(key);
    delay(1000); // Add a delay to avoid key spamming
  }
}

Edit: It's almost like it needs to not be paired to anything when you turn it off if you are switching devices. It also happens if it is already connected to the pc and you update the firmware when it reboots it will auto reconnect to the what it was paired to and will not function until you unpair, then turn it off then back on and re-pair it.

@earlephilhower
Copy link
Owner

Interesting observation, thanks for testing and giving a succinct explanation.

What has me scratching my head is this:

...It also happens if it is already connected to the pc and you update the firmware when it reboots it will auto reconnect ...

The BLE pairing information is actually part of the application binary, so when you flash a new app it gets cleared out. So there are no shared keys available immediately after flashing. No comms would then be possible, I imagine. Maybe the PC is assuming the same BLE MAC already has the key and not negotiating a new one...

@earlephilhower earlephilhower self-assigned this Nov 15, 2023
@earlephilhower
Copy link
Owner

This is a very good issue. Found several things already:

  • Infinite loop if there's data to send but no connection
  • TLV storage is busted. Tries to write a 1-byte boundaries while the flash SDK only supports 256byte alignment. The SDK fixed it, but I copied an older version of their file which didn't have this fix.

That was just looking during lunch. Let me implement some fixes for these two and see if that clears things up. The TLV alignment might explain why only the 1st connection works...the 2nd and subsequent ones would not be stored properly...

earlephilhower added a commit that referenced this issue Nov 21, 2023
If the BLE connection is severed, don't wait for the needToSend
flag to clear in the HID::send routine since it may never actually
clear unless the BLE connection is restored.

Partial #1817
earlephilhower added a commit that referenced this issue Nov 21, 2023
If the BLE connection is severed, don't wait for the needToSend
flag to clear in the HID::send routine since it may never actually
clear unless the BLE connection is restored.

Partial #1817
@earlephilhower
Copy link
Owner

earlephilhower commented Nov 22, 2023

Did some digging around and it looks like this is a BTstack internal thing, and only occurs in BLE mode.

Ths following classic BT sketch pairs with multiple computers in a row without incident:

#include <KeyboardBT.h>

void setup() {
  KeyboardBT.begin();
}

void loop() {
  if (BOOTSEL) {
    KeyboardBT.write('w');
    while (BOOTSEL) delay(100);
  }
}

Only the BLE version has an issue:

#include <KeyboardBLE.h>

void setup() {
  KeyboardBLE.begin();
}

void loop() {
  if (BOOTSEL) {
    KeyboardBLE.write('w');
    while (BOOTSEL) delay(100);
  }
}

Tracing the callbacks shows that BTStack is not calling us with a "new connection handle" event after negotiating with a new BLE host after the initial connection.

case HCI_EVENT_HIDS_META:
switch (hci_event_hids_meta_get_subevent_code(packet)) {
case HIDS_SUBEVENT_INPUT_REPORT_ENABLE:
_con_handle = hids_subevent_input_report_enable_get_con_handle(packet);
if (_onOpened) {
_onOpened(type, channel, packet, size);
}
break;

So the core here can't actually send or receive anything and isn't even aware things are connected.

The infinite loop potential has been removed, and the TLV database is actually okay so those two things are not part of the issue here (TLV issues would affect classic BT too).

@earlephilhower earlephilhower changed the title Bluetooth pairing weirdness BLE can't pair to new host after initial pairing Nov 22, 2023
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

No branches or pull requests

2 participants