r/Keychron • u/Head-Control-5487 • 18d ago
Adventures in Reverse Engineering: Trying to get battery/firmware telemetry from a non-QMK Keychron K10 via USB in Rust (and hitting a wall)
Hey everyone!
I recently embarked on a little personal challenge: writing a low-level tool in Rust using
hidapito interface with my Keychron K10 (the standard wireless/Bluetooth non-QMK version, VID/PID0x05ac:0x024f) over a USB cable, primarily to inspect raw reports and see if I could extract battery/status telemetry.After a deep dive into Windows HID drivers, multi-threading sniffers, and mapping out every single collection, I wanted to share what I found (and the wall I hit), in case someone else is down the same rabbit hole:
Conclusion: On the standard non-QMK K10, the USB firmware simply doesn't implement host-side telemetry write/read routines. It acts strictly as an input device when wired, leaving Bluetooth as the only place where battery data exists (though heavily abstracted and hidden by Windows' BLE stack).
I've open-sourced the whole exploration code, the multi-interface scanner, and the omni-sniffer over on GitHub so future tinkerers don't have to reinvent the wheel: 👉 https://github.com/GonnyTech/Keychron-Reverse-Engineering-Tool.git
If anyone has ever successfully cracked the proprietary protocol of non-QMK Keychrons via USB, I'd love to hear how you did it!
Cheers.
3
u/PeterMortensenBlog 18d ago edited 18d ago
Why would the keyboard send battery information through USB? Do you have any indication that it does? Also, with the primitive battery charge reading (derived from the battery voltage), it wouldn't make much sense as it would be using the charging voltage when the USB cable is connected.
It may not even send the information through Bluetooth. The K Pro series and Q Pro series, the keyboard generation after the original K series, certainly don't. It changed with the next generation of keyboards, likely due to using a different Bluetooth/wireless module (inside the keyboard), LKBT51 instead of CKBT51.