Limitations & risks
Flashing risks
Section titled “Flashing risks”- A failed full OTA can leave the watch unbootable. No button-only or BLE-only recovery path has been proven for every failure mode. If the app or bootloader never comes back, the realistic recovery options are a NAND dump/programmer or vendor service.
- The bootloader is not part of the AOTA image. The OTA updates app-visible partitions
(
TEMP,res,fonts,res_e,sdfs_k); it does not replace the bootloader. - A charged watch is required. A 54 MB image took roughly 10–30 minutes on the reference unit at BLE MTU 23. A weak battery is an avoidable risk.
- Interrupting the transfer aborts the staging phase. Disconnecting during the data phase aborts the staging; the watch may reboot back to the old image, but that outcome is not guaranteed.
- Factory menus can clear app data. Entering a shutdown/reset option from the factory test
menu cleared pairing state on the reference unit. A stale authkey still produced an
A052reply but noA040; re-pairing fixed it. See Shell / AT channel.
Storage ceiling
Section titled “Storage ceiling”/NAND:E (res_e.bin) is a fixed 58,777,088-byte partition.
- Stock content uses 58,776,014 bytes, leaving only 1,074 bytes free.
- Replacing only
9.ajs(4,795,064 bytes) with the 756,479-byte PoC leaves about 3.85 MiB free. - Full Bad Apple is ~19.7 MB (~18.75 MiB), so it requires deleting other warm-up animations, reducing resolution/fps/frame count, or splitting the clip.
Protocol and access limitations
Section titled “Protocol and access limitations”- No arbitrary file read. The shell and BLE command set expose status/control operations,
not a general NAND read.
album.cfgand user watch faces in/NAND:Ccannot be pulled without a dump or a patched app. - No unlock or privilege escalation. The tools use the normal authenticated app protocol.
- Pairing state matters. The authkey is derived from the pairing exchange and the watch secret. After a reset/re-pair, old state produces misleading acknowledgements.
- Encryption is fixed for this generation. Frame payloads use AES-CBC with a fixed IV and a session key derived from the nonce and authkey. Other firmware may change this.
Unresolved formats and internals
Section titled “Unresolved formats and internals”- ACTH header checksum bytes (
+0x1C,+0x20) and+0x0C = 0x62are not fully explained. .stytype-2+0x18font/style selector encoding is unresolved.album.cfgcontents and the.wfdlheader byte+0x17are not fully mapped.- The six AT group callbacks at
0x101F4D70are not fully identified. - SPP opcodes
0x905E/0x9060/0x9063semantics are only partly understood. 0xA055byte 3 reads7on the reference unit while the public FMC client hardcodes capacity6; side-loaded dials are not reported in the list.
Tested scope
Section titled “Tested scope”- Watch: CMF Watch Pro 2, board
JX402, SoC Actions ATS3089C, firmware1.0.0.73. - Host: Windows 11 with Python 3.12 and Bleak. Bleak is cross-platform, but macOS/Linux BLE behaviour and MTU negotiation were not validated.
- These addresses, UUIDs, keys and layouts apply to the tested scope only. The Pro 3, a different firmware build, or a regional variant may differ; a diff is required before any write.
Ethical and legal limits
Section titled “Ethical and legal limits”- Bypassing account, payment or device-ownership protections is outside the intended use.
- Stock firmware, vendor resources or copyrighted animation frames are not redistributed without the corresponding rights.
- The code is AGPL-3.0 because part of the BLE/watcher behaviour is a port of the AGPL-3.0
freethinkel/fmcproject. See Legal & attribution.