m0lte.uk

Mainly amateur radio + code projects.

Packet radio in a browser tab

Browsers can now talk to serial ports (Web Serial) and process audio in real time (Web Audio and WebAssembly), which is everything a packet station needs. So I’ve built two packet radio pages that run entirely in the browser, with nothing to install. Both are in packet-net/pdn-web and need Chrome or Edge, since those have Web Serial. A TNC2 terminal: packet-term-web packet-term.m0lte.uk is a terminal for a KISS modem on a serial port, such as a NinoTNC on USB. It looks and behaves like a TNC2 in terminal mode, on a phosphor green screen: connect to a station, type, read the replies. The AX.25 connected-mode work is done by @packet-net/ax25, the TypeScript library built on the same generated AX.25 state tables as packet.net (see Generating AX.25 code from the specification), and the terminal is xterm.js. ...

12 November 2026

Checking the AX.25 state machine with TLA+

In Generating AX.25 code from the specification I described how the AX.25 v2.2 state-machine figures are held as data and turned into state tables in seven languages. That post ended with a caveat: tests passing doesn’t mean the tables are right. This post is about closing that gap. The tables are now checked by two separate tools that must agree, the checks are measured for how much of the machine they actually reach, and the meaning of every box in the figures has been written down twice, by two readers who never saw each other’s work. ...

12 November 2026

Packet Mail: BBS mail on your phone

Packet BBS mail still mostly means a terminal and typed commands: L to list, R 1234 to read, SP and a hierarchical address to send. That works, but it isn’t how most of us read mail any more, and it’s hard to do on a phone. Packet Mail is a mail app for packet BBSes. You add your BBS the way you’d add an email account, and your personal mail and bulletins turn up in an inbox, with an outbox, sent items, a bulletins browser and an address book. It’s now on the App Store for iPhone. ...

12 November 2026

Mailcast: a month of sending BBS bulletins one way on 40m

I’ve written up the first month of mailcast as a paper: Mailcast: one-way HF delivery of packet BBS bulletins with fountain codes. It’s long, so this post is the short version. What mailcast is UK packet BBSes pass bulletins to each other over slow connected-mode links, and every link carries every bulletin again. On HF that means fading, retries, and bulletins that take days to get through or never arrive because some BBS along the way isn’t set up to forward to the next. ...

12 November 2026

DAPPS, and the tools built around it

DAPPS (Distributed Asynchronous Packet Pub/Sub) is a store-and-forward messaging layer for packet radio networks. Applications send messages to app@CALLSIGN, and DAPPS finds a path, forwards, fragments, retries and acknowledges, and delivers when it can. Real-time connectivity is not a goal. Think of it as packet mail for application developers, with delivery guarantees and a modern interface. There is a project page at /projects/dapps/ and the code is at packet-net/dapps. Why it exists Anything that wants to move data across a network of nodes, with links coming and going, has to build queues, retries and deduplication. I wanted that done once, below the application, so that someone writing an app only has to publish a message and subscribe to replies. ...

12 November 2026

Generating AX.25 code from the specification

AX.25 is the link-layer protocol most of amateur packet radio runs on. The v2.2 specification ends with a set of SDL diagrams (figures C4.1 to C4.7) that draw the connected-mode state machine: states like Disconnected, Awaiting Connection, Connected and Timer Recovery, with every event, guard and action on the arrows. Each AX.25 stack I know of is somebody’s reading of those figures, typed into a switch statement. The readings differ in small ways, and when two stacks disagree there is nothing executable to check against, because the reference is a PDF. ...

12 November 2026

APRS libraries for C#, Rust, Python, TypeScript and C

APRS is widely used and inconsistently implemented. The spec is several documents written over twenty-odd years (APRS 1.0.1, the 1.1 and 1.2 addenda, now merged into APRS12c), real-world packets often bend the rules, and in places the text contradicts itself. Every decoder is somebody’s own reading of all that, and they disagree with each other. I’ve written five APRS libraries, one each in C#, Rust, Python, TypeScript and C, plus a shared set of test cases. All five give the same answer for every packet I’ve tested them with. They’re all at version 1.0.1. ...

12 November 2026