feat: auth-failure bond recovery + BlueZ bond import for dual-boot BT
- On Authentication Failure (Auth Complete status!=0 -- previously swallowed silently -- or disconnect reason 0x05), drop the stale local link key so the next connect falls back to fresh SSP pairing instead of failing identically forever (BlueZ behavior). Log the link-key exchange. - scripts/import-bluez-bond.sh: copy a BlueZ link key into the MontaukOS key store on the installed root. Root cause: the AX211 BD_ADDR override (0xFC31) is cosmetic -- the baseband answers pages on the FACTORY address, so peers see Linux and MontaukOS as ONE device with ONE key slot, and each OS's pairing clobbers the other's key. Sharing identity + key ends the fight: both OSes reconnect (incl. autoconnect) without re-pairing. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -12,4 +12,4 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#define MONTAUK_BUILD_NUMBER 29
|
||||
#define MONTAUK_BUILD_NUMBER 31
|
||||
|
||||
@@ -793,6 +793,29 @@ namespace Drivers::USB::Bluetooth::Hci {
|
||||
|
||||
for (int i = 0; i < MAX_CONNECTIONS; i++) {
|
||||
if (g_connections[i].Active && g_connections[i].Handle == handle) {
|
||||
// Reason 0x05 = Authentication Failure: our stored
|
||||
// link key no longer matches the remote's (typical
|
||||
// after another OS's session made the headset evict
|
||||
// or rotate its copy). Keeping the stale key makes
|
||||
// EVERY reconnect fail the same way until the
|
||||
// headset is power-cycled. Do what BlueZ does:
|
||||
// drop the key, so the next connect sends a
|
||||
// negative key reply and falls back to fresh SSP
|
||||
// pairing (Just Works -- fully automated here).
|
||||
// Invalidate only (no disk I/O in this nested
|
||||
// context); the dirty flag gets flushed from
|
||||
// process context.
|
||||
if (reason == 0x05) {
|
||||
int idx = FindBondIndex(g_connections[i].BdAddr);
|
||||
if (idx >= 0) {
|
||||
g_bonds[idx].valid = false;
|
||||
memset(g_bonds[idx].key, 0, 16);
|
||||
g_bondsDirty = true;
|
||||
KernelLogStream(WARNING, "BT-HCI")
|
||||
<< "Auth failure with stored key: bond dropped;"
|
||||
<< " next connect will re-pair";
|
||||
}
|
||||
}
|
||||
g_connections[i].Active = false;
|
||||
break;
|
||||
}
|
||||
@@ -869,11 +892,13 @@ namespace Drivers::USB::Bluetooth::Hci {
|
||||
memcpy(reply, ¶ms[0], 6);
|
||||
memcpy(&reply[6], g_bonds[idx].key, 16);
|
||||
EnqueueHciCmd(OP_LINK_KEY_REQ_REPLY, reply, 22);
|
||||
KernelLogStream(INFO, "BT-HCI") << "Link key request: stored key sent";
|
||||
} else {
|
||||
// Unknown device: tell the controller we have no key so
|
||||
// the remote falls back to fresh Secure Simple Pairing
|
||||
// (Just Works) instead of failing auth (reason 0x05).
|
||||
EnqueueHciCmd(OP_LINK_KEY_REQ_NEG_REPLY, ¶ms[0], 6);
|
||||
KernelLogStream(INFO, "BT-HCI") << "Link key request: no key, will re-pair";
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -900,6 +925,26 @@ namespace Drivers::USB::Bluetooth::Hci {
|
||||
if (evtParamLen >= 3 && params[0] == 0) {
|
||||
uint8_t enc[3] = { params[1], params[2], 0x01 };
|
||||
EnqueueHciCmd(OP_SET_CONN_ENCRYPT, enc, 3);
|
||||
} else if (evtParamLen >= 3) {
|
||||
// Failed authentication was previously swallowed silently.
|
||||
// Drop the stale bond here too (the remote may not follow
|
||||
// up with a reason-5 disconnect on every firmware).
|
||||
KernelLogStream(WARNING, "BT-HCI") << "Authentication failed, status="
|
||||
<< (uint64_t)params[0];
|
||||
uint16_t handle = (uint16_t)params[1] | ((uint16_t)params[2] << 8);
|
||||
for (int i = 0; i < MAX_CONNECTIONS; i++) {
|
||||
if (g_connections[i].Active && g_connections[i].Handle == handle) {
|
||||
int idx = FindBondIndex(g_connections[i].BdAddr);
|
||||
if (idx >= 0) {
|
||||
g_bonds[idx].valid = false;
|
||||
memset(g_bonds[idx].key, 0, 16);
|
||||
g_bondsDirty = true;
|
||||
KernelLogStream(WARNING, "BT-HCI")
|
||||
<< "Stale bond dropped; next connect will re-pair";
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user