# 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_active` atomic in BleCtx prevents simultaneous central connect with name resolution chain `ble_resolve_next_unnamed_peer` (would get BLE_HS_EALREADY) - `getScanResults()` originally filtered nameless → missed directed adv → no auto-connect - `applyReportMapTypes` depth 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 etc` for 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