mirror of
https://github.com/MarekWo/mc-webui.git
synced 2026-08-08 17:53:00 +02:00
fix(contacts): decode path correctly using MeshCore V1 encoding
Path buffer from firmware contains trailing garbage bytes beyond the actual hop data. out_path_len encodes both hop count (lower 6 bits) and hash size (upper 2 bits). Now we: - Truncate out_path to meaningful bytes (hop_count * hash_size) - Format as readable E7→DE→54→54→D8 instead of raw hex string - Show hop count derived from actual path arrows Example: out_path_len=5 with out_path="e7de5454d81c49dfb86f8a" now correctly displays as "E7→DE→54→54→D8 (5 hops)" instead of showing the full 11-byte buffer. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+11
-4
@@ -230,12 +230,19 @@ def _execute_console_command(args: list) -> str:
|
||||
typ = type_names.get(c.get('type', 1), '?')
|
||||
pk_short = pk[:12]
|
||||
opl = c.get('out_path_len', -1)
|
||||
if opl == -1:
|
||||
path_str = 'Flood'
|
||||
if opl > 0:
|
||||
# Decode path: lower 6 bits = hop count, upper 2 bits = hash_size-1
|
||||
hop_count = opl & 0x3F
|
||||
hash_size = (opl >> 6) + 1
|
||||
raw = c.get('out_path', '')
|
||||
meaningful = raw[:hop_count * hash_size * 2]
|
||||
chunk = hash_size * 2
|
||||
hops = [meaningful[i:i+chunk].upper() for i in range(0, len(meaningful), chunk)]
|
||||
path_str = '→'.join(hops) if hops else f'len:{opl}'
|
||||
elif opl == 0:
|
||||
path_str = '0 hop'
|
||||
path_str = 'Direct'
|
||||
else:
|
||||
path_str = c.get('out_path', f'len:{opl}')
|
||||
path_str = 'Flood'
|
||||
lines.append(f" {name:30} {typ:4} {pk_short} {path_str}")
|
||||
return f"Contacts ({len(lines)}) on device:\n" + "\n".join(lines)
|
||||
|
||||
|
||||
+14
-8
@@ -2376,17 +2376,23 @@ def get_contacts_detailed_api():
|
||||
|
||||
for public_key, details in contacts_detailed.items():
|
||||
# Compute path display string
|
||||
# out_path_len encodes hop count (lower 6 bits) and hash_size (upper 2 bits)
|
||||
# In MeshCore V1: hash_size=1 byte per hop, so each hop = 2 hex chars
|
||||
out_path_len = details.get('out_path_len', -1)
|
||||
out_path = details.get('out_path', '')
|
||||
if out_path:
|
||||
# out_path present = known route (even if out_path_len says -1)
|
||||
path_or_mode = out_path
|
||||
elif out_path_len == -1:
|
||||
path_or_mode = 'Flood'
|
||||
out_path_raw = details.get('out_path', '')
|
||||
if out_path_len > 0 and out_path_raw:
|
||||
hop_count = out_path_len & 0x3F
|
||||
hash_size = (out_path_len >> 6) + 1 # 1, 2, or 3 bytes per hop
|
||||
# Truncate to meaningful bytes (firmware buffer may have trailing garbage)
|
||||
meaningful_hex = out_path_raw[:hop_count * hash_size * 2]
|
||||
# Format as HEX→HEX→HEX (each hop is hash_size*2 hex chars)
|
||||
chunk = hash_size * 2
|
||||
hops = [meaningful_hex[i:i+chunk].upper() for i in range(0, len(meaningful_hex), chunk)]
|
||||
path_or_mode = '→'.join(hops) if hops else out_path_raw
|
||||
elif out_path_len == 0:
|
||||
path_or_mode = '0 hop'
|
||||
path_or_mode = 'Direct'
|
||||
else:
|
||||
path_or_mode = f'Path len: {out_path_len}'
|
||||
path_or_mode = 'Flood'
|
||||
|
||||
contact = {
|
||||
# All original fields from contact_info
|
||||
|
||||
@@ -2148,15 +2148,14 @@ function createExistingContactCard(contact, index) {
|
||||
pathDiv = document.createElement('div');
|
||||
pathDiv.className = 'text-muted small';
|
||||
const mode = contact.path_or_mode || 'Flood';
|
||||
const pathLen = contact.out_path_len;
|
||||
if (mode === 'Flood') {
|
||||
pathDiv.innerHTML = '<i class="bi bi-broadcast"></i> Flood';
|
||||
} else if (mode === '0 hop') {
|
||||
pathDiv.innerHTML = '<i class="bi bi-arrow-right-short"></i> Direct (0 hop)';
|
||||
} else if (mode === 'Direct') {
|
||||
pathDiv.innerHTML = '<i class="bi bi-arrow-right-short"></i> Direct';
|
||||
} else {
|
||||
// mode is hex path string, show hops count + path
|
||||
const hops = pathLen >= 0 ? pathLen : '?';
|
||||
pathDiv.innerHTML = `<i class="bi bi-signpost-split"></i> Path: ${mode} (${hops} hops)`;
|
||||
// mode is formatted path like "E7→DE→54→54→D8"
|
||||
const hopCount = mode.split('→').length;
|
||||
pathDiv.innerHTML = `<i class="bi bi-signpost-split"></i> ${mode} <span class="text-muted">(${hopCount} hops)</span>`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user