File: protocol_z.txt

package info (click to toggle)
concordance 1.1-3
  • links: PTS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 7,416 kB
  • ctags: 1,343
  • sloc: sh: 11,808; cpp: 7,116; ansic: 880; python: 686; perl: 171; makefile: 135; xml: 15
file content (396 lines) | stat: -rw-r--r-- 10,485 bytes parent folder | download | duplicates (6)
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
393
394
395
396

+++ TABLE OF CONTENTS

   - PACKET FORMAT
   - COMMANDS


+++ PACKET FORMAT

For ZWave remotes, there are two basic types of remotes, each of with their own
packet formats: HID-based remotes (89x), and usbnet-based remotes (1000 and
later).

HID-BASED REMOTES

The HID based remotes used two different packet formats. The basic one is
referred to by the remotes as "UDP" - but is unrelated to the network protocol.
We'll always refer to this as HID-UDP. It's format is as follows:

  byte1: Number of the last byte (i.e. length - 1)
  byte2: 1
  byte3: Message Type
  byte4: Command
  .....: Parameters

Message Type is
  0x00 for Command (from software)
  0x01 for Response (from device)

This format use used for all the most basic commands. However, once any
reasonable amount of data needs to be sent, it switches to something that the
remotes refer to as "TCP" - but it bears very little resemblance to the
networking protocol by the same name. We'll refer to this as HID-TCP.

HID-TCP is a connection-oriented wrapper around HID-UDP. The payload of HID-TCP
packets is in fact a HID-UDP packet without the first two bytes (which are
unnecessary since the information is available at the HID-TCP level). The format
for HID-TCP packets is as follows:

  byte1: Number of the last byte (i.e. length - 1)
  byte2: Flags (0x20 is FIN, 0x40 is ACK, and 0x80 is SYN)
  byte3: Sequence Number
  byte4: Acknowledgment Number
  .....: HID-UDP packet, minus the first two bytes

Sequence numbers and Acknowledgment numbers use this formula:

  SEQ = previous guy's ACK number (or random if we haven't seen one?)
  ACK = previous guy's SEQ number + number of *data* bytes (first byte - 3)

The exception to this is that the first ACK the software sends adds one to the
sequence number as a way of acknolwedging the SYN.

The HID-TCP session is setup using the HID-UDP command
INITIATE_UPDATE_TCP_CHANNEL, to which the remote will respond with the
INITIATE_UPDATE_TCP_CHANNEL response over HID-UDP, and then all further
communication must be over HID-TCP.

This part we're still not 100% sure, but we believe it works like this:

At this point the remote sends SYN packets with the sequence number FO and the
ack number FF. We can then send our first command in a SYN+ACK packet. We use a
random seq number and our ack is their seq + 1.

Based in this HID-UDP command we send in this packet, there remote expects a
sequence of events (e.g., START_UPDATE is followed by WRITE_UPDATE_HEADER,
WRITE_UPDATE_DATA, WRITE_UPDATE_DATA_DONE, GET_UPDATE_CHECKSUM, and
WRITE_FINISH_UPDATE). Once we send whatever the appropriate "FINISH" command is,
the remote response with a FIN+ACK, the software ACKs that which is ACK'd, and
then HID-UDP is resumed.


NETUSB-BASED REMOTES

The 1000 and later series use IP-over-USB, aka usbnet.

The payload for these is as follows:

  byte1: MSN = Command Type
         LSN = 0
  byte2: Command
  byte3: Message Type
  byte4: Number of parameters
  .....: Parameters

In this case, Command Types are:
  2: CLIENT
  3: NOTIFY
  4: ENV
  5: IR
  8: ZWAVE
  A: PIC
  E: DEVICE

  The only particularly useful one for our purpose is CLIENT, and the commands
  for this family are in the COMMANDS section below.

Message Type is:
  0x80 (128): Command (from software)
  0x01 (  1): Response (from device)

Numver of Parameters is encoded as follows:

   00: 10.. .... variable length or endian encoding?
       11.. .... then scale = 512
       01.. .... then scale = 4                     
       00.. .... then scale = 1
       ..ss ssss = base_size   
       size = scale * base_size


+++ COMMANDS

