-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathREADME.protocol.txt
392 lines (330 loc) · 13.7 KB
/
README.protocol.txt
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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
The communication protocol between the S710 and the IR dongle is somewhat
obfuscated, but not difficult to understand (NOTE: for USB communications
details, see README.usb in this directory).
Communication takes place by requests from the computer leading to responses
from the watch. The watch does not send data without it being requested by
the computer. Data is sent in packets which have a maximum size of around
1 KB. The watch has a memory capacity of 32 KB.
1) Byte mapping
If the watch is not present, the dongle echoes characters sent to it, but the
echo is not exactly right. Sending a 0x00 results in a 0xff response from the
dongle, sending a 0x01 gets a 0xfc, and so forth. Each byte sent maps to a
unique response byte. The mapping 'M' can be generated by shuffling the bits
of the transmitted byte 'B' as follows:
M = (((B + 0x100 - (1<<6)) & 0xff) & (1<<7)) |
(((B + 0x100 - (1<<5)) & 0xff) & (1<<6)) |
(((B + 0x100 - (1<<4)) & 0xff) & (1<<5)) |
(((B + 0x100 - (1<<3)) & 0xff) & (1<<4)) |
(((B + 0x100 - (1<<2)) & 0xff) & (1<<3)) |
(((B + 0x100 - (1<<1)) & 0xff) & (1<<2)) |
(((B + 0x100 - (1<<0)) & 0xff) & (1<<1)) |
!(B & 1)
So, if B = 0x00, we get
M = (192 & 128) |
(224 & 64) |
(240 & 32) |
(248 & 16) |
(252 & 8) |
(254 & 4 ) |
(255 & 2 ) |
!(0 & 1) = 128 | 64 | 32 | 16 | 8 | 4 | 2 | 1 = 0xff
I am not sure why this mapping exists. It could be an attempt by Polar to
conceal the way that watch settings are changed, but it seems unnecessary on
top of their packet checksum (more on this shortly).
2) Packet protocol
Data is sent to and from the watch using packets. Packet bytes are reverse
mapped using the mapping above before being transmitted. In other words, if
we wish to transmit what will be understood by the watch as a byte value of
0x00, we have to send the byte B which maps to M = 0x00 (the value of B in
this case happens to be 0x55).
Each packet has a header, a payload, and a trailer. The header consists of
one byte identifying the packet type, a second byte identifying the packet
subtype, a 0 byte, and a 16-bit value identifying the length of the packet
(header + payload). The trailer is a 16-bit value which appears to be
some sort of checksum. (Update: 17 Sep 2002 - The trailer is indeed a
checksum. Stefan Kleditzsch found it to be a CRC16 with polynomical 0x8005).
2a) Packets sent to the watch
Packets sent from the computer to the watch always have a type of 0xa3 (163).
The packet subtype determines what the watch is supposed to do when it
receives the packet. Valid subtypes are:
0x01: Set watch info
0x02: Get watch info
0x03: Set exercise
0x04: Get exercise
0x05: Set user info
0x06: Get user info
0x09 Reset to factory defaults
0x0a: Set to watch mode (close connection)
0x0b: Continue data transfer (used when retrieving workout data)
0x0d: Set reminder
0x0e: Get reminder
0x0f: Set logo
0x10: Get logo
0x13: Set bike info
0x14: Get bike info
0x15: Get overview
0x16: Get files
The "Get" packets all have a length of 5 (which means they have an empty
payload), except for subtypes 0x04 (Get exercise) and 0x0e (Get reminder),
which have a length of 6. The extra byte (a single payload byte) identifies
which exercise or reminder is being requested. The value should be 0x11,
0x22, 0x33, 0x44, or 0x55 to get exercise 1, 2, 3, 4 or 5 respectively, and
the value should be 0x00, ..., 0x06 to get reminders 1 through 7 respectively.
Packet size is stored in big-endian order (most significant byte first). Thus,
the following packet represents a "Get overview" request:
0xa3 0x15 0x00 0x00 0x05 0x37 0x90
where the last two bytes are the checksum for this particular packet. The
reverse-mapped packet (the bytes which actually have to be sent through the
serial port) are:
0x34 0xa6 0x55 0x55 0x56 0xb8 0x25
"Set" packets are identical to the "Get" response packets (described below)
with the exception that the packet type is 0xa3 (because the packet is being
sent to the watch), not 0x5c.
The "hard reset" packet is just a minimal packet with no payload, a packet
type of 0xa3, and a packet subtype of 0x09.
2b) Packets sent by the watch
Packets sent from the watch to the computer always have a packet type of
0x5c (92). Note that 0x5c is the two's complement of 0xa3 (163 + 92 = 255).
The packet subtype matches the subtype in the request from the computer.
Note that before the watch's response packet is received by the computer,
the dongle's echo of the transmitted packet will be received. So, if we
transmit a "Get overview" request to the watch:
Transmit: 0x34 0xa6 0x55 0x55 0x56 0xb8 0x25
We first receive the serial IR echo of the reverse-mapped packet:
Receive: 0xa3 0x15 0x00 0x00 0x05 0x37 0x90
Then we receive the response from the watch itself:
Receive: 0xc5 0x15 0x00 <16-bit length> <payload> <16-bit trailer>
2c) Packet error detection
Since the checksum is used to determine if a communication error has occurred,
we are unable to validate packets sent by the watch other than to assure that
the length is equal to what was advertised and that the subtype matches what
was requested.
3) Packet payload structure
The contents of the "request" packets sent by the computer have already been
elucidated above in section 2a. In this section we reveal the structure of
the response packets from the watch (when "Get" requests are sent to it). Some
of the bytes are still unknown; where this is the case, a '?' is shown. Some
bytes are part of multi-byte fields (e.g. 16-bit values, etc). Where this is
the case, "MSB" and "LSB" are used to indicate if the byte is to be interpreted
as the most or least significant byte in the multi-byte value, respectively.
Some bytes contain multiple pieces of information, either stuffed into the
individual bits one by one, or broken into the upper and lower "nibbles" of
the bytes. If a byte holds data in its individual bits, each bit is shown
along with what it means. If a byte holds data in its upper and lower nibbles,
each nibble is shown (L == lower nibble, U == upper nibble). Some values are
stored in binary coded decimal form (BCD); e.g. a value of 59 would be stored
as 0x59 instead of as 0x3b. If this is the case, it is indicated.
Subtype 0x15: "Get overview" response: Length = 11 bytes (6 payload):
-----------------------------------------------------------------------------
Payload byte Meaning
=============================================================================
0 ? always 0x22
1 ? always 0x20
2 Number of files stored
3 ? always 0x00
4 Bytes of workout data (MSB)
5 Bytes of workout data (LSB)
Subtype 0x05: "Get user info" response: Length = 26 bytes (21 payload):
-----------------------------------------------------------------------------
Payload byte Meaning
=============================================================================
0 bit 7: (& 0x80) 0
bit 6: (& 0x40) 0
bit 5: (& 0x20) 0
bit 4: (& 0x10) 0
bit 3: (& 0x08) (Altimeter)
bit 2: (& 0x04) (Polar Fitness Test)
bit 1: (& 0x02) (Predict HR Max - also turns on fitness test)
bit 0: (& 0x01) (Energy Expenditure)
1 bit 7: (& 0x80) 0
bit 6: (& 0x40) 0
bit 5: (& 0x20) 0
bit 4: (& 0x10) 0
bit 3: (& 0x08) (Options Lock)
bit 2: (& 0x04) (Help)
bit 1: (& 0x02) (Units: 0 [kg/cm/km], 1 [lb/ft/mi])
bit 0: (& 0x01) (Activity/Button Sound)
2 L: Heart Touch: Show Lim = 0, Store Lap = 1, Switch Disp = 2)
U: Recording Interval (5s = 0, 15s = 1, 60s = 2)
3 weight (units)
4 height (units)
5 birth day (BCD)
6 birth year (BCD), relative to 1900
7 L: birth month
U: activity level: 0 => low,
1 => medium
2 => high
3 => top
8 VO2 max
9 Max HR
10 Sex (0x50 = male, 0x51 = female)
11 ?
12 ?
13 User ID (0-99)
14 Name (char 1) (see section 4)
15 Name (char 2)
16 Name (char 3)
17 Name (char 4)
18 Name (char 5)
19 Name (char 6)
20 Name (char 7)
Subtype 0x02: "Get watch info" response: Length = 16 bytes (11 payload):
-----------------------------------------------------------------------------
Payload byte Meaning
=============================================================================
0 Time 1 second (BCD)
1 Time 1 minute (BCD)
2 Time 1 hour (BCD)
3 Day (BCD)
4 Year (BCD) (counting from 2000)
5 U: day of week (monday = 0, sunday = 6)
L: month (jan = 0x01, dec = 0x0c)
6 Alarm minute (BCD)
7 Alarm hour (BCD, 24 hour)
8 Time 2 minute (BCD)
9 Time 2 hour (BCD)
10 bit 7: (& 0x80) 0
bit 6: (& 0x40) Time 2 12/24 hour (24 = 0, 12 = 1)
bit 5: (& 0x20) 0
bit 4: (& 0x10) Time zone in use (Time1 = 0, Time2 = 1)
bit 3: (& 0x08) Time 1 12/24 hour (24 = 0, 12 = 1)
bit 2: (& 0x04) 0
bit 1: (& 0x02) Alarm enabled (1 = yes, 0 = no)
bit 0: (& 0x01) 0
Subtype 0x10: "Get logo" response: Length = 52 bytes (47 payload):
-----------------------------------------------------------------------------
Payload byte Meaning
=============================================================================
0 Logo column 1
bit 7: (& 0x80) row 1 (white = 0, black = 1)
bit 6: (& 0x40) row 2
bit 5: (& 0x20) .
bit 4: (& 0x10) .
bit 3: (& 0x08) .
bit 2: (& 0x04) .
bit 1: (& 0x02) row 7
bit 0: (& 0x01) row 8
.
.
.
46 Logo column 47
Subtype 0x14: "Get bike info" response: Length = 30 bytes (25 payload):
-----------------------------------------------------------------------------
Payload byte Meaning
=============================================================================
0 bit 7: (& 0x80) 0
bit 6: (& 0x40) 0
bit 5: (& 0x20) 0
bit 4: (& 0x10) 1 ??? autostart ???
bit 3: (& 0x08) Bike1 Power sensor (0 = disabled, 1 = in use)
bit 2: (& 0x04) Bike1 Cadence sensor (0 = disabled, 1 = in use)
bit 1: (& 0x02) 0
bit 0: (& 0x01) 0
1 Bike1 name char 1 (see section 4)
2 Bike1 name char 2
3 Bike1 name char 3
4 Bike1 name char 4
5 Bike1 Wheel size (lower 2 digits) (BCD)
6 Bike1 Wheel size (upper 2 digits) (BCD
7 bit 7: (& 0x80) 0
bit 6: (& 0x40) 0
bit 5: (& 0x20) 0
bit 4: (& 0x10) 1 ??? autostart ???
bit 3: (& 0x08) Bike2 Power sensor (0 = disabled, 1 = in use)
bit 2: (& 0x04) Bike2 Cadence sensor (0 = disabled, 1 = in use)
bit 1: (& 0x02) 0
bit 0: (& 0x01) 0
8 Bike2 name char 1 (see section 4)
9 Bike2 name char 2
10 Bike2 name char 3
11 Bike2 name char 4
12 Bike2 wheel size (lower 2 digits) (BCD)
13 Bike2 wheel size (upper 2 digits) (BCD)
14 Bike1 Span length (mm) (lower 2 digits) (BCD)
15 U: Bike1 Chain weight (g) (lower digit) (BCD)
L: Bike1 Span length (mm) (upper digit) (BCD)
16 Bike1 Chain weight (g) (upper 2 digits) (BCD)
17 Bike1 Chain length (mm) (lower 2 digits) (BCD)
18 Bike1 Chain length (mm) (upper 2 digits) (BCD)
19 Bike2 Span length (mm) (lower 2 digits) (BCD)
20 U: Bike2 Chain weight (g) (lower digit) (BCD)
L: Bike2 Span length (mm) (upper digit) (BCD)
21 Bike2 Chain weight (g) (upper 2 digits) (BCD)
22 Bike2 Chain length (mm) (lower 2 digits) (BCD)
23 Bike2 Chain length (mm) (upper 2 digits) (BCD)
24 Bike in use (None = 0, Bike1 = 1, Bike2 = 2)
Subtype 0x04: "Get exercise" response: Length = 28 bytes (23 payload):
-----------------------------------------------------------------------------
Payload byte Meaning
=============================================================================
0 which one (1-5)
1 exercise name byte 1 (see section 4)
2 .
3 .
4 .
5 .
6 .
7 exercise name byte 7
8 timer 1 minute (BCD)
9 timer 1 hour (BCD)
10 timer 2 minute (BCD)
11 timer 2 hour (BCD)
12 timer 3 minute (BCD)
13 timer 3 hour (BCD)
14 hr limit 1 lower
15 hr limit 1 upper
16 hr limit 2 lower
17 hr limit 2 upper
18 hr limit 3 lower
19 hr limit 3 upper
20 recovery time minute (BCD)
21 recovery time hour (BCD)
22 recovery end heart rate
Subtype 0x0e: "Get reminder" response: Length = 19 bytes (14 payload):
-----------------------------------------------------------------------------
Payload byte Meaning
=============================================================================
0 which one (0 = 1, etc up to 6 = 7)
1 minute (BCD)
2 hour (BCD)
3 day of month (BCD)
4 year (from 2000) (BCD)
5 L: month 1 = jan, etc.
U: 0 = on, 2 = off
6 text byte 1 (see section 4)
7 text byte 2
8 text byte 3
9 text byte 4
10 text byte 5
11 text byte 6
12 text byte 7
13 L: exercise (0 = none, 1 = basic, 2-6 = ex set 1-5)
U: repeat (0 = off, hourly, daily, weekly, monthly, yearly)
Subtype 0x0b: "Get files" response: Length = variable:
-----------------------------------------------------------------------------
Payload byte Meaning
=============================================================================
0 bit 7: "first packet" = 1
bits 6-0: packets remaining after this one
1 File bytes (MSB)
2 File bytes (LSB)
3 ? 0x22 (magic?)
4 ? 0x02 (magic?)
5..n-1 File data (see README.file_format)
Subtype 0x16: "Continue transmission" response: Length = variable:
-----------------------------------------------------------------------------
Payload byte Meaning
=============================================================================
0 bit 7: "subsequent packet" = 0
bits 6-0: packets remaining after this one
1..n-1 File data (see README.file_format)
4) Alphanumeric character mapping
The following mapping is used by Polar to store printable text such as names
and so forth:
0-9 = 0-9
space = 10
A-Z = 11-36
a-z = 37-62
-%/()*+.:? = 63-72
Thus, for example, the name "DAVE" would be transmitted by the watch as the
byte string 0x0e 0x0b 0x20 0x0f.