multi-byte paths-doc

This commit is contained in:
PacoX
2026-05-12 16:40:34 +02:00
parent b62c1c7338
commit 6e2abfeb2d
4 changed files with 69 additions and 100 deletions
-99
View File
@@ -1287,105 +1287,6 @@ if (reactionInfo != null) {
Reactions are parsed, processed to update target message's reaction counts, but never displayed as standalone messages.
## Routing Paths
MeshCore supports variable-length multi-byte routing paths to scale mesh networks from 256 unique nodes (1-byte hashes) to millions (3-byte hashes).
### Path Encoding Format
**Single Byte Encodes Both Hop Count and Hash Mode**:
```
Path Byte Format:
Bit 7-6: Hash mode (2 bits) → hash_bytes = 1 << mode
Bit 5-0: Hop count (6 bits) → max 63 hops
```
**Supported Modes**:
| Mode | Hash Bytes | Max Hops | Max Unique Nodes | Firmware |
|------|-----------|----------|------------------|----------|
| 0 | 1 | 63 | 256 | v1.13+ |
| 1 | 2 | 63 | 65,536 | v1.14+ |
| 2 | 3 | 63 | 16.7M | v1.14+ |
| 3 | 4 | 63 | 4.3B | v1.14+ |
**Special Values**:
- Path byte = **255** → Direct or flooded message (no path)
- Path byte = **0** → End of contact path data (padding byte)
### Path Byte Calculation
```dart
// Extract mode and hop count from wire byte
final pathLenRaw = frameData[index]; // Single byte
final hopCount = pathLenRaw & 0x3F; // Bits 5-0
final hashMode = (pathLenRaw >> 6) & 0x03; // Bits 7-6
final hashBytes = 1 << hashMode; // 1, 2, 4, or 8
// Total path bytes = hopCount * hashBytes
final pathByteLength = hopCount * hashBytes;
final pathData = frameData.sublist(index + 1, index + 1 + pathByteLength);
```
### Device Capability Detection
The device firmware version determines multi-byte path support:
**Firmware Byte 81** (from `RESP_CODE_SELF_INFO` and device initialization):
- Bits 3-0: Path hash mode capability (0-3)
- v1.13 and earlier: Hardcoded mode 0 (1-byte only)
- v1.14+: Firmware reports mode in byte 81; device generates paths in this mode
**Detection in App**:
```dart
// After receiving RESP_CODE_SELF_INFO
if (firmwareBytes.length >= 82) {
final mode = (firmwareBytes[81] & 0xFF).clamp(0, 2);
pathHashByteWidth = mode + 1; // Sets to 1, 2, 3, or 4 bytes
} else {
pathHashByteWidth = 1; // Fallback for v1.13
}
```
### Path Usage in Different Message Types
**Direct Messages** (`RESP_CODE_CONTACT_MSG_RECV`/`RESP_CODE_CONTACT_MSG_RECV_V3`):
- Path extracted from payload after decryption
- Used to trace back to sender
**Channel Messages** (`RESP_CODE_CHANNEL_MSG_RECV`/`RESP_CODE_CHANNEL_MSG_RECV_V3`):
- Group address + encrypted path in payload
- Decrypted to reveal hop-by-hop routing chain
**Contact Storage** (from `RESP_CODE_CONTACT` frames):
- Byte 32: Path length encoding (hop_count | (mode << 6))
- Bytes 33-96: Path data (max 64 bytes stored, variable interpretation)
**Example Contact Path Parsing**:
```dart
// Mode 0 (1-byte): 3 hops = 3 bytes needed
// [0x83, 0xA1, 0xB2, 0xC3] → hopCount=3, mode=0, path=[A1,B2,C3]
// Mode 1 (2-byte): 3 hops = 6 bytes needed
// [0xC3, 0xA1, 0xA2, 0xB1, 0xB2, 0xC1, 0xC2]
// → hopCount=3, mode=1, path=[A1A2, B1B2, C1C2]
```
### Path Validation During Input
When user enters custom paths in the UI:
1. **Parse comma-separated hex segments**: `"A1B2,C1C2,D1D2"`
2. **Validate segment length**: Each must be exactly `hashBytes * 2` hex characters
3. **Convert to bytes**: Group hex pairs into single bytes
4. **Check hop count**: Total bytes ÷ hashBytes must be ≤ 63
**Example with 2-byte mode**:
- Device reports: `pathHashByteWidth = 2`
- User enters: `"A1B2,C1C2"` (2 hops)
- Parse result: `[0xA1, 0xB2, 0xC1, 0xC2]` (4 bytes total)
- Validation: `4 bytes ÷ 2 bytes/hop = 2 hops`
## References
- **Firmware Repository**: https://github.com/nonik0/meshcore