VARA
kestrel · beta
The VARA mode in hfmodem uses kestrel for link entry, coded data and session control. MFSK bursts establish the link before payload transmission.
Schematic exchange: three MFSK handshake bursts, a wideband link-setup frame carrying the caller’s identity, and data bursts with acknowledgements. The callsigns are K7ABC and W2XYZ.
Channel occupancy
Audio-frequency positions for BW500 subbands and BW2300 rec3 bins. The active bin changes with each emission column.
Link entry
Connect-request and connect-response use one MFSK tone per symbol, from a Visual Basic 6 Rnd() sequence seeded by the called callsign, with no FEC. Connected acknowledgement uses an 11-symbol two-tone control frame: a fixed opening followed by a session-generated tail.
crc = CRC16/GENIBUS(callsign) seed = (crc + SEED_OFF) & 0x7FFF mult = G(callsign) + ((crc+50) >> 15) s = start(seed) repeat (mult + PREADV): s = LCG(s) for k in 0..N-1: s=LCG(s); P = ⌊ s/2²⁴ · 5 ⌋ # 0..4 s=LCG(s); D = ⌊ s/2²⁴ · 7 ⌋ # 0..6 bin[k] = (29 + (k even) + 14·P + 2·D) & 0xFF LCG(s)=(s·0x43FD43FD + 0xC39EC3) & 0xFFFFFF
This integer floor law is the calling-burst tone generator. DATA permutation draws instead reproduce VB6 float32 multiplication and rounding; the two laws must not be substituted for each other.
Callsign addressing
The responder computes the expected tones from MYCALL and correlates them with received audio. The last three callsign characters enter the hash G; the CRC includes the full callsign.
Caller identification
The calling and response MFSK bursts address the called station; native connected acknowledgements use the session control generator. A BW2300 rec3 link-setup frame carries the caller’s identity.
Frame structure and coding
BW500 level 4 uses differential BPSK across two subbands. BW2300 rec3 encodes values as active-bin positions. Above it, levels 5–9 are a few differential-QPSK tones and levels 10–16 are OFDM with a cyclic prefix: differential PSK first, then coherent QAM.
43 payload bytes + marker + 2-byte CRC → 368 bits → XOR whitener → turbo (13,15) rate-½ + 12-bit tail → 748 coded bits → stage-1 raster → differential-BPSK across 394 columns → ⊗ reference grid → 2-subband WOLA at 1350 / 1650 Hz
Each column's cell is de-rotated by a
unit-modulus reference, then bit = 1 if Re(vₖ·conj(vₖ₋₁)) < 0. Two subbands
alternate the active tone symbol-to-symbol.
The historic LUT plot combines truncated prefixes from several columns; complete labelled constellations appear below. The lookup table serves the OFDM levels 10–16, and its QPSK column steps the tone levels 5–9. The base level uses one-hot index modulation with a constant cell value of −1j.
Two identical recursive-systematic
encoders operate in parallel, with log-MAP decoding. State
s = r₀|r₁<<1|r₂<<2; feedback a=u⊕r₁⊕r₂;
parity p=a⊕r₀⊕r₂.
Link-setup frame
The link-setup frame uses the BW2300 rec3 waveform and -byte container. Its one-hot raster selects one bin per emission column across a -bin span. The frame maps information bits to coded bits. The caller’s callsign is packed in six-bit characters at the frame start.
More bits in each cell
Higher VARA levels change constellation width and the amount of parity retained, while keeping the same frame-to-cell pipeline. A wider constellation packs more bits into a cell; fewer parity bits raise throughput and demand cleaner channel observations. The receiver's native answer chooses the next level.
payload · control · CRC
MSB bits + zero pad
C2 stage-2 gather
group parity + dual tails
channel gather
labels · phase · IFFT/CP
Two identical (13,15) recursive constituents start at zero.
Their three termination steps serialize as [s₁,p₁,s₂,p₂] × 3.
Higher-rate groups retain one parity alongside k systematic bits, alternating
C1 and C2 by group. Systematic and component parity streams use this group order.
Full constellation columns
These are the generated labelled points, including the points outside the historic 64-entry LUT's truncated prefix. OFDM bit groups index these labels directly, with no additional Gray pass.
QPSK and 8PSK are differential across time from a reference. 16QAM and 32-cross are coherent on pilots. The cross constellation has 32 points on a 6×6 odd-coordinate grid, with its four corners removed.
One OFDM clock, three carrier sets
The useful IFFT has samples, preceded by cyclic-prefix samples. At 48 kHz, that gives samples per symbol and Hz bin spacing.
| Bandwidth | Levels | Bins | Carriers |
|---|
Each family has three QPSK rows, two 8PSK rows, then 16QAM and 32-cross. Nominal rates follow 1/2, 2/3, 4/5, 2/3, 4/5, 5/6, 4/5. The widest top row is BW2750 L17: 3919 payload bytes per frame, with one or two frames per over. Its nominal speed is about 8489 bps; application throughput also includes control traffic, repeats and source framing.
Pilots create an observable grid
QAM pilots are staggered by bin parity. Each 154-row frame also has extra generator-defined gap cells; they must be skipped when assigning coded bits. PSK instead begins with a reference, then repeats its value at gap cells. Both multiply cells by the fixed per-bin phase scramble.
Reproduce the tables precisely
Stage 1 and stage 2 share each record's VB6 random stream: the second permutation continues the first, then remaining draws generate gaps and pilots. The 24-bit recurrence and float32 draw rounding matter. Whitening and cell scrambling separately reset to seed 29318. The random lead symbols use a session stream; lead draw cost and frame count matter to waveform reproduction.
Complete constants, seeds, labelled points and public code map · All per-level rates, coded lengths and frame capacities · Bit-exact coding and permutation order
ARQ and turn-taking
VARA uses stop-and-wait ARQ. A data burst is answered by an acknowledgement. Applications use separate command and data TCP connections.
| 8300 | command channel — ASCII, \r-terminated |
| 8301 | data channel — raw un-framed bytes |
| CONNECT | start an ARQ session → PENDING/CONNECTED |
| BUFFER n | raw host bytes still queued; drains per ACKed block |
| BW500/2300/2750 | select bandwidth |
| PTT ON/OFF | host keys the radio each burst |
Implementation values
The tables describe the parameters used by kestrel.
▸ MFSK handshake — physical & generator §4.2
| Quantity | Value |
|---|---|
| Modulation | single tone / symbol · sin(2π·carrier·n/2048) |
| Tone → frequency | f = carrier · 48000 / 2048 (= 23.4375 Hz/bin) |
| Sample rate | 48000 Hz |
| Symbol extent (including overlap) | samples |
| Inter-symbol shaping | N= raised-cosine WOLA · hop = |
| LCG (VB6 Rnd) | state = (state·0x43FD43FD + 0xC39EC3) & 0xFFFFFF |
| CR (preamble/N/off/adv) | [74,68,70,60,60,77,50,76,78,74] · N=31 · (50, 1) |
| connect-response | [62,67,55,66,59,72,68,55] · N=15 · (289, 511) |
| connected-ack | two-tone symbols; fixed 4-symbol opening, 7 session-generated state symbols. Native control-frame constants. |
| G basis (last 3 chars) | [-3]=110,220,440,338,134,310 · [-2]=102,204,408,274,6,22 · [-1]=32,64,128,258,36,216 |
▸ BW500 / L4 tone data path §3.6
| Quantity | Value |
|---|---|
| Sub-bands | 2 · centers 1350 / 1650 Hz |
| Samples / symbol | 512 |
| Columns / frame · coded cells | 394 cols · 748 coded |
| Modulation | differential-BPSK · bit = Re(vₖ·conj(vₖ₋₁)) < 0 |
| Frame-start column c₀ | 9 |
| Reference read idx (sub1/sub0) | 471+(462+col)%471 · (460+col)%469 |
| Whitener | additive PN over 368 input bits (VB6-Rnd regenerable) |
| FEC | turbo · two (13,15)-octal RSC · rate-½ (L4) · 12-bit dual tail |
| RSC step | a=u⊕r₁⊕r₂ · p=a⊕r₀⊕r₂ · s'=a|r₀<<1|r₁<<2 |
| Decoder | log-MAP (max*) BCJR · ~12 iterations |
| CRC | CRC-16/GENIBUS (0x1021, init/xor 0xFFFF, no reflect) over frame[:44] |
| Frame payload | 43 bytes + marker + 2B CRC |
▸ BW2300 — base level and the ladder above it §1
| Quantity | Value |
|---|---|
| Base level | record , host BITRATE (4) · index modulation, 175 bps |
| Samples / symbol | · no cyclic prefix, no window, no overlap-add |
| Symbol rate · transform | Bd · plain length- IFFT per symbol |
| Emission | one-hot: exactly one lit bin per symbol, −1j-phased, constant magnitude |
| Bin span | bins of the -point grid · bins at Hz |
| Bits per column | — carried by which bin is lit, Gray-mapped |
| Columns per over | = data + reference |
| Occupied bandwidth | ~735 – 2350 Hz |
| Frame container | bytes · turbo input bits → coded |
| 2048-point analysis window | Four 512-sample columns overlap in each analysis frame. This produces apparent occupancy across bins 34–98 at 23.4375 Hz spacing, with a ~23.7 Bd stride and 100 analysis frames per burst. A 512-point FFT recovers each individual emission column. |
| Levels above the base | tone levels 5–9: 3–10 differential-QPSK tones, a 512-sample pulse each · OFDM levels 10–16: 49 carriers on 1024-point bins behind a 128-sample prefix, QPSK to 32-cross · CRC → whiten → turbo(13,15) → interleave → LUT |
| Level | Family | Carriers | Bits / cell | Samples / symbol | Frame bytes |
|---|
▸ Caller-ID link-setup frame §4.2A · BW2300 rec3 index waveform
| Quantity | Value |
|---|---|
| Waveform | the ordinary BW2300 rec3 index waveform — same waveform, coding chain and container as a DATA over. There is no separate narrowband burst |
| Geometry | -sample symbols · one-hot over a -bin span · data emission columns × bits = coded bits |
| FEC | turbo · (13,15)-octal RSC · rate-½ · N= → coded (2N+12) |
| Internal turbo interleaver | native interleave_stage2 column 3, perm[i] = IL2[3+17·i][:N] — a clean 0..N−1 permutation used directly, with no pruning. Deriving it by dropping entries ≥ N from a larger column yields a different permutation and will not interoperate |
| Channel interleaver | interleave_stage1 column 3, first entries · GATHER: onair[k] = coded[π[k]] |
| Frame / callsign | -byte frame · CRC-16/GENIBUS(body[0:90]) · caller callsign 6-bit packed at the frame start (A–Z→1–26, 0–9→27–36), SSID in body[5] |
▸ ARQ & host API §5 · §7
| Quantity | Value |
|---|---|
| States | DISCONNECTED · LISTENING · CONNECTING · CONNECTED · DISCONNECTING |
| ARQ scheme | stop-and-wait · window 1 · 1 DATA over ⇄ 1 ACK over |
| Connect sequence | |
| Data exchange | Over → peer's two-tone ACK → turn release → peer's over. The caller releases the sending turn with the confirm; the answering station sends the first data burst. |
| Turn release | · SEED_OFF 61, PREADV 391 on the (62, 67) preamble · both stations key it, and the peer answers it by transmitting |
| Turnaround | ~85 ms, transmit to receive |
| Blocks / over | grows 1→2 after consecutive successes |
| Disconnect | one burst, keyed to the called callsign, unanswered · SEED_OFF 60, PREADV 125 |
| Ports | 8300 cmd · 8301 data |
Observed results
Mail reception through K0SI at BW2300 and confirmed outbound delivery through KB8AY (message NL03TXWQ8SGL). Multiple deliveries confirmed by the operator. VARA supports high speed capable and speed limited links.
Implementation evidence records the session conditions.