# Stats Binary Frame Structures Binary frame structures for companion radio stats commands. All multi-byte integers use little-endian byte order. ## Command Codes | Command | Code | Description | |---------|------|-------------| | `CMD_GET_STATS_CORE` | 56 | Get core device statistics | | `CMD_GET_STATS_RADIO` | 57 | Get radio statistics | | `CMD_GET_STATS_PACKETS` | 58 | Get packet statistics | ## Response Codes | Response | Code | Description | |----------|------|-------------| | `RESP_CODE_STATS_CORE` | 24 | Core stats response | | `RESP_CODE_STATS_RADIO` | 25 | Radio stats response | | `RESP_CODE_STATS_PACKETS` | 26 | Packet stats response | --- ## RESP_CODE_STATS_CORE (24) **Total Frame Size:** 10 bytes | Offset | Size | Type | Field Name | Description | Range/Notes | |--------|------|------|------------|-------------|-------------| | 0 | 1 | uint8_t | response_code | Always `0x18` (24) | - | | 1 | 2 | uint16_t | battery_mv | Battery voltage in millivolts | 0 - 65,535 | | 3 | 4 | uint32_t | uptime_secs | Device uptime in seconds | 0 - 4,294,967,295 | | 7 | 2 | uint16_t | errors | Error flags bitmask | - | | 9 | 1 | uint8_t | queue_len | Outbound packet queue length | 0 - 255 | ### Example Structure (C/C++) ```c struct StatsCore { uint8_t response_code; // 0x18 uint16_t battery_mv; uint32_t uptime_secs; uint16_t errors; uint8_t queue_len; } __attribute__((packed)); ``` --- ## RESP_CODE_STATS_RADIO (25) **Total Frame Size:** 13 bytes | Offset | Size | Type | Field Name | Description | Range/Notes | |--------|------|------|------------|-------------|-------------| | 0 | 1 | uint8_t | response_code | Always `0x19` (25) | - | | 1 | 2 | int16_t | noise_floor | Radio noise floor in dBm | -140 to +10 | | 3 | 1 | int8_t | last_rssi | Last received signal strength in dBm | -128 to +127 | | 4 | 1 | int8_t | last_snr | SNR scaled by 4 | Divide by 4.0 for dB | | 5 | 4 | uint32_t | tx_air_secs | Cumulative transmit airtime in seconds | 0 - 4,294,967,295 | | 9 | 4 | uint32_t | rx_air_secs | Cumulative receive airtime in seconds | 0 - 4,294,967,295 | ### Example Structure (C/C++) ```c struct StatsRadio { uint8_t response_code; // 0x19 int16_t noise_floor; int8_t last_rssi; int8_t last_snr; // Divide by 4.0 to get actual SNR in dB uint32_t tx_air_secs; uint32_t rx_air_secs; } __attribute__((packed)); ``` --- ## RESP_CODE_STATS_PACKETS (26) **Total Frame Size:** 25 bytes | Offset | Size | Type | Field Name | Description | Range/Notes | |--------|------|------|------------|-------------|-------------| | 0 | 1 | uint8_t | response_code | Always `0x1A` (26) | - | | 1 | 4 | uint32_t | recv | Total packets received | 0 - 4,294,967,295 | | 5 | 4 | uint32_t | sent | Total packets sent | 0 - 4,294,967,295 | | 9 | 4 | uint32_t | flood_tx | Packets sent via flood routing | 0 - 4,294,967,295 | | 13 | 4 | uint32_t | direct_tx | Packets sent via direct routing | 0 - 4,294,967,295 | | 17 | 4 | uint32_t | flood_rx | Packets received via flood routing | 0 - 4,294,967,295 | | 21 | 4 | uint32_t | direct_rx | Packets received via direct routing | 0 - 4,294,967,295 | ### Notes - Counters are cumulative from boot and may wrap. - `recv = flood_rx + direct_rx` - `sent = flood_tx + direct_tx` ### Example Structure (C/C++) ```c struct StatsPackets { uint8_t response_code; // 0x1A uint32_t recv; uint32_t sent; uint32_t flood_tx; uint32_t direct_tx; uint32_t flood_rx; uint32_t direct_rx; } __attribute__((packed)); ``` --- ## Usage Example (Python) ```python import struct def parse_stats_core(frame): """Parse RESP_CODE_STATS_CORE frame (10 bytes)""" response_code, battery_mv, uptime_secs, errors, queue_len = \ struct.unpack('