12035f2f39
- 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
2.3 KiB
2.3 KiB
Combo Keyboard + Touchpad Devices (Fosmon Example)
Device
Fosmon Mini Bluetooth Keyboard QWERTY + Touchpad, Amazon ASIN B00BX0YKX4 Short link from user: https://a.co/d/0fg4vprm → redirects to B00BX0YKX4 Compatible with Apple TV, Fire Stick, PS4/5, HTPC, smartphones — cheap BLE HID.
BLE HID Report Map Structure (typical)
- Top-level Collection 1: Generic Desktop, Usage Keyboard (0x06)
- Report ID 1 (0x85 0x01)
- Input: mod keys, reserved, 6 keys (8 bytes)
- Top-level Collection 2: Generic Desktop, Usage Mouse (0x02)
- Report ID 2 (0x85 0x02)
- Collection Physical → Input: buttons (5 bits + 3 pad), X, Y, Wheel? → 3-4 bytes
- Possibly Consumer (0x0C) for media keys on Report ID 3
Example hex fragments:
05 01 09 06 A1 01 85 01 ... 95 06 75 08 81 00 C0
05 01 09 02 A1 01 85 02 09 01 A1 00 05 09 19 01 29 05 15 00 25 01 75 01 95 05 81 02 75 03 95 01 81 01 05 01 09 30 09 31 09 38 15 81 25 7F 75 08 95 03 81 06 C0 C0
Behavior
- Sleeps after ~5-10 min idle, stops advertising
- Wakes on any key/touch → sends directed advertising to bonded host for ~30s (RPA, often no complete name, only flags + maybe appearance 0x03C1 keyboard or 0x03C2 mouse or 0x03C0 combo)
- Some cheap firmwares use PUBLIC address, others use RANDOM resolvable (RPA rotates every ~15 min)
- After wake, expects central to connect quickly; if missed, sleeps again → need periodic scan retry
Tactility Specifics
hid_host_activeatomic in BleCtx prevents simultaneous central connect with name resolution chainble_resolve_next_unnamed_peer(would get BLE_HS_EALREADY)getScanResults()originally filtered nameless → missed directed adv → no auto-connectapplyReportMapTypesdepth logic only considers depth 0 Collection type; works for Fosmon because collections are top-level, but nested mouse would fail
Testing Checklist
- Pair → verify Report Map log shows
Report val_handle=... reportId=1 type=0/1 etcfor 2 reports - Move touchpad slowly → cursor should move 1-5 px per packet, not jump 200+
- Press keyboard keys → modifier handling (shift) works
- Let KB sleep 10 min → press key → Tactility should scan within 3s and reconnect (log
Auto-connect retry timer fired→Connecting... addr_type=) - Manual Connect from Paired screen with unknown addr_type should try PUBLIC then RANDOM fallback and log rc