Browse Source

docs: fix broken and misaligned tables

pull/2635/head
Sefinek 1 month ago
parent
commit
2adea02e9c
  1. 18
      docs/companion_protocol.md
  2. 72
      docs/faq.md
  3. 246
      docs/kiss_modem_protocol.md
  4. 98
      docs/nrf52_power_management.md
  5. 32
      docs/packet_format.md
  6. 94
      docs/payloads.md
  7. 68
      docs/stats_binary_frames.md

18
docs/companion_protocol.md

@ -320,13 +320,13 @@ Remaining bytes: Binary payload (variable length)
`data_type` is an **application identifier**, not a payload-format identifier. Each registered value identifies an application that owns its own internal payload schemas. The firmware does not inspect payload contents — `data_type` is transported opaquely. `data_type` is an **application identifier**, not a payload-format identifier. Each registered value identifies an application that owns its own internal payload schemas. The firmware does not inspect payload contents — `data_type` is transported opaquely.
| Value | Constant | Purpose | | Value | Constant | Purpose |
|-----------------|----------------------|--------------------------------------------------------------------------| |-----------------|----------------------|----------------------------------------------------------------------------------------|
| 0x0000 | `DATA_TYPE_RESERVED` | Reserved; invalid on send | | 0x0000 | `DATA_TYPE_RESERVED` | Reserved; invalid on send |
| 0x0001 – 0x00FF | — | Reserved for internal use | | 0x0001 – 0x00FF | — | Reserved for internal use |
| 0x0100 – 0xFEFF | — | Registered application namespaces (see [number_allocations.md](number_allocations.md)) | | 0x0100 – 0xFEFF | — | Registered application namespaces (see [number_allocations.md](number_allocations.md)) |
| 0xFF00 – 0xFFFE | — | Testing/development; no registration required | | 0xFF00 – 0xFFFE | — | Testing/development; no registration required |
| 0xFFFF | `DATA_TYPE_DEV` | Developer/experimental namespace | | 0xFFFF | `DATA_TYPE_DEV` | Developer/experimental namespace |
To register a new application, submit a PR adding a row to the table in [docs/number_allocations.md](number_allocations.md). Internal sub-formats within an allocated application ID are owned by that application and are not tracked in MeshCore firmware or this document. To register a new application, submit a PR adding a row to the table in [docs/number_allocations.md](number_allocations.md). Internal sub-formats within an allocated application ID are owned by that application and are not tracked in MeshCore firmware or this document.
@ -352,10 +352,10 @@ Bytes 9 .. 8+data_len: Payload
**Path Length semantics differ between send and receive**: **Path Length semantics differ between send and receive**:
| Direction | `path_len = 0xFF` | `path_len ≠ 0xFF` | | Direction | `path_len = 0xFF` | `path_len ≠ 0xFF` |
|-----------|---------------------------------|-------------------------------------------------------------------------------------| |-----------|---------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------|
| Send | Flood the network | Direct route; the encoded path follows (low 6 bits = hash count, top 2 bits + 1 = hash size; on-wire byte count = `hash_count × hash_size`) | | Send | Flood the network | Direct route; the encoded path follows (low 6 bits = hash count, top 2 bits + 1 = hash size; on-wire byte count = `hash_count × hash_size`) |
| Receive | Packet arrived via direct route | Packet was flooded; this is the encoded `pkt->path_len` field as observed (no path bytes follow) | | Receive | Packet arrived via direct route | Packet was flooded; this is the encoded `pkt->path_len` field as observed (no path bytes follow) |
In other words, the meaning of `0xFF` is inverted between the two directions, and on receive the field carries metadata only — never a routable path. `path_len` is an encoded byte (see `Packet::isValidPathLen` / `Packet::writePath` in `src/Packet.cpp`), not a raw byte count. In other words, the meaning of `0xFF` is inverted between the two directions, and on receive the field carries metadata only — never a routable path. `path_len` is an encoded byte (see `Packet::isValidPathLen` / `Packet::writePath` in `src/Packet.cpp`), not a raw byte count.

72
docs/faq.md

