chore: move firmware skills in-repo + AGENTS.md
- Migrates tactility-firmware and tactility-bluetooth from ~/.hermes/skills/ into .claude/skills/ for repo co-location - Adds AGENTS.md with local workstation context, board table, board-direct build rule, Hermes PYTHONPATH pitfall, common Tactility pitfalls, and in-repo skill index Refs: personal Gitea mirror
This commit is contained in:
@@ -0,0 +1,73 @@
|
||||
# BLE Scan & Reconnect Fixes
|
||||
|
||||
## Problem 1 — Nameless Filter Dropped Bonded Keyboards
|
||||
|
||||
### Location
|
||||
`Platforms/platform-esp32/source/drivers/bluetooth/esp32_ble_scan.cpp:ble_gap_disc_event_handler`
|
||||
|
||||
### Old
|
||||
```cpp
|
||||
if (!found && record.name[0] != '\0' && ctx->scan_count < 64) { store }
|
||||
```
|
||||
|
||||
### Fixed
|
||||
```cpp
|
||||
if (!found && ctx->scan_count < 64) {
|
||||
// Store ALL unique advertisers, not only named
|
||||
// Bonded keyboards (e.g. Fosmon combo) may advertise with only Appearance+flags or directed RPA without name
|
||||
ctx->scan_results[ctx->scan_count]=record;
|
||||
ctx->scan_addrs[ctx->scan_count]=disc.addr;
|
||||
ctx->scan_count++;
|
||||
should_publish = true; // publish even nameless for cache
|
||||
}
|
||||
if (found) {
|
||||
// also update addr_type for RPA rotation
|
||||
ctx->scan_addrs[i]=disc.addr;
|
||||
}
|
||||
```
|
||||
|
||||
### Impact
|
||||
- `getScanResults()` now includes unknowns → UI shows "Unknown (aabbcc...)" entries; useful debug. Can filter weak RSSI later.
|
||||
- `cacheScanAddr()` / `getCachedScanAddrType()` now works for nameless adv, so `hidHostConnect` gets correct type.
|
||||
|
||||
## Problem 2 — Addr Type PUBLIC vs RANDOM
|
||||
|
||||
### Symptom
|
||||
`ble_gap_connect` fails rc=2 BLE_HS_EALREADY or other when using PUBLIC for device that uses RANDOM RPA.
|
||||
|
||||
### Fix in BluetoothHidHost.cpp:hidHostConnect
|
||||
- Lookup cache: log type
|
||||
- Try PUBLIC -> if fail, retry RANDOM
|
||||
- If cached type was RANDOM and both fail, retry PUBLIC
|
||||
- Increase timeout 5000 -> 8000ms
|
||||
- Log final `addr_type`
|
||||
|
||||
## Problem 3 — Single Scan Misses Wake Window
|
||||
|
||||
### Symptom
|
||||
Fosmon sleeps, stops advertising. Wakes on keypress with directed adv ~30s. If Tactility scanned just before wake, misses.
|
||||
|
||||
### Fix
|
||||
Add retry timer:
|
||||
```cpp
|
||||
static esp_timer_handle_t hid_autoconn_retry_timer = nullptr;
|
||||
static void hidAutoConnRetryCb(void*) {
|
||||
if (hidHostIsConnected()) return;
|
||||
if (!bluetooth_is_scanning(dev)) bluetooth_scan_start(dev);
|
||||
}
|
||||
```
|
||||
In autoConnectHidHost() when not found but autoConnect peers exist:
|
||||
```cpp
|
||||
esp_timer_start_once(hid_autoconn_retry_timer, 3*1e6);
|
||||
```
|
||||
Stopped in hidHostConnect() when connecting, and on successful ready chain.
|
||||
|
||||
Also `bt_event_bridge` SCAN_FINISHED already calls autoConnectHidHost, so loop: scan -> not found -> schedule 3s -> scan -> etc.
|
||||
|
||||
### Files Changed
|
||||
- esp32_ble_scan.cpp inclusive cache + addr update
|
||||
- BluetoothHidHost.cpp dual addr fallback + retry timer + logging
|
||||
- No change needed in Bluetooth.cpp bt_event_bridge, but benefits from inclusive cache
|
||||
|
||||
## Remaining TODO
|
||||
- Manual disconnect with autoConnect=true still retriggers immediate rescan (TODO in code "Fix auto reconnect if user manually disconnects"). Could require user to toggle Auto-connect switch off, or add 10s cooldown.
|
||||
Reference in New Issue
Block a user