Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Supporting more network and node information in v2 spec #9

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 37 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,31 +19,23 @@ good fit for files that will be interpreted by both.
### Encoding Sequences of Bytes
JSON does not natively support sequences of bytes (`char[]`, `Buffer`, bytestrings, etc.), therefore an intermediate representation is necessary.

Sequences of bytes will be encoded as a case-insensitive string of each
byte's hex representation, with leading zeroes, concatenated together. For example,
`\x0A\xBB\xC0` will be represented as `"0abbc0"`.
Sequences of bytes will be encoded as a lowecase string of each byte's hex representation, with leading zeroes, concatenated together. For example, `\x0A\xBB\xC0` will be represented as `"0abbc0"`.

Different platforms may internally use different byte ordering (big endian, little endian). All binary sequences in this format need to be stored **MSB-LSB (big endian)**. For example, IEEE addresses are represented within Z-Stack LSB-MSB (little endian), therefore address `00:12:4b:00:06:10:4e:22` would be internally stored as `22:4e:10:06:00:4b:12:00`. For purposes of this specification the address needs to be reversed and converted to specified byte array representation form - `00124b0006104e22`.

## Backup Structure
The generated backup is a JSON document with the following top-level keys:
* `metadata`: *object*,
* `stack_specific`: *object*,
* `coordinator_ieee`: *string*,
* `pan_id`: *string*,
* `extended_pan_id`: *string*,
* `channel`: *number*,
* `channel_mask`: *number[]*,
* `security_level`: *number*,
* `nwk_update_id`: *number*,
* `network_key`: *object*,
* `network`: *object*,
* `node`: *object*,
* `devices`: *object[]*.

### `metadata`
The top-level `metadata` object contains basic information about the backup itself:
* `format`: *string* - needs to be set to `zigpy/open-coordinator-backup`,
* `version`: *number* - specifier that will be incremented upon major specification
changes that will require migration or introduce new keys. The current value is `1`,
changes that will require migration or introduce new keys. The current value is `2`,
* `source`: *string* - describes the application or package generating the file. This value will be the name of the package, followed by a literal `@`, then the version identifier of the generating package. For example, `[email protected]` or `zigbee-herdsman@d12727f3`. The purpose of this key is to uniquely identify the application generating the backup format and potentially work around bugs introduced in specific versions,
* `internal`: *object* - arbitrary-structure object that can be used by the generating application to store any other useful non-network information. For the purposes of interoperability, it is not recommended to store any critical network information, for example stack-specific settings, in this object. Use the top-level `stack_specific` key with the appropriate sub-object for the stack.

Expand All @@ -58,25 +50,20 @@ Therefore the structure currently supports the following keys:

*Other stack-specific fields may be added as they are used.*

### `coordinator_ieee`
Unique 64-bit coordinator adapter IEEE address represented as described in [Encoding Sequences of Bytes](#Encoding-Sequences-of-Bytes). Example value: `00124b0009d69f77`.

### `pan_id`
### `network.pan_id`
The network's 16-bit Personal Area Network Identifier (PAN ID) will be stored big-endian and encoded as hex, with leading zeroes as per [Encoding Sequences of Bytes](#Encoding-Sequences-of-Bytes). Example value: `d4a1`.
Unique 64-bit coordinator adapter IEEE address represented as described in [Encoding Sequences of Bytes](#Encoding-Sequences-of-Bytes). Example value: `00124b0009d69f77`.

### `extended_pan_id`
### `network.extended_pan_id`
The 64-bit Extended Personal Area Network Identifier (EPID) stored as described in [Encoding Sequences of Bytes](#Encoding-Sequences-of-Bytes). Example value: `00124b0009418a6b`.

### `channel`
The current logical channel of the network will be stored as an integer between 11 and 26.

### `channel_mask`
The logical channels on which the network can be formed will be stored as an array of numbers, each between 11 and 26. If the network can only be formed on a single channel, the array will contain a single integer.
### `network.update_id`
The network update identifier will be stored as an integer between 0 and 255.

### `security_level`
### `network.security_level`
The network security level will be stored as an integer between 0 and 7. Supported values are listed in the table below ([source](https://research.kudelskisecurity.com/2017/11/08/zigbee-security-basics-part-2/)).

| Value | Security Level Identifier | Security Attributes | Data Encryption | Frame Integrity (length of MIC) |
| Value | Security Level Identifier | Security Attributes | Data Encryption | Frame Integrity (length of MIC) |
| - | - | - | - | - |
| **0** | 0x00 | None | OFF | NO (M = 0) |
| **1** | 0x01 | MIC-32 | OFF | YES (M=4) |
Expand All @@ -87,25 +74,46 @@ The network security level will be stored as an integer between 0 and 7. Support
| **6** | 0x06 | ENC-MIC-64 | ON | YES (M=8) |
| **7** | 0x07 | ENC-MIC-128 | ON | YES (M=16) |

### `nwk_update_id`
The network update identifier will be stored as an integer between 0 and 255.
### `network.channel`
The current logical channel of the network will be stored as an integer between 11 and 26.

### `network_key`
### `network.channel_mask`
The logical channels on which the network can be formed will be stored as an array of numbers, each between 11 and 26. If the network can only be formed on a single channel, the array will contain a single integer.

### `network.network_key`
This object contains vital information related to network key required to restore the network. The following keys are present:
* `key`: *string* - 128-bit key encoded as described in [Encoding Sequences of Bytes](#Encoding-Sequences-of-Bytes),
* `sequence_number`: *number* - value of 0 to 255 indicating the re-keying sequence,
* `frame_counter`: *number* - numeric value of the 32-bit network frame counter.

### `network.tc_link_key`
128-bit trust center link key encoded as described in [Encoding Sequences of Bytes](#Encoding-Sequences-of-Bytes). This is usually `ZigBeeAlliance09`: `5a6967426565416c6c69616e63653039`.

### `network.nwk_manager`
16-bit network address of the Network Manager encoded as described in [Encoding Sequences of Bytes](#Encoding-Sequences-of-Bytes). This is usually the coordinator, `0000`.


### `node`
This key holds information about the current node.

* `nwk`: *string* - 16-bit network address of the current node encoded as described in [Encoding Sequences of Bytes](#Encoding-Sequences-of-Bytes). This is usually the coordinator, `0000`.
* `ieee`: *string* - 64-bit IEEE address of the device encoded as per [Encoding Sequences of Bytes](#Encoding-Sequences-of-Bytes),
* `type`: *string* - one of `router`, `coordinator`, or `end_device`.

### `devices`
This is an array of devices relevant to the coordinator: namely children and devices with APS link keys shared with the coordinator. Every object within this array contains the following fields:
* `ieee_address`: *string* - 64-bit IEEE address of the device encoded as per [Encoding Sequences of Bytes](#Encoding-Sequences-of-Bytes),
* `nwk_address`: *string* - 16-bit device network address encoded as per [Encoding Sequences of Bytes](#Encoding-Sequences-of-Bytes). If a device's current 16-bit network address is not known, the value `null` must be used.
* `ieee`: *string* - 64-bit IEEE address of the device encoded as per [Encoding Sequences of Bytes](#Encoding-Sequences-of-Bytes),
* `type`: *string* - one of `router`, `coordinator`, or `end_device`.
* `is_child`: *boolean* (optional) - indicates if the device is a child of the coordinator (if the field does not exist - consider `true`),
* `link_key`: *object* (optional),
* `key`: *string* - 128-bit key encoded as described in [Encoding Sequences of Bytes](#Encoding-Sequences-of-Bytes),
* `rx_counter`: *number* - value of 32-bit receive frame counter for the link key,
* `tx_counter`: *number* - value of 32-bit transmit frame counter for the link key.

### `addresses`
This is an object mapping IEEE addresses to NWK addresses for known devices:
* 64-bit IEEE address: *string* 16-bit

## Samples
Sample may be found in `samples` directory.

Expand Down
86 changes: 56 additions & 30 deletions schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,75 +8,101 @@
"type": "object",
"properties": {
"format": {"type": "string", "pattern": "^zigpy/open-coordinator-backup$"},
"version": {"type": "integer", "minimum": 1, "maximum": 1},
"version": {"const": 2},
"source": {"type": "string", "pattern": "^(.*?)+@(.*?)$"},
"internal": {"type": "object"}
},
"required": ["version", "source"]
},

"stack_specific": {
"type": "object",
"properties": {
"zstack": {
"type": "object",
"properties": {
"tclk_seed": {"type": "string", "pattern": "[a-fA-F0-9]{32}"}
"tclk_seed": {"type": "string", "pattern": "[a-f0-9]{32}"}
}
}
}
},
"coordinator_ieee": {"type": "string", "pattern": "[a-fA-F0-9]{16}"},
"pan_id": {"type": "string", "pattern": "[a-fA-F0-9]{4}"},
"extended_pan_id": {"type": "string", "pattern": "[a-fA-F0-9]{16}"},
"nwk_update_id": {"type": "integer", "minimum": 0, "maximum": 255},
"security_level": {"type": "integer", "minimum": 0, "maximum": 7},
"channel": {"type": "integer", "minimum": 11, "maximum": 26},
"channel_mask": {
"type": "array",
"items": {"type": "integer", "minimum": 11, "maximum": 26}
"network": {
"type": "object",
"properties": {
"pan_id": {"type": "string", "pattern": "[a-f0-9]{4}"},
"extended_pan_id": {"type": "string", "pattern": "[a-f0-9]{16}"},
"update_id": {"type": "integer", "minimum": 0, "maximum": 255},
"security_level": {"type": "integer", "minimum": 0, "maximum": 7},
"channel": {"type": "integer", "minimum": 11, "maximum": 26},
"channel_mask": {
"type": "array",
"items": {"type": "integer", "minimum": 11, "maximum": 26}
},
"network_key": {
"type": "object",
"properties": {
"key": {"type": "string", "pattern": "[a-f0-9]{32}"},
"sequence_number": {"type": "integer", "minimum": 0, "maximum": 255},
"frame_counter": {"type": "integer", "minimum": 0, "maximum": 4294967295}
},
"required": ["key", "sequence_number", "frame_counter"]
},
"tc_link_key": {"type": "string", "pattern": "[a-f0-9]{32}"},
"nwk_manager": {"type": "string", "pattern": "[a-f0-9]{4}"}
},
"required": [
"pan_id",
"extended_pan_id",
"nwk_update_id",
"security_level",
"channel",
"channel_mask",
"network_key",
"tc_link_key",
"nwk_manager"
]
},
"network_key": {
"node": {
"type": "object",
"properties": {
"key": {"type": "string", "pattern": "[a-fA-F0-9]{32}"},
"sequence_number": {"type": "integer", "minimum": 0, "maximum": 255},
"frame_counter": {"type": "integer", "minimum": 0, "maximum": 4294967295}
"nwk": {"type": "string", "pattern": "[a-f0-9]{4}"},
"ieee": {"type": "string", "pattern": "[a-f0-9]{16}"},
"type": {"enum": ["router", "coordinator", "end_device"]}
},
"required": ["key", "sequence_number", "frame_counter"]
"required": ["nwk", "ieee", "type"]
},
"devices": {
"type": "array",
"items": {
"type": "object",
"properties": {
"nwk_address": {"type": ["string", "null"], "pattern": "[a-fA-F0-9]{4}"},
"ieee_address": {"type": "string", "pattern": "[a-fA-F0-9]{16}"},
"ieee": {"type": "string", "pattern": "[a-f0-9]{16}"},
"type": {"enum": ["router", "coordinator", "end_device", null]},
"is_child": {"type": "boolean"},
"link_key": {
"type": "object",
"properties": {
"key": {"type": "string", "pattern": "[a-fA-F0-9]{16}"},
"key": {"type": "string", "pattern": "[a-f0-9]{16}"},
"tx_counter": {"type": "integer", "minimum": 0, "maximum": 4294967295},
"rx_counter": {"type": "integer", "minimum": 0, "maximum": 4294967295}
},
"required": ["key", "tx_counter", "rx_counter"]
}
},
"required": ["nwk_address", "ieee_address"]
"required": ["nwk", "ieee", "type", "is_child"]
}
},
"addresses": {
"type": "object",
"patternProperties": {
"[a-f0-9]{16}": {"type": "string", "pattern": "[a-f0-9]{4}"}
}
}
},
"required": [
"metadata",
"coordinator_ieee",
"pan_id",
"extended_pan_id",
"nwk_update_id",
"security_level",
"channel",
"channel_mask",
"network_key",
"devices"
"network",
"node",
"devices",
"addresses"
]
}