These commands are shared between both HID-based and netusb-based remotes. For
netusb-based remotes they fall under the "client" family.

For the usbnet-based remotes, since these are all CLIENT command type, the first
byte of these will always be 0x20, and we only include the LSB, which is common
between both families of remotes.

COMMAND_GET_SYSTEM_INFO 0x61 (97)
message type: 0x80 (128)
parameters: 0
notes: only from server

message type: 0x01 (1)
parameters: 8
  parameter 1: 2 bytes USB Vendor ID
    sample values: 04 6d (1113)
  parameter 2: 2 bytes USB Product ID
    sample values: c1 1f (49439)
  parameter 3: 2 bytes product Type
    sample values: 00 0b (11)
  parameter 4: 2 bytes firmware Major Version
    sample values: 00 05 (5)
  parameter 5: 2 bytes firmware Minor Version
    sample values: 00 00 (0)
  parameter 6: 1 byte firmware Type
    sample values: 00 (0)
  parameter 7: 2 bytes skin
    sample values: 00 35 (53)
  parameter 8: 2 bytes board revision
    sample values: 01 a2 (418)
notes: sometimes the connection is closed right after this response


COMMAND_GET_GUID 0x67 (103)
message type: 0x80 (128)
parameters: 0
notes: from server, after 0x2061

message type: 0x01 (1)
parameters: 1 (guid)
  parameter 1: 48 bytes (0xb0, 176, 1011 0000)
    sample values:                            
      01 4f fb 2d ee ee ee ee  ee ee ee ee ee ee ee ee
      60 ed 07 db c8 26 45 7c  8d ff 47 4f 61 b5 3a 0f
      db fa 5c 2e 27 6a 4a 5a  8a 03 39 ad 10 ab 98 5c

COMMAND_GET_REGION_IDS 0x6e (110)
message type: 0x80 (128)
parameters: 1
  parameter 1: 1 bytes (flag of some sort)
    sample values: 01
notes: from server, after 0x2067; also sent again after 0x2012

message type: 0x01 (1)
parameters: 1
  parameter 1: 10 bytes (0x8a, 138, 1000 1010) (list of writable regions?)
  sample values:
      01 02 03 05 07 0b 0c 0d  0e 0f
notes: this is variable-length array, which we've observed to be 10 bytes,
usually?

