> **Version:** `1` > **Authored by:** `Raine ` > **Status**: `planning` # Prelude Version 1 has zero security on itself. # Structure Packets are sent in big endian. | offset | size | name | description | example | | -------------------------------- | ------------------------- | ------------- | ---------------------------------------------------------------------------------- | ------------ | | `0x00` | 1 byte | `version` | This describes the version of the packet | `0x01` | | `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` | | `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` | | `0x14` | `<0x11-0x12:data_length>` | `data` | This is the data of the command | `0x0000` | | `0x14 + <0x11-0x12:data_length>` | 4 bytes | `checksum` | This is the CRC32 checksum of the packet without the checksum. | `0x00000000` | # Packets in practice ## Statuses When an error occurs the response should be a `0x0E` (error command). This can contain error data. To mark a success, you should just send back the expected response. ## 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. # Error checking If the CRC32 doesn't match up the receiver will send a `0x0E` (error) packet to the probable source. The error code `0x01`/`net_broken_packet` should be used. The metadata may contain some textual info on what went wrong. The master will not track the broken packet's `packet_id`, so the slave can send it again. # Data types Domo has a data framework reliant on data types. These define what kind of data the property holds. | `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. | ## 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 | offset | size | name | description | example | | ------ | ----------------------------- | ---------------- | ----------------------- | ------- | | `0x00` | 1 byte | `prop_data_type` | Describes the data type | `0x00` | | `0x01` | depending on `prop_data_type` | `data` | The data | | # 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. 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. #### Command data | offset | size | name | description | reserved | example | | ------ | ------- | ----------- | ---------------------------------------------------------- | -------- | ------------ | | `0x14` | 4 bytes | `device_id` | the device identifier. leave `0x00000000` to get random id | no | `0x00000000` | ### `0x02` - Remove node Remove node from network #### Command data there is no extra data required. ### `0x03` - 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.
(`0x00` = no, `0x01` = yes) | no | `0x00` | ### `0x04` - 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" | ### `0x0E` - Error Send a packet to state an error occurred. #### Command data | offset | size | name | description | example | | ------ | ----------------------------- | ------------ | ------------------------------- | ------- | | `0x14` | 1 byte | `error_code` | error code; check 'Error codes' | `0x00` | | `0x15` | `<0x14-0x15:metadata_length>` | `metadata` | metadata | | #### Error codes | `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 | ## `0x1*` - Properties control ### `0x10` - Get property Get a properties value #### 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` | dynamic | `dynamic_data` | Dynamic data snippet | response | `0x0100` | ### `0x11` - Set 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` | dynamic | `dynamic_data` | Dynamic data snippet | no | `0x0100` | ### `0x12` - Reset 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" | ### `0x1A` - Subscribe to property | offset | size | name | description | reserved | example | | ------ | -------- | --------------- | ------------------------------------------- | -------- | ------------ | | `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" | ### `0x1A` - Unsubscribe to property | offset | size | name | description | reserved | example | | ------ | -------- | --------------- | ------------------------------------------- | -------- | ------------ | | `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" | ## `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 | offset | size | name | description | reserved | example | | ------ | --------- | ------ | -------------------- | -------- | ------- | | `0x14` | 8 bytes | `size` | u64 size of the data | request | `0x00` | | `0x1c` | 128 bytes | `mime` | media type of data | request | `0x00` | ### `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. | offset | size | name | description | example | | ------ | -------- | ----------------- | ------------------------------- | ------------ | | `0x14` | 4 bytes | `sequence_number` | the sequence number of the data | `0x00000000` | | `0x18` | `` | `data` | the data | |