HELLO_RESP

The HELLO_RESP payload (type 0x81) is the device's self-description. The host sends HELLO (0x02), and the device responds with this binary structure containing hardware capabilities, loaded modules, and declared datastreams.

Binary Layout

OffsetFieldSizeDescription
0firmware_name16Null-padded UTF-8 string
16version_major1Firmware major version
17version_minor1Firmware minor version
18version_patch1Firmware patch version
19mcu_id8Unique MCU identifier (or zeros)
27ota_capable10x01 if OTA supported
28pin_count1Number of GPIO pins (N)
29pinsNx1Per-pin capability bitmask
29+Ni2c_buses1Number of I2C buses
30+Nspi_buses1Number of SPI buses
31+Nuart_count1Number of UARTs
32+Nmax_payload2Max payload size (LE uint16)
34+Nmodule_count1Number of loaded modules (M)
35+NmodulesvarPer-module descriptors
vards_count1Number of datastreams (D)
vardatastreamsvarPer-datastream descriptors

Pin Capability Bitmask

Each byte in pins[] is a bitmask of supported modes for that pin.

BitCapabilityConstant
0DIGITAL_INCONDUYT_PIN_CAP_DIGITAL_IN
1DIGITAL_OUTCONDUYT_PIN_CAP_DIGITAL_OUT
2PWM_OUTCONDUYT_PIN_CAP_PWM_OUT
3ANALOG_INCONDUYT_PIN_CAP_ANALOG_IN
4I2C_SDACONDUYT_PIN_CAP_I2C_SDA
5I2C_SCLCONDUYT_PIN_CAP_I2C_SCL
6SPICONDUYT_PIN_CAP_SPI
7INTERRUPTCONDUYT_PIN_CAP_INTERRUPT

Example: a pin with bitmask 0x0F (bits 0-3 set) supports digital input, digital output, PWM, and analog input.

Module Descriptor

Each entry in modules[] follows this layout:

FieldSizeDescription
module_id1Index in the modules array
name8Null-padded name (e.g., "servo")
version_major1Module major version
version_minor1Module minor version
pin_count1Number of claimed pins
pinspin_countPhysical pin numbers

Total size per module: 12 + pin_count bytes.

Datastream Descriptor

Each entry in datastreams[] follows this layout:

FieldSizeDescription
name16Null-padded name
type1CONDUYT_TYPE_* code (see Datastream Types)
unit8Null-padded unit string (e.g., "celsius")
writable10x01 if host can write
pin_ref1Associated pin (0xFF if none)
retain10x01 if value is retained

Total size per datastream: 28 bytes.

Worked Example

A device named "MyBoard" running firmware 1.0.0, with 3 GPIO pins and one servo module. No OTA, no I2C/SPI/UART buses, no datastreams.

Offset  Hex                                              Field
------  -----------------------------------------------  -----
00-0F   4D 79 42 6F 61 72 64 00 00 00 00 00 00 00 00 00 firmware_name = "MyBoard\0\0\0\0\0\0\0\0\0"
10      01                                               version_major = 1
11      00                                               version_minor = 0
12      00                                               version_patch = 0
13-1A   00 00 00 00 00 00 00 00                          mcu_id = all zeros
1B      00                                               ota_capable = 0 (no OTA)
1C      03                                               pin_count = 3
1D      0F                                               pin[0] caps = 0x0F (DIN, DOUT, PWM, AIN)
1E      03                                               pin[1] caps = 0x03 (DIN, DOUT)
1F      03                                               pin[13] caps = 0x03 (DIN, DOUT)
20      00                                               i2c_buses = 0
21      00                                               spi_buses = 0
22      00                                               uart_count = 0
23-24   80 00                                            max_payload = 128 (0x0080 LE)
25      01                                               module_count = 1
-- module 0 --
26      00                                               module_id = 0
27-2E   73 65 72 76 6F 00 00 00                          name = "servo\0\0\0"
2F      01                                               version_major = 1
30      00                                               version_minor = 0
31      01                                               pin_count = 1
32      09                                               pins[0] = pin 9
-- end modules --
33      00                                               ds_count = 0

Parsing walkthrough:

  1. Read 16 bytes at offset 0x00: firmware name is "MyBoard" (remaining bytes are 0x00 padding).
  2. Read 3 bytes at 0x10-0x12: firmware version 1.0.0.
  3. Read 8 bytes at 0x13-0x1A: MCU ID is all zeros (no unique ID set).
  4. Read 1 byte at 0x1B: OTA not supported.
  5. Read 1 byte at 0x1C: 3 pins declared. Read the next 3 bytes as pin capability bitmasks. Pin 0 has 0x0F (digital in, digital out, PWM, analog in). Pins 1 and 13 each have 0x03 (digital in, digital out).
  6. Read bus counts at 0x20-0x22: 0 I2C, 0 SPI, 0 UART.
  7. Read 2 bytes at 0x23-0x24: max payload is 128 bytes (0x80 0x00 little-endian = 128).
  8. Read 1 byte at 0x25: 1 module. Parse the module descriptor starting at 0x26: id=0, name="servo", version 1.0, claims 1 pin (pin 9).
  9. Read 1 byte at 0x33: 0 datastreams. Parsing is complete.

Total HELLO_RESP payload size for this device: 52 bytes.