#!/usr/bin/env python3 """Build hand-crafted MeshCore test vectors as individual JSON files.""" # /// script # requires-python = ">=3.10" # dependencies = [] # /// import json import os import struct from pathlib import Path OUT = Path(__file__).parent / "hand" OUT.mkdir(exist_ok=True) def write_case(name: str, case: dict): path = OUT / f"{name}.json" path.write_text(json.dumps(case, indent=2, ensure_ascii=False) + "\n") print(f" {path.name}") # ── Packet building helpers ─────────────────────────────────────── def mc_header(payload_type: int, route_type: int, ver: int = 0) -> int: return (ver << 6) | (payload_type << 2) | route_type def path_len_byte(hop_count: int, hash_size: int) -> int: return ((hash_size - 1) << 6) | (hop_count & 0x3F) DUMMY_PUBKEY = bytes(range(32)) DUMMY_SIG = bytes(64) TS_2026 = struct.pack(" bytes: hdr = bytes([mc_header(0x04, route_type)]) hops = path_hops or [] pl = bytes([path_len_byte(len(hops), hash_size)]) path = b"".join(hops) payload = pubkey + timestamp + DUMMY_SIG + app_data return hdr + pl + path + payload def peer_packet(payload_type: int, route_type: int, dst: int, src: int, mac: bytes, ciphertext: bytes, path_hops: list[bytes] | None = None, hash_size: int = 1, tc: tuple[int, int] | None = None) -> bytes: hdr = bytes([mc_header(payload_type, route_type)]) hops = path_hops or [] pl_byte = bytes([path_len_byte(len(hops), hash_size)]) path = b"".join(hops) body = bytes([dst, src]) + mac + ciphertext tc_bytes = b"" if tc is not None: tc_bytes = struct.pack(" bytes: hdr = bytes([mc_header(0x03, route_type)]) hops = path_hops or [] pl_byte = bytes([path_len_byte(len(hops), hash_size)]) path = b"".join(hops) return hdr + pl_byte + path + struct.pack(" bytes: hdr = bytes([mc_header(payload_type, route_type)]) hops = path_hops or [] pl_byte = bytes([path_len_byte(len(hops), hash_size)]) path = b"".join(hops) return hdr + pl_byte + path + bytes([ch_hash]) + mac + ciphertext def anon_req_packet(dst: int, ephem_pub: bytes, mac: bytes, ciphertext: bytes, route_type: int = 1, path_hops: list[bytes] | None = None, hash_size: int = 1) -> bytes: hdr = bytes([mc_header(0x07, route_type)]) hops = path_hops or [] pl_byte = bytes([path_len_byte(len(hops), hash_size)]) path = b"".join(hops) return hdr + pl_byte + path + bytes([dst]) + ephem_pub + mac + ciphertext def trace_packet(tag: int, auth_code: int, flags: int, trace_hashes: bytes = b"", route_type: int = 1, path_hops: list[bytes] | None = None, hash_size: int = 1) -> bytes: hdr = bytes([mc_header(0x09, route_type)]) hops = path_hops or [] pl_byte = bytes([path_len_byte(len(hops), hash_size)]) path = b"".join(hops) payload = struct.pack(" bytes: hdr = bytes([mc_header(0x0A, route_type)]) pl_byte = bytes([path_len_byte(0, 1)]) control = bytes([(remaining << 4) | (inner_type & 0x0F)]) return hdr + pl_byte + control + inner_payload def control_packet(flags_byte: int, payload: bytes, route_type: int = 1) -> bytes: hdr = bytes([mc_header(0x0B, route_type)]) pl_byte = bytes([path_len_byte(0, 1)]) return hdr + pl_byte + bytes([flags_byte]) + payload # ── Test cases ──────────────────────────────────────────────────── print("Building hand-crafted test vectors...") # ADVERT: basic chat node with name write_case("advert_basic", { "description": "ADVERT flood, chat node with simple ASCII name", "tags": ["advert", "flood", "name", "chat"], "packet_hex": advert_packet(bytes([0x81]) + b"TestNode").hex(), "valid": True, "expected": { "route_type": "flood", "payload_type": "ADVERT", "payload_ver": 0, "transport_codes": None, "path": {"hash_size": 1, "hops": []}, "payload": { "pubkey_prefix": DUMMY_PUBKEY[:4].hex(), "timestamp": 1774600000, "advert": { "flags": 0x81, "node_type": "chat", "location": None, "name": "TestNode" } } } }) # ADVERT: repeater with valid GPS location + name write_case("advert_location", { "description": "ADVERT flood, repeater with valid GPS coords and name", "tags": ["advert", "flood", "location", "repeater"], "packet_hex": advert_packet( bytes([0x92]) + struct.pack("