COMMAND_GET_REGION_VERSION 0x6f (111)
message type: 0x80 (128)
parameters: 1 (region ID)
  parameter 1: 1 byte
    sample values: 00 (0)
    sample values: 01 (1)
    sample values: 02 (...
note: the values sent are the bytes returned in the previous command (0x206e,
0x01)

message type: 0x01 (1)
parameters: 1 (version?)
  parameter 1: 2 bytes
    sample values:
      01 01 (sent in response to 00)
      00 05 (sent in response to 01)
      00 05 (sent in response to 02)
      07 03 (sent in response to 03)
      06 01 (sent in response to 05)
      51 01 (sent in response to 07)
      05 03 (sent in response to 0b)
      00 04 (sent in response to 0c)
      00 04 (sent in response to 0d)
      05 03 (sent in response to 0e)
      00 01 (sent in response to 0f)

COMMAND_GET_HOME_ID 0x89 (137)
message type: 0x80
parameters: 0
notes: sent after all 0x206f commands, but not required (1 trace lacked this)

message type: 0x01
parameters: 1 Home ID (integer)
  parameter 1: 4 bytes
    sample values: 01 4f fb 2d

COMMAND_GET_NODE_ID 0x87 (135)
message type: 0x80
parameters: 0

message type: 0x01
parameters: 1 Node ID (byte)
  parameter 1: 1 byte
    sample values: 00

COMMAND_PING_UDP 0x12 (18)
message type: 0x80
parameters: 0

message type: 0x01
parameters: 0

COMMAND_START_UPDATE 0x41 (65)
message type: 0x80
parameters: 2
  parameter 1: 1 byte (flags)
    sample values: 00
  parameter 2: 1 byte (region ID)
    sample values: 04

message type: 0x01
parameters: 0

COMMAND_WRITE_UPDATE_HEADER 0x42 (66)
message type: 0x80
parameters: 2
  parameter 1: 4 bytes (size)
    sample values: 00 2f 11 34
    sample values: 00 2f 11 39
  parameter 2: 1 bytes (region id)
    sample values: 04

message type: 0x01
parameters: 0

COMMAND_WRITE_UPDATE_DATA 0x43 (67)
message type: 0x80
parameters: 3
  parameter 1: 1 byte (region ID)
    sample values: 04
  parameter 2: 0x400 (1024) bytes (0xc2, 194/2 , 1100 0010) (data)
  parameter 3: 4 bytes (length)
    sample values: 00 00 04 00
notes:
  This is repeated for every 1K-byte chunk.
  Parameter 3 seems to be the length since parameter 2
  is the length rounded up to the next scaling factor.

message type: 0x01
parameters: 0

COMMAND_WRITE_UPDATE_DATA_DONE 0x44 (68)
message type: 0x80
parameters: 1
  parameter 1: 1 byte (region ID)
    sample values: 04
notes: sent after all 0x2043 commands

message type: 0x01
parameters: 0

COMMAND_GET_UPDATE_CHECKSUM 0x45 (69)
message type: 0x80
parameters: 2
  parameter 1: 2 bytes (seed)
    sample values: ff ff
  parameter 2: 1 byte (region ID)
    sample values: 04

message type: 0x01
parameters: 1
  parameter 1: 2 bytes (checksum - integer)
    sample values: 00 02
    sample values: dc 52

COMMAND_FINISH_UPDATE 0x46 (70)
message type: 0x80
parameters: 2
  parameter 1: 1 byte (validate - 0 or 1)
    sample values: 01
  parameter 2: 1 byte (region ID)
    sample values: 04

message type: 0x01
parameters: 0

COMMAND_RESET 0x1b (27)
message type: 0x80
parameters: 0
notes: sent after 0x2046 commands

message type: 0x01
parameters: 0

COMMAND_UPDATE_TIME 0x71 (113)
message type: 0x80
parameters: 12 (0x0c)
  parameter 1: 2 bytes
    year
    sample values: 07 d9 (2009)
  parameter 2: 1 byte
    number of month: 1 = Jan, 2 = Feb, etc.
    sample values: 03 (Mar)
  parameter 3: 1 byte
    day of month
    sample values: 0c (12)
  parameter 4: 1 byte
    hour
    sample values: 13 (19)
    sample values: 12 (18)
  parameter 5: 1 byte
    minute ?
    sample values: 00
    sample values: 35 (53)
  parameter 6: 1 byte
    second ?
    sample values: 2d (45)
    sample values: 25 (37)
  parameter 7: 1 byte
    day of week
    sample values: 04
    sample values: 04
  parameter 8: 2 bytes
    utcOffset
    sample values: 0e 10
  parameter 9: 2 bytes
    0
    sample values: 00 00
  parameter 10: 2 bytes
    0
    sample values: 00 00
  parameter 11: 2 bytes
    0
    sample values: 00 00
  parameter 12: 14 bytes (0x8e, 142, 1000 1110)
    time zone
    sample values:
      45 75 72 6f 70 65 2f 42  65 72 6c 69 6e 00       Europe/Berlin

message type: 0x01
parameters: 0

COMMAND_READ_REGION 0x47 (71)
message type: 0x80 (128)
parameters: 1
  parameter 1: 1 byte (region ID)
    sample values: 04

message type: 0x01 (1)
parameters: 1
  parameter 1: 4 bytes (region size in bytes)
  sample values:
      00 00 3e 88

COMMAND_READ_REGION_DATA 0x48 (72)
message type: 0x80
parameters: 1
  parameter 1: 1 byte (region ID)
    sample values: 04

message type: 0x01
parameters: 3
  parameter 1: 1 byte (region ID)
    sample values: 04
  parameter 2: 0x400 (1024) bytes (0xc2, 194/2 , 1100 0010) (data)
  parameter 3: 4 bytes (length)
    sample values: 00 00 04 00
notes:
  This is repeated for every 1K-byte chunk.

COMMAND_READ_REGION_DONE 0x49 (73)
message type: 0x80
parameters: 1
  parameter 1: 1 byte (region ID)
    sample values: 04

message type: 0x01
parameters: 0

# for vim
vim:textwidth=80: