2023-10-15 18:06:18 +02:00
|
|
|
> **Version:** `1`
|
|
|
|
> **Authored by:** `Raine <raine@ixvd.net>`
|
2023-11-30 21:52:49 +01:00
|
|
|
>
|
|
|
|
# Table of contents
|
|
|
|
- [Table of contents](#table-of-contents)
|
|
|
|
- [Prelude](#prelude)
|
|
|
|
- [Interpretation of types](#interpretation-of-types)
|
|
|
|
- [Booleans](#booleans)
|
|
|
|
- [Reserved fields](#reserved-fields)
|
|
|
|
- [Structure](#structure)
|
|
|
|
- [Data types](#data-types)
|
|
|
|
- [Dynamic data (`dynamic_data`)](#dynamic-data-dynamic_data)
|
|
|
|
- [Commands](#commands)
|
|
|
|
- [`0x0*` - Node management](#0x0---node-management)
|
|
|
|
- [`0x00` - Ping](#0x00---ping)
|
|
|
|
- [Command data](#command-data)
|
|
|
|
- [`0x01` - Register node](#0x01---register-node)
|
|
|
|
- [Command data](#command-data-1)
|
|
|
|
- [`0x02` - Remove node](#0x02---remove-node)
|
|
|
|
- [Command data](#command-data-2)
|
|
|
|
- [`0x0A` - Acknowledge packets](#0x0a---acknowledge-packets)
|
|
|
|
- [`0x0E` - Error](#0x0e---error)
|
|
|
|
- [Command data](#command-data-3)
|
|
|
|
- [Error codes](#error-codes)
|
|
|
|
- [`0x1*` - Properties control](#0x1---properties-control)
|
|
|
|
- [`0x10` - Register property](#0x10---register-property)
|
|
|
|
- [Command data](#command-data-4)
|
|
|
|
- [`0x11` - Remove property](#0x11---remove-property)
|
|
|
|
- [Command data](#command-data-5)
|
|
|
|
- [`0x12` - Get property](#0x12---get-property)
|
|
|
|
- [Command data](#command-data-6)
|
|
|
|
- [`0x13` - Set property](#0x13---set-property)
|
|
|
|
- [Command data](#command-data-7)
|
|
|
|
- [`0x14` - Reset property](#0x14---reset-property)
|
|
|
|
- [Command data](#command-data-8)
|
|
|
|
- [`0x1A` - Subscribe to property](#0x1a---subscribe-to-property)
|
|
|
|
- [`0x1B` - Unsubscribe to property](#0x1b---unsubscribe-to-property)
|
|
|
|
- [`0x1F` - All properties](#0x1f---all-properties)
|
|
|
|
- [Command data](#command-data-9)
|
|
|
|
- [`0xF*` - Raw data transmission](#0xf---raw-data-transmission)
|
|
|
|
- [`0xF0` - Setup transfer](#0xf0---setup-transfer)
|
|
|
|
- [Command data](#command-data-10)
|
|
|
|
- [`0xF1` - Data](#0xf1---data)
|
|
|
|
- [Command data](#command-data-11)
|
|
|
|
|
2023-10-15 18:06:18 +02:00
|
|
|
|
|
|
|
# Prelude
|
|
|
|
|
2023-11-30 21:52:49 +01:00
|
|
|
This document only describes what the protocol looks like.
|
|
|
|
The specification can be found at `./specification.md`.
|
|
|
|
|
|
|
|
## Interpretation of types
|
|
|
|
|
|
|
|
### Booleans
|
|
|
|
|
|
|
|
If in the description of a property it's marked as a boolean the exact logic that should be executed is:
|
|
|
|
`value != 0`
|
|
|
|
|
|
|
|
## Reserved fields
|
|
|
|
|
|
|
|
The "reserved" column (if present) will state what should be filled in by each side.
|
|
|
|
|
|
|
|
- "no": this should be filled in by both sides. (default)
|
|
|
|
- "request": this should only be filled in the request.
|
|
|
|
- "response": this should only be filled in the response.
|
|
|
|
|
2023-10-15 18:06:18 +02:00
|
|
|
|
|
|
|
# Structure
|
|
|
|
|
|
|
|
Packets are sent in big endian.
|
|
|
|
|
2023-10-15 18:06:19 +02:00
|
|
|
| offset | size | name | description | example |
|
2023-11-05 20:52:11 +01:00
|
|
|
| -------------------------------- | ------------------------- | ------------- | ---------------------------------------------------------------------------------- | ------------ |
|
2023-10-15 18:06:19 +02:00
|
|
|
| `0x00` | 1 byte | `version` | This describes the version of the packet | `0x01` |
|
2023-10-15 18:06:30 +02:00
|
|
|
| `0x01` | 4 bytes | `dest` | This describes who the packet is for a.k.a. destination device id | `0xAABBCCDD` |
|
|
|
|
| `0x05` | 4 bytes | `src` | This describes who sent the packet a.k.a. source device id | `0xAABBCCDD` |
|
2023-10-15 18:06:19 +02:00
|
|
|
| `0x09` | 4 bytes | `packet_id` | This is the unique identifier of the packet | `0xFAB1B39D` |
|
|
|
|
| `0x0D` | 4 bytes | `reply_to` | This describes what this packet is replying to, if initial message, value is `0x0` | `0x00000000` |
|
|
|
|
| `0x11` | 1 byte | `command` | This describes what kind of command is sent | `0x00` |
|
|
|
|
| `0x12` | 2 bytes | `data_length` | This describes the length of the data in bytes | `0x0001` |
|
2023-10-15 18:06:22 +02:00
|
|
|
| `0x14` | `<0x11-0x12:data_length>` | `data` | This is the data of the command | `0x0000` |
|
2023-10-15 18:06:19 +02:00
|
|
|
| `0x14 + <0x11-0x12:data_length>` | 4 bytes | `checksum` | This is the CRC32 checksum of the packet without the checksum. | `0x00000000` |
|
2023-10-15 18:06:18 +02:00
|
|
|
|
|
|
|
# Data types
|
|
|
|
|
|
|
|
Domo has a data framework reliant on data types.
|
|
|
|
These define what kind of data the property holds.
|
|
|
|
|
2023-11-05 20:52:11 +01:00
|
|
|
| `data_type` | size | type | description |
|
|
|
|
| ----------- | --------- | ---------- | ---------------------------------------------------------------------- |
|
|
|
|
| `0x0*` | | | **Meta** |
|
|
|
|
| `0x00` | 0 bytes | Nothing | Nothing |
|
|
|
|
| `0x01` | 2+ bytes | Array | An array of DataTypes. first two bytes is the length in u16 BE |
|
|
|
|
| `0x1*` | | | **Basic** |
|
|
|
|
| `0x10` | 1 byte | Boolean | `0x00` = false, `0x01` = true, `0x02` = toggle item (reserved for set) |
|
|
|
|
| `0x11` | 8 bytes | Number | A number. |
|
|
|
|
| `0x12` | 256 bytes | Text | A simple bit of text. |
|
|
|
|
| `0x13` | 4 bytes | Identifier | An identifier. |
|
|
|
|
| `0x2*` | | | **Color** |
|
|
|
|
| `0x20` | 3 bytes | RGB | An RGB value. |
|
|
|
|
|
2023-10-15 18:06:20 +02:00
|
|
|
## Dynamic data (`dynamic_data`)
|
|
|
|
|
|
|
|
Dynamic data is a data snippet with a `prop_data_type` byte and the data next to it.
|
|
|
|
|
|
|
|
> **Note**: this section uses relative offset
|
|
|
|
|
2023-11-30 21:52:49 +01:00
|
|
|
| offset | size | name | description | example |
|
|
|
|
| ------ | --------------------------- | ---------------- | ----------------------- | ------- |
|
|
|
|
| `0x00` | 1 byte | `prop_data_type` | Describes the data type | `0x00` |
|
|
|
|
| `0x01` | depends on `prop_data_type` | `data` | The data | |
|
2023-10-15 18:06:18 +02:00
|
|
|
|
|
|
|
# Commands
|
|
|
|
|
|
|
|
These are the default commands. All Domo nodes should support these.
|
|
|
|
|
|
|
|
> **Note:** all offsets are *absolute*.
|
|
|
|
|
|
|
|
## `0x0*` - Node management
|
|
|
|
|
|
|
|
These are commands specifically for management of the nodes.
|
|
|
|
|
|
|
|
### `0x00` - Ping
|
|
|
|
|
|
|
|
Check to see if a node is up.
|
|
|
|
|
|
|
|
#### Command data
|
|
|
|
|
|
|
|
there is no command data.
|
|
|
|
|
|
|
|
### `0x01` - Register node
|
|
|
|
|
|
|
|
This command will register a node.
|
|
|
|
|
2023-10-15 18:06:26 +02:00
|
|
|
You can try to register as a node with a specific device_id but this might result in an error `0x03`.
|
|
|
|
Leave `0` to get a random id.
|
2023-10-15 18:06:18 +02:00
|
|
|
|
2023-10-15 18:06:26 +02:00
|
|
|
#### Command data
|
2023-10-15 18:06:18 +02:00
|
|
|
|
2023-10-15 18:06:26 +02:00
|
|
|
| offset | size | name | description | reserved | example |
|
2023-11-05 20:52:11 +01:00
|
|
|
| ------ | ------- | ----------- | ---------------------------------------------------------- | -------- | ------------ |
|
2023-10-15 18:06:26 +02:00
|
|
|
| `0x14` | 4 bytes | `device_id` | the device identifier. leave `0x00000000` to get random id | no | `0x00000000` |
|
2023-10-15 18:06:18 +02:00
|
|
|
|
|
|
|
### `0x02` - Remove node
|
|
|
|
|
|
|
|
Remove node from network
|
|
|
|
|
|
|
|
#### Command data
|
|
|
|
|
|
|
|
there is no extra data required.
|
|
|
|
|
2023-11-30 21:52:49 +01:00
|
|
|
### `0x0A` - Acknowledge packets
|
2023-10-15 18:06:18 +02:00
|
|
|
|
2023-11-30 21:52:49 +01:00
|
|
|
Acknowledge received packets.
|
2023-10-15 18:06:18 +02:00
|
|
|
|
2023-11-30 21:52:49 +01:00
|
|
|
| offset | size | name | description | reserved | example |
|
|
|
|
| ------ | ------------- | ----------- | ---------------------------------- | ----------- | ------- |
|
|
|
|
| `0x14` | 4 bytes * `n` | `packet_id` | list of packet_id's to acknowledge | origin node | |
|
2023-10-15 18:06:18 +02:00
|
|
|
|
|
|
|
### `0x0E` - Error
|
|
|
|
|
|
|
|
Send a packet to state an error occurred.
|
|
|
|
|
|
|
|
#### Command data
|
|
|
|
|
2023-11-30 21:52:49 +01:00
|
|
|
| offset | size | name | description | example |
|
|
|
|
| ------ | ------------- | ------------ | ------------------------------- | ------- |
|
|
|
|
| `0x14` | 1 byte | `error_code` | error code; check 'Error codes' | `0x00` |
|
|
|
|
| `0x15` | `data_length` | `metadata` | metadata | |
|
2023-10-15 18:06:18 +02:00
|
|
|
|
|
|
|
#### Error codes
|
|
|
|
|
2023-11-08 00:04:44 +01:00
|
|
|
| `status_code` | name | description | recoverable |
|
|
|
|
| ------------- | ----------------------- | --------------------------------------------------------------------- | --------------------------------- |
|
|
|
|
| `0x0*` | `net_*` | **Network errors** | |
|
|
|
|
| `0x00` | `net_broken_packet` | recent packet was broken; this packet's data did not arrive properly. | resend packet |
|
|
|
|
| `0x01` | `net_invalid_packet` | the packet sent is not valid; this packet's data does not make sense. | send packet with proper values |
|
|
|
|
| `0x02` | `net_dest_unreachable` | the destination could not be reached | no |
|
|
|
|
| `0x1*` | `mgmt_*` | **Management errors** | |
|
|
|
|
| `0x10` | `mgmt_duplicate_packet` | `packet_id` was used recently. | resend with different `packet_id` |
|
|
|
|
| `0x11` | `mgmt_addr_in_use` | the addr requested is in use already | register with another id or `0` |
|
|
|
|
| `0x12` | `mgmt_not_registered` | the src addr is not registered with the master node | register with another id or `0` |
|
|
|
|
| `0x13` | `mgmt_not_delivered` | the sent packet could not be delivered | register with another id or `0` |
|
|
|
|
| `0x2*` | `node_*` | **Node errors** | |
|
|
|
|
| `0x20` | `node_invalid_property` | the property specified is invalid | no |
|
|
|
|
| `0x21` | `node_failed_request` | the request could not be completed. | consult metadata |
|
2023-10-15 18:06:18 +02:00
|
|
|
|
2023-11-30 21:52:49 +01:00
|
|
|
|
2023-10-15 18:06:18 +02:00
|
|
|
## `0x1*` - Properties control
|
|
|
|
|
2023-11-30 21:52:49 +01:00
|
|
|
### `0x10` - Register property
|
|
|
|
|
|
|
|
#### Command data
|
|
|
|
|
|
|
|
| offset | size | name | description | reserved | example |
|
|
|
|
| ------ | -------- | --------------- | ---------------------------------------------- | -------- | ------- |
|
|
|
|
| `0x14` | 32 bytes | `property_name` | The name of the property as a UTF-8 string. | no | "Power" |
|
|
|
|
| `0x34` | 1 byte | `data_type` | The type of data; see "Data types". | no | `0x01` |
|
|
|
|
| `0x35` | 1 byte | `read_only` | Whether the property is readonly. (boolean) | no | `0x00` |
|
|
|
|
| `0x36` | 1 byte | `descriptive` | Whether the property is descriptive. (boolean) | no | `0x00` |
|
|
|
|
|
|
|
|
### `0x11` - Remove property
|
|
|
|
|
|
|
|
#### Command data
|
|
|
|
|
|
|
|
| offset | size | name | description | reserved | example |
|
|
|
|
| ------ | -------- | --------------- | ------------------------------------------- | -------- | ------- |
|
|
|
|
| `0x14` | 32 bytes | `property_name` | The name of the property as a UTF-8 string. | no | "Power" |
|
|
|
|
|
|
|
|
### `0x12` - Get property
|
2023-10-15 18:06:18 +02:00
|
|
|
|
|
|
|
Get a properties value
|
|
|
|
|
|
|
|
#### Command data
|
|
|
|
|
2023-11-30 21:52:49 +01:00
|
|
|
| offset | size | name | description | reserved | example |
|
|
|
|
| ------ | -------- | --------------- | ------------------------------------------- | ---------------- | -------- |
|
|
|
|
| `0x14` | 32 bytes | `property_name` | The name of the property as a UTF-8 string. | no | "Power" |
|
|
|
|
| `0x34` | dynamic | `dynamic_data` | Dynamic data snippet | destination node | `0x0100` |
|
2023-10-15 18:06:18 +02:00
|
|
|
|
2023-11-30 21:52:49 +01:00
|
|
|
### `0x13` - Set property
|
2023-10-15 18:06:18 +02:00
|
|
|
|
|
|
|
#### Command data
|
|
|
|
|
2023-10-15 18:06:20 +02:00
|
|
|
| offset | size | name | description | reserved | example |
|
2023-11-05 20:52:11 +01:00
|
|
|
| ------ | -------- | --------------- | ------------------------------------------- | -------- | -------- |
|
2023-10-15 18:06:20 +02:00
|
|
|
| `0x14` | 32 bytes | `property_name` | The name of the property as a UTF-8 string. | no | "Power" |
|
2023-11-05 20:52:11 +01:00
|
|
|
| `0x34` | dynamic | `dynamic_data` | Dynamic data snippet | no | `0x0100` |
|
2023-10-15 18:06:18 +02:00
|
|
|
|
2023-11-30 21:52:49 +01:00
|
|
|
### `0x14` - Reset property
|
2023-10-15 18:06:18 +02:00
|
|
|
|
|
|
|
#### Command data
|
|
|
|
|
|
|
|
| offset | size | name | description | reserved | example |
|
2023-11-05 20:52:11 +01:00
|
|
|
| ------ | -------- | --------------- | ------------------------------------------- | -------- | ------- |
|
2023-10-15 18:06:32 +02:00
|
|
|
| `0x14` | 32 bytes | `property_name` | The name of the property as a UTF-8 string. | no | "Power" |
|
|
|
|
|
|
|
|
### `0x1A` - Subscribe to property
|
|
|
|
|
|
|
|
| offset | size | name | description | reserved | example |
|
2023-11-05 20:52:11 +01:00
|
|
|
| ------ | -------- | --------------- | ------------------------------------------- | -------- | ------------ |
|
2023-10-15 18:06:32 +02:00
|
|
|
| `0x14` | 4 bytes | `device_id` | Who's property? | no | `0x00000000` |
|
|
|
|
| `0x18` | 32 bytes | `property_name` | The name of the property as a UTF-8 string. | no | "Power" |
|
|
|
|
|
2023-11-30 21:52:49 +01:00
|
|
|
### `0x1B` - Unsubscribe to property
|
2023-10-15 18:06:32 +02:00
|
|
|
|
|
|
|
| offset | size | name | description | reserved | example |
|
2023-11-05 20:52:11 +01:00
|
|
|
| ------ | -------- | --------------- | ------------------------------------------- | -------- | ------------ |
|
2023-10-15 18:06:32 +02:00
|
|
|
| `0x14` | 4 bytes | `device_id` | Who's property? | no | `0x00000000` |
|
|
|
|
| `0x18` | 32 bytes | `property_name` | The name of the property as a UTF-8 string. | no | "Power" |
|
2023-11-05 20:52:11 +01:00
|
|
|
|
2023-11-30 21:52:49 +01:00
|
|
|
### `0x1F` - All properties
|
|
|
|
|
|
|
|
Return all properties.
|
|
|
|
|
|
|
|
#### Command data
|
|
|
|
|
|
|
|
| offset | size | name | description | reserved | example |
|
|
|
|
| ------ | ------ | ------ | ------------------------- | -------- | ------- |
|
|
|
|
| `0x14` | 1 byte | `type` | | no | `0x00` |
|
|
|
|
| | | | `0x00` - all | | |
|
|
|
|
| | | | `0x01` - descriptive only | | |
|
|
|
|
| | | | `0x02` - m only | | |
|
|
|
|
|
2023-11-05 20:52:11 +01:00
|
|
|
## `0xF*` - Raw data transmission
|
|
|
|
|
|
|
|
This is useful for things like OTA updates.
|
|
|
|
|
|
|
|
### `0xF0` - Setup transfer
|
|
|
|
|
|
|
|
Since this procedure is quite expensive (network wise), the sides must shake hands.
|
|
|
|
|
|
|
|
#### Command data
|
|
|
|
|
2023-11-30 21:52:49 +01:00
|
|
|
| offset | size | name | description | reserved | example |
|
|
|
|
| ------ | --------- | ------ | -------------------- | ----------- | ------- |
|
|
|
|
| `0x14` | 8 bytes | `size` | u64 size of the data | origin node | `0x00` |
|
|
|
|
| `0x1c` | 128 bytes | `mime` | media type of data | origin node | `0x00` |
|
2023-11-05 20:52:11 +01:00
|
|
|
|
|
|
|
### `0xF1` - Data
|
|
|
|
|
|
|
|
This is raw data.
|
|
|
|
This may be sent without the initial transfer setup for custom implementations.
|
|
|
|
|
|
|
|
#### Command data
|
|
|
|
|
|
|
|
The `sequence_number` is added for redundancy, all data sent will always reply to it's previous data segment.
|
|
|
|
|
2023-11-30 21:52:49 +01:00
|
|
|
| offset | size | name | description | example |
|
|
|
|
| ------ | ------------- | ----------------- | ------------------------------- | ------------ |
|
|
|
|
| `0x14` | 4 bytes | `sequence_number` | the sequence number of the data | `0x00000000` |
|
|
|
|
| `0x18` | `data_length` | `data` | the data | |
|