@ -717,15 +717,15 @@ You can get the epoch time on <https://www.epochconverter.com/> and use it to se
- For T1000-e, quickly disconnect and reconnect the magnetic side of the cable from the device **TWICE** - For T1000-e, quickly disconnect and reconnect the magnetic side of the cable from the device **TWICE**
- For Heltec T114, click the reset button **TWICE** (the bottom button) - For Heltec T114, click the reset button **TWICE** (the bottom button)
- For Xiao nRF52, click the reset button once. If that doesn't work, quickly double click the reset button twice. If that doesn't work, disconnect the board from your PC and reconnect again ([seeed studio wiki](https://wiki.seeedstudio.com/XIAO_BLE/#access-the-swd-pins-for-debugging-and-reflashing-bootloader)) - For Xiao nRF52, click the reset button once. If that doesn't work, quickly double click the reset button twice. If that doesn't work, disconnect the board from your PC and reconnect again ([seeed studio wiki](https://wiki.seeedstudio.com/XIAO_BLE/#access-the-swd-pins-for-debugging-and-reflashing-bootloader))
5. A new folder will appear on your computer's desktop 2. A new folder will appear on your computer's desktop
6. Download the `flash_erase*.uf2` file for your device on https://flasher.meshcore.io 3. Download the `flash_erase*.uf2` file for your device on https://flasher.meshcore.io
- RAK WisBlock and Heltec T114: `Flash_erase-nRF32_softdevice_v6.uf2` - RAK WisBlock and Heltec T114: `Flash_erase-nRF32_softdevice_v6.uf2`
- Seeed Studio Xiao nRF52 WIO: `Flash_erase-nRF52_softdevice_v7.uf2` - Seeed Studio Xiao nRF52 WIO: `Flash_erase-nRF52_softdevice_v7.uf2`
8. drag and drop the uf2 file for your device to the root of the new folder 4. drag and drop the uf2 file for your device to the root of the new folder
9. Wait for the copy to complete. You might get an error dialog, you can ignore it 5. Wait for the copy to complete. You might get an error dialog, you can ignore it
10. Go to https://flasher.meshcore.io, click `Console` and select the serial port for your connected device 6. Go to https://flasher.meshcore.io, click `Console` and select the serial port for your connected device
11. In the console, press enter. Your flash should now be erased 7. In the console, press enter. Your flash should now be erased
12. You may now flash the latest MeshCore firmware onto your device 8. You may now flash the latest MeshCore firmware onto your device
Separately, starting in firmware version 1.7.0, there is a CLI Rescue mode. If your device has a user button (e.g. some RAK, T114), you can activate the rescue mode by hold down the user button of the device within 8 seconds of boot. Then you can use the 'Console' on https://flasher.meshcore.io Separately, starting in firmware version 1.7.0, there is a CLI Rescue mode. If your device has a user button (e.g. some RAK, T114), you can activate the rescue mode by hold down the user button of the device within 8 seconds of boot. Then you can use the 'Console' on https://flasher.meshcore.io
@ -751,15 +751,15 @@ Allow the browser user on it:
5. you should see `OK` to confirm the repeater device is now in OTA mode 5. you should see `OK` to confirm the repeater device is now in OTA mode
6. Run the DFU app,tab `Settings` on the top right corner 6. Run the DFU app,tab `Settings` on the top right corner
7. Enable `Packets receipt notifications`, and change `Number of Packets` to 10 for RAK, 8 for T114. 8 also works for RAK. 7. Enable `Packets receipt notifications`, and change `Number of Packets` to 10 for RAK, 8 for T114. 8 also works for RAK.
9. Select the firmware zip file you downloaded 8. Select the firmware zip file you downloaded
10. Select the device you want to update. If the device you want to update is not on the list, try enabling`OTA` on the device again 9. Select the device you want to update. If the device you want to update is not on the list, try enabling`OTA` on the device again
11. If the device is not found, enable `Force Scanning` in the DFU app 10. If the device is not found, enable `Force Scanning` in the DFU app
12. Tab the `Upload` to begin OTA update 11. Tab the `Upload` to begin OTA update
13. If it fails, try turning off and on Bluetooth on your phone. If that doesn't work, try rebooting your phone. If you keep getting failures at the "Enabling Bootloader" step, try forgetting the NRF board in your iOS or Android device's bluetooth settings and re-pair it through the DFU app. 12. If it fails, try turning off and on Bluetooth on your phone. If that doesn't work, try rebooting your phone. If you keep getting failures at the "Enabling Bootloader" step, try forgetting the NRF board in your iOS or Android device's bluetooth settings and re-pair it through the DFU app.
14. Wait for the update to complete. It can take a few minutes. 13. Wait for the update to complete. It can take a few minutes.
15. It is strongly recommended that you install and use the OTAFIX bootloader at https://github.com/oltaco/Adafruit_nRF52_Bootloader_OTAFIX. 14. It is strongly recommended that you install and use the OTAFIX bootloader at https://github.com/oltaco/Adafruit_nRF52_Bootloader_OTAFIX.
16. To update a companion node over OTA, it must be running companion firmware v1.15 or greater. 15. To update a companion node over OTA, it must be running companion firmware v1.15 or greater.
17. Please see the MeshCore Blog for additional information on OTA firmware flashing: 16. Please see the MeshCore Blog for additional information on OTA firmware flashing:
- https://blog.meshcore.io/2026/04/06/otafix-bootloader - https://blog.meshcore.io/2026/04/06/otafix-bootloader
- https://blog.meshcore.io/2026/04/02/nrf-ota-update - https://blog.meshcore.io/2026/04/02/nrf-ota-update
@ -776,11 +776,11 @@ After this bootloader is flashed onto the device, you can trigger over the air u
**A:** For ESP32-based devices (e.g. Heltec V3): **A:** For ESP32-based devices (e.g. Heltec V3):
1. On https://flasher.meshcore.io, download the **non-merged** version of the firmware for your ESP32 device (e.g. `Heltec_v3_repeater-v1.6.2-4449fd3.bin`, no `"merged"` in the file name) 1. On https://flasher.meshcore.io, download the **non-merged** version of the firmware for your ESP32 device (e.g. `Heltec_v3_repeater-v1.6.2-4449fd3.bin`, no `"merged"` in the file name)
2. From the MeshCore app, login remotely to the repeater you want to update with admin privilege 2. From the MeshCore app, login remotely to the repeater you want to update with admin privilege
4. Go to the Command Line tab, type `start ota` and hit enter. 3. Go to the Command Line tab, type `start ota` and hit enter.
5. you should see `OK` to confirm the repeater device is now in OTA mode 4. you should see `OK` to confirm the repeater device is now in OTA mode
6. The command `start ota` on an ESP32-based device starts a Wi-Fi hotspot named `MeshCore OTA` 5. The command `start ota` on an ESP32-based device starts a Wi-Fi hotspot named `MeshCore OTA`
7. From your phone or computer connect to the 'MeshCore OTA' hotspot 6. From your phone or computer connect to the 'MeshCore OTA' hotspot
8. From a browser, go to http://192.168.4.1/update and upload the non-merged bin from the flasher 7. From a browser, go to http://192.168.4.1/update and upload the non-merged bin from the flasher
### 7.3. Q: Is there a way to lower the chance of a failed OTA device firmware update (DFU)? ### 7.3. Q: Is there a way to lower the chance of a failed OTA device firmware update (DFU)?
@ -820,27 +820,27 @@ where `&type` is:
`sensor = 4` `sensor = 4`
### 7.6. Q: How do I connect to the companion via Wi-Fi, e.g. using a heltec v3? ### 7.6. Q: How do I connect to the companion via Wi-Fi, e.g. using a heltec v3?
**A:** **A:**
Wi-Fi firmware requires you to compile it yourself, as you need to set the wifi ssid and password. Wi-Fi firmware requires you to compile it yourself, as you need to set the Wi-Fi ssid and password.
Edit WIFI_SSID and WIFI_PWD in `./variants/heltec_v3/platformio.ini` and then flash it to your device. Edit WIFI_SSID and WIFI_PWD in `./variants/heltec_v3/platformio.ini` and then flash it to your device.
### 7.7. Q: I have a Station G2, or a Heltec V4, or an Ikoka Stick, or a radio with a EByte E22-900M30S or a E22-900M33S module, what should their transmit power be set to? ### 7.7. Q: I have a Station G2, or a Heltec V4, or an Ikoka Stick, or a radio with a EByte E22-900M30S or a E22-900M33S module, what should their transmit power be set to?
**A:** **A:**
For companion radios, you can set these radios' transmit power in the smartphone app. For repeater and room server radios, you can set their transmit power using the command line command `set tx`. You can get their current value using command line command `get tx` For companion radios, you can set these radios' transmit power in the smartphone app. For repeater and room server radios, you can set their transmit power using the command line command `set tx`. You can get their current value using command line command `get tx`
⚠️ **WARNING: Set these values at your own risk. Incorrect power settings can permanently damage your radio hardware.** ⚠️ **WARNING: Set these values at your own risk. Incorrect power settings can permanently damage your radio hardware.**
| Device / Model | Region / Description | In-App Setting (dBm) | Target Radio Output | Notes | | Device / Model | Region / Description | In-App Setting (dBm) | Target Radio Output | Notes |
| :--- | :--- | :--- | :--- | :--- | |:-----------------------------------------------------------------------------------|:------------------------------------|:---------------------|:-----------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------|
| **Station G2** <br> [Reference](https://wiki.uniteng.com/en/meshtastic/station-g2) | US915 Max Output | 19 dBm | 36.5 dBm (4.46W) | | | **Station G2** <br> [Reference](https://wiki.uniteng.com/en/meshtastic/station-g2) | US915 Max Output | 19 dBm | 36.5 dBm (4.46W) | |
| | US915 Max at 1dB compression point | 16 dBm | 35 dBm (3.16W) | 1dB compression point | | | US915 Max at 1dB compression point | 16 dBm | 35 dBm (3.16W) | 1dB compression point |
| | EU868 Max at 1dB compression point | 15 dBm | 34.5 dBm (2.82W) | 1dB compression point | | | EU868 Max at 1dB compression point | 15 dBm | 34.5 dBm (2.82W) | 1dB compression point |
| | US915 1W Output | 10 dBm | 1W | Refer to your local government's requirements | | | US915 1W Output | 10 dBm | 1W | Refer to your local government's requirements |
| | EU868 1W Output | 9 dBm | 1W |Refer to your local government's requirements | | | EU868 1W Output | 9 dBm | 1W | Refer to your local government's requirements |
| **Ikoka Stick E22-900M30S** | 1W Model | 19 dBm | 1W | **DO NOT EXCEED** (Risk of burn out) [data sheet](https://www.cdebyte.com/pdf-down.aspx?id=4216) | | **Ikoka Stick E22-900M30S** | 1W Model | 19 dBm | 1W | **DO NOT EXCEED** (Risk of burn out) [data sheet](https://www.cdebyte.com/pdf-down.aspx?id=4216) |
| **Ikoka Stick E22-900M33S** | 2W Model | 9 dBm | 2W | **DO NOT EXCEED** (Risk of burn out) [data sheet](https://www.cdebyte.com/pdf-down.aspx?id=4216) Refer to your local government's requirements | | **Ikoka Stick E22-900M33S** | 2W Model | 9 dBm | 2W | **DO NOT EXCEED** (Risk of burn out) [data sheet](https://www.cdebyte.com/pdf-down.aspx?id=4216) Refer to your local government's requirements |
| **Heltec V4** | Standard Output | 10 dBm | 22 dBm (~0.15W) | | | **Heltec V4** | Standard Output | 10 dBm | 22 dBm (~0.15W) | |
| | High Output | 22 dBm | 28 dBm (~0.5W to 0.6W) | | | | High Output | 22 dBm | 28 dBm (~0.5W to 0.6W) | |
--- ---

246
docs/kiss_modem_protocol.md

@ -10,10 +10,10 @@ Standard KISS TNC firmware for MeshCore LoRa radios. Compatible with any KISS cl
Standard KISS framing per the KA9Q/K3MC specification. Standard KISS framing per the KA9Q/K3MC specification.
| Byte | Name | Description | | Byte | Name | Description |
|------|------|-------------| |--------|-------|------------------------------------|
| `0xC0` | FEND | Frame delimiter | | `0xC0` | FEND | Frame delimiter |
| `0xDB` | FESC | Escape character | | `0xDB` | FESC | Escape character |
| `0xDC` | TFEND | Escaped FEND (FESC + TFEND = 0xC0) | | `0xDC` | TFEND | Escaped FEND (FESC + TFEND = 0xC0) |
| `0xDD` | TFESC | Escaped FESC (FESC + TFESC = 0xDB) | | `0xDD` | TFESC | Escaped FESC (FESC + TFESC = 0xDB) |
@ -28,10 +28,10 @@ Standard KISS framing per the KA9Q/K3MC specification.
The type byte is split into two nibbles: The type byte is split into two nibbles:
| Bits | Field | Description | | Bits | Field | Description |
|------|-------|-------------| |------|---------|-------------------------------------|
| 7-4 | Port | Port number (0 for single-port TNC) | | 7-4 | Port | Port number (0 for single-port TNC) |
| 3-0 | Command | Command number | | 3-0 | Command | Command number |
Maximum unescaped frame size: 512 bytes. Maximum unescaped frame size: 512 bytes.
@ -39,21 +39,21 @@ Maximum unescaped frame size: 512 bytes.
### Host to TNC ### Host to TNC
| Command | Value | Data | Description | | Command | Value | Data | Description |
|---------|-------|------|-------------| |-------------|--------|--------------------|-------------------------------------------------------------|
| Data | `0x00` | Raw packet | Queue packet for transmission | | Data | `0x00` | Raw packet | Queue packet for transmission |
| TXDELAY | `0x01` | Delay (1 byte) | Transmitter keyup delay in 10ms units (default: 50 = 500ms) | | TXDELAY | `0x01` | Delay (1 byte) | Transmitter keyup delay in 10ms units (default: 50 = 500ms) |
| Persistence | `0x02` | P (1 byte) | CSMA persistence parameter 0-255 (default: 63) | | Persistence | `0x02` | P (1 byte) | CSMA persistence parameter 0-255 (default: 63) |
| SlotTime | `0x03` | Interval (1 byte) | CSMA slot interval in 10ms units (default: 10 = 100ms) | | SlotTime | `0x03` | Interval (1 byte) | CSMA slot interval in 10ms units (default: 10 = 100ms) |
| TXtail | `0x04` | Delay (1 byte) | Post-TX hold time in 10ms units (default: 0) | | TXtail | `0x04` | Delay (1 byte) | Post-TX hold time in 10ms units (default: 0) |
| FullDuplex | `0x05` | Mode (1 byte) | 0 = half duplex, nonzero = full duplex (default: 0) | | FullDuplex | `0x05` | Mode (1 byte) | 0 = half duplex, nonzero = full duplex (default: 0) |
| SetHardware | `0x06` | Sub-command + data | MeshCore extensions (see below) | | SetHardware | `0x06` | Sub-command + data | MeshCore extensions (see below) |
| Return | `0xFF` | - | Exit KISS mode (no-op) | | Return | `0xFF` | - | Exit KISS mode (no-op) |
### TNC to Host ### TNC to Host
| Type | Value | Data | Description | | Type | Value | Data | Description |
|------|-------|------|-------------| |------|--------|------------|----------------------------|
| Data | `0x00` | Raw packet | Received packet from radio | | Data | `0x00` | Raw packet | Received packet from radio |
Data frames carry raw packet data only, with no metadata prepended. The Data command payload is limited to 255 bytes to match the MeshCore maximum transmission unit (MAX_TRANS_UNIT); frames larger than 255 bytes are silently dropped. The KISS specification recommends at least 1024 bytes for general-purpose TNCs; this modem is intended for MeshCore packets only, whose protocol MTU is 255 bytes. Data frames carry raw packet data only, with no metadata prepended. The Data command payload is limited to 255 bytes to match the MeshCore maximum transmission unit (MAX_TRANS_UNIT); frames larger than 255 bytes are silently dropped. The KISS specification recommends at least 1024 bytes for general-purpose TNCs; this modem is intended for MeshCore packets only, whose protocol MTU is 255 bytes.
@ -84,79 +84,79 @@ MeshCore-specific functionality uses the standard KISS SetHardware command. The
### Request Sub-commands (Host to TNC) ### Request Sub-commands (Host to TNC)
| Sub-command | Value | Data | | Sub-command | Value | Data |
|-------------|-------|------| |-----------------|--------|------------------------------------------|
| GetIdentity | `0x01` | - | | GetIdentity | `0x01` | - |
| GetRandom | `0x02` | Length (1 byte, 1-64) | | GetRandom | `0x02` | Length (1 byte, 1-64) |
| VerifySignature | `0x03` | PubKey (32) + Signature (64) + Data | | VerifySignature | `0x03` | PubKey (32) + Signature (64) + Data |
| SignData | `0x04` | Data to sign | | SignData | `0x04` | Data to sign |
| EncryptData | `0x05` | Key (32) + Plaintext | | EncryptData | `0x05` | Key (32) + Plaintext |
| DecryptData | `0x06` | Key (32) + MAC (2) + Ciphertext | | DecryptData | `0x06` | Key (32) + MAC (2) + Ciphertext |
| KeyExchange | `0x07` | Remote PubKey (32) | | KeyExchange | `0x07` | Remote PubKey (32) |
| Hash | `0x08` | Data to hash | | Hash | `0x08` | Data to hash |
| SetRadio | `0x09` | Freq (4) + BW (4) + SF (1) + CR (1) | | SetRadio | `0x09` | Freq (4) + BW (4) + SF (1) + CR (1) |
| SetTxPower | `0x0A` | Power dBm (1) | | SetTxPower | `0x0A` | Power dBm (1) |
| GetRadio | `0x0B` | - | | GetRadio | `0x0B` | - |
| GetTxPower | `0x0C` | - | | GetTxPower | `0x0C` | - |
| GetCurrentRssi | `0x0D` | - | | GetCurrentRssi | `0x0D` | - |
| IsChannelBusy | `0x0E` | - | | IsChannelBusy | `0x0E` | - |
| GetAirtime | `0x0F` | Packet length (1) | | GetAirtime | `0x0F` | Packet length (1) |
| GetNoiseFloor | `0x10` | - | | GetNoiseFloor | `0x10` | - |
| GetVersion | `0x11` | - | | GetVersion | `0x11` | - |
| GetStats | `0x12` | - | | GetStats | `0x12` | - |
| GetBattery | `0x13` | - | | GetBattery | `0x13` | - |
| GetMCUTemp | `0x14` | - | | GetMCUTemp | `0x14` | - |
| GetSensors | `0x15` | Permissions (1) | | GetSensors | `0x15` | Permissions (1) |
| GetDeviceName | `0x16` | - | | GetDeviceName | `0x16` | - |
| Ping | `0x17` | - | | Ping | `0x17` | - |
| Reboot | `0x18` | - | | Reboot | `0x18` | - |
| SetSignalReport | `0x19` | Enable (1): 0x00=disable, nonzero=enable | | SetSignalReport | `0x19` | Enable (1): 0x00=disable, nonzero=enable |
| GetSignalReport | `0x1A` | - | | GetSignalReport | `0x1A` | - |
### Response Sub-commands (TNC to Host) ### Response Sub-commands (TNC to Host)
Response codes use the high-bit convention: `response = command | 0x80`. Generic and unsolicited responses use the `0xF0`+ range. Response codes use the high-bit convention: `response = command | 0x80`. Generic and unsolicited responses use the `0xF0`+ range.
| Sub-command | Value | Data | | Sub-command | Value | Data |
|-------------|-------|------| |--------------|--------|-----------------------------------------|
| Identity | `0x81` | PubKey (32) | | Identity | `0x81` | PubKey (32) |
| Random | `0x82` | Random bytes (1-64) | | Random | `0x82` | Random bytes (1-64) |
| Verify | `0x83` | Result (1): 0x00=invalid, 0x01=valid | | Verify | `0x83` | Result (1): 0x00=invalid, 0x01=valid |
| Signature | `0x84` | Signature (64) | | Signature | `0x84` | Signature (64) |
| Encrypted | `0x85` | MAC (2) + Ciphertext | | Encrypted | `0x85` | MAC (2) + Ciphertext |
| Decrypted | `0x86` | Plaintext | | Decrypted | `0x86` | Plaintext |
| SharedSecret | `0x87` | Shared secret (32) | | SharedSecret | `0x87` | Shared secret (32) |
| Hash | `0x88` | SHA-256 hash (32) | | Hash | `0x88` | SHA-256 hash (32) |
| Radio | `0x8B` | Freq (4) + BW (4) + SF (1) + CR (1) | | Radio | `0x8B` | Freq (4) + BW (4) + SF (1) + CR (1) |
| TxPower | `0x8C` | Power dBm (1) | | TxPower | `0x8C` | Power dBm (1) |
| CurrentRssi | `0x8D` | RSSI dBm (1, signed) | | CurrentRssi | `0x8D` | RSSI dBm (1, signed) |
| ChannelBusy | `0x8E` | Result (1): 0x00=clear, 0x01=busy | | ChannelBusy | `0x8E` | Result (1): 0x00=clear, 0x01=busy |
| Airtime | `0x8F` | Milliseconds (4) | | Airtime | `0x8F` | Milliseconds (4) |
| NoiseFloor | `0x90` | dBm (2, signed) | | NoiseFloor | `0x90` | dBm (2, signed) |
| Version | `0x91` | Version (1) + Reserved (1) | | Version | `0x91` | Version (1) + Reserved (1) |
| Stats | `0x92` | RX (4) + TX (4) + Errors (4) | | Stats | `0x92` | RX (4) + TX (4) + Errors (4) |
| Battery | `0x93` | Millivolts (2) | | Battery | `0x93` | Millivolts (2) |
| MCUTemp | `0x94` | Temperature (2, signed) | | MCUTemp | `0x94` | Temperature (2, signed) |
| Sensors | `0x95` | CayenneLPP payload | | Sensors | `0x95` | CayenneLPP payload |
| DeviceName | `0x96` | Name (variable, UTF-8) | | DeviceName | `0x96` | Name (variable, UTF-8) |
| Pong | `0x97` | - | | Pong | `0x97` | - |
| SignalReport | `0x9A` | Status (1): 0x00=disabled, 0x01=enabled | | SignalReport | `0x9A` | Status (1): 0x00=disabled, 0x01=enabled |
| OK | `0xF0` | - | | OK | `0xF0` | - |
| Error | `0xF1` | Error code (1) | | Error | `0xF1` | Error code (1) |
| TxDone | `0xF8` | Result (1): 0x00=failed, 0x01=success | | TxDone | `0xF8` | Result (1): 0x00=failed, 0x01=success |
| RxMeta | `0xF9` | SNR (1) + RSSI (1) | | RxMeta | `0xF9` | SNR (1) + RSSI (1) |
### Error Codes ### Error Codes
| Code | Value | Description | | Code | Value | Description |
|------|-------|-------------| |---------------|--------|-------------------------|
| InvalidLength | `0x01` | Request data too short | | InvalidLength | `0x01` | Request data too short |
| InvalidParam | `0x02` | Invalid parameter value | | InvalidParam | `0x02` | Invalid parameter value |
| NoCallback | `0x03` | Feature not available | | NoCallback | `0x03` | Feature not available |
| MacFailed | `0x04` | MAC verification failed | | MacFailed | `0x04` | MAC verification failed |
| UnknownCmd | `0x05` | Unknown sub-command | | UnknownCmd | `0x05` | Unknown sub-command |
| EncryptFailed | `0x06` | Encryption failed | | EncryptFailed | `0x06` | Encryption failed |
| TxBusy | `0x07` | Transmit busy | | TxBusy | `0x07` | Transmit busy |
### Unsolicited Events ### Unsolicited Events
@ -172,41 +172,41 @@ The TNC sends these SetHardware frames without a preceding request:
All values little-endian. All values little-endian.
| Field | Size | Description | | Field | Size | Description |
|-------|------|-------------| |-----------|---------|-------------------------|
| Frequency | 4 bytes | Hz (e.g., 869618000) | | Frequency | 4 bytes | Hz (e.g., 869618000) |
| Bandwidth | 4 bytes | Hz (e.g., 62500) | | Bandwidth | 4 bytes | Hz (e.g., 62500) |
| SF | 1 byte | Spreading factor (5-12) | | SF | 1 byte | Spreading factor (5-12) |
| CR | 1 byte | Coding rate (5-8) | | CR | 1 byte | Coding rate (5-8) |
### Version (Version response) ### Version (Version response)
| Field | Size | Description | | Field | Size | Description |
|-------|------|-------------| |----------|--------|------------------|
| Version | 1 byte | Firmware version | | Version | 1 byte | Firmware version |
| Reserved | 1 byte | Always 0 | | Reserved | 1 byte | Always 0 |
### Encrypted (Encrypted response) ### Encrypted (Encrypted response)
| Field | Size | Description | | Field | Size | Description |
|-------|------|-------------| |------------|----------|------------------------------------------------|
| MAC | 2 bytes | HMAC-SHA256 truncated to 2 bytes | | MAC | 2 bytes | HMAC-SHA256 truncated to 2 bytes |
| Ciphertext | variable | AES-128 block-encrypted data with zero padding | | Ciphertext | variable | AES-128 block-encrypted data with zero padding |
### Airtime (Airtime response) ### Airtime (Airtime response)
All values little-endian. All values little-endian.
| Field | Size | Description | | Field | Size | Description |
|-------|------|-------------| |---------|---------|----------------------------------------------|
| Airtime | 4 bytes | uint32_t, estimated air time in milliseconds | | Airtime | 4 bytes | uint32_t, estimated air time in milliseconds |
### Noise Floor (NoiseFloor response) ### Noise Floor (NoiseFloor response)
All values little-endian. All values little-endian.
| Field | Size | Description | | Field | Size | Description |
|-------|------|-------------| |-------------|---------|-----------------------|
| Noise floor | 2 bytes | int16_t, dBm (signed) | | Noise floor | 2 bytes | int16_t, dBm (signed) |
The modem recalibrates the noise floor every 2 seconds with an AGC reset every 30 seconds. The modem recalibrates the noise floor every 2 seconds with an AGC reset every 30 seconds.
@ -215,35 +215,35 @@ The modem recalibrates the noise floor every 2 seconds with an AGC reset every 3
All values little-endian. All values little-endian.
| Field | Size | Description | | Field | Size | Description |
|-------|------|-------------| |--------|---------|---------------------|
| RX | 4 bytes | Packets received | | RX | 4 bytes | Packets received |
| TX | 4 bytes | Packets transmitted | | TX | 4 bytes | Packets transmitted |
| Errors | 4 bytes | Receive errors | | Errors | 4 bytes | Receive errors |
### Battery (Battery response) ### Battery (Battery response)
All values little-endian. All values little-endian.
| Field | Size | Description | | Field | Size | Description |
|-------|------|-------------| |------------|---------|---------------------------------|
| Millivolts | 2 bytes | uint16_t, battery voltage in mV | | Millivolts | 2 bytes | uint16_t, battery voltage in mV |
### MCU Temperature (MCUTemp response) ### MCU Temperature (MCUTemp response)
All values little-endian. All values little-endian.
| Field | Size | Description | | Field | Size | Description |
|-------|------|-------------| |-------------|---------|--------------------------------------------|
| Temperature | 2 bytes | int16_t, tenths of °C (e.g., 253 = 25.3°C) | | Temperature | 2 bytes | int16_t, tenths of °C (e.g., 253 = 25.3°C) |
Returns `NoCallback` error if the board does not support temperature readings. Returns `NoCallback` error if the board does not support temperature readings.
### Device Name (DeviceName response) ### Device Name (DeviceName response)
| Field | Size | Description | | Field | Size | Description |
|-------|------|-------------| |-------|----------|----------------------------------|
| Name | variable | UTF-8 string, no null terminator | | Name | variable | UTF-8 string, no null terminator |
### Reboot ### Reboot
@ -251,11 +251,11 @@ Sends an `OK` response, flushes serial, then reboots the device. The host should
### Sensor Permissions (GetSensors) ### Sensor Permissions (GetSensors)
| Bit | Value | Description | | Bit | Value | Description |
|-----|-------|-------------| |-----|--------|----------------------------------------|
| 0 | `0x01` | Base (battery) | | 0 | `0x01` | Base (battery) |
| 1 | `0x02` | Location (GPS) | | 1 | `0x02` | Location (GPS) |
| 2 | `0x04` | Environment (temp, humidity, pressure) | | 2 | `0x04` | Environment (temp, humidity, pressure) |
Use `0x07` for all permissions. Use `0x07` for all permissions.
@ -265,12 +265,12 @@ Data returned in CayenneLPP format. See [CayenneLPP documentation](https://docs.
## Cryptographic Algorithms ## Cryptographic Algorithms
| Operation | Algorithm | | Operation | Algorithm |
|-----------|-----------| |-----------------------------------|-------------------------------------------------------------------------------------|
| Identity / Signing / Verification | Ed25519 | | Identity / Signing / Verification | Ed25519 |
| Key Exchange | X25519 (ECDH) | | Key Exchange | X25519 (ECDH) |
| Encryption | AES-128 block encryption with zero padding + HMAC-SHA256 (MAC truncated to 2 bytes) | | Encryption | AES-128 block encryption with zero padding + HMAC-SHA256 (MAC truncated to 2 bytes) |
| Hashing | SHA-256 | | Hashing | SHA-256 |
## Notes ## Notes

98
docs/nrf52_power_management.md

@ -24,36 +24,37 @@ The nRF52 Power Management module provides battery protection features to preven
### Shutdown Reason Tracking ### Shutdown Reason Tracking
Shutdown reason codes (stored in GPREGRET2): Shutdown reason codes (stored in GPREGRET2):
| Code | Name | Description |
|------|------|-------------| | Code | Name | Description |
| 0x00 | NONE | Normal boot / no previous shutdown | |------|--------------|---------------------------------------|
| 0x4C | LOW_VOLTAGE | Runtime low voltage threshold reached | | 0x00 | NONE | Normal boot / no previous shutdown |
| 0x55 | USER | User requested powerOff() | | 0x4C | LOW_VOLTAGE | Runtime low voltage threshold reached |
| 0x42 | BOOT_PROTECT | Boot voltage protection triggered | | 0x55 | USER | User requested powerOff() |
| 0x42 | BOOT_PROTECT | Boot voltage protection triggered |
## Supported Boards ## Supported Boards
| Board | Implemented | LPCOMP wake | VBUS wake | | Board | Implemented | LPCOMP wake | VBUS wake |
|-------|-------------|-------------|-----------| |-------------------------------------------|-------------|-------------|-----------|
| Seeed Studio XIAO nRF52840 (`xiao_nrf52`) | Yes | Yes | Yes | | Seeed Studio XIAO nRF52840 (`xiao_nrf52`) | Yes | Yes | Yes |
| RAK4631 (`rak4631`) | Yes | Yes | Yes | | RAK4631 (`rak4631`) | Yes | Yes | Yes |
| Heltec T114 (`heltec_t114`) | Yes | Yes | Yes | | Heltec T114 (`heltec_t114`) | Yes | Yes | Yes |
| GAT562 Mesh Watch13 | Yes | Yes | Yes | | GAT562 Mesh Watch13 | Yes | Yes | Yes |
| Promicro nRF52840 | No | No | No | | Promicro nRF52840 | No | No | No |
| RAK WisMesh Tag | No | No | No | | RAK WisMesh Tag | No | No | No |
| Heltec Mesh Solar | No | No | No | | Heltec Mesh Solar | No | No | No |
| LilyGo T-Echo / T-Echo Lite | No | No | No | | LilyGo T-Echo / T-Echo Lite | No | No | No |
| SenseCAP Solar | Yes | Yes | Yes | | SenseCAP Solar | Yes | Yes | Yes |
| WIO Tracker L1 / L1 E-Ink | No | No | No | | WIO Tracker L1 / L1 E-Ink | No | No | No |
| WIO WM1110 | No | No | No | | WIO WM1110 | No | No | No |
| Mesh Pocket | No | No | No | | Mesh Pocket | No | No | No |
| Nano G2 Ultra | No | No | No | | Nano G2 Ultra | No | No | No |
| ThinkNode M1/M3/M6 | No | No | No | | ThinkNode M1/M3/M6 | No | No | No |
| T1000-E | No | No | No | | T1000-E | No | No | No |
| Ikoka Nano/Stick/Handheld (nRF) | No | No | No | | Ikoka Nano/Stick/Handheld (nRF) | No | No | No |
| Keepteen LT1 | No | No | No | | Keepteen LT1 | No | No | No |
| Minewsemi ME25LS01 | No | No | No | | Minewsemi ME25LS01 | No | No | No |
Notes: Notes:
- "Implemented" reflects Phase 1 (boot lockout + shutdown reason capture). - "Implemented" reflects Phase 1 (boot lockout + shutdown reason capture).
@ -143,24 +144,25 @@ The LPCOMP (Low Power Comparator) is configured to:
VBUS wake is enabled via the POWER peripheral USBDETECTED event whenever `configureVoltageWake()` is used. This requires USB VBUS to be routed to the nRF52 (typical on nRF52840 boards with native USB). VBUS wake is enabled via the POWER peripheral USBDETECTED event whenever `configureVoltageWake()` is used. This requires USB VBUS to be routed to the nRF52 (typical on nRF52840 boards with native USB).
**LPCOMP Reference Selection (PWRMGT_LPCOMP_REFSEL)**: **LPCOMP Reference Selection (PWRMGT_LPCOMP_REFSEL)**:
| REFSEL | Fraction | VBAT @ 1M/1M divider (VDD=3.0-3.3) | VBAT @ 1.5M/1M divider (VDD=3.0-3.3) | | REFSEL | Fraction | VBAT @ 1M/1M divider (VDD=3.0-3.3) | VBAT @ 1.5M/1M divider (VDD=3.0-3.3) |
|--------|----------|------------------------------------|--------------------------------------| |--------|----------|------------------------------------|--------------------------------------|
| 0 | 1/8 | 0.75-0.82 V | 0.94-1.03 V | | 0 | 1/8 | 0.75-0.82 V | 0.94-1.03 V |
| 1 | 2/8 | 1.50-1.65 V | 1.88-2.06 V | | 1 | 2/8 | 1.50-1.65 V | 1.88-2.06 V |
| 2 | 3/8 | 2.25-2.47 V | 2.81-3.09 V | | 2 | 3/8 | 2.25-2.47 V | 2.81-3.09 V |
| 3 | 4/8 | 3.00-3.30 V | 3.75-4.12 V | | 3 | 4/8 | 3.00-3.30 V | 3.75-4.12 V |
| 4 | 5/8 | 3.75-4.12 V | 4.69-5.16 V | | 4 | 5/8 | 3.75-4.12 V | 4.69-5.16 V |
| 5 | 6/8 | 4.50-4.95 V | 5.62-6.19 V | | 5 | 6/8 | 4.50-4.95 V | 5.62-6.19 V |
| 6 | 7/8 | 5.25-5.77 V | 6.56-7.22 V | | 6 | 7/8 | 5.25-5.77 V | 6.56-7.22 V |
| 7 | ARef | - | - | | 7 | ARef | - | - |
| 8 | 1/16 | 0.38-0.41 V | 0.47-0.52 V | | 8 | 1/16 | 0.38-0.41 V | 0.47-0.52 V |
| 9 | 3/16 | 1.12-1.24 V | 1.41-1.55 V | | 9 | 3/16 | 1.12-1.24 V | 1.41-1.55 V |
| 10 | 5/16 | 1.88-2.06 V | 2.34-2.58 V | | 10 | 5/16 | 1.88-2.06 V | 2.34-2.58 V |
| 11 | 7/16 | 2.62-2.89 V | 3.28-3.61 V | | 11 | 7/16 | 2.62-2.89 V | 3.28-3.61 V |
| 12 | 9/16 | 3.38-3.71 V | 4.22-4.64 V | | 12 | 9/16 | 3.38-3.71 V | 4.22-4.64 V |
| 13 | 11/16 | 4.12-4.54 V | 5.16-5.67 V | | 13 | 11/16 | 4.12-4.54 V | 5.16-5.67 V |
| 14 | 13/16 | 4.88-5.36 V | 6.09-6.70 V | | 14 | 13/16 | 4.88-5.36 V | 6.09-6.70 V |
| 15 | 15/16 | 5.62-6.19 V | 7.03-7.73 V | | 15 | 15/16 | 5.62-6.19 V | 7.03-7.73 V |
**Important**: For boards with a voltage divider on the battery sense pin, LPCOMP measures the divided voltage. Use: **Important**: For boards with a voltage divider on the battery sense pin, LPCOMP measures the divided voltage. Use:
`VBAT_threshold ≈ (VDD * fraction) * divider_scale`, where `divider_scale = (Rtop + Rbottom) / Rbottom` (e.g., 2.0 for 1M/1M, 2.5 for 1.5M/1M, 3.0 for XIAO). `VBAT_threshold ≈ (VDD * fraction) * divider_scale`, where `divider_scale = (Rtop + Rbottom) / Rbottom` (e.g., 2.0 for 1M/1M, 2.5 for 1.5M/1M, 3.0 for XIAO).
@ -177,12 +179,12 @@ This ensures compatibility regardless of BLE stack state.
Power management status can be queried via the CLI: Power management status can be queried via the CLI:
| Command | Description | | Command | Description |
|---------|-------------| |-------------------------|-----------------------------------------------------------------------|
| `get pwrmgt.support` | Returns "supported" or "unsupported" | | `get pwrmgt.support` | Returns "supported" or "unsupported" |
| `get pwrmgt.source` | Returns current power source - "battery" or "external" (5V/USB power) | | `get pwrmgt.source` | Returns current power source - "battery" or "external" (5V/USB power) |
| `get pwrmgt.bootreason` | Returns reset and shutdown reason strings | | `get pwrmgt.bootreason` | Returns reset and shutdown reason strings |
| `get pwrmgt.bootmv` | Returns boot voltage in millivolts | | `get pwrmgt.bootmv` | Returns boot voltage in millivolts |
On boards without power management enabled, all commands except `get pwrmgt.support` return: On boards without power management enabled, all commands except `get pwrmgt.support` return:
``` ```

32
docs/packet_format.md

@ -67,13 +67,13 @@ This is the protocol level packet structure used in MeshCore firmware v1.12.0
### Packet Format ### Packet Format
| Field | Size (bytes) | Description | | Field | Size (bytes) | Description |
|-----------------|----------------------------------|----------------------------------------------------------| |-----------------|----------------------------------|-----------------------------------------------------------------|
| header | 1 | Contains routing type, payload type, and payload version | | header | 1 | Contains routing type, payload type, and payload version |
| transport_codes | 4 (optional) | 2x 16-bit transport codes (if ROUTE_TYPE_TRANSPORT_*) | | transport_codes | 4 (optional) | 2x 16-bit transport codes (if ROUTE_TYPE_TRANSPORT_*) |
| path_length | 1 | Encodes path hash size in bits 6-7 and hop count in bits 0-5 | | path_length | 1 | Encodes path hash size in bits 6-7 and hop count in bits 0-5 |
| path | up to 64 (`MAX_PATH_SIZE`) | Stores `hop_count * hash_size` bytes of path data if applicable | | path | up to 64 (`MAX_PATH_SIZE`) | Stores `hop_count * hash_size` bytes of path data if applicable |
| payload | up to 184 (`MAX_PACKET_PAYLOAD`) | Data for the provided Payload Type | | payload | up to 184 (`MAX_PACKET_PAYLOAD`) | Data for the provided Payload Type |
> NOTE: see the [Payloads](./payloads.md) documentation for more information about the content of specific payload types. > NOTE: see the [Payloads](./payloads.md) documentation for more information about the content of specific payload types.
@ -100,19 +100,19 @@ Bit 0 means the lowest bit (1s place)
`path_length` is not a raw byte count. It packs both hash size and hop count: `path_length` is not a raw byte count. It packs both hash size and hop count:
| Bits | Field | Meaning | | Bits | Field | Meaning |
|------|-------|---------| |------|----------------|--------------------------------|
| 0-5 | Hop Count | Number of path hashes (`0-63`) | | 0-5 | Hop Count | Number of path hashes (`0-63`) |
| 6-7 | Hash Size Code | Stored as `hash_size - 1` | | 6-7 | Hash Size Code | Stored as `hash_size - 1` |
Hash size codes: Hash size codes:
| Bits 6-7 | Hash Size | Notes | | Bits 6-7 | Hash Size | Notes |
|----------|-----------|-------| |----------|-----------|-------------------------------|
| `0b00` | 1 byte | Legacy / default mode | | `0b00` | 1 byte | Legacy / default mode |
| `0b01` | 2 bytes | Supported in current firmware | | `0b01` | 2 bytes | Supported in current firmware |
| `0b10` | 3 bytes | Supported in current firmware | | `0b10` | 3 bytes | Supported in current firmware |
| `0b11` | 4 bytes | Reserved / invalid | | `0b11` | 4 bytes | Reserved / invalid |
Examples: Examples:

94
docs/payloads.md

@ -97,10 +97,10 @@ Returned path messages provide a description of the route a packet took from the
For the common chat/server helpers in `BaseChatMesh`, the current request type values are: For the common chat/server helpers in `BaseChatMesh`, the current request type values are:
| Value | Name | Description | | Value | Name | Description |
|--------|----------------------|---------------------------------------| |--------|-----------|----------------------------------------------------|
| `0x01` | get stats | get stats of repeater or room server | | `0x01` | get stats | get stats of repeater or room server |
| `0x02` | keepalive | keep-alive request used for maintained connections | | `0x02` | keepalive | keep-alive request used for maintained connections |
### Get stats ### Get stats
@ -152,26 +152,26 @@ Not defined in `BaseChatMesh`.
## Response ## Response
| Field | Size (bytes) | Description | | Field | Size (bytes) | Description |
|---------|-----------------|-------------| |---------|-----------------|-----------------------------------|
| content | rest of payload | application-defined response body | | content | rest of payload | application-defined response body |
Response contents are opaque application data. There is no single generic response envelope beyond the encrypted payload wrapper shown above. Response contents are opaque application data. There is no single generic response envelope beyond the encrypted payload wrapper shown above.
## Plain text message ## Plain text message
| Field | Size (bytes) | Description | | Field | Size (bytes) | Description |
|--------------------|-----------------|--------------------------------------------------------------| |--------------------|-----------------|-----------------------------------------------------------------------------------|
| timestamp | 4 | send time (unix timestamp) | | timestamp | 4 | send time (unix timestamp) |
| txt_type + attempt | 1 | upper six bits are txt_type (see below), lower two bits are attempt number (0..3) | | txt_type + attempt | 1 | upper six bits are txt_type (see below), lower two bits are attempt number (0..3) |
| message | rest of payload | the message content, see next table | | message | rest of payload | the message content, see next table |
txt_type txt_type
| Value | Description | Message content | | Value | Description | Message content |
|--------|---------------------------|------------------------------------------------------------| |--------|---------------------------|--------------------------------------------------------------------------|
| `0x00` | plain text message | the plain text of the message | | `0x00` | plain text message | the plain text of the message |
| `0x01` | CLI command | the command text of the message | | `0x01` | CLI command | the command text of the message |
| `0x02` | signed plain text message | first four bytes is sender pubkey prefix, followed by plain text message | | `0x02` | signed plain text message | first four bytes is sender pubkey prefix, followed by plain text message |
# Anonymous request # Anonymous request
@ -200,57 +200,57 @@ txt_type
## Repeater - Regions request ## Repeater - Regions request
| Field | Size (bytes) | Description | | Field | Size (bytes) | Description |
|----------------|-----------------|-------------------------------------------------------------------------------| |----------------|--------------|------------------------------|
| timestamp | 4 | sender time (unix timestamp) | | timestamp | 4 | sender time (unix timestamp) |
| req type | 1 | 0x01 (request sub type) | | req type | 1 | 0x01 (request sub type) |
| reply path len | 1 | path len for reply | | reply path len | 1 | path len for reply |
| reply path | (variable) | reply path | | reply path | (variable) | reply path |
## Repeater - Owner info request ## Repeater - Owner info request
| Field | Size (bytes) | Description | | Field | Size (bytes) | Description |
|----------------|-----------------|-------------------------------------------------------------------------------| |----------------|--------------|------------------------------|
| timestamp | 4 | sender time (unix timestamp) | | timestamp | 4 | sender time (unix timestamp) |
| req type | 1 | 0x02 (request sub type) | | req type | 1 | 0x02 (request sub type) |
| reply path len | 1 | path len for reply | | reply path len | 1 | path len for reply |
| reply path | (variable) | reply path | | reply path | (variable) | reply path |
## Repeater - Clock and status request ## Repeater - Clock and status request
| Field | Size (bytes) | Description | | Field | Size (bytes) | Description |
|----------------|-----------------|-------------------------------------------------------------------------------| |----------------|--------------|------------------------------|
| timestamp | 4 | sender time (unix timestamp) | | timestamp | 4 | sender time (unix timestamp) |
| req type | 1 | 0x03 (request sub type) | | req type | 1 | 0x03 (request sub type) |
| reply path len | 1 | path len for reply | | reply path len | 1 | path len for reply |
| reply path | (variable) | reply path | | reply path | (variable) | reply path |
# Group text message # Group text message
| Field | Size (bytes) | Description | | Field | Size (bytes) | Description |
|--------------|-----------------|--------------------------------------------| |--------------|-----------------|----------------------------------------------|
| channel hash | 1 | first byte of SHA256 of channel's shared key | | channel hash | 1 | first byte of SHA256 of channel's shared key |
| cipher MAC | 2 | MAC for encrypted data in next field | | cipher MAC | 2 | MAC for encrypted data in next field |
| ciphertext | rest of payload | encrypted message, see below for details | | ciphertext | rest of payload | encrypted message, see below for details |
The plaintext contained in the ciphertext matches the format described in [plain text message](#plain-text-message). Specifically, it consists of a four byte timestamp, a flags byte, and the message. The flags byte will generally be `0x00` because it is a "plain text message". The message will be of the form `<sender name>: <message body>` (eg., `user123: I'm on my way`). The plaintext contained in the ciphertext matches the format described in [plain text message](#plain-text-message). Specifically, it consists of a four byte timestamp, a flags byte, and the message. The flags byte will generally be `0x00` because it is a "plain text message". The message will be of the form `<sender name>: <message body>` (eg., `user123: I'm on my way`).
# Group datagram # Group datagram
| Field | Size (bytes) | Description | | Field | Size (bytes) | Description |
|--------------|-----------------|--------------------------------------------| |--------------|-----------------|----------------------------------------------|
| channel hash | 1 | first byte of SHA256 of channel's shared key | | channel hash | 1 | first byte of SHA256 of channel's shared key |
| cipher MAC | 2 | MAC for encrypted data in next field | | cipher MAC | 2 | MAC for encrypted data in next field |
| ciphertext | rest of payload | encrypted data, see below for details | | ciphertext | rest of payload | encrypted data, see below for details |
The data contained in the ciphertext uses the format below: The data contained in the ciphertext uses the format below:
| Field | Size (bytes) | Description | | Field | Size (bytes) | Description |
|--------------|-----------------|--------------------------------------------| |-----------|-----------------|----------------------------------------------------------|
| data type | 2 | Identifier for type of data. (See number_allocations.md) | | data type | 2 | Identifier for type of data. (See number_allocations.md) |
| data len | 1 | byte length of data | | data len | 1 | byte length of data |
| data | rest of payload | (depends on data type) | | data | rest of payload | (depends on data type) |
# Control data # Control data

68
docs/stats_binary_frames.md

@ -4,9 +4,9 @@ Binary frame structures for companion radio stats commands. All multi-byte integ
## Command Codes ## Command Codes
| Command | Code | Description | | Command | Code | Description |
|---------|------|-------------| |-----------------|------|--------------------------------------------------|
| `CMD_GET_STATS` | 56 | Get statistics (2-byte command: code + sub-type) | | `CMD_GET_STATS` | 56 | Get statistics (2-byte command: code + sub-type) |
### Stats Sub-Types ### Stats Sub-Types
@ -19,9 +19,9 @@ The `CMD_GET_STATS` command uses a 2-byte frame structure:
## Response Codes ## Response Codes
| Response | Code | Description | | Response | Code | Description |
|----------|------|-------------| |-------------------|------|--------------------------------------------------------|
| `RESP_CODE_STATS` | 24 | Statistics response (2-byte response: code + sub-type) | | `RESP_CODE_STATS` | 24 | Statistics response (2-byte response: code + sub-type) |
### Stats Response Sub-Types ### Stats Response Sub-Types
@ -38,14 +38,14 @@ The `RESP_CODE_STATS` response uses a 2-byte header structure:
**Total Frame Size:** 11 bytes **Total Frame Size:** 11 bytes
| Offset | Size | Type | Field Name | Description | Range/Notes | | Offset | Size | Type | Field Name | Description | Range/Notes |
|--------|------|------|------------|-------------|-------------| |--------|------|----------|---------------|---------------------------------|-------------------|
| 0 | 1 | uint8_t | response_code | Always `0x18` (24) | - | | 0 | 1 | uint8_t | response_code | Always `0x18` (24) | - |
| 1 | 1 | uint8_t | stats_type | Always `0x00` (STATS_TYPE_CORE) | - | | 1 | 1 | uint8_t | stats_type | Always `0x00` (STATS_TYPE_CORE) | - |
| 2 | 2 | uint16_t | battery_mv | Battery voltage in millivolts | 0 - 65,535 | | 2 | 2 | uint16_t | battery_mv | Battery voltage in millivolts | 0 - 65,535 |
| 4 | 4 | uint32_t | uptime_secs | Device uptime in seconds | 0 - 4,294,967,295 | | 4 | 4 | uint32_t | uptime_secs | Device uptime in seconds | 0 - 4,294,967,295 |
| 8 | 2 | uint16_t | errors | Error flags bitmask | - | | 8 | 2 | uint16_t | errors | Error flags bitmask | - |
| 10 | 1 | uint8_t | queue_len | Outbound packet queue length | 0 - 255 | | 10 | 1 | uint8_t | queue_len | Outbound packet queue length | 0 - 255 |
### Example Structure (C/C++) ### Example Structure (C/C++)
@ -66,15 +66,15 @@ struct StatsCore {
**Total Frame Size:** 14 bytes **Total Frame Size:** 14 bytes
| Offset | Size | Type | Field Name | Description | Range/Notes | | Offset | Size | Type | Field Name | Description | Range/Notes |
|--------|------|------|------------|-------------|-------------| |--------|------|----------|---------------|----------------------------------------|----------------------|
| 0 | 1 | uint8_t | response_code | Always `0x18` (24) | - | | 0 | 1 | uint8_t | response_code | Always `0x18` (24) | - |
| 1 | 1 | uint8_t | stats_type | Always `0x01` (STATS_TYPE_RADIO) | - | | 1 | 1 | uint8_t | stats_type | Always `0x01` (STATS_TYPE_RADIO) | - |
| 2 | 2 | int16_t | noise_floor | Radio noise floor in dBm | -140 to +10 | | 2 | 2 | int16_t | noise_floor | Radio noise floor in dBm | -140 to +10 |
| 4 | 1 | int8_t | last_rssi | Last received signal strength in dBm | -128 to +127 | | 4 | 1 | int8_t | last_rssi | Last received signal strength in dBm | -128 to +127 |
| 5 | 1 | int8_t | last_snr | SNR scaled by 4 | Divide by 4.0 for dB | | 5 | 1 | int8_t | last_snr | SNR scaled by 4 | Divide by 4.0 for dB |
| 6 | 4 | uint32_t | tx_air_secs | Cumulative transmit airtime in seconds | 0 - 4,294,967,295 | | 6 | 4 | uint32_t | tx_air_secs | Cumulative transmit airtime in seconds | 0 - 4,294,967,295 |
| 10 | 4 | uint32_t | rx_air_secs | Cumulative receive airtime in seconds | 0 - 4,294,967,295 | | 10 | 4 | uint32_t | rx_air_secs | Cumulative receive airtime in seconds | 0 - 4,294,967,295 |
### Example Structure (C/C++) ### Example Structure (C/C++)
@ -96,17 +96,17 @@ struct StatsRadio {
**Total Frame Size:** 26 bytes (legacy) or 30 bytes (includes `recv_errors`) **Total Frame Size:** 26 bytes (legacy) or 30 bytes (includes `recv_errors`)
| Offset | Size | Type | Field Name | Description | Range/Notes | | Offset | Size | Type | Field Name | Description | Range/Notes |
|--------|------|------|------------|-------------|-------------| |--------|------|----------|---------------|--------------------------------------------------------------|-------------------|
| 0 | 1 | uint8_t | response_code | Always `0x18` (24) | - | | 0 | 1 | uint8_t | response_code | Always `0x18` (24) | - |
| 1 | 1 | uint8_t | stats_type | Always `0x02` (STATS_TYPE_PACKETS) | - | | 1 | 1 | uint8_t | stats_type | Always `0x02` (STATS_TYPE_PACKETS) | - |
| 2 | 4 | uint32_t | recv | Total packets received | 0 - 4,294,967,295 | | 2 | 4 | uint32_t | recv | Total packets received | 0 - 4,294,967,295 |
| 6 | 4 | uint32_t | sent | Total packets sent | 0 - 4,294,967,295 | | 6 | 4 | uint32_t | sent | Total packets sent | 0 - 4,294,967,295 |
| 10 | 4 | uint32_t | flood_tx | Packets sent via flood routing | 0 - 4,294,967,295 | | 10 | 4 | uint32_t | flood_tx | Packets sent via flood routing | 0 - 4,294,967,295 |
| 14 | 4 | uint32_t | direct_tx | Packets sent via direct routing | 0 - 4,294,967,295 | | 14 | 4 | uint32_t | direct_tx | Packets sent via direct routing | 0 - 4,294,967,295 |
| 18 | 4 | uint32_t | flood_rx | Packets received via flood routing | 0 - 4,294,967,295 | | 18 | 4 | uint32_t | flood_rx | Packets received via flood routing | 0 - 4,294,967,295 |
| 22 | 4 | uint32_t | direct_rx | Packets received via direct routing | 0 - 4,294,967,295 | | 22 | 4 | uint32_t | direct_rx | Packets received via direct routing | 0 - 4,294,967,295 |
| 26 | 4 | uint32_t | recv_errors | Receive/CRC errors (RadioLib); present only in 30-byte frame | 0 - 4,294,967,295 | | 26 | 4 | uint32_t | recv_errors | Receive/CRC errors (RadioLib); present only in 30-byte frame | 0 - 4,294,967,295 |
### Notes ### Notes

Loading…
Cancel
Save