# freefit (also known as: FereFit, Lyne_Wearables, HomieFit, zwsvibe, WIRCASS) Reverse-engineering a sketchy Chinese watch app Documentation/protocols derived from decompiled FereFit Android app (jadx) (com.czw.freefit, SHENZHEN ZHONGWEI INTELLIGENT TECHNOLOGY Co.,Ltd) ## BLE characteristics ### Main characteristics (presumably Nordic UART/Nordic semiconductor chips) - Service UUID: 6E40FC00-B5A3-F393-E0A9-E50E24DCCA9E - Write characteristic UUID: 6E40FC20-B5A3-F393-E0A9-E50E24DCCA9E - Notify characteristic UUID: 6E40FC21-B5A3-F393-E0A9-E50E24DCCA9E ### Jieli/JL chip characteristics (untested) - Service UUID: 0000ae00-0000-1000-8000-00805f9b34fb - Write characteristic UUID: 0000ae01-0000-1000-8000-00805f9b34fb - Notify characteristic UUID: 0000ae02-0000-1000-8000-00805f9b34fb ## Protocols/functions ### Battery status/notification (read/6E40FC21) Sent by watch if command is invalid. TODO find proper trigger for this byte[0] = 0x94 (BATTERY command/response) byte[1] = battery percentage (0-100) ### syncTime Time sync packet structure (write/6E40FC20) byte[0] = 0x01 (command) byte[1-4] = Unix timestamp (big endian, seconds) byte[5-8] = timezone offset (big endian, seconds) byte[9] = i (unknown param, use 0x00) byte[10] = language code byte[11] = 0x01 if traditional Chinese, else 0x00 Response: 0x81 0x00 (success, notify/6E40FC21) ### enterMakeDial (watch face) Watch face header packet (write/6E40FC20) byte[0] = 0xE4 (ZK_DIAL command) byte[1] = 0x51 (mode flag) byte[2] = 0x01 (start) byte[3] = 0x00 byte[4-5] = total packet count (big endian) byte[6-9] = total image bytes (big endian) byte[10] = 0x00 byte[11-12] = MTU size (big endian) byte[13] = rotation flag byte[14] = 0x01 byte[15] = time text direction byte[16] = 0x00 byte[17-18] = transparent color (RGB565) byte[19-20] = checksum (sum of all image bytes, big endian) byte[21] = show date (0x01 = yes, 0x00 = no) Header packet is followed by chunked RGB565 data, 1 chunk = MTU-14 bytes