aboutsummaryrefslogtreecommitdiff
path: root/README.md
blob: 321d78fe017998de5b70805c8e8eb0db815a7bf7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# 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/6EFC20)  
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