C6-Reticulum-ASM/tests/packet/test_packet_serialize_header.py
DeFiDude f5ed3bb3b8 packet: parse_header + accessors + serialize_header end-to-end
Reticulum wire-format header parser and accessors. Layout per
upstream/Reticulum/RNS/Packet.py.unpack:

  byte 0  flags (header_type bit 6, packet_type bits 0-1)
  byte 1  hops
  bytes 2..17     dest_hash (HEADER_1)
  bytes 2..33     transport_id + dest_hash (HEADER_2)
  byte after     context + payload

src/include/packet.S pins the packet_t struct offsets and the header
constants (HASH_LEN, HEADER_MINSIZE, FLAG_*, MASK_*, PKT_OK,
PKT_ERR_TRUNCATED). Both the parser and accessors load by these
symbolic offsets, not raw immediates, so a layout change touches one
file.

packet_parse_header populates a caller-provided packet_t (24 bytes)
from a raw buffer. Returns 0 on success, -1 if the input is shorter
than HEADER_MINSIZE (or HEADER_H2_SIZE for HEADER_2). No allocation,
no signature check (deferred to milestone 5+).

packet_get_dest_hash / packet_get_payload — pointer arithmetic into
the caller's raw buffer.

packet_serialize_header — round-trip skeleton. Today copies raw
bytes from packet.raw_ptr; milestone 3 (announce TX) replaces this
with the construction path.

src/state/packet.S adds a 24-byte packet_struct in .bss for _main's
single-packet pipeline.

_main: each KISS frame is now fed to packet_parse_header. The log
emits kiss.rx_frame, then either packet.parsed (status==0) or
packet.rejected (status<0). Integration test sends KISS-framed
HEADER_1 packets via qemu's stdin and asserts the right log lines
come back. The full bring-up demo path — UART RX → KISS decode →
Reticulum parse → structured log — is observable end-to-end.

147 tests, all green. 20 asm functions verified.
2026-05-01 23:05:16 -06:00

35 lines
1.2 KiB
Python

"""Tests for src/packet/packet_serialize_header.S — round-trip skeleton."""
from __future__ import annotations
import re
import pytest
from harness import build
@pytest.fixture(scope="module")
def artifacts() -> build.BuildArtifacts:
return build.build("qemu-virt")
def test_function_exists(artifacts: build.BuildArtifacts) -> None:
assert build.symbol_address(artifacts.elf, "packet_serialize_header") > 0
def test_overflow_returns_minus_one(artifacts: build.BuildArtifacts) -> None:
body = build.objdump_disassemble(artifacts.elf, symbol="packet_serialize_header")
assert re.search(r"\bli\b\s+a0,\s*-1\b", body), body
def test_copies_byte_by_byte(artifacts: build.BuildArtifacts) -> None:
body = build.objdump_disassemble(artifacts.elf, symbol="packet_serialize_header")
assert re.search(r"\blbu\b\s+\w+,\s*0\(t1\)", body), body
assert re.search(r"\bsb\b\s+\w+,\s*0\(t2\)", body), body
def test_returns_bytes_written(artifacts: build.BuildArtifacts) -> None:
body = build.objdump_disassemble(artifacts.elf, symbol="packet_serialize_header")
# Final mv a0, t0 returns raw_len (which we loaded into t0 at the top).
assert re.search(r"\bmv\b\s+a0,\s*t0", body), body