Documentation
HFEdge,
clearly.
HFEdge is a free, open desktop application, radio protocol, and measurement pipeline that turns a commodity HF station into a node of a distributed ionospheric observatory.
Development status
Simulation and loopback testing exist — including Watterson-channel tests of the H-Mode physical layer. Published on-air curves, classifier validation against instrument ground truth, and a general-availability source release remain pending. Until release channels are available, this documentation is a technical preview rather than an installation promise.
What it measures
A transmitter sends a deterministic Base36 stream in framed profiles. Because a receiver can regenerate the expected stream from the shared PCG64 seed — 128 bits of OS entropy, with the low 64 bits seeding the generator and the high 64 bits setting the sequence — every substitution, erasure, insertion, and confidence change becomes a channel observation attributable to the path, not the message.
The application scores character error rate, erasures, insertions, block error rate, burst behavior, and a 36×36 expected-versus-received confusion matrix. Optional soft outputs include per-character confidence and six log-likelihood ratios per character, plus per-resource channel state (linear SNR, magnitude, phase).
Build path preview
The planned source build requires CMake 3.21 or later, Ninja, a C++20 compiler, and Qt 6.5 or later. Supported compiler families include MSVC 2022, GCC 12+, Clang 15+, and MinGW 13+. Optional dependencies (SoapySDR, librtlsdr, spdlog) are fetched automatically when absent.
cmake -S . -B build -G Ninja -DCMAKE_BUILD_TYPE=Release \
-DCMAKE_PREFIX_PATH=<Qt prefix>
cmake --build build
ctest --test-dir build --output-on-failure1. Verify without RF
Run the synthetic loopback before connecting a radio. A clean loopback validates the full TX → DSP → RX → scoring path — and establishes your station’s equipment-noise baseline, which later lets analyses separate rig artifacts from channel effects.
./build/hfedge_cli --loopback2. Add a station path
Choose either a CAT-controlled transceiver with an audio interface or a SoapySDR-compatible receiver. Verify PTT and frequency readback before any scheduled session.
3. Start receive-only
A monitoring station is the safest first role — no license is required to listen, and reception reports still feed the science. Confirm device gain, timing quality, and decode behavior before considering a licensed test transmission.
4. Run a PING
PING carries 720 scored payload characters and finishes in moments. It is the shortest defined profile and the recommended first path observation.
Hardware integration
CAT — transceiver path
Native control families: Icom CI-V, Yaesu, Kenwood TS, Elecraft K3/KX, FlexRadio TCP, and Hamlib rigctld — with custom command templates for exotic rigs. The CAT layer handles PTT and polling with a watchdog.
SDR — direct path
Anything SoapySDR speaks: RTL-SDR, Airspy, SDRplay, HackRF, LimeSDR, USRP, plus Flex IQ — and a simulated device for CI, training, and classrooms. A sub-$200 station is a valid sensor node.
Classic modes & clock
Built-in modems for Olivia, PSK31/63/125, MFSK16, RTTY, and CW, plus an fldigi bridge, so HFEdge can serve as a daily digital-mode station. Time comes from GPSD when available, NTP otherwise, with an explicit free-running quality flag carried in every report — in a sensor network, bad timestamps are worse than no timestamps.
Observation profiles
| Profile | Payload | Best used for |
|---|---|---|
| PING | 720 characters | Link check or band probe; seconds-scale channel occupancy |
| SHORT | 3,200 characters | Path characterization with modest airtime |
| STANDARD | 64,000 characters | Disturbance morphology; resolves TID-period structure |
| DEEP | 1,000,000 characters | Long-duration statistics; confusion-matrix convergence |
All payloads use 64-character frames with ==Fxxxx== markers (uppercase hex global frame index). Frame F0000 is the identification frame — H2 + callsign(10) + profile + mode + CRC32(8) + grid6 — and is excluded from scoring. A Hunt → Locked → Tracking → Lost sync state machine tolerates marker loss: two consecutive markers to lock, three missing to drop to Lost, with continuous resync scanning.
Waveform profiles are runtime-selectable JSON configurations — robust for disturbed or unknown paths, balanced by default, high_speed for strong SNR, classic for H-MODE-1.0 interop. No recompilation; experiments ship as data.
Measurement outputs
- CER — character error rate: substitutions over compared characters.
- ERAS — erasure rate: expected characters that did not arrive.
- INS — characters inserted by the receive path.
- BLER — block error rate.
- Confusion — a 36×36 expected-versus-received matrix: adjacent-symbol errors indicate ISI and timing; distributed errors indicate noise and turbulence; erasures indicate deep fades. Three different physical mechanisms, one table.
- Soft evidence —
SoftChar { c, confidence, llr[6], ofdm_index }and optionalResourceCsi { snr_lin, magnitude, phase }.
Reported aggregate metrics include 95% confidence intervals. Clock quality travels with each session so downstream work can distinguish GPS, NTP, and free-running time — and restrict cross-station timing analyses to GPS-quality tiers.
Network participation
The prototype REST surface (/v2/sessions…) accepts reception logs in rlog (frame text) or diff (per-frame substitutions/insertions/erasures) formats. A background upload queue with retry lets unattended stations survive connectivity loss without losing scorecards.
Server-side scoring returns CER, ERAS, INS, and BLER with 95% confidence intervals, plus timelines, burst-erasure statistics, and per-report confusion data. Each link is geolocated at its estimated one-hop ionospheric pierce point, and /v2/map/anomalies surfaces typed candidates — d-region-absorption, epb-spread-f, sporadic-e, tid — with severity and detail fields. Duplicate-upload replay detection and a flagged-report moderation surface protect dataset quality. Archives export as JSON and CSV.
Built like it matters
Under the polish is production engineering: modern C++20/23, a Qt 6 (≥6.5) QML interface, Catch2 suites for the core protocol and every H-Mode waveform family, continuous integration that exercises the synthetic loopback path, reproducible CMake presets, and a documented release and security process.
Three choices deserve emphasis. Determinism everywhere: published test vectors and a bit-exact classic profile mean two independent implementations produce identical streams — that is what makes cross-station scoring a measurement rather than a comparison of implementations. Headless parity: hfedge_cli runs the same engine as the GUI, so Raspberry-Pi-class remote nodes are first-class citizens. Queue-based networking: upload is decoupled from sessions by design.
Open by design
The waveform specification, stream protocol, test vectors, configuration schema, reference implementation, and API surface are intended to be public and independently auditable. Nothing in seeded operation depends on a secret algorithm: obscurity requires secrecy, and nothing here is secret. Any third party can capture a transmission, regenerate the expected stream, and independently compute CER, ERAS, and the confusion matrix — which is what makes reported scorecards auditable claims rather than assertions.
H-Mode is designed for FCC Part 97-style amateur operation: no messages encoded to obscure meaning (§97.113(a)(4)), emissions confined to ≤ ~2.8 kHz per bonded channel with windowing-enforced masks (§97.305), and transparent identification in frame F0000 on every session (§97.119). One-way test operation belongs under licensed control. It is not certified or universally approved — digital-mode bandwidth and one-way rules vary by administration. Operators remain responsible for their license, band plan, local rules, and control of any transmission.