Skip to content

Commit 02ddc05

Browse files
Reorganise KISS protocol to close gaps.
1 parent 203d86f commit 02ddc05

3 files changed

Lines changed: 116 additions & 52 deletions

File tree

docs/kiss_modem_protocol.md

Lines changed: 52 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -96,17 +96,20 @@ MeshCore-specific functionality uses the standard KISS SetHardware command. The
9696
| Hash | `0x08` | Data to hash |
9797
| SetRadio | `0x09` | Freq (4) + BW (4) + SF (1) + CR (1) |
9898
| SetTxPower | `0x0A` | Power dBm (1) |
99-
| GetRadio | `0x0C` | - |
100-
| GetTxPower | `0x0D` | - |
101-
| GetVersion | `0x0F` | - |
102-
| GetCurrentRssi | `0x10` | - |
103-
| IsChannelBusy | `0x11` | - |
104-
| GetAirtime | `0x12` | Packet length (1) |
105-
| GetNoiseFloor | `0x13` | - |
106-
| GetStats | `0x14` | - |
107-
| GetBattery | `0x15` | - |
108-
| Ping | `0x16` | - |
109-
| GetSensors | `0x17` | Permissions (1) |
99+
| GetRadio | `0x0B` | - |
100+
| GetTxPower | `0x0C` | - |
101+
| GetCurrentRssi | `0x0D` | - |
102+
| IsChannelBusy | `0x0E` | - |
103+
| GetAirtime | `0x0F` | Packet length (1) |
104+
| GetNoiseFloor | `0x10` | - |
105+
| GetVersion | `0x11` | - |
106+
| GetStats | `0x12` | - |
107+
| GetBattery | `0x13` | - |
108+
| GetMCUTemp | `0x14` | - |
109+
| GetSensors | `0x15` | Permissions (1) |
110+
| GetDeviceName | `0x16` | - |
111+
| Ping | `0x17` | - |
112+
| Reboot | `0x18` | - |
110113

111114
### Response Sub-commands (TNC to Host)
112115

@@ -121,20 +124,22 @@ MeshCore-specific functionality uses the standard KISS SetHardware command. The
121124
| SharedSecret | `0x27` | Shared secret (32) |
122125
| Hash | `0x28` | SHA-256 hash (32) |
123126
| OK | `0x29` | - |
124-
| Radio | `0x2A` | Freq (4) + BW (4) + SF (1) + CR (1) |
125-
| TxPower | `0x2B` | Power dBm (1) |
126-
| Version | `0x2D` | Version (1) + Reserved (1) |
127-
| Error | `0x2E` | Error code (1) |
128-
| TxDone | `0x2F` | Result (1): 0x00=failed, 0x01=success |
129-
| CurrentRssi | `0x30` | RSSI dBm (1, signed) |
130-
| ChannelBusy | `0x31` | Result (1): 0x00=clear, 0x01=busy |
131-
| Airtime | `0x32` | Milliseconds (4) |
132-
| NoiseFloor | `0x33` | dBm (2, signed) |
133-
| Stats | `0x34` | RX (4) + TX (4) + Errors (4) |
134-
| Battery | `0x35` | Millivolts (2) |
135-
| Pong | `0x36` | - |
136-
| Sensors | `0x37` | CayenneLPP payload |
137-
| RxMeta | `0x38` | SNR (1) + RSSI (1) |
127+
| Error | `0x2A` | Error code (1) |
128+
| Radio | `0x2B` | Freq (4) + BW (4) + SF (1) + CR (1) |
129+
| TxPower | `0x2C` | Power dBm (1) |
130+
| CurrentRssi | `0x2D` | RSSI dBm (1, signed) |
131+
| ChannelBusy | `0x2E` | Result (1): 0x00=clear, 0x01=busy |
132+
| Airtime | `0x2F` | Milliseconds (4) |
133+
| NoiseFloor | `0x30` | dBm (2, signed) |
134+
| Version | `0x31` | Version (1) + Reserved (1) |
135+
| Stats | `0x32` | RX (4) + TX (4) + Errors (4) |
136+
| Battery | `0x33` | Millivolts (2) |
137+
| MCUTemp | `0x34` | Temperature (2, signed) |
138+
| Sensors | `0x35` | CayenneLPP payload |
139+
| DeviceName | `0x36` | Name (variable, UTF-8) |
140+
| Pong | `0x37` | - |
141+
| TxDone | `0x38` | Result (1): 0x00=failed, 0x01=success |
142+
| RxMeta | `0x39` | SNR (1) + RSSI (1) |
138143

