hfmodemDocumentation

STANAG 5066 (the HF subnetwork profile)

hfmodem.bateleur.s5066 is the STANAG 5066 edition 1.2 link layer: the subnetwork interface, channel access and data transfer sublayers of annexes A, B and C. Annex A.2.2 defines the client framing; the station uses TCP port 5066 by default. It runs on the bateleur modem, so the waveform underneath is any of 188-110 serial, STANAG 4285, STANAG 4539 or the 39-tone mode. Interoperation with a foreign implementation remains unverified; the tests below exercise byte sequences and local nodes.

What is implemented

PartWhereAnnex
D_PDU framing: the 0x90 0xEB sync, EOW, EOT, the address field in half bytes, the header CRC-16 (0x9299) and segment CRC-32 (0xF3A4E550), checked against the annex's own worked exampledpduC.3.2
Every D_PDU type: DATA-ONLY, ACK-ONLY, DATA-ACK, RESET/WIN-RESYNC, EXPEDITED DATA and ACK, MANAGEMENT, NON-ARQ and EXPEDITED NON-ARQ, WARNINGdpdu, dtsC.3.3–C.3.12
Selective-repeat ARQ: the window (128 at most), selective acknowledgement, in-order and any-order delivery, segmentation and reassembly of C_PDUs; the window synchronisation testsdtsC.4.1, C.6.2, C.6.3.2
Expedited ARQ, stop and wait, ahead of ordinary datadtsC.3.7–C.3.8, C.6.1.3
Non-ARQ delivery with repeated copies, to a node or a group address; delivery with errors, the bad and missing spans reporteddtsC.3.10–C.3.11, C.4.2
The data rate change, master and slave (EOW types 1 and 2 in MANAGEMENT D_PDUs, table C-26's repetitions); separate transmitted management acknowledgements and reception of combined request-with-ACK messagesdtsC.5, C.6.4
The full resetdtsC.6.5
Physical links: made, accepted, rejected, broken, confirmed; exclusive and nonexclusive; crossing requests; retries with a random backoff (this implementation's choice; the annex sets none), so that two nodes whose requests collided do not collide againcasB.3
The S_primitives of A.2.1 and their framing on the client's streamprimitivesA.2.1, A.2.2
Clients bound to SAPs; ARQ, non-ARQ and expedited U_PDUs; node and client delivery confirmation; time to live; soft links made for queued data and broken when idle; hard links of all three typessisA.1, A.2, A.3
Half-duplex turn taking: keying only when the channel is clear, the far end's EOT for when a lost transmission would have ended, a wait for the answer before sending againnodeC.3.2.3

On the modem

OnAir puts a node on a BateleurModem. The node is the modem's only user: what the receivers hear is what it hears, and what it has to send the modem sends. The EOT it writes, and how much it puts in one transmission, come from the mode itself, long interleavers' block quantisation included.

A data rate change retunes the modem to the 188-110 or STANAG 4539 mode of that rate and interleaver. Those receivers find the mode from the signal, so those are the rates a node accepts. Under STANAG 4285 and the 39-tone modes, whose receivers must be told the mode beforehand, a node accepts only the rate it is already at.

On the station:

[protocols.bateleur]
enabled = true
host = "s5066"             # instead of "bateleur", the raw byte ports
addresses = ["0.0.0.1"]    # the node's own
mode = "110 1200L"         # where it starts; a DRC may move it
port = 5066

A client connects to the port, binds a SAP and trades S_primitives. Many clients can be connected at once, one SAP each.

How it is tested

Node exchange tests use two simulated channels. Both run in simulated time.

The station tests put a node on the station's modem. A far node's broadcast, off replayed air, reaches a client bound on the port. A client's broadcast keys through the arbiter and decodes back into the same D_PDUs.

The test drivers live under tests/bateleur/s5066/ether.py. The regression suite adds frames with explicit window edges, combined management messages, restarted links, CRC-failed non-ARQ segments and long segmented C_PDUs.

Bounds and delivery

A transmitted D_PDU fits a single modem burst. Segmentation uses the current mode's byte budget, including headers, and a proposed rate must accommodate outstanding frames. Local transmit refusals leave the composed data and acknowledgements pending. Ordinary frames stop after six retransmissions; DRC management messages allow three, with a 120-second procedure timeout. These are local defaults. A peer's reply alone does not count as progress.

Non-ARQ reception windows cover the remaining copies, including later bursts. The sender stops sending a C_PDU after its advertised deadline. Reassembly accepts at most 2054 bytes per C_PDU, eight active C_PDUs per source and 64 in total, held for at most 600 seconds. In-order C_PDUs wait behind an earlier partial C_PDU from the same source and service. Complete any-order C_PDUs may be delivered sooner. The node keeps the last 256 heard D_PDUs.

A client selects delivery with errors by binding with service mode 3. Missing and CRC-failed data spans reach that client only when the C_PDU and S_PDU headers are intact; damaged routing bytes cannot select a SAP. Other clients receive only complete data. Non-ARQ and group receptions never request a client delivery report over the channel.

The SIS queue admits at most 64 outstanding requests per client and 256 in total. Expedited limits count outstanding requests. Unbinding removes queued requests and suppresses late reports to a subsequent binder of the same SAP. A higher-ranked valid bind may preempt an existing SAP. Mode 0 is invalid in a bind; A.2.1.4 defines no matching rejection reason, so this implementation uses reason 1 as a local fallback. That choice is not verified against a foreign SIS client. A client trace containing a mode-0 bind and its rejection would establish the expected reason.

TTL is capped at 648000 two-second units (15 days, A.2.2.20). The transmitted TTD uses day of year modulo 16 and seconds in UTC (A.3.1.1). Reception searches actual calendar dates in the next 15 days, including across New Year, instead of treating a date over eight days away as expired. The field has no epoch: a sufficiently old message can share a residue with a future expiry, and New Year can repeat residues within the allowed horizon. This reading is unverified against a foreign implementation. A recording with known sender UTC, submitted TTL and delivery times for nine-day and fifteen-day TTLs, expired messages, and messages crossing 31 December would settle how a peer resolves that ambiguity.

What is not implemented

PartStatus
Annex D (the modem interface)The modem is driven directly rather than over the annex's interface.
Annex E (modem remote control)Informative. Not written.
Annex F's clients (RCOP, UDOP, HMTP, HFPOP, CFTP, IP)Not written. A client of the port is the application.
Annex G (rates above 2400 bit/s)The DRC names them, and 4539 carries them. The annex's own procedures are not written.
The CSMA and token-passing media access of later editionsNot in edition 1.2. Not written.
InteroperationUntested. No other implementation has been run against this one, and no radio has carried it.