mirror of
https://github.com/ratspeak/C6-Reticulum-ASM
synced 2026-08-12 18:07:18 -04:00
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.
35 lines
1.2 KiB
Python
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
|