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. 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 ## References
- **Firmware Repository**: https://github.com/nonik0/meshcore - **Firmware Repository**: https://github.com/nonik0/meshcore
+2 -1
View File
@@ -14,7 +14,8 @@ MeshCore Open is an open-source Flutter client for MeshCore LoRa mesh networking
8. [Notifications](notifications.md) - System notifications, unread badges, and notification preferences 8. [Notifications](notifications.md) - System notifications, unread badges, and notification preferences
9. [Repeater Management](repeater-management.md) - Repeater hub, status, CLI, telemetry, and neighbors 9. [Repeater Management](repeater-management.md) - Repeater hub, status, CLI, telemetry, and neighbors
10. [Additional Features](additional-features.md) - GIF picker, localization, debug logs, SMAZ compression, and more 10. [Additional Features](additional-features.md) - GIF picker, localization, debug logs, SMAZ compression, and more
11. [BLE Protocol & Data Layer](ble-protocol.md) - Technical reference for the communication protocol and data architecture 11. [Routing Paths](routing-paths.md) - Path encoding, validation, device capability detection, and storage
12. [BLE Protocol & Data Layer](ble-protocol.md) - Technical reference for the communication protocol and data architecture
## App Overview ## App Overview
+1
View File
@@ -21,6 +21,7 @@ From the Contacts screen, tap any Chat-type contact to open the ChatScreen.
- **Action buttons**: - **Action buttons**:
- **Routing mode** (waves icon): Switch between Auto, Direct, and Flood routing - **Routing mode** (waves icon): Switch between Auto, Direct, and Flood routing
- **Path management** (timeline icon): View recent paths with hop count, round-trip time, age, and success count. Paths are color-coded by direct repeater (green/yellow/red/blue for ranked repeaters, grey for unknown). Tap a path to activate it (the device verifies and confirms via snackbar), long-press to view full path details, set custom paths, or force flood mode. A warning banner appears when history reaches 100 entries. - **Path management** (timeline icon): View recent paths with hop count, round-trip time, age, and success count. Paths are color-coded by direct repeater (green/yellow/red/blue for ranked repeaters, grey for unknown). Tap a path to activate it (the device verifies and confirms via snackbar), long-press to view full path details, set custom paths, or force flood mode. A warning banner appears when history reaches 100 entries.
- Custom path entry follows the device's current hash width, so multibyte paths are entered as comma-separated hex prefixes such as `A1B2,C1C2` when that mode is enabled.
- **Info** (info icon): Contact info dialog showing type, path, GPS coordinates, public key, and SMAZ compression toggle - **Info** (info icon): Contact info dialog showing type, path, GPS coordinates, public key, and SMAZ compression toggle
### Message List ### Message List
+66
View File
@@ -0,0 +1,66 @@
# Routing Paths
This page covers how MeshCore Open represents, selects, validates, and stores routing paths in the UI and data layer.
## Path Routing
MeshCore supports variable-length multi-byte routing paths so the app can scale from small meshes to very large node sets.
### Path Encoding Format
Each path byte packs both the hop count and the hash width:
```
Bit 7-6: Hash mode (2 bits) → hash_bytes = 1 << mode
Bit 5-0: Hop count (6 bits) → max 63 hops
```
| 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+ |
### Path Byte Calculation
```dart
final pathLenRaw = frameData[index];
final hopCount = pathLenRaw & 0x3F;
final hashMode = (pathLenRaw >> 6) & 0x03;
final hashBytes = 1 << hashMode;
final pathByteLength = hopCount * hashBytes;
final pathData = frameData.sublist(index + 1, index + 1 + pathByteLength);
```
### Device Capability Detection
The app reads the device's reported capability byte to determine whether multi-byte paths are available:
```dart
if (firmwareBytes.length >= 82) {
final mode = (firmwareBytes[81] & 0xFF).clamp(0, 2);
pathHashByteWidth = mode + 1;
} else {
pathHashByteWidth = 1;
}
```
### Path Usage in Different Message Types
- Direct messages extract the path from the decrypted payload to trace the sender route.
- Channel messages decrypt a hop-by-hop routing chain from the payload.
- Contact storage keeps the path length encoding in byte 32 and the raw path bytes in bytes 33-96.
### 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]
```