- 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
CircuitPython version
Code/REPL
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
Additional information
btmon.log