139144
### Error Codes
140145

@@ -151,9 +156,9 @@ MeshCore-specific functionality uses the standard KISS SetHardware command. The
151156

152157
The TNC sends these SetHardware frames without a preceding request:
153158

154-
**TxDone (0x2F)**: Sent after a packet has been transmitted. Contains a single byte: 0x01 for success, 0x00 for failure.
159+
**TxDone (0x38)**: Sent after a packet has been transmitted. Contains a single byte: 0x01 for success, 0x00 for failure.
155160

156-
**RxMeta (0x38)**: Sent immediately after each standard data frame (type 0x00) with metadata for the received packet. Contains SNR (1 byte, signed, value x4 for 0.25 dB precision) followed by RSSI (1 byte, signed, dBm). Standard KISS clients ignore this frame.
161+
**RxMeta (0x39)**: Sent immediately after each standard data frame (type 0x00) with metadata for the received packet. Contains SNR (1 byte, signed, value x4 for 0.25 dB precision) followed by RSSI (1 byte, signed, dBm). Standard KISS clients ignore this frame.
157162

158163
## Data Formats
159164

@@ -218,6 +223,26 @@ All values little-endian.
218223
|-------|------|-------------|
219224
| Millivolts | 2 bytes | uint16_t, battery voltage in mV |
220225

226+
### MCU Temperature (MCUTemp response)
227+
228+
All values little-endian.
229+
230+
| Field | Size | Description |
231+
|-------|------|-------------|
232+
| Temperature | 2 bytes | int16_t, tenths of °C (e.g., 253 = 25.3°C) |
233+
234+
Returns `NoCallback` error if the board does not support temperature readings.
235+
236+
### Device Name (DeviceName response)
237+
238+
| Field | Size | Description |
239+
|-------|------|-------------|
240+
| Name | variable | UTF-8 string, no null terminator |
241+
242+
### Reboot
243+
244+
Sends an `OK` response, flushes serial, then reboots the device. The host should expect the connection to drop.
245+
221246
### Sensor Permissions (GetSensors)
222247

223248
| Bit | Value | Description |

examples/kiss_modem/KissModem.cpp

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,15 @@ void KissModem::handleHardwareCommand(uint8_t sub_cmd, const uint8_t* data, uint
225225
case HW_CMD_GET_SENSORS:
226226
handleGetSensors(data, len);
227227
break;
228+
case HW_CMD_GET_MCU_TEMP:
229+
handleGetMCUTemp();
230+
break;
231+
case HW_CMD_REBOOT:
232+
handleReboot();
233+
break;
234+
case HW_CMD_GET_DEVICE_NAME:
235+
handleGetDeviceName();
236+
break;
228237
default:
229238
writeHardwareError(HW_ERR_UNKNOWN_CMD);
230239
break;
@@ -536,3 +545,25 @@ void KissModem::handleGetSensors(const uint8_t* data, uint16_t len) {
536545
writeHardwareFrame(HW_RESP_SENSORS, nullptr, 0);
537546
}
538547
}
548+
549+
void KissModem::handleGetMCUTemp() {
550+
float temp = _board.getMCUTemperature();
551+
if (isnan(temp)) {
552+
writeHardwareError(HW_ERR_NO_CALLBACK);
553+
return;
554+
}
555+
int16_t temp_tenths = (int16_t)(temp * 10.0f);
556+
writeHardwareFrame(HW_RESP_MCU_TEMP, (uint8_t*)&temp_tenths, 2);
557+
}
558+
559+
void KissModem::handleReboot() {
560+
writeHardwareFrame(HW_RESP_OK, nullptr, 0);
561+
_serial.flush();
562+
delay(50);
563+
_board.reboot();
564+
}
565+
566+
void KissModem::handleGetDeviceName() {
567+
const char* name = _board.getManufacturerName();
568+
writeHardwareFrame(HW_RESP_DEVICE_NAME, (const uint8_t*)name, strlen(name));
569+
}

examples/kiss_modem/KissModem.h

