Deep dives on the engineering behind HTCommander — real-world findings, protocol reverse-engineering and DSP experiments. The honest ledger of what works, what doesn't, and what we still don't know.
Building and tuning DART (Data Adaptive Rate Transport), an adaptive OFDM modem for sending data over ordinary VHF/UHF FM voice radios (2 m / 70 cm) across a Bluetooth (SBC) audio link. Best read in order — each post builds on the last, walking from the first over-the-air observation down to the root-cause diagnosis and fix.
The first over-the-air test on two UV-Pro radios. Which modes work, which fail, and the first evidence that the quality ceiling lives in the audio path — not the RF, band, or transmit level.
Read more → Part 2The Bluetooth SBC codec adds a small noise floor under the signal. We measure how much, and show that raising the bitpool saturates quickly and never moves the ceiling.
Read more → Part 3How SBC spends its bits across subbands, and why its default loudness allocation is the wrong choice for data — a free quality gain from switching data frames to SNR allocation.
Read more → Part 4Building a phase-noise channel model and a phase-drift meter to turn "it's probably phase noise" into a measurement — then fixing it with pilot-aided phase tracking, recovering a rung of throughput, and showing the remaining ceiling is raw SNR (a link-budget problem), not DSP.
Read more → Part 5A lopsided constellation reveals that short frames are mostly known zero-padding. Telling the decoder those bits are known (code shortening) buys 5+ dB of margin on short frames — for free, and scaling exactly with how short the frame is.
Read more → Part 6Building a multipath echo channel to test whether DART's deliberately-short cyclic prefix is big enough. It finds the classic ISI knee at the CP boundary, confirms the SBC/audio path adds no dispersion the CP misses, and shows the short-CP bet was safe.
Read more → Part 7Why repetitive data (a frame full of zeros) wrecks spectrum, PAPR, and phase tracking — and why the fix is to make the data look like noise first. Compares the self-synchronizing G3RUH scrambler against an additive frame-synchronous one, and lays out the LDPC-friendly PN15 whitener DART will adopt.
Read more →FIguring out the radio's firmware-update path — from the cloud check that finds an update to the two-phase Bluetooth flash that writes it into the radio.
A walk through the firmware-update path — from the cloud update check and patch-based download to the device-paced, two-phase GAIA transfer that streams a new image into the radio over Bluetooth.
Read more → FirmwareA field report on the online side — the gRPC check, the patch-based download, and the honest ledger of what we've proven and the DID puzzle we still can't crack.
Read more →The low-level language HTCommander and the radio speak to each other.
A byte-level reference for the whole control protocol — the two Bluetooth framings, the command envelope and response bit, the full basic/extended opcode set, the bit-packed layout of every important payload (device info, settings, channels, HT status, GPS position, BSS, FM radio, buttons), the notification model, and the two sub-protocols that ride on top: fragmented TNC data carrying AX.25 packets, and the VM firmware-update channel.
Read more → RadioA field note on BSS, the undocumented Baofeng/BTech binary format for text, location, and "ring my radio" alerts — the 0x01 marker that separates it from AX.25, the length-includes-type TLV framing, a packet decoded by hand, the 0x85 message-ID sentinel, the field catalog and the location-request / call-request verbs, and an honest ledger of the location bytes still on the workbench.
Making HTCommander features portable between operators and radios.
Trusting what comes off the air — proving who sent a message, without breaking the no-encryption rules.
Connecting HTCommander to the wider ecosystem of tools operators already run.
Getting good diagnostics out of the app when something goes wrong.
Bringing internet-linked voice into the same app that drives the radio.
A full walk through the EchoLink stack in pure Dart — the GSM voice codec, the UDP audio/control ports and TCP directory, the RTCP SDES/BYE handshake that opens a QSO, how voice and chat are wrapped, what callsign suffixes and node numbers mean, a NAT pinhole that quietly eats receive audio, and how to get an account and make your first connection.
Read more → InternetA design note written before the first line of code — what APRS-IS is, the single-line passcode login, the TNC2 ⟷ AX.25 codec that lets internet packets reuse the existing APRS pipeline, the full-IGate rules for gating between RF and the internet (q-constructs, NOGATE, the "recently heard" list), and the receive-only-first test plan.
Read more → InternetHow we speak Asterisk's native IAX2 protocol from pure Dart to connect to an AllStarLink node — the single-UDP-port design, full vs. mini frames, the NEW/AUTHREQ/AUTHREP/ACCEPT/ANSWER call handshake, MD5 challenge-response auth, GSM and μ-law voice, UDP reliability with sequence numbers and the 0x8000 timestamp-resync trick, why we connect client-to-node (DVSwitch/iaxRPT style), and how to configure a node and make your first call.
Read more → InternetThe other direction — turning HTCommander into a node others dial into. Running the inbound IAX2 server (the handshake in reverse), sharing one socket between calls and registration by call-number range, IAX2 registration so the network can find you, and the radio relay: bridging 8 kHz call audio to a handheld's PTT with half-duplex carrier arbitration so local RF always wins. Plus accepting Web Transceiver clients safely by validating their portal token the way a real app_rpt node does.
Sending and shaping audio through the radio — from the microphone to Morse.
Working amateur radio satellites with a handheld — tracking, passes, and Doppler.
Pulling life-saving signals out of the air — receive-only, on protected bands.
How HTCommander packs large datasets into small, fast, self-contained files.
How the FCC's weekly amateur-license dump becomes a small binary .cdb you can binary-search offline — and the stack of encoding tricks (base-37 packed keys, an offset-free index, epoch-relative dates, state/class/status/city dictionaries, numeric ZIPs, and xz) that shrink every record to the bone.
How the same .cdb format is reused for Canada's ISED amateur data behind a single header flag — and the three encoding changes the Canadian data forced: alphanumeric postal codes packed in alternating bases, qualifications as a bitmask instead of class/status, and dropping expiry dates that never exist.
How HTCommander is built under the hood — the threading, plumbing, and design decisions that keep the radio responsive.
Getting a full HTCommander development environment running on your own machine.