You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Serial protocol for the KISS modem firmware. Enables sending/receiving MeshCore packets over LoRa and cryptographic operations using the modem's identity.
3
+
Standard KISS TNC firmware for MeshCore LoRa radios. Compatible with any KISS client (Direwolf, APRSdroid, YAAC, etc.) for sending and receiving raw packets. MeshCore-specific extensions (cryptography, radio configuration, telemetry) are available through the standard SetHardware (0x06) command.
4
4
5
5
## Serial Configuration
6
6
7
7
115200 baud, 8N1, no flow control.
8
8
9
9
## Frame Format
10
10
11
-
Standard KISS framing with byte stuffing.
11
+
Standard KISS framing per the KA9Q/K3MC specification.
12
12
13
13
| Byte | Name | Description |
14
14
|------|------|-------------|
@@ -18,89 +18,156 @@ Standard KISS framing with byte stuffing.
| SetHardware |`0x06`| Sub-command + data | MeshCore extensions (see below) |
51
+
| Return |`0xFF`| - | Exit KISS mode (no-op) |
52
+
53
+
### TNC to Host
54
+
55
+
| Type | Value | Data | Description |
56
+
|------|-------|------|-------------|
57
+
| Data |`0x00`| Raw packet | Received packet from radio |
58
+
59
+
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.
60
+
61
+
### CSMA Behavior
62
+
63
+
The TNC implements p-persistent CSMA for half-duplex operation:
64
+
65
+
1. When a packet is queued, monitor carrier detect
66
+
2. When the channel clears, generate a random value 0-255
67
+
3. If the value is less than or equal to P (Persistence), wait TXDELAY then transmit
68
+
4. Otherwise, wait SlotTime and repeat from step 1
69
+
70
+
In full-duplex mode, CSMA is bypassed and packets transmit after TXDELAY.
71
+
72
+
## SetHardware Extensions (0x06)
73
+
74
+
MeshCore-specific functionality uses the standard KISS SetHardware command. The first byte of SetHardware data is a sub-command. Standard KISS clients ignore these frames.
Response codes use the high-bit convention: `response = command | 0x80`. Generic and unsolicited responses use the `0xF0`+ range.
119
+
120
+
| Sub-command | Value | Data |
121
+
|-------------|-------|------|
122
+
| Identity |`0x81`| PubKey (32) |
123
+
| Random |`0x82`| Random bytes (1-64) |
124
+
| Verify |`0x83`| Result (1): 0x00=invalid, 0x01=valid |
125
+
| Signature |`0x84`| Signature (64) |
126
+
| Encrypted |`0x85`| MAC (2) + Ciphertext |
127
+
| Decrypted |`0x86`| Plaintext |
128
+
| SharedSecret |`0x87`| Shared secret (32) |
129
+
| Hash |`0x88`| SHA-256 hash (32) |
130
+
| Radio |`0x8B`| Freq (4) + BW (4) + SF (1) + CR (1) |
131
+
| TxPower |`0x8C`| Power dBm (1) |
132
+
| CurrentRssi |`0x8D`| RSSI dBm (1, signed) |
133
+
| ChannelBusy |`0x8E`| Result (1): 0x00=clear, 0x01=busy |
134
+
| Airtime |`0x8F`| Milliseconds (4) |
135
+
| NoiseFloor |`0x90`| dBm (2, signed) |
136
+
| Version |`0x91`| Version (1) + Reserved (1) |
137
+
| Stats |`0x92`| RX (4) + TX (4) + Errors (4) |
138
+
| Battery |`0x93`| Millivolts (2) |
139
+
| MCUTemp |`0x94`| Temperature (2, signed) |
140
+
| Sensors |`0x95`| CayenneLPP payload |
141
+
| DeviceName |`0x96`| Name (variable, UTF-8) |
142
+
| Pong |`0x97`| - |
143
+
| SignalReport |`0x9A`| Status (1): 0x00=disabled, 0x01=enabled |
144
+
| OK |`0xF0`| - |
145
+
| Error |`0xF1`| Error code (1) |
146
+
| TxDone |`0xF8`| Result (1): 0x00=failed, 0x01=success |
147
+
| RxMeta |`0xF9`| SNR (1) + RSSI (1) |
148
+
149
+
### Error Codes
90
150
91
151
| Code | Value | Description |
92
152
|------|-------|-------------|
93
-
|`ERR_INVALID_LENGTH`|`0x01`| Request data too short |
94
-
|`ERR_INVALID_PARAM`|`0x02`| Invalid parameter value |
95
-
|`ERR_NO_CALLBACK`|`0x03`| Feature not available |
96
-
|`ERR_MAC_FAILED`|`0x04`| MAC verification failed |
97
-
|`ERR_UNKNOWN_CMD`|`0x05`| Unknown command |
98
-
|`ERR_ENCRYPT_FAILED`|`0x06`| Encryption failed |
99
-
|`ERR_TX_PENDING`|`0x07`| TX already pending |
153
+
| InvalidLength |`0x01`| Request data too short |
154
+
| InvalidParam |`0x02`| Invalid parameter value |
155
+
| NoCallback |`0x03`| Feature not available |
156
+
| MacFailed |`0x04`| MAC verification failed |
157
+
| UnknownCmd |`0x05`| Unknown sub-command |
158
+
| EncryptFailed |`0x06`| Encryption failed |
159
+
160
+
### Unsolicited Events
161
+
162
+
The TNC sends these SetHardware frames without a preceding request:
163
+
164
+
**TxDone (0xF8)**: Sent after a packet has been transmitted. Contains a single byte: 0x01 for success, 0x00 for failure.
165
+
166
+
**RxMeta (0xF9)**: 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). Enabled by default; can be toggled with SetSignalReport. Standard KISS clients ignore this frame.
100
167
101
168
## Data Formats
102
169
103
-
### Radio Parameters (CMD_SET_RADIO / RESP_RADIO)
170
+
### Radio Parameters (SetRadio / Radio response)
104
171
105
172
All values little-endian.
106
173
@@ -111,35 +178,77 @@ All values little-endian.
111
178
| SF | 1 byte | Spreading factor (5-12) |
112
179
| CR | 1 byte | Coding rate (5-8) |
113
180
114
-
### Received Packet (CMD_DATA response)
181
+
### Version (Version response)
115
182
116
183
| Field | Size | Description |
117
184
|-------|------|-------------|
118
-
| SNR | 1 byte | Signal-to-noise × 4, signed |
119
-
| RSSI | 1 byte | Signal strength dBm, signed |
120
-
| Packet | variable | Raw MeshCore packet |
185
+
| Version | 1 byte | Firmware version |
186
+
| Reserved | 1 byte | Always 0 |
121
187
122
-
### Noise Floor (RESP_NOISE_FLOOR)
188
+
### Encrypted (Encrypted response)
123
189
124
-
Response to `CMD_GET_NOISE_FLOOR` (0x13). Little-endian.
190
+
| Field | Size | Description |
191
+
|-------|------|-------------|
192
+
| MAC | 2 bytes | HMAC-SHA256 truncated to 2 bytes |
193
+
| Ciphertext | variable | AES-128-CBC encrypted data |
- Data payload limit (255 bytes) matches MeshCore MAX_TRANS_UNIT; no change needed for KISS “1024+ recommended” (that applies to general TNCs, not MeshCore)
158
277
- Modem generates identity on first boot (stored in flash)
159
-
- SNR values multiplied by 4 for 0.25 dB precision
160
-
- Wait for `RESP_TX_DONE` before sending next packet
161
-
- Sending `CMD_DATA` while TX is pending returns `ERR_TX_PENDING`
278
+
- All multi-byte values are little-endian unless stated otherwise
279
+
- SNR values in RxMeta are multiplied by 4 for 0.25 dB precision
280
+
- TxDone is sent as a SetHardware event after each transmission
281
+
- Standard KISS clients receive only type 0x00 data frames and can safely ignore all SetHardware (0x06) frames
162
282
- See [packet_structure.md](./packet_structure.md) for packet format
0 commit comments