Bluetooth & GATT pipe¶
Each half is an independent BLE peripheral: HID over GATT + a custom service. The host merges the two streams; there is no inter-half radio.
Stack facts¶
- SoC: Nordic nRF52811 (coded-PHY evidence), Bluetooth 5.4, 1M/2M/125k, up to +9 dBm. No proprietary radio.
- Separate BLE FW v0.2.29 (
be/100f→00 02 1d— not battery). - BLE-side commands: see
BEin the command map (pair addr, unpair, slots, dongle addr, CLEAR ALL SPLIT LINKS). - USB serials double as device IDs (per-device values, private — not reproduced here).
GATT map (confirmed, bonded via nRF Connect)¶
0x1800Generic Access,0x1801Attribute,0x180FBattery (0x2A19NOTIFY — ticks 89–92%),0x180ADevice Info (Model/Manufacturer/PnP),0x1812HID over GATT (standard keyboard/mouse/consumer reports),0x1234custom service, single characteristic0x5678[Notify, Read, Write] + CCCD.
Pipe 0x1234/0x5678 verdict: NOT an input stream¶
- Unbonded READ → static byte
0x65. Unbonded WRITEs accepted, no effect. - Bonded: CCCD subscribe succeeds, but zero notifications arrive during trackball/module activity (~16 s window) while battery notifications keep flowing in the same window (subscription path OK).
- Trackball/touch input reaches the host exclusively via standard HID reports (Report ID 3 = mouse).
The pipe is most likely a host-initiated command/control channel
(pairing, config, module DFU?) — phone→keyboard, not keyboard→phone.
Bonded READ stays static 0x65 ("e"); value never changes, nothing
notifies — the pipe is idle in normal use.
Open micro-steps¶
- Bonded READ of DIS
0x180Astrings (free info). - Careful bonded WRITE probes (small, observed) — deferred, needs a wedge-recovery plan first.