Lines changed: 33 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,20 @@
3737
#define HW_CMD_HASH 0x08
3838
#define HW_CMD_SET_RADIO 0x09
3939
#define HW_CMD_SET_TX_POWER 0x0A
40-
#define HW_CMD_GET_RADIO 0x0C
41-
#define HW_CMD_GET_TX_POWER 0x0D
42-
#define HW_CMD_GET_VERSION 0x0F
43-
#define HW_CMD_GET_CURRENT_RSSI 0x10
44-
#define HW_CMD_IS_CHANNEL_BUSY 0x11
45-
#define HW_CMD_GET_AIRTIME 0x12
46-
#define HW_CMD_GET_NOISE_FLOOR 0x13
47-
#define HW_CMD_GET_STATS 0x14
48-
#define HW_CMD_GET_BATTERY 0x15
49-
#define HW_CMD_PING 0x16
50-
#define HW_CMD_GET_SENSORS 0x17
40+
#define HW_CMD_GET_RADIO 0x0B
41+
#define HW_CMD_GET_TX_POWER 0x0C
42+
#define HW_CMD_GET_CURRENT_RSSI 0x0D
43+
#define HW_CMD_IS_CHANNEL_BUSY 0x0E
44+
#define HW_CMD_GET_AIRTIME 0x0F
45+
#define HW_CMD_GET_NOISE_FLOOR 0x10
46+
#define HW_CMD_GET_VERSION 0x11
47+
#define HW_CMD_GET_STATS 0x12
48+
#define HW_CMD_GET_BATTERY 0x13
49+
#define HW_CMD_GET_MCU_TEMP 0x14
50+
#define HW_CMD_GET_SENSORS 0x15
51+
#define HW_CMD_GET_DEVICE_NAME 0x16
52+
#define HW_CMD_PING 0x17
53+
#define HW_CMD_REBOOT 0x18
5154

5255
#define HW_RESP_IDENTITY 0x21
5356
#define HW_RESP_RANDOM 0x22
@@ -58,20 +61,22 @@
5861
#define HW_RESP_SHARED_SECRET 0x27
5962
#define HW_RESP_HASH 0x28
6063
#define HW_RESP_OK 0x29
61-
#define HW_RESP_RADIO 0x2A
62-
#define HW_RESP_TX_POWER 0x2B
63-
#define HW_RESP_VERSION 0x2D
64-
#define HW_RESP_ERROR 0x2E
65-
#define HW_RESP_TX_DONE 0x2F
66-
#define HW_RESP_CURRENT_RSSI 0x30
67-
#define HW_RESP_CHANNEL_BUSY 0x31
68-
#define HW_RESP_AIRTIME 0x32
69-
#define HW_RESP_NOISE_FLOOR 0x33
70-
#define HW_RESP_STATS 0x34
71-
#define HW_RESP_BATTERY 0x35
72-
#define HW_RESP_PONG 0x36
73-
#define HW_RESP_SENSORS 0x37
74-
#define HW_RESP_RX_META 0x38
64+
#define HW_RESP_ERROR 0x2A
65+
#define HW_RESP_RADIO 0x2B
66+
#define HW_RESP_TX_POWER 0x2C
67+
#define HW_RESP_CURRENT_RSSI 0x2D
68+
#define HW_RESP_CHANNEL_BUSY 0x2E
69+
#define HW_RESP_AIRTIME 0x2F
70+
#define HW_RESP_NOISE_FLOOR 0x30
71+
#define HW_RESP_VERSION 0x31
72+
#define HW_RESP_STATS 0x32
73+
#define HW_RESP_BATTERY 0x33
74+
#define HW_RESP_MCU_TEMP 0x34
75+
#define HW_RESP_SENSORS 0x35
76+
#define HW_RESP_DEVICE_NAME 0x36
77+
#define HW_RESP_PONG 0x37
78+
#define HW_RESP_TX_DONE 0x38
79+
#define HW_RESP_RX_META 0x39
7580

7681
#define HW_ERR_INVALID_LENGTH 0x01
7782
#define HW_ERR_INVALID_PARAM 0x02
@@ -171,6 +176,9 @@ class KissModem {
171176
void handleGetBattery();
172177
void handlePing();
173178
void handleGetSensors(const uint8_t* data, uint16_t len);
179+
void handleGetMCUTemp();
180+
void handleReboot();
181+
void handleGetDeviceName();
174182

175183
public:
176184
KissModem(Stream& serial, mesh::LocalIdentity& identity, mesh::RNG& rng,

0 commit comments

Comments
 (0)