Skip to content

Adaptive FHSS: authenticated hopset state and commit protocol #263

Description

@josephnef

Summary

Build the deterministic state model and authenticated control protocol for adaptive FHSS hopset changes. This is the protocol foundation for receiver-driven exclusion and later autonomous TX decisions; it does not choose which channels are bad.

Follow-up to #153 / #262. The fixed-hop implementation and measured behavior are documented in docs/fhss.md; adaptive exclusion is its stated next step.

Design

Keep the configured base hopset immutable. Every adaptive state identifies active channels by stable base-hopset bit positions:

struct HopsetState {
    uint32_t epoch;
    uint32_t generation;
    uint64_t active_mask;
    uint64_t activate_round;
};

Derive each round's permutation from (schedule_key, generation, round, active_mask). Including generation ensures a mask change produces a fresh keyed order instead of merely exposing a filtered form of the previous permutation. The schedule remains stateless by absolute slot.

Add versioned authenticated messages:

  • HopsetProposal: epoch, proposed generation/mask, observation count, activation round, reason bitmap, authentication tag.
  • HopsetCommit: epoch, generation, mask, activation round, authentication tag.
  • HopsetStatus: epoch, current generation/mask/round, authentication tag.

TX is the schedule authority: RX proposes; TX validates policy constraints and repeatedly commits; both activate on the announced future round. Derive separate schedule and control keys from DEVOURER_HOP_SEED with explicit domain separation. A schedule fingerprint is not authentication.

Commits must be announced at least 8 rounds ahead and repeated until activation. Acquisition always scans the immutable base hopset; sync/status markers advertise generation and mask fingerprint so an RX that missed the transition can recover. Add infrequent keyed base-hopset rendezvous/probe slots if hardware testing shows acquisition cannot reliably find a reduced set.

Reject stale epochs, replayed/non-monotonic generations, unknown base-hopset fingerprints, activation outside the allowed window, and masks below the configured minimum diversity.

Implementation

  • Extend HopSchedule (or a sibling header-only module) with generation/mask-aware stateless lookup and stable base-hopset indexing.
  • Add dependency-free encode/decode/MAC helpers for the three control messages; do not change caller-owned FEC payload bytes.
  • Extend FHSS sync markers with generation plus active-mask fingerprint while retaining versioned backward rejection.
  • Add structured events for proposal, commit, activation, rejection reason, generation mismatch, and recovery.
  • Document the state machine and wire format in docs/fhss.md.

Acceptance criteria

  • Known-answer tests pin schedule output for fixed key/generation/mask/slot tuples.
  • Every adaptive round covers every active channel exactly once.
  • Two independent instances agree after direct join at a nonzero generation.
  • Tests cover lost, duplicated, reordered, forged, and replayed control frames; TX/RX restart; generation rollover policy; invalid masks; and missed pre-activation commits.
  • A process-level test demonstrates synchronized future-round activation and recovery after one peer misses the commit window.
  • Existing sequential/keyed fixed-hop behavior remains unchanged when adaptive mode is disabled.

Out of scope

  • Deciding which channel to exclude.
  • RF feedback transport policy.
  • Autonomous TX sensing.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions