mirror of
https://github.com/zjs81/meshcore-open.git
synced 2026-07-11 11:07:04 +10:00
bug fix
This commit is contained in:
@@ -15,7 +15,6 @@ The device capability determines the hash width (number of bytes per hop):
|
|||||||
| 1 byte | 256 | Single-byte node IDs |
|
| 1 byte | 256 | Single-byte node IDs |
|
||||||
| 2 bytes | 65,536 | Medium meshes |
|
| 2 bytes | 65,536 | Medium meshes |
|
||||||
| 3 bytes | 16.7M | Large networks |
|
| 3 bytes | 16.7M | Large networks |
|
||||||
| 4 bytes | 4.3B | Gigantic deployments |
|
|
||||||
|
|
||||||
### Device Capability Detection
|
### Device Capability Detection
|
||||||
|
|
||||||
@@ -23,13 +22,15 @@ On device connection, the app reads the firmware capability to set `pathHashByte
|
|||||||
|
|
||||||
```dart
|
```dart
|
||||||
// Read from device info response (offset 81)
|
// Read from device info response (offset 81)
|
||||||
final modeRaw = firmwareBytes.length >= 82
|
final modeRaw = firmwareBytes.length >= 82
|
||||||
? (firmwareBytes[81] & 0x3F)
|
? (firmwareBytes[81] & 0xFF)
|
||||||
: 0;
|
: 0;
|
||||||
final mode = modeRaw.clamp(0, 3);
|
final mode = modeRaw.clamp(0, 2);
|
||||||
_pathHashByteWidth = mode + 1; // 1, 2, 3, or 4 bytes per hop
|
_pathHashByteWidth = mode + 1; // 1, 2, or 3 bytes per hop
|
||||||
```
|
```
|
||||||
|
|
||||||
|
The current implementation intentionally clamps to modes `0..2`, so the supported hop width is `1..3` bytes. Do not document 4-byte hops unless the connector implementation is widened first.
|
||||||
|
|
||||||
### Path Data Structure
|
### Path Data Structure
|
||||||
|
|
||||||
Paths in messages and storage consist of:
|
Paths in messages and storage consist of:
|
||||||
|
|||||||
@@ -51,6 +51,12 @@ class PathTraceData {
|
|||||||
|
|
||||||
String _hopKey(Uint8List hopBytes) => PathHelper.formatHopHex(hopBytes);
|
String _hopKey(Uint8List hopBytes) => PathHelper.formatHopHex(hopBytes);
|
||||||
|
|
||||||
|
Uint8List _lastHopChunk(Uint8List path, int hopWidth) {
|
||||||
|
if (path.isEmpty) return Uint8List(0);
|
||||||
|
final width = hopWidth.clamp(1, path.length);
|
||||||
|
return Uint8List.fromList(path.sublist(path.length - width));
|
||||||
|
}
|
||||||
|
|
||||||
class PathTraceMapScreen extends StatefulWidget {
|
class PathTraceMapScreen extends StatefulWidget {
|
||||||
final String title;
|
final String title;
|
||||||
final Uint8List path;
|
final Uint8List path;
|
||||||
@@ -208,8 +214,9 @@ class _PathTraceMapScreenState extends State<PathTraceMapScreen> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final mirroredHops = <Uint8List>[...pathHops];
|
final mirroredHops = <Uint8List>[...pathHops];
|
||||||
if (widget.targetContact?.type == advTypeRepeater ||
|
final isRepeaterOrRoom = widget.targetContact?.type == advTypeRepeater ||
|
||||||
widget.targetContact?.type == advTypeRoom) {
|
widget.targetContact?.type == advTypeRoom;
|
||||||
|
if (isRepeaterOrRoom) {
|
||||||
final pk = widget.targetContact?.publicKey;
|
final pk = widget.targetContact?.publicKey;
|
||||||
if (pk != null && pk.length >= hopWidth) {
|
if (pk != null && pk.length >= hopWidth) {
|
||||||
mirroredHops.add(Uint8List.fromList(pk.sublist(0, hopWidth)));
|
mirroredHops.add(Uint8List.fromList(pk.sublist(0, hopWidth)));
|
||||||
@@ -220,8 +227,16 @@ class _PathTraceMapScreenState extends State<PathTraceMapScreen> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
// For repeaters/rooms, include full reversed path
|
||||||
|
mirroredHops.addAll(pathHops.reversed);
|
||||||
|
} else {
|
||||||
|
// For non-repeater/room targets, reverse without duplicating the pivot hop
|
||||||
|
if (pathHops.length > 1) {
|
||||||
|
mirroredHops.addAll(
|
||||||
|
pathHops.sublist(0, pathHops.length - 1).reversed,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mirroredHops.addAll(pathHops.reversed);
|
|
||||||
|
|
||||||
final traceBytes = <int>[];
|
final traceBytes = <int>[];
|
||||||
for (final hop in mirroredHops) {
|
for (final hop in mirroredHops) {
|
||||||
@@ -396,7 +411,8 @@ class _PathTraceMapScreenState extends State<PathTraceMapScreen> {
|
|||||||
(c) =>
|
(c) =>
|
||||||
c.hasLocation &&
|
c.hasLocation &&
|
||||||
c.path.isNotEmpty &&
|
c.path.isNotEmpty &&
|
||||||
_hopKey(Uint8List.fromList([c.path.last])) == hopKey,
|
_hopKey(_lastHopChunk(c.path, widget.pathHashByteWidth)) ==
|
||||||
|
hopKey,
|
||||||
)
|
)
|
||||||
.toList();
|
.toList();
|
||||||
if (peers.isNotEmpty) {
|
if (peers.isNotEmpty) {
|
||||||
@@ -442,7 +458,10 @@ class _PathTraceMapScreenState extends State<PathTraceMapScreen> {
|
|||||||
(c) =>
|
(c) =>
|
||||||
c.hasLocation &&
|
c.hasLocation &&
|
||||||
c.path.isNotEmpty &&
|
c.path.isNotEmpty &&
|
||||||
_hopKey(Uint8List.fromList([c.path.last])) == lastHopKey,
|
_hopKey(
|
||||||
|
_lastHopChunk(c.path, widget.pathHashByteWidth),
|
||||||
|
) ==
|
||||||
|
lastHopKey,
|
||||||
)
|
)
|
||||||
.toList();
|
.toList();
|
||||||
if (peers.isNotEmpty) {
|
if (peers.isNotEmpty) {
|
||||||
|
|||||||
Reference in New Issue
Block a user