8000 Bluetooth pairing on a second Linux based machines invalidate the pairing key on the first one · Issue #6626 · adafruit/circuitpython · GitHub
[go: up one dir, main page]

Skip to content

Bluetooth pairing on a second Linux based machines invalidate the pairing key on the first one #6626

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

Open
hyx0329 opened this issue Jul 21, 2022 · 2 comments
Milestone

Comments

@hyx0329
Copy link
hyx0329 commented Jul 21, 2022

CircuitPython version

- Adafruit CircuitPython 7.3.2 on 2022-07-20; MakerDiary nRF52840 MDK USB Dongle with nRF52840
- Customized CircuitPython 7.3.1; MakerDiary M60 Keyboard with nRF52840

Code/REPL

"""
Minimum working example adapted from https://github.com/adafruit/Adafruit_CircuitPython_BLE/blob/main/examples/ble_hid_periph.py
"""

# import board
import sys
import time
import microcontroller

from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keyboard_layout_us import KeyboardLayoutUS

import adafruit_ble
import _bleio
from adafruit_ble.advertising import Advertisement
from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
from adafruit_ble.services.standard.hid import HIDService
from adafruit_ble.services.standard.device_info import DeviceInfoService

# Use default HID descriptor
hid = HIDService()
device_info = DeviceInfoService(
    software_revision=adafruit_ble.__version__, manufacturer="Adafruit Industries"
)
advertisement = ProvideServicesAdvertisement(hid)
advertisement.appearance = 961
# scan_response = Advertisement()  # not used

# ble handle
ble = adafruit_ble.BLERadio()

# prepare mac address pool
cpu_id = list(microcontroller.cpu.uid)
cpu_id_reverse = list(microcontroller.cpu.uid)
cpu_id_reverse.reverse()
mac_pool = bytearray(cpu_id + cpu_id_reverse)

# set bt id
# that's to say:
#   1. stop advertising and drop all existing connections
#   2. change full_name, MAC address
#   3. start advertising
def set_bt_id(bt_id):
    ble.stop_advertising()
    if ble.connected:
        for c in ble.connections:
            c.disconnect()
    # change name
    name = 'PYKB %d' % bt_id
    advertisement.full_name = name
    ble.name = name
    # change mac
    uid = mac_pool[bt_id : bt_id + 6]
    uid[-1] = uid[-1] | 0xC0
    address = _bleio.Address(uid, _bleio.Address.RANDOM_STATIC)
    ble._adapter.address = address
    # log
    print(ble._adapter.address)
    print(ble.name)
    # start advertising
    print("advertising")
    ble.start_advertising(advertisement, timeout=60)  # 60 secs

# set bt id and start the main loop
set_bt_id(0)
k = Keyboard(hid.devices)
kl = KeyboardLayoutUS(k)
while True:
    while not ble.connected:
        pass
    print("Start typing:")
    while ble.connected:
        c = sys.stdin.read(1)
        # change to PYKB #n by entering corresponding number
        if '0' <= c <= '9':
            set_bt_id(int(c))
            continue
        sys.stdout.write(c)
        kl.write(c)
        # print("sleeping")
        time.sleep(0.1)
    if not ble.advertising:
        print('restart advertising')
        ble.start_advertising(advertisement)

Behavior

I'm using a custom bluetooth keyboard based on CircuitPython which can switch to different hosts by changing its bluetooth MAC and full name. The code above is provided as a minimum working example. You can switch to different MAC and full name by entering 0-9 in the REPL. There should be no error.

Recently I encounter the issue that if I use the keyboard on two different Linux setups, after pairing to the second host, the pairing key for the first linux host is replaced/invalidated(my presumption), and the first host won't be able to connect to my keyboard without another manual pairing(connected and then immediately disconnected, see btmon.log). I have to adapt some tricks for dual boot pairing to share keys between two different Linux hosts to work it around.

There may be some bugs in either CircuitPython or Linux's bluetooth implementation(I think it's the latter).

Description

  • Only occurs between my Linux based hosts
  • on iPad, Windows, Android device work as expected
  • tested with 2 Arch Linux hosts, my laptop and my mini PC

Additional information

btmon.log

@hyx0329 hyx0329 added the bug label Jul 21, 2022
@tannewt tannewt added this to the Long term milestone Jul 25, 2022
@mr4s
Copy link
mr4s commented Sep 28, 2022

@hyx0329 I'm interested in taking this on

@hyx0329
Copy link
Author
hyx0329 commented Sep 29, 2022

I'm interested in taking this on

Glad to hear that! I can test the code. Is there any extra information required?

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

No branches or pull requests

3 participants
0