Last updated 2026-10-13 03:23 UTC
mLink

The mLink Manual

A plain-speech guide and technical deep dive into a self-organizing data network for amateur radio

By Tyler Dinsmoor, K7OTR ยท tyler@dinsmoor.us

Preface: How to Read This Manual

1 Who this book is for

You hold an amateur licence, you have an HF (high frequency, shortwave) transceiver, and you want to move messages and mail between stations without the internet. You do not need to be a programmer. If you have made an FT8 contact, run a packet node or sat through an evening net, you have the background this book assumes.

It is also written for the ham who wants to know why: why a lost frame costs only that frame, why the station sometimes waits before keying when the channel sounds clear. The reasoning is in plain speech, with the numbers taken from the software itself. It is not a programming reference: it names frames and bytes, because those travel between stations, but never a source file.

2 Two ways through the book

The operator route is Parts I and II. Part I is the big picture: Chapter 1, then Chapter 2, which follows one piece of mail from one operator to another and is the best short tour of the whole system, then the radio background in Chapter 3. Part II is the operator's manual: installing, every window of the client, what the outbox is telling you, and accounts.

The deep dive is everything after that, in the order a reader needs it. Part III is the signal: the passband, the error-correcting codes, the three modems and the receiver. Part IV is the protocol, everything that happens on the air between stations. Part V covers the services built on it, such as emergency calls and mail. Part VI is the station software, Part VII is FmLink, and Part VIII explains how mLink is tested.

Each idea is explained once, in one chapter, and every other chapter links to it: when a sentence ends in a link, the full story is at the other end. Reading only the box at the top of each chapter is a fair way to get the shape of the parts you skip. For a number in a hurry, go to Appendix A; for the bytes of a frame, Appendix B.

3 Conventions

3.1 One yardstick for signal strength

Every signal-to-noise figure in this book is on one scale, SNR@3k: the signal against the noise in a 3 kHz SSB (single sideband) bandwidth, defined in Section 3.4.3.

3.2 Frame chains in brackets

One transmission from an mLink station is usually several frames back to back. We write it as frame names in square brackets, in the order they go out:

[presence][rts][bulk 0][bulk 1][bulk 2]

That reads: a PRESENCE frame (who is talking), a request to send (what is coming and for whom), then three bulk data frames. "Protocol" in this book always means what happens on the air, never the conversation between your station and the program you look at.

3.3 The boxes

A term with a dotted underline, like region, is a glossary entry. Hover over it for a one-line definition, or follow it to the glossary at the back. A term is linked the first time it appears in a chapter. References to chapters, sections, figures and tables are live links, numbered automatically. Acronyms are spelled out the first time a chapter uses them, and where the wider industry has a name for something mLink built, we give that name too.

Part I: The Big Picture

Chapter 2

Mail in mLink

2.1 The example

Three stations are on one 40 m frequency. None has internet access.

The mail is a text report. Compressed and wrapped it is 2,000 bytes. B has reported hearing A at +10 dB (SNR@3k), and A uses that figure.

2.2 Scenario 1: B hears A

A sender B recipient C unattended 1. the mail, one transmission 2. reply: what arrived, what to repeat C hears it and stays off the air
Figure 2.1. Scenario 1: A reaches B directly.
  1. Compose. The operator at A writes the mail in the client and presses Send. The client hands it to the station daemon in one command; the station makes every decision from here (Section 5.5.2, Chapter 30).
  2. Outbox. The station saves the mail in its outbox as pending, then queues it (Chapter 6).
  3. Check and wrap. The station computes a 16-bit integrity check over A's callsign, B's callsign and the mail. That value also names the mail on the air. It then tags the content as mail, compresses it if that makes it smaller, and adds one byte saying how it was packed: 2,000 bytes (Section 16.2, Chapter 21).
  4. Choose how to send. The station picks from the size and its link estimate for B. A small message or a weak path goes as a shortburst or longburst. 2,000 bytes over a path better than +6 dB go as a bulk transfer. With the 2-byte check in front that is 2,002 bytes in three frames: frame 0 at rate 1/2 holds 603, frame 1 at rate 3/4 holds 907, frame 2 at rate 5/6 holds the last 492 (Chapter 15).
  5. Wait for a free moment. The station keys only when it is not in another exchange, no other station has reserved the part of the passband it needs (a defer), and its receiver hears nothing. If the frequency has just gone quiet it first waits a random time, from a fraction of a second to several seconds. The outbox row becomes airing (Chapter 17).
  6. Transmit. One transmission carries the mail: [presence][rts][bulk 0][bulk 1][bulk 2]. PRESENCE gives A's callsign and grid. The RTS says three bulk frames follow for KX0BBB, rates up to 5/6, and gives the check value. Both are 0.64-second frames on the bulk-control channel (Section 8.5.1). After 150 ms come the three 5.44-second bulk frames, sent by OFDM (Chapter 12) and protected by an LDPC code (Chapter 9). Total: 17.8 seconds. C hears the RTS and stays off the bulk region until the transfer ends (Chapter 14).
  7. Receive. B decodes the PRESENCE and RTS, works out when frame 0 starts, and finds each later frame one frame-length further on. In this example a fade destroys frame 1. Frame 2 still decodes, because its position was fixed by frame 0. B keeps frames 0 and 2 and has a 907-byte gap (Section 13.8).
  8. Reply. About two thirds of a second after A's transmission ends, B sends [presence][dnak] on the same control channel, 1.3 seconds. The dNAK is a map with one bit per bulk frame; only frame 1's bit is set (Chapter 16).
  9. Repair. A sends only frame 1's 907 bytes, and one rate more robust than they were lost at: two rate-1/2 frames of 603 and 304 bytes, in [presence][retx-rts][bulk 0][bulk 1], 12.3 seconds. B writes them into the gap. mLink calls this selective repair dARQ (Section 16.5).
  10. Verify. B unwraps the mail and computes the same 16-bit check. It matches. A mail that fails the check is neither delivered nor acknowledged.
  11. Acknowledge. B sends [presence][ack]. The ACK names the mail by its check value. B's client shows new mail from A. A's outbox row becomes sent.

From the first PRESENCE to the end of the ACK: about 35 seconds, of which 32.7 are transmission (17.8, 1.3, 12.3 and 1.3).

A B [P][RTS] bulk 0 (1/2) bulk 1 (3/4) bulk 2 (5/6) decoded faded: lost decoded [P][dNAK] "frame 1 missing" [P][RETX-RTS] bulk 0 (1/2) bulk 1 (1/2) only frame 1's 907 bytes: 603 + 304 [P][ACK] 0 s 10 s 20 s 30 s
Figure 2.2. Scenario 1 on the air, to scale. Hatched blocks are the short opening and reply frames; plain blocks are 5.44-second bulk frames, marked with their rates. The transmission lengths are exact; the gaps between them are approximate.
1 Compose 2 Outbox 3 Check + wrap 4 Choose 5 Wait 6 Transmit 7 Receive 8 dNAK 9 Repair 10 Verify 11 ACK: sent at station A at station B, and back
Figure 2.3. The eleven steps of a direct delivery.

2.3 Scenario 2: B cannot hear A, but C hears both

A sender B recipient C unattended 1. the mail: B does not hear it 2. A asks for a relay; C offers, A picks C 3. C sends its copy; B replies to C 4. C tells A the mail was delivered
Figure 2.4. Scenario 2: C, which hears both, relays the mail.

A's estimate for B is a few minutes old and still looks good, so steps 1 to 6 happen as before. C is not the addressee, but it decodes the transfer and keeps a copy.

  1. Silence. A waits five seconds for a reply. None comes.
  2. Probe. A does not send the bulk frames again. It sends one short question, [presence][qsl], a probe that carries no data. Silence again (Section 16.6).
  3. Ask for a relay. A sends a REQUEST naming KX0BBB and the mail's check value. It does not carry the mail. C holds that mail and heard B within the last two minutes, so after a random wait it sends an OFFER saying how well it hears B. A waits two seconds for better offers, then names C in a SELECT: [presence][relay/request], [presence][relay/offer], [presence][relay/select].
  4. The relay delivers. C sends the mail to B as a transfer of its own: [presence][relay/for][rts][bulk 0][bulk 1][bulk 2]. The RELAY/FOR frame names A as the author and gives the original check value. B replies to C exactly as in Scenario 1, repairs included, and files the mail as coming from A.
  5. Result. C sends A a RELAY/RESULT frame. A's outbox row becomes sent. If C cannot reach A at once, it holds the result and sends it when it next hears A (Chapter 19).
A C (relay) B transfer to B: no answer, "did you get that?": no answer [presence][relay/request] (to all) [presence][relay/offer] [presence][relay/select] [presence][relay/for][rts][bulk...] [presence][ack] [presence][relay/result]
Figure 2.5. Scenario 2. C offers because it holds the mail (overheard from A) and heard B within the last two minutes. B files the mail as coming from A.

2.4 Scenario 3: nobody can reach B

A sender B recipient C unattended 1. the mail: B is off the air 2. A asks for a relay; nobody offers C cannot hear B either 3. A keeps the mail and tries again when it next hears a station
Figure 2.6. Scenario 3: nobody can reach B, so A keeps the mail and tries again later.

B is off the air and C cannot hear it either.

  1. Transfer, silence, probe, REQUEST happen as in Scenario 2. Nobody offers.
  2. One more attempt. A station can hold a copy only if it caught the opening frames, so no offers may mean the opening was lost. A sends the whole transmission once more, then asks again (Section 16.6.3).
  3. Deferred. Still nothing. A stops transmitting for this mail and marks the row deferred: no relay has volunteered yet; it will ask again after a growing wait.
  4. Try again later. When A next hears any station, and at least one minute has passed since the last try (doubling after each failed try, up to 32 minutes), it tries again: directly if the station it hears is B, otherwise by asking for a relay. Waiting mail goes oldest first and is never discarded for waiting (Chapter 20).

If a gateway is on the frequency there is one more path. A gateway that overhears the mail puts a copy in B's mailbox on the mailserver and answers A's REQUEST by saying so; A's row becomes deposited. Any gateway that later hears B offers B the waiting mail (Chapter 24).

2.5 What to remember

Chapter 3

The Radio You Need to Know

3.1 Your transceiver is an audio pipe

An SSB (single sideband) transceiver is usually thought of as a voice radio. For data work, think of it as a pipe for audio. Whatever audio you feed into its data input comes out of the far station's data output, much the same as it went in. To your radio, every mLink signal is just sound.

3.1.1 Upper sideband: audio pitch becomes radio frequency

In upper sideband (USB) mode, the radio takes each audio tone and moves it up so that it sits that many hertz above the dial frequency. A 1,000 Hz tone fed into a radio set to a dial frequency f goes out on the air at f + 1,000 Hz. At the receiving end the process runs backwards, and a receiver set to f turns that signal back into a 1,000 Hz tone. Tones stay tones, their spacing stays the same and their timing is preserved. mLink runs on upper sideband, in the radio's data mode where it has one (often labelled DATA-U, PKT-U or DIG-U).

That is why this book describes mLink's signals in audio terms. When a later chapter says a signal is centred on 2,250 Hz, it means the audio fed to the radio, and therefore 2,250 Hz above the dial on the air.

Audio into the radio E announce bulk 0 1,000 Hz 2,000 Hz 3,000 Hz upper sideband: add the dial frequency On the air dial f f + 1 kHz f + 2 kHz f + 3 kHz
Figure 3.1. On upper sideband, audio pitch maps straight onto radio frequency above the dial. The blocks are mLink's three regions: the small black one (E) is for emergencies, then announce, then bulk. Chapter 8 gives the layout.

3.1.2 The pipe is about 3 kHz wide

The passband is the range of audio frequencies the radio lets through. SSB radios are built around voice, and a typical one passes something like 3 kHz of audio. mLink is designed to fit inside that, and it uses nearly all of it, from very low audio right up to the top. Both ends matter. Many radios narrow their filter for data modes, or roll off the low audio to keep voice crisp, and a radio that does either cuts off part of mLink.

3.2 Sound cards and samples

Between the radio and the computer sits a sound card, often built into a small interface box. On receive it measures the audio voltage many thousands of times a second and hands the computer a stream of numbers. Each number is a sample, and how many are taken each second is the sample rate. On transmit it does the reverse.

A sampled signal can only represent frequencies up to half the sample rate. mLink does all of its signal processing at 12,000 samples per second, so it can represent audio up to 6,000 Hz, twice what the passband needs. Many sound cards prefer to run at 48,000 samples per second; the station then converts between the card's rate and its own.

Because the rate is fixed, time and samples are interchangeable throughout mLink. One second is 12,000 samples. A bulk frame is 65,280 samples, which is exactly 5.44 seconds. Timing that matters is counted in samples, and that is how a receiving station can predict, to the sample, where the next frame of a transfer will begin.

3.3 Tones, phase and the I/Q picture

Every mLink signal is built from tones. A pure tone has three properties: its frequency (how many cycles per second), its amplitude (how loud) and its phase (where in its cycle it is at a given instant). A modem carries data by changing one or more of these from one short stretch of time to the next. Each stretch is a symbol, and the number of symbols per second is the baud rate.

mLink changes tones in three ways. Its emergency modem changes the frequency, picking one of eight tones for each symbol (Chapter 10). Its announce modem changes the phase of a single tone (Chapter 11). Its bulk modem changes the phase of many tones at once, side by side (Chapter 12).

3.3.1 Phase as an arrow

Picture phase as an arrow spinning around a circle. The arrow's length is the tone's amplitude; its angle at any instant is the phase. Now watch it from a viewpoint that spins at exactly the tone's own frequency: the arrow stands still. If the transmitter jumps the phase by a quarter turn, the arrow jumps by a quarter turn and stays there.

Describe the arrow's tip by two coordinates, how far across and how far up, and you have what radio engineers call I and Q: the in-phase and quadrature parts of the signal. The receiver works with both numbers for every sample. The pair records not just how strong the signal is but where it is in its cycle, which is exactly what a modem that shifts phase needs to read. Plot where the arrow lands for each received symbol and you get the constellation display that digital-mode software shows: tight clusters for a clean signal, fuzzy clouds for a noisy one.

I Q I: across Q: up length = amplitude angle = phase one arrow, two coordinates I Q many received symbols, with noise
Figure 3.2. The I/Q picture. Left: a tone seen as an arrow, described by how far across (I) and how far up (Q) its tip is. Right: where the arrow landed for a run of received symbols when the transmitter used four phases a quarter turn apart. Noise scatters the points into clouds; as long as the clouds do not overlap, each symbol can still be read.

3.4 Noise, decibels and SNR

Every receiver hears noise: the hiss of the atmosphere, distant lightning, the power line next door and the receiver's own electronics. The most important number about any received signal is how strong it is compared with that noise, the signal-to-noise ratio, or SNR.

3.4.1 Decibels without tears

Radio people write ratios like this in decibels (dB), because the ratios involved span a huge range. A decibel figure is shorthand for a multiplication. The few values worth memorising:

Table 3.1. Decibels as power ratios.
dBPower ratioIn words
+3×2twice the power
+10×10ten times
+20×100a hundred times
0×1equal
−3×½half the power
−10×1/10a tenth
−20×1/100a hundredth

Decibels add where ratios multiply: +13 dB is +10 dB and +3 dB, so twenty times. An SNR of 0 dB means the signal and the noise have equal power. A negative SNR means the signal is weaker than the noise: at −10 dB the noise has ten times the signal's power. For voice that is hopeless, but data modes copy signals like that every day.

3.4.2 Why an SNR needs a bandwidth

Noise is spread across all frequencies more or less evenly. A receiver listening through a wide filter lets in more of it; a narrow filter lets in less. Halve the bandwidth and you halve the noise power, which is −3 dB. So an SNR figure means nothing until you say what bandwidth the noise was measured in. The same signal can honestly be described as −15 dB in a 3 kHz bandwidth and about +3 dB in a 50 Hz one, because the 50 Hz slice holds sixty times less noise (about 17.8 dB less).

This is also half of the answer to "how can anything copy a signal below the noise?" A narrow signal only has to beat the noise inside its own narrow slice. The other half is time and coding: long symbols let the receiver average the noise down, and error-correcting codes repair the symbols that still come out wrong (Chapter 9).

3.4.3 The SNR@3k yardstick

mLink quotes every SNR against one fixed reference: the noise that a 3,000 Hz-wide SSB receiver lets through. We write this SNR@3k. It is the natural yardstick for an SSB station, because 3 kHz is roughly what the radio passes anyway. It means the same thing whether the signal being measured is mLink's narrowest or its widest, so any two figures can be compared directly. And it is one number everywhere: the strength your station reports for each station it hears, every figure in this book, and the thresholds the station uses to make its decisions are all SNR@3k.

If you use FT8 or JS8, you already know this kind of number. Those programs report against a 2.5 kHz reference instead of 3 kHz, so the same signal reads about 0.8 dB lower on mLink's scale. That is close enough to compare directly: a station that gives you −12 on FT8 is very close to −12 dB SNR@3k.

How far down each of mLink's three signals can be copied is listed in Section A.8. The short version: the slow ones work well below 0 dB, and the fast one needs to be a few decibels above it. mLink chooses between them from the measured path (Chapter 15).

3.5 Half duplex: you are deaf while you transmit

An amateur transceiver cannot transmit and receive at the same time on the same frequency. Its own signal is millions of times stronger at its antenna than anything it could hope to hear. This is half duplex, and it shapes a great deal of mLink's behaviour.

A station switches between receive and transmit with the PTT (push-to-talk) line, the same thing your microphone button does. mLink can key the radio by a CAT (computer aided transceiver) command, by a control line on a serial port, or by VOX (voice operated switch), where the radio keys itself when audio arrives. VOX needs no cable but is slow to react, so a station keyed that way sends a short tone ahead of every transmission to give the radio time (Chapter 8).

Half duplex has three consequences you will meet again and again:

3.6 The HF channel

A VHF path is usually line of sight and stays much the same from minute to minute. HF (high frequency, 3 to 30 MHz) is different, and the difference is why mLink's signals look the way they do.

3.6.1 The ionosphere and skip

Above about 60 km, sunlight ionises the thin upper atmosphere into layers, together called the ionosphere. An HF signal heading upward is bent back toward the ground and can come down hundreds or thousands of kilometres away: skip. It may bounce off the ground and go up again for a second hop. Which frequencies are bent back, and where they land, depends on the time of day, the season and the sunspot cycle. A path that works on 40 m in the evening may not work at noon.

Signals sent nearly straight up on the lower HF bands come back down all around the transmitter. This near-vertical incidence skywave (NVIS) is the workhorse of regional emergency communications, and it has the same character as any other skywave path: echoes, fading and drift.

3.6.2 Echoes: multipath

A signal rarely arrives by one path alone. One copy may come by a single hop and another by two; the ionosphere may split the signal into two copies travelling slightly different routes. Each copy covers a different distance, so they arrive at slightly different times. The receiver hears the sum: the signal plus delayed echoes of itself. This is multipath. On skywave paths the echoes typically trail the first arrival by half a millisecond to a few milliseconds, and in bad conditions by as much as 10 milliseconds.

3.6.3 Fading

The ionosphere is never still, so the lengths of the paths change all the time. When two copies of a tone arrive in step they add up; when they arrive half a cycle apart they cancel. As the paths shift, a signal fades in and out, sometimes over a fraction of a second, sometimes over minutes. Because the adding and cancelling depends on frequency, a fade can take out one part of the passband while leaving another untouched: on a waterfall display you can see dark notches wander slowly across a signal. A long transmission on HF should expect some part of it to meet a fade.

3.6.4 Drift and Doppler

The moving ionosphere also shifts each signal's frequency slightly, by a fraction of a hertz to a few hertz, and smears it: a pure tone arrives a little blurred. This is the Doppler effect, the same thing that changes the pitch of a passing siren. Separately, no two radios agree perfectly on what frequency their dials are set to. A few hertz or tens of hertz of difference is normal, and on upper sideband that error shifts every received tone by the same amount. Chapter 13 explains how mLink copes; an accurately calibrated radio still helps.

The standard channel models engineers use to test HF modems describe "good" through "poor" conditions as echoes of 0.5 to 2 milliseconds with Doppler smearing of 0.1 to 1 Hz. mLink's own tests run its stations through simulated fading, echoes and noise of this kind (Chapter 33).

ionosphere TX RX one hop two hops (arrives later) fast symbols: each echo lands on top of the next symbol slow symbols: guard the echo's spill-over falls inside the guard
Figure 3.3. Multipath. Above: the same signal reaches the receiver by two routes of different length. Below: when symbols are short, each delayed echo overlaps the following symbols; when symbols are long and start with a guard interval, the echo's overlap is absorbed by the guard.

3.7 Why slow symbols

Put all of that together and the trouble with sending data quickly over HF becomes clear. The obvious way to go fast is to send short symbols very quickly on a single carrier. At 2,400 symbols per second, a symbol lasts about 0.4 milliseconds. A 2-millisecond echo then overlaps the next five symbols, and the receiver hears each symbol mixed with the ghosts of the ones before it. A filter that learns the echo pattern can subtract it, but the pattern keeps changing as the path fades and drifts, so the filter is always chasing it, and a deep fade can leave it lost.

The other way is to make every symbol long compared with the echoes, so that an echo smears only the edge of a symbol and not the whole of the next one. All three of mLink's signals do this. The emergency modem's symbols last 160 milliseconds, which an echo of a few milliseconds barely touches. The announce modem's last 5 milliseconds, still longer than a typical echo. The bulk modem gets its speed back without shortening anything: it sends many slow tones side by side, each symbol about 27 milliseconds long, and starts each symbol with a guard interval that soaks up the echoes (Chapter 12).

Why three different signals and not one clever one is a question about jobs, not about echoes: one must be heard by everybody, one must move a lot of data, and one must get a distress call through almost anything. Chapter 8 takes it up.

3.8 What to remember

Part II: Operating a Station

Chapter 4

Installing and First Run

4.1 What you need

4.1.1 At the radio

Transceiver SSB, data input Sound interface or built into radio Linux computer station daemon database file RX audio TX audio PTT (optional) USB serial / CAT desktop client web browser same computer or anywhere on the LAN
Figure 4.1. A complete station. Solid lines carry audio; dashed lines are the keying and control paths, which a VOX-keyed station does without.

4.1.2 The computer

The station daemon, the program wired to the radio, is built for Linux today; Windows and macOS are future build targets for it. The ready-made package is for 64-bit PCs (x86-64); on other processors, such as 64-bit ARM, you build it from source. The client you operate with comes as a Linux desktop program, a Windows desktop program and a web page for any browser. All three reach the daemon over the network, so a Windows or browser operator works a station that runs on a Linux computer. The mailserver is a separate program that somebody runs for a whole group (Chapter 25); your station needs only its address.

The computer should keep accurate UTC time, because every time the station records is UTC.

4.2 Getting mLink

4.2.1 The AppImage

The simplest route is a single file, mLink-x86_64.AppImage. An AppImage is a whole program in one file that runs without installing anything. This one holds the desktop client, the station daemon, the small web bridge that lets browsers connect, and the web client. It runs on Linux distributions from about 2020 onward, on any 64-bit x86 processor from about 2009 onward.

chmod +x mLink-x86_64.AppImage
./mLink-x86_64.AppImage

That opens the client. To run only the daemon, for example on a computer with no screen, put --daemon-only first; everything after it goes to the daemon:

./mLink-x86_64.AppImage --daemon-only --callsign W1AW --grid FN31pr --audio auto

4.2.2 Building from source

On a Debian or Ubuntu system the ready-made package is built with these packages: gcc g++ make cmake python3 autoconf automake libtool pkg-config patch bzip2 xz-utils zlib1g-dev libasound2-dev libx11-dev libxrandr-dev libxinerama-dev libxcursor-dev libxi-dev libgl-dev, plus libpipewire-0.3-dev for the PipeWire sound backend. The heavier libraries mLink depends on ship inside the source tree and are built along with it.

Use these three targets; a plain make builds a much slower debugging daemon.

make release                    # the daemon:  build/release/mlinkd
make mlinkd-ws-bridge-release   # the web bridge, next to it
make client-release             # the client:  client/bin/Release/mlink-client

Add USE_PIPEWIRE=1 to the first line to include PipeWire; without it the daemon uses ALSA, which every Linux system has. On a 64-bit PC the build assumes a processor from about 2013 onward (one with AVX2); for an older machine add MARCH=x86-64-v2. The web client needs the Emscripten compiler: make -C client web builds it into client/bin/web.

4.3 First run

4.3.1 Starting the station

From the client. Start the client. With nothing running yet, the "Connect to Daemon" window opens (Section 5.2). Leave the host at 127.0.0.1, the port at 8488 and the password at its default, mLink; type a name and press "Start local daemon". The client starts the daemon and signs you in.

By hand. Run the daemon in a terminal, then point any client at it:

mlinkd --callsign W1AW --grid FN31pr --audio auto

It runs until you press Ctrl+C. What you give on the command line is saved, so later runs need no options. mlinkd --help lists them all, and Chapter 29 explains them.

Both ways start the same station: the daemon keeps one database in one per-user data folder, however it was started, and a second daemon on the same database refuses to run. Where that file is, and why to back it up, is in Chapter 29.

4.3.2 Callsign and grid

Until the station has a real callsign it will not transmit, and the client shows a red "STATION BLOCKED" banner with the code callsign_missing (Section 14.2.2 has the rule and its one exception). Open Settings, then "Identity":

4.3.3 Sound device

Open Settings, "Audio", "Backend". First choose the sound system, the audio backend: pipewire if the daemon offers it and PipeWire runs on the computer, otherwise alsa. (null means no sound hardware, for testing.) Then pick the devices: "Capture (RX)" carries the radio's receive audio, "Playback (TX)" feeds the radio. "(System default)" uses the system's choice. Press "Apply".

The switch happens live and is saved. The daemon will not change devices in the middle of a transmission, and if the new device will not open it goes back to the one it had. "Refresh" shows an interface plugged in after the daemon started.

4.3.4 Audio levels

mLink has no level controls of its own. Set receive and transmit levels with the radio and the computer's sound mixer, as for any sound-card data mode. On receive, the "Waterfall" should show band noise as a steady speckle: black means too little audio, bright all over means too much. On transmit, raise the level until the radio gives the power you want, and stay below the point where the radio's ALC (automatic level control) acts. ALC squeezes the peaks, and a squeezed mLink signal spills outside its own strip of the passband (Section 8.8).

4.3.5 Keying the transmitter

Open Settings, "Radio", "Rig control". Its first line shows the current state, for example Rig: ptt-serial (key tier line). Under it is a form:

"Apply" takes effect at once and is saved. The daemon then keys by a control line if one is set, otherwise by a CAT command if the radio's description has one, otherwise by VOX, and the first line names the result as the "key tier": line, cat-writeonly, cat-validated or vox. The same line warns in capitals of "CAT SILENT" (the radio stopped answering), "DEVICE LOST" (the serial port vanished) or "PTT STUCK" (the radio reports it is still transmitting when it should not be).

The description files are the ones written for OmniRig, the rig-control library by VE3NEA, so mLink needs no code of its own for each radio. The source tree carries nineteen, for popular Elecraft, Icom, Kenwood and Yaesu radios, in its rigs folder. The AppImage does not contain them: copy your radio's file from the source tree or from the OmniRig library to the station computer and give its path in the form.

Table 4.1. Typical rig-control settings for common interfaces.
InterfaceBackendPTT line"VOX keying"
SignaLink type (VOX only)noneNoneticked
Digirig type (serial PTT)ptt-serial, or omnirig for frequency control tooRTSnot ticked
Radio with built-in USB audio and CATomnirig with the radio's fileNone (keys by CAT), or the line the radio documentsnot ticked

The last setting is Settings, "Radio", "Keying (VOX)". A new station assumes the radio is not keyed by VOX. If yours is, tick "VOX keying"; the "VOX leader (ms):" box then takes any length from 0 to 2000. Or tick "Auto from rig control", and the station treats a key tier of vox, or no rig control at all, as VOX.

4.3.6 Why the VOX leader is 800 ms, and what it costs

A VOX-keyed radio starts transmitting only after it has heard audio, so the start of every transmission never reaches the air. A station set to VOX therefore sends a plain tone, the VOX leader, in front of every transmission, distress calls included, and lets the radio swallow that instead of the first frame (Section 8.9.1 says where the tone sits). A station keyed by a line or by CAT sends none.

The default, 800 ms, comes from a measurement. On an inexpensive VOX-keyed handheld with a Digirig, the transmitter's VOX and the far radio's squelch together swallowed 550 to 750 ms of each transmission. A 250 ms leader lost every one; 800 ms decoded reliably. If your radio's VOX is quicker you can shorten the leader, but test with another station first: a leader that is too short loses whole transmissions, while one that is too long only wastes time.

The cost is the leader itself: every transmission a VOX station makes is 0.8 seconds longer. A one-frame message that takes just under two seconds from a line-keyed radio takes almost three, and that time comes out of a channel everybody shares. A VOX station is also placed behind the others when stations take turns after activity (Section 17.7.1). The client says so in red when you tick the box. VOX works, but a radio keyed by a line or by CAT serves the whole frequency better.

4.3.7 Connecting to a mailserver

Mail for stations that are not on the air right now passes through a mailserver. In "Messages", select the "Mailbox (net)" folder (Section 5.5.3), type the server's address next to "Server URL:" and press "Apply". Then register, once: press "Register (internet)", or, with no internet here, type the callsign of a gateway you can hear next to "Gateway:" and press "Register over the air". What registering does is in Chapter 25; how mail then travels is in Chapter 24.

4.3.8 Operating from a browser

The daemon starts the web bridge by itself, and the bridge serves the web client on port 8489. The AppImage needs nothing more; a source build must be told where the web client's files are, with --web-root client/bin/web. Open http://127.0.0.1:8489 in a browser on the station computer. To let other computers on your network in, start the daemon with --web-lan; it prints the address to use. Chapter 30 explains the connection.

4.4 A first test

Before you depend on a station, prove each link of the chain in turn.

  1. Is audio arriving? Open "Waterfall". Band noise should scroll. "Waiting for spectrum frames..." means the daemon has no audio.
  2. Is the station happy? The tray should show a green dot and no red banner. If there is a banner, click it.
  3. Is anyone heard? Tune to your group's frequency and wait. Stations appear in "Stations", "Heard" as they are decoded, each with an SNR on the SNR@3k scale. A newly started station listens for a while before it announces itself (Section 18.2).
  4. Does the transmitter key? Send a short line in "Chat" to 0CQCQCQ. Watch the radio key, send, and unkey.
  5. Does a message arrive? Select a heard station, press "Message", write a line and send. In "Messages", "Sent", its state goes from pending to airing to sent, and "Message acknowledged" appears in "Notifications". If the row shows anything else, Chapter 6 says what it means.

4.5 What to remember

Chapter 5

The Operator's Guide to the Client

5.1 Before you start

The client does not run the radio. The station daemon does, and the client is a view onto it and a set of buttons that send it commands (Section 1.3). Close the client and the station keeps working. Open it again, on the same computer or another one, and everything is where you left it, because your QSO log, friends, canned messages, map objects and window arrangement are all kept by the station.

On-screen labels are quoted here exactly as the client shows them. Every time and date in the client is UTC; the clock in the bottom right corner reads, for example, 04:04:12 Z.

5.2 Connecting and signing in

When the client is not connected to a daemon, a window titled "Connect to Daemon" opens by itself in the middle of the screen. It closes by itself the moment you are signed in. It has five fields:

The sign-in rule is printed under the Name field: "If your name has an account on the station, the password is your account password; otherwise the station password signs you in." Chapter 7 explains accounts, roles and walk-up guests.

Two tick boxes let the client remember what you typed: "Remember host/port" and "Save password (plaintext)", which writes the password to a file on this computer unscrambled.

Two buttons sit at the bottom. "Connect" attaches to a daemon that is already running. "Start local daemon" appears only when the host is this computer: it starts a daemon if none is answering on that port and signs you in as soon as it is ready (Chapter 4). Once you are connected, the same window, reopened from the Start menu, offers "Disconnect" instead.

The status line under the tick boxes says what happened. "Status: timed-out (no daemon answering at ...)" means nothing answered. "Status: sign-in refused" is followed by a short code in brackets and the station's own sentence of explanation:

If the station ends a session you already had, the window comes back with "Status: signed out by the station" and the code, and a red message pops up telling you to sign in again.

5.3 The desktop

The screen is a desktop with a taskbar along the bottom. Each tool opens in its own window, and the client calls these tools applets. Drag a title bar to move a window; drag an edge or corner to resize it. Each title bar carries four small buttons. From left to right they are "?", which opens the Help window at the page for this applet, then minimise, maximise and close.

Dragging a window against an edge of the screen snaps it: to the top edge to fill the screen, to the left or right edge to take that half. If you shrink the client's own window until some windows fall off the edge, the client stacks them back into view.

The first time you connect to a new station, the client opens a starter set: "Status & Diagnostics", "Messages", "Stations" and "Waterfall". After that it restores the arrangement you left, which the station keeps, so it follows the station and not the computer you happen to sit at.

5.3.1 The Start menu

Click "mLink" at the bottom left to open the Start menu. The applets are grouped under six headings, in this order: Communicate, Stations & Map, Radio, Station, Data and System. Clicking an item opens the applet, or brings it to the front if it is already open; there is only ever one window of each.

Below the separator are three more items. "Connect..." reopens the "Connect to Daemon" window. "Stop daemon" stops a daemon that this client started; it is greyed out otherwise. "Quit client" leaves, after up to two questions. If your station is net control, a "Net control" box offers "Sign off & quit", "Leave silently" or "Cancel" (Section 22.9.9). If this client started the daemon, a "Quit mLink" box offers "Stop & quit", "Leave running" (the station stays on the air) or "Cancel".

Three applets, "Messages", "Stations" and "Status & Diagnostics", are each a hub: several related views under tabs in one window. When some other window has a "Message" or "Go to" button, it takes you to the right tab of the right hub.

Table 5.1. Where each job lives. Tabs are shown after the applet name.
You want to...Open
Read, write or file mailMessages
See what you sent and whether it wentMessages, "Sent"; Status & Diagnostics, "TX Queue"
Type a quick line to someoneChat
Run or join a virtual net, call a roll callNets
Fill in an ICS-213 or other standard formStandard Forms
Send a distress call, or answer one heardDeclare Emergency
See who is on the airStations, "Heard"; World Map
Log a contactStations, "QSO Log"
Keep a list of regularsStations, "Friends"
Mark places and lay out a search planWorld Map; POIs
Watch the bandWaterfall; Spectrum
Send a prepared message with one clickBeacons
Set callsign, grid, audio, rig, keyingSettings
Manage accounts or a station clusterOrganization
See every event the station flaggedNotifications
Follow weather or other internet dataTracked Data
Check the connection, role and station stateStatus & Diagnostics, "Status"
Read the station's log linesDaemon Log

5.3.2 The taskbar and the tray

Every open window has a slot on the taskbar. Click a slot to bring its window to the front; click the slot of the window already in front to minimise it.

The right end of the taskbar is the tray. It tells you, without opening anything, whether the station is connected, what it is doing, and whether anyone is in trouble.

Abort I KD7XYZ ยท alice ยท operator 04:04:12 Z only while sending link state messages emergency callsign on the air ยท who is signed in ยท role UTC clock
Figure 5.1. The tray, left to right: the Abort button (present only while something is queued or on the air), the four status icons, the identity cell and the UTC clock.

The four small icons, left to right:

The identity cell next to the clock says which callsign this station transmits as and who is signed in with what authority, as in KD7XYZ ยท alice ยท operator. A walk-up guest shows as guest: and the name typed at sign-in; a one-operator station shows only the callsign and the role. The role is shortened to admin, tech or operator. Hover over the cell for the long version.

While a transmission is queued or on the air, an "Abort" button appears just left of the icons. It calls off the current transmission and puts the message back in your Drafts (Section 16.9).

5.3.3 The red banner

Some problems stop a station from working at all: no callsign set, the sound device vanished, the radio would not key. When the daemon reports one of these, a red strip appears across the very top of the screen, above every window, reading "STATION BLOCKED --" followed by a short code and the reason, with "(+N more)" when there are several. It cannot be hidden behind a window, and it stays until the problem is fixed. Click it and the client takes you to the place to fix it: the matching Settings entry for a keying or FM-mode mismatch, "Status & Diagnostics" for anything else.

5.3.4 Pop-up messages

Short messages pop up at the bottom right, just above the taskbar, and fade after a few seconds: a green edge for success, amber for a warning, red for an error, blue for plain information. These are called toasts. A short one stays about three seconds; a long one stays up to eight, so you have time to read it. Click any toast to dismiss it. A toast that ends in a small ยป is also a link: clicking it opens the applet it is about.

Every warning and critical event the station reports gets a toast as well as a row in "Notifications", except the blocking problems that already own the red banner.

5.3.5 The keyboard and the lists

The Escape key peels away one layer per press, the most transient first. It cancels a quit box if one is showing; otherwise it closes the Start menu; otherwise it takes the text cursor out of the field you were typing in. While a dropdown list or a dialog box is open, Escape leaves the window behind it alone; close a dialog with its own "Cancel". Only when nothing else is in the way does Escape close the window in front.

Table 5.2. Keys that work across the client.
KeyEffect
EscDismiss one layer, as described above
Tab, Shift+TabMove between text fields in the window
Ctrl+A, Ctrl+C, Ctrl+X, Ctrl+VSelect all, copy, cut and paste in a text field. Password fields refuse copy and cut.
EnterSend the line in "Chat"; finish a line or area on the map
Backspace (map)Remove the last point of a shape in progress
Mouse wheelZoom the map around the pointer; scroll a list
Shift+click (map)Measure: first click sets A, second sets B

Most lists in the client share one design. Click a column heading to sort by it, click again to reverse. A row of small filter boxes above the headings narrows the list to rows containing what you type.

5.4 On a phone-sized screen

The client has a second layout for a hand-held screen: the same applets and controls, arranged for a finger. It picks a layout when it starts, before it signs in, from the choice saved on this device or from what the device reports about itself. When neither settles it, it asks, full screen: "Are you on a phone or a desktop?", with two large buttons, "Phone" and "Desktop". The answer is saved. To change it later, open Settings, "Display", "UI scale" and press "Use phone layout" or "Use desktop layout"; the change takes effect the next time the client starts.

What differs in the phone layout:

A finger works like this. Touch and lift to press something. Slide to scroll a list. Hold still on a spot for the menu a right-click would open. On the map, slide to move it and use two fingers to zoom.

5.5 Communicate

5.5.1 Messages

"Messages" is your mail program, laid out like a desktop email client. Folders are on the left, the selected folder's contents on the right, and a toolbar with "Compose" and "Get Mail" across the top. The folder tree is headed by your callsign and holds:

Reading a mail shows "From:", an "Operator:" line with the sender's name and position if they gave one, "To:" and "Cc:", "Subject:", and a "Via:" line naming the mode the mail arrived in, with the dial frequency when your rig reports one. The buttons under the header are "Reply", "Reply All", "Forward", "Archive" and "Delete". Attachments are listed with a "Save" button each, which writes the file to your home directory. Small text files show their first lines, and pictures show as a thumbnail. A map attachment shows a one-line summary of its objects and an "Import to map" button that adds them to your World Map under the sender's callsign (Section 28.3.4).

If another operator at the same station is already replying to a mail, pressing "Reply" opens a box titled "Already being answered" that names them and asks "Reply as well?", with "Reply anyway" and "Cancel" (Chapter 7).

In Sent, select a row to "Edit" it (it reopens in the composer and replaces the original when you send), "Delete" it, or "Abort" it while it is still queued or on the air. In Drafts, "Send" transmits the draft exactly as saved, attachments included, "Edit" reopens it and "Delete" removes it.

At a station that is part of a cluster (Chapter 31), a "Mailbox:" choice at the right of the toolbar lets you look at another member's mailbox, read-only; "Local" brings your own back.

5.5.2 Writing mail

"Compose" in the toolbar, or any "Message" button anywhere in the client, opens the composer inside the Messages window. Its heading says what you are doing: "New message", "Reply", "Reply all", "Forward" or "Editing draft". A "New" button at the top right clears it. The fields are:

The figures at the right of the attachment row are worth learning to read. They show two sizes in kilobytes: the message after compression, and the most one transfer can carry. When the station has measured the link to the recipient, the second figure becomes what that link can carry, and the line adds the rate it expects to use, the link's signal-to-noise ratio (on the SNR@3k yardstick) and an estimate of the time on the air. Green fits this link now, amber would fit a better link or a relay, red never fits in one message and must be trimmed. Hover over the line for the reason in words (Section 15.5).

"Save Draft" keeps the message without sending. "Send" hands it to the station, and a small line at the bottom then shows the state of that send as it changes. A message that is too large is refused on the spot with a red toast.

If this station is not registered with a mailserver, the composer says so next to "Via:" in red: "not registered - relays won't carry this" on "Radio", or "needs Mailbox registration" on "Internet (CMS)". Registration is one button in the "Mailbox (net)" folder.

When the station holds an encryption key, an "Encrypt:" choice appears too, with "Clear", "To recipient" and "Group key". "To recipient" says beside it whether the station holds that callsign's certificate ("cert on file (encryptable)" or "no cert for this callsign"); "Group key" adds a second list to pick the key. Under the choice the composer says where encrypted mail can and cannot go, in red if "Via:" is set to "Internet (CMS)". The rules are in Chapter 26.

5.5.3 Mailbox (net) and Get Mail

The "Mailbox (net)" folder is where you connect this station to a mailserver (Chapter 25). A line at the top says which server is set and whether the station is registered. Below it:

The "Get Mail" button on the toolbar does the same check by the best route available: over the internet when the station is registered, otherwise over the air.

5.5.4 Chat

"Chat" is a scrolling conversation, one line at a time, in the style of IRC or a keyboard net. A choice at the bottom left picks where the line goes:

Enter sends, and so does the "Send" button. A counter shows how much room is left: a chat line is capped at 156 bytes, the most one short message carries (Section 15.2). Anything longer is mail, and in "On air" the "Mail" button opens the composer already addressed to the same callsign. Your own lines are shown in dark red. Click an on-air line to see, at the bottom of the scrollback, how many times the station heard that message and when it first did. The view follows new lines only while you are at the bottom.

5.5.5 Nets

"Nets" runs or joins a virtual net: an optional net with a name, a net control, numbered members and roll calls (Chapter 22). The window has three parts: status lines at the top, a row of buttons that depends on what you are in the net, and the roster.

The status lines. With no net heard the window says "No virtual net on frequency." Otherwise the first line names the net, its type ("Casual" or "Safety Critical"), its net control, and two counters, the term and the roster's edition. The second line says what you are:

More lines appear when they apply: that you follow net control through another member; who owns the net when the station running it is a stand-in or was handed the job; whether the net's standing orders are in your mail; "Asking to join ..."; "Roll call in progress", with a note when routine traffic is held, and afterwards "Last roll call:" with how many did not answer. After each roll call net control also reads how many members it heard directly, and, when another member reports hearing more of the net, a suggestion to let that member run it (Section 22.9.6).

The buttons follow from what you are.

Two more lines sit under the buttons. "Bulletin:", for members and net control, takes a text every member must have and sends it with "Send bulletin"; net control's window then shows whether every member confirmed it or how many still lack it (Section 22.7.2). "Standing orders:", for the owner and the station running the net, takes a subject and a text; the button reads "Post standing orders", or "Replace standing orders" when the net already has some (Section 22.7.3).

The roster has three columns: the member's number, CALLSIGN and NOTE. The note says what the station knows about that member: "net control", "owner", "this station", "left the net", "did not answer the roll", "not heard lately", "listed on another member's word", and "alternate n". Net control's own line carries no number when your copy of the roster has no entry for it.

Things the net tells you arrive as toasts and as rows in "Notifications": a message or bulletin to the net ("Net name: message from callsign", or "(not a member) writes to the net" at net control), a roster copy that arrived, standing orders that reached your mail, that net control has taken you off the roster, and that another net with the same name is on the frequency.

5.5.6 Standard Forms

"Standard Forms" fills in the message forms that emergency communicators already use: ICS-213, Radiogram and about 150 others, grouped by organisation and region in a tree, with the forms you used recently at the top under "Recent" and a "Search:" box above. Choose one and it appears as ordinary fields. Required fields that are still empty are outlined in red when you press the form's submit button, and the form will not submit until they are filled. A successful submit places the finished text in the composer with the subject filled in; you choose the recipients and press "Send". Four buttons above the form do the rest: "Save draft" and "Load draft" keep a half-finished form, "Attachโ€ฆ" adds a file, and "Save PDF" makes a copy for a paper file.

5.5.7 Declare Emergency

"Declare Emergency" has two tabs: "Declare", to send a distress call, and "Heard", for distress calls the station has received. The service behind them is described in Chapter 23.

The "Declare" tab is built so that nothing on it can stop you sending. The red button at the bottom is always live. It reads "SEND DISTRESS" when a position will be included and "SEND DISTRESS (no location)" when not. Every field above it is optional, and a line of advice at the top changes as you fill them in, for example "No position - rescuers cannot locate you directly", in red when the news is bad. It warns; it never refuses.

Most fields are short menus, so they are quick under stress:

If the station is transmitting something else at that moment, a line above SEND says "The station is transmitting now. Sending will interrupt it." SEND is still one press. Afterwards a box names what was stopped, "Message 12 aborted to transmit emergency broadcast.", and that message is in "Drafts" (Section 23.2).

After you send, the tab changes. It shows "BEACONING - repeating until canceled or acknowledged", the severity and whether a position went out, and two buttons: "CANCEL / SAFE" to stand the call down, and "UPDATE (re-send)" to send a corrected version after you change the severity or the detail in the fields below. A critical notification at the same moment gives the expected time between repeats (Section 23.4.1). Every client connected to the station shows the beacon, so any operator there can cancel it, not only the one who sent it.

The "Heard" tab label carries a count of unacknowledged calls, as in "Heard (1!)". A new call also raises a critical toast and turns the tray triangle red. Each row gives the call's number, who sent it, the severity and the station it came through, with "[ACK]" in front once it is acknowledged. Select one to see "What:" and "Where:", the detail text, and "Position:" with an "On map" button, or a line saying there is no position. After you have passed the call to the authorities, fill in "Contact:" (agency, case number or phone; optional) and press "Acknowledge (I forwarded this)" (Section 23.6). The row then reads "Acknowledged by ..." with the contact.

At the top of this tab, the tick box "Auto-relay heard SOS beacons" lets the station re-send distress calls it hears (Section 23.7). Leave it on unless you must stay silent.

5.6 Stations and the map

5.6.1 Stations: Heard

The "Heard" tab of "Stations" is the station's heard list (Section 18.6). The columns are CALLSIGN, GRID, SNR (Section 18.6.1), KM and BRG (distance and bearing from you), LAST HEARD, MODE (the mode the last frame arrived in, with your dial frequency when your rig reports it), VIA (which member of a cluster heard it) and EM (an exclamation mark for a station declaring an emergency). [NC] after a callsign marks the net control of the net on the frequency. The list is sorted by SNR, strongest first, until you pick another column. Distance and bearing need your own position; with only a grid square set they are worked from the grid.

The list has no age setting of its own. The station forgets a station one hour after it last decoded it (longer on a frequency with more than twenty stations), and LAST HEARD tells you how fresh each row is, so sort on that column to see who is on the air now. In a cluster, stations heard by other members are listed too.

Select a row and two buttons appear: "Message" opens the composer addressed to that station, and "Show on map", offered when the station's position is known, centres the World Map on it.

5.6.2 Stations: QSO Log

The "QSO Log" tab is an ordinary contact log: WHEN, CALLSIGN, GRID, FREQ, MODE, SENT and RCVD reports, and a COMMENT. "New" starts an entry stamped with the current time; the editor under the list changes the selected entry, with a "Message" button for that callsign and a "Delete" that asks first. "Export ADIF" writes the whole log to an ADIF file in your home directory, ready for LoTW, QRZ or any logging program, and "Import ADIF" reads one in.

5.6.3 Stations: Friends

"Friends" is your list of up to 32 regulars, whether or not they have been heard lately. Type a callsign next to "Add:" and press "Add". Each friend has a "Note:" and an "Alert:" setting of "Mute", "Notify" or "Sound", and "Message" and "Delete" buttons. With anything other than "Mute", a text message from that friend puts a row in "Notifications". "Sound" makes no sound yet, and the window says so. Friends are also the first suggestions when you address mail.

5.6.4 World Map

The World Map showing stations as yellow
squares joined by green and amber link lines, a shaded search sector, the
layer buttons down the left edge, the shape toolbar along the top, a group
selector at top right, a legend at bottom left and a coordinate read-out at
bottom right.
Figure 5.2. The World Map with the legend turned on. Across the top, the shape toolbar; down the left, the layer and action buttons; top right, the group selector. The lines between stations are links, and the read-out at bottom right follows the pointer.

"World Map" shows you, the stations heard, the links between them, your own map objects, objects other stations have shared, and weather observations. The map ships with the client and needs no internet. Drag with the left button to move it; turn the wheel to zoom around the pointer. The night side of the Earth is shaded. The read-out at the bottom right follows the pointer: latitude and longitude, grid square, approximate local solar time there, and the distance and bearing from you. A scale bar in kilometres sits in the corner below it.

Markers. Your own station is green. A heard station is yellow, or a dimmer yellow when only its grid square is known and it is shown at the square's centre. A station not heard for half an hour fades, and fades further after six hours. A station in emergency is red and never fades, and while your own distress call is active your marker is joined by a pulsing red "SOS". A gateway has a ring round it. Click a station that has been sending position reports and its recent track appears.

Layers. The column of buttons down the left edge switches layers on and off: heard stations, your own objects, shared objects from others, link lines, a panel listing links station by station, weather, city names and the legend. A layer that is off shows its button pushed in and greyed, and the client remembers your choices on this computer. Below a divider are four actions: drop a search datum, centre on your position, zoom to fit every object, and "Beacon my position now".

The legend lists only the kinds of marker now on the map, from "You", "SOS (armed)", "Station", "Station (grid only)", "Station in emergency", "CMS gateway (ring)", "POI", "Shared object (heard)", "Weather", "Link (strong)" and "Link (weak / ~seen)". The link lines and the link panel come from the links map (Section 18.8). The panel, headed "Links - who hears whom", lists each station and the stations it hears, with their SNR; a double-click on a line centres the map on that station.

The toolbar along the top holds the tools for the tactical overlay (Section 28.3). While a tool is selected, a line across the top of the map says what the next click will do. "Object" stays selected so you can place several; the shape tools go back to "Select" when the shape is finished, and Escape goes back at any time. Dragging still moves the map in every tool.

Table 5.3. The map toolbar.
ButtonWhat it does
SelectClick a marker or a shape to select it. Dragging an object of your own that is already selected moves it; Escape during the drag puts it back.
ObjectClick to place a named point
LineClick each corner; Enter or a right-click finishes, Backspace removes the last corner, Escape abandons
AreaClick each corner; it closes itself when you finish, and is labelled with its size in square kilometres
CircleClick the centre, click again to set the radius
VectorClick the origin, then a point along the bearing; the map shows the bearing and range
SendSend the selected object to everyone
Share allSend all your objects in one transfer
KillWithdraw the selected object from everyone's map and delete it
BeaconSend one position report

Moving an object you have already sent sends it again, so everyone's copy follows. How objects travel and how a newer copy replaces an older one is in Section 28.3.2.

The right-click menu is in four groups: Place ("Drop POI here", "Drop datum here (SAR)", "Search pattern here..."), Navigate ("Center map here", "Copy coordinates", "Measure from here"), Weather ("Get weather here (one-off)", "Track weather here") and Radio ("Poll this area (who's here?)", "Beacon my position now").

Groups. Objects can carry a group label, such as a mission or team name. When any object on the map has one, a choice at the top right shows only one group's picture, yours and everyone else's together; "All groups" brings everything back. While a group is chosen, "Share all" sends only that group and zoom-to-fit fits only what is shown. The choice lasts until you close the client (Section 28.3.3).

5.6.5 POIs

"POIs" (points of interest) is the list view of your own map objects: ID, LABEL, GROUP, OWNER, LAT, LON and EXPIRES. Select one and edit it below: "Label:", "Notes:", "Group:", "Owner:", "Symbol:" and a colour, and fields that depend on the shape, such as "Radius (m):" with optional rings at two and three times the radius, "Brg/Range:" for a vector, a "Filled" box for an area, or a "Moving" box with a course and speed (Section 28.3.1). Tick "Set" next to "Expires:" to give it an expiry time, or leave it clear for an object that never expires. "Refresh" renews an object so it does not expire, "On map" centres the map on it, and "Delete" asks first.

5.7 Radio

5.7.1 Waterfall and Spectrum

"Waterfall" is the familiar scrolling picture of the band: frequency across, 0 to 3 kHz of audio as your receiver passes it, and time downward, newest at the top. Its toolbar has a "dB floor" slider (lower it to bring out weak signals; the colours span 60 dB above it), a colour scheme ("Heatmap", "Viridis", "Grayscale" or "Plasma"), and a "samples/row" slider that averages several measurements into each row, which scrolls slower and shows weak signals more steadily. Make the window taller for more history.

"Spectrum" shows the same measurements as a bar graph of the current moment, scaled to the loudest bar.

5.7.2 Beacons

"Beacons" holds up to sixteen canned text messages you send with one click: a net check-in, a standing CQ, a status line. Each slot has a "Label:", a "To:" and a "Body:". Wherever the body says %CALLSIGN%, your callsign is filled in; the "Preview:" line underneath shows the result. Press "SEND" on a row, or "Send Beacon" in the editor. "New slot" adds one and "Delete" removes the selected one.

These are separate from the beacons the station sends by itself (Section 18.3).

5.8 Station, data and system

5.8.1 Settings

"Settings" is a tree on the left and an editor on the right. Select a top-level group and the editor describes what lives in it. A box above the tree, "Filter settings...", shows only entries whose name, or whose group's name, contains what you type; type vox and you are one click from the keying settings. The groups and their entries are:

The Identity, Audio, "Rig control" and "Keying (VOX)" entries are covered step by step in Chapter 4. Three others need a word here.

"Relay policy" sets how much this station carries for others. The list offers listen_only, relay_off, announce_only and allow_bulk, with "Apply". The page itself says that allow_bulk is right for almost every station; what each level does is in Section 19.9.

"Operator presence" has one tick box, "Operator at the radio". Unticked, the station announces itself as unattended (Section 18.3.1).

"FM mode (FmLink)" belongs to FM operation, which has its own part of this book (Chapter 32).

The "Internet Sources" window that the Advanced page opens is the list of data providers behind "Tracked Data" (Section 27.2): ID, NAME, KIND, ORIGIN, REFRESH, ON and STATUS, with "List Sources", "Refresh Selected" and "Toggle Enabled". It is not on the Start menu.

5.8.2 Organization

"Organization" has two tabs, "Cluster" and "People". Most of what they do needs an administrator, and the window says so where it applies.

"Cluster" is for a station made of several daemons sharing one callsign (Chapter 31). It shows this member's name; a MEMBERS list with STATE, BAND, DIAL and LAST SEEN, and a "Query member" button that fetches a live member's status; PENDING JOIN REQUESTS with "Approve" and "Deny"; and a JOIN A CLUSTER form with "Host:", "Port:" and "Name:" and a "Join cluster" button. A member of a cluster sees "Leave cluster" instead, which asks first.

"People" is for operator accounts (Chapter 7). The first line says how this session signed in. Below it:

5.8.3 Notifications

"Notifications" is the station's event list, newest first, holding the last 64: WHEN, SEVERITY (info, notice, warning or critical), CODE and MESSAGE. It collects acknowledgments for your messages, mail arriving, area broadcasts for your position, relay outcomes, what a virtual net tells you, the state of a distress beacon, distress calls heard, and the blocking problems behind the red banner. Select a row to read the whole message. Where the code has a natural home, a "Go to" button takes you there: mail and message codes to "Messages", emergency codes to "Declare Emergency", relay codes to the "Relay" tab, other transmit codes to "TX Queue", cluster codes to "Organization", rig and PTT codes to Settings.

5.8.4 Tracked Data

"Tracked Data" is where you ask for data from the internet, such as weather observations, and keep it fresh (Section 27.3). Tabs across the top sort the rows by kind, starting with "All". Each row shows LABEL, PARAMS, MODE, VIA, AGE, STATUS and whether it is ON. Four buttons act on the list:

The pane below shows when the selected row was last fetched, where from, and the data itself. The easier route for weather is the map: right-click a spot and choose "Track weather here". Weather with a position also appears on the map's weather layer.

5.8.5 Status & Diagnostics

This hub has four tabs.

"Status" is the at-a-glance panel, in four groups. CONNECTION: the daemon address, the state, the session number. STATION: the callsign and grid the station transmits, who is signed in, and the role, coloured by authority. RADIO: the station's current state and when it last changed, the "Mode" (with "VOX" added for a VOX-keyed radio), the relay policy, the outbox with how many messages are pending and how many are on the air, the net control heard on the frequency, and the virtual net with what you are in it. CLUSTER: this member's name and how many members are reachable, or "Standalone station". The panel is read-only.

"Diagnostics" is the daemon's own counters, with a "Refresh" button and the age of the figures: frames sent and received, acknowledgments, relay requests and offers, emergency frames decoded, the last SNR, the number of stations heard, and under "NAV (busy time remaining)" how long the station believes each announce channel and the bulk region stay occupied, which this book calls a defer (Section 17.2). Received-frame counts that go up show the station is decoding mLink signals, even before any station has shown up in "Heard".

"TX Queue" lists what is waiting for the transmitter. When anything is waiting, "Stop all waiting..." offers to stop them all; the question it asks gives the count and reminds you that the message on the air and emergency traffic are not affected. Select an item to rewrite its destination or text ("Apply edit") or remove it ("Drop") before it goes out.

"Relay" has two lists: RELAY CANDIDATES, the stations heard recently with a usable link, and LEARNED ROUTES, the relay paths that have worked lately. It is where a relay notification's "Go to" takes you (Chapter 19).

5.8.6 Daemon Log

"Daemon Log" shows the daemon's recent log lines: TIME, LVL (the level) and MESSAGE. The client keeps the last two hundred. It follows new lines as they arrive, but only while you are at the bottom, so you can scroll back without it jumping away. The filter boxes above the columns are the quickest way to find something; filter LVL on warn to see only warnings. What the daemon logs is in Chapter 29.

5.8.7 Help

"Help" is a tree of short topics in the same groups as the Start menu, plus an introduction and a "Troubleshooting" page. The "?" button on any window's title bar opens Help at that window's topic.

5.9 Habits worth forming

5.10 What to remember

Chapter 6

The Outbox, and Why Your Station Waits

6.1 Where to look

Everything you ask the station to send is written to its outbox before anything reaches the air. You see the outbox in "Messages" (Section 5.5.1): the "Sent" folder lists every message that has left Drafts, chat lines included, and its STATE and ERROR columns are what this chapter explains. The ERROR column holds the station's note on the row, which is very often not an error at all. "Status & Diagnostics" counts the rows that are pending and on the air, and its "TX Queue" tab lists what is waiting for the transmitter (Section 5.8.5).

6.2 The states

There are nine states. In everyday running you will see pending, airing and sent on almost every row, deferred and deposited now and then, and failed rarely.

Table 6.1. Every outbox state, as the Sent list shows it.
StateWhat it meansWhat you do
draftSaved, not committed to the air. Shown in "Drafts", not in "Sent". An aborted message returns here."Send" it when you want it to go.
pendingAccepted and waiting its turn for the transmitter.Nothing. If it stays for long, see Section 6.5.
airingBeing transmitted, waiting for the other station's answer, or in the middle of a search for a relay. Mail sent by internet is airing while it is handed to the mailserver.Nothing. "Abort" stops it.
sentThe addressee confirmed it holds the complete message, directly or through a relay. For a message to everyone, which nobody acknowledges, it means the transmission went out.Nothing. It is done.
depositedMail only: the mailserver holds it for its recipients. Your own station put it there over the internet, or a gateway that heard it did and said so.Nothing.
deferredThe station could not finish, still holds the message, and will try again by itself. The note says what it is waiting for.Leave it alone.
failedThe station has stopped trying. The note says why.Read the note, fix the cause, then "Edit" and send again.
transferredOnly at a station made of several daemons (Chapter 31): another member has taken over sending this mail. The row follows what that member achieves.Nothing.
expiredDoes not occur in normal running. A lifetime that runs out leaves the row deferred and the station still trying (Section 20.6).Nothing.

6.3 Deferred or failed?

Deferred means the station is still working on it. It keeps the message and tries again without being asked, at growing intervals, once it has heard some station since the last try (Section 20.6.1). A message becomes deferred when:

Failed means the station has stopped, and tells you why. The reasons fall into four groups:

6.4 Reading the note

The notes are in the station's own terse words. "CMS" means the mailserver and "B" means bytes. The ones you are likely to meet:

Table 6.2. Notes in the ERROR column of the Sent list, as written, and what each one tells you.
StateNoteMeaning
deferred"no relay volunteered yet; will retry on next contact"No answer from the destination, and nobody offered to relay (Section 19.7).
deferred"relay handed off; awaiting confirmation on next contact"A relay took the message but has not reported back. It may well have been delivered (Section 19.6.1).
deferred"relay failed; will retry on next contact"The relay reported it could not deliver. The station will look for another way.
deferred"relay hand-off preempted; will re-ask on next contact"A station agreed to relay but did not get the message from yours. It will ask again.
deferred"still seeking a relay; will keep trying" or "delivery still unconfirmed; will keep trying"The message has waited a whole lifetime and the station has started another.
deferred"no pickup: waiting for a gateway", later "still waiting for a gateway; will keep trying"Your mail went out for pickup and no gateway took it. It goes again when a gateway is heard.
deferred"addressee not heard lately - depositing at the CMS", "we have internet - depositing the pickup at the CMS" or "no path to addressee - depositing at the CMS"Your station has internet and is handing the mail to the mailserver instead of transmitting it. The same notes can also begin "cms deposit in flight:".
pending"gateway heard; retrying pickup"A gateway has just been heard, and the waiting mail is queued again.
pending"mailserver deposit failed - sending over the air"The internet deposit did not work, so the mail goes by radio after all.
deposited"cms fallback: deposited for pickup" or "own mail returned by courier: deposited at the CMS"The mail is at the mailserver, by one route or another.
failed"listen_only relay policy in effect" or "no reply; listen_only suppresses relay request"The station is set to listen only.
failed"tx mode UNSUPPORTED (reason) for n B compressed (m B raw)"No way to send this size to this destination. The reason begins "link below announce floor" (the link is too weak for anything), ">1 bulk frame and link too weak for bulk" (too big for so weak a link) or "broadcast > one segment" (too long for a message to everyone).
failed"bulk build failed (...)", "shortburst build failed (...)", "longburst build failed (...)" or "envelope wrap failed"The transmission could not be prepared; with "bulk", usually because the message is too large even after compression.
failed"relay reported delivery failure"The relay could not deliver and the message had no time left.
failed"mailserver unreachable / rejected the mail", "cms fallback deposit failed" or "internet send could not start"The mailserver could not be reached or refused the mail. Check "Mailbox (net)".
failedOn a row whose TYPE begins RELAY_: "relay delivery failed" or "relay transmit failed to start"Traffic your station carried for someone else, and how that went. Nothing for you to do.

A note not listed here is the station reporting something unusual; the Daemon Log has the detail.

6.5 Why the station waits before keying

A row that sits at pending for a few seconds, or occasionally much longer, is waiting for one of these reasons:

You can watch the first reason directly. "Status & Diagnostics", "Diagnostics" shows, under "NAV (busy time remaining)", how long the station believes each announce channel and the bulk region stay occupied.

6.6 What you can do to a row

There is no "retry now" button; a deferred row retries by itself.

One more thing puts a message in Drafts: sending a distress call while that message is on the air. The message stops, and its row carries the note "interrupted by emergency broadcast" (Section 23.2).

6.7 After a restart

The outbox is kept on disk, so nothing is lost when the daemon stops. Rows that were pending or airing, and mail whose deposit at the mailserver was under way, come back as drafts: look in "Drafts" after any restart and send what you still want sent. Deferred rows stay deferred and carry on where they were. Section 20.7 has the reasoning.

6.8 What to remember

Chapter 7

Accounts, Roles and Shared Stations

7.1 Solo or organisation

There is no setup question asking what kind of station you run. The station works it out from what exists, and calls the answer its posture:

Solo is simply an organisation with no accounts yet, so there is nothing to convert: create the first account and the station is an organisation. It then stays one, because the station always keeps at least one administrator account. The screens are the sign-in window (Section 5.2) and the "People" tab of "Organization" (Section 5.8.2).

7.1.1 The station password

A new station's password is mLink. Change it before the daemon can be reached from anywhere but its own computer: "Organization", "People", STATION PASSWORD, or Settings, "Network", "Change daemon password". It can be up to 63 characters and cannot be empty. Changing it does not sign anyone out; it applies to the next sign-in.

The daemon also understands a separate technician password and administrator password for a station without accounts, but the client has no control for setting them. A station that wants to separate duties creates accounts.

7.2 Operator accounts

An operator account is a named person: a name, a password, a role, an enabled switch and an optional tactical position of up to 31 characters, such as OPS CHIEF. Names are 1 to 24 characters of lower-case letters, digits, underscore and hyphen, so that one person has exactly one spelling wherever the name appears. A station holds up to 64 accounts.

An administrator manages accounts in the People tab. Two guards keep a station from locking itself out: the first account created must be an administrator, and the last enabled administrator cannot be removed, disabled or given a lower role until another administrator exists.

Accounts belong to the station, not to one computer. At a station made of several daemons, an account created on one member works on all of them (Chapter 31).

7.3 The sign-in rule

You always type a name and a password. What happens next leaves no room for doubt:

  1. If the name is an account's name, the password must be that account's password. Capital letters in the name are ignored. There is no falling back to the station password: an account name belongs to its owner, and nobody borrows a colleague's identity by knowing the station password.
  2. If the name is not an account, the station password applies. At a solo station it gives full control. At an organisation it gives a walk-up guest session with the lowest role, operator, if the administrator allows guests; otherwise the sign-in is refused and the station says it requires an account.

Guests are allowed until an administrator unticks "Allow walk-up guest operating (station password)" in the People tab. With guests off, someone without an account cannot use the station for anything, a distress call included (Section 23.1.1). Think about that before switching it off at a station that might be the only radio in the room.

A wrong password and a disabled account get the same refusal, and take the same time to get it, so the answer does not reveal which accounts exist or are suspended. The real reason is in the station's own log.

7.3.1 How passwords are kept

The station never stores a password. It stores a one-way fingerprint made with PBKDF2: the password is mixed with 16 random bytes, different for every password, and run through a cryptographic hash 100,000 times, leaving 32 bytes that cannot be turned back into the password. Checking a sign-in repeats the work on what you typed and compares the two results. The station password is kept the same way as account passwords. The only place a password is ever written down as typed is the client's own settings file, and only if you tick "Save password (plaintext)" in the sign-in window.

The repetition is deliberate. One check costs the station a fraction of a second, which you never notice when signing in, but it makes guessing passwords from a stolen database very slow. So that a flood of attempts cannot tie up the daemon, each network address gets five sign-in attempts in any ten seconds; further ones are told to wait, whether or not their password was right.

No password of any kind is ever sent by radio (Chapter 26). Between a client and the daemon, however, the sign-in crosses your network unencrypted, which is one more reason to keep the daemon on a network you trust.

7.4 Changes take effect at once

Whenever an account changes, every signed-in session that belongs to an account is checked again on its next command:

The same holds across a cluster: an account disabled on one member stops working on the others as soon as the change reaches them.

Sessions that signed in with the station password are not tied to an account, so account changes do not touch them. Those from before the first account was created keep the role they had; the People tab points them out and offers "Sign out others". Switching guest access off stops new guest sign-ins at once; to be sure a guest who is already signed in is gone, select that session under SESSIONS ON THIS MEMBER and press "Sign out". An administrator can end any session that way.

A session that sends nothing for 30 minutes is closed by the station. An open client talks to the daemon every few seconds, so this only clears away seats whose client was closed or lost its network. A daemon holds up to 32 sessions at a time.

7.5 Roles: who may do what

mLink has three roles. Each may do everything the one below it may do.

Table 7.1. The three roles and what each adds. Reading is open to every role.
RoleMay do, in addition to the roles belowTypical person
AdministratorCreate, change and remove accounts; switch walk-up guest access; change the station password; sign out other people's sessions. Add encryption keys and certificates and send the station's certificate. Join or leave a cluster, and approve or deny a member that asks to join.The station's trustee or a club officer.
TechnicianEverything that sets how the station behaves on the air: callsign, grid, the station's position, gpsd and the automatic position beacon; relay policy and operator presence; the FM mode and keying settings; rig control; sound devices; whether heard distress calls are repeated. The mail server link: its address and registering with it. Adding, changing and refreshing internet sources.Whoever looks after the radios and computers.
OperatorTheir own traffic and their own work: sending messages, chat lines and mail by radio or by internet; drafts, the Sent list and the transmit queue, including Abort; reading and filing mail; checking the mail server for mail and fetching it, by internet or by radio; mailing-list subscriptions and the internet chat room; position reports, map objects and area calls; everything in the Nets window; tracked-data requests; notes, the QSO log, friends and beacons lists; every status, log and diagnostic view; station chat; and every emergency action.Everyone at an operating position.

Three principles decide which role a command needs.

Refusals are explicit. A command above your role comes back with the reason, the role it needs and the role you have, and the client shows it; nothing is silently ignored or half done. An operator who tries to change the mail server's address meets exactly this, because setting up the mail server link is technician work; pressing "Get Mail" is not, and works for every role.

7.6 Several operators at one station

Many clients can be connected to one daemon at the same time: desktop clients on the shack computers, and browsers on anyone's laptop. Each connection is a seat, named by the account or, for a guest, by the name typed at sign-in. All seats see the same station: the same heard list, the same inbox, the same Sent list. The radio behaves exactly as it would with one operator; what follows happens between clients and daemon, never on the air.

7.6.1 Who wrote this mail

Mail from a shared station can say which person wrote it and in what capacity. The client attaches the name you signed in with and whatever you typed in the "Position:" field of the sign-in window, each up to 31 characters, and the receiving operator sees them as an "Operator:" line when reading the mail. This is separate from the callsign: the station is who sent it on the air, the author is who wrote it. The position kept with an account in the People tab is a record for the administrator; it is the sign-in window's field that travels with mail. Chapter 24 covers the mail format.

7.6.2 Not answering the same message twice

When one seat starts a reply to a received mail, every other seat's inbox shows a pencil in front of that mail. Anyone else who presses "Reply" on it is told who is already answering and asked "Reply as well?". The mark clears when the reply is sent or abandoned, and when that seat signs out or its session ends. A daemon tracks up to 16 replies in progress, and in a cluster each member keeps its own.

7.6.3 Talking between seats

"Chat" has a mode called "This station": a conversation among the station's own operators (Section 5.5.4). It is never transmitted and never written to disk. The daemon remembers the last 100 lines so that a seat connecting later can catch up, and forgets them when it stops. In a cluster it is one conversation for the whole station: a line typed in the shack reaches the operator at another member (Chapter 31).

7.7 What to remember

Part III: The Signal

Chapter 8

One Passband, Three Regions

8.1 Band, channel, region

Three words carry the whole geography of mLink, and they nest like boxes inside boxes.

A band is an amateur frequency range: 40 metres, 20 metres, 2 metres. It is the thing on your licence and the thing the band plan chops up.

A channel is one mLink operating frequency inside a band: the dial frequency, and sideband, that you and everyone you want to reach have set.

A region is a strip of the audio that comes out of (and goes into) your rig on that channel. There are three: emergency, announce and bulk, and each belongs to exactly one kind of modem.

Band contains channel, channel contains regions. They are levels, not synonyms. In this book "channel" never means a region, with one deliberate exception: the announce region is itself split into narrow announce channels, and that is simply what they are called.

8.2 The map

Every frequency in this chapter is an audio frequency: "150 Hz" means 150 Hz above your dial frequency on the air (Chapter 3).

announce region 200โ€“1500 Hz bulk region 1500โ€“3000 Hz emergency 125โ€“175 Hz 400 800 1200 VOX leader 1400 Hz (optional) bulk-control 2250 OFDM 1594โ€“2906 Hz 05001000 150020002500 3000 Hz emergency (8 tones) announce channel (QPSK) bulk (OFDM) allotment boundary (not where energy stops)
Figure 8.1. The whole mLink passband. Heights are schematic, not to scale. The dashed lines at 200 and 1500 Hz are allotment boundaries; the shapes show where each modem's energy actually sits.

The lines on the map come in two kinds. The allotment boundaries are round numbers that say which region owns which strip: emergency from 125 to 175 Hz, announce from 200 to 1,500 Hz, bulk from 1,500 to 3,000 Hz. The energy edges are where each modem's signal actually starts and stops, and they sit well inside the allotments. The modems themselves are in Chapter 10, Chapter 11 and Chapter 12; every figure is collected in Appendix A.

8.3 The emergency region: the bottom 50 hertz

The emergency region is the narrowest strip, centred on 150 Hz. One modem sends one of eight tones at a time, 6.25 Hz apart, from 128.125 up to 171.875 Hz, and starts each frame with a short sweep from 125 to 175 Hz. Its filter passes nothing below 115 or above 185 Hz.

That tiny footprint is the point. The emergency modem gets through far below the noise by going very slowly in a very narrow strip, so it needs little room, and it gets that room at the edge of the passband, where it takes nothing from the wide middle the data modems want. Its lowest tone still sits well clear of 67 Hz, the bottom of the CTCSS (continuous tone-coded squelch system) tones.

It is also the only region a station never waits for: the rules about holding off while others are busy (Chapter 17) do not apply to a distress call.

8.4 The announce region: three channels side by side

The announce region holds three identical, independent announce channels, numbered 0, 1 and 2. Each carries the same QPSK modem at its own centre frequency: 400, 800 and 1,200 Hz.

Each channel's signal is about 270 Hz wide, so the three occupy 265โ€“535, 665โ€“935 and 1,065โ€“1,335 Hz. Each is its own resource: three stations can be sending on the three channels at once, and a listener hears all three.

Why three channels and not one wider, faster one? Announce traffic is many short, independent frames from many stations, and three conversations at once beat queuing for one fast channel when most transmissions last a second or two. How a station chooses among the three is in Chapter 17.

8.5 The bulk region: the wide top half

The bulk region carries the high-throughput modem: OFDM (orthogonal frequency-division multiplexing), 28 closely spaced carriers sent at once. The carriers run from 1,617 to 2,883 Hz, centred on 2,250 Hz, and the modem's filter stops its data hard at 1,594 and 2,906 Hz. It gets the widest strip because it moves the most bytes: more bandwidth is more carriers, and more carriers is more bits per second.

8.5.1 The bulk-control channel

One more tenant lives in the bulk region. At its centre, 2,250 Hz, there is a fourth QPSK channel, the same modem as the three announce channels. This is the bulk-control channel, and it carries only the short control frames of a bulk exchange: the opener (the sender's PRESENCE and the frame that says "I'm about to send a bulk burst"), the replies that say what arrived, and the openers of any repair or follow-on burst. Short messages and other routine announce traffic never use it.

How can a QPSK channel sit in the middle of the OFDM modem's strip? Because the two take turns. A station keys the bulk-control channel only while the bulk region is quiet, under the same rule that decides when it may start a bulk burst; the burst it opens follows its control frames instead of overlapping them; and the replies go out once the burst has ended. At any moment the bulk region carries either a bulk burst or bulk-control frames, never both.

The pay-off: the frames managing a big transfer never compete with the routine chatter in the announce region.

8.6 Guard bands: measured from energy, not from lines

A guard band is empty spectrum left between two signals so that one's skirts do not spill into the other's receiver. The honest way to measure one is from where the energy really stops.

Take the gap between the emergency region and the lowest announce channel. On the allotment map it is a 25 Hz sliver, from 175 to 200 Hz. But nothing transmits at either frequency. The highest emergency tone is at 171.875 Hz and the body of the lowest announce signal begins at about 265 Hz, so the real separation is about 93 Hz.

emergency filter 115โ€“185 Hz allotment lines 175 / 200 announce channel 0 begins โ‰ˆ 93 Hz between real signals 100150200 250300 Hz
Figure 8.2. The bottom of the passband, magnified. The allotment lines suggest a 25 Hz guard; the energy says about 93 Hz.

The same reading applies everywhere:

8.7 One audio stream, many signals

The audio coming out of your receiver is one stream of numbers. If one station is sending an announce frame on 800 Hz, another is halfway through a bulk burst, and a third is sending a distress call, your audio is simply those three signals added together, plus noise. There is no switchboard and no time slot; the rigs and the air do the adding.

time โ†’ 150400800 1200150022503000 Hz station B: distress call, 150 Hz station C station D station E station C, next message station A: bulk burst station A: presence, opener
Figure 8.3. What one listener's audio contains. Signals from different stations overlap in time and are told apart by frequency. Stations C and E transmit at the same moment on different announce channels, and C's next message goes out on whichever channel is free, not the one it used before. Station A's own transmission stays in the bulk region: its opening frames go on the bulk-control channel at 2250 Hz, and the bulk burst follows them. (Sketch; not to scale.)

Taking the sum apart is equally simple: every detector and demodulator in the receiver is handed the same audio, and each looks only at its own strip through its own filter (Chapter 13). Because the strips do not overlap, the other signals are, to it, silence.

8.8 Keeping each signal in its own strip

The sum only works if nobody spills. A signal that leaks outside its strip, even faintly, lands inside somebody else's detector. So there is one rule, applied everywhere: every modem filters its own output before it goes to the radio. The filter is part of the modem, not an optional stage somebody might forget to add.

The receiving side's own protection against a very loud neighbour's leftovers is in Section 13.5.

8.8.1 All modems at the same level

Each modem produces its signal at the same average power. No region is built to be louder than another; whatever your rig's drive and ALC (automatic level control) do to one, they do to all.

8.9 Soft edges: the keying ramp

Switching a signal on or off instantly makes a click, and a click splashes energy across the whole passband. On the air that is the familiar key click. Inside mLink it is worse: to a sensitive detector in another region, a loud station's click looks a little like the start of a frame.

So every announce and bulk transmission gets a soft start and a soft finish. The first and last 20 ms (240 samples) of the assembled transmission are faded along a raised-cosine curve, the smooth S-shape that goes from nothing to full without a corner. The 20 ms is shorter than the natural run-in and run-out of an announce frame's pulse shaping, so on an announce frame the fade touches only the part of the signal that is already rising or falling, never a symbol that carries data.

The emergency modem's sweep carries its own fade-in and fade-out of about 21 ms.

8.9.1 Where the VOX leader tone sits

A station whose rig is keyed by VOX puts a plain tone, the VOX leader, in front of every transmission to wake the rig before the first frame; why it is needed, and why it lasts 800 ms unless the operator sets another length, is in Chapter 4. The tone is at 1,400 Hz, in the empty gap between the top announce channel and the bottom of the bulk region. A steady tone there matches no detector's pattern. It fades in and out over 10 ms and is sent at the same level as the frames behind it.

The leader goes in front of emergency transmissions too, since a one-frame distress call has no later frame to fall back on if VOX swallows the first. A station that keys by a CAT command or a PTT (push-to-talk) line sends no leader at all.

8.10 What to remember

Chapter 9

Error Correction: Reed-Solomon and LDPC

9.1 Why error correction

A voice operator who misses a word says "say again". A data station could do the same for every damaged frame, and on a noisy HF path it would spend most of its time asking.

Forward error correction (FEC) turns that around. The sender adds redundancy up front: extra bits computed from the data by fixed rules. The receiver checks the rules, and when some of them fail, it works out which bits must be wrong and flips them back. No second transmission is needed. The price is air time: every redundant bit is a bit of payload that was not sent. The code rate says how the air time is split. At rate 1/2, half the bits are data and half are redundancy; at rate 5/6, five out of six are data.

FEC does not replace asking again; it makes asking rare. Each frame fixes its own small errors, so the only frames left to repair (Chapter 16) are the ones that were truly overwhelmed.

9.2 Parity: the whole idea in one bit

Every code in this chapter is built from one operation, XOR (exclusive or). XOR of two bits is 1 if they differ and 0 if they match. XOR a string of bits together and the answer tells you whether it contains an odd or even number of 1s.

A parity bit is one extra bit chosen so that a group of bits, parity included, has an even number of 1s. If one bit in the group flips on the way, the count turns odd and the receiver knows something is wrong. It does not know which bit, though.

To find the bit, use several overlapping groups. Lay nine data bits out in a 3 × 3 grid and add a parity bit for every row and every column. When one bit flips, exactly one row and one column go odd, and the bad bit sits where they cross. Flip it back and the data is repaired.

sent: 9 data bits + 6 parity bits 1 0 1 0 0 1 1 0 1 1 0 0 0 0 0 received: one bit flipped 1 0 1 0 0 0 1 0 odd! 1 1 0 0 0 0 odd! 0
Figure 9.1. Row and column parity on a 3 × 3 grid. One flipped bit makes one row check and one column check odd, and their crossing locates it.

That is the whole trick behind real error-correcting codes: many overlapping parity checks, arranged so that any likely pattern of damage leaves a distinctive pattern of failed checks. The codes mLink uses are far more efficient than the grid, but they rest on the same idea.

9.3 Reed-Solomon: the code for short frames

9.3.1 Bytes instead of bits

A Reed-Solomon code (RS) works on whole bytes rather than single bits. The sender treats the data bytes as the coefficients of a polynomial and appends extra bytes computed from it, using arithmetic in which every byte value from 0 to 255 is a number and every sum and product stays inside that range. The receiver can then solve for which bytes are wrong and what they should have been. The same codes protect CDs, QR codes and deep-space probes.

The useful property is simple to state: for every two parity bytes added, the code can correct one damaged byte, anywhere in the block, whether one bit of that byte is wrong or all eight.

mLink uses one Reed-Solomon code, written RS(23,11): 11 data bytes followed by 12 parity bytes, 23 bytes on the air. Twelve parity bytes let it correct up to six damaged bytes out of the 23, in any positions, without being told which ones they are. (Technically it is the standard 255-byte Reed-Solomon code with the unused positions filled with zeros that are never sent; the receiver puts them back before decoding.) Each 23-byte block is one codeword: data and redundancy together.

11 data bytes (the frame) 12 parity bytes Any 6 bytes of the 23 can arrive wrong, in any positions, and the frame is still recovered exactly. Here 3 bytes are hit: easily fixed.
Figure 9.2. One RS(23,11) codeword. Eleven bytes of frame, twelve of parity; up to six damaged bytes anywhere in the 23 are repaired exactly.

Every short frame mLink sends is exactly 11 bytes, and each one travels as a single RS(23,11) codeword. That covers every frame of the announce modem (Chapter 11), which carries the network's bookkeeping and its short messages, and every frame of the emergency modem (Chapter 10), which backs the code up by sending a distress message several times (Section 10.8). The two modems differ only in how the 184 coded bits reach the air.

Those 184 bits go out in the order they sit in the codeword: byte 0 first, most significant bit of each byte first, parity bytes last.

9.3.3 Hard decisions, and knowing when it failed

The Reed-Solomon decoder in mLink works on hard decisions: each received bit is rounded to a plain 0 or 1 before decoding, and the code's six-byte budget does the rest. It has a valuable second talent. When a frame has more damage than the code can fix, the decoder almost always notices that the damage cannot be explained and reports failure instead of inventing an answer. mLink discards such a frame; it never reaches the protocol. For a frame that carries a callsign or names a message, a missing frame is far better than a wrong one.

9.4 LDPC: the code for bulk frames

The bulk modem (Chapter 12) sends large frames close to the noise, and for that mLink uses a low-density parity-check code (LDPC). LDPC codes were invented by Robert Gallager around 1960 and sat unused for decades because computers could not decode them in reasonable time. They now protect Wi-Fi, 5G and satellite TV, because given a long enough codeword they correct errors almost as well as theory allows.

Every bulk frame is exactly one LDPC codeword of 9,720 bits, whatever its code rate. A higher rate does not make the frame longer or shorter; it only changes how many of the 9,720 bits are data and how many are parity. So every bulk frame takes the same time on the air, and a receiver always knows how much to collect.

9.4.1 The rulebook: the parity-check matrix

An LDPC code is nothing more than a long list of parity checks like the rows and columns of the grid example. Each check names a handful of bits in the codeword and says "these must XOR to zero" (contain an even number of 1s). Written out as a table, with one row per check and one column per bit and a 1 wherever a check includes a bit, this list is the parity-check matrix, usually called H.

"Low density" means that table is almost entirely zeros. Each check touches only 6, 12 or 18 of the 9,720 bits, and each bit takes part in exactly three checks. That sparseness is what makes decoding fast.

Table 9.1. The three bulk LDPC codes. Every one has a 9,720-bit codeword; only the split between information and parity changes. Every check in a code covers the same number of bits, and every bit sits in three checks.
RateInformation bitsParity bits (= checks)Bits per check
1/24,8604,8606
3/47,2902,43012
5/68,1001,62018

The three matrices are fixed tables built into every mLink station, generated once from fixed random seeds. Two stations can only talk bulk if they hold the identical tables, so they are part of the protocol in the same way the carrier frequencies are. Which of the three rates a given frame uses is decided by the frame's position in its transmission, up to a limit the sender announces beforehand; Chapter 15 explains that ladder.

9.4.2 The Tanner graph

The same rulebook is easier to think about as a picture. Put every bit on the bottom row as a circle and every check on the top row as a square, and connect each check to the bits it covers. This is a Tanner graph. Decoding is a conversation along its lines.

c1 c2 c3 c4 b1 b2 b3 b4 b5 b6 b7 b8 checks bits check c2 says: b2 + b4 + b6 + b7 must be even Real bulk code: 9,720 bits; 1,620 to 4,860 checks; each bit in 3 checks
Figure 9.3. A toy Tanner graph with eight bits and four checks. The real rate-1/2 bulk code has 9,720 bit circles and 4,860 check squares, and 29,160 lines between them.

9.4.3 Soft bits: how sure is each bit?

The bulk modem does not hand the decoder plain 0s and 1s. For every bit it hands over a number that says which way the bit leans and how strongly: a log-likelihood ratio (LLR), a soft bit. In mLink it is a whole number from −127 to +127. A large positive value means "almost certainly 0", a large negative one "almost certainly 1", and anything near zero means "no idea". A bit that came in on a strong, clean carrier gets a big number; one that came in on a carrier sitting in a fade gets a small one (Section 12.8.4 shows how the modem sets them).

Those confidence values are worth decibels. A hard-decision decoder has to treat every bit as equally trustworthy. A soft-decision decoder knows that the doubtful bits are the likely culprits when a check fails, and fixes those first.

9.4.4 Belief propagation: decoding as a conversation

The LDPC decoder uses belief propagation, also called message passing. A useful picture is a room full of people (the bits), each with a hunch about their own value, and a number of committees (the checks), each made up of a few of those people and bound by one rule: their answers must add up to even.

  1. Everyone starts with the modem's hunch. Each bit sends its soft value to every check it belongs to.
  2. Each check replies to each of its members. A check looks at what its other members said and tells this one: "given what the rest of us believe, for our sum to be even you should be a 0 (or a 1), and I am this sure." A check is only as sure as its least sure other member.
  3. Each bit updates its belief. It adds its original hunch to what all its checks told it. A bit that the modem called a weak 1, but whose three checks all say firmly "you must be 0", now believes 0.
  4. Test. Take every bit's current belief as a hard 0 or 1 and run every check. If they all pass, the codeword is found: stop.
  5. Otherwise go round again. Each bit tells each check its updated belief, leaving out what that same check told it last time (so no committee just hears its own opinion echoed back), and the conversation continues.

mLink's decoder uses the min-sum form of this algorithm: in step 2 a check's reply takes the product of its other members' signs and the smallest of their sizes. It is a well-known shortcut, slightly weaker than the exact rule and far cheaper to compute. The decoder allows at most 15 rounds. If every check passes before then it stops early; if not, it gives up and reports that the frame did not decode.

9.4.5 Knowing when a decode is wrong

"All checks pass" nearly always means the right codeword, but not quite always. Very occasionally, a badly damaged frame lands on a different valid codeword, one that satisfies every check but holds different data. mLink guards against that with the filler described in Section 9.5: every bulk frame ends with a stretch of known bits, and a decode that lands on the wrong codeword scrambles them. A bulk frame is accepted only if the decoder converged and the filler came out exactly right. Anything else is treated as a lost frame, which the receiver can ask for again by number (Chapter 16), instead of as garbage that would only show up when the whole message failed its check.

9.4.6 Encoding straight from the rulebook

The sender's job is the reverse: given the information bits, find parity bits that make every check pass. mLink's codes are systematic, which means the information bits appear in the codeword unchanged, behind the parity bits. The textbook way to compute the parity needs a second table derived from H, and for a 9,720-bit code that table is huge. mLink instead encodes directly from the sparse H, with a method published by Richardson and Urbanke: it rearranges H once so that most of it forms a staircase in which each check introduces exactly one parity bit not yet fixed, then works along the staircase, each new parity bit being simply the XOR of bits already known. A small leftover block is solved by ordinary elimination. The sender needs no table the decoder does not already have.

9.5 Filling the codeword: the pi pattern

A codeword has a fixed number of information bits (4,860 at rate 1/2), but the last frame of a message, or the only frame of a short one, rarely has exactly that much to carry. The rest of the space has to be filled with something, and the receiver has to be able to tell where the real data stops. mLink solves both with one pattern. After the frame's payload bytes, the sender writes:

  1. a two-byte marker, 00 00;
  2. then a fixed 200-byte pattern that begins with the digits of pi (03 14 15 92 65 35 89 79 …), repeated as often as needed, up to the end of the information bits.
The k information bits of one frame (rate 1/2: k = 4860 bits, about 607 bytes) this frame's payload bytes 00 00 03 14 15 92 65 35 89 79 ... (pi) marker fixed filler: the receiver knows it exactly The 9720-bit codeword the encoder produces parity bits (9720 - k) the k information bits, unchanged
Figure 9.4. Top: the information bits of one bulk frame, filled with payload, then the 00 00 marker, then the fixed pi pattern. Bottom: the codeword that comes out of the encoder, parity in front of the unchanged information bits.

The receiver, after decoding, searches from the start of the information bits for a 00 00 whose every following bit matches the pi pattern exactly. The first such position is the end of the payload. The length of each frame's data is therefore never sent anywhere: it is written into the frame by the filler itself. A payload that happens to contain 00 00 causes no confusion, because every bit after that point, all the way to the end of the information bits, would also have to match the pattern.

To make sure there is always room for the marker, the sender never fills a frame completely: it holds back four bytes of every frame's capacity for the marker and at least two bytes of pi. That is why a rate-1/2 frame carries 603 payload bytes rather than 607 (4,860 bits is 607 whole bytes).

The same filler is the tripwire that catches a decode that landed on the wrong codeword. A lightly filled frame ends in thousands of known bits; even a frame filled to capacity ends in about 35 of them, and a wrong decode is very unlikely to reproduce them by chance.

9.6 The bulk path, end to end

An interleaver reorders bits before transmission so that errors which arrive in a clump on the air are spread out by the time they reach the decoder. LDPC works bit by bit, and a clump concentrated on a few checks can overwhelm them, so a bulk codeword is reordered twice on its way out. Straight after encoding, its 9,720 bits are written into a grid of 5 rows by 1,944 columns, row by row, and read out column by column, so bits that leave next to each other sat 1,944 places apart in the codeword. The modem then spreads the result across the frame's symbols with a second, larger grid of its own (Section 12.5). The receiver undoes both, in reverse order, before the LDPC decoder sees a single soft bit.

frame's bytes up to 603-1008 pad 00 00 + pi LDPC encode k to 9720 bits 5 x 1944 interleave 48 x 203 interleave QPSK + OFDM 203 symbols transmit bytes out check pad LDPC decode undo 5 x 1944 undo 48 x 203 OFDM demod receive (soft bits flow right to left)
Figure 9.5. What happens to one bulk frame's bytes. The receiver runs the same steps in reverse order, passing soft bits all the way to the LDPC decoder and only turning them into bytes at the end.

9.7 The slope and the cliff

Plot the share of frames a code decodes against signal-to-noise ratio (all figures here are SNR@3k) and the two codes in this chapter trace very different curves.

9.7.1 Reed-Solomon fades out along a slope

The short frames fail gradually. Measured on the announce modem (Section 11.9), practically every frame arrives at −5 dB, about 95 % at −6, two in three at −7, one in four at −8, and hardly any at −9: four decibels from everything to nothing.

0%25%50% 75%100% −10−9−8 −7−6−5 −4 SNR@3k (dB) frames received 4%25%67% 95%99.7% four decibels from almost none to almost all
Figure 9.6. The Reed-Solomon slope: the measured share of announce frames received at each signal level, in steady noise. Each decibel lost costs more frames, but there is no single point where they stop.

The reason is the size of the frame. A Reed-Solomon frame survives if no more than six of its 23 bytes are damaged, and with so few bytes, luck matters: at a given signal level one frame collects four bad bytes and the next collects eight. As the signal weakens, the unlucky frames become steadily more common. Nothing snaps.

9.7.2 LDPC falls off a cliff

The bulk frames behave differently. This steep curve is called a waterfall, and for a long LDPC code it is nearly a cliff. A rate-1/2 bulk frame, perfectly located in steady noise, decodes almost every time from about +3 dB; two decibels below that, none do. The higher rates carry less parity and need a little more signal still.

Belief propagation is a chain reaction. Above the cliff, the confident bits outnumber the doubtful ones enough that every round of the conversation corrects more than it confuses, and the whole codeword snaps into place. Below it, the doubtful bits win the argument, the corrections never catch on, and after 15 rounds the checks are still failing. There is little middle ground: the decoder either gets the whole frame or does not get it at all. And where 23 bytes leave plenty of room for luck, 9,720 bits average it away; longer codewords make the cliff steeper.

9.7.3 A coin flip per frame, and why +6

On the narrow edge of the cliff, whether a given frame decodes depends on the exact noise it happened to meet. Each frame is effectively a coin flip, weighted by the SNR, and a transmission of many frames is many flips in a row. If each frame succeeds 60 % of the time, ten frames arriving without a single loss is about a one-in-165 event. The same link two decibels stronger delivers every frame.

So a station does not aim for the edge. It trusts bulk only on a link it has measured at +6 dB or better, three decibels clear of the rate-1/2 cliff, so that frames land on the flat top of the curve rather than its lip. Below that level, a message goes by the announce modem's short frames or through a relay with a better path (Chapter 15). And a lost frame is not a lost message: the receiver names exactly which frames are missing and only those are sent again (Chapter 16).

9.8 What to remember

Chapter 10

The Emergency Modem: NB8FSK

10.1 One job, done at any cost

The emergency modem exists for distress calls and nothing else. Its whole design follows from one requirement: when someone is in trouble, the call must get through on the worst path, with the weakest signal, from the most improvised station. Speed does not matter. Being heard does.

The modem is called NB8FSK: narrow-band 8-tone frequency-shift keying. It lives in the emergency region, the 50 Hz strip from 125 to 175 Hz at the bottom of the passband (Section 8.3). What the distress service does with it (who sends, how often, who answers) is the subject of Chapter 23. This chapter is only about the signal.

10.2 Eight tones, one at a time

Frequency-shift keying (FSK) is the oldest trick in data radio: pick a set of tones, and send information by choosing which tone to play. RTTY does it with two tones. NB8FSK does it with eight.

With eight tones to choose from, each tone choice carries three bits, because there are exactly eight different three-bit patterns (000 through 111). The tone number is simply those three bits read as a binary number, with the first bit sent as the ones place. Tone 0 means the three bits were all zero; tone 6, binary 110, means the bits sent were 0, then 1, then 1.

The eight tones are spaced 6.25 Hz apart, centred on 150 Hz:

transmit and receive filter, 115โ€“185 Hz 0123 4567 000001010011 100101110111 binary tone 6.25 Hz synchronising sweep, 125 โ†’ 175 Hz 110125150175190 Hz
Figure 10.1. The NB8FSK tone ladder: 128.125, 134.375, 140.625, 146.875, 153.125, 159.375, 165.625 and 171.875 Hz. The eight tones fit in under 44 Hz.

10.2.1 Six and a quarter tones per second

Each tone is held for 160 ms, so the modem sends 6.25 tones per second: 6.25 baud. At three bits per tone that is 18.75 bits per second on the air, before any error correction.

The tone spacing and the baud rate are the same number on purpose. When the tones are exactly one baud apart, a receiver that listens to one tone for exactly one symbol period hears nothing from its neighbours: over those 160 ms a neighbouring tone completes exactly one more (or one fewer) whole cycle, and its contribution averages out to zero. This is the tightest spacing at which the tones do not blur into each other for a receiver that does not track phase, and it is how eight tones fit into under 44 Hz.

The modem changes from one tone to the next without a jump in the waveform: the new tone picks up exactly where the old one's phase left off. A phase jump would be a small click at every symbol boundary, and clicks spread energy outside the band. What faint sidelobes remain are cut off by the modem's own transmit filter, 115 to 185 Hz (Section 8.8).

10.3 Why so slow, and why so narrow

Here is why going slow wins. The receiver does not listen to 3 kHz of noise when it decides which tone was sent. It listens to each tone position for 160 ms, and a 160 ms listen only admits noise from a strip about 6.25 Hz wide. The ratio 3000 / 6.25 is 480, which is about 27 dB. So a signal at −15 dB SNR@3k, invisible on a waterfall, is roughly 12 dB above the noise in the tone bin the receiver is actually looking at, and 12 dB is plenty to tell which of eight tones is loudest most of the time.

That is the whole secret, and it has a price: each halving of the symbol rate halves the noise the receiver lets in per decision (3 dB better) and doubles the time on the air. NB8FSK sits far out on that trade.

10.4 From eleven bytes to sixty-two tones

An emergency frame carries 11 bytes. Two of them are a small header (which frame of the message this is, how many frames the message has, and a number identifying the incident), and nine are content. The first frame's nine bytes are a packed summary of the emergency; later frames carry text, thirteen characters to a frame, from a fixed set of digits, capital letters, space and a few punctuation marks. Chapter 23 describes the contents; this section follows the bytes onto the air.

11 data bytes +12 check bytes = 23 bytes (Reed-Solomon) 184 bits, in codeword order + 2 padding bits = 186 bits 62 tones ร— 3 bits 62 ร— 160 ms = 9.92 s 62 tones sweep 0.32 s one frame on the air: 10.24 s
Figure 10.2. Encoding one emergency frame. Eleven bytes become twenty-three with error correction, and their bits, taken in order three at a time, each choose a tone. A synchronising sweep goes in front.

The 11 bytes are first protected by the Reed-Solomon code RS(23,11), which adds 12 check bytes and lets the receiver repair up to 6 wrong bytes out of the 23 (Section 9.3.2).

The 23 bytes are 184 bits, and they go to the modem in order, three at a time, each group choosing one tone. 184 is not a multiple of three, so two zero bits are added at the end to make 186, which is exactly 62 groups. Sixty-two tones at 160 ms each is 9.92 seconds. The receiver knows the two padding bits are there and ignores them.

10.5 Finding the start: the sweep

A receiver can only decode a frame if it knows where the first tone begins, and at these signal levels there is almost no energy to go by. So every emergency frame begins with a known signal that the receiver searches for: a synchronising sweep, a single tone that glides smoothly upward from 125 Hz to 175 Hz over 320 ms, exactly two symbol periods. Radar engineers call this a chirp. It is faded in and out at its ends over about 21 ms and passes through the same filter as the tones, so it is as narrow as the rest of the frame.

125150175 Hz โ€ฆ sweep 0.32 s tone 0.16 s โ€ฆ62 tones in all, 9.92 s frame 0: summary frame 1: text frame 2: text โ€ฆ up to 15 each frame 10.24 s, back to back, each with its own sweep
Figure 10.3. Top: the start of one frame, time across and frequency up. The sweep glides through the whole band; the data tones sit still. Bottom: a strung message of several frames. (Not to scale.)

10.5.1 Why a sweep and not a tone pattern

The obvious synchronising signal would be a short, fixed pattern of the modem's own tones: "tone 0, tone 7", say. The trouble is that the data can contain that same pattern. Any stretch of payload whose bits happen to produce tone 0 followed by tone 7 looks, to the receiver, exactly like a frame start, and in a message of several frames sent back to back the receiver can latch onto the data and decode garbage.

A sweep cannot be imitated by the data. Payload tones sit still on one of eight frequencies for 160 ms each; the sweep passes through every frequency in the band without stopping on any. It has two more virtues. Compared against incoming audio, it produces a sharp peak about 20 ms wide, which marks the frame start far more precisely than a pair of tones would. And random noise is less likely to resemble a sweep than a tone, so false alarms are rarer.

10.6 Air time

One frame is the 0.32 s sweep plus 9.92 s of tones: 10.24 seconds for 11 bytes, a useful rate of about 8.6 bits per second. A message is one to fifteen frames, sent back to back with no gap, each frame with its own sweep, so the longest message lasts 153.6 s. The first frame alone is a complete distress call (Chapter 23), and it is the shortest thing the modem ever sends. A station keying by VOX puts its leader tone in front (Section 8.9.1).

10.7 Receiving it

Every station searches the emergency region for the sweep whenever it is not transmitting. How that search works, how it sets its threshold against the noise and how it refuses to be fooled by a loud signal elsewhere in the passband are all in Section 13.3.1. What follows is what happens once the start of a frame is known.

10.7.1 Reading the tones

When the 9.92 seconds of tones have arrived, the frame is filtered to 115โ€“185 Hz and, for each 160 ms tone period, the receiver measures how much energy is present at each of the eight tone frequencies. It does not need to know the phase of the signal, only how loud each tone is. This is called non-coherent detection, and it is what lets the modem work on paths where the phase wanders.

For each of the three bits, the receiver adds up the energy of the four tones that would mean "this bit is 0" and the four that would mean "1", and compares. That gives a decision and a confidence for each bit. The decisions are packed back into 23 bytes and handed to the Reed-Solomon decoder, which returns the 11 bytes exactly as sent or reports the frame unreadable.

When a frame decodes and its header says more frames follow, the receiver collects the next one exactly 10.24 seconds after this one's sweep, without searching for it again.

10.7.2 Telling real frames from noise

A receiver that listens around the clock, below the noise, will sooner or later see noise that happens to form a valid-looking block. mLink takes two cheap precautions before it reacts to an emergency frame. They never stop a frame being decoded; they only decide whether to act on the result.

10.8 Reaching −17 dB: repetition

Measured in steady noise through the whole receive path, a single emergency frame gets through about 96 % of the time at −15 dB, 85 % at −16, two times in three at −17 and one in three at −18. So one pass of a distress call is dependable to about −15 dB. What gives out first is finding the sweep, not reading the tones: a frame whose start is already known still decodes 98 % of the time at −17 dB.

The distress service does not send once. It repeats the whole message on a schedule until it is acknowledged or the operator stops it (Chapter 23). The receiving side collects frames across the repeats: a frame missed on one pass is simply picked up on a later one, in any order, and the message is complete when every frame has arrived at least once. Each pass is another independent chance through the noise. If one pass at −17 dB succeeds two times in three, three passes all failing happens less than one time in twenty-five.

That is how the message floor reaches −17 dB: not by a cleverer single frame, but by patience. Real HF adds fading, which helps some passes and hurts others, and repetition is exactly the right tool for that too, because a fade that swallows one pass is unlikely to swallow them all.

10.9 What to remember

Chapter 11

The Announce Modem: QPSK

11.1 The modem every station needs

Everything that makes mLink a network rather than a pair of stations travels in announce frames: who is on the air, who is about to send, what arrived and what did not (Chapter 14). That role sets the design. The announce modem must be robust enough to reach every station worth talking to, short enough that a busy channel is not choked by bookkeeping, and simple enough to be completely fixed: every announce frame, from every station, looks exactly the same on the air.

11.2 QPSK: two bits in every twist of phase

The emergency modem changes which tone it sends. The announce modem sends one steady tone and changes where that tone is in its cycle: its phase.

Picture the tone as a clock hand spinning steadily. At each symbol boundary the transmitter can jump the hand to one of four positions, a quarter-turn apart. The receiver, knowing where the hand should be if nothing had changed, sees which of the four positions it jumped to. Four choices carry two bits. This is QPSK, quadrature phase-shift keying: "quadrature" because the four positions are a quarter-turn apart.

00 10 11 01 45ยฐ 135ยฐ 225ยฐ 315ยฐ the four phases, with the two bits each one carries ร— received: nearest is 00 noise moves the point; the receiver picks the nearest
Figure 11.1. The QPSK constellation. Each dot is one of the four phases the tone can take; the labels are the two bits it carries (first bit sent, then second). Neighbouring dots differ in exactly one bit.

Look at the labels. Going round the circle, 00, 10, 11, 01: each dot differs from both its neighbours in exactly one bit. That arrangement is a Gray code, and it matters because when noise pushes a received phase to the wrong dot, it almost always pushes it to a neighbouring dot. With Gray coding, that common mistake costs one wrong bit instead of two.

11.2.1 200 symbols per second

The announce modem sends 200 symbols per second, 200 baud, so each symbol lasts 5 ms (60 samples). At two bits per symbol that is 400 bits per second on the air before error correction: about twenty times the emergency modem's raw rate.

11.3 Smooth symbols: root-raised-cosine shaping

If the transmitter slammed the phase from one position to the next at each symbol boundary, every jump would be a sharp corner in the waveform, and sharp corners splash energy far beyond the channel. So instead of sending each symbol as a hard-edged 5 ms block, the modem sends each one as a smooth pulse that rises, peaks at the symbol's centre, and dies away, overlapping its neighbours. The shape of that pulse decides how wide the signal is.

mLink uses a root-raised-cosine (RRC) pulse, the standard choice. The shaping is split in half: the transmitter applies one half, the root, and the receiver applies the matching other half, and the combination is the full raised-cosine shape. That combined shape has a subtle and useful property: the pulses from neighbouring symbols overlap in time, yet at the exact centre of each symbol all the neighbours pass through zero, so they do not disturb the reading. The receiver's half also happens to be the filter that best rejects noise for this pulse.

The pulse has one setting, the roll-off, which trades bandwidth against how quickly the pulse dies away. The announce modem uses a roll-off of 0.35, so the signal occupies 200 × 1.35 = 270 Hz. Each pulse is eight symbols long, which gives every stretch of symbols a run-in and run-out of about 40 ms where the first and last pulses fade up and down. A final sharp filter trims the skirts the shaping leaves behind (Section 8.8).

11.4 Where it runs

The same modem runs on each of the three announce channels, centred on 400, 800 and 1200 Hz (Section 8.4), and on the bulk-control channel (Section 8.5.1). Everything in this chapter applies to each of them identically.

11.5 The fixed eleven-byte frame

Every announce frame carries exactly 11 bytes. No more, no less, never a different modulation, never a header describing the frame. The receiver always knows exactly what is coming, which is what lets it be so simple, and it saves the air time a header would cost. The first byte says what kind of frame it is (Chapter 14); the byte layouts are in Appendix B.

type 10 data bytes 12 Reed-Solomon check bytes the 11-byte frame 23 bytes = 184 bits = 92 QPSK symbols on the air
Figure 11.2. One announce frame. Eleven bytes of content become twenty-three with error correction.

The 11 bytes are protected by the Reed-Solomon code RS(23,11), which adds 12 check bytes and repairs up to 6 wrong bytes out of the 23 (Section 9.3.2). The 23 bytes are 184 bits; they go to the modulator in order, two at a time, and become 92 QPSK symbols.

11.6 The preamble: four known symbols

Before the 92 data symbols, every announce frame sends a preamble: four QPSK symbols that are always the same, at phases 225ยฐ, 315ยฐ, 315ยฐ and 135ยฐ. With the pulse shaping's run-in and run-out, the preamble lasts about 100 ms. It does two jobs.

  1. It says "a frame starts here." The receiver searches for this known pattern on each channel continuously (Section 13.3.2). When it finds it, it knows exactly where the data begins.
  2. It tells the receiver the phase. QPSK carries its information in phase, but a receiver cannot know in advance what phase a distant station's tone will arrive with: the path, the two rigs' oscillators and the exact moment of arrival all shift it. Because the preamble's phases are known, the receiver can measure how far the whole signal has been turned, and turn it back.

The transmitter makes that measurement usable by keeping the tone continuous from the preamble into the data: the data section starts at exactly the phase the preamble's tone would have reached had it kept going. So the phase the receiver measures on the preamble is the phase it needs for the data, with no jump in between.

11.6.1 Phase is measured afresh on every frame

Each announce frame carries its own preamble, and the receiver measures the phase from that frame's preamble and applies it to that frame only. It does not carry a phase from one frame to the next, and it does not run a loop that follows the phase through the frame; the one measurement serves the whole 540 ms of data behind it. This is what lets frames from different stations, arriving back to back on the same channel, each decode on their own terms: every frame brings its own reference.

Precise timing matters to this. Every sample of error in locating the preamble turns the measured phase by between 12ยฐ (on the 400 Hz channel) and 36ยฐ (on the 1200 Hz channel), and 45ยฐ of error puts a symbol on the edge between two dots. So the receiver finds the preamble's position to the single sample before it measures the phase.

11.7 Frame timing on the air

preamble 92 data symbols next frameโ€ฆ preamble 100.2 ms 540.2 ms guard 21.3 ms one frame: 640.3 ms (7684 samples) frame start to next frame start: 661.7 ms
Figure 11.3. One announce frame and the start of the next, to scale. The guard between strung frames is silence.

Adding it up: the preamble is 4 symbols plus the pulse run-in and run-out, 100.2 ms. The data section is 92 symbols, 460 ms, plus run-in and run-out: 540.2 ms. One whole frame is 7684 samples, 640.3 ms.

When a transmission strings several announce frames together, the frames are separated by exactly 256 samples of silence, 21.3 ms. So in a string, each frame starts 661.7 ms after the previous one. The silence gives the receiver a clean break in which to find the next frame's preamble instead of hunting for it against the tail of the previous frame; it costs about 3 % of the air time of a string. A lone frame is 0.64 s on the air, two frames 1.30 s, and seven frames about 4.6 s.

Every transmission starts and ends with the keying ramp described in Section 8.9. The ramp is shorter than the pulse run-in, so it only touches signal that is already fading up or down.

11.8 Reading a frame

Once the detector has located a frame and measured its phase, the decoder filters the audio to the channel's band, removes the channel's tone using that phase, applies the receiver's half of the pulse shaping, and reads the signal at the centre of each of the 92 symbols. Each reading lands somewhere near one of the four dots, and the nearest dot gives two bits. The 184 bits are packed back into 23 bytes and handed to the Reed-Solomon decoder. Out comes the 11-byte frame exactly as sent, or nothing: a frame the code cannot repair is dropped.

11.9 The −5 dB floor

Measured in steady noise through the whole receive path, 99.7 % of announce frames arrive at −5 dB SNR@3k, and the figure is the same on every announce channel. Below that the frames fade out over about four decibels: 95 % at −6, two in three at −7, and almost none at −9 (Figure 9.6).

Simple arithmetic shows where the number comes from. Each 5 ms QPSK symbol admits noise from a strip about 200 Hz wide, and 3000 / 200 is 15, about 12 dB. So at −5 dB each symbol arrives roughly 7 dB above the noise it is competing with, and Reed-Solomon mops up the symbols that noise gets wrong. The emergency modem's symbols are 32 times longer, which is 15 dB, and its floor is 10 to 12 dB lower (Section 10.3): the same trade seen from the other side. The announce modem sits where it does because its frames are everyday bookkeeping, and at ten seconds a frame the bookkeeping would crowd out the traffic it exists to manage.

The announce floor is, in practice, the edge of the network. Two stations that can hear each other's announce frames can do everything mLink offers, if slowly. Two stations below it cannot exchange traffic directly, though a third station that hears both can relay for them (Chapter 19).

11.10 What to remember

Chapter 12

The Bulk Modem: OFDM

The bulk modem lives in the bulk region of the passband (Chapter 8) and uses a technique called OFDM, orthogonal frequency division multiplexing: the same family of modulation used by Wi-Fi, DSL, digital TV and DAB radio, scaled down to fit inside a single SSB channel. Which messages travel this way is decided in Chapter 15.

12.1 Why many slow carriers

On HF the same signal arrives several times, a few milliseconds apart, because it reaches the receiver by more than one path (Chapter 3). Those echoes are harmless to a slow signal and ruinous to a fast one. If each symbol (the smallest unit a modem puts on the air: one tone, one phase, one "letter") lasts 1 ms and the second copy arrives 3 ms late, every symbol is smeared across the three that follow it. If each symbol lasts 25 ms, the same echo only muddies the first eighth of it, and the receiver can simply look at the rest. So the fix for echoes is to go slow, and the cost is obvious: a single slow carrier moves very few bits per second.

12.1.1 Slow, but many at once

OFDM keeps the slow symbols and gets the speed back by running many carriers side by side. Each carrier is an audio tone at its own frequency, changing its phase only once per symbol. Any one of them is sluggish, but 24 of them carrying data at the same time move 24 times as many bits. The slow symbols make the signal robust against echoes; the parallelism makes it useful.

The alternative would be one fast carrier. To match the bulk modem's 1,800 bits per second, a single QPSK carrier would need symbols about 1.1 ms long, shorter than the echo spread of many HF paths, and the receiver would need an adaptive equalizer that learns and cancels the echoes as they change: complex, hungry for training signals, and prone to losing track in fast fading. OFDM avoids the problem instead of fighting it. What makes it practical is two tricks that the rest of this chapter unpacks: the carriers are packed so tightly that their spectra overlap and yet do not interfere (the "orthogonal" part), and one fast Fourier transform builds or separates all of them at once.

12.2 One FFT makes all the carriers

12.2.1 The FFT in one paragraph

The FFT (fast Fourier transform) is an algorithm that takes a short stretch of audio samples and tells you how much of each frequency is in it, and at what phase. Feed it 256 samples and it returns 256 "bins", each one a frequency slot with an amplitude and a phase. The inverse FFT (IFFT) goes the other way: give it the amplitude and phase you want in each bin, and it hands back the 256 audio samples that contain exactly those tones.

That is the whole transmitter in miniature. To send one OFDM symbol, the modem writes the phase it wants on each carrier into the matching bins, leaves every other bin at zero, and runs one IFFT. Out comes a stretch of audio that is the sum of all the carriers, each at its chosen phase. The receiver does the reverse: one FFT over the same stretch of audio, then it reads the phase in each carrier's bin. No bank of 28 oscillators and 28 filters is needed.

12.2.2 256 points at 12 kHz

At 12,000 samples per second, a 256-point FFT covers a window of 256 samples, or 21.33 ms, and the spacing between neighbouring bins is the sample rate divided by the FFT size:

12,000 Hz ÷ 256 = 46.875 Hz

Each carrier sits in its own bin, so the carriers are 46.875 Hz apart. The design aimed for round 50 Hz spacing, which would need a 240-point FFT; the fast FFT wants a power of two, so the size rounds up to 256 and the spacing tightens slightly.

12.2.3 Orthogonality: overlapping but not interfering

A tone that lasts exactly one FFT window does not occupy a single thin line in the spectrum. Because it starts and stops, its spectrum spreads into a hump with ripples on either side (the shape is called a sinc). With carriers only 46.875 Hz apart, those humps overlap heavily. So how can the receiver tell them apart?

The answer is the spacing itself. When the carrier spacing is exactly one divided by the window length (1 ÷ 21.33 ms = 46.875 Hz), every carrier's sinc crosses zero precisely at the centre frequency of every other carrier. When the receiver's FFT measures bin 7, it sees carrier 7 at full strength and all the other carriers at exactly zero. Two signals that can be added together and then separated perfectly like this are called orthogonal.

carrier 1 carrier 2 carrier 3 carrier 4 carrier 5 Each carrier peaks at its own frequency (black dot) where every other carrier is exactly zero (open dot) spacing = 12000 / 256 = 46.875 Hz = 1 / (21.33 ms FFT window)
Figure 12.1. Five neighbouring carriers' spectra overlap heavily, yet each one peaks exactly where all the others pass through zero. That is what lets an FFT read each carrier without interference from its neighbours.

Orthogonality is fragile in two specific ways, and the rest of the modem is largely built to protect it. It needs the FFT window to line up with a symbol that is steady for the whole window (the job of the cyclic prefix, below), and it needs the carriers to land on their bins, so the two stations' frequencies have to be close to each other (Section 13.10).

12.3 28 carriers: 24 for data, 4 pilots

The bulk modem uses 28 carriers. Before being shifted up into place they occupy FFT bins 1 through 28; bin 0 (zero frequency) is left empty, as are all the bins above 28. After the shift described in Section 12.7, the 28 carriers run from 1,617 Hz to 2,883 Hz, centred on 2,250 Hz. Every figure in this chapter is fixed, never negotiated between stations, and all of them are collected in Appendix A.

Four of the 28 are pilots. A pilot carries no data at all. It sends the same known value, a fixed phase, in every symbol, so the receiver can compare what arrived with what it knows was sent and work out what the path did to that part of the spectrum. The pilots are the 4th, 11th, 18th and 25th carriers counting up from the bottom (1,758, 2,086, 2,414 and 2,742 Hz): seven carriers apart, with three data carriers outside each end pilot and six between each pair of pilots. The other 24 carriers carry data.

One channel's audio passband (0 to 3 kHz) 0 500 1000 1500 2000 2500 3000 Hz emergency announce (3 channels) bulk OFDM P P P P 1617 2250 (centre) 2883 28 carriers, 46.875 Hz apart: 24 data (filled) + 4 pilots (open, P) at 1758, 2086, 2414 and 2742 Hz
Figure 12.2. Top: where the bulk modem sits in one channel's audio passband. Bottom: the 28 carriers. The four pilots (open bars, marked P) sit evenly among the 24 data carriers so every data carrier is at most three carriers from a pilot.

12.3.1 Two bits per carrier

Each data carrier, in each symbol, takes one of four phases, which is two bits. This is QPSK, the modulation the announce modem uses on its single carrier, and Chapter 11 explains it. Here the four phases are 45°, 135°, 225° and 315°, all at the same strength, and the two bits are assigned so that the first chooses left or right of centre and the second chooses up or down, independently. That lets the receiver judge each bit on its own axis: how far right or left the point landed says how sure it is of the first bit, and how far up or down says how sure it is of the second.

With 24 data carriers at two bits each, one OFDM symbol carries 48 bits.

12.4 The cyclic prefix

Slow symbols make echoes small, but not zero. An echo of symbol 1 that arrives 3 ms late still spills 3 ms into the start of symbol 2. If the receiver's FFT window covered that spill, the window would contain the tail of one symbol glued to the head of the next, the carriers would not be steady tones across the window, and orthogonality would break: every carrier would leak into its neighbours.

The fix is to put a buffer in front of each symbol and have the receiver ignore it. mLink's buffer is the cyclic prefix: a copy of the last 64 samples of the symbol, stuck on the front. The transmitted symbol is therefore 64 + 256 = 320 samples long, 26.67 ms, and the receiver takes its 256-sample FFT window from the last 256 of those. At 37.5 symbols a second and 48 bits a symbol, that is 1,800 bits per second before error correction.

CP symbol 1 body copy of the last 64 samples CP symbol 2 body copy of the last 64 samples echo direct late copy of symbol 1 late copy of symbol 2 the receiver's 256-sample FFT window for symbol 2 spill CP 64 samples = 5.33 ms | body 256 samples = 21.33 ms | symbol 320 samples = 26.67 ms
Figure 12.3. Each symbol carries a copy of its own last 64 samples in front (CP). A late echo of symbol 1 spills into symbol 2's prefix, which the receiver throws away; its FFT window sees only symbol 2.

12.4.1 Why a copy, and not silence?

A stretch of silence would also give echoes somewhere harmless to land. The copy does something extra. The FFT treats its window as if it repeated forever. Because the prefix is the symbol's own tail, the echo of a symbol that arrives a little late still shows the FFT a complete, seamless cycle of every carrier: it is the same tones, just shifted in time, and a time shift is only a phase change on each carrier. So an echo shorter than the prefix does not smear the symbol at all; it just changes each carrier's amplitude and phase by some fixed amount. The pilots measure exactly that change and the receiver undoes it carrier by carrier.

The prefix is 5.33 ms, which covers the echo spread of most HF skywave paths. The price is time: one fifth of every symbol carries no new information (64 of 320 samples). mLink pays that for the robustness.

12.5 The cross-symbol interleaver

Fading on HF does not hit bits at random. A deep fade, a static crash or a brief burst of interference wipes out a stretch of time, and in OFDM a stretch of time is a group of whole symbols. Losing one symbol means losing all 48 of its bits at once. If those 48 bits sat next to each other in the codeword, the error-correcting code would face a dense hole in one spot, which is the hardest kind of damage for it to repair.

So before the bits go onto carriers, the bulk modem shuffles them with a cross-symbol interleaver. Picture a grid 48 rows tall and 203 columns wide. The codeword is written into it row by row; then each OFDM symbol takes one column, top to bottom. The 48 bits a symbol carries therefore come from 48 different rows: positions 203 apart in the codeword. When a symbol is lost, the receiver puts the bits back in order and the damage lands as 48 isolated doubtful bits spread evenly through the codeword, one every 203 positions. Scattered damage like that is exactly what the decoder is good at fixing.

write the codeword in rows ... ... send one column per OFDM symbol 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 row 1 row 6 this symbol fades out back in codeword order, the lost bits are scattered, one per row: real size: 48 rows (bits per symbol) x 203 columns (symbols per frame); lost bits land 203 apart
Figure 12.4. The cross-symbol interleaver, shrunk to 6 rows by 12 columns. The codeword fills the grid row by row; each OFDM symbol sends one column. When one symbol fades (dark column), its bits turn out to be spread across the whole codeword.

Why 203 columns? The codeword is 9,720 bits and each symbol carries 48, so a codeword needs 9,720 ÷ 48 = 202.5 symbols. The grid rounds up to 203 columns (9,744 cells), and the 24 spare cells at the end are filled with zeros that the receiver ignores. The error-correction layer has already applied a smaller shuffle of its own before the bits reach the modem (Chapter 9).

12.6 The bulk frame

A bulk frame is what the modem sends for one codeword of the bulk error-correcting code, LDPC (Chapter 9). It always has the same shape: one sync symbol of 320 samples, which the receiver uses to find the frame (Section 12.9), then 203 data symbols of 320 samples each. That is 65,280 samples, or 5.44 seconds. Frames in one burst follow each other with no gap, so frame i starts exactly i × 65,280 samples after frame 0.

The length never changes, because the codeword is 9,720 bits at every code rate: a stronger rate carries fewer message bytes in the same air time and never makes the frame longer. How many bytes each rate carries is tabulated in Appendix A, and which rate each frame of a burst uses is in Chapter 15.

12.7 The transmit path, step by step

Here is what happens to one frame's worth of codeword bits on the way to the radio.

  1. Cross-symbol interleave. The 9,720 codeword bits, plus 24 zeros, go into the 48 × 203 grid and come out column by column.
  2. Map to carriers. For each of the 203 symbols, the next 48 bits are taken two at a time and turned into QPSK points, one per data carrier, lowest carrier first. The four pilot bins get their fixed known value. Every other bin is zero.
  3. IFFT. One inverse FFT turns the 256 bins into 256 audio samples: the sum of all 28 carriers for that symbol.
  4. Add the cyclic prefix. The last 64 samples are copied to the front, giving the 320-sample symbol.
  5. Shift up to the bulk region. Straight out of the IFFT the carriers sit between 47 Hz and 1,313 Hz. The whole block is shifted up by 1,570.3 Hz so its centre lands on 2,250 Hz.
  6. Filter. Each OFDM symbol starts and stops abruptly, and those edges splash a little energy outside the carriers (the ripples of the sinc shapes in Figure 12.1). The modem removes everything outside 1,594 to 2,906 Hz so that none of it falls into the announce channels (Section 8.8).
  7. Level. The result is scaled to the same average power as every other mLink modem produces, and the sync symbol, generated separately and brought to the same level, is placed in front.

12.7.1 Audio in, audio out

Internally the modem works with complex signals: each sample has an in-phase and a quadrature part, which is what lets a carrier have a phase that the FFT can read. What goes to the radio, though, is ordinary audio. The transmitter keeps only the real part of the finished signal, and the receiver rebuilds the complex form with the pre-filter described below. Nothing in the bulk modem needs an IQ interface to the radio.

12.8 The receive path, step by step

Once the receiver has found where a frame starts (Section 13.8), the modem's job is to turn 5.44 s of audio back into 9,720 soft bits. It runs the transmit path in reverse, with two extra stages that do the heavy lifting: estimating what the path did to each carrier, and deciding how much to trust each bit.

12.8.1 The pre-filter

The whole frame, sync symbol included, first goes through one large FFT. Everything outside 1,594 to 2,906 Hz is thrown away, which removes the emergency and announce regions and any noise outside the bulk region; and the negative-frequency half of the spectrum is discarded, which turns the real audio back into the complex signal the rest of the receiver needs. An inverse FFT brings it back to the time domain. The sync symbol rides along at the front to give this filter something to settle on, so the first data symbol is clean.

12.8.2 One FFT per symbol

For each of the 203 data symbols, the receiver skips the 64-sample prefix, shifts the remaining 256 samples back down by the same 1,570.3 Hz the transmitter added, and runs a 256-point FFT. Bins 1 to 28 now hold one received value per carrier: an amplitude and a phase, bent by the path and sprinkled with noise.

12.8.3 Channel estimation from the pilots

HF does not treat the whole 1.3 kHz of the bulk region the same. Echoes create notches: frequencies where two copies of the signal arrive out of phase and cancel. One carrier may come in strong and nearly on its original phase while another, a few hundred hertz away, comes in weak and rotated by 90°. Before the receiver can read any QPSK point it has to know, for each carrier, how much the path shrank it and how far it turned it. That knowledge is the channel estimate.

The pilots provide it. Each pilot was sent at a known value, so whatever arrives in a pilot bin is the path's effect at that frequency, plus noise. That gives four measurements per symbol. For the carriers in between, the receiver assumes a straight line: a carrier two-sevenths of the way from one pilot to the next gets a blend of five-sevenths of the first pilot's reading and two-sevenths of the second's. The three carriers outside each end pilot simply borrow that pilot's reading.

strong weak 1 4 11 18 25 28 carrier number (1 to 28) dashed: what the path really did | diamonds: pilot readings | solid: the estimate
Figure 12.5. How strongly the path passes each of the 28 carriers in one symbol. The receiver sees only the four pilot readings (diamonds) and joins them with straight lines. Where the true response curves between pilots, the estimate is off, and the next step accounts for that.

The estimate is made fresh for every symbol from that symbol's own pilots. A path that changes from one symbol to the next (a fade rolling through, the phase drifting because the two radios are a few hertz apart) is followed symbol by symbol, 37.5 times a second.

12.8.4 Equalization and weighted soft bits

With an estimate for each carrier, the receiver can undo the path: rotate each received point back by the estimated phase and scale it back up by the estimated loss. That step is called equalization. The naive version divides by the estimate outright, which works beautifully on strong carriers and terribly on weak ones: a carrier sitting in a notch has been shrunk to almost nothing, and dividing by almost nothing multiplies its noise enormously. The result is a confident-looking point in a random place.

mLink uses an MMSE (minimum mean-square error) equalizer instead. It adds a noise term to the division, so a carrier's correction is scaled back as its strength approaches the noise level. A strong carrier is corrected almost exactly; a carrier buried in a notch is left small instead of being blown up.

The noise term has to come from somewhere, and again the pilots supply it. If the path were perfectly flat, the four pilot readings would be identical, and any scatter between them would be pure noise. The receiver takes that scatter as its noise estimate. On a path that is not flat, some of the scatter is the path's own shape, so the estimate comes out too high, which only makes the equalizer more cautious, never less. The noise estimate is smoothed across symbols (each new symbol contributes a fifth of the running value), kept within fixed upper and lower bounds, and started afresh at the beginning of every frame so one frame's conditions cannot leak into the next.

Then the soft bits: the per-bit confidence numbers that Chapter 9 calls LLRs and feeds to the decoder. For each data carrier, the equalized point's horizontal position becomes the first bit's value and its vertical position the second's. The sign says which way the bit leans; the size says how sure. Before handing them on, the receiver multiplies every carrier's pair by a weight that depends on how strong that carrier was: a carrier in a deep notch gets its soft bits shrunk twice over, once because it is weak and once more by the equalizer's caution. The decoder therefore hears strong carriers loudly and faded carriers as a mumble. The values are finally clipped to the range −127 to +127 so each fits in one byte.

12.8.5 Undoing the interleaver

The 203 symbols yield 9,744 soft bits. The receiver writes them into the 48 × 203 grid column by column and reads them out row by row, restoring codeword order; the 24 filler values at the end are dropped. The remaining 9,720 soft bits go to the decoder.

12.9 The sync symbol

Everything above assumes the receiver knows, to within a few samples, where each symbol starts. If its FFT window is misplaced by more than the part of the prefix that the echoes have left clean, symbols bleed into each other and the frame is lost. So each bulk frame begins with one extra OFDM symbol whose only job is to be found.

12.9.1 A symbol that repeats itself

The sync symbol is built in the style of a well-known method published by Schmidl and Cox (the Schmidl-Cox preamble). Instead of data, it carries a fixed pattern of +1 and −1 on the even-numbered bins only (2, 4, 6 … 28: fourteen carriers), with every odd bin empty. Using only every second bin has a neat consequence in time: the 256-sample symbol consists of the same 128 samples played twice. It is scaled so its power matches the data symbols, and it has a cyclic prefix like any other symbol, so it is also 320 samples long.

That shape gives a receiver three things:

The repetition test alone is not enough to trust: any OFDM symbol repeats itself somewhat, because it carries a copy of its own tail in its prefix, and a steady tone repeats perfectly. How the receiver combines the three, and why it only looks for a bulk frame where an RTS (request to send) has told it to expect one, is in Section 13.8.

12.10 What to remember

Chapter 13

The Receiver: Always Listening

13.1 Why listen to everything, all the time

On one channel, at one moment, there may be an emergency call at the bottom of the passband, short frames on two announce channels, and a bulk transfer up top. Any of them might concern this station, and a distress call must never be missed because the station was "busy" hearing something else.

So the receiver has no notion of "busy". It keeps a continuous recording of the audio and runs three independent searches over it, one for each region, on every fresh slice of sound. Finding a frame in one place never stops the search anywhere else.

13.2 The recording

Audio arrives from the sound card in blocks of 512 samples (about 43 ms) by default. Every sample is written into a capture ring: a circular recording 524,288 samples long, about 43.7 seconds, in which the newest sample overwrites the oldest. Every sample also gets an absolute position, a counter that only ever counts up, so a detection, the frame it belongs to and the moment that frame's last sample will arrive are all numbers on one timeline.

For every block the receiver does the same four things, in this order:

  1. Write the block into the ring.
  2. Hand over any frame that is now completely recorded to a decoder.
  3. Run the three detectors over the most recent stretch of the ring.
  4. Measure the overall audio level (Section 13.11).
sound card 512-sample blocks capture ring 524,288 samples about 43.7 s emergency detector 125โ€“175 Hz sweep announce detector four channels bulk detector only when an opener arms it tentative detections wait for the whole frame, then copy out to a decoder worker two decoder workers then on to the protocol
Figure 13.1. What happens to each block of audio. The detectors only read the ring; they never block each other, and none of them ever stops the others from looking.

13.3 Three detectors, three kinds of sync

Every mLink frame starts with a short, known waveform whose only job is to say "a frame starts here": a preamble, also called a sync. Each region has its own. Because the receiver knows exactly what each preamble looks like, it can search for it with a matched filter.

Picture a transparent strip with the preamble's waveform printed on it. Slide it along the recording and, at each position, multiply the strip by the recording under it point by point and add everything up. Where the recording is just noise, the products are as often negative as positive and mostly cancel. Where the preamble really is under the strip, every product is positive and they pile up. That sum is the detector's score at that position, and a real preamble shows up as a sharp peak. The longer the preamble, the more products pile up, which is why a long preamble can be found under a lot of noise: this is the matched filter's processing gain.

Table 13.1. The three detectors. "Checks every" is how finely the first search steps along the recording before it refines a hit.
EmergencyAnnounceBulk
Listens to115โ€“185 Hz 150 Hz either side of each announce channel; 135 Hz either side of the bulk-control channel1,500โ€“2,900 Hz
PreambleA rising sweep, 3,840 samples (0.32 s) Four QPSK symbols, 1,202 samples (0.10 s) One OFDM symbol in two identical halves, 320 samples (0.027 s)
Checks every48 samples (4 ms) 30 samples (2.5 ms)Every sample, where a frame is expected
When it runsAlwaysAlways Only while a heard opener has promised a burst

13.3.1 The emergency detector

The emergency preamble is a smooth sweep across the whole emergency region (Chapter 10 says why). Matched against a copy of itself it gives a peak only about 20 ms wide, sharp enough to say where a ten-second frame starts.

The region is only 50 Hz wide, so 12,000 samples a second is far more detail than it needs. The detector removes everything above about 200 Hz, keeps every eighth sample, and narrows that copy to 115โ€“185 Hz: eight times cheaper, with nothing lost. When a score passes the tests below, the detector goes back to the full recording and searches again, every other sample within 4 ms either side of the hit. That second pass matters most at the weakest signals: the weaker the signal, the less misalignment the emergency demodulator tolerates, and a whisper of a call decodes only if the start is right to within a few milliseconds.

13.3.2 The announce detector

The announce detector watches four channels at once: the three announce channels and the bulk-control channel, which carries the same kind of frame. It turns the newest stretch of the recording into a spectrum once, shares that work across all four, and with one more Fourier transform per channel has the score at every position. It looks at every 30th position for a peak and, when one passes the tests, re-examines every position within 30 samples of it to land on the best one.

To read a QPSK symbol the decoder has to know the carrier's phase, the exact point in its cycle the carrier is at. The preamble's peak gives that phase as well as the position, and the detector passes both on. Get the position wrong and the phase comes out wrong too: every sample of error turns it by 12° on the 400 Hz channel and 36° on the 1,200 Hz channel, and at 45° a symbol sits on the edge between two values, so the frame decodes to confident garbage. That is why the detector refines its hit to the single best sample.

13.3.3 The bulk detector

The bulk detector does not run at all unless the station has just decoded an opener announcing a bulk burst, normally an RTS (request to send). A bulk frame is never valid without an opener in front of it, so not looking means a stray bit of noise can never pretend to be one. The price is plain: a station that missed the opener will not hear the burst behind it. Section 13.8 has the details.

13.4 How loud is "there"? Adaptive thresholds

A score on its own means nothing: the same number might be a clear signal on a quiet night and pure noise at noon on a crackling band. So the emergency and announce detectors compare every score against the scores they have recently seen when nothing was there.

Radar engineers call this CFAR, constant false alarm rate: decide how often you are willing to be fooled by noise, then keep moving the bar so that noise alone clears it about that often. If the band gets noisier the bar rises; if it goes quiet the bar drops, and weaker real signals become findable.

Each detector keeps a rolling memory of its recent noise scores: the last 512 for the emergency detector and the last 4,096 for each channel of the announce detector. From the average of that memory it estimates how widely noise scores spread, and sets the threshold at five times that spread.

time score threshold real preamble quiet band band gets noisier
Figure 13.2. A noise-relative threshold. When the noise rises the bar rises with it, so noise alone never clears it; a real preamble still towers over both. (Sketch, not measured data.)

Three pieces of housekeeping keep that memory honest.

Until a detector has collected 64 scores it uses a cold-start bar instead, set from the noise level in its region: a slow running average that follows only readings no more than 6 dB above it, so a burst of signal cannot drag it upward.

13.4.1 How weak a signal each detector finds

Measured through the whole receive path, one frame at a time in steady noise, the emergency detector finds about 97% of frames at −15 dB (SNR@3k), 86% at −16, 69% at −17, 51% at −18 and 34% at −19. A frame that has been found and lined up still decodes 98% of the time at −17 dB. So at the emergency floor it is the detector, not the decoder, that decides whether a single frame gets through; the distress service's repeats cover what one look misses (Chapter 10).

For announce frames it is the other way round: the detector finds essentially every frame down to −9 dB, well below the −5 dB at which they stop decoding (Chapter 11).

13.5 The loud neighbour

Each region's threshold is tied to that region's own noise, which can be very low. Suppose a station a few kilometres away is running a bulk transfer at S9+20 while you listen for a faint emergency call. No filter is perfect: a tiny fraction of the bulk signal's energy leaks into the emergency region, and against that region's tiny noise level, multiplied by the matched filter's processing gain, the leak could score like a real preamble.

The dynamic-range guard stops that: every detector also requires its score to clear a second bar, one quarter of the loudness of all the audio, whatever region it is in. A real signal in your region clears that easily with the matched filter's gain behind it. A faint leak from somewhere else does not.

The guard only bites when the signal you want is enormously weaker than the loudest thing on the channel: roughly 37 dB for bulk, 43 dB for an announce frame and 48 dB for an emergency call. With no loud neighbour it changes nothing.

13.6 Deaf while you talk

mLink is half duplex (Chapter 3): while the station transmits, its receiver hears nothing useful. The receiver handles that in three ways.

13.6.1 Holding your own key while a frame comes in

The reverse case is a frame that is arriving when the station wants to transmit. A tentative detection on any of the announce detector's four channels or in the bulk region, or a frame already with a decoder, holds the station's ordinary transmissions back: genuine traffic is about to be decoded. A reply the station owes and a distress call are never held.

A tentative emergency detection holds nothing. Holding the radio for every false alarm of that sensitive detector would cost ten seconds of silence each time, and a real call repeats and is heard by the other stations in range as well. The rest of the decision to key is in Chapter 17.

13.7 From a hit to a decode

When a score clears both bars, the detector does not decode anything yet. It records a tentative detection for that channel: where the preamble starts, how good the score was, the phase (for announce) and an SNR estimate. Each channel has room for one.

13.7.1 Upgrading a detection

The detectors re-scan overlapping stretches of the recording every block, so the same preamble is seen several times as it slides through, sometimes only partly the first time. A new peak within one preamble length of the tentative one replaces it if it scores better: that is the same frame, better aligned. A peak somewhere else replaces it only if it is stronger. Two refinements keep this from going wrong on runs of frames.

13.7.2 Handing the frame to a decoder

On every block, before searching, the receiver checks each tentative detection: has the last sample of that frame arrived? Once it has, the whole frame is copied out of the ring and handed to a decoder worker, a separate thread that does the heavy demodulation and error correction without holding up the listening. A station runs two, so a bulk frame and an announce frame can be decoding at the same time. After the hand-over the receiver refuses to detect the same frame again as it slides through later searches.

13.8 Lining up on a bulk burst

A bulk transfer is a string of OFDM frames, each 5.44 seconds long, laid end to end with no gaps (Chapter 12). The bulk detector has to find each frame's start to within a sample or two, and make sure that one missing frame cannot throw off the rest.

13.8.1 The opener arms the search

A bulk transmission has the shape [presence][rts][bulk 0][bulk 1].... The RTS says how many frames are coming and the highest code rate they will reach, and its own position in the recording says where they will be: frame 0 starts 150 ms (1,800 samples) of silence after the RTS ends, and every later frame follows at a fixed stride. So a decoded RTS gives the receiver a predicted start for frame 0 and a frame count, and the bulk detector searches around the predicted starts and nowhere else. The opener of a repair burst, or of a later segment of a long transfer, arms it the same way. Once the burst's air time has passed, the arming lapses.

Around a predicted start the detector first asks two cheap questions. Is the bulk region at least 3 dB louder than its usual noise? And does the audio repeat itself half a symbol later, as the bulk preamble does (Section 12.9)? Only then does the matched filter look for the exact start, at the positions the prediction allows. The result must clear the loud-neighbour guard and a bar set from the bulk region's noise level. The bulk detector keeps no rolling memory of scores, because while a burst is expected nearly everything it sees is signal; its noise level is refreshed from the announce region's at the moment of arming.

13.8.2 Frame 0 first, and it must really be frame 0

Frame 0 is the anchor for every other frame's position, and the rest of the message cannot be checked without it (Chapter 15). So the detector insists on finding it first:

The station does not need the silence as time to get ready. An RTS has to be recorded to its last sample and then decoded before the search can be armed, and on a busy station that can take longer than the silence lasts. If the search is armed more than about 0.2 seconds after frame 0 was due to begin, the receiver waits until the whole of frame 0's search window has been recorded and searches it once, straight from the ring, with the same tests except the loudness question.

If frame 0 has still not been found by the time it would have finished arriving, plus 16,384 samples (about 1.4 seconds), the detector stops looking for this burst altogether and nothing of it is decoded. A station that was only overhearing lets it go. The station a directed transfer was addressed to still answers when the burst should have ended, with a dNAK (the reply that lists missing frames) naming every frame; Chapter 16 says what the sender does with it.

13.8.3 Every other frame at an exact stride

When frame 0 is found, its true position replaces the prediction. From then on frame i can only start at that position plus i times the frame length (65,280 samples), and the detector searches only 64 samples (5.3 ms) either side of that spot. The two stations' sound cards run at very slightly different speeds, but over a burst the drift is a handful of samples at most.

P RTS 150 ms frame 0 (1/2) frame 1 faded out frame 3 frame 4 wider search, coherence test narrow searches at exact multiples of 5.44 s frame 2's narrow window finds nothing: its slot stays empty, frames 3 and 4 are still found in the right place and decoded at the right rate
Figure 13.3. Frame 0 is searched for in the wider window and must pass the coherence test; after that, each later frame is looked for only at its exact predicted start. (Not to scale: the silence is 150 ms, each frame 5.44 s.)

The narrow search is what makes a missing frame harmless. If a fade wipes out frame 2, its window contains no preamble and slot 2 stays empty. The receiver never goes looking a few thousand samples away, so frames 3 and 4 are found exactly where they should be, and the sender is asked to repeat only frame 2 (Chapter 16).

Position also tells the decoder the frame's code rate, which follows from its place in the burst (Chapter 15). The receiver works out that place from where the preamble landed relative to frame 0, not by counting frames as they arrive, so a missing frame cannot make it decode the next one at the wrong rate.

13.9 Signal reports: the SNR estimate

Every emergency and announce detection comes with an estimate of how strong the signal was. The matched filter's peak says how strongly the preamble was heard; a noise reference says how strong noise looks through the same kind of measurement. Their ratio, in decibels, rises one-for-one with the real SNR but includes the matched filter's processing gain, so each detector subtracts a fixed correction, set on simulated air with a precisely known SNR.

When a frame decodes and names its sender, the reading goes into that station's link estimate (Chapter 18).

13.10 Frequency offset

Two rigs set to the same dial frequency are never exactly on the same frequency, and the difference shifts every tone in the audio by a few hertz. The bulk preamble lets the receiver measure that shift. Its two halves are identical when sent, so any rotation of phase between them, as received, can only come from a frequency offset. The measurement is unambiguous up to about 47 Hz either way. The announce and emergency detectors measure no offset.

Where the station has CAT control of a rig that supports RIT (receiver incremental tuning), it runs a slow correction loop instead. Each decoded bulk frame's offset is averaged in, the newest counting for a quarter; when the average drifts beyond 10 Hz the station nudges the rig's RIT the opposite way, no more often than once every two seconds. Announce and emergency frames are left out, because a reading of "no measurement" from them would pull the average toward zero. The loop therefore moves only when bulk traffic keeps showing a sustained drift.

13.11 A quick ear for the key-up decision

A detector needs most of a preamble, up to a few tenths of a second, before it can say anything. That is too slow for the question the station asks before every key-up: is anyone on the air right now? So for every block of real audio the receiver also compares the overall level with a floor that drops quickly in quiet stretches and rises only slowly (Chapter 17).

13.12 What to remember

Part IV: Talking on the Air

Chapter 14

The Transmission Is the Unit

14.1 One press of the key

In mLink a transmission is exactly one push-to-talk (PTT) turn: the radio keys, a run of frames goes out back to back, and the radio unkeys. Nothing about a transmission is spread across two key-ups.

That sounds obvious, but it is a real design decision, and much of the protocol leans on it. The receiver does not treat the passband as a stream of loose frames to be sorted out later. It treats each keyed burst as a unit and reads the middle in the light of the beginning. The rest of this chapter is about that beginning.

14.1.1 How long a transmission is

Transmissions are built from two kinds of frame. Control and short data travel in announce frames: each is on the air for about 640 ms, and the frames of one transmission are separated by a silent gap of about 21 ms, so every extra frame costs about 662 ms of air (Section 11.7). Large data travels in bulk frames of 5.44 s each (Chapter 12).

A short exchange is therefore short. An acknowledgement is two announce frames, about 1.3 s of transmitter time. A bulk transfer opens with two announce frames, pauses for 150 ms, and then sends its bulk frames end to end. One transmission carries at most ten bulk frames, about 54 s; a bigger message goes out as a series of such transmissions (Section 16.7).

one PTT turn (not to scale) key up key down bulk-control PRESENCE RTS 21 ms gap bulk 150 ms bulk 0 bulk 1 bulk 2 640 ms each 5.44 s each, back to back
Figure 14.1. One bulk transmission, written [presence][rts][bulk 0][bulk 1][bulk 2]. The two announce frames go out on the bulk-control channel (Section 8.5.1); 150 ms after the RTS ends, the bulk frames follow in the bulk region. It is all one keying of the transmitter.

14.2 PRESENCE goes first

The first frame of every ordinary mLink transmission is a PRESENCE frame. It is one announce frame, and it says three things:

A PRESENCE on its own is a complete transmission: that is what a beacon is, a station keying up for one frame just to say "here I am". Everything else the station sends is PRESENCE plus whatever it actually came to say.

14.2.1 The gateway flag

The locator does not need all of the four bytes it is given. Packed as one number it takes 25 of the 32 bits. The other seven are flags about the station itself: three are in use and four are spare (Section B.5).

The one that matters most is the first of them, the gateway flag. A station sets it while it can reach its mail server over the internet: the server is configured, the station is registered with it, and the last successful contact was less than ten minutes ago. A station that is part of a cluster (Chapter 31) also sets it when another member of the cluster can reach the server on its behalf.

Because the flag rides in every PRESENCE, every station within earshot learns who the gateways are at no cost in air time, and a gateway whose internet link drops simply stops setting the bit. What stations do with that knowledge is the business of Chapter 24. The other two flag bits belong to Chapter 32.

14.2.2 No traffic under a placeholder callsign

The station will not transmit without a real callsign. If the configured callsign is empty, is the placeholder N0CALL, or is not a valid amateur callsign, the station refuses to send, beacon or report its position, and the client shows an error until one is set. The one thing allowed out regardless is a distress call (Chapter 23): a call for help under the wrong name beats silence.

14.2.3 Where PRESENCE is not the first frame

Three kinds of signal are built differently.

14.3 The type byte and the frame families

Every frame on an announce channel, and on the bulk-control channel, is the same physical object: eleven bytes, which the announce modem protects with twelve more and sends as one frame (Section 11.5). There is no separate "data frame", "reply frame" or "relay frame" format. A PRESENCE, an acknowledgement and a slice of a text message are all announce frames; only the meaning of the eleven bytes changes.

The first of the eleven is the type byte, and it says what the other ten mean. It is split into two halves of four bits each:

Written in hexadecimal the two halves read straight off the byte: 0x21 is family 2, subtype 1, which is an RTS; 0x01 is family 0, subtype 1, a PRESENCE from a station with an operator present. That is how the kind of a PRESENCE costs no data byte: it is the subtype.

type 10 data bytes 12 parity bytes 11 bytes: what the protocol sees added by the modem family subtype high 4 bits low 4 bits 0x21 = 0010 0001 family 2 (transfer control), subtype 1 (RTS)
Figure 14.2. The anatomy of an announce frame. The two halves of the type byte name the family and the subtype.

Four bits give room for sixteen families of sixteen frames each. Nine families are in use:

Table 14.1. The announce frame families
FamilyNameWhat it is forExplained in
0x0PRESENCE"It's me": callsign, grid and status, plus the start-up and geopoll questions and answers.this chapter; Chapter 18
0x1RELAYMessages one station holds for another: recruiting a relay, mail custody and pickup, and repeating a heard distress call.Chapter 19, Chapter 24, Section 23.7
0x2BULKControl of every data transfer, large or small: announcing it, answering it, repairing it, continuing it, cancelling it. Also the one-frame request for internet data.Chapter 15, Chapter 16, Section 27.4
0x3SHORTBURSTThe data frames of a message small enough to ride in announce frames. The low half of the type byte is the frame's position, not a subtype.Section 15.2
0x4APRS (Automatic Packet Reporting System)A precise position report.Section 28.2.1
0x5GEOThe circle that a transfer to an area is aimed at.Section 28.4
0x6HELLO"I recently heard this station": one line of the sender's heard list.Section 18.7
0x7ANCHORVirtual nets: net control's regular anchor, the roster, joining, the roll call and its tally, and the owner's instructions.Section 22.2
0x8TIMEA shared time reference.Chapter 32

Families 0x9 to 0xF are unassigned. The BULK family is named for the bulk transfer it was built around, but it controls shortbursts too, for a plain reason: the SHORTBURST family spends its subtype half on the frame's position and has no room left for control frames.

This chapter stops at the families. What each frame is for, and where every field sits in it, is listed once, in Appendix B.

Two consequences of the fixed eleven bytes run through the whole protocol. A frame that needs fewer bytes is padded with zeros and costs exactly as much air as a full one, so nothing in mLink saves bytes by leaving a field out. And anything that needs more than eleven bytes is split across several announce frames in the same transmission.

14.4 What follows the PRESENCE

After the PRESENCE comes the reason for keying up. Written in the bracket notation this book uses, a transmission is a frame chain: the frames in the order they go out, such as [presence][ack]. Most chains have the same three-part shape:

  1. PRESENCE, always.
  2. Optional followers: frames that add something without ending the chain. HELLO frames, a position report, an AREA frame naming the circle a message is aimed at, a FOR frame naming the original sender of a relayed message, the manifest of a longburst, the pieces of a repeated distress call and most named-net frames are followers.
  3. One opener: the frame that says what this transmission is for. An RTS (request to send) announces a bulk transfer, an SB-RTS announces a shortburst, an ACK or dNAK answers someone else's transfer, a relay or mail frame asks or answers a question. Data frames, if any, come after the opener.

Not every chain has an opener: a beacon that carries a few HELLOs, or a position report, is PRESENCE and followers and nothing else. When a transfer does carry followers, they sit between the PRESENCE and the opener in a fixed order. Three chains show the range:

In practice most transmissions are two or three announce frames before any data starts. The chains seen most often on the air are tabulated in Section B.3.

14.5 Who said this? Binding by timing

Here is the payoff for putting PRESENCE first. Almost none of the frames that follow it carries a callsign. So how does a listener know who sent them?

It knows by timing and position, the same way you know who is talking on a voice net: the voice that just gave its call is the voice that is still talking. mLink calls this temporal binding. For each announce channel it listens to, the receiver remembers the most recent PRESENCE it decoded there and when. A frame that arrives on the same channel shortly afterwards is taken to be from that station.

14.5.1 The freshness window

"Shortly afterwards" has a precise value. The next frame of a chain is due one frame plus one gap later, about 662 ms. The receiver allows twice that, 1.32 s, for decode delay and timing jitter. This is the freshness window, and it is measured from the last frame that kept the chain going, not from the PRESENCE itself. Each follower restarts the clock, so a chain with several followers is just as safe as one with none.

The rules the receiver applies are short:

14.5.2 Followers must also be on the beat

The window alone would let a stranger in. Suppose station B's transmission ends, and half a second later station F's begins on the same channel, but F's PRESENCE is lost to a fade. F's next frame arrives inside B's window, and would be credited to B.

For followers that say something about their sender (a HELLO, a position report, a named-net frame, a piece of a repeated distress call) the receiver therefore checks one more thing. A transmitter sends the frames of a chain at an exact, fixed spacing, and the receiver knows, to the audio sample, where each frame it decodes began. A follower that starts a whole number of frame spacings after the bound station's last frame is credited to that station. One that is off the beat, by more than a sample plus the small drift between two sound cards' clocks, belongs to somebody else and is left without a sender; a HELLO or a net frame with no sender is discarded.

Each of the three announce channels keeps its own binding, and so does the bulk-control channel, which carries the PRESENCE, RTS and replies of bulk transfers. One channel can be in the middle of receiving a shortburst while another carries a different station's ACK; the two never cross.

channel 0 channel 1 PRESENCE W1AW ACK "W1AW acknowledges" PRESENCE K6MQI RTS "K6MQI wants to send" time
Figure 14.3. Each channel keeps its own binding. The ACK on channel 0 is credited to W1AW and the RTS on channel 1 to K6MQI, even though the two chains overlap in time.

14.5.3 Binding the data frames

Shortburst frames follow their SB-RTS on the same channel, and belong to the reception it opened until that reception closes.

Bulk frames are in a different part of the passband, so they are bound by the clock instead. The RTS says how many bulk frames are coming; they start 150 ms after the RTS ends and follow one another every 5.44 s. The receiver works out the expected arrival times from the moment it decoded the RTS, and a bulk frame that arrives on that schedule belongs to that RTS, and so to the station whose PRESENCE the RTS was bound to. Its place in the schedule also says which frame of the transfer it is (Section 16.3). How closely the receiver searches around each expected time is in Chapter 13.

14.5.4 The safety net under binding

Timing is a strong clue but not a proof. On a busy channel with stations that cannot all hear each other, a receiver could decode frames from two transmissions and join them. Two checks catch it. Every message carries a two-byte check value computed over the sender's callsign, the receiver's callsign and the message; the receiver recomputes it using the sender it bound by timing, and a message credited to the wrong station fails (Section 16.2). And a station waiting for a reply accepts it only from the station it sent to, on the channel the exchange used (Section 16.4.4).

14.6 Callsigns in six bytes

A callsign is written in a small alphabet: a space for padding, the digits, the letters, and the two marks callsigns actually use, the stroke / of a portable or visiting station and the hyphen - of a secondary station identifier. That is 39 symbols, so mLink writes each callsign as a number in base 39, the same idea the FT8 family uses. This is callsign packing.

The recipe:

  1. Convert the callsign to capitals.
  2. Pad with spaces to nine characters.
  3. Give each character a value: space is 0, the digits 0 to 9 are 1 to 10, the letters A to Z are 11 to 36, / is 37 and - is 38.
  4. Read the nine values as a nine-digit base-39 number, first character most significant, and store that number in six bytes, most significant byte first.

For example, W1AW becomes W 1 A W followed by five spaces, values 33, 2, 11, 33, 0, 0, 0, 0, 0, which works out to the number 176,932,451,189,169, stored as the bytes A0 EB 4B E7 01 B1. Every station does the same arithmetic, so every station unpacks the same six bytes back to W1AW.

Why nine? Six bytes hold a little over 281 trillion values, and nine base-39 characters need about 209 trillion, so nine is the most that fits. That covers every real callsign with its suffix: VE3XYZ/P, KH6/W1AW and KX0AAA-7 all go on the air whole and come back character for character. A received value too large to be nine characters is not a callsign, and the receiver rejects it.

14.7 Addressees that belong to nobody

Every frame that names a destination names it with a six-byte packed callsign. There is no other kind of address field. To send to more than one station, mLink uses reserved addressees: names that start with the digit 0. No licensed station can hold one, because no callsign series in the international allocation table begins with 0. One simple rule, "a leading 0 means not a station", covers all of them:

Table 14.2. The reserved addressees
AddresseeMeaningWhere it comes from
0CQCQCQEvery station that hears this. The universal amateur general call.
0CQQTHEvery station, with the attention of those inside a stated area. The area rides in an AREA frame just before the opener in the same transmission (Section 28.4).QTH, the Q-code for location.
0 + a net name, e.g. 0MARITIME The members of a virtual net (Section 22.7.1).The net's own name, up to eight characters after the 0.

A receiver treats a transfer addressed to any of them as addressed to itself: it receives and keeps the message. Neither the area nor the net is a filter on who may receive; each decides who gets alerted.

Because they are reserved, none of them is ever treated as a real station: a receiver never adds 0CQCQCQ to its list of heard stations or to its map of who hears whom. The two-byte message check still works for them. For a message to everyone, whether to 0CQCQCQ or to an area, it is computed with 0CQCQCQ standing in as the receiver; a message to a net is checked against the net's own addressee. Any listener can reproduce either.

14.7.1 Why there is no broadcast flag

The FCC's station identification rule for amateurs (47 CFR §97.119) asks a station to transmit its callsign at the end of each communication and at least every ten minutes during one, so that listeners know where the signal is coming from. Other administrations have similar rules.

mLink's reading is that PRESENCE satisfies this without any extra machinery. Every ordinary transmission opens with the station's own callsign, so the station identifies every time it keys, and no transmission lasts anywhere near ten minutes. The last transmission of any exchange (an ACK, say) is itself headed by a PRESENCE, so the end of the communication is identified too. The four named-net frames that go out alone carry the callsign inside the frame. The callsign is packed, not spelled out, the same posture FT8, JS8 and other modern digital modes take, and anyone running mLink software decodes it back to the plain callsign.

That is why there is no separate periodic identification and no Morse-code tail: the protocol already says who is transmitting, at the top of every transmission, as a side effect of how it binds its frames. It is also why the station refuses to transmit under a placeholder callsign: sending the wrong identity is exactly what the rule exists to prevent.

14.9 What to remember

Chapter 15

Three Sizes of Message

15.1 Why three sizes

mLink has two modems that can carry a message, and they are good at opposite things. The announce modem (Chapter 11) moves 10 bytes in each frame of about two-thirds of a second, and it still decodes at −5 dB SNR@3k. The bulk modem (Chapter 12) moves 603 to 1,008 bytes in each frame, but a frame always lasts 5.44 seconds however little is in it, and stations only trust it on a link of +6 dB or better (Section 9.7.3).

For a 40-byte text, a bulk frame would be nearly all padding. For a 5 kB mail, the announce modem would hold a shared channel for minutes. So there are three ways for a message to travel, and one rule table that picks.

Table 15.1. The three sizes. Air times are for the sending transmissions only, without the replies.
ShortburstLongburstBulk
Carries1 to 156 bytes157 to 601 bytes 1 to 64,004 bytes
Rides onOne announce channel One announce channel, up to 4 transmissions The bulk region
Frames1 to 16 announce frames 2 to 4 shortbursts1 to 64 bulk frames
Used on a link ofany strength under +6 dB, or unknown+6 dB or better
Air time2.0 to 11.9 s14.5 to 46.9 s 6.9 s for one frame, 5.44 s for each one more

All three work on the size of the message after it has been compressed and wrapped (Chapter 21). A chatty 300-character text may well compress into a shortburst.

15.2 Shortburst

A shortburst is a message sent as a string of ordinary announce frames, in one transmission, on one announce channel:

[presence][sb-rts][sb 0][sb 1]โ€ฆ[sb 15]

PRESENCE says who is sending (). The shortburst RTS (request to send) names the addressee, or a reserved "everyone" address for a broadcast, and carries the message's 16-bit check, which is also its name on the air (Section 16.2). Then come the data frames.

15.2.1 What is in the frames

An announce frame holds one type byte and 10 bytes of data. In a shortburst data frame, half of the type byte gives the frame's place in the message, 0 to 15. Four bits of position is why a shortburst is at most 16 frames long.

Frame 0 spends four of its ten data bytes on a header: the length of the message (2 bytes) and the check (2 bytes). That leaves 6 bytes of message in frame 0 and 10 in each later frame, so the largest shortburst is 6 + 15 × 10 = 156 bytes. The layouts are in Appendix B.

15.2.2 On the air

Frames follow each other every 0.66 seconds. A message of 1 to 6 bytes is three frames on the air, about 2.0 seconds. Every further 10 bytes adds one frame, and a full 156-byte shortburst is 18 frames, about 11.9 seconds. The RTS does not say how long the message is; frame 0 does, so a listener that has decoded frame 0 knows how many frames are still to come and keeps off that announce channel until they have passed (Chapter 17).

15.3 Longburst

Between 157 and 601 bytes there is an awkward gap: too big for one shortburst, and the path may be too weak for bulk. The longburst fills that gap and nothing else.

15.3.1 How it works

A longburst is one message sent as up to four shortbursts, each in its own transmission. The message is cut into pieces of 156 bytes (the last piece gets what is left), and each piece travels as a complete, addressed shortburst with its own RTS, its own check over just that piece, and its own acknowledgement.

The first transmission carries one extra frame right after PRESENCE, the longburst manifest. It says three things: the length of the whole message, the check for the whole message, and how many pieces are coming. Because the pieces are always cut at the same 156-byte boundaries, both ends work out from the total length which bytes belong in which piece, and no piece has to say which one it is.

[presence][manifest][sb-rts][sb 0]โ€ฆ[sb 15]  … reply …  [presence][sb-rts][sb 0]โ€ฆ  … reply …

The sender sends the next piece only after the addressee has acknowledged the one before. When the last piece is in, the receiver tests the whole message against the check from the manifest before it delivers anything.

15.3.2 Why it stops at 601 bytes

601 bytes is what one bulk frame carries at its most robust rate. The longburst is held to one bulk frame's worth on purpose: it is the stopgap for a weak link, not a way to move files over the announce channels. A full 601-byte longburst already costs about 47 seconds of sending, against 6.9 seconds for the same bytes as one bulk frame.

A longburst is always addressed to one station, because it leans on that station acknowledging each piece.

15.4 Bulk

A bulk transfer puts the message into the fast modem in the bulk region.

[presence][rts][bulk 0][bulk 1]โ€ฆ[bulk n]

PRESENCE and the RTS are announce frames sent on the bulk-control channel (Section 8.5.1). The RTS names the addressee and gives three numbers: how many bulk frames follow, the highest code rate they will reach, and the message's check. After 150 ms of silence the bulk frames follow back to back, 5.44 seconds each. From the start of PRESENCE to the start of frame 0 is 1.45 seconds, so a one-frame transfer lasts 6.9 seconds and every further frame adds 5.44.

The bytes that travel are the 2-byte check followed by the wrapped message, cut into frames in order. Nothing else is added: a bulk frame has no header of its own (Section 16.3).

15.4.1 The rate ladder

Every bulk frame is one error-correcting codeword of the same length, so every frame takes the same air time (Section 9.4). What can differ is the code rate: how much of the codeword is message and how much is protection. There are three rates. A frame at rate 1/2 carries 603 bytes, at rate 3/4 it carries 907, and at rate 5/6 it carries 1,008 (Appendix A has the table).

Which rate a frame uses is decided by its position in the transfer and by nothing else. This is the rate ladder:

With a ceiling of 5/6 the rates run 1/2, 3/4, 5/6, 5/6, 5/6 and so on. With a ceiling of 3/4 they run 1/2, 3/4, 3/4, 3/4. With a ceiling of 1/2 every frame is 1/2.

1/2 bulk 0 603 B 3/4 bulk 1 907 B 5/6 bulk 2 1,008 B 5/6 bulk 3 1,008 B 5/6 bulk 4 1,008 B 5/6 bulk 5 1,008 B 5/6 bulk 6 1,008 B 5/6 bulk 7 1,008 B Every frame: 5.44 s. Filled part = message, open part = protection. ceiling 5/6: held
Figure 15.1. The rate ladder across an eight-frame transfer with a ceiling of 5/6. Under each frame: the bytes it can carry.

From the ceiling and the frame count in the RTS a receiver knows, before the first bulk frame arrives, the rate of every frame, how many bytes each can hold and where they belong in the message. Nothing inside a frame says what rate it is.

15.4.2 Who picks the ceiling

The sender, and it uses only two values for a new transfer. A directed message that needs more than one frame, on a link the sender rates at +6 dB or better, gets a ceiling of 5/6. A message that fits in one frame gets 1/2 (it is frame 0 anyway), and so does every broadcast, which has no single link to judge by. The station tunes the ceiling no finer than that: a link is good enough for bulk or it is not. A ceiling of 3/4 only appears when lost frames are sent again (Section 16.5.2).

15.4.3 Why frame 0 is the most robust

The first frame matters more than any other, for two reasons. It is the frame the receiver fixes its timing on: every later frame is looked for at an exact distance from where frame 0 was found (Section 13.8.2). And its first two bytes are the check for the whole message, without which nothing that follows can be accepted. A receiver that does not find frame 0 decodes nothing of that transmission. So frame 0 always gets the strongest protection the code offers, whatever the ceiling, and the rates climb from there.

The climb costs no air time, only bytes: the first two frames of a transfer carry 506 bytes fewer than they would at 5/6. What happens when frame 0 is lost all the same is in Section 16.5.5.

15.4.4 How big it can get

A transfer is at most 64 frames, which is also the number of frames one reply can name as missing. With a ceiling of 5/6 that is 603 + 907 + 62 × 1,008 = 64,006 bytes, two of them the check: 64,004 bytes of wrapped message, and close to six minutes of sending. A single frame at rate 1/2 holds 601 bytes of message.

A transfer longer than 10 frames is sent in segments of 10, each its own transmission, and the addressee confirms what it has after each one (Section 16.7). A broadcast has nobody to confirm anything, so a broadcast is held to one segment at rate 1/2: 10 × 603 bytes less the check, 6,028 bytes of message.

15.5 How the station chooses

When you send, the station's transmission policy looks at a handful of facts and picks one of four answers: shortburst, longburst, bulk, or unsupported (not directly, not now).

15.5.1 What it looks at

15.5.2 The rules, in order

The policy is a list checked from the top. The first rule that fits decides, and the station records which one it was.

Table 15.2. The transmission policy, first match wins. "Floor" is −5 dB, "good" is +6 dB or better.
#If the message is…Send asWhy
1up to 156 bytes, estimate below the floor ShortburstIt is cheap, and the estimate may be out of date.
2157–601 bytes, to one station, estimate below the floorLongburst, one tryNeighbours can overhear it and keep a copy, which gives a relay search something to find.
3anything else with the estimate below the floor UnsupportedNothing direct will work.
4up to 60 bytesShortburstA 5.44 s bulk frame would be nearly all padding.
5up to 156 bytes, link not good or unknown ShortburstThe announce modem works down to the floor.
6up to 156 bytes, bulk region takenShortburst Leave the bulk region to whoever has it.
7up to 100 bytesShortburstClose to a bulk frame's air time, tougher, and it leaves the bulk region free.
8a broadcast, 157–6,028 bytesBulk, ceiling 1/2No link to judge by, so the most robust rate throughout.
9a broadcast over 6,028 bytesUnsupported A broadcast cannot confirm segments; address it or shorten it.
10up to 601 bytes, good linkBulk, one frame at 1/2About a seventh of a longburst's air time.
11up to 601 bytes, link not goodLongburst The gap-filler.
12over 601 bytes, good linkBulk, ceiling 5/6 Fewer 5.44 s frames.
13over 601 bytes, link not goodUnsupported Too big for the announce channels, too weak a path for bulk.

Three things about the order are worth noticing. A small message beats a bad estimate (rule 1): an estimate can be minutes old and caught in a fade, and refusing a cheap shortburst because of it would make a bad estimate worse than none. If the addressee really cannot hear, the silence is dealt with in the ordinary way (Section 16.6). The longburst of rule 2 is sent once: if its first piece goes unanswered, the station goes straight to asking for a relay. And a taken bulk region only steers messages that fit a shortburst anyway (rule 6); a bigger one waits its turn.

15.5.3 Broadcasts

With no estimate, a broadcast is treated as an unknown path. Up to 156 bytes it goes as a shortburst (rules 4 and 5). Past that there is no longburst to fall back on, so it goes as bulk at rate 1/2 throughout (rule 8). Stations on weak paths may not hear it; that is the trade a large broadcast makes.

15.5.4 Where shortburst gives way to bulk

On a good link, why not send everything over 60 bytes as bulk? Because one bulk frame costs 6.9 seconds of air whether it carries 1 byte or 601. A shortburst costs 2.0 seconds plus 0.66 seconds for each 10 bytes after the first 6. The two lines cross at 76 bytes: an eight-frame shortburst takes 6.6 seconds, and the nine frames that 77 bytes need take 7.3.

The station keeps using the shortburst a little past that point, up to 100 bytes (rule 7), where it takes 8.6 seconds, 1.7 more than the bulk frame. For that small cost the message rides the modem that still decodes 11 dB below the level at which bulk is trusted, and it occupies one narrow announce channel instead of the whole bulk region. Past 100 bytes on a good, free link the single bulk frame wins, and the gap grows quickly: a 156-byte shortburst takes 11.9 seconds against bulk's 6.9.

01020 304050 s 0100200 300400500 600 message size (bytes, after compression and wrapping) 156 601 shortburst longburst (four pieces at most) bulk: one frame up to 601 bytes
Figure 15.2. Sending air time against message size (replies not included). Shortburst: solid; longburst: dashed; bulk: dotted. A longburst costs up to seven times a bulk frame, and more than the figure shows, because each piece waits for its acknowledgement.

15.5.5 When the answer is "unsupported"

Unsupported means the station will not send the message directly right now, because nothing it could send would work: the path is below the floor, or the message is bigger than a longburst and the path is too weak for bulk, or it is a broadcast over 6,028 bytes. It does not have to mean the message goes nowhere.

15.6 Four sends, four answers

15.7 What to remember

Chapter 16

Getting Every Byte There

16.1 The promise: all of it, or none of it

On HF some of what is sent will be lost, and there has to be a plan for getting it back. The general name for that plan is ARQ (automatic repeat request): the receiver reports what it did or did not get, and the sender repeats what is needed. mLink's selective version is called dARQ, and it has three habits:

16.2 The check, and the message's name

Every message carries a two-byte integrity check. It is a CRC (cyclic redundancy check): a short number computed from a block of bytes, so that changing any byte almost certainly changes the number.

16.2.1 What it covers

The unusual part is what goes into it. mLink computes the 16 bits over three things, in this order:

  1. the sender's callsign, in its packed six-byte form,
  2. the addressee's callsign, also six bytes, and
  3. the message itself, as it stood before the station compressed it and put the wrapping bytes of Chapter 21 around it.

For a broadcast to everyone, or to everyone in an area, the "addressee" is the all-stations address 0CQCQCQ; for a virtual net it is the net's own address. Every station knows those, so every station can compute the same value.

Folding in both callsigns turns "are these bytes intact?" into "are these the bytes that station meant for this one?". mLink's data frames carry no sender and no sequence number, and if a frame from somebody else's conversation were ever stitched into a message, the check would come out wrong.

16.2.2 The same two bytes are the message's name

Because the check is computed before compression, the same message gets the same value however it was packed for the trip. So the value doubles as the message's short name on the air. The opening frame of a transfer carries it; the ACK repeats it; so do the frames that ask about a transfer, cancel one, continue one, or ask other stations to relay it (Chapter 19).

Sixteen bits make only 65,536 names, and nothing treats the two bytes as unique on their own. A station reads them together with who is speaking and who was addressed: an overheard message is filed under sender, addressee and check together. Where a mix-up would cost the most, when another station offers to relay "that message", the offer also quotes the length of its copy and a 32-bit fingerprint of it, and the sender compares both.

16.2.3 Where it rides

The check goes out twice: in the opening frame (the RTS of a bulk transfer, the shortburst RTS of a short message), so listeners know which message is coming before any data is decoded; and at the front of the data. A bulk transfer's bytes begin with the two check bytes. A shortburst's frame 0 begins with the two-byte length and then the check.

A longburst (Section 15.3) has two levels. The whole message's check, its name, rides in the manifest. Each piece also carries a check of its own, over just that piece's bytes as they were sent, so a bad piece is caught and repaired before the next goes out.

16.2.4 Checked last, and only last

A receiving station never tests the message's check frame by frame. It waits until it holds every byte, undoes the wrapping (decompression first), computes the value over sender, addressee and the unwrapped message, and compares it with the two bytes from the front of the data.

One damaged message in 65,536 would pass a 16-bit check by luck, but the check is rarely handed damaged bytes at all: every frame has already passed its own error correction, which rejects a frame it cannot fix.

16.3 Bulk frames have no header: position is the header

A bulk data frame has no "frame 7 of 12", no callsign, no length, no rate. Every bit is message, end-of-data filler (Section 9.5) or parity. Both ends work out what a header would have said from three things explained elsewhere:

So the receiver lays out the whole transfer before it arrives: a buffer with a slot for every frame. The last frame is usually only partly full, and its filler marks where the data ends, so the length of the message is never sent as a number.

16.3.1 Why a lost frame changes nothing

Losing a frame does not disturb any other. If frame 3 of 8 fades out, frame 4 still arrives where it was due, decodes at the rate its place implies, and drops its bytes into its own range of the buffer. The gap where frame 3 belongs is simply a gap.

16.3.2 Shortbursts are numbered

The frames of a shortburst do carry their number, 0 to 15, and frame 0 carries the message length (Section 15.2). The rest of this chapter applies to shortbursts as to bulk, except where it says otherwise.

16.4 The answer: ACK or dNAK

When a directed transfer ends, the addressee answers with one of two replies, each a single announce frame behind a PRESENCE that says who is answering. The layouts are in Appendix B.

16.4.1 When the answer comes

A station cannot hear while it transmits (Section 3.5), so the addressee must not answer before the sender has stopped, and it knows when that will be. For a bulk transfer the RTS gave the frame count, so the transmission ends 150 ms plus that many times 5.44 seconds after the RTS. The addressee adds half a second for the sender's radio to drop out of transmit and settle, and a further 150 ms of turnaround. Then it decides: complete means ACK, incomplete means dNAK.

A shortburst that arrived whole is acknowledged as soon as its last frame has been decoded; one with frames missing is answered half a second after its computed end.

A reply never waits for the channel to look clear. The sender is listening for it, so it is keyed at its moment whatever reservations the addressee has noted and whatever else it is hearing (Chapter 17).

16.4.2 ACK: "got it"

[presence][ack]

The ACK (acknowledgement) says the message arrived whole and passed its check. It carries no callsign; it repeats the check from the opening frame it answers, so the sender knows which transfer is meant. The ACK for a longburst piece also says how many pieces are still to come. For a message sent straight to its addressee, the ACK is what turns it to "sent".

16.4.3 dNAK: "here is what I'm missing"

[presence][dnak]

The dNAK, the selective negative acknowledgement, fills its frame exactly:

There is no room left for the check, and none is needed: a dNAK taken for the wrong exchange costs a repair nobody wanted, never a false "sent".

A dNAK can name every frame. That happens when the addressee decoded the RTS but none of the data, which includes the case where frame 0 was lost and nothing after it could be placed (Section 13.8.2). If the RTS itself was never decoded, the addressee does not know a transfer was aimed at it and says nothing. The same goes for a shortburst whose frame 0 was lost: without the length it cannot say how many frames it missed.

16.4.4 Where replies are sent

ACKs and dNAKs carry no "to" callsign. What ties a reply to its exchange is where and when it appears. The addressee keys its reply on the channel the opening frame arrived on: the bulk-control channel for a bulk transfer (Section 8.5.1), and for a shortburst, whichever announce channel it used. A reply is never moved to another channel because that one looks busy.

The sender accepts a reply only on its own exchange's channel, only from the station it addressed, and, for an ACK, only with the right check. A station can be the addressee of two transfers at once, and without these rules both senders could take one ACK as their own.

16.4.5 How long the sender waits

When its transmission ends, the sender opens a reply window of 5 seconds: the half second of settling, the 150 ms of turnaround, 1.3 seconds for the two-frame reply itself, and about 3 seconds for the addressee to finish decoding, build the reply and key its radio. The window is the same for every size of transfer.

The window is not stretched when other stations hold the announce channels reserved. The addressee's reply does not wait for a reservation (see below), so a busy frequency is not what delays it.

A B A sends (top), B hears and answers (bottom). Not to scale: a bulk frame is 5.44 s, an announce frame 0.64 s. P RTS 0.15 s 1/2 3/4 5/6 5/6 5/6 f0 f1 f2 f3 f4 got got lost got lost 0.65 s P dNAK missing: f2, f4 P RETX 0.15 s 1/2 3/4 only f2 + f4 bytes P ACK check passes first transmission: B keeps f0, f1, f3 B's answer repair: missing bytes, packed again from 1/2 done time
Figure 16.1. A five-frame bulk exchange with one repair round. B loses frames 2 and 4 and names them in its dNAK. A sends only those bytes, in two new frames that start again at rate 1/2.

16.5 Selective repair: sending only what is missing

16.5.1 The receiver keeps its partial copy

The addressee does not throw away the frames it did get. It keeps a kept partial: the message buffer with every received frame's bytes in place, holes where the missing ones belong, and a note of which byte ranges are still empty. It holds this for 10 minutes, starting the clock again each time a repair round arrives, and then discards it.

16.5.2 The sender gathers only the missing bytes

The sender still has the whole message. From the dNAK's map it works out which byte ranges those frames carried and copies just those ranges, in order, into one new stream. That stream is cut into fresh frames on the same rate ladder as any transfer, starting again at rate 1/2.

The ceiling for the repair is one step more robust than the most robust frame that was lost. If only 5/6 frames were lost, the repair climbs no higher than 3/4. If a 3/4 frame was among them, every repair frame is 1/2. The path could not carry that rate, so the repair asks for less.

[presence][retx-rts][bulk 0][bulk 1]...

The repair's opening frame, the RETX-RTS, has the layout of an RTS and carries the same check, but marks what follows as a repair. An addressee holding a kept partial from this sender uses the frames to fill it; a station without one ignores them.

16.5.3 The receiver fills the holes in order

The repair frames were cut from one stream of missing pieces, so their edges do not line up with the original frames. One repair frame may carry the end of one hole and the start of the next. Both ends hold the same map of which byte ranges were gathered and in what order, so the receiver simply writes each repair frame's bytes into the first unfilled hole and, when that is full, carries on into the next.

Only the addressee does this. A third station that overheard part of the message does not use the repair frames to complete its copy: to hold the message, as a future relay must, it has to have heard every frame of the first transmission.

Original transfer (bytes) f0 603 f1 907 f2 1,008 (hole) f3 1,008 f4 500 solid = kept by the receiver, dashed = missing Gathered missing bytes (1,508) f2 bytes f4 bytes Repair frames r0 1/2: 603 r1 3/4: 905 r1 straddles the f2 / f4 edge r0 fills the first 603 bytes of f2; r1 fills the last 405 bytes of f2, then carries on into f4 and fills its 500.
Figure 16.2. The repair in Figure 16.1 as bytes. Lost frames 2 and 4, both sent at rate 5/6, leave 1,508 missing bytes, which are cut again from rate 1/2 with a ceiling of 3/4. Repair frame r1 carries the end of one hole and all of the next.

When every hole is full, the receiver checks the message exactly as it would one that arrived in one piece, and on a match delivers it and sends the ordinary ACK.

16.5.4 Round after round

A repair can lose frames too. The addressee then writes in the repair frames that did arrive, works out which byte ranges are still empty, and sends another dNAK. That dNAK's map names frames of the repair, not of the first transmission. The sender kept its map of which original bytes went into each repair frame, so it translates back, gathers what is still missing, and packs it again from rate 1/2.

After the first round the holes stop being whole frames. In the figure, if repair frame r1 were lost, the holes left would be the last 405 bytes of frame 2 and the 500 bytes of frame 4, and the next repair would carry those 905 bytes as two rate-1/2 frames. The dNAK stays a simple map of frames while the repair stays exact to the byte, and nothing that has arrived is ever asked for again.

The round count keeps the two ends in step. If the addressee's count shows it never heard the latest repair at all, the sender sends that repair again exactly as it was, instead of reading the map against the wrong round. It does that once. If the second copy also goes unheard, the message goes to relay.

16.5.5 When a rate-1/2 frame is lost

There is no fixed limit on the number of rounds. What ends them is this rule. Rate 1/2 is the most robust bulk rate, so when a dNAK names a frame that was sent at 1/2, "one step more robust" has nowhere to go:

  1. The first time in an exchange, the sender repairs anyway, with every frame at rate 1/2. The dNAK shows the addressee can hear the sender, and one lost 1/2 frame is more often a collision or a noise burst than a path that has collapsed.
  2. The second time, the sender sends no more data and asks other stations to relay the message (Chapter 19).

This is also what happens when frame 0 is lost. Frame 0 is always rate 1/2, and the addressee's dNAK then names every frame. The sender does not repeat the first transmission as it was: it packs the whole message into rate-1/2 frames and sends that as a repair, once.

16.5.6 Shortbursts and longbursts

Shortburst repair is the same idea, simplified. The dNAK names the missing announce frames; the sender sends just their bytes as a new, shorter shortburst behind a repair version of the shortburst RTS; the receiver fills its holes. There is only one announce rate, so there is no rate to step down and no rule to end the rounds: every dNAK gets a repair. Each piece of a longburst is an ordinary shortburst with its own ACK or dNAK and its own repairs, and the ACK for one piece invites the next.

16.6 When the other end goes quiet

Sometimes the reply window closes with neither an ACK nor a dNAK. Replies ride the announce modem, which decodes far below the level bulk needs, so silence rarely means "the reply was lost". It usually means the addressee never heard the opening frames, is not there, or cannot be reached from here right now, and repeating the data fixes none of those.

16.6.1 Short messages: try again, politely

A shortburst is a few seconds of announce air, so on silence the sender tries again, up to three more times. Before each retry it waits a random time, from nothing up to twice the length of the transmission plus about two and a half seconds, and it sends only when the exchange's announce channel is free and nothing is audible (Chapter 17 says why the wait is random). The same goes for each piece of a longburst. If every retry meets silence, the message goes to relay.

16.6.2 Bulk: never resend into silence

Bulk data is sent again only in answer to a dNAK, and then only the missing part. Silence leads down this path instead:

  1. Ask once: "did you get that?" The sender sends a QSL probe, named after the ham "QSL?" (do you confirm receipt?): [presence][qsl]. It names the addressee and the message's check and carries no data. The sender then listens for between 8 and 9.5 seconds.
  2. The addressee answers only from what it already holds. If it delivered the message, it sends the ACK again. If it holds a kept partial, it sends its last dNAK again. If it is still waiting for a transfer to end, it gives its verdict now. If it knows nothing of this message, it stays silent.
  3. Still silence: ask for a relay. The sender asks any station that holds the message and hears the addressee to carry it the rest of the way (Chapter 19).

16.6.3 One fresh attempt, when nobody at all answers

There is one narrow exception to "never resend bulk". A station can only hold a copy of a bulk transfer if it decoded the RTS. If the request for a relay gets no offers at all, the likeliest story is that the RTS was lost for everyone. In that one case the sender makes exactly one fresh attempt at the whole transfer, after a random wait and when the bulk region is free. If that also meets silence, it probes and asks for a relay as before, and a second empty search leaves the message waiting as deferred (Chapter 20).

The fresh attempt is not made when the message went to relay after a second lost rate-1/2 frame or a repair that went unheard twice: the addressee had answered, so the opening frames plainly got through. And when other stations have been heard in the last two minutes, an empty search is also read as a sign of collisions, and the station spaces out its new bulk transfers for a while (Chapter 17).

16.7 Long transfers: segments and checkpoints

A bulk transfer can be 64 frames, close to six minutes of air, and a sender should not learn only at the end that the addressee faded out in the first minute. So a transfer longer than 10 frames is split into segments of at most 10 frames (54 seconds), each its own transmission.

16.7.1 How the segments are sent

The first transmission opens with the ordinary RTS, which announces the total frame count, and carries frames 0 to 9. Each later segment has a continuation frame in place of the RTS:

[presence][seg-rts][bulk 10]...[bulk 19]

The SEG-RTS says which frame the segment starts at and how many it holds, and repeats the addressee and the check. Each frame still uses the rate its place in the whole transfer implies; for assembly and repair it is one transfer.

16.7.2 "Did you get all that?"

Half a second after each segment but the last has ended, the addressee sends a checkpoint, [presence][ckpt]. It says either "everything so far arrived" or gives a 64-bit map of the missing frames, counted over the whole transfer, and it says how many frames the addressee has been told about. The sender waits for it before keying the next segment. Then:

After the last segment the addressee answers with the ordinary ACK or dNAK. An addressee that hears a segment and then no continuation waits about 30 seconds before it gives its verdict on what it has.

16.8 Broadcasts get no receipts

Everything above is about messages to one station. A broadcast, whether to everyone, to an area or to a virtual net, gets no ACK and no checkpoint: a dozen stations answering at once would bury each other. That holds for everything sent as a broadcast, a map object as much as a bulletin. Listeners still check a broadcast before delivering it. A broadcast does get one limited repair: listeners who missed frames may ask, after a random wait, for them to be said again, and the sender answers the requests it hears with a single repair. One round and no more (Chapter 17). A net control that needs to know who received a bulletin asks with a roll call (Chapter 22).

16.9 Calling off a transfer

An operator can cancel a message while it is on the air or while the station waits for the reply (Chapter 5); it goes back to the drafts. A directed transfer on the air can be stopped two ways:

16.10 What to remember

Chapter 17

Sharing the Channel

17.1 Five pieces of air

A station that is transmitting cannot hear (Section 3.5), but a station that is listening decodes the whole passband at once (Section 13.3). Two stations can hold two conversations on two announce channels while a third sends a file in the bulk region, and your station hears all of it. The rules in this chapter let several conversations run side by side without two of them landing on the same piece of spectrum at the same moment.

There are five pieces to share: the three announce channels, the bulk region, and the bulk-control channel at the centre of the bulk region (Section 8.5.1). The emergency region is not shared this way; distress traffic has it to itself (Chapter 23).

17.2 Defer: honouring what you heard

Before a station sends anything substantial, it announces it. A bulk transfer opens with [presence][rts], a shortburst with [presence][sb-rts]. Those openers tell the addressee what is coming, but every other station hears them too, and each one says, or implies, how long the transfer will occupy which piece of spectrum.

A station that hears an opener meant for someone else writes down a "busy until" time for that piece of spectrum and starts nothing of its own there until the time has passed. mLink calls this defer. Wi-Fi (IEEE 802.11) calls the same idea the NAV (network allocation vector), or virtual carrier sense: instead of listening for a carrier, you believe what the other stations announced about their plans.

No round trip is involved. The addressee does not grant anything and nobody says "go ahead". A heard opener is the reservation.

17.2.1 One busy-until time per piece of spectrum

A station keeps four busy-until times: one for each of the three announce channels, and one for the bulk region as a whole. There is only one bulk modem per channel, so two bulk transfers at once would always collide.

The bulk-control channel has no time of its own. It carries only the announce-type frames of bulk exchanges, so the bulk region's time governs it: a new bulk opener waits for the bulk region to be free, and the replies that follow on the bulk-control channel belong to the exchange that holds the region.

Each reservation is therefore narrow. A shortburst heard on one announce channel keeps a station off that channel and nowhere else. A bulk transfer keeps it out of the bulk region, yet it may still send a short message on a free announce channel. The few holds that stop the whole station are called out where they appear below.

Two rules keep the bookkeeping safe. A new reservation can only move a busy-until time later, so two overlapping reservations leave the later end standing. And a busy-until time simply runs out: once the clock passes it, the spectrum is free again with no further message. The one frame that releases a reservation early is the ABORT a station sends when it calls off a transfer (Chapter 16).

17.2.2 What each heard frame reserves

Table 17.1. What a decoded frame reserves at a station it is not addressed to, counted from the moment it is decoded. A bulk frame lasts 5.44 s; an announce frame with its gap lasts 0.66 s.
HeardReservesFor
Bulk RTS for N frames (also the RTS of a repair burst)The bulk region0.15 s + N ร— 5.44 s + 0.5 s, counting at most the first 10 frames
SEG-RTS (the next segment of a long transfer)The bulk region0.15 s + that segment's frames ร— 5.44 s + 0.5 s
Shortburst RTSThe announce channel it came on10.4 s: fifteen more frames plus 0.5 s, the most a shortburst can still need
A shortburst data frame on a channel with no reservation (the opener was missed)That announce channelThe frames a full-length shortburst would still have to send, plus 0.5 s
A PRESENCE that opens a transmissionThe announce channel it came on; on the bulk-control channel, the bulk region2.5 s: three more frames plus 0.5 s. Each further frame of the chain that decodes moves the end to 1.8 s after that frame.
A PRESENCE on the bulk-control channel, at a station that is idleAll three announce channels and the bulk region3 s, long enough for the RTS behind it to say who the transfer is for
A dNAKThe channel it came on, and the bulk region if the exchange is a bulk oneThe repair it invites: 0.15 s of turnaround, the repair's air time, and 0.5 s
A longburst ACK that says more pieces are comingThe announce channel it came on11.9 s: 1.5 s for the next piece's opener, then a full shortburst
An ABORTFrees the channel it came on and the bulk regionAt once

A worked example: a five-frame bulk transfer reserves the bulk region for 0.15 + 5 ร— 5.44 + 0.5 = 27.85 seconds from the moment its RTS is decoded. The 0.15 seconds is the silent gap between the RTS and the first bulk frame; the half second at the end covers the sender's radio dropping out of transmit.

A long transfer goes out in segments of at most ten frames, each its own transmission (Chapter 16). The RTS announces the total but reserves only the first segment, 55 seconds at most; each later SEG-RTS reserves its own. A station that hears only the opening does not lock itself out for six minutes on the strength of a transfer that may stop after the first minute.

A shortburst RTS does not say how long the shortburst is, so a listener reserves the channel for the longest possible one: ten seconds at most, on one announce channel out of three.

A virtual net's roll call reserves its announce channel in the same way, for as long as the roll call runs (Chapter 22).

17.2.3 Stations you cannot hear

Defer only works for stations you can hear. On HF, with skip zones and one-way fades, two stations often hear the same third station perfectly well and not each other. Radio engineers call this the hidden station problem (in Wi-Fi, the "hidden node"), and it is the main way reservations fail.

mLink uses the replies to cover part of it. If you cannot hear station A but can hear station B, you still hear B's dNAK asking A for a repair. A dNAK names the missing frames and says whether the exchange is a bulk one, so you reserve the time A's repair will take even though you will never hear A's opener. If you did hear A's RTS, you work out the repair's length the way A will; if not, you assume the longest it could be, five frames for every three missing. A longburst works the same way: the addressee's ACK for one piece says more are coming, so a station that cannot hear the sender still keeps that announce channel clear for the next piece. Wi-Fi does this job with a "clear to send" frame; mLink gets it from replies that are sent anyway.

A B C A sends to B; C has a bulk message queued. Not to scale. P RTS 0.15 s 3 bulk frames P ACK B's reply, just after A stops bulk region reserved 0.15 + 3 ร— 5.44 + 0.5 = 17 s 2 s random P RTS C's bulk frames C's own wait after the reservation ends C decodes the RTS time
Figure 17.1. Defer in action. C decodes A's RTS and marks the bulk region busy for the whole transfer plus half a second. B's reply falls inside the two seconds C must wait before opening a new bulk transfer, so the reply always gets the air first. Then C waits a random extra time (see Section 17.7) before keying.

17.3 Picking a channel

A station with a shortburst or a chain of announce frames to send chooses one of the three announce channels at random from the ones that are free. A channel is free when nobody's reservation on it is still running and the station is not in the middle of hearing a chain of frames on it. A queued message is released only once at least one announce channel is free.

Random, and not "always the lowest free channel", matters when several stations are ready at once: two of them often land on different channels and both get through.

That is the rule for messages, for relay and mail housekeeping frames, for most named-net frames, and for the periodic beacon. The exceptions:

The periodic beacon is more careful than a message in one further way: it also avoids an announce channel where the receiver detected an mLink-shaped signal in the last 1.5 seconds but could not decode it. Someone is keying there, even if this station cannot read them. If no channel passes, the beacon waits.

17.4 Who goes first

A station often has more than one thing it could send. The transmitter itself knows three grades of traffic. Distress traffic and owed replies key even while the receiver is in the middle of a frame; everything else waits for the receiver to finish. On top of that, each kind of voluntary traffic has its own conditions, and together they give a clear order.

Table 17.2. What a station keys, in order of precedence.
TrafficWhat it waits for
1. A distress call, or the acknowledgment of one, in the emergency regionOnly for a transmission of its own that is already going out. It ignores reservations and keys even while the receiver is busy.
2. Owed replies: ACK, dNAK, checkpoint, the "did you get that?" probe, a check-in in a roll-call turn that belongs to this stationOnly its own moment in the exchange. It ignores reservations and keys even while other signals are arriving.
3. The next step of an exchange already under way: a repair burst, the next segment or longburst piece, a retry, handing a message to a chosen relayThe receiver to be idle. New messages wait until the exchange is settled.
4. New messages: your own and ones you relayThe station not to be receiving a transfer addressed to it; a free announce channel; quiet air; and, for anything larger than a shortburst, a free bulk region, its turn after a reservation ends, and the pacing described below. Messages go in the order they were queued, except that a short one passes a large one that is held.
5. Automatic traffic: beacons, position reports, geopollsEverything in row 4, plus a longer random wait after any activity. It may wait minutes.

Row 1 is a transmit priority and nothing more. A distress call does not cut off a transmission the station already has on the air, and it does not silence other stations. What it does change is the station's own routine traffic: while its distress call is active, its queued messages and beacons wait, so that the station is listening between repeats for the acknowledgment (Chapter 23).

17.4.1 Replies beat new traffic by construction

When a bulk transfer ends, its addressee replies about two thirds of a second after the sender stops (Chapter 16). Every station waiting to start a new bulk transfer must wait at least 2 seconds after the reservation ends, plus a random amount. The reply is therefore on the air and decoded before any newcomer's earliest moment, and the reply's own frames extend the reservation again.

The same courtesy runs the other way. When the addressee acknowledges one longburst piece and more are coming, or sends a shortburst dNAK that invites a repair, it holds all of its own voluntary traffic for 3 seconds, on every channel, so the sender it just invited can get the next transmission started.

17.4.2 Crossing calls

Now and then two stations call each other at almost the same moment. Each keyed before hearing the other, so each is waiting for a reply that will never come, and left alone they would give up together and try again together. mLink breaks the tie by listening while it waits. A station waiting for a reply that hears a call addressed to it takes the call and answers it. Its own transfer is set aside and tried again, after a random delay, once the incoming exchange is finished.

17.5 Listening before talking

Reservations cover traffic whose opener was heard. They do nothing about a station that keys up just as you do. So a station also listens to the air itself before it starts anything voluntary, whether a message, a relay offer or a beacon. It will not start while either of these is true:

The level is measured over one block of received audio, 512 samples or about 43 milliseconds, and each block gives a fresh reading. The floor it is compared with follows quiet blocks quickly and climbs only slowly, so steady band noise does not keep a station off the air, but a new signal stands out.

17.5.1 The last check before keying

The decision to send is made a fraction of a second before the transmitter keys, because the audio has to be prepared first, and a signal that started in between would go unnoticed. So for the opening transmission of a message (first attempt or retry) and for a relay offer, the transmitter looks once more at the very moment it is about to key. It uses the same one-block level reading and the same 6 dB test, and this time the reading must be no more than 0.1 seconds old. If the air has become busy, the transmission is not sent. A message goes back to the head of the queue, a retry waits again, and a relay offer picks a new time.

Owed replies and distress traffic skip all of this. A reply is timed to land in a moment the exchange already owns, and holding it back because of noise would only make the sender give up on a transfer that worked.

17.5.2 The race that cannot be closed

Even with all that listening, a small window stays open. Two stations that decide to key within about a tenth of a second of each other (one block of audio plus the time for a transmitter to come up) cannot yet hear each other. Add hidden stations, which no amount of listening reveals, and collisions on a busy channel are a fact of life. mLink accepts that. It keeps the window small, makes sure stations that collided once do not collide again the same way (Section 17.7), and relies on Chapter 16 to recover what a collision destroys.

17.6 How long to listen to someone else's transfer

Listening has a price. Every mLink station tries to decode the directed bulk transfers it overhears, so that it holds a copy if the sender later asks for a relay (Chapter 19), and a station that is collecting a frame will not key. Left at that, every bulk transfer would silence every station within earshot for its whole length, about 22 seconds for four frames, as if only one station could talk at a time.

mLink settles it by asking what the overhearing station's relationship to the traffic is, which it knows the moment the RTS is decoded.

Stopping is not the same as stepping on the transfer. The reservation the RTS made still stands, so the station stays out of the bulk region; what it may use is an announce channel. Two more courtesies go with it. The station does not call either party of the transfer while it is on the air: the sender is deaf, and a call to the addressee would pull it into a reply in the middle of receiving. Messages to anyone else, and broadcasts, go ahead. And while that transfer is on the air, the level test of the previous section is not applied: the energy filling the passband is explained by a reservation the station already holds. The cost is that a second, unknown signal starting in that time is caught only by the decoders and by reservations, not by level.

Letting every bystander talk during every transfer would throw away the copies that relays depend on; holding everyone for every transfer is the one-talker channel described above. Giving up only what a station could not have used costs nothing.

17.7 The random wait

The most dangerous moment on a shared channel is the moment it goes quiet. Every station that was waiting for the same reservation sees it end at the same instant, because they all worked it out from the same opener. If each keyed at once they would collide, wait out the same time limit, and collide again. The waiting itself would put them in step.

So wherever a station acts on a moment that other stations share, it first waits a random back-off: it picks a random time within a set limit and stays quiet until that time has passed. mLink's version has two twists:

The first station to key is heard by the others, whose own waits have not yet run out; they decode its opener, record its reservation, and wait again. A pile-up becomes a queue.

Without a random wait reservation ends C D both key at once: they collide With a random wait C D C keys D's wait D heard C: defers to it dotted = random wait
Figure 17.2. Why every shared moment gets a random wait. Without one, stations waiting on the same reservation key together. With one, the first to finish its wait keys, and the others hear its opener in time to defer.

17.7.1 Where the random waits are

In the table, the random part is the most the wait can be; the station picks a time anywhere from zero up to it. N is the number of stations heard in the last 30 minutes, held between the two bounds shown.

Table 17.3. The random waits. The fixed part always applies; the random part is an upper limit.
BeforeFixed partRandom part, up toLongest
A queued message, when the air or a hold on the station has cleared within the last 2 s0.15 s0.45 s ร— N (4 to 12)1.95 s on a small net, 5.55 s with twelve or more
A new bulk transfer, after a bulk reservation it heard has ended2 s1.5 s ร— N (6 to 12)11 s to 20 s
A beacon, a position report, a geopoll, an anchor: after any activity on the channel0.2 s1.5 s ร— N (6 to 12)9.2 s to 18.2 s; a VOX-keyed station waits one full span longer
A retry of your own transfer (no reply came, or it was set aside for a crossing call)0, 1 or 2 places, each as long as the transmission plus 1.05 s0.45 sTwo places plus 0.45 s
Your next message after an exchange ends: the station that received the ACKNone0.4 s0.4 s
The same, for the station that sent the ACK2.6 s0.4 s3.0 s
Asking a broadcaster to say again1 s, then 0 to N−1 places of 2.25 s (N 4 to 8)0.45 s17.2 s
A response whose moment arrives while the air is busy0.25 s0.45 s ร— N (4 to 12)5.65 s, then it looks again

Some notes on the rows. In the first, only a recent change from busy to quiet counts: a message queued on a channel that has been quiet for a while goes straight away. In the third, every decoded frame, every undecoded detection and the station's own transmissions restart the clock, and stations keyed by VOX, whose transmitters are slower to come up, are placed behind all the others. The places in the fourth are long enough that a later station hears the earlier one's whole transmission before its own turn. And the station that sent an ACK waits long enough to hear the other one start.

Two more sets of slots are described with the things they answer: those for answers to a SEED or a geopoll (Section 18.4), and those for relay offers (Chapter 19).

17.7.2 Slowing down when the channel is jammed

Random waits spread stations out; they do not reduce how much everyone is trying to send. Under heavy load, collisions cause retries, relay searches and repairs, which are more transmissions, which cause more collisions. Left alone, that feedback can jam a busy channel.

So each station watches for one piece of evidence that it is part of the problem: a relay search for one of its own messages came back with no answers at all (Chapter 16), although it has heard some other station within the last two minutes. On a lively channel that almost always means nobody decoded its opener, which means a collision. Each time it happens, the station spaces out the large sends it starts: 15 seconds between them at first, doubling with each further piece of evidence, up to 10 minutes. Each large transfer that completes halves the spacing, and so does every minute without new evidence. Halved below 15 seconds, the spacing is gone.

Only traffic the station chooses to start, and only what is too big for a shortburst, is paced: new bulk and longburst transfers, and fresh attempts at ones that were held or set aside. Short messages are never held behind a paced transfer, and replies, repairs inside a running exchange, distress traffic and beacons are never paced at all.

17.8 Broadcasts: "say again"

A directed message that meets a collision has an addressee who will say what went wrong (Chapter 16). A broadcast has none, and a dozen listeners all sending dNAKs at the same instant would destroy each other. Yet a broadcast can lose a frame at one listener to a local collision while everyone else gets it cleanly. mLink handles this with a single, delayed say-again round:

  1. A listener that received a broadcast incompletely keeps its partial copy, as it would for a directed transfer.
  2. It waits one second, then a random number of places 2.25 seconds apart, then up to 0.45 seconds more (the say-again row of Table 17.3). Then, if the air is quiet, it sends a request shaped like a dNAK, [presence][dnak], on the broadcast's channel, naming the frames it is missing. The request is ordinary voluntary traffic, not an owed reply.
  3. A listener that hears someone else's request covering all of its own missing frames stays quiet: the repair will carry its frames anyway.
  4. The sender collects requests for 22 seconds after the broadcast ends. It then sends one repair, as a broadcast, holding every frame anyone asked for; a bulk repair is packed again at rate 1/2 like any repair. Each listener fills in the parts it needs.

If two requests collided at the sender, both listeners would wait forever. So each listener asks once more, about 35 seconds after its first request and at a freshly picked place, unless the repair has arrived in the meantime; and a sender that heard no requests in its 22 seconds keeps listening for another 60 before it concludes everyone got the broadcast.

There is only one repair round. It covers a broadcast sent as one bulk or one shortburst transmission, not a longburst sent in pieces, and it needs the listener to have decoded the opener. A listener still missing frames after the repair drops its partial copy.

17.9 What to remember

Chapter 18

Finding Each Other

18.1 Three sources of knowledge

mLink has no net control to keep a log of who is on frequency (Section 1.4), yet much of what a station does depends on knowing who is around and how well it hears them. So every station builds its own picture of the neighbourhood, from three sources:

18.2 Coming up on frequency

mLink calls the start-up process convergence: the station arriving at the conclusion "this is a live mLink channel and I am part of it". It has up to four stages. None of them changes what the station can receive (it decodes everything from the first second) or stops the operator sending a message. They only decide when the station volunteers a beacon of its own.

18.2.1 Stage 1: listening

For the first ten minutes after start-up the station sends no beacons. A newly started station has no idea whether the frequency it was tuned to is quiet, busy with another mode, or in the middle of somebody's contact, and ten minutes of listening is how a careful operator would treat a strange frequency too. It is also usually all it takes: on a working channel somebody transmits within ten minutes, and the moment your station decodes a frame from another station it goes straight to the last stage.

18.2.2 Stage 2: seeding

If the ten minutes pass and nothing has been heard, the station starts to ask. It sends a SEED: a PRESENCE frame of a kind that means "I am here; can anyone hear me?" It is a single announce frame carrying the callsign and grid like any other PRESENCE, sent on a free announce channel.

The first SEED waits a random extra time of up to 16 seconds. A group of stations switched on together, at the start of an exercise or when power comes back, would otherwise all finish listening at the same instant and key on top of each other. After that a SEED goes out about every 90 seconds, each interval made up to 20 percent longer or shorter at random so that two stations do not fall into step.

A station that hears a SEED answers it with a SEED-ACK, another kind of PRESENCE. That answer is the point of seeding. An ordinary beacon tells others you exist; a SEED asks them to prove they heard you. It covers a case listening alone cannot detect: a station whose receiver is buried in local noise but whose transmitter works. Such a station would listen forever and conclude the band is dead. Hearing a SEED also counts as hearing a station for the one that answers, so both sides finish in the same exchange.

18.2.3 Stage 3: seeding slowly

If twenty minutes have passed since start-up and the station has still heard nobody, it stops seeding every 90 seconds and drops back to one SEED about every ten minutes. At that moment, once, it raises an advisory for the operator: check the antenna, interference, frequency and modulation. It does not give up. A station on a quiet frequency may simply be the first to arrive, and when the second one shows up the slow SEEDs make sure they find each other.

The operator can cut the listening stage short and have the first SEED sent at once. In any later stage the request does nothing, because there is nothing left to skip.

18.2.4 Stage 4: converged

The instant the station decodes a valid frame from another station (a PRESENCE, a SEED-ACK, a message opener, a relay frame) it is converged, whatever stage it was in. From here on it sends a beacon only when it has been quiet for a while.

0 10 min 20 min 30 min 1. Listening no beacons at all 2. Seeding SEED every ~90 s 3. Seeding slowly SEED every ~10 min operator advisory, once 4. Converged beacon only after 10 to 60 min of its own silence hear any station SEED-ACK or any station
Figure 18.1. The four start-up stages. The top row is what happens on a frequency where nobody answers; the arrows show that hearing any other station, at any point, moves straight to the converged stage. Tick marks are SEEDs; every interval varies by up to 20 percent.

18.3 Beacons

A beacon is a transmission that is a PRESENCE frame and little else: no message, no request, only "this is me, here".

18.3.1 AUTO and OPERATOR

Every PRESENCE says one of two things about the station behind it: AUTO, it is running unattended, or OPERATOR, a person is at the station. The operator sets which, and it costs no air time: the two are different kinds of PRESENCE, told apart by the frame's type byte (Section 14.3). The same mark rides on the PRESENCE at the front of every data transmission.

18.3.2 How often a converged station beacons

The rule is simple: a station beacons only when it has been silent for a long time. The beacon timer restarts every time the station keys a transmission that opens with its PRESENCE. A station passing traffic every few minutes therefore never sends a separate beacon; its traffic is its beacon.

How long "a long time" is depends on how crowded the net is. The base interval is ten minutes. Once a minute the station counts the stations it has heard recently (the "on the net" window in Section 18.9). With up to ten stations heard, the interval stays at ten minutes. Beyond that it grows by ten minutes for each further ten stations: 20 minutes with eleven to twenty heard, 30 with twenty-one to thirty, and so on up to an hour with more than fifty. Each interval also varies at random by up to 20 percent either way.

There is one exception. If the station has heard no traffic (any frame that is not a beacon or an answer to one) for ten minutes, it takes the band to have gone quiet and beacons at least every twenty minutes however many neighbours it has. That only changes anything on a frequency with more than twenty stations. A quiet band is when stations most need to find each other again, and when an extra beacon costs nobody anything. The rule looks only at traffic, so the extra beacons it causes cannot make the band look busy.

A beacon that comes due is a voluntary transmission and waits its turn like one: for the station to be idle, a free announce channel, quiet air, and the random wait after any activity (Section 17.7.1). Nothing is lost by waiting. A beacon the operator asks for by hand waits the same way and goes out once, however long that takes. A station set to listen only never beacons, and neither does one with no callsign set (Section 14.2.2).

18.4 Answering a question

Two kinds of PRESENCE are answers: the SEED-ACK that answers a SEED, and the answer to a geopoll (next section). When one station asks, everyone who heard the question wants to answer, and they all heard it at the same instant. If they all answered at once nobody would decode anything.

mLink spreads these reactive beacons out in both time and frequency:

There is also a limit on how many answers go out. While a station waits for its slot it counts the other answers it hears, on any channel. If three other stations have already answered, it stays quiet: the asker knows the channel is alive, and a fourth answer adds air time without adding information. A station in the middle of an exchange when its slot arrives answers once the exchange is over, and one whose receiver is busy with a frame waits a short random time and looks again. Answers are always a single frame.

18.5 Who is over there? Geopoll

A geopoll is the reverse of a beacon. Instead of "here I am", it asks "is anyone in this area?" The operator gives an area, a centre (a latitude and longitude, or a grid square) and a radius in kilometres, and the station sends one frame that carries that circle. It is a PRESENCE-family frame, but the circle takes the place of the callsign and grid, and it goes out alone with no PRESENCE in front, so a geopoll does not say who is asking (Section B.7). It is sent on any free announce channel once the air is clear, and has no time limit: if the band is busy for five minutes, the poll goes out in five minutes. Only one such request waits at a time; a newer one replaces it.

Every idle station that decodes the poll tests its own configured grid square against the circle. If the centre of its square is inside, it answers in its slot with a PRESENCE of the geopoll-answer kind, carrying its callsign and grid as usual. A station with no grid square set never answers, because it cannot place itself.

The kind of the answer matters to the station that asked. An ordinary beacon heard a few seconds after a poll might be a coincidence; a geopoll answer means that station heard the poll. Answers go into the asker's heard list like any other PRESENCE.

A geopoll only asks who is present. Sending a message to everyone in an area is a different thing (Chapter 28).

18.6 The heard list

The other half of finding each other is remembering what was heard. Each station keeps a heard list: one record per station it has decoded first-hand.

A record is created or refreshed by every PRESENCE the station decodes, of any kind: the one at the front of a transmission, a beacon, a SEED, a SEED-ACK, a geopoll answer. The four named-net frames that travel alone with the sender's callsign inside refresh it the same way (Chapter 22). A record holds:

Only first-hand decodes create records. Hearing somebody else mention a station, in a HELLO, a relay request or a message, never does.

The station forgets a record when it has decoded nothing from that station for three of its current beacon intervals, and never sooner than one hour: one hour with up to twenty stations heard, up to three hours on the most crowded frequency. Whatever shorter age limit a screen applies is a matter of display (Chapter 5).

18.6.1 The link estimate

Each decoded announce frame comes with a measured SNR (Section 13.9), on the SNR@3k scale like every figure in this book. HF signals flutter: one frame can arrive 6 dB down in a fade and the next 6 dB up. If the station decided things on the latest reading alone, a single fade could flip it from "send this as bulk data" to "this link is too weak" and back a minute later.

So alongside the latest reading it keeps a link estimate for each station: a running average in which the newest reading counts for 40 percent and everything older shares the other 60 percent, each earlier reading fading by the same factor again. The first reading starts the estimate as it stands. After that a single odd reading can move it at most 40 percent of the way, and three readings that agree carry nearly 80 percent of the weight.

Three rules decide what goes into the estimate and when it may be used.

The figure that comes out is what a station grades a link on: when it chooses how to send (Chapter 15), and when it offers to relay (Chapter 19).

18.6.2 Gateways heard

A station that can reach its mail server says so with the gateway flag in its PRESENCE (Section 14.2.1). The heard list records the flag with the time it was last seen, and HELLO frames and relay offers pass it on second-hand, so a station can learn of a gateway it cannot hear itself. Hearing a gateway's PRESENCE is also the cue for mail that is waiting for one to try again (Chapter 24).

18.7 HELLO: sharing who you hear

The heard list tells a station who it hears. It says nothing about who they hear. For that, stations share notes in HELLO frames.

One HELLO is one sentence: "I recently heard this station." The "I" is whoever sent the PRESENCE at the front of the transmission, so the HELLO does not repeat it. It names the station heard and gives how many minutes ago it was last heard, the SNR in whole dB (the sender's link estimate for that station, or its latest reading if there is no estimate yet), whether that station was showing the gateway flag, and the class of the link, strong or weak. The layout is in Section B.11.

Strong means the SNR being reported is +6 dB or better, the level from which a station trusts a link with bulk data. So "strong" is more than "loud"; it means "I would send you bulk over this link". Weak means heard, but good only for the short, rugged traffic of the announce channels.

A station that is one radio of a cluster (Chapter 31) also speaks for the cluster's other radios. One HELLO in each transmission that carries any may name a station that only another of the cluster's radios hears, on another band for instance, marked as such. A listener keeps that as "reachable through this station", not as "on this frequency": it does not count toward who can hear whom here, but it tells a sender that a relay through the cluster can work.

18.7.1 HELLO never keys the radio by itself

A station never transmits just to send HELLOs. They ride only on transmissions that are happening anyway:

At most one transmission a minute carries any. Each HELLO adds two thirds of a second, so the cost is at most two seconds of air time a minute, however busy the operator is. SEEDs and answers never carry one.

Only stations heard within the "on the net" window are advertised, so HELLOs describe the net as it is now. The station works through that list in rotation, starting each time where it stopped, so successive transmissions advertise different stations. On a directed transfer it skips the destination: the opener right behind names that station and tells every listener "I can hear this one".

Every HELLO your station decodes, and can tie to the PRESENCE in front of it, becomes one row of its links map: "reporter hears subject, strong or weak, at so many dB, so many minutes ago". A newer HELLO about the same pair replaces the row.

Three other frames also say something about who hears whom:

The last two are marked as inferred, because nobody measured anything. An inferred sighting refreshes a row's age and can raise it from weak to strong. It never turns a strong row weak and never replaces an SNR that someone measured.

The links map is strictly second-hand knowledge. It never creates or changes a heard-list record. A row that has not been refreshed for two hours is dropped, so stations that have left do not linger as ghost lines.

The map feeds two things. One is the report already described: a row in which another station says how well it hears you grades your link to it, in preference to your own estimate. Only measured rows count for that, never inferred ones. The other is the operator's picture of the net: which stations can reach which, and where the gaps are.

Choosing a relay does not consult the map. A station volunteers only on the strength of its own first-hand hearing of the destination (Chapter 19).

18.9 How recent is "recently"?

Many parts of mLink ask "have we heard that station recently?", and they do not all mean the same thing by it.

Table 18.1. The "heard recently" windows.
QuestionWindowWhy that long
Is my link figure still good enough to choose how to send, or to offer a relay?5 min since the station was last decoded (or, for its own report, since it last heard you)Long enough to span a few exchanges, short enough that a change in the band is noticed.
May I volunteer to relay to this destination? May a deferred message try it directly again?2 min since last decodedA promise to carry someone's message should rest on fresh evidence.
How many stations should a random wait be spread over?30 min since last decodedCounts the stations that might be waiting for the same moment.
Is this station on the net? (the count behind the beacon interval; which stations HELLOs advertise)30 min, or 2ยฝ beacon intervals when that is longer; always inside the time a heard-list record lastsSized to span a quiet station's own beacon interval with room for a missed beacon, so that members of a big net stay in the count between beacons.
How long is a heard-list record kept?1 h since last decodedA fixed limit. A station heard again after that simply gets a new record.
How long is a links-map row kept?2 h since last refreshedLonger than the slowest beacon, so live links are not dropped; short enough that departed stations disappear.

One more interval is built on the beacon interval: how long a promise to act "next time I hear that station" must stay alive. That is the contact horizon, one and a half beacon intervals (Chapter 20).

18.10 What to remember

Chapter 19

Relay: Recruiting a Helper

The relay setting is on the Settings screen (Chapter 5), and the notes a relayed message shows in the outbox are listed in Chapter 6.

19.1 Why relay, and why this way

Two stations 400 km apart may have no usable HF path at the hour you want to send, while a third station hears both perfectly. Voice operators solve this all the time: "I can hear him, I'll pass it along."

mLink's relay does the same thing, and differs from classic packet digipeating in three ways:

The handshake uses five frames of the RELAY family: REQUEST, OFFER, SELECT, FOR and RESULT. Each is one announce frame behind a PRESENCE that names the station sending it; their byte layouts are in Section B.10. They name the message by its 16-bit check value (Section 16.2.2), called the message's id in this chapter. We follow one message with three stations:

A C X originator helper destination โœ• 1. direct send to X (never heard) C overhears, stores a copy reply window: silence 2. [presence][REQUEST X, id] holds id? heard X in 2 min? link to X at least โˆ’5 dB? waits for its slot (0 to ~16 s) 3. [presence][OFFER id, SNR to X, length, fingerprint] collects offers 2 s, checks length + fingerprint 4. [presence][SELECT C, id] 5. [presence][FOR A, id][rts][dataโ€ฆ] one transmission, C's own mode choice A overhears: "it's moving" 6. [presence][ACK] files it as from A, notes "A via C" 7. [presence][RESULT id, delivered] outbox: sent (via relay)
Figure 19.1. The relay handshake with three stations. Solid arrows are transmissions that are heard; the dashed first arrow never reaches X. The shaded bars are waits.

19.2 Step 1: REQUEST

The originator sends [presence][relay/request]. The REQUEST names the destination and the message id, and has one flag, explained under Section 19.7.2. It does not carry the message.

A REQUEST is something the station chooses to say, not a reply another station is waiting for, so it goes out on a free announce channel and waits its turn like any other new transmission (Chapter 17). The station remembers which of the three announce channels it used, because its SELECT will go out on the same one. Then it listens for OFFERs for up to 24 seconds.

A client can also ask the station to run this search for a stored message, naming the destination and the id. The search is the same, except that the station has no copy of its own to compare OFFERs against.

19.3 Step 2: OFFER

19.3.1 Who may volunteer

Every station that decodes the REQUEST asks itself three questions:

  1. Do I hold the message? That means a complete, checked copy with this id, from this requester, to this destination. The REQUEST's PRESENCE names the requester and the REQUEST names the destination, so two unrelated messages that happen to share an id are not confused unless they also share both callsigns.
  2. Can I hear the destination? The station must have decoded the destination within about the last half hour; the window grows when the stations on the frequency beacon less often (Section 18.9). A station whose last hearing of the destination is older than two minutes still answers, but stands four places further back in line (Section 19.3.4) and drops its OFFER as soon as it hears one other.
  3. Does my relay setting allow it? See Section 19.9.

A station that passes all three still checks one more thing before it speaks: its link estimate toward the destination (Chapter 18) must be at least โˆ’5 dB. Below that figure its own sending rules refuse any directed transmission (Section 15.5.5), and an offer it would then refuse to honour would leave the originator waiting for nothing.

19.3.2 What an OFFER says

An OFFER fills its frame. Besides the message id it carries:

The last two are for the originator, the one station that certainly knows the real message. It ignores any OFFER whose length or fingerprint does not match its own copy. The fingerprint is a different kind of sum from the 16-bit check, so two messages that share an id will almost never share it too.

Everyone else listening learns from an OFFER as well: it goes into their links map as a HELLO would (Chapter 18).

19.3.3 Spreading the answers out

A REQUEST is heard by many stations at the same instant. If every volunteer keyed at once, the originator would hear none of them. So each waits for a slot:

With only a few stations able to help, that is all there is to it: the slot does not depend on signal strength, and the originator compares whatever offers arrive.

19.3.4 When many could help

Nine slots on two channels are plenty for three helpers and far too few for thirty. On a busy frequency, or in a large net, dozens of stations may hold the message and hear the destination. If they all drew a slot by chance, several would share each one and cover each other, and the originator might decode none of them. So a station that believes five or more could answer, itself included, does not draw by chance. It works out its own place in line.

The place decides when it answers:

Place in lineAnswers
1 and 2In the first slot, on different announce channels, so the two do not cover each other.
3 and 4In the second slot, two seconds later, having listened to the first.
5 and 6In the fourth slot, six seconds after the REQUEST. The third slot is left empty: that is when the originator's SELECT is on the air.
7 to 16Two to a slot in the five slots after that, the last starting 16 seconds after the REQUEST.
17 and laterNot at all, for this REQUEST. The station sets nothing aside for it and is free to answer the next one.

A station waiting for its slot counts the OFFERs it hears for the same request. When it has heard two, it drops its own unsent: two offers are enough for the originator to choose from, and a third would only take air time. It also drops its offer when it hears the SELECT, as every volunteer does.

The usual result is that the two best-placed stations answer and nobody else transmits. The later slots are there for the case where the best two did not hear the REQUEST: then the next in line speak, and the message still finds its relay in the same search. Where the volunteers cannot hear one another, none of them can count the others' OFFERs, so about two answer in each slot until the SELECT is heard. Once one relay to a destination has taken place, everyone who overheard the offers knows who hears that destination and how well, and the next search is ranked by signal instead of by chance.

Sixteen places are a limit on purpose. On a full frequency a hundred stations may each believe they could help, and a rule that gave every one of them a turn would put most of them in the same last slot, where they would cover each other and the originator would decode nobody. With sixteen places, at most two stations are meant to key in any slot, whatever the size of the crowd.

The price is paid when few can help. Take a destination that only three stations among a hundred can hear. Each of the three hears a hundred others, knows nothing about what they hear, and will usually draw a place past the sixteenth, so the first REQUEST may pass in silence. The repeats put that right. A station that has heard a REQUEST for a message go by with no OFFER, no SELECT and no RESULT knows that the crowd it feared did not answer. On the next REQUEST for the same message it draws its place from half as many, on the one after from a quarter, and so on down to the number of places there are. Within two or three requests the few that can help are answering. When many can help, somebody is heard on the first REQUEST and nothing widens.

One thing does change the slots: a virtual net. While a net is active on the frequency (Chapter 22), only eight of the nine slots are used, in two halves. A net member, or net control, volunteering for a message to or from a station on its own net's roster answers in the first four, so its OFFER starts within 6.4 seconds. Every other volunteer answers in the next four, between 8 and 14.4 seconds. The net's own stations are heard first, and a bystander who hears the SELECT in the meantime stands down. When many could help, each half ranks itself separately: members among the members in the first, second and fourth slots, everyone else among the others in the fifth, sixth and eighth. Each half therefore has six places, two to a slot, and a station that works out a seventh place or later stays silent for that REQUEST, opening up on the repeats in the same way.

19.4 Step 3: SELECT

When the first acceptable OFFER arrives, the originator starts a two-second clock to see whether a better one follows. When the clock runs out it chooses:

  1. A volunteer that already holds the message beats one that would need it sent first.
  2. Among equals, the highest link estimate to the destination wins.

It then sends [presence][relay/select], naming the chosen station and the message id, on the announce channel its REQUEST used.

An OFFER is a promise, so the volunteer protects it. For 5.2 seconds after its OFFER goes out, which is the two seconds the originator spends collecting plus a slot length each for the OFFER and the SELECT, the volunteer holds back its own outgoing traffic so that it is listening when the SELECT comes. In that time, and for as long as a relay it was selected for is in progress, it does not answer a different station's REQUEST for a different message. A new REQUEST for the same message, or from the same requester, still gets a fresh answer.

19.5 Step 4: FOR, and the message itself

The chosen station now delivers the message as an ordinary transfer from itself to the destination. It chooses shortburst or bulk afresh, from the size of the message and its own link to the destination (Section 15.5.2), not from how the originator sent it. ACKs and repairs work on this hop as on any other. What was sent stays what it was: a relayed mail arrives as mail.

The one addition is a FOR frame, naming the originator and the original message id. It rides in the same transmission, right in front of the RTS:

[presence][relay/for][rts][bulk 0][bulk 1]...

If the SELECT arrives while the helper is receiving something else, or waiting for the answer to a transfer of its own, it holds the SELECT for up to 20 seconds and acts as soon as it is free. It also will not start while all three announce channels are reserved. If 20 seconds pass without a chance, it lets the job go, and the originator's own waiting (below) covers the rest.

19.5.1 At the destination

When the destination decodes a FOR, it makes a note: "the next message from this station is really from A, with this id". The note lasts 30 seconds, and is stretched when the helper's opening frame arrives so that it covers the whole transfer and a round of repair.

The transfer is checked like any other, with the check the helper computed for its own hop. Once it passes, the destination files the message as from A, under A's original id, and uses the note once. It also works out what the id should be for A, itself and those contents, and logs a warning if the two differ. Last, it records that A can be reached through C. A client can list these learned routes; the station does not use them to choose a path.

19.6 Step 5: RESULT

When the destination acknowledges the transfer, or the helper's attempt fails for good, the helper tells the originator with [presence][relay/result]: the message id and one of two words, delivered or failed.

The RESULT goes out once, straight away. A lost RESULT leaves the originator's outbox saying "awaiting confirmation" for a message that did arrive, which is a wrong label and not a lost message; repeating every RESULT to guard against that would add air time to every relay on the net. Only if the helper cannot send the RESULT at all, for example because its operator switched it to listen only in the middle of the relay, does it store it. It then sends it the next time it hears the originator, and keeps it for up to one message lifetime (Section 20.4).

The originator accepts a RESULT only from the station it selected, and only with the right id:

19.6.1 How long the originator waits

The RESULT is not repeated on its own, but it can be asked for again. A helper remembers the messages it has delivered and seen acknowledged. If the originator, still showing "awaiting confirmation", sends another REQUEST for one of them, the helper does not offer and does not carry the message a second time. It answers with the RESULT, in one of the first two answer slots, and any station waiting to offer for that REQUEST stands down when it hears it. The helper gives this answer once for each delivery: two messages with exactly the same words have the same id, and a helper that kept answering "delivered" would report a new one as delivered without sending it. For the same reason the originator believes the answer only for a message it handed to that very station.

The originator, for its part, keeps quiet while the RESULT is due. A station that is transmitting hears nothing, on any channel, and an originator that started its own routine traffic the moment the helper's last data frame ended would talk over the destination's acknowledgment and the RESULT that follows it. So from the moment it hears its helper begin delivering, the originator holds its own routine transmissions: queued messages, its beacons, and net upkeep if it is net control. The hold ends when the RESULT is heard, or 6.8 seconds after the last frame of the delivery it decoded: five seconds for the destination's reply, 1.3 for the RESULT frame, and half a second of margin. A distress call is never held, nor is a reply the station owes somebody, nor its turn in a roll call.

After its SELECT, the originator waits up to 60 seconds for the RESULT. But A can usually hear C, which is why C could be chosen, so A often overhears the relay happening: the FOR frame naming A, and each opening frame C sends to the destination, repair rounds included. Every time A hears one of those, the 60 seconds start again. It does not give up on a helper it can hear working.

If 60 seconds pass with no RESULT and no sign of progress, the message is not marked failed. The row becomes deferred, with the note "relay handed off; awaiting confirmation on next contact", and the station keeps a record on disk of which helper it is waiting on. A RESULT from that helper still settles the message, however late it comes. Meanwhile the station keeps trying, as described next.

19.7 When nobody volunteers

Sometimes the 24 seconds close with no OFFER at all. Nobody may hold a copy, or the stations that do may not hear the destination right now. After a bulk transfer, an empty search first earns the message one fresh attempt at the whole transfer (Section 16.6.3). After that, or straight away for a short message, the row becomes deferred with the note "no relay volunteered yet; asking again after a growing wait".

For mail there is one more helper, and only on a repeat REQUEST. When a first REQUEST for the station's own clear mail has found nobody who can reach the destination, the repeats carry a second flag: "a station connected to the mailserver may ask for a copy". A gateway that neither holds the mail nor hears the destination may then answer with an OFFER marked "send it to me first", claiming the worst possible link, so that any station which really hears the destination is chosen ahead of it. Gateways answer in the later slots, ranked among themselves for the six places there. If one is chosen it is handed the mail, leaves it at the mailserver for the recipient to collect, and announces that it has taken it; the originator's row then reads "handed to callsign, which left it at the mailserver for pickup". Gateways stay silent on a first REQUEST, so station-to-station delivery is always tried first. The flag is never set for encrypted mail, nor for mail from a station that is not registered at the mailserver.

19.7.1 Seeking: asking again later

A deferred message waits for the neighbourhood to change. Nothing happens until the station has heard some station since it set the message aside, and until the message's retry gap has passed; the gaps grow from one minute to thirty-two (Section 20.6.1). Then:

The same two moves apply to a message that was handed to a helper whose RESULT never came. Should that helper deliver late after all, the destination recognises the second copy as one it already has.

19.7.2 HANDOFF: when nobody holds a copy

A REQUEST sent straight after a direct attempt invites only stations that hold the message, provided a complete copy went on the air. If only part of it aired (a message sent in several parts stops after the first when the destination does not answer), no bystander can hold it, and the first REQUEST already carries the wider invitation described next. A REQUEST sent later, from the deferred state, always sets the flag that widens the invitation: "nobody seems to hold this; a station that hears the destination may offer without a copy". A station that has heard the destination within the same half-hour window, passes the โˆ’5 dB test and is set to allow bulk may then answer with an OFFER marked "send it to me first". Such an OFFER carries no length and no fingerprint.

If the originator selects such a station, it waits 2.5 seconds after its SELECT and then sends the message to it as an ordinary directed transfer with a HANDOFF frame in front, in the place a FOR would take. The HANDOFF names the real destination and the message id. The receiving station does not show the message to its operator. It stores it exactly as though it had overheard it, and then carries on as a normal relay: FOR, transfer, RESULT. The originator's 60-second wait for the RESULT starts when the helper acknowledges the hand-over.

A station selected this way waits 90 seconds for the hand-over to begin before it gives up its promise. If the hand-over fails, the originator treats the relay as failed, defers the message, and asks again later.

19.8 More than one hop, and other helpers

Nothing in the handshake is limited to one hop. If the helper's own transfer to the destination meets silence, the helper asks for a relay as it would for a message of its own, and waits for that second helper's RESULT. Whatever comes of it, delivered, failed or no offer at all, the first helper reports it to the original requester with a RESULT of its own and is done; it does not go on seeking for somebody else's message. Every station remembers the true author of a relayed message it overheard, so a FOR frame two hops down the line still names the original author and the original id.

Three other kinds of helper can answer a REQUEST:

19.9 The operator's relay setting

Each station has a relay setting with four positions. A new station starts at allow bulk.

Listen only is the strong one. A listen-only station transmits nothing except a distress call its own operator declares: no beacons, no traffic of its own, and none of the frames in this chapter. It still hears, records and shows everything. The setting is looked at again right before each relay frame would go out, so switching to it in the middle of a relay takes effect at once. What that does to a message of the station's own depends on the moment:

Relay off sends the station's own traffic normally but carries nobody else's. It never answers a REQUEST with an OFFER and never takes on mail as a courier.

Announce only carries only small messages. It volunteers only when the copy it holds is 156 bytes or less, the most one shortburst carries, and is not mail. It never volunteers without a copy, whose size it cannot know, and takes on no courier duty.

Allow bulk carries everything: short messages, bulk transfers, relaying without a copy, and mail courier duty.

The level is looked at when the REQUEST is heard and again when the OFFER would go out, so lowering it takes effect for the next OFFER. The two middle levels do not affect the repeating of a heard distress call, which has a switch of its own (Chapter 23).

19.10 What to remember

Chapter 20

Patience: How mLink Thinks About Time

What each outbox state and note means for the operator is in Chapter 6.

20.1 Why not just use a timeout?

Most networking software is built on timeouts: send something, start a stopwatch, and if no answer arrives before it runs out, assume the message was lost and send it again. On a wired network, where an answer comes back in milliseconds, that works well.

On a shared HF channel the answer has to win a turn on the channel like everything else. If the channel is busy, the answer is late, not lost. A stopwatch cannot tell late from lost, so it resends. The resend adds traffic to a channel that was already busy, so other stations' answers get later still, so their stopwatches run out and they resend. The more crowded the channel, the more of its time goes to copies of messages that were already on their way. That is how a busy net seizes up, and the name for it is congestion collapse.

20.2 Opportunistic and lazy

mLink's answer fits in three words: opportunistic and lazy.

20.3 Three kinds of waiting

Every wait in the station belongs to one of three kinds, and the kind decides how its number is chosen and what it means when it runs out.

Table 20.1. The three kinds of wait.
KindThe question it answersHow it is setExamples
TurnaroundWhen may I key? When is the other station ready to hear me?Worked out from air time; exact; never shown to the operatorThe pause before a reply (Section 16.4.1)
ReclamationHow long is this remembered fact still worth believing?Generous; too long does no harm"Heard recently" before offering to relay; how long a link measurement is trusted (Chapter 18)
LifetimeHow long do I keep working on this before I set it aside?Generous, and restarted by evidence that someone is still working on itThe wait for a relay's RESULT (Section 19.6.1); the message lifetime below

The kinds are kept apart because they go wrong in different ways. A turnaround that is too short makes a station key over the reply it is waiting for, so these are exact. A reclamation that is too long does little harm. A lifetime that is too short makes a station declare defeat while the answer was merely stuck behind other traffic, so a lifetime never pronounces failure by running out. It sets the message aside to be tried again.

20.4 The message lifetime

The longest wait is the message lifetime. For a message that has to ask for a relay it starts with the first REQUEST. It is used in four places:

The lifetime is 15 minutes, or the contact horizon if that is longer.

20.4.1 The contact horizon

Several of these waits are promises of the form "I will deal with this the next time I hear that station". Such a promise is only worth something if it lasts until the next time can come around. On a big net a quiet station beacons only about once an hour (Chapter 18), and a 15-minute promise to act on next contact with it would lapse before contact could happen.

So the station works out a contact horizon: its own current beacon interval, plus half as much again for margin. The beacon interval is ten minutes with up to ten stations heard and stretches in steps to an hour on a very crowded frequency, so the horizon runs from 15 minutes to 90. A lifetime is never shorter than the horizon.

20.5 Deferred is not failed

When a lifetime-kind wait runs out, the message becomes deferred, not failed. An empty search for a relay, a relay that was chosen and then never reported, a relay that reported failure, mail on its way to the mailserver over the internet: all of these are deferred. The station still holds the message and is still working on it.

Failed means the station has stopped. It is used when the station may not transmit (it is set to listen only, or the transmitter refuses), when the message cannot be built or is too big to send at all, and when the sending rules find no way to send it to that station (Section 15.5.5). Time passing does not, by itself, make a message failed.

20.6 Mail never expires

No clock ends a deferred message. When its lifetime runs out, the station changes the note, starts another lifetime and carries on. This holds for every directed message that has reached the point of asking for a relay, and for mail waiting for a gateway. A message that is waiting is never dropped for having waited.

A station with a working radio will sooner or later hear the destination, a helper or a gateway, and waiting costs nothing on the air: while the station hears nobody, a deferred message makes it transmit nothing at all.

Deferred messages are tried oldest first, even when newer traffic is queued behind them.

20.6.1 Retry gaps

Patience does not mean pestering. Two conditions must both hold before a deferred message is tried again:

A message that has waited all afternoon therefore asks about twice an hour, not twice a minute. What a retry consists of, a direct send if the destination has been heard and otherwise a new request for a relay, is in Section 19.7.1. Mail waiting for a gateway uses the same doubling gaps between its tries. The separate slowing of new bulk transfers on a channel that shows collisions is in Chapter 17.

20.7 Across a restart

What comes back after the station program is stopped, or crashes, depends on how far each message had got:

Anything the station held only in memory is gone: a relay search in progress, a partly received message, a promise to relay for someone.

20.8 Whose clock?

Every wait in this chapter is measured by one station, on its own clock, from things it observed itself: the end of its own transmission, the moment it decoded a frame, the last time it heard a callsign. None of them compares one station's clock with another's, so two stations whose clocks disagree by an hour relay for each other just the same. The few clock times that do go on the air are counted as Section 21.5 describes.

20.9 What to remember

Chapter 21

Inside a Payload

21.1 The layers, from the outside in

A message is a letter in a set of envelopes. The outermost belongs to the transport: the frames, the error correction and the two-byte integrity check, which travels in front of the data (Section 16.2.3). Inside that, every size of message looks the same.

Reassembled message (after error correction) integrity check 2 bytes envelope byte 1 byte crypto header only if encrypted compressed together (when that helps) kind byte body text, mail, map objects, weather... HOW it is packed WHAT it is did it arrive intact? Receiver, left to right: envelope byte, decrypt, decompress, take off the kind byte, verify the check over the body.
Figure 21.1. The layers of an mLink message. The envelope byte is always first after the transport's own check; the kind byte always sits inside the part that gets compressed (and sealed, when encryption is used).

The sending station builds the layers in one place, in this order:

  1. it computes the integrity check over the message exactly as the client handed it over, before anything is added or squeezed (Section 16.2.1);
  2. it puts the kind byte in front of the message;
  3. it compresses kind byte and message together, and keeps the result only if it is smaller;
  4. if encryption was asked for, it seals what it has (Chapter 26);
  5. it puts the envelope byte in front.

The receiving station undoes them in the opposite order, also in one place, for every kind of delivery: read the envelope byte, decrypt, decompress, take off the kind byte, verify the check over what is left, and hand the content to whichever part of the station handles that kind. Anything added at that one place, such as a new dictionary, reaches every kind of message at once.

21.2 The envelope byte

The first byte of every message is its envelope byte. It answers one question: how were the following bytes packed? It says nothing about what they are for.

Table 21.1. The eight bits of the envelope byte (bit 0 is the least significant).
BitsNameMeaning
0compressed0 = sent as it is; 1 = compressed with zstd.
1reservedSent as 0; ignored on receipt.
2text1 = the content is text for a person to read. Set for text messages and net bulletins. A hint only, since the kind byte already says what the content is.
3–4encryption0 = in the clear; 1 = sealed with a shared group key; 2 = sealed for one recipient using certificates; 3 = reserved for a one-time pad, and a station neither sends nor accepts it. The modes are explained in Chapter 26.
5–6dictionaryWhich shared compression dictionary was used: 0 = none; 1 = the operator-text dictionary; 2 and 3 are unassigned. It means something only when the compressed bit is set.
7extensionAlways 0. A receiver that sees it set drops the message.

So a chat line that compressed well with the text dictionary carries compressed = 1, text = 1, encryption = 0, dictionary = 1: the byte 0x25. A weather report that went out as it was, in the clear, carries 0x00.

21.2.1 Room to grow, and failing loudly

Two bits are held back. Bit 1 is simply spare. Bit 7 is the extension bit: if mLink ever needs more bits, a set bit 7 will mean "a second envelope byte follows". A station today does not know what that byte would say, so it refuses the whole message instead of guessing.

The same rule covers the dictionary field. If a message names a dictionary the receiver does not have, decoding through another would produce plausible-looking nonsense, so the receiver drops the message and logs why. An operator sees a delivery that did not happen, never a mail full of scrambled words.

21.2.2 What protects the two wrapping bytes

The integrity check covers the message, not the envelope byte or the kind byte in front of it. Those two rely on the error correction that carried them, which rejects a frame it cannot repair (Chapter 9). Most damage to the envelope byte would show anyway: a wrong compressed or dictionary bit makes decompression fail or yield different bytes, and then the check does not match. A message that fails to unwrap is dropped and not acknowledged, like one that fails its check. In a sealed message the envelope byte is also covered by the seal.

21.3 The payload kind byte

Once any encryption and compression are undone, the first byte of what remains is the payload kind. Where the envelope says how, the kind says what, and the station hands the rest to the part of itself that knows that format.

Table 21.2. The payload kinds in use.
ValueKindWhat the content is
0x00reservedNever sent. A message that shows it is dropped.
0x01textWhat you type into a chat.
0x02opaque dataArbitrary bytes a client program asked the station to send, delivered untouched.
0x03internet responseThe answer to a request for internet data, such as a weather report (Chapter 27).
0x04mailSubject, recipients, body, attachments (Chapter 24).
0x05certificateA station's identity certificate. Always sent in the clear (Chapter 26).
0x06map overlayMap objects: points, lines, areas (Chapter 28).
0x07mailbox controlMailbox requests to a gateway out of direct range, sent as a message so that they can be relayed.
0x08mailbox listingA gateway's list of waiting mail.
0x09mail bundleSeveral whole mails for the same destination in one transmission.
0x0Anet rosterA virtual net's whole roster, sent by a member to a station that asked for it (Chapter 22).
0x0Bnet bulletinText to a virtual net that every member must have. It is kept and shown as text.
0x0Cnet standing ordersOne mail holding a virtual net's standing orders. It has its own kind so that none of the ways ordinary mail is passed along acts on it.
0x0Dnet held mailNet control's list of the mail it keeps for members who are off the air (Section 22.8).

Values 0x0E and 0x0F are kept for mLink's own future use. Values 0x10 to 0xFF are open for other programs and experiments. A station that receives a kind it does not know logs it and discards the content. The bytes arrived correctly, so the transfer is still acknowledged, but nothing unreadable is put in front of the operator.

21.3.1 Why two bytes and not one

The envelope is about transport: whether to decompress, whether to decrypt. It has to be readable before anything else is done. The kind is about the application: which part of the station gets the content. Keeping them apart leaves the envelope its spare bits and gives the kind 256 values of its own.

It also keeps the kind private. The kind byte sits inside the compressed and sealed part, so a listener to an encrypted message, or a station relaying it without the key, cannot tell a chat line from a mail.

21.4 Compression

A byte that never has to be transmitted is the cheapest byte there is, so every message gets a chance to be made smaller before it goes out. mLink compresses with zstd (Zstandard), a widely used, openly published compressor, run at its strongest setting. That costs a fraction of a second of computing on the sending side, which is nothing next to the seconds of transmitting it saves, and the receiving side decompresses just as fast whatever setting the sender used.

21.4.1 Compressed only if smaller

A compressed stream carries a few bytes of its own bookkeeping, so a very short message, or one that is already dense like a photograph, can come out larger. So the sending station tries and compares:

  1. the content as it is;
  2. the content compressed with plain zstd;
  3. for text messages, mail, net bulletins and standing orders only, the content compressed with the shared text dictionary (below).

It sends the smallest. A compressed form wins only if it is strictly smaller than what it would replace, and the envelope byte records the choice.

21.4.2 The shared text dictionary

A compressor learns the patterns of a message from the message itself, and a typical radio message, a few dozen to a few hundred bytes, is over before there is anything to learn. A compression dictionary gives both ends a head start. It is a block of typical content prepared in advance and built into every station, so the compressor can say "the next 30 characters are the same as this stretch of the dictionary" from the very first byte.

mLink has one dictionary today. It is 8,192 bytes, made from about 420 sample amateur messages: net check-ins, contact exchanges, formal traffic in the National Traffic System style, position, status and welfare reports, search-and-rescue updates and short mail bodies.

The difference is large. A 257-character net check-in (callsign, grid, power, antenna, a welfare report, weather, "73") comes to about 195 bytes with plain zstd and to about 115 with the dictionary, well under half its typed size. A 35-character "QSL, see you on the net tonight. 73" does not get smaller either way, so it goes out as it is. A mail that is mostly an attachment gains nothing from a text dictionary, and then plain zstd or the plain bytes win the comparison: the dictionary can never make a message larger.

21.4.3 Size limits

21.5 The mLink time epoch

Some fields carry a time: when a weather observation was made, or "mail since this moment" in a mailbox check. Every such time on the air is counted from one fixed instant, the mLink epoch: 2020-04-20 00:00:00 UTC. Most fields count whole seconds in 32 bits.

Most computer systems count from 1 January 1970. Counting from 2020 buys two things. A 32-bit count of seconds lasts about 136 years, so it runs out in about 2156 instead of 2106, with no extra bytes on the air. And the numbers are small today, near 200 million late in 2026 against 1.79 billion, which leaves room for narrower fields where a time only needs a short range.

A time before the epoch is sent as the epoch itself. The epoch lives only on the air, and in the signed requests a station sends to the mailserver (Chapter 25). In the station's database and logs, and in everything it tells its client programs, times are ordinary Unix milliseconds. The station converts when it builds or reads a field, so no operator and no client program has to know the epoch exists.

21.6 The rule: payload details ride with the payload

Look over the announce frames (Section B.2) and a pattern shows. Every one is about who, when or what happened to a transfer. None says what a message is about or how it was packed. A text, a mail, a map object and a weather report travel the same way: an opening frame such as an RTS (Section B.8), some data frames, an ACK. What tells them apart is inside the message. That is a rule, and it has three reasons.

The test for something new is simple. If stations need it to decide who gets the bytes, when to transmit or what to repair, it belongs in an announce frame. If it only describes what the bytes are or how to read them, it belongs with the bytes: in the envelope byte if any kind of payload might want it, in the kind byte or the content if not.

21.7 What to remember

Chapter 22

Virtual Nets

The Nets window and its buttons are in Chapter 5. This chapter is about what the stations do.

22.1 What a virtual net is, and why have one

mLink's ordinary channel has no net control and needs none (Chapter 1). A virtual net is an optional layer on top. An operator opens a net under a name, such as TETON or MARITIME, and their station becomes the net's net control. Other operators ask to join and are given member numbers. The net can then do three things a crowd of peers cannot: know who is present, by a roll call in which every member answers in its own numbered slot; get a bulletin to everyone and know it arrived; and put its own traffic first when help is asked for.

The layer is opt-in in both directions. A station that never opens or joins a net works exactly as it would with no net on the frequency. Members still send ordinary messages to each other by callsign, and net control is not in that path: if it disappears, only the roll call and the bulletins wait for a new one. Net control carries no authority either. It keeps time, keeps the list and calls the roll; it cannot stop anyone transmitting, and any station may open a net under any name.

Any number of virtual nets may share a frequency as long as their names differ. Two nets that both call themselves TETON are treated as one net that has to sort itself out (Section 22.10).

22.1.1 Who is who

A station's part in a virtual net is worked out from what it has heard and done. It is never a separate setting.

Table 22.1. The parts a station can play in a virtual net
PartWhoWhat it does for the net
ownerThe station that opened the net, was handed it, or took it overIts net is the one that continues when a split heals. It ranks the alternates and sets the period and the net type. Usually it also runs the net.
net controlThe station running the net: the owner, a member the owner asked to run it, or a stand-inSends the anchor every cycle, keeps the roster, calls roll calls, sends bulletins.
stand-inA member that took over as net control while the owner was out of earshotEverything net control does; gives the net back when it hears the owner.
alternateOne of up to three members the owner has rankedGoes first, in rank order, when the net needs a stand-in.
memberA station that holds a member numberAnswers roll calls, passes along joiners net control cannot hear, can take over as net control.
bystanderA station that hears a virtual net but is not in itNothing. It keeps off the announce channel a roll call is using and lets the members answer first when help is asked for.

Any station that decodes a virtual net's anchor starts following that net as a bystander. A station follows one virtual net at a time. A station set to listen only follows the net and sends nothing.

22.2 The net's frames

What a virtual net sends for its own upkeep is ordinary 11-byte announce frames of one family, ANCHOR (Section 14.3), thirteen in all. Net control sends the cycle ANCHOR and the closing ANCHOR, the ROSTER entry, the ROLL and four kinds of TALLY. A member, or a station that wants to be one, sends the CHECKIN, the JOIN, the JOIN THROUGH (asking for somebody else) and the ROSTER REQUEST. The owner sends the INSTRUCT when another station runs its net. The bit layouts are in Section B.14.

None of these frames is acknowledged with a frame of its own. A station knows its request worked when it sees the result: a joiner is in when it hears itself on the roster.

22.2.1 Frames that travel alone

Nine of the thirteen ride behind the sender's PRESENCE (Section 14.5). Four do not: the CHECKIN, a station's own JOIN, the ROSTER REQUEST and the INSTRUCT carry the sender's full callsign inside the frame and go out as one frame with nothing in front of it. The reason is air time: in a roll call every member sends the same short answer in turn, and with the callsign inside each answer is one frame of 0.64 s instead of two. The callsign in the frame is the station's identification (Section 14.8).

22.2.2 Name, key and tag

Only the anchor carries the net's full name. The other frames identify the net in one of two shorter ways:

Five bits give 32 values, so two nets on one frequency can easily share a tag. That is fine, because the tag only narrows a frame down; something else always decides whether the frame is acted on. A check-in counts only when its callsign is on the station's own roster under the number the frame claims. A tally and a roster entry count only from the station's own net control. A roster request is answered only when the asker is on the answering member's roster. An INSTRUCT is obeyed only from the owner.

The one exception is the open check-in of a station with no number yet (Section 22.6.4), which is on nobody's roster. Net control accepts it when the tag fits, the frame arrives inside the open slots of net control's own roll call, and it names that roll call.

22.3 Opening, naming and joining

22.3.1 Net names

A net name is one to eight letters and digits, upper-cased. A message to a net is addressed to 0 followed by its name (Section 14.7), so eight is the most that fits a nine-character addressee, and the names CQCQCQ and CQQTH are refused because they would spell the all-stations and area addressees.

22.3.2 Opening a net

The station that opens a net becomes its owner, its net control and member 1, and sends its first anchor as soon as the rules for a beacon allow. There is no check that the name is unused: if a net of that name is already on the frequency, the two settle it between themselves.

The opener chooses two things, and both ride in every anchor. The cycle period is how often the anchor goes out: 300 s unless the opener picks another value from 150 to 600 s in steps of 30 s. Every wait in this chapter that is counted in cycles is timed by each station from the period it hears in the anchor. The net type is Casual or Safety Critical (Section 22.9.8).

22.3.3 Joining

A station asked to join a net waits until it hears that net's anchor, then sends one JOIN frame, alone, with its own callsign and the net's key. Net control lists the joiner, and the joiner learns it is in when its own roster entry arrives behind a later anchor.

If the entry does not come, the joiner asks again, more slowly each time: one cycle after the first JOIN, two cycles after the second, and so on. After six unanswered JOINs it stops and tells its operator. A standing join is remembered across restarts and starts the six tries again whenever the net is heard.

Each of these gaps, and further on each gap between re-sendings of an INSTRUCT, a member's bulletin and the owner's standing orders, also carries a random extra of up to 9 s on a small net and 18 s on a large one, so that members sent back to ask by one frame do not all key in the same instant a cycle later.

A member can ask for you. A member that decodes a JOIN from a station not on the roster keeps a note of it, and if the joiner is still not listed one cycle later (net control did not hear it) the member passes the request along as [presence][join through], with the joiner's callsign in the frame. Each member waits 1.5 s per member number beyond the cycle, so the lowest-numbered member who heard the joiner usually does it and the others see the listing and stay quiet. A member holds at most four such notes and passes each along once.

JOIN and JOIN THROUGH carry the same two things; the frame type says whether net control heard the joiner directly. A station listed from a JOIN THROUGH is marked heard through another member, and the mark comes off if its own JOIN gets through later. A joiner that hears its request passed along waits one cycle from that moment before it sends another JOIN.

Joining a net you cannot hear. A station in net control's skip zone never hears the anchor. When its operator asks it to join anyway, it listens for one cycle and then sends its JOIN regardless, on the same thinning schedule, for a member to pass along. In a Safety Critical net that member then speaks for it; in a Casual net it is listed but hears nothing back.

22.4 The roster and member numbers

The roster is net control's list of members. Each entry is a callsign, a member number and a few marks: listed on another member's word (heard through), did not answer the last roll call, has left the net, is the net's owner, is the owner's first, second or third alternate.

Numbers are handed out in order: the opener is 1, and each new member gets one more than the highest number on the roster. They are never reused: a member who leaves keeps its number, marked as left, and gets it back on return. The limit is 127, because a member number is seven bits and zero means "no number"; a joiner beyond that is not listed.

22.4.1 How the roster reaches the members

Up to three ROSTER frames ride behind each anchor, in the same transmission. A new or changed entry goes first, then the entries follow in rotation, so a newly listed member normally hears its own entry at the next anchor and a net of a dozen goes round in four. A full net of 127 would take 43 anchors, which is why a member has two faster ways to fill in its copy, described below.

Every change to the roster moves its edition on by one. The edition counts from 1 to 15 and starts again at 1; the anchor, every ROSTER frame and the ROLL carry it. Stations only ask whether two editions are the same: an anchor whose edition differs from a member's copy says changed entries are still to come round. The anchor also carries the highest member number on the roster, so a member whose copy holds fewer rows can see it is short. A listed station that sends JOIN again has not heard its own entry yet, and net control moves that entry to the front of the rotation.

The owner's entry rides in the rotation marked as the owner's, whichever station sends the roster, so that every copy says whose net this is. A stand-in sends no entry for itself: its PRESENCE already says who runs the net.

Net control keeps its roster across a restart and comes back running the net, with the edition moved on by one; if the members seated someone else meanwhile, the two are settled like any two net controls (Section 22.10). A member does not keep its copy: it comes back with its net, its number and the owner's callsign, and collects the rows again from the air.

22.4.2 Rows learned from a roll call

A check-in carries a callsign and a member number, which is one roster row. A member following a roll call of its own net adds a row when it decoded the ROLL, the check-in is in a numbered slot inside the range called, it has no row under that number or for that callsign, and the frame arrived when that number's slot says it should. The timing is the evidence the tag alone is not. Net control never learns rows this way; its list is the original.

22.4.3 Asking a member for the whole roster

A station that wants the whole list at once sends one ROSTER REQUEST frame, alone: its callsign, the net tag, the number of the member asked (zero for "any member"), and whether it wants the roster, the standing orders (Section 22.7.3), or both.

Asked of "any member", the members who heard the request line up by member number, lowest first, since the longest-serving member is likeliest to hold a complete copy. Each place in line is three seconds, long enough for those further back to decode the opening frames of an answer, and a member that hears another member begin a transmission to the asker stands down. There are eight places; members further back share the last, and a member whose path to the asker is too weak for a bulk transfer (below +6 dB SNR@3k, or unmeasured) goes behind all eight. A member whose place comes up while the channel is busy or a roll call is running looks again shortly. A member asked by number answers straight away.

The answer is the whole roster as one ordinary directed, acknowledged message with its own payload kind (Chapter 21): the net's name, the edition, the owner's callsign and one eight-byte row per member, about 110 bytes for a dozen members and a kilobyte for 127.

The asker adds the rows it lacks. A row it already holds is replaced only when the copy is of the same edition as the entries the asker last heard from net control, because an entry heard from net control outranks another member's copy of it; for the same reason a number it holds under a different callsign stays. Its own row is never taken from a copy.

If no answer comes, the station asks again by itself, three times at most: 90 s after the first request and 180 s after the second, giving up 360 s after the third.

22.5 The anchor and net control's cycle

The anchor is net control's heartbeat. Once every cycle period, give or take up to a fifth, net control sends

[presence][anchor][roster][roster][roster][hello][hello][hello]

on any free announce channel: the anchor, up to three roster entries and up to three HELLO frames (Section 18.7.1), a little over five seconds of air at most. It goes out under the rules of any beacon: the station is idle, an announce channel is free, no roll call is running, and the beacon's random wait has passed (Section 17.7.1). It also restarts the station's ordinary beacon timer. The spread in the period keeps two stations that send anchors for one net without hearing each other from landing on top of each other cycle after cycle.

One anchor frame carries the net's full name, its cycle period and its type; the roster edition and the highest member number; and:

A closing anchor has the same shape. It says whether the whole net is closing or only net control is stepping down, and in place of the first alternate it names the member the seat is handed to.

22.6 Roll call, check-ins and the tally

In an mLink roll call, net control sends one frame and every member answers in its own numbered slot, one after another.

22.6.1 The call and the slots

Net control sends [presence][roll] on a free announce channel, and the whole roll call stays on that channel. The ROLL carries the net's key and tag, which roll call this is, the first and last member numbers called, the roster edition, and a bulletin tag that is zero for an ordinary roll call. By default the call runs from the lowest to the highest number still on the roster. Net control's own number and members who have left are not called when they sit at either end; every number in between keeps its slot whether or not anyone will answer in it, which is what lets any station place any slot from two numbers and a constant.

A slot is 1.2 seconds, always, and is carried on no frame: 0.64 s of check-in and a margin for each member timing the slots from its own decode of the ROLL. The first slot starts 0.4 s after the ROLL is decoded, member n's slot starts (n − first) slots later, and the member keys its check-in exactly at the start of its slot. Net control, which cannot decode its own frame, counts from the moment its transmitter reports the ROLL sent.

Only two things keep a member out of its slot: an exchange of its own that is still under way, or a distress exchange (Chapter 23). A member held up that way may still start up to half a second into the slot. Later than that the frame would run into the next slot, so it lets this one go and gets a second try in the tail.

22.6.2 The check-in

A check-in is one CHECKIN frame, alone, in the member's slot. It carries the sender's callsign; the net tag and which roll call it answers; the sender's member number (zero means "I hold no number yet: list me"); how many slots come after this one, 0 to 30 exactly and 31 for "31 or more"; one other member's number that this station heard; and six marks:

Vouching up front. In its numbered slot, a member puts in the heard field the number of the last member it heard check in before it. Net control then counts that member as present even if it missed the check-in itself, and marks it heard through. A frame net control lost in a one-second fade is repaired by the very next check-in, and the roll call often needs no tail at all.

Finding your slot without the ROLL. A member that missed the ROLL places the roll call from a check-in whose callsign is on its own roster under that same number and which is not out of turn. The sender's slot began about 0.9 s before the decode finished, so its own slot is (its number minus the sender's) slots later, and the last slot is the sender's plus the count that comes after. If its own slot has gone by, it waits for the tail.

22.6.3 The tally and the tail

Half a second after the last slot, net control sends a TALLY behind its PRESENCE: who was called and not accounted for. A member is accounted for if net control heard its check-in or another member named it.

One frame has 64 bits for the answer and a net can hold 127 members, so there are four kinds of tally:

  1. Missing list. Up to nine missing numbers; an empty list means nobody is missing. This is the tally of nearly every roll call.
  2. Heard list. If more than nine are missing but nine or fewer were heard, the heard numbers; every other number called is missing. It is used only when every number in the range belongs to a member still in the net.
  3. Low map and high map. Otherwise one bit per member number, set for a missing one: numbers 1 to 64 in the low map and 65 to 127 in the high map. A map is sent only if somebody is missing on its side. When both are needed they go as [presence][low map][high map], and the first says one more follows.

Every tally also carries the net tag, the roll call it belongs to, a final mark and the length of the tail that follows. With nothing missing, the TALLY is final and the roll call is over. Otherwise there is a tail in two parts:

  1. Second tries. One slot for each member named missing, in number order. A missed check-in is nearly always a fade, so the station most likely to fix it is the missing member itself a few seconds later. Its second check-in is marked out of turn.
  2. Vouch slots. Then one slot for every number called, in order. A member that decoded a missing member's check-in itself, and has not heard anybody else speak for it, says so in its slot: one check-in, out of turn, with the missing number in the heard field.

After the tail net control sends the final TALLY, and the "did not answer the last roll call" marks on every station's roster follow it.

A member that placed the roll call from a check-in does not know which number was called first, so it can take its second try but cannot place a vouch slot or read a heard-list tally.

ROLL numbered slots TALLY tail slots FINAL open slots 2345 52345 123 net control member 2 member 3 member 4 member 5 joiner R T F #2 #3←2 #4←3 #5←4 #5 +5 #0 missing5 missingnone members hold routine traffic; everyone else keeps off this announce channel #4←3 = check-in by member 4 that names 3 as the last member it heard; dashed = net control did not hear it; +5 = a vouch for member 5; #0 = a check-in from a station with no number yet. The first tail slot is member 5's second try; the vouch slots follow. Each slot is 1.2 s.
Figure 22.1. One roll call, calling members 2 to 5. Net control misses the check-ins of members 3 and 5. Member 4 names 3 as the last member it heard, so 3 is counted present and the tally lists only 5. In the tail, member 5 checks in again, and member 4, the one member that decoded 5's first check-in, vouches for it. The final tally is clean. A station that asked to join but has no number yet checks in during the open slots.

22.6.4 The open check-in

The final TALLY also asks "any late or new check-ins?": three open check-in slots follow it. A station that has asked to join but has no number picks one of the three from its callsign mixed with the roll call's number (two joiners that collide once do not collide every time), adds a small delay within the first quarter of the slot, and sends one CHECKIN with number zero. Nobody owns an open slot, so here the station does check that the channel is quiet first.

Net control lists a station it hears in the open slots at once. The joiner then waits for net control's next anchor, which carries the newest roster entry first. If that anchor does not list it, the joiner sends an ordinary JOIN five seconds later; if no anchor is heard, after two cycles.

22.6.5 The hold

The stations that hear a roll call stand back from it. How far depends on who they are.

A member, net control included, holds all its routine traffic on every channel from the moment it decodes the ROLL: new messages, beacons, JOINs and other voluntary frames wait. Replies to exchanges under way and anything to do with distress are not held. From the ROLL the hold covers the numbered slots, the tally and the longest tail this roll call could have, two more slots per number called; a TALLY with numbers missing says how long the tail really is. The hold ends at the final TALLY plus the three open slots, or when the time runs out. A member that placed the roll call from a check-in holds too.

Everyone else (a bystander of this net, a station in another net or in none) keeps off the one announce channel the roll call runs on, by treating it as reserved (Section 17.2), and carries on as usual on the other two and in the bulk region. Such a station need not have heard the ROLL. Every check-in says how many slots come after it, so a station that decodes any check-in, of any net, keeps that channel clear until those slots and the tally behind them are over, and each later check-in corrects the estimate. A TALLY with numbers missing keeps it clear through the tail.

A roll call of a twelve-station net (net control and eleven members) with nobody missing takes about 21 seconds from the first frame to the last open slot. One member missing adds a tail of twelve slots and a second TALLY, about 17 seconds. A member that decodes that ROLL and nothing after it holds for about 45 seconds.

Distress beats the roll call: a station that hears a distress call, or raises one, abandons the roll call and drops the hold at once. And outside roll calls, everyone who follows a net listens to a bulk transfer to or from one of its members for its whole length (Section 17.6).

22.7 Messages and bulletins to the net

22.7.1 A message to the net

Any station can address a message to 0 followed by the net name, for example 0TETON. It is a reserved addressee, so the message is sent as a broadcast: one transmission, no ACK (Section 16.8). Every station that decodes it keeps it. What differs is who is alerted. A message from a member or from net control alerts net control and every member. A message from outside the net is usually a question for net control, so only net control is alerted, and told the sender is not a member. Stations not in the net keep either kind quietly.

A member that catches only part of a message to the net asks for the missing piece with the usual say-again for broadcasts (Section 17.8). A bystander does not ask for missing pieces of a broadcast from a member of the net it overhears.

22.7.2 The bulletin and the receipt roll

Some traffic every member must have, such as a change of frequency. For that, net control sends a bulletin of up to 200 characters, in two steps:

  1. Net control sends the text as a message to the net, under a payload kind of its own so that every station shows it as a bulletin.
  2. Once that has gone out, net control calls a receipt roll: a roll call of every member whose ROLL carries a bulletin tag, eight bits made from the bulletin's message id (Section 16.2.2) and never zero. Each member answers in its slot as usual and sets "has the bulletin" if it holds a message from net control to this net whose id gives the same tag; members remember the ids of the last eight such messages. A "got it" left over from an earlier bulletin therefore cannot be mistaken for the new one.

If anyone lacks the bulletin (a member that did not check in counts as lacking it), net control sends it once more and calls one more receipt roll. A member that said "has the bulletin" the first time keeps that credit. Then net control tells its operator the result: every member has it, or the callsigns of those still lacking it, who can be reached by directed mail. One bulletin is in progress at a time. If net control loses the seat, the bulletin cannot be sent, or distress interrupts its roll call, the operator is told it was not confirmed.

The receipt rides in the check-in a member would send anyway, and a receipt roll is a real roll call in every other way, so the net pays for one round of slots and not for a dozen ACKs keyed in the same second.

A member's bulletin. Any member can send a bulletin: its station sends the text to the net marked as one. Net control's station takes it up without its operator doing anything. It sends the text again as its own bulletin, with the member's callsign in square brackets in front, and runs the receipt roll on that. If another bulletin is still being confirmed, net control does not take the second one up and its operator is told. The member's station listens for net control's sending of its bulletin. If that does not come within one cycle it sends the bulletin again, and a third time two cycles after that; four cycles later it tells its operator. Net control takes a given bulletin up only once.

22.7.3 Standing orders

A bulletin is news. A net's standing orders are the opposite: what every member is to know and do for as long as the net runs, such as how to check in and what to do after losing the net. A station that joins late must get them.

Standing orders are therefore mail (Chapter 24): one mail addressed to the net that carries a "standing orders" mark, a subject of up to 60 characters and a text of up to 1,000. Every member that takes them files them with its other mail. On the air they travel under a payload kind of their own, so that none of the machinery that carries ordinary mail for other stations acts on them, and the mail server plays no part. Only the net's owner or the station running the net may post them. The post goes to the net once, as a message to the net, and a later post replaces the one before.

What is current. Every ROSTER frame carries eight bits that name the current standing orders, or zero when the net has none. The value is computed from the mail itself, so every station holding the mail computes the same one, and a station learns that standing orders exist from the same frame that tells it it is listed. A net control that knows a different copy was current under the net control before it names none.

Who is believed. A member takes a copy as the net's standing orders in two cases only: the owner or its net control sent it, or another member sent it and it is the very copy net control names. Anything else is refused and not kept. Like every net frame this rests on the sender's callsign; nothing is signed.

Getting a copy. A member that missed the post, holds an older copy, or joined afterwards sees a value in the roster entries that is not the value of what it holds. Every such member learns it from the same frame at the same instant, so none of them asks at that instant. Each:

  1. waits one minute, because a post on its way usually arrives by then. A station listed within the last two cycles that holds no copy has nothing on its way and skips the minute;
  2. picks a random time: one of four to eight slots (more when more stations have been heard lately), a little under two seconds apart, counted only while the channel is quiet;
  3. sends one ROSTER REQUEST marked "standing orders".

The members that hold the current copy answer as they answer a request for the roster (Section 22.4.3): they line up by member number, the first sends the mail to the asker as one directed, acknowledged message, and the others stand down when they hear it start. An unanswered request is repeated on the roster request's schedule, each time after a fresh random time, so two stations that picked the same slot key together once and then come apart.

One request is normally enough for everybody. A member that lacks the copy and hears another member ask before its own slot comes does not ask: it waits, overhears the copy sent to the asker and keeps it. Only if a minute passes and no copy has come does it start over with its own wait and slot. A station that has just taken a new post ignores roster entries naming a different copy for two cycles, because net control's entries may trail the post.

An owner that is not running the net. Members that hear its post take it at once, but the net as a whole learns of it from net control's roster entries, so net control has to take it up. The owner's station watches those entries and sends its post again if they do not name it: after one cycle, then two cycles later. Four cycles after the third sending it tells its operator.

22.8 Mail held for a member who is off the air

A mail between two members of a net often goes to a station that is not on the air: switched off, out of range, gone for the day. Outside a net that mail waits in the sender's outbox, and the sender's station keeps asking the frequency for a relay for as long as it stays on. In a named net, net control keeps the mail instead and hands it over at the member's next check-in. The sender may switch off.

22.8.1 When net control takes custody

The sender's station does nothing new. Its direct transfer goes unanswered, it sends a relay REQUEST as for any directed message (Chapter 19), and nobody who hears the member offers. Net control steps in only when all of these hold:

When it already has the mail. Every station keeps what it overhears, so net control usually heard the direct attempt. After decoding the REQUEST it waits until the last relay OFFER could have been heard: 18.5 seconds, plus 0, 0.5 or 1 second more, chosen from its own callsign and the mail's id. That puts its answer after every station that can reach the member and still inside the sender's search, so the sender hears it before giving up. If in that time it hears any OFFER, a SELECT or a RESULT for the mail, or another station's TAKEN, it says nothing: a relay or a gateway is taking care of it. It still records the mail as held, quietly, in case the relay never reaches the member. Otherwise it sends [presence][taken] with the status "held" (Table B.23).

When it does not. A later REQUEST invites stations that hold no copy, and a REQUEST for mail sent in the clear carries a bit saying so. On such a REQUEST net control offers "send it to me first", claiming no link to the recipient, in the late slots, so that any station that can reach the member is chosen first. If the sender chooses it, the mail comes across behind a HANDOFF frame (Section 19.7.2) and net control answers with TAKEN "held". A message that turns out not to be one it keeps is carried on as any helper would carry it, and net control offers for that message no more.

At the sender. The TAKEN closes the matter. The outbox row reads held, with the note "held by net control" and its callsign (Chapter 6). The station asks the frequency for that mail no more, chooses no relay for it, and never sends it again by itself; a fresh send is the operator's decision. A sender that missed the TAKEN asks again later, and net control answers again, no sooner than 15 seconds after its last TAKEN for that mail.

Net control's own mail to a member who is off the air is kept the same way without anything going on the air: the row reads held at once.

22.8.2 The "mail held" list

Net control tells its net what it is keeping with a short net document, the "mail held" list: for each mail the member's callsign, the original sender's callsign and the mail's id. It holds at most ten entries, 148 bytes in all, so it always fits one short transfer (Section B.14). Over ten, net control still keeps every mail; the list names the oldest ten.

The list works like the standing orders (Section 22.7.3). Eight bits folded from it, or zero when nothing is held, ride in every ROLL frame. Net control sends the list to the net whenever an entry is added or cleared, through its ordinary send queue and after any TAKEN of its own has gone, so the sender hears the TAKEN first. A mail kept quietly, behind a relay, is named only by the next ROLL. A member whose copy does not match the ROLL asks for the list exactly as it asks for stale standing orders, with the same wait and the same random slot, and believes a copy on the same terms: from net control or the owner, or from another member when it is the copy the ROLL names. Each member keeps the entries with its own records.

22.8.3 Delivery

Only the station in the seat delivers. A held mail becomes due when its member checks in at net control's roll call, however old the check-in, or, outside a roll call, when net control hears the member transmit after it began holding the mail, for five minutes after that hearing. A hearing from before the hold does not count: it is how net control knew the member was gone.

Net control delivers in the quiet part of the cycle: not during a roll call, its hold or the open check-in window after it. It sends the oldest mail first, one at a time, as an ordinary directed transfer, and not when the transfer and its acknowledgement would run into its next anchor. The transfer carries a FOR frame naming the original sender and the mail's id (Section 19.5), so the member files the mail under the person who wrote it. When the member acknowledges, net control sends TAKEN "delivered direct", and the sender's row, if it hears it, becomes sent. A delivery that is not acknowledged leaves the mail held. It never starts a relay search; the next chance is the member's next check-in or the next time net control hears it.

An entry clears only when the mail is delivered: by net control itself; by a courier whose TAKEN says "delivered direct"; by a relay whose RESULT reports delivery for a request net control heard; or when net control overhears another station's delivery fronted by FOR and the member's acknowledgement of it, such as a gateway handing over the copy from the member's mailbox. Held mail never expires (Section 20.4).

22.8.4 Leaving a copy at the mailserver

If a station with internet has been heard in the last two minutes and the member has not, net control hands each held mail that is not yet at the mailserver to a gateway, the way a courier does (Section 24.6.2). The gateway's TAKEN "deposited" marks the entry as also at the mailserver, and the sender's row becomes deposited. The entry stays on the list. The member can now collect the mail through any gateway anywhere, and net control still delivers it directly if the member checks in first. After such a direct delivery net control sends a short mailbox-control message, "delivered" (Section 24.9), to the gateway it deposited with, or to the gateway heard most recently, once one has been heard in the last two minutes; that gateway marks the member's copy delivered so it is not offered again.

22.8.5 When net control changes

A member that stands in for net control (Section 22.9) already holds the list, so the entries become its own. Its ROLL frames carry the same eight bits, and it delivers each mail from its own copy, which it has because it overheard the mail when it was sent. A stand-in that never heard a mail cannot yet fetch it, so that entry waits for a station that holds it. When the owner comes back and takes its seat again it keeps its own records and its list goes on from there.

When a net splits, two stations may each think they are net control. Both may keep the same mail and send TAKEN "held", and both may deliver it. The member files it once and discards the second copy, because a mail is known by its author and its id.

22.9 When net control goes quiet

When net control fades out or goes off the air, the net does not end: a member takes over, and the name, the roster and the member numbers stay as they were.

22.9.1 Noticing the silence

A member considers net control gone when it has heard nothing from it for three and a half cycles: 17.5 minutes at the normal period. An anchor, an anchor said again by a member, a ROLL or a TALLY all count as hearing it. The wait is that long because the station running a net is also the busiest station in it: its anchor waits its turn behind the net's own traffic and can come more than a cycle late. A shorter wait would have members trying for the seat of a net control that was there all along.

Only members take over. A member also holds back if it has heard another member's check-in within the same three and a half cycles: other members are answering roll calls, so net control is alive and merely a hidden station to this member.

22.9.2 Who takes over

The members do not vote on the air. Each works out, from the HELLO reports in its links map (Section 18.8), how widely it is heard by other stations; its own claims about itself do not count. To be considered at all, a member must itself report at least two stations it hears, and at least one of those must report hearing it. A station that cannot hear, or cannot be heard, never takes the seat, whatever is said below about who goes first.

The member that ranks itself first claims first; each lower rank waits three more seconds, plus a random amount of up to about two. A claim is simply an anchor with the next term and the cycle period the net was running on. Being an anchor, it also takes the random wait every beacon takes, up to between 9 and 18 seconds, so the order is a tendency and not a schedule. What makes it work is that a member that hears a claim before its own has gone out drops its own and follows the new net control. Two claims at nearly the same moment are settled like any two net controls (Section 22.10).

Once seated, a net control stays until it goes silent, steps down or gives way under those rules. A better-placed member does not replace it: the scores move with propagation.

22.9.3 The owner and the stand-in

Every member remembers the callsign of the net's owner. A member that takes over while the owner it knows has merely gone quiet does not become the owner. It becomes a stand-in: it runs the net exactly as net control does, and every anchor it sends says so, in one bit of a frame that is sent anyway.

It matters because of the shape HF gives a net. A net seldom loses its net control for good; it loses half its members for an evening. The skip changes, the far half hears three and a half cycles of silence and seats one of its own, and the net carries on in two pieces. When the band comes back the two pieces are one net, and the original should simply continue, whichever half is bigger:

The numbers come through intact. Everyone listed before the split is still on the owner's roster under the same number. A station that joined the stand-in's half during the split holds a provisional number, because the owner's half may have given the same one to someone else; when the owner returns it gives the number up, and the owner lists it afresh.

A station becomes the owner by opening the net, by being handed it in a plain goodbye from the owner, by taking the seat after the owner has stepped down, or by its operator's decision to take over a net it stands in for. A station that has only ever followed a stand-in and never learned whose net it is stands in too if it takes the seat. Across a restart an owner comes back as the owner and takes the net back from an ordinary stand-in at once; a stand-in comes back standing in.

Taking over for good. If the owner is gone for good, the stand-in's operator can make the net theirs. Nothing on the air changes except the stand-in mark. If the old owner comes back after that, the net stays with the station that took it over, and the old owner rejoins as a member. Both can tell from the air: the new owner is on the old owner's roster and its anchors carry a newer term, which only a station seated later can have. This is the one use the term has in a virtual net.

22.9.4 Alternates

The owner can choose who stands in for it by ranking up to three members as alternates. The first alternate's number rides in every anchor and all three ranks ride in the roster entries, so choosing them costs no extra air. When net control goes quiet, alternate 1 claims first, alternate 2 three seconds later, then 3, and every other member waits as many three-second steps as there are alternates before its own claim. An alternate's claim skips the beacon's random wait, though it still needs a clear channel.

Each member counts the silence from the last anchor it heard itself, so a member that missed one more anchor than the alternate can still claim first. The member running the net then hands it to the best-ranked alternate that answers its roll call, with the goodbye that names a successor. Only the owner, or a station the owner has asked to run the net, can rank or drop alternates.

22.9.5 Letting another station run the net

Net control is a job, done best by the station that hears the most members, and that is not always the station whose operator opened the net: a net opened from a valley is better run from the hilltop. So the owner can hand the job to a member and stay the owner. On the air this is the goodbye that names a successor (Section 22.9.9), with one mark added to the closing anchor: "by the owner's wish". Because of it:

A station running the net this way can rank alternates and change the period and the net type, which an ordinary stand-in cannot. No alternate replaces it while it is on the air, and if a member that cannot hear it claims as an ordinary stand-in, the owner's choice keeps the seat whatever the two member counts are. If it goes quiet, the members choose as always, and whoever is seated then is an ordinary stand-in.

The owner's instructions. The owner keeps its powers from where it sits. Removing a member, ranking an alternate, changing the period or the net type, handing the job to a different member and closing the net each go to the station running the net as one INSTRUCT frame, alone: the owner's callsign, the net tag, what is to be done, and the member number or value it applies to. That station acts only for the owner it knows, and schedules an anchor three seconds later so the owner sees the result. There is no reply frame. If the change does not show in the anchors and roster entries, the owner's station sends the frame again after one cycle and a third time two cycles after that; four cycles later it tells its operator.

The owner and the seat. If the owner stops hearing the station that runs its net, that station may still be running it perfectly well for everyone else. After the usual silence the owner may claim the seat, as any member may, but it claims as a stand-in, and gives way if the station it handed the job to turns out to be there. Only its operator's decision to take the job back makes the owner claim as the owner, and the station running the net then gives way as a stand-in does when its owner returns.

22.9.6 Is this a good seat?

A station cannot tell by itself that it is a poor place to run a net from, but a roll call shows it. After each roll call it ran, net control's station tells its operator how many of the members called it heard itself, how many it counted only on another member's word, and how many nobody heard.

It also finds, from the members' HELLO reports (Section 18.7), the member that reports hearing the most other members. When at least three members were called, fewer than half were heard from the seat, and that member hears more of the net than this station does, the operator gets one notice naming it. The comparison counts who each station hears, not who hears it: a station with a big signal and a noisy receiver is heard by everyone and hears almost nobody. Nothing goes on the air and no seat moves: who hears whom changes by the minute on HF, so the station reports and a person decides.

22.9.7 Members who cannot hear net control

A member that cannot hear net control must not conclude that the net has lost it. Besides the check-in rule above, three things keep one net from becoming two.

After a hand-over, wait. A member that hears a goodbye naming another member as the next net control does not try for the seat itself, even if it never hears that member. It waits the usual three and a half cycles and two more, and any sign in that time that the net is being run settles the matter: an anchor, an anchor said again by a member, a roll call, a check-in, a tally.

The old net control says the new one's first anchor again. The station that handed the seat over listens for its successor's first anchor and repeats it once, as [presence][anchor] marked as said again. Such an anchor carries net control's own fields plus net control's member number, so a listener can tell whose it is. A station in the net takes one only from a member on its own roster, treats it as if it had heard net control itself, and remembers which member it came through.

A wrong claim is corrected by the members who hear both. If a member that cannot hear net control claims the seat, net control may never hear the claim, and nothing would ever tell the claimant it had lost. So each member that follows a live net control and decodes the claim gets ready to say net control's anchor again for the claimant. They do not all speak: they stand in a line by member number, three seconds apart, after first leaving three seconds for net control to answer for itself. The wait is counted only while the channel is quiet, so the order holds. The first one speaks; the rest decode its anchor and stand down. The claimant then gives way under the rules for two net controls and ends up a member again under the number it had.

Two things keep it from trying again straight away. For as long as it still hears the member it reaches net control through, it does not try at all: the members who do hear net control will deal with a real vacancy. And when the net control it gave way to runs the net by the owner's wish, each time it gives way doubles the silence it waits for before its next attempt, up to sixteen times the usual.

22.9.8 Casual and Safety Critical nets

A net has a type, chosen when it is opened and carried as one bit in every anchor. A Casual net is the default: an evening round-table on a busy band, where nothing is said twice. A Safety Critical net is for when every member has to be reached and the frequency is the net's to use: a search, a storm watch. The owner, or a station running the net by the owner's wish, can change the type while the net runs. The rest of this section happens only in a Safety Critical net. One more difference is in the mail chapter: a member of a Safety Critical net that has internet asks over the air for every mail whose recipient it has not heard, as well as leaving a copy at the mailserver (Section 24.4.2).

One member speaks for each station that cannot hear net control. A station gets such a member in one of two ways, each of which already has a single speaker: the member passed the station's JOIN along, or it corrected the station's claim to the seat. A member speaks for at most four stations. For each of them it:

The station takes roster entries, and the value that names the standing orders, on that member's word, and asks it once for the whole roster. At a roll call it places its slot from a check-in it can hear and answers there; the member hears the answer and names it in a check-in of its own.

A member stops speaking for a station when it has not heard it for half an hour, when the station leaves, or when the net stops being Safety Critical. A station taken on by passing its JOIN along is also let go as soon as net control lists it plainly, and whenever the net gets a new net control, because it may hear the new one. If it cannot, it will claim the seat sooner or later, be corrected, and be taken on again; one taken on that way is kept.

Net control repeats what members say. Every text message to the net of up to 400 bytes that net control copies from a member, it sends once more itself, with the first sender's callsign in square brackets in front. Two members that cannot hear each other but both hear net control get each other's traffic this way. Each station keeps track of the messages it holds and the ones it has said again, so nobody is alerted twice and nobody repeats twice. A message to the net is thus sent twice, and three times when a station that cannot hear net control is involved, which is air time a Casual net on a shared frequency should not spend.

22.9.9 Stepping down, and the named successor

A net control that is leaving says so with one goodbye, [presence][roster][anchor]: its own roster entry, then a closing anchor that says the net goes on. Members that hear it cut the three and a half cycles to five seconds and then choose a new net control as above. If a roll call is running, net control finishes it first. If the goodbye then cannot go out within 15 seconds because the channel stays busy, the station stops being net control anyway.

Stepping down is not leaving. The entry in the goodbye puts the departing station on every member's copy of the roster, and so on the next net control's, under the number it had. If its entry has not come round one cycle after it hears the new net control, it sends a JOIN like any returning member.

An owner that steps down gives the net away: the next station to take the seat is the owner. After a stand-in steps down the owner is who it was, and the next member seated stands in too.

Net control can also name its successor: the closing anchor carries that member's number. The roster entry goes ahead of the anchor on purpose, because the members count their five seconds from the closing anchor and a frame after it would eat into the successor's head start. When the five seconds are up the named member claims first, with no rank wait, no random delay and no beacon wait. Every other member waits one extra three-second step, hears the successor first and follows it. The naming lapses after two and a half cycles, or as soon as any net control is heard. A successor named by the owner without the "by the owner's wish" mark becomes the owner.

22.9.10 Closing the net

Net control's operator can close the net, and so can the owner through an INSTRUCT. Closing sends [presence][anchor] with a closing anchor that says the net is closed. Every station that hears it from its net control forgets the net: members lose their numbers and bystanders stop following it. A standing join survives, so those stations ask again the next time a net of that name is heard.

22.10 Two net controls under one name

Two net controls under one name happen in two ways. The common one on HF is a net that propagation split. The rarer one is two operators out of each other's earshot each opening TETON: two owners, two different nets. Each net control that hears the other applies the same tests in the same order, so exactly one gives way:

  1. Between two stand-ins, one that runs the net by the owner's wish keeps the seat.
  2. Between an owner and a stand-in, the owner keeps the seat.
  3. Between two owners of the same net (one took it over while the other was away), the one that took it over keeps the seat.
  4. Otherwise the live count decides.

22.10.1 The bigger live net keeps the seat

A net control's live count, the number in its anchor, is the members on its roster it has heard within the last three and a half cycles, plus itself. When both net controls own their nets, or both are ordinary stand-ins, the one with the higher live count keeps the seat. If the counts are equal, the alphabetically lower callsign keeps it. The term is not consulted. Both sides read the same two numbers and the same two callsigns, so both reach the same answer, and the one that keeps the seat schedules an anchor three seconds later so that nearby members hear it soon.

When the other owner is not on its roster, a net control knows two different nets have met, and tells its operator which net keeps the name. Renaming a net, or agreeing which net to run, is the operators' call.

Members apply the same tests to a rival anchor for their own net, comparing its live count with the one their own net control last announced. A rival that would win is followed at once. One that would lose is ignored while their own net control is still being heard, and remembered: if their own net control then goes silent for three and a half cycles, they follow the rival.

22.10.2 Handing over the roster

The net control that gives way sends the winner everyone on its roster who has not left:

[presence][join through m1][join through m2]...[join through m15]

Each frame is a JOIN THROUGH with one member's callsign. One transmission carries up to fifteen, the most a chain with no opener holds (Section B.3); a longer roster goes out as further chains five seconds apart. The former net control also sends a JOIN for itself.

The winner lists the handed-over members as heard through, with new numbers after its own members', whose numbers stand. Each member of the losing net sees that its net is run by a station that was not on its roster, which tells it this is a merge and not an ordinary change of net control. It drops its old number and roster and waits one cycle before sending a JOIN of its own, so the hand-over can list it first.

A stand-in handing back to the owner sends the same chain with a different outcome. Members listed before the split are already on the owner's roster and keep their numbers. Those the stand-in listed during the split get fresh numbers, and a member the owner dropped for silence during a long split gets its old number back.

22.11 Leaving, and dropping off after silence

There is no separate frame for leaving. A member says goodbye with a check-in that carries the "last check-in" mark.

Outside a roll call it sends one CHECKIN at the next free moment, marked "last check-in" and "out of turn", and forgets the net without waiting for confirmation. Net control accepts a check-in from a listed member outside a roll call for exactly this purpose: it marks the entry as left, keeps the number for a possible return, and sends the changed entry behind its next anchor. Members that decode the goodbye mark the row on their own copies straight away. During a roll call the goodbye rides in the member's own check-in, in its numbered slot; the member then forgets the net but goes on holding its routine traffic until the roll call is over. If its slot has gone by, the goodbye goes out after the roll call.

Stations also just disappear. Once a cycle, net control looks for members listed more than two hours ago that have shown no sign of life for two hours: it has not heard them, and no check-in has come from them or named them. A member that net control never hears directly but that the others vouch for at every roll call therefore stays. The silent ones are marked as left, numbers kept. A stand-in never drops the owner this way. Net control's operator can also remove a member sooner.

A member that hears its own entry come round marked as left, although it never said goodbye, takes it at its word: it stops answering roll calls and becomes a bystander, and its operator is told. A standing join for that net is cancelled too, so the station does not ask straight back in; the operator can join again by hand, and gets the old number back.

22.12 Members first

Three cooperative jobs spread their answers over time slots so that they do not collide: offering to relay (Chapter 19), carrying someone else's mail as a courier, and answering "who has mail for me?" (Chapter 24).

While a virtual net is alive on the frequency, each of those sets of slots is cut in two. A station helping its own net's traffic takes one of the early half; every other helper takes one of the late half. Nothing else about the timing changes. For a relay OFFER, which ordinarily has nine slots, a member helping a member answers in one of the first four and anyone else in one of the next four; the ninth goes unused. The station that asked chooses about two seconds after the first OFFER arrives, and volunteers still waiting stand down when they hear its choice, so in practice a member's offer is the one chosen.

Inside each half, a large net does not crowd the slots. When five or more stations could answer, each works out its own place in line and normally only the best two speak (Section 19.3.4). A member ranks itself among the members, and on an equal signal the lower member number is ahead.

"Its own net's traffic" means the message is addressed to this station, or this station is in the net and the message's sender or addressee is a member or net control. Everything else, including a bystander helping the net, is late. "Alive" means the station has heard its net's anchor, or another virtual net's anchor, within the last three and a half cycles.

The result is members first, not "members only": a bystander that is the only station able to help still answers, just later. Distress traffic is never affected by net membership.

22.13 What to remember

Part V: Services Built on the Protocol

Chapter 23

Emergency: The SOS Service

The screens for declaring, hearing and acknowledging an emergency are described in Chapter 5. This chapter is about what the station does.

23.1 The rule that outranks every other rule

Everything else in mLink is engineering, tuned for the typical case. The emergency service has three rules that are not open to that kind of trade.

  1. Never make emergency decoding worse. No change anywhere in the station may cost the emergency receiver even a marginal amount of sensitivity, whatever it buys elsewhere and however rarely the loss would bite.
  2. Nothing blocks an emergency send. There is no form to complete, no field that must be valid and no confirmation that must be understood. The client may warn ("no position, rescuers cannot locate you directly") but it never refuses, and neither does the station.
  3. Every field is optional. Position, the nature of the trouble, how many people, who you are: each has a "not provided" value, and a call with nothing filled in is still a complete distress alert.

23.1.1 Sign-in and roles

Rule 2 reaches the station's access control (Chapter 7). Five commands count as emergency commands: declaring an emergency, cancelling one, acknowledging one, reading the lists of emergency codes, and listing the stations in distress. All five need only the lowest role, operator. And they still run for a session that an administrator's decision would otherwise close: an operator whose account was suspended or removed while they were signed in (the session then ends at their next ordinary command), and a walk-up guest who was signed in when guest access was switched off.

The exemption covers a session that already exists. On a station with walk-up access switched off, a stranger who walks up afterwards cannot sign in at all, and so cannot send anything, a distress call included.

23.2 What "comes first" means on the air

The emergency service has its own slice of the passband, the emergency region (Section 8.3). The regions do not overlap in frequency, so the receiver listens to all of them at once, and nothing else the station does switches emergency decoding off. The one limit is physical: a radio cannot hear while it transmits (Section 3.5).

On the transmit side, "emergency comes first" means these things and no others.

23.3 What an emergency message carries

The emergency region has its own slow modem, NB8FSK, which delivers one emergency frame of 11 bytes in 10.24 seconds (Chapter 10). An emergency message is 1 to 15 of those frames sent back to back in one transmission. Every frame starts with two header bytes: which frame this is and how many the message has, and the incident number that ties the frames of one message together. The other nine bytes are content. The layouts are in Section B.17; here is what the fields mean.

23.3.1 Frame 0: the whole emergency in nine bytes

Frame 0 is the only frame that must exist, and it is complete without the others. It packs what a rescue coordinator acts on into 72 bits:

The operator does not set the incident age. The station works it out from the time since the declaration before every pass, so a listener who first hears the call three hours in learns straight away that this is a survival situation, not a fresh accident.

23.3.2 Environment and nature

mLink asks two questions where many distress systems have one flat list, because a dispatcher decides two things. Which team to send depends on where the casualty is: on water, in wilderness, on a mountain, on a road, in an aircraft, in a building or underground. What that team must bring, and how fast depends on what is wrong: illness, injury, exposure, entrapment, fire, hazardous material, lost or stranded, violence, or disabled and adrift.

The station daemon owns these lists and hands them to any client that asks, so every screen uses the same words. A code the receiver does not recognise is shown as that list's "not provided" entry; it never causes an error.

23.3.3 The text frames: who you are and what is happening

Every frame after frame 0 carries thirteen characters of text, from one fixed set of 45: the space, the digits, the letters A to Z, and . , - / ? : + #. Lower-case letters are sent as capitals. Any other character is left out, never replaced and never a reason to refuse; the station tells the client how many it left out. Thirteen characters from that set fit exactly in nine bytes.

The text is two fields, identity and detail, sent as one run of characters: the identity, a separator, the detail, then padding to fill the last frame. The separator is a 46th value that stands for no printable character, and the padding is the same value. An identity with no detail carries no separator, so a 13-character identity takes one text frame, not two.

Fourteen text frames give room for 182 characters: identity, separator and detail together. Identity is free text (a callsign, a vessel name, a person's name); nothing checks that it looks like a callsign. If the text is too long, the identity is kept whole, up to 181 characters, and the end of the detail is cut off.

23.3.4 How an incident is recognised everywhere

Two numbers name an incident across the network. The first is the one-byte incident number in every frame header. The station keeps a counter that survives restarts and adds one for every declaration, so a station that reboots does not reuse a number listeners may still remember.

The second is a 16-bit check value computed over the decoded content: frame 0 with the incident age treated as "fresh", then the identity and detail text. The sender and every station that decodes the call arrive at the same value, and leaving the age out means it does not change as the call ages. The pair (incident number, check value) is what an acknowledgment must match to stop the call, and how every station recognises a repeat of an incident it already knows.

23.4 An active distress call

Declaring an emergency does not send one message. It starts the SOS beacon: the station builds the frames, transmits the first pass at once, and keeps repeating the same frames until one of three things happens:

The beacon never gives up by itself. The call is written to the station's database before the first pass, so a station that loses power or restarts while the SOS is active starts repeating again without anyone re-entering anything, with the incident age still counted from the original declaration.

Repetition is how a whole message gets through at −17 dB SNR@3k when a single pass is dependable only to about −15 (Section 10.8). And a neighbour that was transmitting during one pass heard none of it; it will hear a later one.

23.4.1 When the next pass goes out

The schedule has two rules, and the later of the two wins.

  1. A repeat rule: the next pass is due 75 seconds after the current pass was keyed, plus a random 0 to 15 seconds.
  2. A listening rule: after the station stops transmitting (anything at all, not only the SOS), it listens for at least 15 seconds, plus a fresh random 0 to 15 seconds, before the next pass may key.

The random parts keep two stations in distress from falling into step and colliding on every pass. The listening rule exists for the acknowledgment described below: the answer to an SOS is one ten-second frame that must fit in the gap between passes.

For a short call the repeat rule decides: a one-frame call takes about 10 seconds, repeats every 75 to 90, and leaves 65 to 80 seconds of listening. For a long call the listening rule decides: an eight-frame call is about 82 seconds of air, so its gap is 15 to 30 seconds, and the longest call, 15 frames, repeats about every 169 to 184 seconds.

In distress emergency region A station that hears it Acknowledging station pass 1 (3 frames) listening gap (never under 15 s) pass 2 beacon stops rebroadcast on the announce band, 5 s or more after hearing pass 1 operator acknowledges announce-band ACK one-frame ACK in the emergency region 0 s 50 s 100 s
Figure 23.1. One SOS from start to finish (a three-frame call; times approximate). The distress station's passes and the one-frame acknowledgment both use the slow emergency region; the rebroadcast and the announce-band ACK are short bursts in the faster announce region. The acknowledgment keys the moment pass 2 ends, inside the listening gap, and the beacon stops before a third pass.

23.4.2 Cancelling

Cancelling stops the passes and clears the stored call. Nothing is transmitted to say so: there is no "cancel" frame. Other stations notice only that the passes have stopped, and their rebroadcasts stop too, because a station rebroadcasts again only while it keeps hearing the call.

23.5 Hearing an SOS

A decoded emergency frame must pass two cheap checks before the station acts on it, so that noise which happens to look like a frame cannot raise an alarm (Section 10.7.2). Those checks never judge the values in the frame: a strange position, an unknown nature code or an empty identity all pass.

23.5.1 Putting the message together

Frames are collected by incident number, in any order and across passes, and an unfinished message is kept for as long as it takes. The station follows up to six incidents at once; a seventh takes the place of the one that has been quiet the longest, so a new distress call is never turned away because a table is full.

A complete message is reported exactly once. Later passes are recognised as repeats, and each one tells the station that the incident is still active, which matters for rebroadcasting and acknowledging.

23.5.2 What a completed incident sets off

A newly completed incident, heard directly or through another station's rebroadcast, is stored in the station's message log with every decoded field, so a station with no client connected still holds it. It raises a critical notification on every connected client that spells out the incident in one line, including which station passed it on, if any. A gateway also hands it to the mail server, as described at the end of this chapter, and a directly heard incident is queued for rebroadcast.

If what the station hears is its own distress call coming back through another station's rebroadcast, nothing is stored; the operator is told that the call was heard and rebroadcast, and by whom.

23.6 Acknowledgment: how the repeats stop

The beacon keeps going until somebody takes responsibility. In mLink terms that somebody is an Authoritative Station. That is not a special kind of station and not a setting: it is whichever operator passed the emergency to the people who can respond (the coast guard, a sheriff's dispatcher, a search team) and says so on the air. Any signed-in operator may acknowledge an incident the station holds, adding a line of contact text (agency, reference number, phone).

The station records the acknowledgment at once, drops any rebroadcast of that incident it had waiting, and sends the acknowledgment two ways.

23.6.1 The announce-band acknowledgment

The first copy is a short chain in the announce region: the station's PRESENCE, then frames carrying the incident number, the check value and up to 118 bytes of contact text. It is sent once, as voluntary traffic, when the station is idle and an announce channel is free.

Every station that hears it records who acknowledged and the contact text, drops any rebroadcast it had waiting, and never rebroadcasts that incident again. If the station in distress hears it, and the number and check value match its own call, the beacon stops and the operator is shown who acknowledged and how to reach them.

23.6.2 The emergency-region acknowledgment

The announce region needs about −5 dB, but the SOS can be heard at −17 dB. In between, you can hear the distressed station perfectly well but it cannot hear your announce traffic at all. So the acknowledgment is also sent on the distressed station's own terms: as an emergency frame, decodable as deep as the SOS itself.

It is sent as a single frame 0. It carries the incident number and check value it answers, and two bits that mark it as an acknowledgment, so a receiver can never mistake it for a new distress call. Its own header carries the answered incident number with every bit flipped, so it cannot be confused with the frames of the call it answers. It carries no contact text, although the format has room for text frames: several frames might not fit in the distressed station's listening gap, and one frame always does.

This frame is not sent at the moment the operator acknowledges, because the distressed station is probably in the middle of a pass and deaf. The acknowledging station waits for the end of the next pass it hears:

It answers again at the end of later passes, no more than once a minute, for as long as it keeps hearing them. If a second operator acknowledged the same incident, whichever station hears the other's emergency-region acknowledgment first stands down, so the distressed station is answered by one voice and not a chorus.

A station in distress that hears only this frame stops its beacon just the same. It cannot name who answered, so the operator is told that "an Authoritative Station" acknowledged.

23.7 Other stations pass it on

The emergency region is slow and deep; the announce region is fast and heard by everyone near a station. A station that decodes a distress call directly therefore repeats it in the announce region, so that everyone within reach of that station learns of it too, including stations with a poor path to the person in distress.

The rebroadcast is one chain: the station's own PRESENCE, then up to 15 EMERG frames (Section B.10.1). They carry the incident number, the check value, the nine bytes of frame 0, and as much text as fits, packed as in the emergency region, which leaves room for 156 characters. Identity is kept whole; detail may be cut short. The check value is carried as first computed, never worked out again, so a copy with shortened detail still names the same incident. Receivers show the incident as heard "via" the rebroadcasting station.

Rebroadcasting is on by default and has its own setting, which takes the technician role to change. A station with it switched off, or set to listen only, still hears, stores and reports every incident to its own operator. The relay policy levels (Section 19.9) do not affect it.

23.7.1 Not everyone at once

If ten stations hear the same SOS, ten rebroadcasts would be nine too many, and ten stations keying at the same instant would destroy each other. So each station waits a hold-off that differs from station to station, and drops its own rebroadcast if it hears someone else's, or an acknowledgment, first.

The hold-off is at least 5 seconds. On top of that the station takes one of a set of slots 1.5 seconds apart, plus up to 0.45 seconds within the slot. Both come from scrambling the station's callsign together with the incident's check value and the time of the incident's last rebroadcast, so neighbours land at different times without any coordination, and two that share a slot once are unlikely to do so again. There are 8 slots, growing to 16 with the number of stations heard in the last half hour, so the wait runs from 5 seconds to about 16 on a quiet band and to about 28 on a busy one. A slot is longer than it takes to send and decode an announce frame, so a station in a later slot hears the earlier rebroadcast in time to drop its own.

When its moment comes, the station must be idle, hear no signal, and have an announce channel free. If not, it waits a quarter of a second plus a short random time and looks again, so that stations held up by the same busy channel do not all key on its first quiet instant.

Three more rules keep the flood in check:

23.8 From the air to a dispatcher

Hearing an SOS helps only if a person who can start a rescue finds out. Many mLink stations are also gateways to a mail server (Chapter 25), and those stations hand every incident they hear to it.

When a station completes a new incident, direct or through a rebroadcast, and its own link to the mail server is up (enabled, registered, and in contact within the last ten minutes), it writes the incident up as an ordinary mail message and deposits it at the server. The subject reads like SOS Immediate threat to life (Mayday): Medical (illness) / Water / marine; the body lists every field of the alert, the identity and the detail, then the incident number and check value and a note on how to reply. Depositing costs no air time and never delays alerting or rebroadcasting.

The server files the message in a reserved SOS mailbox, so nothing is lost even if nobody is watching yet, and copies it to everyone subscribed to the reserved sos mailing list. Subscribing to that list is how an administrator or trained dispatcher volunteers to receive incidents.

Acknowledgments follow the same path. A gateway that deposited an incident and later hears it acknowledged, or whose own operator acknowledges it, deposits a follow-up, ACKNOWLEDGED SOS ..., naming who acknowledged and their contact text.

If the station in distress is itself a working gateway, it deposits its own incident as soon as the beacon starts, alongside the radio call, and tries again at each pass until a deposit has been handed off. Its message is the one any gateway that hears it would write, so the copies merge.

23.8.1 Two-way SOS

The incident mail is addressed to the SOS mailbox and, if the identity is a valid callsign, also to that callsign. That second address is the return path. A dispatcher who replies to all puts an answer in the distressed station's mailbox at the mail server, and ordinary mail delivery carries it over the radio from there: any gateway that hears the station offers it the waiting mail (Chapter 24). The station answers with ordinary mail.

This is why a callsign is the best identity to give. A name or a vessel description still reaches the dispatcher, but it cannot be addressed, so replies have nowhere to go.

23.9 What to remember

Chapter 24

Mail Over the Air

The windows for writing, sending and collecting mail are described in Chapter 5; the states a mail passes through in the Sent list are in Chapter 6.

24.1 Mail is built from what is already there

A mail is an ordinary message with a particular payload shape. It travels by the same transfers, the same acknowledgements and the same relay handshake as anything else. On top of that sit four announce frames that exist only for mail (TAKEN, QRY, AVAIL and GET), three small payloads for mailbox business, and a server on the internet, the mailserver (Chapter 25), that holds mail for stations that are not on the air right now.

The design goal fits in one phrase: lazy on the air. Never key the radio for something the internet, another station, or plain patience can do instead. No station opens a "session" with anything.

24.2 What a mail is made of

A mail is the payload of an ordinary message whose kind byte says "this is mail" (Section 21.3), so it is compressed, and sealed when encryption is used, like any other payload. In the order they are packed, a mail holds:

A part that is absent costs nothing. One flag is not a part at all: it marks the mail as the standing orders of the virtual net it is addressed to (Chapter 22). The sender tag is added by a station that is registered at a mailserver. No station on the air can check it; it lets the server refuse a mail that some other station hands in under your callsign (Section 25.5.1).

24.2.1 Two kinds of "to"

There are two addresses on every mail, and keeping them apart is the key to the whole chapter.

The first is the on-air addressee: the station the transmission is aimed at, the one whose acknowledgement the sender waits for. It rides in the transfer's opening frames, not in the mail. The second is the list of recipients: the To and Cc callsigns inside the mail, the people the mail is for.

Usually the two agree. But they are allowed to differ, and mLink uses the difference as a signal. A transmission aimed at a gateway, carrying a mail whose recipients do not include that gateway, means "please carry this onward". A transmission aimed at nobody in particular, the all-stations address 0CQCQCQ (Section 14.7), carrying a mail whose recipients are real callsigns means "anyone: can you get this to the mailserver?" No marker byte says so; the mismatch between the two addresses is the request.

Outside addresses get no special treatment on the air. Only the mailserver acts on them, when the mail reaches it.

24.2.2 Attachments

The type codes cover plain text, JPEG, PNG, WAV, Opus, MP4, PDF, JSON, HTML, a generic "binary", and one type of mLink's own: a batch of map objects that the recipient can put on their own map (Chapter 28). A receiver treats a type code it does not know as plain binary.

24.2.3 How big a mail can be

The format allows an attachment of four gigabytes. The air does not. A mail must fit in one transfer after it has been compressed and wrapped: 64,004 bytes to a single station (Section 15.4.4), and 6,028 bytes when it is sent to everyone, because a broadcast gets no checkpoints and so may not run past one segment (Section 15.5.3). Text shrinks a good deal on the way; a picture or a PDF barely shrinks at all, because it is compressed already. A mail too big for any transfer is marked failed with the reason.

24.3 Where mail lives on a station

A station keeps every mail it decodes: mail addressed to it, and also mail it overheard between other stations, which is filed quietly in case somebody later needs a station that holds it. Beside the fields it keeps the exact packed bytes that came off the air. When the station later carries somebody's mail onward, it sends those bytes unchanged, so every copy of a mail everywhere is byte-for-byte identical. The same author with identical bytes is one mail, however many ways it arrived. Nothing is removed automatically; the station has a command to delete mail older than a given date, and the operator decides when to use it.

24.4 How a mail finds its way out

A station works down a short list of ways out. The rule of the list: prefer the way that uses less air and fewer other stations, and fall back only when the better way is not there.

0. By internet, when the operator asks for it Straight to the mailserver. No air at all. The station must be registered there. By radio: the station works down this list by itself 1. You are a gateway, recipient not heard in two minutes: deposit now Straight to the mailserver, nothing aired. Your own pickup broadcast goes the same way. 2. One recipient, link good enough: direct transfer Aimed at the recipient; their acknowledgement ends it. Sent. 3. Direct transfer went unanswered: relay search Another station may carry it; a gateway that holds it deposits it instead. 4. Link too weak to even try: mailserver first Your own internet deposits it; else a gateway heard in two minutes takes it; else failed. 5. Several recipients, or addressed to 0CQCQCQ: pickup broadcast Any gateway that hears it deposits it; any other station may carry it later. Step 1 needs internet at your station. Steps 2 to 4: one recipient. Step 5: chosen by addressing. Every step that reaches the mailserver ends with the mail waiting there for its recipients.
Figure 24.1. The ways out for an outgoing mail, in the order a station tries them.

24.4.1 By internet, on request

An operator whose station is registered at a mailserver can ask for a mail to go by internet. The station hands it straight to the server; nothing is keyed, and the mail is marked deposited when the server accepts it, or failed if the server cannot be reached or says no. A radio-only recipient still gets the mail over the air later, from whichever gateway hears them (Section 24.8), so a mail sent this way still has to fit a radio transfer to arrive.

24.4.2 When your own station is a gateway

A station that is itself a working gateway (Section 24.5.1) asks one question before it sends a mail by radio: has the recipient been heard in the last two minutes? If so, the mail goes over the air as below. If not, there is no point keying up for a station that is probably not listening, so the station deposits the mail at the mailserver at once and airs nothing. The mail shows as deferred while the deposit is under way and deposited when the server has it.

There is one exception: mail for a station in your own net. A net exists so that its members reach each other, so here the station does both. It leaves a copy at the mailserver, and it also asks the frequency for a station to carry the mail over the air, as any relay search does (Chapter 19), asking again after a growing wait until the mail is delivered or its lifetime ends. The row reads "copy left at the mailserver; asking the net to carry it over the air". "In your own net" means any of three things: the recipient is on the roster of a net you are a member of; a member of that net has said within the last 30 minutes that one of its other radios hears the recipient (Section 18.7); or your net is Safety Critical, in which case every recipient you have not heard counts. When the mail arrives over the air the station tells the mailserver its copy was delivered, so the recipient is not offered it again. If nobody carries it before the lifetime ends, the row rests as deposited.

Should that deposit fail, the mail goes back in line and is sent by radio exactly as a station without internet would send it; the station does not try the server a second time for that mail. A deposit cut short by a restart leaves the mail as a draft (Section 20.7).

A gateway's own pickup broadcast (below) goes the same way: it deposits the mail itself and airs nothing. Mail addressed to a virtual net or to an area on the map is not a pickup and is sent over the air as usual.

24.4.3 Straight to the recipient

With one recipient, the transmission is aimed at that recipient and sent like any other directed message: the station picks how to send it from the size and its estimate of the link (Section 15.5.2), sends, and waits for the acknowledgement. The acknowledgement is the proof of delivery; the mail is sent.

24.4.4 When the direct transfer goes unanswered

If the recipient never answers, the station asks for a relay, as it would for any directed message (Chapter 19). Mail adds one more kind of helper to that search: a gateway that overheard the mail. What it does is described under overheard mail; the outcome is a mail marked deposited, and a search that ended in success.

In a named net there is one more rung. When nobody who hears the recipient answers and both stations are on the net's roster, net control keeps the mail for the recipient and delivers it at their next check-in; the mail is marked held (Section 22.8).

24.4.5 When the link is too weak to try

Sometimes the sending rules say a direct transfer of this size cannot work at all (Section 15.5.5). For mail that is not the end. The station tries, in this order:

  1. If it is itself a working gateway, it deposits the mail. No air. If the server refuses or cannot be reached, the mail is failed.
  2. Otherwise, if it has heard a gateway within the last two minutes, it aims the mail at that gateway instead of at the recipient, choosing the most recently heard one. The gateway sees a mail not addressed to it, recognises the request, and deposits it.
  3. If neither is possible, the mail is failed, with the size and the rule that refused it in the note. It does not sit in a queue pretending.

24.4.6 The pickup broadcast

A mail for several recipients, or one addressed to 0CQCQCQ, goes out as a pickup broadcast: a transmission aimed at everyone, carrying a mail whose recipients are real callsigns or outside addresses. It means "anyone who can: take this to the mailserver". It must fit the broadcast limit of 6,028 bytes; a bigger mail must be sent to one station.

The broadcast airs and the mail shows as sent, which for a broadcast means only that it went out. The station then listens for somebody to claim it. The next sections say who can.

24.4.7 Encrypted mail takes only the direct ways

A mail sealed with encryption (Section 26.3) goes over the air and nowhere else. The mailserver, a gateway and a courier all work by reading a mail, to find its recipients and to file it, so none of them is offered one: no deposit, no gateway in place of the recipient, no bundle, and no courier or gateway acts on a sealed mail it happens to be able to open. A request to send a sealed mail by internet is refused. This is today's limit, not the intended design: delivery help from stations and a mailserver that cannot read the mail is planned and not yet built (Section 25.6).

24.5 Custody: who is holding your mail

Custody is responsibility. A station that takes custody of a mail is saying: "I have stored it somewhere safe, and it is my problem now, not yours." In mLink the only safe place that counts is the mailserver, and the only station that can claim custody is one that has just put the mail there.

24.5.1 Gateways

A gateway is any station whose link to a mailserver is switched on, registered and recently proven. It says so with the gateway flag in every PRESENCE it sends (Section 14.2.1), and every station that hears it notes the flag in its heard list. It needs no special hardware and no special licence, only a working internet connection.

The proof is kept fresh by the gateway itself: it looks in its own mailbox every five minutes, and also 15 seconds before each of its own beacons, and brings in whatever is there. The look before a beacon is why a station with its own internet connection is not offered its mail over the air: by the time another gateway hears the beacon and looks, the mailbox is empty. If a request to the server gets no answer at all, the gateway stops showing the flag at once and tries again a minute later. A server that answers with a refusal is plainly still there, so a refusal does not stop the flag.

24.5.2 The custody rule

A gateway takes custody of a mail when all of these hold:

It then deposits the mail at the mailserver, and only after the server confirms does it send [presence][taken]. That one announce frame is the whole custody layer on the air. It names the mail's author and its message id, and carries one of four statuses (Section B.10):

A gateway never announces custody it does not have. If the deposit fails, it stays silent, and the mail stays in play for someone else. A sender accepts a TAKEN naming its mail at any time, even long after it stopped listening for one.

24.5.3 When several gateways hear the same broadcast

Each waits a random time of up to four seconds before depositing. The first to finish sends TAKEN; the others hear it while they wait and drop the job. If two deposit anyway, no harm is done: the mailserver recognises the identical bytes and stores the mail once, and the second TAKEN says "already held".

24.5.4 When the sender missed the TAKEN

A TAKEN can be lost, and the sender will then send the mail again. A gateway that hears a mail it knows to be at the mailserver does not ignore the repeat; it answers "already held". It gives that answer at most once in 15 seconds for one mail. Because the repeat reaches every gateway at once, each waits a short random turn of its own before answering, so the first answer is heard by the others and they stay quiet. Where many gateways are in earshot, a repeat REQUEST is answered by place in line, as the first was.

24.5.5 Overheard mail

A gateway also overhears mail aimed at other stations. It deposits that too, with no TAKEN: the transfer in progress has its own proof of delivery, the recipient's acknowledgement. The quiet deposit costs no air, and the mailserver discards duplicates.

It pays off when the direct transfer fails. The sender's REQUEST for a relay names the mail, and a gateway that holds that mail can help without any path to the recipient. It waits three to four seconds, and if in that time it hears neither a SELECT choosing a radio relay for the mail nor another station's TAKEN, it deposits the mail again and sends TAKEN. A gateway that hears five or more other gateways does not rely on that short wait, because dozens of gateways may hold the same mail. It takes a place in line among the gateways it has heard in the last half hour, by the rule relay volunteers use (Section 19.3.4): places one and two answer about three seconds after the REQUEST, on different announce channels, three and four at about five seconds, five and six at about nine. A gateway past the sixth place still leaves its copy at the mailserver and says nothing on the air. A gateway waiting to answer drops its answer the moment it hears another gateway's TAKEN for the same mail. If a REQUEST goes by with no answer heard, each gateway draws its place from half as many on the next one, down to six, so a few gateways among many still answer within a request or two. The sender's station counts its search as answered and marks the mail deposited. The mailserver behaves like a relay with endless patience: it hands the mail over whenever the recipient next turns up.

24.6 Couriers: carrying mail toward the internet

Now suppose nobody who heard a pickup broadcast is a gateway. The mail is in their stores, but nobody can deposit it. A station that hears a pickup broadcast and cannot deposit it becomes a courier: it holds the mail and moves it one step closer to the mailserver, or to its recipient, when a chance comes along.

Sender A Courier C Gateway G Mailserver pickup broadcast (0CQCQCQ) stores the mail, sends nothing waits at least 24 s hears G's PRESENCE with the gateway flag set directed transfer to G acknowledgement deposit accepted [presence][taken] A cannot hear G: wait a delay graded by how well C hears A [presence][taken], once A's mail: deposited
Figure 24.2. A pickup that no gateway heard, carried one hop by a courier.

24.6.1 Who becomes one, and the wait

A courier announces nothing when it takes the job. It already has the mail in its store; it makes a note: this mail, this author, still needs a way out. A station keeps up to eight such jobs at a time.

Four kinds of station never make the note: a working gateway (the custody rule covers it), a station set to listen only, a station whose relay setting is below allow bulk (Section 19.9), and any station when the sender of the broadcast was itself showing the gateway flag, because the courier would only be carrying the mail back to where it came from.

A courier waits at least 24 seconds before doing anything, because a gateway that heard the broadcast directly can take about that long, on a busy channel, to deposit and get its TAKEN on the air. On top of that comes a wait of its own: one of 8 turns on a quiet net and of up to 16 on a busy one, the turns six seconds apart, plus up to three seconds more. Its first chance therefore comes between 24 seconds and a little over a minute after the broadcast on a quiet net, and up to two minutes after it on a busy one. Two couriers holding the same mail reach their first chance at different moments, and the later one sees what the earlier one did. A TAKEN heard at any point ends the job.

24.6.2 Handing it on

Once its wait is over, a courier checks about once a second whether it has a way forward:

  1. If the mail has exactly one recipient, no Cc and no outside address, and the courier has heard that recipient in the last two minutes, it sends the mail straight to them. Delivery beats custody. When the recipient acknowledges, the courier sends TAKEN with the "delivered direct" status.
  2. Otherwise, if a gateway is on its heard list as on the net (Section 18.9), it sends the mail to the most recently heard one. The gateway applies the custody rule, deposits, and sends TAKEN.
  3. Otherwise it keeps waiting, and transmits nothing to say so.

Either way the transfer carries a FOR frame at the front naming the mail's true author and its id, the same frame a relay uses (Section 19.5), so the mail is filed under the person who wrote it and not under the courier. A courier holds off for two seconds after hearing a gateway's PRESENCE, since that gateway is still transmitting and cannot hear anything yet, and while any announce channel is reserved (Section 17.2).

Net control of a named net uses the same hand-off for mail it keeps for an absent member (Section 22.8.4), aimed at gateways only, since it delivers to its members itself. The gateway deposits and says TAKEN "deposited"; net control keeps its own copy and still delivers it if the member checks in first, and then tells the gateway with a "delivered" message (Section 24.9) so the mailbox copy is closed.

After a gateway acknowledges the transfer, the courier allows 30 seconds for the TAKEN. If none comes, or the transfer came to nothing, it tries again a minute later. It keeps the job for one message lifetime (Section 20.4) and then forgets it. That is the courier giving up, not the mail: the sender's station still owns the mail and keeps trying.

24.6.3 A crowd of couriers

Picture a pickup broadcast heard by ten stations, none of them gateways, and then a gateway coming into range. Three habits stop all ten sending the same mail to it.

24.6.4 Carrying the news back

The gateway's TAKEN reaches the stations that hear the gateway. But the sender may have been heard only by the courier, and may never hear that TAKEN. The courier whose finished transfer the TAKEN answers therefore repeats it once, toward the sender.

Only that one courier does it, and lazily. It skips the repeat if the links map says the sender hears the gateway directly (Section 18.8). Otherwise it waits three seconds plus 0.7 seconds for every decibel by which its link estimate for the sender falls short of +18 dB, plus up to six seconds more that differ from station to station. A courier that has not heard the sender in the last half hour counts as hearing it worst and waits about 23 to 29 seconds. If another TAKEN for the same mail is heard first, the repeat is cancelled.

Each courier only ever moves the mail closer: from a holder to a gateway, or from a holder to the recipient. Nobody plans a route.

24.7 When nobody took it: waiting for a gateway

After a pickup broadcast airs, the sender listens for a TAKEN for ten minutes. If none arrives, the mail becomes deferred with the note "no pickup: waiting for a gateway". Nothing is transmitted while it waits, and no clock ends the wait (Section 20.6).

The cue to try again is an event: hearing any PRESENCE that shows the gateway flag. The station then waits two seconds, waits for all three announce channels to be free of reservations, and sends its waiting mail again. This time it aims the mail at the gateway it has just heard: a transfer aimed at one station gets an acknowledgement and repair of lost frames, and the gateway's custody rule takes it from there. Several waiting mails go together (Section 24.11). If the link to that gateway is too weak for a transfer of that size, the mail is broadcast again instead.

A mail that has been tried and failed does not go again on every gateway heard. It waits the same doubling gaps as any deferred message, one minute to thirty-two (Section 20.6.1). A gateway heard while a mail is inside its gap is remembered, and the mail goes as soon as the gap ends, provided the gateway has been heard within the last two minutes. The station also holds these sends back while it is slowing its large transfers on a crowded channel (Section 17.7.2).

24.8 Receiving mail without asking

To receive mail held at the mailserver, a station normally does nothing at all. It does not need to be registered, to have internet, or to ask.

24.8.1 A gateway hears you

Every transmission starts with a PRESENCE. A gateway that hears one, from any station and for any reason, asks the mailserver over the internet whether that station's mailbox holds anything unread. If it does, the gateway sends [presence][avail]. AVAIL is an announce frame naming the mailbox, the number of unread mails and their total size. If the box is empty, the gateway says nothing.

Three limits keep this polite. A gateway looks in any one station's mailbox at most once in fifteen minutes. When it has told a station of waiting mail and the station has not asked for it, the gateway waits longer before saying the same thing again: 15 minutes after the first time, 30 after the second, and 60 after the third and every later one. The wait goes back to 15 minutes when the station asks this gateway for its mail or about its mailbox, or when the number or size of the mails waiting changes. A station heard asking a different gateway for its mail has plainly been told already, so every other gateway counts that as a telling of its own and stays quiet for its first wait of 15 minutes. That quiet is given once for each gateway the station asks. It never offers to a station that shows the gateway flag, because that station fetches its own mail over the internet. And when several gateways hear the same station, each waits a turn of its own within the first ten seconds or so, and a gateway that hears another's AVAIL for that station, or hears the station ask another gateway, drops its own, including one still waiting for its turn.

24.8.2 Offer, request, delivery

A station that hears an unasked AVAIL for itself, showing mail waiting, and that cannot reach the mailserver itself, answers by itself with [presence][get]: an announce frame naming that gateway and asking it to deliver everything. The gateway fetches the oldest unread mail and sends it as an ordinary directed transfer with a FOR frame in front naming the mail's author. When the recipient acknowledges, the gateway tells the mailserver the mail was delivered, and then sends the next. One mail per transfer, each confirmed before the next starts.

A GET gets no acknowledgement of its own. If nothing arrives within 12 seconds the station sends it again, up to three times in all, and it holds the repeat back while a delivery from that gateway is visibly under way. If the gateway still has not answered, the station asks again two minutes later and then at doubling gaps, for as long as that gateway's AVAIL is less than ten minutes old. On the gateway's side, a repeated GET while the same mail is already queued or on the air for that station does not start a second copy.

24.8.3 Asking instead of waiting

A station can also ask. It sends a mailbox query, [presence][qry]: "any gateway, please check my mailbox". A gateway that hears it checks and answers with an AVAIL marked as an answer, even when the answer is "no mail". Gateways take turns as they do with unasked offers. A station may send one query a minute.

The query can ask for a list as well. The AVAIL then says a list follows, and the gateway sends one to three short messages, each a mailbox listing payload naming up to five waiting mails, oldest first: the author, the size, the mail's id and the first 14 bytes of its subject. Nothing is delivered until the operator chooses. Without the list, the station answers the AVAIL with a GET for everything.

If no gateway answers within 30 seconds, the station looks for a gateway that told it about waiting mail in the last ten minutes, and if there is one, sends that gateway a GET.

24.9 Mailbox business that travels as a message

The four mail frames reach only the stations that hear them directly. For business with a gateway out of direct range there is a mailbox control payload (Section 21.3): a few bytes sent as an ordinary directed message, so that the relay handshake can carry it. It has eight uses.

24.9.1 Mailing lists over the air

Lists live at the mailserver (Section 25.7.1), and a station without internet uses them with nothing but mail. To post, it sends a mail with the list's address as an outside address. To join or leave, it sends a mail to the list's address whose subject or body is the single word "subscribe" or "unsubscribe". Either goes out as a pickup broadcast, a gateway deposits it, and the server acts on it; the confirmation comes back as mail. Since a default server accepts a carried mail only when it can check the sender tag, this works for a station that has registered, which it can do over the air.

24.10 How a pickup is named

A mail on the air is named by its two-byte message id (Section 16.2.2), and two bytes are too few to name a mail alone. So every mail frame or payload that names a mail carries the author's callsign beside the id: TAKEN, the FOR on a delivery, the fetch-one request. In storage a mail is looked up by the pair.

One wrinkle is particular to mail. The id depends on the on-air addressee, so the same mail aimed at a gateway and sent as a broadcast would have two different ids. For pickup and custody mLink always uses the broadcast form, computed as if the mail had been sent to 0CQCQCQ, whichever way a copy travelled. The sender, the courier and the gateway all compute the same number without anyone transmitting it. The one exception is a gateway answering a REQUEST for a relay: its TAKEN quotes the id the REQUEST used.

24.11 Bundles

Every transfer starts with opening frames, and those are the part most likely to collide with somebody else. So when a station is about to send a mail, it looks at what else is queued. Any other mail for the same station joins the same transmission as a bundle: up to eight mails, each kept byte-for-byte as it would have been sent alone. When the destination shows the gateway flag, waiting pickup broadcasts join too, since the gateway would deposit them anyway. Several waiting pickups can also go out together as one broadcast. Compression works across the whole bundle, so mails with similar headers shrink further together.

A bundle holds at most 48,000 bytes of mail before compression when aimed at one station, and 5,600 bytes as a broadcast, which keeps it inside the broadcast limit. Each mail inside keeps its own id, worked out by both ends in the broadcast form, so custody, TAKEN and the spotting of duplicates work on each mail separately, and each keeps its own entry in the sender's outbox. Encrypted mail and mail addressed to an area are never bundled.

24.12 What to remember

Chapter 25

The Mailserver

The windows where an operator sets up, registers and uses the mailserver are described in Chapter 5.

25.1 A mailbox server with no radio

The mailserver, called the CMS (central mail server) in the station's log, never touches audio, never transmits, and never reads a station's database. Stations reach it in exactly one way: a gateway, a station with a working internet connection, sends it a request on its own behalf or on behalf of a radio-only station it has heard. When gateways do that is the subject of Chapter 24.

Mailserver mailboxes, lists, chat, journal radio-only stations gateways (radio + internet) outgoing email relay (SMTP) provider mailbox (POP3) warm standby (copy of the database) on the air internet email out email in copies of the database
Figure 25.1. Everything the mailserver talks to. Radio-only stations never talk to it directly; a gateway always stands in between.

The program is deliberately plain. It keeps everything in one database file, listens on the local machine only (port 8380 unless told otherwise), speaks unencrypted HTTP and handles one connection at a time. The public address and its TLS certificate belong to an ordinary reverse proxy in front of it. Everything a station asks goes to one address as a small JSON document naming a command, and every request is complete in itself: there is no session to open or keep alive.

25.2 What it stores

25.2.1 The mail exactly as it flew

The mailserver stores each mail as the exact packed bytes that go over the air, the same bytes a station keeps in its own store. It unpacks a mail only to read what it needs: the recipients, to know which mailboxes get a copy, and the subject and size, to show in a listing. A gateway that later fetches the mail gets those same bytes back and sends them unchanged. There is one mail format in mLink, not a radio format and a server format with translation in between.

25.2.2 Mailboxes appear on their own

There is one mailbox per callsign, and it comes into existence the first time a mail arrives for that callsign. The owner does not have to have registered, or even to have heard of the mailserver. Mail simply waits. Registration matters for other things: asking the server anything at all, and letting other stations hand in mail the owner wrote (Section 25.5.1). Reserved addresses such as 0CQCQCQ are never mailboxes; the server skips them when handing out copies.

25.2.3 A mail only moves forward

Each stored mail has one of three states, and it only ever moves forward:

  1. Deposited: waiting for its recipient. This is what "unread" means in a listing.
  2. Fetched: the recipient has it, either because their own station collected it over the internet or because a gateway delivered it over the air and reported the delivery.
  3. Archived: the owner's station has confirmed that it holds its own copy. A station that collects its mail over the internet does this as soon as the mail is safely stored. Archived mail drops out of the ordinary listing.

Collecting mail never deletes it, and nothing deposited or fetched is ever removed automatically. The server's operator may choose to delete archived mail after a number of days, in an hourly sweep; the default is to keep everything.

Each mail also records whether it came from the internet, from a radio gateway or from the server itself.

25.2.4 How the server tells mails apart

The server identifies a mail by its own row number and by a fingerprint of its bytes (a SHA-256 hash). A mailbox can hold a given fingerprint only once. That one rule makes every deposit safe to repeat: if five gateways overhear the same broadcast and all deposit it, the mailbox ends up with one copy, and the later depositors are told they were not first.

The server also stores the mail's two-byte on-air message id (Section 16.2.2), because gateways quote it, but never relies on it to tell two mails apart.

25.3 Mail login: the mailkey

A station that wants to ask the mailserver anything registers once. From then on it proves who it is with a mailkey: a 32-byte secret that only that station and the server hold. A secret cannot be sent over amateur radio in the clear, and it may not be sent encrypted either (Section 26.1). So the mailkey is never sent at all. Both ends work it out.

Station private key (kept) public key mailkey (computed) Mailserver private key (kept) public key mailkey (computed) only public keys are exchanged (65 bytes each way; nothing secret) Each side: own private key + other side's public key, plus callsign and key number -> the same 32-byte mailkey on both ends A gateway passing the keys along holds neither private key, so it cannot compute the mailkey.
Figure 25.2. The mailkey is worked out at both ends, not sent. Only public keys are exchanged, and a public key hides nothing.

25.3.1 Registering without sending a secret

The first time it needs one, a station creates a key pair on the standard P-256 curve: a private key that never leaves the station's computer, and a matching 65-byte public key. The mailserver has a key pair too. Registration swaps the two public keys and nothing else:

  1. The station sends its callsign and its public key.
  2. The server records the callsign against that public key, and answers with its own public key and a key number.
  3. Each side combines its own private key with the other side's public key, by the ECDH method, and runs the result through a standard key-derivation step (HKDF-SHA256) together with a fixed label, the callsign and the key number. Both arrive at the same 32 bytes. That is the mailkey.

The station keeps its key pair, the key number and the mailkey in its own database. The server keeps the station's public key and the mailkey.

Because nothing secret crosses in either direction, registration also works over the air. A station with no internet sends its public key to a gateway as a mailbox-control message of 66 bytes; the gateway registers it at the server and sends back a status, the key number and the server's public key, 71 bytes (Section 24.9). The gateway holds neither private key and can compute nothing from what it carries. A dishonest gateway that swapped in a wrong server key would leave the station with a mailkey the server does not share: a registration that does not work, not a stolen identity.

The server program also accepts a registration by callsign and password, and then makes up a random key and returns it in its reply. That path is for tools and administrators on the internet. No mLink station registers that way, and no password is ever part of an exchange over the air (Section 26.5).

25.3.2 When someone else claims your callsign

The first registration for a callsign claims its mailbox. After that, an attempt to register the same callsign with a different public key, or with a wrong password, gets nothing. The server adds one to a conflict counter for the mailbox, records the attempt, and puts a notice titled "Mailbox ownership conflict" into the real owner's mailbox. Only one such notice is outstanding at a time, so repeated attempts do not flood the box. Registering the same public key again changes nothing.

For a real dispute the server's administrator has two offline commands: one lists every mailbox with unresolved conflicts, and one resets a mailbox's credential by hand.

25.3.3 A second device

A home station and a field laptop under one callsign each have their own key pair and therefore their own mailkey. Since a second public key for a claimed callsign is refused, the second device needs the first one's permission, and the server provides for it with an enrollment code. A registered device asks for one: 128 random bits, valid for 24 hours, usable once. The operator carries it to the new device by hand, and the new device registers its public key together with a keyed check computed with the code over its callsign, the time and its public key. That check is safe to send in the clear: a 128-bit random code cannot be guessed from it the way a password could, and the code works once. The server tries up to eight keys for one callsign.

This is a function of the server. The station software has no control yet for asking for a code or for using one.

25.3.4 Signed requests

Every request other than registration carries three extra fields: the station's callsign, the time in seconds since the mLink epoch (Section 21.5), and an 8-byte keyed check. The check is the first 8 bytes of an HMAC-SHA256, keyed with the mailkey, over a fixed label, the callsign, the time and a hash of the request's body. The server works the check out again with each mailkey it holds for that callsign and accepts the request if one matches.

It refuses a request whose time is more than ten minutes from its own clock (the default; the server's operator can change it), any exact repeat of a request it has accepted, and any request older than one it has already accepted from the same callsign. Together those stop someone replaying a recorded request. Every request also carries a number of its own, so that two otherwise identical requests in the same second do not look like a replay. The check proves who is asking and hides nothing: the request itself is readable.

25.4 Open pickup: anyone may carry anyone's mail

Any registered station may list and fetch any station's mailbox, not just its own. That is the open-pickup model, and it is what makes receiving without asking work (Section 24.8): a gateway that hears a station asks "what is waiting for this callsign?" under its own mailkey, fetches the mail, and delivers it over the air. Three rules keep this sensible:

25.5 Mail coming in

Mail enters a mailbox in one of five ways.

25.5.1 A gateway deposits mail it carried

This is the everyday case. The gateway sends the mail's bytes, the author's callsign and the mail's on-air id. Its own callsign is proved by the signed request; the author's is only claimed.

That claim is checked with the sender tag, the two bytes a registered station puts at the end of every mail it writes. The tag is the first two bytes of an HMAC-SHA256, keyed with the author's mailkey, over every byte of the mail before it, under a different fixed label from the one signed requests use, so that neither can be passed off as the other. The server tries the claimed author's mailkeys against it:

So mail from an unregistered station still reaches anyone it can reach over the air, but on a default server no gateway can carry it into a mailbox.

25.5.2 Why two bytes are enough

A real digital signature would cost 64 bytes, which is 41 % of the 156 bytes a shortburst holds (Section 15.2). Two bytes are 1.3 %. mLink chose air time.

Two bytes work because of how the tag can be attacked. Nobody can compute a tag without the mailkey, so there is nothing to work out at leisure from recorded traffic. A forger can only guess, and each guess means handing the server a deposit: one chance in 65,536 for each key the author has. The server limits the guessing where it is aimed. Once five deposits naming one author have failed that author's tag within ten minutes of the first failure, every further deposit naming that author is refused until those ten minutes are up, whichever station posts it, and the refusal comes before any key is tried. The count is kept on the author, not on the depositing station: a gateway that carries a forged mail it heard on the air is not the forger. The price is that someone posting bad tags under your callsign can hold up mail that other stations carry in for you; mail you send over the internet yourself is not affected.

25.5.3 A station sends directly over the internet

A registered station with internet can hand a mail it wrote straight to the server. No tag check is needed: the author is the station making the signed request.

25.5.4 A distress call is heard

A gateway that completes an on-air distress call writes it up as a mail and deposits it (Section 23.8). The server files it in the reserved SOS mailbox, the permanent record, and gives a copy to every station subscribed to the reserved mailing list "sos". Every gateway that hears the same call writes the same bytes, so the fingerprint rule merges their deposits into one. A distress deposit is never refused for a missing sender tag.

25.5.5 Internet email arrives

If its operator sets it up, the mailserver collects incoming internet email from an ordinary email provider's mailbox, every 60 seconds by default. It does this as a POP3 client (POP3 is the standard way to download mail from a mailbox); it is not a server that mail programs can connect to. The addressing is either CALLSIGN@ the operator's domain, sent through a catch-all, or mailbox+CALLSIGN@, which works on any provider that keeps the part after the plus sign. Each email becomes an mLink mail in that callsign's mailbox, from the special sender EMAIL, with the email address as the sender name. The server keeps the subject and the first plain-text part, up to 60,000 bytes. Email to anything that is not a valid callsign is thrown away. The server does not speak encrypted POP3 itself; it expects a small local tunnel program to handle that.

25.5.6 The server writes to you

The server sends its own notices as sender MLINKMAIL: ownership conflicts, and confirmations of mailing-list subscriptions.

25.6 Encrypted mail: not held here yet

mLink can encrypt a mail for services whose rules allow it, such as the MARS and SHARES programs (Section 26.3). On amateur frequencies encryption stays off, and nothing in this section applies.

The mailserver holds no key that opens anyone's mail, and it is never given one. It files a mail by reading it: the recipients decide which mailboxes get a copy, and the sender tag is checked against the text. An encrypted mail gives it nothing to read. So today's rule is simple: an encrypted mail is never deposited. It goes over the air to the stations it is addressed to and nowhere else.

The stations enforce this, not the server:

The cost falls on the sender. Nothing holds an encrypted mail for a recipient who is off the air: no mailbox, no pickup later from another gateway, no copy to an email address or a mailing list. The mail waits at the sending station, which keeps trying, and every attempt goes out encrypted the same way. A service that needs both encryption and a mailbox that holds mail for absent stations does not get both from mLink today.

The on-air side of the same rule is in Section 24.4.7.

25.7 Where a mail goes

When a mail arrives by any of these routes, the server gives a copy to each recipient.

The server reports back how many of the copies were new. That is what lets a gateway say on the air either "deposited" or "already held".

25.7.1 Mailing lists

A list is named by its topic, the part before the @: letters, digits, dots, dashes and underscores, up to 32 characters, case ignored. A topic comes into existence with its first subscriber.

A mail to a list whose subject or body is exactly "subscribe" or "unsubscribe" is a command from its sender: the server updates the list and mails back a confirmation, and nobody else sees it. Anything else is a post, and every subscriber except the author gets a copy. A registered station with internet can also join, leave and ask for the list of topics with a signed request. How a station without internet does the same is in Section 24.9.1.

25.7.2 Email out

If the operator configures one, the mailserver hands queued internet email to an outgoing mail relay, acting as an SMTP client (SMTP is the standard way to send mail). The relay is usually a mail program on the same host. The mail goes out from CALLSIGN@mlink.org by default, carrying the subject and body text; attachments are not sent on. The queue is checked every 15 seconds. A failed attempt is retried after 30 seconds, then after doubling delays up to eight hours, and a message is marked failed after ten attempts.

25.8 Mail going out to stations

A station reads a mailbox in two steps: a check, which lists what is there (sender, subject, size, state, id and folder), and a fetch, which returns one mail's bytes. A station whose mailserver link is on and registered checks its own mailbox every five minutes, fetches what is unread, and confirms each mail once it is stored. A mail that also arrived over the air appears once.

Folders exist on both sides. The server keeps an inbox for each mailbox and lets the owner file mail elsewhere; when an operator files a mail on a registered station, the station asks the server to file its copy the same way, naming the mail by its fingerprint.

25.9 Chat channels

The mailserver also hosts simple chat rooms for stations with internet. A channel is named like a mailing-list topic and comes into existence with its first line. A line may be up to 512 bytes; a channel keeps its most recent 500 lines, and a station collects new lines 50 at a time. Posting and reading both need registration. Chat is not mail: nothing is per-recipient, and nothing is kept once it has scrolled out of the 500.

25.10 The journal

Every change the server makes to mail and accounts (a registration, a deposit, a state change, a folder move, a list subscription, a failed tag, an email sent) also adds a line to a journal, in the same database transaction, so the two can never disagree. Journal lines hold references and facts (which mailbox, which mail, which station did it), not copies of mail or keys. It is the audit trail behind open pickup. Chat lines are not journaled.

25.11 Staying up: the warm standby

A mailserver can run with a warm standby: a second copy of the program on another host, kept up to date and ready to take over. The primary is started with a shared secret, which switches on two private addresses: one that reports the journal's latest line number, and one that returns a consistent copy of the whole database. The standby is started pointing at the primary with the same secret. Every 10 seconds by default it asks for the line number, and when that has moved on it downloads a fresh copy and swaps it in. The whole database is copied because the journal holds no mail and no keys and so could not rebuild them.

A standby refuses all normal requests with "service unavailable", so stations cannot write to two servers at once. To promote it, the operator restarts it without the standby setting. The server's own key pair lives in the database, so the promoted standby has the same one, and every station's mailkey keeps working without anyone registering again.

25.12 What to remember

Chapter 26

Security Under Part 97

The encryption settings and the composer's encryption choice are described in Chapter 5.

26.1 The rule, and where mLink stands

In the United States, amateur radio is governed by Part 97 of the FCC rules. Section 97.113(a)(4) prohibits "messages encoded for the purpose of obscuring their meaning", and other countries' licences carry similar conditions. The test is simple: anyone with the right, openly available tools must be able to read what you send.

Security features meet that test in two very different ways.

Everything else mLink does to a message is readable by anyone running mLink. Compression is an openly published method with a dictionary built into every copy of the software (Section 21.4), and the frame formats are in this book (Appendix B).

26.2 Authentication: mail login

The authentication mLink uses on the air belongs to mail, and its home is Section 25.3. In brief: a station and the mailserver each work out the same secret from public keys they have swapped, so the secret is never transmitted; the station uses it to sign its requests to the server, and to put two bytes at the end of each mail it writes so that the server can tell that mail from a forgery. None of this hides anything, which is why all of it is usable on amateur frequencies.

26.3 Optional encryption

Encryption is asked for one message at a time, and only for three kinds of message: a text, a data message, and a mail sent by radio. Without a request a message goes in the clear, and a request the station does not understand is treated as clear too. A station with no keys loaded cannot seal anything. Everything a station sends on its own account is always in the clear: beacons, position reports, certificates, mailbox requests and listings, and every mail a gateway or courier carries for somebody else.

There are two modes, recorded in two bits of the envelope byte (Section 21.2):

A sealed mail travels over the air only. Depositing at a mailserver, courier carriage and bundling all work by reading the mail, so none of them is used for one (Section 24.4.7).

26.3.1 The cipher

26.3.2 Where it sits in a message

envelope 1 B key no. 2 B group only nonce 12 B, random sealed: compressed kind byte + body unreadable without the key tag 16 B readable, but covered by the tag hidden Compress first, then seal. Any change to any byte, readable or hidden, makes the tag fail. Extra cost per message: 30 bytes with a group key, 28 bytes in certificate mode.
Figure 26.1. An encrypted message. The envelope byte, the key number and the nonce stay readable so the receiver knows which key to use, but the tag covers them too, so they cannot be altered on the way.

The message is compressed first and sealed second, because sealed data looks random and would not compress. The nonce (a "number used once") is 12 random bytes, fresh for every message, so the same text sent twice gives different sealed bytes. Certificate mode needs no key number: the key follows from who is sending to whom, and the transmission already says that.

26.3.3 What is protected, and what is not

The body and the kind byte are hidden, so a listener cannot tell a chat line from a mail. The rest of the transmission is as readable as ever: who is sending, who is addressed, how long the message is, and its 16-bit check, which is computed over the message before it is sealed (Section 16.2).

The receiving station reads the envelope byte, finds the key (the group key with that number, or the key it shares with the sending station) and opens the seal. If it has no such key, or the tag does not verify, the message is dropped and not acknowledged. A station that overhears a sealed message it cannot open keeps no copy today, and so cannot offer to relay it. Relaying by stations that cannot read the message is planned and not yet built.

In certificate mode the key between two stations is the same every time, computed from their two long-lived keys. That costs no extra transmissions, but anyone who later obtains one station's private key can open the recorded traffic between that pair.

26.4 Certificates and the keyring

Certificate mode rests on a certificate authority (CA) run by the group that wants it: one root certificate that every station in the group is given. A separate command-line tool, run on a machine that is not a station, creates that root and issues certificates, and the CA's private key never touches a station. Each operator receives a private key and a certificate, signed by the CA, that ties their callsign to their public key. The station is told where those files and the root are when it starts. A station without them still works; it can use group keys but not certificate mode.

To seal a message for a station you need that station's certificate. It arrives in one of two ways: installed by hand, or over the air, since a station can send its own certificate as an ordinary message whose payload kind is certificate, always in the clear because it holds nothing secret. Either way the receiving station accepts it only if it is signed by the root and the callsign in it is the callsign it was installed under or came from. Nobody can file a certificate under someone else's callsign.

All of this lives in the station's keyring: its own identity, if it has one, the group keys it has been given, and the certificates of other stations. Group keys and other stations' certificates are stored in the station's database and loaded again at start-up; the station's own private key stays in its own file. The station will report what it can do (whether it has an identity, which key numbers it holds, which stations it holds a certificate for) but never the keys themselves.

26.5 No password ever goes on the air

A password is short and guessable. If any proof of knowing one were sent by radio, a listener could record the proof and try every likely password against it at leisure, and the cure, encrypting the proof, is what the rule forbids. So no mLink exchange over the air contains a password or anything computed from one. What goes on the air in its place is a public key, when a station registers at a mailserver, and after that the two-byte tag on each mail (Section 25.3.1). The names and passwords operators use to sign in to a station stay between the client and that station (Chapter 7).

26.6 Why distress messages are never signed or sealed

A distress call (Chapter 23) has no envelope byte and no place for a key: it is a fixed format that every station can read.

The same holds when a gateway writes a call up as mail for the mailserver (Section 23.8). The write-up carries no gateway name, no clock time and no sender tag, so that every gateway hearing the same call writes exactly the same bytes and the server stores them once. A tag or signature inside it would be the gateway's, not the distressed station's, and it would differ from gateway to gateway, turning one incident into several. Who carried the call is still known, because the gateway's request to the server is signed. And the server never refuses a distress deposit for want of a tag.

26.7 What to remember

Chapter 27

Sharing the Internet Over the Air

The Tracked Data window and the map's weather menu are described in Chapter 5. This chapter is about how the data is described, asked for and carried.

27.1 The idea

A station in a field camp, on a boat or in a disaster area often has a radio and a laptop and nothing else, while a few hundred kilometres away another station has working internet. mLink lets the second fetch small, well-defined pieces of data for the first. Weather is the one data type the network carries today. The design keeps three things apart:

27.2 Sources: what a station knows how to fetch

An internet source is a capability, not a request. It describes one web service the station knows how to use: a web address with named blanks to fill in (a weather-station code, or a latitude and longitude), any request headers the service expects, and, for each field mLink wants, the path to that value in the service's JSON reply. It also names the kind of data the result is, a default refresh interval, an enabled switch and, for services that need one, an API key. The key stays on the station and is never sent on the air.

Two weather sources come built in, both enabled. One reads the latest observation from a US National Weather Service observing station, given that station's code, and refreshes every 10 minutes by default. The other reads current weather from wttr.in for any latitude and longitude, and refreshes every 30 minutes.

The list of sources lives in the station's database. An operator can add sources or change a built-in one; an edited built-in source is marked as the operator's own, so a later software update can add new sources without overwriting the change.

27.3 Queries and the cache

An internet query is a record that says "I want this data". It names a source and its parameters, and makes two choices. How often: one-off (fetch once, then stop; the record stays for reference) or tracked (fetch again every refresh interval until it is removed or disabled). How: from this station's own internet, or by asking over the air and waiting for another station to answer.

A third kind is never created by an operator: a peer-served query, which the station makes for itself when it hears another station ask for data and can answer (Section 27.5).

Queries are kept in the station's database, so tracked queries carry on after a restart. Each records where its latest data came from (this station's own internet, or a peer over the air), when, and whether the last attempt succeeded.

Results go into the cache, one entry per source and set of parameters. An entry outlives the queries that filled it: stale data is still useful data, especially in the field. Entries that no enabled query uses and that are more than seven days old are cleared out when the station starts.

27.4 Asking over the air: the INET-REQ frame

When a query is set to ask over the air, the station sends one short transmission: its PRESENCE, saying who is asking, followed by one INET-REQ frame (Table B.17).

[presence][inet_req]

The request has no addressee. It is a question to anyone in earshot who can answer, and it says four things: the kind of data wanted (weather at a position is the only kind today), a session number, a freshness hint, and the parameters for that kind, which for weather are a latitude and longitude good to a metre or two.

27.4.1 The session number and the freshness hint

The answer comes back some seconds later as a separate transmission, and the session number ties the two together. The asker picks it at random from 1 to 254, stores it on the query, and looks for it in every answer that arrives. Each request gets a new one, so an answer to an older request, arriving after the station has asked again, does not match and is set aside.

The freshness hint is the asker's way of saying how old an answer may be and still be useful; it is 30 minutes unless the query says otherwise. It is a hint, not a contract: an answering station today fetches fresh data every time.

Asking is a transmission the station chose to make, not a reply someone is waiting for, so it goes at normal priority (Section 17.4). A tracked query sends a fresh request, with a fresh session number, at each refresh interval, so the data keeps arriving for as long as someone in range can supply it.

27.5 Who answers

Every station that hears an INET-REQ considers it. What happens next depends on what the hearing station has.

Several connected stations may hear the same request, and one answer is enough. So a station with an answer ready does not send it at once. It waits 0.3 seconds plus a random time of up to about 7 to 10 seconds (longer when more stations have been heard lately), and if the station is busy or hears a signal when that time comes, it waits a little longer. A station that hears another station's answer to the same asker and session while it is waiting drops its own.

The asker gives each request an answer window of 20 seconds. If nothing arrives, a one-off query asks once more with a new session number, and after a second silence it is marked "no station answered". A tracked query is left alone: it asks again at its next refresh anyway.

A station set to listen only neither asks nor answers.

27.6 The answer: an ordinary short message

The answer is not a special frame. It is an ordinary message addressed to the asker, sent as a shortburst (Section 15.2):

[presence][sbrts][shortburst]

What makes it an answer is inside the payload. Its kind byte says internet response (Section 21.3), and the first two bytes of the body repeat the kind of data and the session number from the request. The weather record follows. The answer is sent once; if it is lost, the asker's second request or a tracked query's next one brings another.

Off-grid station Connected station Internet [presence][inet_req] weather, session 57, lat/lon, "30 min is fine" web request JSON reply (background worker) [presence][sbrts][shortburst] kind: internet response | weather | session 57 | 18-byte record match session 57, show in Tracked Data + map
Figure 27.1. An over-the-air weather request and its answer. The question is a single announce frame after PRESENCE; the answer is an ordinary directed short message. The web fetch in between happens off the air, in the background.

27.6.1 The weather record

The weather travels as a packed binary record of 18 bytes, not as the JSON the web service returned, which runs to hundreds or thousands of bytes.

Table 27.1. The weather record (multi-byte fields big-endian).
BytesFieldEncoding
1format versionCurrently 2.
1forecast countHow many hourly forecast entries follow the observation; answers today carry none.
2temperatureSigned, in tenths of a degree Celsius.
2pressureTenths of a hectopascal (millibar).
1wind speedWhole knots.
1wind directionThe full circle in 256 steps, about 1.4 degrees each.
4timeSeconds since the mLink epoch (Section 21.5), stamped when the answer is built.
6gridThe six-character Maidenhead locator of the place the source reported for.

The answering station converts whatever units its source used (pascals or millibars, metres per second or kilometres per hour) into this one format, so the asker never needs to know which web service answered. With the envelope byte, the kind byte, the data kind and the session, the whole payload is 22 bytes. A record that small and that dense does not get smaller with compression, so it goes out as it is.

On arrival the asker decodes the record, stores it in its cache as if it had fetched it itself, marks the query as answered by a peer, and gives the clients a map marker at the requested position.

27.7 The background worker

A web request is slow by radio standards: a bad one can hang for tens of seconds while a server times out. Meanwhile the station has to keep listening, decoding and keying the transmitter on time. So all internet work is kept away from the radio side of the station (Chapter 29).

Tracked queries schedule themselves on the same worker: when a fetch finishes, the next one is booked for one refresh interval later.

27.8 What to remember

Chapter 28

Position, Maps and Tactical Overlays

The World Map window, its tools and its menus are described in Chapter 5. This chapter is about what goes over the air and what the station keeps.

28.1 Your station's position

28.1.1 Grid squares and how precise they are

Amateur radio names places with the Maidenhead grid locator, such as DM43. Each pair of characters divides the previous area again: two letters name a field of 20° of longitude by 10° of latitude, two digits a square of 2° by 1° (roughly 170 by 110 km at mid latitudes), and two more letters a subsquare of 5 by 2.5 minutes of arc, a few kilometres across.

Every PRESENCE frame carries the sender's locator to six characters (Section B.5): a subsquare, about 5 by 7 km at mid latitudes. It costs nothing extra and it is on every transmission, so every station heard has a place on the map: the centre of its subsquare. An operator who would rather not say that much can set the station to send four characters, which puts it only within a square of roughly 170 by 110 km. A station that has declared an emergency sends six whatever the setting. The map keeps whatever precision was heard last. The frames in this chapter are finer still. An area can be given as a six-character locator; a position report, a map object and a weather request carry latitude and longitude to about 1 to 2 metres; a distress call carries them to about 10 to 20 metres, with a statement of how far to trust them (Section 23.3.1).

The grid square you configure also answers two questions other stations ask: "is anyone in this area?" (the geopoll, Section 18.5) and "am I inside the area this message was aimed at?" (later in this chapter). Both use the centre of that square. A station with no grid square set never claims to be anywhere.

28.1.2 A precise position, typed or from GPS

The station also keeps a precise position for itself, separate from the grid square. An operator can type one in, or a GPS receiver can keep it current.

mLink does not talk to GPS hardware itself. It reads fixes from gpsd, the standard Linux GPS service, over its network interface (by default on the same computer, TCP port 2947). The station daemon connects, asks gpsd to stream position reports, and uses any 2D or 3D fix. A vehicle standing still would otherwise cause a disk write every second, so the daemon stores a new position at most every 10 seconds, or sooner when the station has moved more than 25 metres. If gpsd is not running yet, the daemon tries again after 5 seconds, doubling the wait up to a minute, so the order in which things start at boot does not matter.

The precise position moves your own marker on every connected client's map and feeds the automatic position reports below. It does not change the grid square in your PRESENCE; that stays the one you configured.

28.2 Position reports

Radio amateurs have tracked vehicles and hikers for decades with APRS, the Automatic Packet Reporting System: a station sends its position now and then, and everyone's map shows it moving. mLink has the same idea as an announce frame of its own, the position report, and borrows the name for it.

28.2.1 The position report frame

A position report is one announce frame (Section B.12). It holds a latitude and longitude, a course in 2-degree steps and a speed in km/h (both optional), and one printable character that listeners use as the map symbol, * unless the sender chooses another.

The frame carries no callsign. It is credited to the station whose PRESENCE came just before it on the same announce channel (Section 14.5), so a report goes out as [presence][position]. A report whose PRESENCE was missed cannot be credited to anyone and is dropped: an anonymous dot on the map is noise, not information.

Reports are sent once and never acknowledged; the next one will be along soon. Each station that hears one moves the sender's marker to the reported spot and adds the point to that sender's track history, which the map shows as a trail.

28.2.2 Sending reports

A report goes out in one of two ways.

The automatic report uses the precise position if the station has one, and otherwise the centre of its grid square. It reports the station as stationary (no course or speed), and up to three of the station's HELLO frames may ride behind it (Section 18.7.1).

A position report is routine traffic. It goes on any free announce channel and waits until one is free, with the same random wait as a beacon (Section 17.3). A station set to listen only sends none, and none go out while the station's own SOS is active (Section 23.2); the SOS frames carry the position anyway.

28.3 The tactical overlay

A position report says where one station is. A search, an event or a wildfire response also needs to say where things are: the area already searched, the route of a march, the command post, the last known position of a missing hiker. The tactical overlay is a shared set of such map objects. A station sends them, and they appear on the map of every station that receives them, labelled with the sender's callsign.

28.3.1 What an object can be

There are four shapes. A point may have a radius, which makes it a circle, and one or two wider rings at twice and three times that radius. A line and an area (a closed polygon) have up to 24 corners. A vector is a bearing and a range from a point. Every object has a colour, a symbol, a label of up to 39 characters and a comment of up to 120, and positions are stored to a metre or two.

An object can also carry a course and speed. The map then shows where the object would be by now, joined to its last reported spot by a dotted line, the way APRS maps show dead reckoning. The projection stops at 24 hours.

28.3.2 How objects travel

Map objects do not have an announce frame of their own. A batch of 1 to 64 objects is packed into a compact payload of its own payload kind (Section 21.3) and sent like any other message, so it gets the right size of transmission for its length and a chance at compression without anything new on the air.

Unless the sender names a station, the batch is a broadcast to everyone. A broadcast is not acknowledged: listeners who missed part of it may ask once for it to be said again, and that is all (Section 16.8). A broadcast also has a size limit, and a batch larger than that cannot go to everyone in one piece (Section 15.4.4).

Every object is named by two things: the callsign of the station that sent it and a number that station gave it. Sending an object again under the same number replaces the old version wherever the new one is heard; that is how moving an area or renaming a point updates other maps. Withdrawing an object sends a short record for that number, called a tombstone, and every station that receives it deletes the object.

The station daemon stores the objects it receives, and its own sent ones, so a client that connects later, or reconnects after a restart, sees the same picture.

28.3.3 Named groups

Any object can carry a group name of up to 23 characters, such as SAR Bravo or Water stations. The group travels with the object, so every receiving map can show one group and hide the rest. A batch in which no object has a group is sent in the shorter form without the field.

28.3.4 The overlay file

Sometimes the right way to hand over a map picture is to mail it: to a team leader at another site, or to the next shift. The client can attach all of a station's objects, or one group, to a mail as a file with the extension .mlov. The file holds exactly the bytes of a broadcast batch. When the recipient imports it, the objects are stored under the mail sender's callsign, as if that station had been heard sending them. Mail delivery is covered in Chapter 24.

28.3.5 Search and rescue helpers

The client builds the shapes a search coordinator reaches for most. They are ordinary objects, sent like any other; nothing on the air knows they are special.

A datum is the starting point of a search, usually the last known position. Dropping one makes a point with a radius of one nautical mile (1,852 m) and rings at two and three times that. The map labels the three circles 50 %, 75 % and 95 %, the usual rule of thumb for how likely the subject is to be within each distance.

A search pattern is a line laid out from a datum:

Each takes the heading of its first run. The square and the ladder take a number of straight segments from 6 to 23, the most one line object can hold.

28.4 Reaching stations in an area

Sometimes you do not know who you want to reach, only where. "Anyone near the river crossing, the bridge is out." For that mLink has the area CQ: a text message addressed to a circle on the map.

The circle travels in an AREA frame, placed in the chain just before the frame that opens the transfer: [presence][area][rts][bulk 0]... for a longer message, or the equivalent short-message chain. The AREA frame holds a centre, as latitude and longitude or as a grid locator of up to six characters, and a radius of 1 to 65,535 whole kilometres (Section B.6). The transfer itself is addressed to 0CQQTH, the reserved addressee for an area (Section 14.7).

What happens on receipt is the important part:

The AREA frame applies only to the next broadcast that completes within 30 seconds, and is used up by it, so a stale circle cannot attach itself to some later, unrelated message.

radius sender (anywhere) keeps + alerted keeps + alerted keeps it quietly outside the circle keeps it quietly no grid square set addressed area
Figure 28.1. An area CQ. Everyone who hears it keeps the message; only stations whose configured grid square lies inside the circle are told they were addressed.

28.5 The offline map

The map every client shows is a vector map, not a set of downloaded picture tiles. The coastlines, borders, lakes, rivers and city names come from the public-domain Natural Earth data set and ship with the client, so the map works with no internet connection at all, which is the situation mLink is built for. It uses a plain equirectangular projection (latitude and longitude as straight horizontal and vertical lines), which stretches east-west distances toward the poles but is adequate at the scale HF radio works on; the scale bar corrects for the stretch at the map's centre.

28.6 What to remember

Part VI: The Station Software

Chapter 29

Inside the Station Daemon

29.1 One program, a few busy threads

The station daemon is called mlinkd ( places it among the three programs). One daemon drives one radio. It is built for Linux today; Windows and macOS are future build targets for the daemon. Operators never touch it directly; they talk to it through a client ().

Inside, the daemon is split into a handful of threads, each with one job, handing work to each other through queues. The split follows one idea: nothing slow may ever stand in the way of something that must be on time. The sound card delivers a fresh block of 512 samples every 43 milliseconds whether or not anything else is ready; a command to a rig can take a fifth of a second to be answered; a query to an internet server can take several seconds. Each of those lives on its own thread so none of them can stall the others.

operators' clients command thread UDP/JSON, sessions timer, 100 ms event loop MAC: decides, does the talking sweeps: read records, advise one message at a time station manager the database records only, never acts decoder workers (2) demodulate, correct errors audio thread receiver's detectors, key-up sequence encoder thread one transmission rendered into one audio buffer network worker mail server, cluster, sources sound card + radio rig thread: CAT, PTT line GPS thread (gpsd) audio in audio out detections frames plan buffer key/unkey writes reads requests own position
Figure 29.1. The daemon's threads. The event loop in the middle makes every decision; the audio thread sits closest to the radio; the station manager keeps the records everyone else reads.
Table 29.1. The daemon's threads and what each one does.
ThreadIts one job
Event loopTakes messages off a queue one at a time and acts on them. Every decision about the air is made here.
TimerPosts a tick to the event loop every 100 ms, so deadlines fire on time.
Command threadReceives requests over the network, from clients and from other members of a cluster, checks who is asking, runs them one at a time and answers.
Audio threadReads and writes the sound device, runs the receiver's detectors on every incoming block, and runs the key-up and key-down sequence.
Decoder workers (two)Turn a detected stretch of audio into bytes (Section 13.7).
Encoder threadTurns a planned transmission into audio samples, ahead of time.
Rig threadOwns the serial port to the radio: keying, frequency, mode.
Network workerEverything that waits on the internet or the local network: the mailserver, internet sources, the other members of a cluster. One job at a time, so a slow server holds up only the next network job, never the radio.
Stream pumpPackages live audio and spectrum for clients that asked to see them, ten times a second.
Device watcherRe-reads the list of sound devices while a client is showing it, and reports when one is plugged in or removed.
GPS threadOptional. Reads position fixes from a GPS service (Section 28.1.2).

The program that lets web browsers in is not a thread at all but a separate process ().

29.2 The event loop: one line of decisions

Everything that could change what the station does next arrives at the event loop as a message in one queue: "a frame was decoded", "a timer tick", "an operator wants to send this", "an emergency was armed". The loop takes one message, deals with it completely, and takes the next. It never works on two at once.

That single line is deliberate. The protocol juggles reservations, reply windows, retries, relays and the emergency service; if two threads could change that state at once, the station would sooner or later make two contradictory decisions in the same instant. With one line, the question "what did the station know when it decided?" always has one answer.

The loop waits at most 100 ms for a message, and the timer's tick arrives every 100 ms. Deadlines that matter to the protocol (the end of an incoming transfer, the window for an expected reply) are checked on every tick; housekeeping in the database runs about once a second.

29.3 Three parts: the MAC, the record keeper, the sweeps

Inside the event loop, work is divided by one rule that explains most of the station's behaviour:

29.4 Render the whole transmission, then key

Receiving runs all the time on the audio thread and the decoder workers; Chapter 13 follows a block of audio from the sound card to a decoded frame. Transmitting goes the other way, and it is built around one rule: everything in a transmission (Section 14.1) is decided and turned into sound before the radio keys.

  1. The MAC builds a plan. Which frames, in which order, on which channel, at which bulk rate.
  2. The encoder thread renders the whole transmission. Every frame is encoded, modulated and laid end to end into one continuous audio buffer, with the ends faded as describes. Up to 16 transmissions can wait to be rendered.
  3. The audio thread keys the radio. A rendered buffer of ordinary traffic waits while the station is in the middle of hearing a frame (Section 13.6.1) and then gets one last listen (Section 17.5.1). The audio thread then asks the rig thread to key and sends 60 ms of silence while the radio's transmit chain settles. If the rig has reported by then that it did not key, the transmission is dropped before any signal is sent. Otherwise the buffer plays from start to finish.
  4. The audio thread lets go. After the buffer ends come 40 ms of silence, then the unkey, then receiving again.

Rendering first and keying second means the radio is keyed for exactly as long as the transmission needs, and the rendering is done while the station is still listening, so it costs no time on the channel. What the receiver does while the station's own signal is going out is in .

29.5 The database is the station

Everything the station must remember lives in one SQLite database file. The rule is short: if a fact must survive a restart, it is in the database; if it need not, it is a live event and nothing more. What is kept there:

Because the records are on disk, stopping and starting the daemon loses very little; what a restart does with messages that were on their way out is in Section 20.7.

29.5.1 Where the file lives

Unless told otherwise the file is mlink.db in one per-user data folder, ~/.local/share/mlink/, or $XDG_DATA_HOME/mlink/ if that variable is set. The daemon creates the folder the first time it runs. Setting the environment variable MLINK_DATA_DIR names a different folder, and the --db flag names a different file outright.

Every way of starting the daemon finds the same file: started by the client (which passes no database path), started from the packaged application, or run by hand in a terminal. A daemon pointed at a different file is a brand-new station with an empty mailbox.

One database serves one daemon. At start-up the daemon takes a lock beside the file; a second daemon started on the same database stops with a message naming the file and leaves the first one alone.

29.6 Settings, flags and what sticks

The daemon keeps its configuration in the database. Changes made from the client are applied at once and saved, so they are still in force after a restart. Running the daemon with no flags always means "use what is saved".

Four of the command-line flags name station settings, and for those a flag given on the command line wins, and is saved. Start the daemon once with --callsign W1AW and W1AW is stored; start it next time with no flags and it is still W1AW. Such a flag overwrites what was saved every time it is given, so a start-up script that passes an old value keeps undoing changes made from the client. The remaining flags describe this one run and are not remembered.

Table 29.2. Every command-line flag of the station daemon. "Saved" means the value is written to the database and used on later runs that do not give the flag.
FlagWhat it setsSaved
--callsign CALLStation callsign. A fresh station has the placeholder N0CALL and sends no ordinary traffic under it (Section 14.2.2).yes
--grid GRIDMaidenhead locator.yes
--password PASSThe station password clients must present, up to 63 characters (default mLink). Stored as a hash.yes
--audio BACKENDSound system: auto, alsa, pipewire or null. Any other name is refused and the daemon does not start.yes
--port NNetwork port for clients (default 8488).no
--local-onlyAccept clients from this computer only, the web client included.no
--ws PORTPort for the web client (default 8489; 0 turns it off).no
--web-lanServe the web client to the whole local network, not just this computer. Ignored, with a message, when --local-only is also given.no
--web-root DIRWhere the web client's files are. By default a folder named web next to the daemon program.no
--db PATHThe database file.no
--loopback ADDR:PORT, --node NConnect to the simulated air used for testing, as station number N, and not to a radio (Chapter 33).no
--help, -hPrint the list and stop.

An unknown flag, or a flag missing its value, stops the daemon with an error and is never ignored: a typing mistake should not quietly start a station with defaults. In a cluster, a password given on the command line holds only until the member next catches up with the others (Section 31.8.1).

29.7 Sound systems

The daemon reaches the radio's audio through an interchangeable audio backend. Three exist:

With auto, or with nothing chosen, the daemon picks PipeWire when it was built with it and PipeWire is installed, and ALSA otherwise. Capture and playback can be different devices: receive from one interface, transmit through another. The backend and the devices can be changed from the client while the station runs, but only while the MAC is idle, never in the middle of a transmission; a request at any other moment is refused and can be repeated. If the new choice will not open, the daemon goes back to the previous one.

If the sound device disappears (a USB cable pulled, the sound server restarted), the daemon raises a blocking alert, keeps running, tries the device again about every eight seconds, and clears the alert when it comes back.

29.7.1 Never keep the sound card warm

Between transmissions the audio thread hands the sound system nothing to play. It writes samples only from key-up to key-down.

29.8 Rig control and keying

Everything that talks to the radio over a serial cable goes through the rig thread. A CAT command can take tens to hundreds of milliseconds to answer; the audio thread, which works in 43 ms blocks, must never wait for one, so it posts "key" or "unkey" and carries on. A key request is served ahead of any queued frequency or mode command, and a newer one replaces an older one that has not been served yet.

The station keys the radio in one of three ways (the form that chooses is described in Chapter 4):

The rig thread also keeps watch. When the rig can report whether it is really transmitting, the thread checks after an unkey and between commands; if the transmitter is still on it sends the unkey again, then drops the keying line, and if even that fails it sends every client a critical notice to check the radio at once. A USB serial rig that drops off the bus is held with the keying line low while the thread looks for the same device and reconnects when it returns.

If a rig was configured and does not come up when the daemon starts (unplugged, in use by another program, no permission), the daemon still starts, with no keying, and raises a blocking alert saying why.

29.9 Alerts that stop the station

Most things the daemon has to say are advisories: a message delivered, a relay failed, mail arrived. A few conditions mean the station cannot do its job. Those are states, not one-off events: they stay raised until the cause is gone, and a client that connects afterwards is told at once. The client shows them as the red banner (Section 5.3.3). The causes are:

A distress call is not held back by a missing callsign (Chapter 23).

29.10 Reading the daemon's log

The daemon narrates what it does. The same lines go to its console and to any client that asks for them (). The daemon keeps the most recent 1,024 lines in memory; a client can ask for the last 200 of them, or up to 512, and then receives new lines as they happen.

Most lines have a fixed shape: the time in seconds since the daemon started, a level, the part of the daemon that is speaking, then a short event name in lower case with underscores and named values. When the audio thread keys the radio it logs audio_rx_to_tx_rampup with the channel and the priority; when someone signs in, auth_ok with the role and the account.

Levels run from trace and debug (for developers) through info (normal activity) to warn (something unusual) and error (something failed). Clients are sent info and above. A warn line is not an alarm: the daemon uses warnings for things like a refused sign-in or a cluster member that went quiet. Things the operator must act on arrive as alerts.

29.11 What to remember

Chapter 30

The Client and the Daemon

30.1 Two programs, one conversation

The station daemon (Chapter 29) owns the radio, the protocol and the database. The client owns the screen ( walks through it). They talk only through a defined set of commands and live updates, sent over ordinary networking, and that set is the whole relationship between them.

The client never opens the station's database, not even to read it. Every fact it shows, it asked the daemon for or was told by the daemon. There are good reasons for this beyond tidiness:

desktop client shack PC, laptop web browser same client, in the page WebSocket bridge separate process station daemon port 8488 (UDP) database inside UDP datagrams, JSON inside ws:// port 8489: web page + WebSocket UDP
Figure 30.1. Two ways in. The desktop client speaks the daemon's own protocol directly. A browser speaks WebSocket to a small bridge program, which turns it into the same protocol; to the daemon, both look alike.

30.2 Datagrams with JSON inside

Client and daemon exchange UDP datagrams, by default on port 8488. UDP sends self-contained packets with no connection to set up or tear down, which suits a conversation made of short questions and answers.

Each datagram starts with five bytes: one byte saying what kind of packet it is, two bytes of sequence number and two bytes giving the length of what follows. What follows is JSON text.

Table 30.1. Packet kinds in the first byte of every datagram.
KindDirectionCarries
Commandclient to daemonA request.
Responsedaemon to clientThe answer to one request.
Eventdaemon to clientA live update on a stream the client subscribed to.
Command, response and event fragmentsas abovePieces of a document too large for one datagram ().

The daemon listens on every network interface unless it was started with --local-only, in which case only programs on the same computer can reach it (Section 29.6 has every flag). The password is the gate, and nothing in the conversation is encrypted, so a station reachable from a network should have its own password and should be on a network you trust.

30.3 The request and its answer

Every command is a JSON object with the same outer shape, called the command envelope:

The req_id matters because a client may send several requests before the first answer returns, and a late answer to an old question must not be mistaken for the answer to a new one.

Every answer has a type naming what kind of answer it is, and the echoed req_id if there was one. An error is an answer too, with "type":"error", a human-readable error message, and in most cases a code: a short fixed word a program can test for.

30.3.1 Strict where it matters, lenient where it helps

Each command declares its parameters in the daemon: name, type, whether it is required, and for some, the list of allowed values. Before a command runs, the daemon checks the request against that declaration.

Command names are forgiving about spelling. Upper and lower case, underscores, hyphens and spaces are all ignored when a name is looked up, so get_config, GetConfig and Get-Config are the same command. An unknown command gets an error saying so.

Clients do not need a printed list of commands. help returns every command the daemon offers with its category, a description and the role needed to use it; get_commands returns each command's parameters in full. A command that is declared but not built yet is still listed, and answers with the code not_implemented.

Table 30.2. Error codes every client should handle, besides the three parameter codes.
CodeMeaning
unauthorizedNo session number, an unknown or expired one, or a failed sign-in. Sign in again.
auth_throttledToo many sign-in attempts from this address; wait a few seconds.
insufficient_roleThe command needs a higher role than this session has.
account_revoked, accounts_requiredThe account behind the session was removed or disabled, or guest access was switched off. The session has been ended.
not_implementedThe command is declared but not built.
busyNot now; ask again shortly.
subs_fullThe session already holds its limit of stream subscriptions.
response_too_largeThe answer would not fit even in fragments. Narrow the question.

Individual commands add a few codes of their own, such as not_found.

30.4 A worked example

Here is an exchange with a fresh daemon, shortened where marked. The client signs in first, with the station password and a name for itself:

{"command":"auth","req_id":1,"password":"mLink","client_name":"alice-laptop"}

The daemon answers:

{"req_id":1,"type":"auth_ok","client_id":69848641,"role":"administrator",
 "posture":"solo","guest":false,"timeout_expiry_min":30}

The client_id is this client's session number from now on. The answer also says which role the session was given, whether the station signs people in by one password or by named accounts, and after how many idle minutes the session expires. Session numbers start at a random point, so another computer on the network cannot simply guess one.

Now the client asks to be kept up to date on the station's configuration, then changes the grid locator:

{"command":"subscribe","req_id":7,"client_id":69848641,"stream":"config"}
{"req_id":7,"type":"subscribed","stream":"config","newly_added":true}

{"command":"set_grid","req_id":8,"client_id":69848641,"grid":"DM12ab"}

Two things come back. One is the answer to the request. The other is an event on the config stream, sent to every client subscribed to it, so every open screen in the station shows the new value (shortened here):

{"type":"event","stream":"config","callsign":"N0ABC","grid":"DM12ab",
 "relay_policy_name":"allow_bulk","operator_present":false, ... }
{"req_id":8,"type":"grid_updated","grid":"DM12ab"}

The event carries no req_id: it is not an answer to anyone's question, it is news. It arrived here before the answer; either order can happen, which is why the client matches answers by number.

30.5 Streams: being told instead of asking

A client that asked for everything every second would keep the daemon busy answering questions whose answers had not changed. So most things the client shows arrive on streams: named feeds the daemon publishes to when something changes. A client subscribes to a stream by name and from then on receives an event whenever there is news.

Table 30.3. The main streams a client can subscribe to.
StreamTells the client about
messagesA message received over the air.
mailChanges to the mail store.
tx_statusEach step in the life of an outgoing message.
stations, linksA station heard or changed; who hears whom.
notificationsAdvisories and alerts for the operator.
emergencyEmergency events.
configThe station's configuration.
mac_stateWhat the daemon's protocol layer is doing: idle, sending, waiting for a reply.
netThe virtual net the station belongs to.
logThe daemon's log lines.
seats, clusterOther operators' activity at this station; cluster membership.
audio_rx, audio_tx, spectrumLive audio and a spectrum display, only while a client wants them.

A tx_status event carries the message's number in the outbox (tx_id), a state, a time, and sometimes an error text giving the reason. The state is one of the nine outbox states by their names inside the daemon (draft, pending, airing, sent, failed, deferred, expired, deposited, transferred), or queued when a message goes back into the send queue because the channel turned out to be busy at key-up. What each state means to the operator is in .

Subscriptions belong to the session, so they disappear when the client signs out or its session expires. A session can hold up to 32 of them. Stream names are free text: subscribing to a stream that nothing publishes is harmless and delivers nothing. The heavy streams (audio and spectrum) cost the daemon nothing unless someone is subscribed.

30.5.1 A snapshot, then the stream

A stream only reports changes, so a client that has just connected also needs the current state. The pattern is the same everywhere: subscribe to the stream, then ask for a snapshot with the matching get_ command.

For each kind of state, the snapshot answer and the stream event are built by the same piece of the daemon, so they cannot drift apart: the config event above carries exactly the fields that get_config returns.

Clients adopt what the daemon reports, not what they asked for. If an operator types a callsign in lower case, the daemon stores it in upper case and announces that, and every screen shows the upper-case form.

30.5.2 Alerts that must not be missed

Notifications come in two sorts. Most are advisories, sent once. A few are blocking conditions, which are states and not events (Section 29.9 lists their causes). Each is announced when it is raised and again when it clears, and when a client subscribes to notifications the daemon immediately repeats every one that is raised at that moment. A client that connects an hour after the sound card died still finds out at once.

30.6 Sessions and who is asking

A session begins with a successful auth and is identified by its session number. The daemon remembers where each session's packets come from and sends answers there. If a known session number arrives from a new address (a laptop that moved from wired to wireless, say), the session simply follows it. Every command refreshes the session; after 30 minutes with no command at all it expires, and the next command is told to sign in again. A daemon holds up to 32 sessions at once.

Who may sign in with which name and password, and what each role may do, is decided by the rules in Chapter 7. At this level only three things show. Sign-in attempts are limited to five in any ten seconds from one address, because checking a password is deliberately slow work and a flood of guesses must not tie up the thread that answers every other command. Each session carries a role (operator, technician or administrator), each command needs one, and the daemon compares the two on every single command, not once at sign-in. And a command above the session's role is refused with the reason spelled out:

{"type":"error","error":"insufficient role for this command",
 "code":"insufficient_role","required":"technician","role":"operator",
 "command":"set_callsign"}

Because the comparison happens every time, a change to someone's account takes effect on their very next command: a new role is adopted without signing out, and a removed or disabled account's session is ended. The emergency commands are the one exception to that ending (Section 23.1.1).

30.6.1 Knowing the daemon is still there

UDP has no connection that breaks, so a client cannot tell from silence alone whether the daemon has stopped or simply has nothing to say. The reference client handles this by asking: after four quiet seconds it sends a small harmless request. It declares the connection lost only when nothing at all has arrived for twelve seconds and that probe has gone five seconds without an answer, or at once if the computer reports that nothing is listening on the daemon's port any more. Any packet from the daemon counts as a sign of life, so a busy session never needs to ask. An ordinary request that gets no answer within five seconds is reported as timed out.

30.7 Mismatches are loud

Clients and daemons are released together, and a client expects the daemon it talks to to understand the commands the client relies on. If the daemon rejects one of those, that is not something to work around quietly: it means the client and daemon come from different versions. The reference client checks what it needs when it connects, and if the daemon does not know one of those things it raises the same red banner as a lost sound card, reading "client/daemon version mismatch" and naming what failed.

30.8 When one datagram is not enough

A UDP datagram carries at most about 64 KB. Most answers are far smaller, but some are not: a mail with attachments, a long list of messages with their bodies. Those are split into fragments. Each fragment carries a short sub-header (which document it belongs to, its position, and how many fragments there are) followed by a 60 KB piece. Every piece except the last is the same size, so the receiver can put each one in place as it arrives, in any order. One document can be up to 4 MB this way, in either direction.

Lost fragments are not resent. A document that has gone five seconds without a new piece and is still incomplete is thrown away, and the requester's normal timeout reports the failure; on a LAN or on the same computer that is rare. An answer too large even for 4 MB is replaced by an error with the code response_too_large.

30.9 Browsers and the WebSocket bridge

A web browser cannot send UDP datagrams. What it can do is open a WebSocket: a two-way message connection that starts life as an ordinary web request. To let browsers in, mLink has a small separate program, the WebSocket bridge.

The daemon starts the bridge itself, as a child process, and by default it listens on port 8489 (--ws changes the port, and --ws 0 turns the bridge off). For every browser tab that connects, the bridge opens its own UDP conversation with the daemon and relays packets both ways, unchanged: each WebSocket message holds one datagram, header and all. To the daemon, a browser looks exactly like a desktop client on another port: signing in, sessions, roles and streams all work the same way.

The bridge does one piece of translation for the browser's benefit: large documents. A browser may send one oversized request as a single WebSocket message, and the bridge splits it into fragments for the daemon; fragmented answers and events from the daemon are put back together in the bridge and handed to the browser as one message. Browser code never has to deal with fragments.

The bridge also keeps an eye on each browser: it sends a WebSocket ping every 30 seconds and closes the connection if no reply has come for 60 seconds. If a browser reads too slowly and its outgoing queue fills, the oldest whole messages are dropped, never part of one. It serves up to 32 connections.

30.10 The web client

The client an operator sees in a browser is the same client program as the desktop one, built to run inside a web page as WebAssembly. The bridge serves it: a plain web request to port 8489 gets the client's page and files, and the page then opens its WebSocket back to the same address. Every file is sent marked "do not cache", so a browser always loads the client that matches the daemon it came from, and a daemon upgrade upgrades every operator's screen with nothing to install.

By default the web client is served to the station computer only. Start the daemon with --web-lan and it serves the whole local network; the daemon prints the address operators should open, such as http://shackpc.local:8489. Operators still sign in exactly as they would from a desktop client. The WebSocket connection is not encrypted, so keep this to a network you trust.

30.11 Writing your own client

Everything above is the whole contract. A terminal program, a phone app or a logging bridge can talk to a station with nothing more than a UDP socket and a JSON library: sign in with auth and keep the client_id; call help and get_commands to learn what the daemon offers; subscribe to the streams you care about, then fetch their snapshots; number your requests and match the answers; and treat an unknown error as a mismatch to report, not to hide.

The contract is not frozen: commands are still being added and refined. get_commands on the daemon in front of you is always the current description.

30.12 What to remember

Chapter 31

Clusters: One Station, Several Radios

31.1 When one radio is not enough

The basic unit of mLink is simple: one station daemon drives one radio on one band (Chapter 29). Real stations outgrow that. A club's emergency trailer may carry a 40 m rig for regional traffic and a 2 m rig for the local served agency. A home station may have an HF radio in the shack and a VHF radio on a hilltop across town, connected over the internet. mLink handles this with a cluster: several daemons, one callsign, acting as one station. Growth in people, several operators with their own names and roles, is a separate matter (Chapter 7).

31.2 A cluster is one station with several radios

Each daemon in a cluster is a member. A member is a machine, never a person: it has one radio, one band, and a short human label such as valley or 40m-trailer that you choose when it joins (the computer's hostname is used if you give none). All members share the same callsign, because on the air they are the same station.

Members talk to each other over the cluster link, which is ordinary networking: a LAN inside a trailer, or the open internet between a home and a hilltop. It uses the same network port a member's clients use (Section 30.2), and it never touches the radio. It carries three kinds of thing: a short keepalive, the shared record of what every radio hears, and occasional pieces of real work handed from one member to another.

cluster link LAN or internet, never the radio member "shack" daemon + HF rig 40 m internet gateway member "hilltop" daemon + VHF rig 2 m member "trailer" daemon + HF rig 80 m W7AAA (40 m) K7BBB (2 m) on the air on the air operator's client connects to any member
Figure 31.1. A cluster: one callsign, three daemons, three radios on three bands. Members reach each other over the cluster link (dashed). An operator's client connects to whichever member is convenient and sees the whole station.

From the operator's chair the cluster is almost invisible. You connect your client to whichever member is nearest, you see the stations every member has heard, and you send mail the way you always do.

31.3 Joining a cluster

Joining takes a label, one address, and one decision by an administrator. There is no shared secret to type into every machine.

  1. On the new member, an administrator gives the address and port of any member already in the cluster, plus a label for the new machine. The new member makes a fresh private/public key pair for itself and sends a join request carrying its callsign, its label, a random member number and its public key.
  2. The existing member holds the request as pending and shows it to its own clients with the callsign, the label and a short fingerprint of the new member's key, written like ab12-cd34. The same fingerprint is shown on the joining machine.
  3. An administrator compares the two fingerprints (by phone, by looking at both screens, by voice on the radio) and approves or denies. Matching fingerprints show that nobody in the middle swapped in their own key.
  4. On approval, the existing member sends back the cluster's shared secret and, if the station has one, its mail key, both sealed so that only the new member's private key can open them. The new member asks for this answer every two seconds until it arrives.

The shared secret is 32 random bytes. It is made the first time a daemon approves a join request, which is the moment an ordinary single station becomes the first member of a cluster. A member holds at most eight pending requests; one that nobody decides on is forgotten after 15 minutes, and the joining machine gives up after 10 minutes of waiting. A daemon whose callsign differs from the cluster's is refused with a clear error: a cluster is one station, and one station has one callsign. Because membership itself travels through the shared record (), a new member only ever needs one reachable address; it learns about every other member from there. A cluster holds up to 16 members.

31.3.1 The shared mail key is only borrowed

Approving a member hands it the station's mail key, the credential this station uses with the mailserver (). Approving is therefore a trust decision: the new machine can now act for the station with the mailserver.

The key arrives on a lease. Every successful signed contact with another member renews it. A member that has had no such contact for seven days throws the key away, logs a warning, and has to be approved again to get it back. Leaving the cluster throws it away at once. Radio kits move between missions, and a box that was lent to another group should not keep acting as your station. A mail key that a member registered for itself, before it joined, is that member's own: it is kept, and it is never leased or discarded.

31.4 Keeping in touch

Every member sends every other member it can reach a small keepalive every 10 seconds and gets a reply. Both carry a signature made with the cluster secret, and a time that must be within 120 seconds of the receiver's clock; a message seen a second time is refused. Members that keep network time never notice this. A member whose clock is minutes off fails its keepalives, and each failure is logged as a warning. The keepalive also carries the member's label, its current band and dial frequency, and whether it has a working path to the mailserver.

A member heard from within the last 30 seconds (three keepalive periods) counts as live. After three failed keepalives in a row, a member is only tried on every sixth round, about once a minute, so a dead machine does not cost the others much effort.

The station's rule for a silent member is short: if we can't reach that daemon, we can't use it to reach anyone.

No warning is sent at start-up for a member that was already silent.

31.5 Sharing what every radio hears

The heart of a cluster is the journal. Every member keeps a numbered, append-only log of what it has learned: a station heard, a position or status report, a link between two stations, a change in membership, a station-wide setting, the outcome of work another member asked it to do. Each member writes only its own log. Nobody ever edits somebody else's.

Copying is done by asking, never by pushing. After each successful keepalive, a member asks its peer: "for each member's log I hold, what comes after entry number N?" The answer comes back six entries at a time, up to sixteen answers per member per round, and it also lists the newest entry number of every log the peer holds, so a member learns about logs it had never heard of. Any member will serve any log it holds, not just its own. A member hidden behind a home router, which nobody can reach directly, still catches up: it asks a reachable member, and that member hands over everyone's news.

Three rules make this sturdy without any clever merging.

Members may be on opposite sides of the internet with clocks that disagree, so an entry about a station never says "heard at 14:02:17". It says "heard 12 seconds ago", and the member that applies it works out the time on its own clock.

A member hears a busy station many times a minute, so routine "still hearing it" updates for the same station are written at most once every 30 seconds, while anything that matters (a new station, a new position, new telemetry or status, an emergency) is written immediately. Entries older than two hours are pruned, the same limit the station uses for its own links map (Section 18.8). Membership and station-wide settings are never pruned, so a member that joins next year still learns them from the first entry on.

31.5.1 Heard by me, and heard by the station

Every member keeps what other members heard in separate records from what its own radio heard. Everything the member does on the air (choosing whether to offer a relay, deciding who is reachable, building the list of stations it tells others it hears) reads only its own radio's records, exactly as it would if it were alone. The client gets both, with each row marked by the member that heard it. The same distant station heard by two members on two bands appears as two rows, one per member.

31.6 Carrying traffic across bands

The payoff of shared hearing is backhaul: moving a message from one member's band to another member's band over the cluster link. It is one more kind of helper in the ordinary relay exchange (Section 19.8 gives the on-air side, including the 3 dB a cluster member takes off the figure in its OFFER).

Suppose W7AAA on 40 m has a message for K7BBB and cannot reach it, so it sends a relay REQUEST. The station's 40 m member overheard the original message and holds a copy, but its own radio cannot hear K7BBB. The hilltop member's 2 m radio heard K7BBB within the last two minutes, and the hilltop is live. The 40 m member may then volunteer, provided its relay setting allows carrying large messages (Section 19.9) and the message is no larger than 40,960 bytes.

  1. If W7AAA selects it, the 40 m member passes the message to the hilltop over the cluster link, trying twice if need be, with the name of the original author attached.
  2. The hilltop sends the message to K7BBB on 2 m as a relay would, naming W7AAA as the author.
  3. The hilltop writes the outcome into its journal. The 40 m member picks it up the next time it asks, and sends the RESULT to W7AAA on 40 m.

The 40 m member waits up to 60 seconds for that outcome before reporting failure. The member that talked with W7AAA never transmits the delivery, and the member that delivered never talks to W7AAA.

There is a second form. When a REQUEST asks for a station that can reach the destination even without a copy (), a member that holds no copy and cannot hear the destination itself, but has a live member that can, may still offer. The requester then sends it the message first, and it travels on over the cluster link as above.

31.6.1 Members that share a callsign must not share timing

When several stations might answer the same thing, each waits a different time so they do not all key at once, and some of those waits are worked out from the station's callsign (). Cluster members share a callsign, so two members on the same band within earshot of each other would choose identical waits and collide every time. Each member therefore mixes its own member number into the calculation. A daemon that is not in a cluster behaves exactly as it would without any of this.

31.7 Who owns the mail

The rule that only the owner acts matters most for mail, which must never be lost and never be sent twice by accident. The member where a mail was composed owns it; its outbox row is the truth about that mail. Ownership moves only when the owner hands it over, or when the owner is gone.

The cluster uses this in three places, all to do with reaching the mailserver through a member that has a working internet path to it, a gateway member ( explains gateways, pickup and custody):

Mail sealed with encryption is never handed to another member or copied to one: that member would be depositing its plain text (Section 24.4.7).

31.7.1 When the member that wrote the mail goes silent

The owner rule has one weak spot: a member that dies takes its unsent mail with it. If the hilltop box loses power with three mails in its outbox, the owner of those mails is the one machine that can no longer act. So each member lodges a copy of its unsent mail with a gateway member, before the copy is needed.

So an operator's mail survives the loss of the machine it was typed on.

31.8 Administering the whole cluster from one seat

Administration happens from the client, from any member. Underneath, any command from a signed-in client can name a target member, by its label or its member number, in a field called member. The member you are connected to carries the command over the cluster link and hands back the answer, as if you had connected to the target directly. Your own role travels with the request, and the target member enforces it exactly as if you had signed in there. A few things never travel this way: the cluster commands themselves, signing in, and subscribing to live updates, which all belong to your own connection. A request cannot be passed on a second time from the target to a third member.

31.8.1 Station-wide settings

A few settings describe the station, not the machine, and every member must agree on them. These travel through the journal:

Values are sealed before they enter the journal (with AES-256-GCM, the cipher of Section 26.3.1, under a key derived from the cluster secret), because the cluster link is signed but not otherwise encrypted and may cross the open internet. Passwords were already stored only as one-way hashes; sealing hides even those. Each setting is decided by the most recent change anywhere in the cluster, so two administrators editing two different people never overwrite each other; on an exact tie, the member with the higher member number wins, so every member reaches the same answer.

Everything about a particular machine stays on that machine and is never shared: audio devices, band, rig control, keying, calibration.

31.8.2 What the cluster secret does and does not protect

The cluster secret is the boundary of the station. Every message between members carries a signature made with it, so a machine that holds the secret is trusted as a member: its journal entries are applied, and its forwarded requests are honoured at whatever role they claim. That is why joining requires an administrator's approval with a fingerprint check, and why that approval is the only gate.

The signature proves who is speaking and that nothing was changed on the way. It does not hide anything. Apart from the answer to a join request and the sealed settings, what members send each other, messages and mail on their way across included, crosses the link readable; run the cluster link over a network you trust or through a private tunnel.

A member leaves by its own command, which wipes its copy of the secret, the journal, its records of other members' hearing, and its borrowed mail key. The cluster has no command that removes another member.

31.9 What to remember

Part VIII: How We Know It Works

Chapter 33

How We Know It Works

33.1 Why test on a simulated band

mLink is tested on real radios too, but a real band is a poor laboratory. You can't make it do the same thing twice, you can't make twelve stations key up on one frequency whenever you change a line of code, and when something goes wrong you get one recording from one receiver and a lot of guessing.

So most of the testing happens on the simulated air, which the project calls the fake over the air harness, or fOTA for short. It gives three things a real band can't:

What makes this more than a toy is that the stations in the simulation are the real thing: the station program you install (), with only the sound card swapped out.

33.2 The simulated air

33.2.1 Real stations, fake sound cards

For simulation a station is started with a null audio device that touches no hardware. Instead it trades audio with a separate program, the channel mixer, over the computer's internal network. The audio is what a sound card would carry: one stream at 12,000 samples per second (), traded in blocks of 512 samples, 42.7 milliseconds each. Each block is one round:

  1. Every station sends the mixer its next block of transmit audio. A station that isn't transmitting sends silence.
  2. The mixer builds a separate receive mix for each station. For listener B it adds up every other station's transmit block, each scaled by the strength of the path from that station to B, plus B's own noise, plus whatever band-wide interference the test has switched on. A separate mix per listener is what lets a test build a station that hears one neighbour and not another, or a path that works one way only.
  3. Each station gets its own mix back as its receive audio, and the next round begins.
Station A real station program Station B real station program Station C real station program null audio device instead of a sound card Channel mixer one round = 512 samples (42.7 ms of audio) gain for each path A→B noise at each listener fades, dropped frames carriers, crashes, voice one receive mix per listener waits for every station before each round solid: transmit dashed: receive Event log every frame, labelled Recording the band, with labels Test script drives, then grades commands to stations; their logs come back for grading
Figure 33.1. The simulated air. Real station programs trade audio with a channel mixer in 512-sample rounds; a test script sets up the band, talks to the stations as a client would, and grades what they did.

33.2.2 A second is 12,000 samples

Here is the idea the rest of the harness is built on. Inside the simulation, time isn't read off the computer's clock. A second is 12,000 samples of audio, and nothing else.

Each simulated station runs on a sample clock: its sense of "now" is worked out from how much audio it has used up. Every timer, every wait and every deadline inside the station counts in that time. The mixer measures elapsed time the same way, as its position in the audio stream divided by 12,000, and so do the test's own waits and deadlines. Everything in the run agrees on one clock, and that clock is the audio.

The mixer also runs in lockstep. It won't send out a round until every station has delivered its block for that round, so if one station stalls the whole air waits for it. And a station holds its own clock still while it's decoding what it just heard or building a transmission it's about to send, so thinking time never leaks into air time.

Put those together and you get the property that matters: a busy computer makes a run slower, never different. A starved machine can't make a station miss a deadline, because the deadline is counted in the same samples the station is waiting on. It is also why the air can run far faster than real time: up to 16 times by default in the test suite, and usually eight times in the long operator simulations described later.

33.2.3 A test that breaks at speed is a bug

This leads to a hard rule for the test suite. If a scenario passes at real time and fails at sixteen times real time, the speed is not the problem. Somewhere, in the scenario or in the station, something is counting wall-clock time where it should be counting on-air time. That is a defect with a location, and the fix is to find it, not to slow the test down until it passes.

One more detail keeps the simulation honest. Real stations' clocks have nothing to do with each other, so in the test suite each simulated station's clock starts at its own random offset of up to a day. Any behaviour that accidentally depends on stations sharing a clock shows up in simulation instead of hiding there.

33.3 Making the band misbehave

A clean band isn't much of a test. The harness has a set of impairments, and each one is built to work the way the real thing does, not just to produce the same symptom.

33.3.1 Effects on one path

These act on one sender's signal on its way to one listener, before the mixing. They're the things that make "A hears B" differ from "C hears B".

33.3.2 Effects on the whole band

These are interference that every listener hears the same way, whoever is transmitting, added after the mixing: a steady carrier at a chosen frequency, optionally amplitude-modulated; atmospheric crashes, random impulses at a set average rate, like static from distant lightning; over-the-horizon radar, a train of chirped pulses, the "woodpecker" older hams will remember; and a recorded SSB voice clip dropped into the passband at a chosen dial offset, like a phone contact drifting onto the frequency.

33.3.3 An impairment that never happens fails the run

There's a quiet trap in every channel simulator. Suppose a test asks for "B loses frame 3 of A's next bulk transfer", but A never sends one, or the test misnames the frame. Nothing is lost, every repair check downstream passes on a clean channel, and the test goes green for a situation that never happened.

The harness closes this trap. Any impairment aimed at a particular sender that's still waiting to fire when the run ends is reported as never fired, and the whole run counts as failed: it proved nothing.

33.4 Stopping the air at an exact moment

Some scenarios need the test script to act at a precise instant on the air: "hand station A a message while station C's probe is on the air". The stations and the mixer count samples, but a test script is ordinary software on an ordinary computer. With the air running sixteen times faster than real time, a tenth of a second of the script's own delay is 1.6 seconds of air, long enough for the moment to pass entirely.

So the mixer can pause the air. The test arms a pause to happen right now, or a set on-air delay after a named station's next key-up or after it logs a particular event. When the moment comes, the mixer stops sending rounds, and since every station is waiting on its next block, every station's clock stops with it. The stations still answer commands, so the script can do what it came to do (submit a message, stop a station, arm a frame loss), check that the station took it, and resume. However long the script takes, it costs no time on the air.

A pause lands on the first round boundary at or after the requested moment, so it's accurate to one round. While paused, the test can also step the air forward by an exact on-air duration and stop again, to place a second action at a computed offset from the first.

Two safety checks keep pauses honest, and both fail the run. A pause that isn't resumed within three seconds of real time is given up, and the mixer resumes on its own. And a pause that was armed but never triggered is reported the same way as an impairment that never fired.

33.5 What a run leaves behind

33.5.1 The event log and the labelled recording

Every station forwards its structured log events to the mixer as they happen. The mixer uses them to write an event log: one line per event, each with a start time and end time on the air clock. The most important kind is the transmitted frame. For every frame that goes on the air there's an entry naming the sender, the frame (PRESENCE, RTS, a numbered bulk frame and so on), the channel it went out on, where in the audio stream it starts, how long it lasts, and the part of the passband it occupies.

The mixer can also record the band itself: the sum of every station's transmission plus the band-wide noise and interference, the way a monitoring receiver on the frequency would hear it. (The per-path effects belong to each listener, not to the band, and are left out.) The event log is written into the recording as an extra section of a standard WAV file, so a spectrogram viewer that knows about it can put a labelled box around every frame and show which station sent what and where two transmissions collided.

Labels are only useful if they're right, so a tool compares every label with the audio energy in its band, both ways: a label with no signal under it, or signal with no label. A simulation's collision count is only quoted after its labels have passed this check.

33.5.2 Assertions graded from the stations' own logs

A scenario says what it expects as a list of assertions. Each one names a station, the event that station should log, an optional detail it must match, and a deadline in on-air seconds. For example: "station 1 logs that it transmitted a dNAK within 60 seconds after the previous step passed". Assertions can chain: one starts watching only when the previous one passes.

Each assertion ends in one of three states: pass; fail (the deadline ran out, or the run ended while it was still watching); or skip (it never started, because a step it depended on failed). Skips are kept apart from failures so that one broken link in a chain doesn't read as five separate problems.

Two design choices matter here. First, assertions are graded from what the stations say they did, not from energy on the channel: "some station transmitted something" is a weak test, and "the receiver sent a dNAK naming frame 3" is a strong one. Second, the report line for each assertion is generated from the assertion's own fields, so the words in the report can't drift away from what's being checked.

33.6 The layers of the test suite

The simulated air is the biggest part of mLink's testing, but not the only part. The layers run from small to large.

33.6.1 Unit tests

More than eighty standalone test programs each exercise one piece of the system in isolation: the modems and their round trips through noise, the error-correcting codes, frame layouts and integrity checks, message assembly, the reservation bookkeeping, the payload formats, the command interface, accounts and roles, the mail server's storage and authentication, and more. They run with one command, and each reports a plain pass or fail. A unit test is the right tool when the question is "does this piece compute the right answer", with no timing or other stations involved.

33.6.2 The discrimination test: the bulk floor from both sides

One unit test deserves its own mention, because it checks the claim the whole passband layout rests on (): that all five signals can share one SSB passband at once. It generates simultaneous traffic in every region (the emergency tones, all three announce channels and a bulk frame), adds them into one audio stream, adds noise, and asks each receiver path to pull out its own data.

The noise is swept across a range of levels, measured against the combined power of all five signals (each region's own SNR is several decibels lower, and the test prints both). It passes only if two things hold:

The second condition is the unusual one. A test that only checks that something works above a threshold would keep passing if a mistake in the SNR arithmetic quietly made the noise several decibels weaker than labelled. Requiring a failure just below brackets the bulk decoder's cliff (Section 9.7.2) from both sides. If either the noise scale or the decoder's real floor moves, this test goes red.

33.6.3 The receiver test: one long recording

Another test checks the receiver as a whole (). It builds a two-and-a-half-minute recording of steady noise with frames of all three modems dropped into it at stated levels: emergency frames from −15 dB up, announce frames on each of the three announce channels from −6 dB up, and four bulk frames laid end to end. It plays the recording into the real receiver in sound-card-sized blocks. With one exception, every frame has to be found by its detector and then decoded byte for byte.

The exception is the lowest announce level, because Reed-Solomon frames fade out along a slope a few decibels wide and not at a cliff (Section 9.7.1). At −6 dB, one decibel under the announce floor, about one frame in twenty is lost whatever the receiver does, so one frame there says nothing. The test sends 60 announce frames at that level, twenty on each channel, and judges them as a rate: it passes when at least 50 decode. A healthy receiver decodes about 95 in 100 there, and one decibel lower about two in three, 40 of 60, which fails.

33.6.4 Finding and reading, measured separately

A frame near its floor can be lost in two places: the detector never found it, or the detector found it and the decoder could not read it. Two measuring programs tell these apart, one for an emergency frame and one for an announce frame. Each puts a single frame into noise at an exact level, plays it into the real receiver, and repeats that many times with fresh noise. For every trial it records whether the detector found the frame, how far from the true start it placed it, whether the frame decoded from there, and whether it decoded when handed over at its true position. The difference between the last two is the loss that belongs to finding. The emergency program can also be run on noise alone, to count false alarms.

These are instruments, not pass-or-fail tests: they are run by hand when a floor is in question, and the statements about which stage gives out first (Section 13.4.1) rest on them.

33.6.5 Integration scenarios

The largest layer is more than two hundred scenario scripts. Each starts a simulated band and a handful of stations (sometimes a mail server, a cluster or the client too), sets up a situation, and grades what happens. Each one checks one behaviour: a bulk transfer recovering from one lost frame, a relay carrying a message across a one-way path, two stations calling each other at the same moment, mail handed to a gateway, and so on.

Three rules keep the results trustworthy:

33.6.6 Expected reds and known reds

Sometimes a scenario is written before the fix: it shows a misbehaviour on purpose, so the fix can later be shown to cure it. Such a scenario is marked expected red, and the suite runner counts it as behaving correctly while it fails. If it ever passes unannounced, the runner flags that loudly: either the fix landed and the mark should come off, or the scenario has stopped testing what it claims to.

The suite also keeps a short, dated list of scenarios that are known to be failing and owed a diagnosis. That list never turns a red into a green. It only lets the runner say "these failures are new" separately from "these are the known ones", with a different exit code for each.

33.7 Operator simulations

Scenario tests check one behaviour at a time. Operator simulations ask the bigger question: what happens when a whole net uses this for hours? Each one scripts an event from start to finish (who sends what to whom, and when), makes propagation change as the event goes on, runs every station through it, and then grades the results against the stations' own databases. Each also has a variant in which some of the stations form a named net (Chapter 22) while others share the frequency without belonging to it.

33.7.1 The marathon: a 12-station 40 m event

This simulation is a marathon check-in net on 40 metres by NVIS (near-vertical incidence skywave). It has twelve stations: net control (which is also the mail gateway to a mail server), a start station, eight aid stations along the course, a medical rover sending position reports, and the finish. 250 runners in three waves pass the aid stations at randomly varied paces, and the aid stations report them. Over more than three simulated hours the operators send mail and short texts, run a roll call and welfare checks, handle medical incidents, register with the mail server over the air, collect replies from headquarters, and work one distress call from the SOS to the stand-down. Propagation follows a day on 40 m: strong at dawn, weaker through midday absorption with static crashes and slow fades on some paths, then recovering into the evening.

33.7.2 Search and rescue: a lost vessel on 20 m

This one is harder on purpose. About fourteen stations are spread across a map of an ocean search. Each path is worked out from the distance between stations using a 20 m one-hop model, including a skip zone that moves through the day, so many paths are one-way and many pairs of stations are hidden from each other. A vessel in distress sends an SOS and its power fades afterwards. Search units move. The search aircraft works on a VHF FM channel of its own, reachable only through an on-scene vessel whose HF and VHF stations are clustered together (Section 31.6). Getting traffic through here means relays (Chapter 19) and clustered stations doing real work.

33.7.3 Scale: a hundred stations and more

The scale runs put 100 stations on one simulated passband for two hours of air, to see whether finding each other () and background announce traffic hold up in a crowd; a few AI agents acting as operators sent traffic through it partway through. A further run started 256 stations across two computers, as a check of the harness's own capacity as much as of mLink.

33.7.4 What they measured

The table gives the results on record, with the evidence behind each. "Two seeds" means two runs of the same event script with different random choices; each run is a single sample.

Table 33.1. Operator simulation results on record (measured in simulation).
SimulationMeasuredEvidence
Marathon, 12 stations Mail fully delivered: 76 of 76 and 77 of 77. Short texts: 55 of 55 on both. SOS acknowledged and the distress beacon stood down on both. Frames that overlapped another station's transmission on the air: 0.6% and 0.0%. Two seeds, one run each, early September 2026.
Marathon, 12 stations, October build Mail fully delivered: 76 of 76, and 3 of 3 replies collected through the mailserver. Short texts: 55 of 55. SOS acknowledged and stood down. Frames that overlapped another station's transmission: 0 of 2,366. No message needed more than two attempts. One seed, one run, 8 October 2026, with the beacon interval of ten minutes up to ten stations. Labels checked against the audio.
Marathon with a virtual net, 38 stations: the 12 as a net, 26 more on the frequency outside it Mail 77 of 78 (the last one still waiting at the end, not lost). Short texts 188 of 193. All 11 joins confirmed; six roll calls, the last five with nobody missing; a bulletin confirmed by all 10 members asked. The 26 outside stations' own traffic: 155 of 155 delivered. SOS acknowledged. Frames overlapped: 71 of 5,465 (1.3%). One seed, one run, 8 October 2026, same build. The same event on the build of 5 October gave the same delivery figures and 2.2% overlap. Labels checked against the audio.
Search and rescue, about 14 stations, two bands Directed mail 5 of 5, texts 37 of 37, SOS acknowledged, on both seeds. No relay offered to carry a message body that didn't match the one asked for. Two seeds, one run each, mid-September 2026. Labels checked against the audio. Later changes to station timing and mail delivery have not been graded in this simulation.
Scale, 100 stations All 100 registered, stayed up and found each other; every station's list of heard stations held 98 or 99 of the other 99. Background announce traffic used about 4-5% of each announce channel's air time. Test messages sent by the agents were delivered, except one bulk message lost when its opening frame collided. One run, August 2026, on the code of that month. Every path was a clean 40 dB, so only collisions could cause losses: no fading and no hidden stations.

The simulations also taught something about their own instrument. When the search-and-rescue event was run twice on the same code with the same event script, the share of overlapping frames came out at 4.5% one time and 9.4% the other. Roughly half to two-thirds of those overlaps were between stations that can't hear each other at all, which no amount of listening before transmitting can prevent (). So a small change in the overlap figure between two runs says nothing on its own.

33.8 Test integrity

One rule sits above all the others: a test asserts what the protocol should do. If the code doesn't do it, the test stays red.

There are comfortable ways to break it: loosen an assertion from "the sender retransmits exactly the lost frame" to "the message got there somehow", rewrite the expectation to match whatever the code happens to do, or hand over a scenario that was never run as if it passed. Each turns a red into a green, and each is worse than leaving the red alone. A red test is the suite working. A false green is the suite lying, and once one green is known to be a lie, every other green has to be checked again by hand.

So, in mLink's suite:

33.9 How to read a measured number

33.9.1 One run per side is not a comparison

Suppose a scenario fails, you change something, and it passes. It's tempting to conclude that the change did it. But many scenarios involve timing and random choices, and some fail now and then for reasons nobody has yet explained. If a scenario fails one time in three, two single runs will often disagree, and the disagreement will line up with whatever you just changed, because something has to. The danger isn't that the explanation is weak. The danger is that it's good.

The rule: run both sides of a comparison at least three times before blaming a difference on the change. If the two sets of results overlap, there's no effect to explain, only an intermittent failure to understand. The overlap figures above show why: the same code and the same event script gave 4.5% one time and 9.4% the next.

33.9.2 A single run near a cliff tells you nothing

Near a decoder's floor, whether one frame decodes depends on the exact noise that happened to land on it (). One run at +3 dB that decoded proves nothing about +3 dB, and one that failed proves nothing either. Only many runs, or a test built with a known margin on each side like the discrimination test and the announce rate check, say anything about where a floor really is.

33.9.3 Randomness decides when, never whether

Stations use random delays to avoid transmitting at the same instant as each other (Section 17.7). That randomness is allowed to decide when a station transmits. It must never decide whether an exchange completes. So a scenario whose outcome changes from run to run has found something real: a rule that should always hold, and doesn't for some random choices. "It was just bad luck" describes the spread of results; it isn't a cause. The harness gives each run fresh random starting conditions so that the full range of those choices gets exercised.

33.9.4 Every verdict says how it knows

A result should say what kind of evidence it rests on. "Measured on two seeds, one run each" is different from "consistent with the logs", which is different from "a hypothesis". A comparison is only as good as its control: if the control run would have looked the same whether or not the suspected cause were real, it can't clear or convict anything. "The computer was too slow" is never an explanation, because the lockstep design rules it out. A failure that can't be explained yet is written down as undiagnosed and kept on a list that is owed an explanation. That's why the results table above gives a date and an evidence class for every number; when you read a claim about mLink's performance, look for those two things first.

33.10 What to remember

Appendices

Appendix A

Numbers at a Glance

Times are on-air time. Audio positions are counted in samples at 12,000 per second. Every signal level is on the SNR@3k scale (Section 3.4.3). "Derived" marks a figure worked out from others. In the random waits, N is the number of stations heard in the last 30 minutes, held between the bounds shown.

A.1 Audio and the passband

Table A.1. Audio rate and the layout of one channel (audio frequencies).
ItemValueSee
Audio sample rate12,000 samples per secondSection 3.2
Audio block512 samples = 42.7 msSection 13.2
Receiver's running recording524,288 samples = 43.7 sSection 13.2
Emergency regionallotted 125–175 Hz; tones 128.125–171.875 Hz; filtered to 115–185 HzSection 8.3
Announce regionallotted 200–1,500 Hz; three channels (next table)Section 8.4
Bulk regionallotted 1,500–3,000 Hz; carriers 1,617.2–2,882.8 Hz; filter passes 1,614–2,886 Hz, stops below 1,594 and above 2,906 HzSection 8.5
All signals togetherenergy 115–2,906 Hz; information from 125 to about 2,900 HzSection 8.3
Empty spectrum between signals93 Hz emergency to announce; 130 Hz between announce channels; 260 Hz announce to bulk; 94 Hz above bulkSection 8.6
Keying rampfirst and last 20 ms (240 samples)Section 8.9
VOX leader, VOX-keyed stations only1,400 Hz tone; 800 ms by default, settable 0–2,000 msSection 8.9.1, Section 4.3.6
Table A.2. The four QPSK channels (Hz). Each carries the same 270 Hz signal.
ChannelCentreSignal occupiesTransmit filterDetector listens to
Announce 0400265–535211–589250–550
Announce 1800665–935611–989650–950
Announce 21,2001,065–1,3351,011–1,3891,050–1,350
Bulk-control (Section 8.5.1)2,2502,115–2,3852,061–2,4392,115–2,385

A.2 The three modems

Table A.3. Modem parameters and frame air times.
Emergency (NB8FSK)Announce (QPSK)Bulk (OFDM)
Modulation8 tones 6.25 Hz apart, one at a timeQPSK on one carrier, roll-off 0.3528 carriers 46.875 Hz apart: 24 of QPSK data, 4 pilots
Symbol1,920 samples (160 ms)60 samples (5 ms)320 samples (26.67 ms): 256 + 64 of cyclic prefix
Symbol rate6.25 baud200 baud37.5 per second
Bits per symbol3248
Raw bit rate (derived)18.75 bit/s400 bit/s1,800 bit/s
Marker at the front of a framesweep 125 to 175 Hz, 3,840 samples (0.32 s)4 known symbols, 1,202 samples (100.2 ms)one 320-sample symbol in two identical halves
Data in one frame11 bytes11 bytes603, 907 or 1,008 bytes
Coded frame23 bytes as 62 tones23 bytes as 92 symbols9,720 bits as 203 symbols
Frame air time122,880 samples = 10.24 s7,684 samples = 640.3 ms65,280 samples = 5.44 s at every rate
Frames in a rowback to back, up to 15256 samples (21.3 ms) apart: one every 7,940 samples (661.7 ms)back to back, up to 10 per transmission
Useful rate (derived)about 8.6 bit/sabout 133 bit/sabout 890 to 1,480 bit/s
Decodes down to−15 dB in one pass, −17 dB with repeats−5 dBabout +3 dB at rate 1/2
SeeChapter 10Chapter 11Chapter 12
Table A.4. Bulk modem geometry.
ItemValueSee
FFT256 samples (21.33 ms)Section 12.2.2
Carriersbins 1 to 28, shifted up 1,570.3 Hz; centre 2,250 HzSection 12.3
Pilotscarriers 4, 11, 18 and 25: 1,758, 2,086, 2,414 and 2,742 HzSection 12.3
Cyclic prefix64 samples = 5.33 msSection 12.4
Frame1 sync symbol (14 carriers, even bins only) + 203 data symbolsSection 12.6

A.3 Error correction

Table A.5. Codes and checks.
WhereCodeSee
Emergency and announce framesReed-Solomon (23,11): 11 data + 12 parity bytes, repairs up to 6 damaged bytes; bits sent in orderSection 9.3.2
Bulk framesLDPC, one 9,720-bit codeword per frame; each bit in 3 checks; soft bits −127 to +127; at most 15 decoding roundsSection 9.4
Bulk interleavers5 × 1,944 after the encoder; 48 × 203 in the modem (24 cells unused)Section 9.6, Section 12.5
Filling a bulk framepayload, 00 00, then a fixed 200-byte pattern repeated; 4 bytes held back per frame; a full frame ends in 34 to 36 known bitsSection 9.5
Message check16 bits over sender, addressee (6 bytes each) and the message before compressionSection 16.2.1
Table A.6. The three bulk code rates and what one frame carries at each.
Code rateUsed byInformation bitsParity bitsBits per checkCapacityUsable bytesThroughput (derived)
1/2frame 04,8604,8606607 bytes603about 890 bit/s
3/4frame 17,2902,43012911 bytes907about 1,330 bit/s
5/6frame 2 onward8,1001,620181,012 bytes1,008about 1,480 bit/s

A.4 Message sizes and limits

Table A.7. How much fits. Sizes are counted after compression and wrapping.
ItemValueSee
Shortburst1 to 156 bytes in up to 16 announce frames: 6 in frame 0, 10 in each later oneSection 15.2.1
Longburst157 to 601 bytes as 2 to 4 shortbursts; to one station onlySection 15.3.1
Bulk, one frame601 bytes of message (603 less the 2-byte check)Section 15.4.4
Bulk, largest (derived)64 frames: 603 + 907 + 62 × 1,008 = 64,006 bytes, 64,004 of messageSection 15.4.4
Bulk segment10 frames per transmissionSection 16.7
Largest broadcast (derived)6,028 bytes: 10 × 603 less the checkSection 15.4.4
Rate ceiling5/6 to one station, over 601 bytes, on a link of +6 dB or better; 1/2 for one frame and every broadcast; 3/4 only in repairsSection 15.4.2, Section 16.5.2
Sizes and link levels the station decides on60, 100, 156, 601 and 6,028 bytes; −5 dB and +6 dBTable 15.2
Grid locator in a PRESENCEsix characters (about 5 by 7 km at mid latitudes); four if the operator chooses (about 170 by 110 km); always six from a station that has declared an emergencySection B.5
Longest chain with no openerPRESENCE + 15 framesSection B.3
Longest shortburst chain18 frames; 19 with a longburst manifest; 22 with two HELLOs, FOR and AREA tooSection 14.4
Largest message a station accepts for sending, and a receiver will expand1,048,576 bytes (1 MiB)Section 21.4.3
Table A.8. Air times.
ItemValueSee
Two-frame reply, such as [presence][ack]15,624 samples = 1.30 sSection 14.1.1
Shortburst with n data frames(n + 2) × 7,940 − 256 samples: 1.96 s for one, 11.89 s for sixteenSection 15.2.2
Longburst, sending only (derived)14.5 s for 157 bytes, 46.9 s for 601Section 15.3.2
Silence between the RTS and bulk frame 01,800 samples = 150 msSection 13.8.1
Start of PRESENCE to start of bulk frame 017,424 samples = 1.452 sSection 15.4
Bulk transmission of N frames1.452 s + N × 5.44 s: 6.89 s for one, 12.33 s for two, 55.85 s for tenSection 15.4
Shortburst and one bulk frame cost the same at76 bytes; the station switches at 100Section 15.5.4
Longest emergency message15 frames = 153.6 sSection 10.6
Silence around a transmission60 ms after keying, 40 ms before unkeyingSection 29.4

A.5 Reservations (defers)

Table A.9. What a decoded frame reserves at a station it is not addressed to. Full table: Table 17.1.
HeardReservesFor
Bulk RTS for N frames, or a repair's RTSthe bulk region0.15 s + N × 5.44 s + 0.5 s, counting at most 10 frames: 27.85 s for five, 55.05 s for ten
SEG-RTSthe bulk region0.15 s + that segment's frames × 5.44 s + 0.5 s
Shortburst RTSits announce channel10.43 s: fifteen more frames + 0.5 s
A PRESENCE that opens a transmissionits announce channel; on the bulk-control channel, the bulk region2.48 s; each further frame decoded moves the end to 1.82 s after it
A dNAKits channel, and the bulk region for a bulk exchange0.15 s + the repair's air time + 0.5 s
A longburst ACK with pieces still to comeits announce channel11.93 s: 1.5 s + a full shortburst
Own reply that invites the other station straight backevery channel and the bulk region, at the replying station3 s
A signal on an announce channel that did not decodethat channel, for the periodic beacon only1.5 s
Anything, for distress trafficnothingnever defers (Section 23.2)

A.6 Random waits

Table A.10. The fixed part always applies. The random part is an upper limit, not the wait itself.
BeforeFixed partRandom part, up toLongestSee
A queued message, after the channel clears0.15 s0.45 s × N (4 to 12)1.95 to 5.55 sTable 17.3
A new bulk transfer, after a heard bulk reservation ends2 s1.5 s × N (6 to 12)11 to 20 sTable 17.3
A beacon, position report, geopoll or anchor0.2 s1.5 s × N (6 to 12)9.2 to 18.2 s; a VOX-keyed station waits one full span longerTable 17.3
Asking a broadcaster to say again1 s + one of N places 2.25 s apart (4 to 8)0.45 s17.2 sSection 17.8
A relay OFFERone of 9 slots starting 2.0 s apart0.4 sstarts by 16.4 sSection 19.3.3
A relay OFFER when 5 or more stations could answerby the station's own place in line: places 1–2 at once, 3–4 after 2.0 s, the rest after 6.0 s; dropped after hearing 2 offers0.4 sstarts by 6.4 s (14.4 s for a station outside an active net)Section 19.3.4
An answer to a SEED or a geopoll0.2 s + one of 9 slots 0.75 s apart (36 for a SEED)nonestarts by 6.2 s (geopoll), 26.45 s (SEED)Section 18.4
Repeating a heard distress call5 s + one of 8 to 16 slots 1.5 s apart0.45 sabout 16 to 28 sSection 23.7.1
A courier's first try24 s + one of 8 to 16 turns 6 s apart3 s69 to 117 sSection 24.6.1
Answering an internet request0.3 s1.2 s × N (6 to 8)7.5 to 9.9 sSection 27.5

A.7 Replies, retries and relay

Table A.11. Reply, retry and relay timings.
ItemValueSee
Reply to a bulk transmission of N frameskeyed 150 ms + N × 5.44 s + 0.5 s + 150 ms after the RTSSection 16.4.1
Sender's reply window5 s (0.5 + 0.15 + 1.302 + 3.048)Section 16.4.5
Follower tied to a PRESENCEwithin 1,323 ms of the chain's last frameSection 14.5.1
Shortburst retriesup to 3Section 16.6.1
After a "did you get that?" probe8 to 9.5 s of listening, then relaySection 16.6.2
A partly received transfer is kept10 min, restarted by each repairSection 16.5.1
Checkpoint after a segmentthe sender waits 8 s for it, probes once, waits 8 s more; the addressee waits 30 s for the next segmentSection 16.7.2
Say-again round of a broadcastrequests collected for 22 s, and 60 s more if none came; a listener asks again after 35 sSection 17.8
Spacing of large sends after an empty relay search15 s, doubling to 10 minSection 17.7.2
First-frame ruleverdict 7.73 s after the RTS decodesSection 17.6
Listening before keyingbusy at 6 dB over the quiet floor, over one audio block; a reading may be 0.2 s old at release, 0.1 s at key-upSection 17.5, Section 17.5.1
Relay search24 s from the REQUEST; the choice is made 2 s after the first valid OFFERSection 19.2, Section 19.4
A volunteer holds its own traffic5.2 s (2 s + 2 × 1.6 s)Section 19.4
Who may volunteerdestination decoded within 30 min, or 2.5 beacon intervals if longer; a volunteer whose hearing is older than 120 s stands 4 places further back; link of −5 dB or betterSection 19.3.1
Waiting for a RESULT60 s, restarted by signs of progressSection 19.6.1
Retry gaps of a deferred message1, 2, 4, 8, 16, then 32 minSection 20.6.1

A.8 Signal levels

Table A.12. Floors and the levels stations act on.
ItemValueKindSee
Emergency message−17 dB with repeats; about −15 dB in one passmeasuredSection 10.8
Announce frames−5 dBmeasuredSection 11.9
Bulk at rate 1/2about +3 dB; none decode 2 dB lowermeasuredSection 9.7.2
Bulk trusted; a HELLO calls a link strongfrom +6 dBsettingSection 9.7.3, Section 18.7
Link estimate under −5 dBonly messages of up to 601 bytes are still tried directly; a station does not volunteer to relaysettingTable 15.2, Section 19.3.1
An FT8 or JS8 report of the same signalabout 0.8 dB higherderivedSection 3.4.3
Link estimatenewest reading weighs 40 %; usable for 5 min; readings while the bulk region is reserved, and for 8 s after, are left outsettingSection 18.6.1
Detector threshold5 × the spread of recent noise scores, and one quarter of the loudness of all the audiosettingSection 13.4, Section 13.5
Finding bulk frame 0within 1,400 samples (116.7 ms) of the predicted start, match of 0.70 or better; given up 16,384 samples after it should have endedsettingSection 13.8.2
Finding later bulk frameswithin 64 samples (5.33 ms) of the expected startsettingSection 13.8.3
Frequency offsetmeasured to 47 Hz either way; RIT corrected past 10 Hz, at most once per 2 ssettingSection 13.10
Table A.13. Measured share of single frames that get through in steady noise, through the whole receive path.
LevelAnnounce frame decodedLevelEmergency frame foundEmergency frame found and decoded
−5 dB99.7 %−15 dB97 %96 %
−6 dB95 %−16 dB86 %85 %
−7 dB67 %−17 dB69 %67 %
−8 dB25 %−18 dB51 %35 %
−9 dB4 %
SeeSection 9.7.1Section 13.4.1Section 10.8

A.9 Beacons and finding each other

Table A.14. Start-up, beacons and how long "heard" lasts.
ItemValueSee
Listening after start-up10 min, then a random 0 to 16 s before the first SEEDSection 18.2.1
SEED while nobody is heardevery 90 s ±20 %; from 20 min after start-up, every 10 min ±20 %Section 18.2.2
Beacon interval10 min with up to 10 stations on the net; 10 min more per further 10 (20 min for 11–20, up to 60 min above 50), ±20 %; 20 min at most after 10 min without trafficSection 18.3.2
HELLO framesup to 2 on a new shortburst or bulk transfer, 3 on a beacon, position beacon or anchor chain; one such transmission per 60 sSection 18.7.1
"Heard recently"2 min to retry a station directly, or to be counted present by net control holding its mail; 5 min for a link estimate; 30 min to count in a random wait; "on the net" (next row) to offer to relay to itTable 18.1
On the net30 min, or 2.5 beacon intervals if longerTable 18.1
Records kepta heard station for 3 beacon intervals, never less than 1 h (1 h with up to 20 stations, 3 h at most); a links-map row for 2 hSection 18.6, Section 18.8
A station with a mailserver connection looks in its own mailboxevery 5 min, and 15 s before each of its own beaconsChapter 24
Gateway flag shownwhile the last mail server contact is under 10 min oldSection 14.2.1
Position beaconoff, or every 30 s to 1 day, ±20 %Section 28.2.2

A.10 Lifetimes and time

Table A.15. Message lifetimes and the time base.
ItemValueSee
Message lifetime15 min, or the contact horizon if longerSection 20.4
Contact horizon1.5 beacon intervals: 15 to 90 minSection 20.4.1
Mailnever expiresSection 20.6
On-air time epoch2020-04-20 00:00:00 UTCSection 21.5

A.11 Virtual nets

Table A.16. Named-net limits and timings.
ItemValueSee
Cycle (anchor period)300 s; settable 150 to 600 s in steps of 30 sSection 22.3.2
Membersup to 127; up to 3 ranked alternatesSection 22.4, Section 22.9.4
Roll-call slot1.2 s; the first starts 0.4 s after the ROLL decodes; the TALLY follows the last by 0.5 sSection 22.6.1, Section 22.6.3
Roll call of twelve stations, nobody missingabout 21 sSection 22.6.5
Net control taken as goneafter 3.5 cycles (17.5 min at 300 s); 5 s after a closing anchorSection 22.9.1, Section 22.9.9
Claiming a vacant net3 s per place in the order, plus up to 1.875 sSection 22.9.2
Bulletin; standing orders200 characters; subject 60 and text 1,000 charactersSection 22.7.2, Section 22.7.3
Asking for the standing ordersafter 60 s, in one of 4 to 8 slots 1.875 s apartSection 22.7.3
A silent member is taken off the rosterafter 2 hSection 22.11
Safety Critical neta member speaks for up to 4 stations; net control says again texts of up to 400 bytesSection 22.9.8
Net control keeps a member's mailwhen the member has not been heard for 120 s; answers 18.5 s after decoding the REQUEST, plus 0, 0.5 or 1 s; says it again no sooner than 15 s after its last TAKENSection 22.8.1
"Mail held" listup to 10 entries, 148 bytes; named by an 8-bit tag in every ROLL frame (0 = nothing held), which leaves 7 spare bits; fetched like the standing ordersSection 22.8.2
Held mail deliveredafter the member's check-in, or for 5 min after net control hears the member transmit once the hold has begunSection 22.8.3
Held mail left at the mailserverwhen a gateway has been heard in the last 120 s and the member has notSection 22.8.4

A.12 Mail

Table A.17. Mail limits, gateway timings and the mail login.
ItemValueSee
Largest mail, wrapped64,004 bytes to one station; 6,028 as a broadcastSection 24.2.3
Recipients and fields16 To and 16 Cc callsigns; 8 outside addresses; subject 255 bytes; body 65,535; 16 attachmentsSection 24.2
Bundle, before compression48,000 bytes to one station; 5,600 as a broadcastSection 24.11
A gateway deposits instead of transmittingwhen the recipient has not been heard for 120 sSection 24.4.2
A gateway answers a relay REQUEST for mail it holdsafter 3 to 4 sSection 24.5.5
TAKEN statuses0 deposited, 1 already held, 2 delivered direct, 3 held by net controlTable B.23
REQUEST flag bitsbit 0 anyone who hears the destination may offer; bit 1 a station with the mailserver may ask for a copy; bit 2 the message is mail in the clearTable B.19
Mailbox control "delivered"operation 0x08, 15 bytes: author 6, message id 2, recipient 6Section 24.9
Payload kind of the "mail held" list0x0DSection 21.3
Unasked "you have mail"mailbox looked at once per station per 15 min; the same news repeated after 15, then 30, then 60 min (stays at 60) while unanswered; back to 15 when the station asks or the waiting mail changesSection 24.8.1
GET with no deliverysent again after 12 s, 3 times in allSection 24.8.2
Mailbox queryone per minute; 30 s for an answerSection 24.8.3
Pickup broadcast with no TAKENdeferred after 10 minSection 24.7
Signed request to the mailserver8-byte keyed check; clock within 10 minSection 25.3.4
Sender tag2 bytes; 5 bad tags for one author within 10 min shut that author's deposits out until the 10 min endSection 25.5.2

A.13 Emergency

Table A.18. Distress calls. Their signal levels are in Section A.8.
ItemValueSee
Emergency message1 to 15 frames of 11 bytes (2 of header, 9 of content): frame 0 (72 bits) and up to 14 text framesSection 23.3
Text13 characters per frame from a set of 45; 182 in all; the identity kept whole up to 181Section 23.3.3
Incident age steps15 min, 1 h, 6 hSection 23.3.1
Next pass of an SOS75 s + a random 0 to 15 s after the last pass was keyed, and never sooner than 15 s + a random 0 to 15 s after the station last stopped transmittingSection 23.4.1
Acknowledgment in the emergency regionone frame 0, keyed 0.4 s after a heard pass ends, at most once per 60 sSection 23.6.2
Acknowledgment in the announce regionsent once, with up to 118 bytes of contact textSection 23.6.1
Rebroadcast of a heard callPRESENCE + up to 15 frames, up to 156 characters of text; not again within 5 minSection 23.7, Section 23.7.1

A.14 Clusters

Table A.19. Cluster limits and timings.
ItemValueSee
Membersup to 16Section 31.3
Joiningthe newcomer asks every 2 s and gives up after 10 min; a pending request is kept 15 minSection 31.3
Keepaliveevery 10 s; live when heard within 30 s; gone after 180 sSection 31.4
Relay through another member's radiomessage of 40,960 bytes or less; the OFFER claims 3 dB less; outcome awaited 60 sSection 31.6

A.15 Sessions and station software

Table A.20. Ports, sessions and limits of the station software.
ItemValueSee
Default portsclients 8488; web client 8489; mailserver 8380Table 29.2, Section 25.1
Sessions and accounts32 sessions at once, closed after 30 min without a command; up to 64 accountsSection 30.6, Section 7.2
Sign-in5 attempts per 10 s from one address; passwords stored through 100,000 rounds of PBKDF2Section 7.3.1
Appendix B

On-Air Frame Reference

B.1 Conventions

B.2 Every frame, by type byte

"Place" is the frame's place in a transmission (Section 14.4): first opens a chain; alone is a one-frame transmission with no PRESENCE; a follower rides behind a PRESENCE and leaves the chain open; an opener closes it.

Table B.1. Every assigned type byte
TypeFramePlaceWhat it is for
0x00PRESENCE, automaticfirstHeads every ordinary transmission: who and where. Unattended station.
0x01PRESENCE, operatorfirstThe same, with an operator present.
0x02GEOPOLLaloneAsks every station inside an area to answer.
0x03GEOPOLL-RESPONSEfirstA station inside a polled area answers. One frame.
0x04SEEDfirstA station starting up asks any hearer to answer. One frame.
0x05SEED-ACKfirstA station that heard a SEED answers. One frame.
0x10REQUESTopenerThe originator of an undelivered message asks who can relay it.
0x11OFFERopenerA volunteer answers a REQUEST: how well it hears the destination, and which copy it holds.
0x12SELECTopenerThe originator names the relay it chose.
0x13FORfollowerA relay, ahead of its delivery, names the original sender.
0x14RESULTopenerA relay tells the originator: delivered or failed.
0x15(reserved)Not sent.
0x16EMERGfollowerA station that decoded a distress call repeats it on an announce channel, in up to fifteen frames.
0x17EMERG-ACKfollowerAn Authoritative Station acknowledges an incident it passed to emergency services.
0x18MAIL-TAKENopenerA station that took a mail into custody says so.
0x19MAIL-QRYopenerA station asks any gateway whether mail is waiting for it.
0x1AMAIL-AVAILopenerA gateway says how much unread mail a station has, asked or unasked.
0x1BMAIL-GETopenerThe recipient tells one gateway to deliver its mail.
0x1CHANDOFFfollowerThe originator, ahead of a transfer to a relay that holds no copy: carry this to that station.
0x20ABORTopenerA sender abandons a transfer part way.
0x21RTSopenerAnnounces a bulk transfer and reserves the bulk region.
0x22ACKopenerThe addressee: the message arrived complete and checked.
0x23dNAKopenerThe addressee: these frames are missing.
0x24LONGBURSTfollowerThe manifest of a longburst, in its first transmission only.
0x25SB-RTSopenerAnnounces a shortburst; the data frames follow at once.
0x26RETX-RTSopenerAnnounces a bulk repair holding only the missing bytes.
0x27SB-RETX-RTSopenerThe same for a shortburst repair.
0x28INET-REQopenerAsks a neighbour with internet access for a piece of internet data.
0x29SEG-RTSopenerOpens each transmission after the first of a long bulk transfer.
0x2ACKPTopenerThe addressee, between those transmissions: all good so far, or what is missing.
0x2BQSLopenerA sender whose expected reply did not come asks for it again, once.
0x30–0x3FSHORTBURST 0 to 15after SB-RTSThe message itself.
0x40APRS positionfollowerA precise position report.
0x50AREAfollowerThe circle a transfer to 0CQQTH is aimed at.
0x60HELLO, strongfollower"I recently heard this station, well enough for bulk."
0x61HELLO, weakfollowerThe same, well enough for announce frames only.
0x70ANCHORfollowerNet control, once a cycle: the net's name, period and roster edition.
0x71ANCHOR, closingfollowerNet control steps down or closes the net.
0x72ROSTERfollowerOne roster entry, in an anchor chain.
0x73JOINaloneA station asks to be listed in a net.
0x74JOIN THROUGHfollowerA member passes a JOIN on to net control; also a former net control handing over its roster.
0x75ROLLfollowerNet control calls a range of member numbers to check in.
0x76CHECKINaloneA member answers a roll call; also a goodbye, or "list me".
0x77–0x7ATALLY: missing list, heard list, low map, high mapfollowerNet control, after a roll call's slots: who did not answer.
0x7BROSTER REQUESTaloneA station asks a member for the roster, the standing orders, or both.
0x7CINSTRUCTaloneThe net's owner tells the station running its net what to do.
0x80TIMEfollowerThe time, from a station with a real time source (Chapter 32).

A PRESENCE with an unassigned subtype (0x06 to 0x0F) is read as 0x00. Any other unassigned type byte is ignored.

B.3 Common chains

Followers go out in a fixed order: PRESENCE, HELLOs, FOR or HANDOFF, LONGBURST, AREA, then the opener.

Table B.2. Frame chains
ChainWhat it is
[presence]A beacon; also a SEED, SEED-ACK or GEOPOLL-RESPONSE.
[presence][hello][hello][hello]A periodic beacon with up to three HELLOs.
[geopoll]An area poll.
[presence][sb-rts][sb 0]...[sb n]A shortburst, up to sixteen data frames.
[presence][longburst][sb-rts][sb 0]...The first transmission of a longburst.
[presence][rts][bulk 0]...[bulk n]A bulk transfer, or its first ten frames. The bulk frames start 150 ms after the RTS ends.
[presence][seg-rts][bulk 10]...The next ten frames of a long bulk transfer.
[presence][hello][hello][rts]...A new bulk transfer or shortburst with up to two HELLOs.
[presence][area][rts]...A transfer to 0CQQTH; also with an SB-RTS.
[presence][ack], [presence][dnak], [presence][ckpt]The addressee's replies.
[presence][retx-rts][bulk 0]..., [presence][sb-retx-rts][sb 0]...A repair.
[presence][qsl], [presence][abort]The sender asks for a missing reply; the sender gives up.
[presence][request], [presence][offer], [presence][select], [presence][result]The relay handshake.
[presence][for][rts][bulk 0]...A relay delivering; also with an SB-RTS.
[presence][handoff][rts][bulk 0]...The originator handing a relay the message to carry.
[presence][mail-qry], [presence][mail-avail], [presence][mail-get], [presence][mail-taken]Mail pickup and custody.
[presence][inet-req]A request for internet data.
[presence][aprs-pos][hello]...A position report; the automatic position beacon adds up to three HELLOs.
[presence][emerg 0]...[emerg n], [presence][emerg-ack 0]...A repeated distress call; its acknowledgement.
[presence][anchor][roster]...[hello]...Net control's cycle: the anchor, up to three roster entries, up to three HELLOs.
[presence][roster][anchor]Net control stepping down: its own entry, then the closing anchor.
[presence][roll], [checkin], [presence][tally]A roll call: the call, each answer, the tally (two TALLY frames when both maps are needed).
[join], [presence][join-through]..., [roster-request], [instruct]Other named-net business.

A chain with no opener (a repeated distress call, a net chain, a beacon) holds at most fifteen frames after its PRESENCE.

B.4 Callsign packing

A callsign is upper-cased, padded with spaces to nine characters, and read as a nine-digit base-39 number: space is 0, 0 to 9 are 1 to 10, A to Z are 11 to 36, / is 37 and - is 38. The number is stored in six bytes, big-endian. A received value of 399 (208,728,361,158,759) or more is rejected. The rules for a valid operator callsign are in Section 14.6; a reserved addressee is any name whose first character is 0.

Table B.3. Packed callsign examples
TextSix bytes
W1AWA0 EB 4B E7 01 B1
K6MQI67 2B 6D C1 30 AD
VE3XYZ/P9D A6 DC 5C BA B5
0CQCQCQ (everyone)06 93 E3 F7 AB C3
0CQQTH (area)06 94 2F AF 70 70
0MARITIME (the net MARITIME)07 C6 9B E8 B3 69

B.5 Grid field

Four bytes read as one 32-bit number, most significant byte first. The top seven bits are flags about the station. The low 25 bits are one location number, and the range it falls in says how precise the location is.

Table B.4. Grid field bits
BitsMeaning
31gateway flag: 1 = the station can reach its mail server (Section 14.2.1)
301 = the station keys by VOX and sends a leader tone before each transmission (Chapter 32)
291 = the station's audio path is declared able to carry bulk frames on FM (Chapter 32)
28–25spare: sent as 0, ignored on receive
24–0location number
Table B.5. Location number ranges
Location numberMeaning
0 to 18,662,399six-character locator. The six characters are digits of one number in mixed radix 18, 18, 10, 10, 24, 24, first character most significant.
18,662,400 to 18,694,799four-character locator only (radix 18, 18, 10, 10), counted from 18,662,400
18,694,800 to 18,695,123two-character field only (radix 18, 18), counted from 18,694,800
33,554,431 (all ones)no location
any other valueread as no location; the frame still counts for its callsign and flags

The flags do not depend on the location: a station with no locator set still sends them.

B.6 Compact area

GEOPOLL and AREA carry an area in bytes 1 to 10. Byte 1 says which form follows.

Table B.6. Compact area (frame bytes 1 to 10)
ByteForm 0: callsignForm 1: circle by positionForm 2: circle by grid
112
2–4callsign (bytes 2–7)latitude, 24 bits big-endian: round((lat + 90) / 180 × 16,777,215)locator, up to 6 ASCII characters, zero-padded (bytes 2–7)
5–7longitude, 24 bits big-endian: round((lon + 180) / 360 × 16,777,215)
8–9radius in kmradius in km

B.7 PRESENCE family

Table B.7. PRESENCE, GEOPOLL-RESPONSE, SEED and SEED-ACK (0x00, 0x01, 0x03, 0x04, 0x05)
ByteFieldContents
1–6callsignthe transmitting station
7–10gridSection B.5

GEOPOLL (0x02): bytes 1 to 10 are a compact area (Section B.6).

B.8 BULK family

Table B.8. RTS (0x21) and RETX-RTS (0x26)
ByteFieldContents
1frame countbulk frames in the whole transfer (RETX-RTS: in the repair), 1 to 64
2top ratelow 4 bits: 0 = 1/2, 1 = 3/4, 2 = 5/6
3–8addresseecallsign or reserved addressee
9–10message idsame value as the container's first two bytes; a RETX-RTS repeats the original message's id
Table B.9. SB-RTS (0x25) and SB-RETX-RTS (0x27)
ByteFieldContents
1–2message idsame value as the shortburst's frame 0 (SB-RETX-RTS: the id of the gathered repair bytes)
3–8addresseecallsign or reserved addressee

Note the order: the SB-RTS carries the message id first.

Table B.10. SEG-RTS (0x29)
ByteFieldContents
1first frameindex, in the whole transfer, of the first bulk frame in this transmission
2frame countbulk frames in this transmission
3–8addresseecallsign
9–10message idof the whole transfer
Table B.11. LONGBURST manifest (0x24)
ByteFieldContents
1–2total lengthbytes in the whole message
3–4whole-message idmessage id of the whole message
5piece countshortburst transmissions in the series, at most 4

Piece i of a longburst is bytes 156·i onwards of the message; the pieces carry no index.

Table B.12. ACK (0x22)
ByteFieldContents
1–2message idecho of the id in the opener being answered
3pieces remainingfor a longburst piece: pieces still to come; otherwise 0
Table B.13. dNAK (0x23)
ByteFieldContents
1–8missing map64 bits; bit set = frame missing
9roundbursts of this exchange the replier has seen (1 = the original only)
10contextbit 0: 1 = bulk exchange, 0 = shortburst

B.8.1 Missing-frame map bit order

The dNAK and CKPT maps are one 64-bit number, least significant byte first; bit i stands for frame i. Map bytes 0A 00 00 00 00 00 00 00 report frames 1 and 3 missing. A dNAK's map refers to the most recent burst of the exchange, which after a repair is the repair burst.

Table B.14. CKPT (0x2A)
ByteFieldContents
1all good1 = nothing missing so far
2–9missing map64 bits, indexed by frame of the whole transfer (used when byte 1 is 0)
10frontierhow many frames of the transfer the replier knows have been announced, capped at 255
Table B.15. QSL (0x2B)
ByteFieldContents
1–2message idthe exchange being asked about
3–8addresseethe station being asked
9kind0 = waiting for a checkpoint, 1 = waiting for the final ACK or dNAK
Table B.16. ABORT (0x20)
ByteFieldContents
1–2message idthe transfer being abandoned
3reason0 = operator cancelled, 1 = pre-empted by higher-priority traffic
Table B.17. INET-REQ (0x28)
ByteFieldContents
1data kind1 = weather at a position
2sessionchosen by the requester; the answer echoes it
3–4freshness hintseconds, big-endian: "I would prefer data newer than this"
5–7latitudesigned 24-bit, big-endian, units of 90/8,388,607 degree
8–10longitudesigned 24-bit, big-endian, units of 180/8,388,607 degree

Bytes 5 to 10 depend on the data kind; these are the ones for weather.

B.9 SHORTBURST family

Frame n has type byte 0x30 + n. The number of frames follows from the length in frame 0.

Table B.18. SHORTBURST frame 0 (0x30)
ByteFieldContents
1–2lengthmessage length in bytes, 1 to 156
3–4message idsame value as the SB-RTS
5–10datamessage bytes 0 to 5

Frame n, for n = 1 to 15: bytes 1 to 10 are message bytes 6 + 10(n − 1) onwards.

After an SB-RETX-RTS, frame 0's length and id describe the gathered repair bytes, not the original message.

B.10 RELAY family

Table B.19. REQUEST (0x10)
ByteFieldContents
1–6destinationcallsign
7–8message idthe message to be relayed
9flagsbit 0: nobody holds a copy; a station that only hears the destination may offer. bit 1: this is clear mail and an earlier REQUEST found nobody who can reach the destination; a station connected to the mailserver may ask for a copy. bit 2: the message is mail sent in the clear (not sealed); net control of a named net may ask for a copy to keep for a member who is off the air (Section 22.8)
Table B.20. OFFER (0x11)
ByteFieldContents
1–2message idthe message offered for
3SNR to destinationsigned dB, the offerer's last measurement
4flagsbit 0: the destination was showing the gateway flag; bit 1: "hand me the message" (the offerer holds no copy)
5–6lengthlength of the held copy, saturating at 65,535; 0 if bit 1 is set
7–10fingerprint32-bit FNV-1a hash of the held copy; 0 if bit 1 is set
Table B.21. SELECT (0x12), FOR (0x13) and HANDOFF (0x1C)
ByteFieldContents
1–6callsignSELECT: the chosen relay. FOR: the original sender. HANDOFF: the final destination.
7–8message idthe message's original id
Table B.22. RESULT (0x14)
ByteFieldContents
1–2message idthe relayed message
3status0 = delivered, 1 = failed
Table B.23. MAIL-TAKEN (0x18)
ByteFieldContents
1–6original sendercallsign
7–8message idthe mail taken into custody
9status0 = deposited at the mailserver, 1 = the mailserver already held it, 2 = handed directly to the final recipient, 3 = held by net control for a member who is off the air (Section 22.8)
Table B.24. MAIL-QRY (0x19)
ByteFieldContents
1–4sinceseconds since the mLink epoch; 0 = all mail
5flagsbit 0: also send a list of the mail
Table B.25. MAIL-AVAIL (0x1A)
ByteFieldContents
1–6mailboxcallsign whose mail this reports
7countunread mails, capped at 255; 0 = no mail
8–9total sizeunread bytes in units of 256 bytes
10flagsbit 0: this answers a MAIL-QRY; bit 1: a mail list follows
Table B.26. MAIL-GET (0x1B)
ByteFieldContents
1–6gatewaycallsign of the chosen gateway
7flagsbit 0: deliver everything unread; bit 1: only mails no larger than the size cap
8–9size capper-mail limit in units of 256 bytes (used with bit 1)

B.10.1 EMERG (0x16) and EMERG-ACK (0x17)

Each carries a content stream, eight bytes per frame, in 1 to 15 frames.

Table B.27. EMERG and EMERG-ACK frame
ByteFieldContents
1incident numberthe original caller's incident number
2positionhigh 4 bits: this frame's index (0 to 14); low 4 bits: frame count (1 to 15)
3–10content8 bytes of the content stream, zero-padded on the last frame
Table B.28. EMERG content stream (at most 120 bytes)
ByteContents
00
1–2incident check value, carried unchanged from the first decode
3–11the caller's 9-byte alert, as in emergency frame 0
12 onwardsidentity and detail, packed as in the emergency text frames: up to twelve 9-byte groups of 13 characters (156 characters); the detail is shortened to fit
Table B.29. EMERG-ACK content stream (at most 120 bytes)
ByteContents
0–1incident check value of the incident being acknowledged
2 onwardscontact text, plain bytes (not packed), up to 118

The incident check value is a CRC-16 (same form as the message id) over the caller's 9-byte alert with its incident-age field set to 0, then the identity text as decoded, a zero byte, and the detail text as decoded.

B.11 HELLO family

Table B.30. HELLO (0x60 strong, 0x61 weak)
ByteFieldContents
1–6subjectcallsign of the station heard
7ageminutes since the sender last heard the subject, capped at 255
8SNRsigned dB, the sender's link estimate for the subject (its last reading when it has no estimate)
9flagsbit 0: the subject was showing the gateway flag. bit 1: the subject is heard by another radio of the sender's cluster, not on this frequency

A HELLO never causes a transmission. Up to two ride on a new shortburst or bulk transfer, up to three on a periodic beacon, an automatic position beacon or net control's anchor chain, on at most one transmission a minute (Section 18.7.1).

B.12 APRS family

Table B.31. APRS position (0x40)
ByteFieldContents
1–3latitudesigned 24-bit, big-endian, units of 90/8,388,607 degree (about 1.2 m)
4–6longitudesigned 24-bit, big-endian, units of 180/8,388,607 degree (about 2.4 m at the equator)
7coursedegrees ÷ 2, rounded; valid when flag bit 0 is set
8speedkm/h, 0 to 254; valid when flag bit 0 is set
9symbolone printable ASCII character for the map; * by default
10flagsbit 0: the station is moving

B.13 GEO family

AREA (0x50): bytes 1 to 10 are a compact area (Section B.6).

B.14 ANCHOR family (virtual nets)

Bytes 1 to 10 of every frame in this family are one 80-bit field, most significant bit first: bit 0 is the top bit of byte 1, bit 79 the bottom bit of byte 10. A callsign is the usual six bytes in 48 consecutive bits; a member number is seven bits, 1 to 127, with 0 for "none". The anchor carries the net's full name; ROLL, JOIN and JOIN THROUGH carry a 32-bit key of it; the rest carry a 5-bit tag (Section 22.2.2).

B.14.1 Net name, key and tag

A net name is 1 to 8 characters from A–Z and 0–9. A–Z have the values 1 to 26 and 0–9 the values 27 to 36. The packed name is the base-37 number formed from those values, first character most significant, with no padding; it fits in 42 bits, and 0 means "no name". The names CQCQCQ and CQQTH are refused.

The key is the low 32 bits of the packed name, XOR (the bits above the low 32, multiplied by 2,654,435,761, modulo 232). For names of six characters or fewer the key is the packed name itself. The tag is the top five bits of (key × 2,654,435,761 modulo 232).

Table B.32. Net name examples
NamePackedKeyTag
TETON0x2403D520x02403D5222
MARITIME0x1203B5825300xC530C21030

B.14.2 Anchor (0x70 cycle, 0x71 closing)

Table B.33. Anchor (0x70, 0x71)
BitsFieldContents
0–3termcounts net controls round a circle of 16: 1 to 7 steps ahead is newer; 8 apart is a tie
4–7periodcycle period: 150 s + 30 s × this value
8–14live countstations net control counts as live, itself included; 127 at most (Section 22.10.1)
15–56net namepacked name; 0 = no name
57–60edition / flags0x70: roster edition, 1 to 15. 0x71: lowest bit set = the net is closed; clear = net control steps down and the net goes on
61actingnet control is a stand-in for the net's owner
62–68alt0x70: the owner's first alternate. 0x71: the member the job is handed to. 0 = none
69–75tophighest member number on the roster
76delegated0x70, with acting: the owner handed this station the job and stays owner. 0x71: alt is handed the job that way
77repeatednet control's anchor said again by a member; alt then holds net control's own member number
78safety criticalset = a Safety Critical net, clear = a Casual one

Bits 61 and 76 to 78 mean nothing on an anchor with no name.

Table B.34. ROSTER (0x72)
BitsFieldContents
0–3editionroster edition this entry belongs to
4–8net tagtag of the net's name
9–56callsignthe member
57–63numbermember number, 1 to 127
64–69flagssum of: 1 = heard through another member; 2 = not heard at the last roll call; 4 = left the net; 8 × the owner's alternate rank (1 to 3); 32 = the net's owner
70–77standing ordersnames the current standing orders: the CRC-16 of that message, high byte XOR low byte, 255 in place of 0; 0 = none (Section 22.7.3)
Table B.35. JOIN (0x73) and JOIN THROUGH (0x74)
BitsFieldContents
0–47callsignthe joiner, in both frames
48–79net keykey of the net's name
Table B.36. ROLL (0x75)
BitsFieldContents
0–31net keykey of the net's name
32–36net tagtag of the net's name
37–38roll calllow two bits of net control's count of roll calls
39–45firstfirst member number called
46–52lastlast member number called; every number between has a slot
53–56editionroster edition
57–64bulletin tag0 = ordinary roll call; otherwise a receipt roll for the bulletin whose message id, folded the same way as the standing orders, is this value
65–72held tagnames net control's current "mail held" list: the CRC-16 of the list, folded the same way as the standing orders; 0 = net control holds no mail for any member (Section 22.8)
73–79sparesent as 0, ignored on receive

A roll-call slot is 1.2 s. The length is a constant and is carried on no frame.

Table B.37. CHECKIN (0x76)
BitsFieldContents
0–47callsignthe sender
48–52net tagtag of the net's name
53–54roll callthe roll call answered
55–61numberthe sender's member number; 0 = it has none ("list me")
62–66remainingslots that come after this one: 0 to 30 exactly, 31 = 31 or more
67–72statussum of: 1 = operator present; 2 = has traffic; 4 = needs help; 8 = leaving; 16 = has the bulletin; 32 = out of turn (not in the sender's own slot)
73–79heardin its own slot: the last member the sender heard check in before it; out of turn: the missing member it vouches for; 0 = none
Table B.38. TALLY (0x77 missing list, 0x78 heard list, 0x79 low map, 0x7A high map)
BitsFieldContents
0–4net tagtag of the net's name
5–6roll callthe roll call tallied
7finalset = no further slots follow; the roll call is over
8moreset = one more tally frame follows in the same transmission
9–15tailhow many slots follow the tally, in units of two slots
16–79payloadlists: up to nine member numbers, seven bits each; a 0 ends the list. Maps: one bit per member, set = missing. Low map: bit 79 is number 1, bit 16 number 64. High map: bit 79 is number 65, bit 17 number 127

A missing list names the members not accounted for. A heard list names those accounted for; every other number the ROLL called is missing. When both maps are needed, the low map goes first with more set.

Table B.39. ROSTER REQUEST (0x7B)
BitsFieldContents
0–47callsignthe asker
48–52net tagtag of the net's name
53–59member askedmember number of the station asked; 0 = any member
60–61wanted0 = the roster; 1 = the roster and the standing orders; 2 = the standing orders only; 3 = the "mail held" list only
Table B.40. INSTRUCT (0x7C)
BitsFieldContents
0–47callsignthe sender, who must be the net's owner
48–52net tagtag of the net's name
53–55kind1 = take a member off the roster; 2 = rank an alternate; 3 = set the period; 4 = hand net control to a member; 5 = close the net; 6 = set the net's type
56–62memberthe member concerned (kinds 1, 2 and 4)
63–66valuekind 2: the rank, 1 to 3, or 0 for "not an alternate". Kind 3: the period, as in the anchor. Kind 6: 1 = Safety Critical, 0 = Casual

The roster sent in answer to a ROSTER REQUEST is an ordinary directed message of payload kind "net roster" (Section 21.3). Its body: a version byte (1); the packed net name, six bytes big-endian; the roster edition, one byte; the owner's callsign, six bytes (zero if unknown); a count byte; then eight bytes per member: callsign, member number, and the ROSTER flags without "not heard".

The "mail held" list is a message of payload kind "net held mail" (Section 21.3), sent by net control to the net, or to one member that asked for it. Its body: a version byte (1); the packed net name, six bytes big-endian; a count byte, at most 10; then fourteen bytes per entry: the member's callsign (six bytes), the original sender's callsign (six bytes) and the message id the mail is held by (two bytes, low byte first). Ten entries make 148 bytes, one shortburst (Section 22.8).

B.15 TIME family

Table B.41. TIME (0x80)
ByteFieldContents
1–6timemilliseconds since the mLink epoch, 48 bits
7quality1 = from an internet-connected clock, 2 = from GPS

B.16 The bulk frame

A bulk frame has no header: no sender, no index, no length. Its sender and its place in the transfer come from when it arrives (Section 14.5.3), and its code rate from that place: frame 0 at rate 1/2, frame 1 at 3/4, later frames at 5/6, none above the top rate in the RTS.

B.16.1 The container

Table B.42. Bulk container
Container byteContents
0–1message id
2 onwardsthe message as sent on the air, after its envelope and compression (Chapter 21)

The container is cut front to back: frame 0 takes the first 603 bytes, frame 1 the next 907, each later frame 1,008, the last frame whatever is left (fewer at a lower top rate; Table A.6). A transfer is at most 64 frames, so the largest container is 603 + 907 + 62 × 1,008 = 64,006 bytes, of which 64,004 are message.

B.16.2 Inside one frame

Table B.43. Information bits of one bulk frame, in order
PartContents
datathe frame's container bytes, most significant bit of each byte first
markertwo zero bytes
fillera fixed 200-byte table, repeated as needed, to the end of the information bits; it begins with the decimal digits of pi two per byte (03 14 15 92 65 35 …)

The data ends at the first two zero bytes that are followed by exactly the filler, to the last bit (Section 9.5). A full frame still holds the marker and at least 18 bits of filler.

B.17 The emergency frame

The emergency region has its own modem (Chapter 10); its frame is also eleven bytes, protected by the same Reed-Solomon code. A distress call is 1 to 15 frames sent back to back and repeated, with no PRESENCE.

Table B.44. Emergency frame (every frame)
ByteFieldContents
0positionhigh 4 bits: this frame's index (0 to 14); low 4 bits: frame count (1 to 15)
1incident number0 to 255, one more for each incident a station declares. An acknowledgement carries the bitwise complement of the number it answers
2–10contentframe 0: the alert or the acknowledgement (below); later frames: text

Frame 0's content is a 72-bit field, most significant bit first from the top bit of byte 2. Bits 64 and 65 say which of two layouts it is. In an alert, a zero in any field means "not provided".

Table B.45. Emergency frame 0: the alert
BitsFieldCoding
0–20latituderound((lat + 90) / 180 × 2,097,151); 0 if no position (about 9.5 m steps)
21–41longituderound((lon + 180) / 360 × 2,097,151); 0 if no position (about 19 m steps at the equator)
42–44position uncertainty0 unknown; 1 to 6: about 10 m, 50 m, 150 m, 500 m, 2 km, 10 km; 7 more
45–46position source0 none, 1 GPS, 2 entered by hand, 3 dead-reckoned or last known
47–50environment0 unspecified, 1 water, 2 wilderness, 3 mountain, 4 roadway, 5 aircraft, 6 structure, 7 underground
51–54nature0 undesignated, 1 medical, 2 trauma, 3 exposure, 4 entrapment, 5 fire, 6 hazardous material, 7 lost or stranded, 8 violence, 9 disabled and adrift
55–56severity0 unknown, 1 immediate threat to life, 2 urgent, 3 advisory
57–59persons involved0 unknown, 1 none, 2 one, 3 two, 4 three or four, 5 five to nine, 6 ten or more
60–61mobility0 unknown, 1 can move, 2 impaired, 3 cannot move
62–63incident age0 under about 15 min, 1 under an hour, 2 under 6 h, 3 longer; advances as the call repeats
64–65layout0 = alert
Table B.46. Emergency frame 0: the acknowledgement
BitsField
0–7incident number of the call being acknowledged
8–23incident check value of that call
64–65layout = 1

A station sends the acknowledgement as frame 0 alone (Section 23.6.2). The format allows text frames behind it (who acknowledged, then contact details), and a receiver reads them if present.

B.17.1 Text frames

Frames 1 onwards carry thirteen characters each of one stream: the caller's identity, a separator, the detail, then padding. With no detail there is no separator. The stream holds at most 182 characters; the detail is shortened first.

Table B.47. Emergency text character values
ValueCharacter
0separator and padding
1space
2–110 to 9
12–37A to Z (lower-case letters are sent as capitals)
38–45. , - / ? : + # in that order

The thirteen values of a frame are the digits of one base-46 number, first character most significant, stored big-endian in the nine content bytes. A character outside the table is left out, never replaced.

Appendix C

A Busy Frequency: the 200-Station Simulation

The test ran on the simulated air described in Section 33.2: every station is the real mlinkd program, and a channel program mixes their audio according to who can hear whom. Nothing here was measured with radios. Times are on-air time. Where the two runs differ enough to matter, both figures are given, the first run first. The detailed tables are from the second run, whose frequency was the less crowded of the two.

How hard the test is, in numbers:

C.1 Who was on the frequency

Table C.1. The stations in the six-hour run.
GroupStationsWhat they did
Search-and-rescue net MERIDIAN15A Safety Critical net working a search for a vessel. Net control was handed from one station to another partway through. One member is a cluster with a VHF FM radio that reaches an aircraft.
Evening net PRAIRIE30A casual net that opened about three hours in, called the roll and exchanged typed lines.
Stations in neither net155From chatty to silent: groups of two to four in conversation for about an hour, typed at a quarter of an average typist's speed; a few pasting blocks of specifications; three calling CQ over and over; many saying little or nothing.
On VHF only2The aircraft and the cluster's VHF radio. They are not counted in the 200.

Of the 200 stations, 123 had an internet connection and acted as mail gateways to one shared mailserver. The search-and-rescue field stations mostly had none. Every station was registered at the mailserver before the run began, and every station required authentication tags on what it received.

Stations could not all hear each other. The channel program worked out each one-way path from where the two stations were and where the sun was: ground wave out to about 100 km over land and 300 km over sea, then a skip zone in which nothing is heard, then one reflection from the ionosphere out to about 3,800 km and two beyond that. The run began at 19:00 UTC on an October day and ran into the North American evening, so the skip zone widened as the hours passed, and the vessels in the search area had fallen inside the skip zone of many inland stations by the end. The farthest pair was about 6,300 km apart; there were no stations overseas.

Scripted on top of the everyday traffic: one distress call; one gateway that lost its internet for an hour; mail for stations that were off the air and came on later; mail between stations that could not hear each other; message forms and lists; longer letters; blocks of data that do not compress; one message of 46,000 bytes, near the largest a station may send; and a few stations joining late or leaving early.

C.2 How busy the frequency was

Table C.2. Use of the frequency over the whole of each run, as the channel program recorded it.
MeasureFirst runSecond run
Time during which at least one station was transmitting81.4 %78.9 %
Stations transmitting at once, on average1.271.18
Each announce channel in use30 to 31 % of the time28 to 30 %
Bulk region in use11.7 %; its control channel 5.0 %10.6 %; its control channel 5.4 %
Emergency region in use0.6 % (three transmissions, 133 s in all)the same
Frames sent, from all 200 stations39,07436,073
Frames that overlapped another station's frame on the same part of the frequency31.3 %27.7 %

Nothing in the script differed between the two runs. A transmission that lands a moment earlier or later changes who waits for whom from then on, and the first run's frequency ended up the more crowded, with more messages asking another station for help. Six runs of this script on near versions of the software delivered between 774 and 793 of the 802 messages, sent between 34,600 and 39,100 frames, and overlapped between 24.4 and 31.3 % of them. A difference inside that range between two runs means nothing by itself.

The overlap figure counts two stations transmitting at once anywhere on the continent, as the channel program saw it. Many of those pairs could not hear each other and were heard by different listeners, so it overstates what any one receiver had to cope with. It was not measured per listener. In the quiet half hours about one frame in ten overlapped another; in the busiest, with the evening net open on top of everything else, about four in ten.

Table C.3. What the transmitted seconds carried, over the six-hour runs. The shares are nearly the same in a 28-station run.
What the air was spent onShare of all transmitted seconds
Message text and data (typed lines, bulk frames, weak-link series)50 to 52 %
Station identification, which opens every transmission17 to 18 %
Hearing reports, which ride along at most once a minute per station10 to 11 %
Openers, acknowledgements and requests to repeat10 to 11 %
Net frames (announcements, joins, roll calls)3 to 5 %
Relay requests, offers and hand-overs2 to 3 %
Mail notices between gateways and stations2 %

About a third of the message-text frames were repeats of text already sent once. Where the sender repeated a typed line after hearing no acknowledgement, the text really had not arrived in 93 to 96 % of the cases; a lost acknowledgement accounts for the rest. Most of the lost copies had another station transmitting on the same channel at the time.

C.3 What size the traffic was, and which part of the frequency carried it

Most messages were short and went as short frames, but most of the bytes went through the bulk region. Sizes are after compression and wrapping; "delivered" counts messages to one station.

Table C.4. Messages by how the sender last chose to send them (second run).
How it wentMessagesBytes on the airSender's air timeDelivered
Short frames (up to 156 bytes)96670,86011,284 s649 of 659
Weak-link form (157 to 601 bytes, as short frames)2410,3561,150 s24 of 24
One bulk frame (up to 601 bytes)6312,755694 s60 of 60
Several bulk frames (over 601 bytes)1733,022504 s15 of 16
Not sent direct: over 601 bytes and the link too weak for bulk22–021 of 22, by another route

Of what was delivered to one station in the second run, short frames carried 84 % of the messages and 27 % of the bytes, and bulk carried 10 % of the messages and 29 % of the bytes. In the first run the 46,000-byte message went by bulk and bulk's share of the bytes was 51 %. The stations sent 456 bulk frames in the second run: 375 at rate 1/2, 62 at rate 3/4 and 19 at rate 5/6.

A message too big for one bulk frame is not sent direct to a station whose link is measured too weak for bulk. Mail in that case is left with a gateway or at the mailserver and reaches the addressee from there; 21 of those 22 arrived by another route. When the link has simply not been measured lately, a message of up to 6,028 bytes is tried: the sender sends the first bulk frame, asks the addressee what it received, and sends the rest.

C.4 How much compression saved

The text and mail in this test were generated by a script, so how well they compress says as much about the script's wording as about the compressor. Real traffic will differ.

Table C.5. Bytes handed to the modem and bytes sent, by kind of message (second run). The ratio is bytes sent divided by bytes handed over; 1.00 means no saving.
Kind of messageMessagesBytes handed overBytes sentRatio
Longer mail1953,21824,4440.46
Message forms and lists3437,60018,9160.50
Pasted specifications67,5383,8930.52
Other mail (between home stations, through a station in between)52,8881,6950.59
Search-and-rescue traffic (mail and typed lines)227,6643,3810.44
CQ calls24823,79120,5850.86
Typed lines (conversations, occasional exchanges, the evening net, answers to a CQ)74757,31154,2460.95
Data that does not compress1173,61172,8200.99
Everything1,092263,621199,9800.76

Mail, forms and pasted blocks went out at about half their size. A typed line of 80 bytes is too short to gain anything: 432 of the 1,092 messages went out no smaller, nearly all of them short lines. The first run's figures are the same to within a hundredth.

C.5 How fast the bytes moved

Three speeds are worth telling apart. On the air is the bytes actually sent, divided by the seconds the sender spent transmitting that message, its identification, opening frames and repeats included. Counting compression uses the same seconds but counts the bytes the operator handed over, which is what the operator experiences as the transfer rate. Send to arrival divides those bytes by the whole time from pressing send to the message arriving, waiting for a clear frequency included.

Table C.6. Speed in bit/s for messages to one station that arrived (second run). Each cell is all the bytes over all the seconds; the median message is in brackets.
How it wentMessagesOn the airCounting compressionSend to arrival (median)
Short frames64946 (68)48 (66)6
Weak-link form2472 (79)131 (144)27
One bulk frame60143 (107)220 (133)20
Several bulk frames15526 (570)697 (725)93
All of them74874 (69)94 (68)8

A transfer of several bulk frames moved the operator's bytes at about 700 bit/s while it was transmitting in the second run and about 900 in the first. The same transfers managed 93 and 202 bit/s from send to arrival, because on a frequency in use four fifths of the time most of the wait is for a turn. Over the whole run the frequency delivered 234,168 bytes of operator text to single stations in the first run and 192,978 in the second, about 39,000 and 32,000 bytes an hour; most of the difference is the 46,000-byte message. Broadcasts and lines to a whole net are not in those figures because they have no one recipient to count.

A typed line of about 70 bytes, sent once and acknowledged, takes 9.2 s of air: the sender's identification, up to two hearing reports, the opener and eight short frames, then the addressee's identification and acknowledgement. The text itself is about 5 s of that. Averaged over every such line, repeats included, the cost was 12 to 15 s in these runs and about 10 s in a 28-station run.

C.6 What got through

Table C.7. Messages delivered in each run, and how long delivery took in the second run from the moment the operator sent.
Kind of trafficDelivered, first runDelivered, second runHalf arrived withinNine in ten within
Conversation lines410 of 413412 of 4131.3 min11 min
Occasional exchanges169 of 177176 of 1771.4 min12 min
Answers to a CQ45 of 4645 of 461.0 min4.6 min
Search-and-rescue traffic16 of 1814 of 181.2 min (12 timed)41 min
Evening net, typed lines to one member47 of 5551 of 553.6 min18 min
Pasted specifications5 of 66 of 613 min42 min
Message forms and lists35 of 3636 of 362.8 min (25 timed)19 min
Longer mail23 of 2424 of 244.6 min (11 timed)26 min
Mail between home stations3 of 33 of 33.2 min (one timed)–
Mail arriving from the internet side4 of 43 of 420 min91 min
Mail for stations that were off the air6 of 66 of 678 min121 min
Mail between stations that cannot hear each other4 of 44 of 431 min50 min
Data that does not compress (1,500 to 3,700 bytes)9 of 98 of 93.7 min15 min
One message of 46,000 bytes1 of 10 of 1––
All of the above777 of 802 (96.9 %)788 of 802 (98.3 %)––

Nearly everything short arrived, half of it within a minute or two and nine in ten within about ten to twenty minutes. In the first run, with its busier evening, half the conversation lines arrived within 2.2 minutes and nine in ten within 24. Mail that had to wait for a gateway, a station in between or the addressee coming on the air took tens of minutes. Nearly all of the messages not delivered were typed lines still waiting, when the run ended, for a station in between to offer help.

The distress call was logged by 194 of the 200 stations in both runs, and the base operator acknowledged it (Chapter 23).

C.7 What did not work well

Each weak spot below was traced to its cause in the station logs. Most of them are rules that serve a small net well and cost something when a hundred stations apply them at once.

C.8 Where it stops working

The point at which this frequency overloads has not been measured on this version of the software. With an earlier version and a simpler model of who hears whom, a one-hour run of 250 stations with twice the chatter had some station transmitting 90 % of the time and delivered two conversation lines in three within the hour. The distress call was logged by 246 of those stations and acknowledged; it has its own part of the frequency (Section 8.3).

C.9 What it cost the computer

Table C.8. Cost of running 202 station programs, the channel and the mailserver on one 24-core workstation (first run).
MeasureValue
Speed2.5 times real time: 24.4 minutes of wall time per on-air hour
Processor16.9 cores busy on average
Memory10.1 GB at most
Station logs1.4 GB
Station stores1.0 GB
Audio packets the channel failed to deliver0
Scripted operator actions that fired late19 in 20 within 0.5 s; the latest by 42 s

Divided out, one station program on a busy frequency used about three hundredths of a processor core in real time and about 50 MB of memory. The stations ran with no sound card, no rig control and no client program, so a real station costs somewhat more.

C.10 What this test does not show

Appendix D

Glossary

Every underlined term in this manual links here. Each entry lists the chapters that use it.

ACK (acknowledgement)
The BULK-family reply saying a message arrived complete and checked. It echoes the message identifier so the sender cannot mistake another exchange's ACK for its own.Used in: Chapter 2, Chapter 14, Chapter 16
ADIF (Amateur Data Interchange Format)
The standard file format for exchanging contact logs between logging programs. The client's QSO Log exports and imports it.Used in: Chapter 5
AEAD (authenticated encryption with associated data)
A kind of cipher that both hides a message and attaches a tag proving nothing was changed, including readable header bytes it was told to protect. mLink uses AES-256-GCM.Used in: Chapter 26
alternate (named net)
One of up to three members the owner of a named net has ranked to stand in for it. When net control goes quiet the alternates claim the seat first, in rank order, three seconds apart, ahead of every other member.Used in: Chapter 22
anchor
Net control's heartbeat frame for a named net, sent once a cycle (150 to 600 seconds, normally 300) on announce channel 0. One frame carries the net's name, type and cycle period, the term, the live member count, the roster edition, the highest member number, the first alternate, and whether net control is a stand-in.Used in: Chapter 22
announce channel
One of the three independent QPSK channels inside the announce region, centred at 400, 800 and 1,200 Hz and numbered 0, 1 and 2. Three stations can use the three at the same moment.Used in: Chapter 8
announce frame
The one small frame format of the announce channels and the bulk-control channel: eleven bytes (a type byte and ten data bytes) plus twelve Reed-Solomon parity bytes, sent as one QPSK frame of about 640 ms.Used in: Chapter 14, Chapter 22
AppImage
A Linux program packaged as a single executable file that runs without installation. mLink's AppImage holds the client, the station daemon, the web bridge and the web client.Used in: Chapter 4
applet
One tool in the mLink client, opened in its own window from the Start menu: Messages, Stations, World Map, Waterfall and so on.Used in: Chapter 5
APRS (Automatic Packet Reporting System)
The long-established amateur system for sending positions that others plot on a map. mLink's position report frame follows the same idea on mLink's own announce band.Used in: Chapter 28
area CQ
A message addressed to a circle on the map rather than to a callsign. Everyone who hears it keeps it; stations whose grid square lies inside the circle are also alerted.Used in: Chapter 5, Chapter 28
ARQ (automatic repeat request)
Any scheme in which the receiver reports what it did or did not get and the sender repeats what is needed.Used in: Chapter 16
audio backend
The part of the daemon that talks to a particular sound system: ALSA or PipeWire on Linux, or null for no sound hardware.Used in: Chapter 4
Authoritative Station
Any station whose operator has passed a heard emergency to the people who can respond and says so on the air by acknowledging it. It is not a setting or a special kind of station. The acknowledgment stops the caller's beacon and tells other stations the incident is handled.Used in: Chapter 23
backhaul
Carrying a message from one cluster member to another over the cluster link, so it can be delivered on the second member's band.
band
An amateur frequency range such as 40 metres or 20 metres. A band contains mLink channels.Used in: Chapter 8
beacon
A transmission that is only a PRESENCE frame (plus, for the periodic beacon, up to three HELLO frames): "this is me, here". A converged station beacons only after 10 to 60 minutes of its own silence.Used in: Chapter 5, Chapter 14, Chapter 18
belief propagation
The LDPC decoding method: bits and checks repeatedly exchange opinions along the Tanner graph until every check is satisfied or a round limit is reached (15 in mLink).Used in: Chapter 9
bulk frame
One LDPC codeword sent on the bulk modem: a sync preamble symbol plus 203 data symbols, 65,280 samples or 5.44 s long at every code rate.Used in: Chapter 12
bulk transfer
A transfer carried in the bulk region as one or more OFDM frames of 5.44 s each, opened by [presence][rts]. The station uses it for messages above about 100 bytes when its estimate of the path is +6 dB SNR@3k or better.Used in: Chapter 2, Chapter 15
bulk-control channel
A fourth QPSK channel, at 2,250 Hz in the middle of the bulk region, that carries only the short control frames of a bulk exchange: its opener, its replies and the openers of repair or follow-on bursts. It is keyed only while no OFDM burst is using the region.Used in: Chapter 8, Chapter 17
bulletin (named net)
Text of up to 200 characters that net control sends to every member, followed by a receipt roll to find out who has it and one re-send for those who do not. A member's bulletin is taken up and sent by net control.Used in: Chapter 22
bystander
A station that hears a named net but is not a member of it. It sends nothing for the net, keeps its routine traffic off the announce channel a roll call is using, and lets the net's members answer first when help is asked for.Used in: Chapter 22
callsign packing
Writing a callsign as a nine-character base-39 number (space, digits, letters, '/' and '-') stored in six bytes, the same idea the FT8 family uses. Portable and SSID suffixes are kept.Used in: Chapter 14
capture ring
The receiver's continuous recording of incoming audio: 524,288 samples, about 43.7 seconds at 12,000 samples per second. The newest audio overwrites the oldest, and every sample is addressed by an ever-increasing position so detections and frames share one timeline.Used in: Chapter 13
carrier (OFDM)
One of the tones that together make up an OFDM signal. In mLink's bulk modem the carriers are 46.875 Hz apart and each carries one QPSK point per symbol, or a known pilot value.Used in: Chapter 12
CAT (computer aided transceiver)
Control of a radio from a computer over a serial or USB cable: keying, frequency and mode.Used in: Chapter 4, Chapter 29
certificate authority (CA)
The trusted signer whose signature on an operator's certificate vouches that a public key belongs to a callsign. A group that uses certificate-mode encryption runs one, offline and away from any station.Used in: Chapter 26
CFAR (constant false alarm rate)
A detection threshold that moves with the noise instead of being fixed: the bar is set from recently seen noise-only scores, so noise alone clears it about equally rarely however loud the band gets. mLink sets it at five times the estimated noise spread.Used in: Chapter 13
channel
One mLink operating frequency inside a band: the dial frequency everyone in a conversation tunes to. A channel's audio passband is divided into regions. (The three announce channels inside the announce region are the one exception to this meaning.)Used in: Chapter 8
channel estimate
The receiver's measurement of how the path changed each carrier's strength and phase, taken from the pilots and filled in between them by straight-line interpolation, fresh for every symbol.Used in: Chapter 12
channel mixer
The program at the centre of the simulated air. Each round it collects every station's transmit audio and builds a separate receive mix for each listener, applying path gains, noise, fades and band-wide interference.Used in: Chapter 33
check-in
A member's answer in a roll call: one announce frame sent alone, carrying the sender's callsign, its member number, how many slots come after it, status marks such as 'has traffic' or 'needs help', and the number of another member it heard. It is not acknowledged. A check-in marked as the last one is also how a member leaves the net.Used in: Chapter 22
checkpoint (CKPT)
The addressee's reply after each segment except the last of a long transfer: either everything so far arrived, or a map of the frames that did not, plus how many frames it has been told about.Used in: Chapter 16
client
The program an operator looks at. It sends commands to a station daemon and shows live updates from it over a local network connection, but never transmits or stores traffic itself. The reference client runs on the desktop or in a web browser.Used in: Chapter 1, Chapter 2, Chapter 4, Chapter 5
cluster
Several mLink station daemons, each with its own radio and band, sharing one callsign and acting as one station. Members share what they hear and can carry traffic between bands over the internet.Used in: Chapter 5, Chapter 31
cluster journal
Each cluster member's numbered, append-only log of what it has learned (stations heard, links, membership, station-wide settings, work outcomes). Only the owner writes its log; other members copy it by asking for entries after a number.
The ordinary network connection (LAN or internet) between cluster members. It never involves the radio.
cluster member
One daemon in a cluster: a machine with one radio on one band and a short human label. A member is never a person.
code rate
The fraction of a codeword that is data rather than redundancy. mLink's bulk LDPC code runs at 1/2, 3/4 or 5/6.Used in: Chapter 9, Chapter 15
codeword
One complete block of an error-correcting code: data plus redundancy. A Reed-Solomon codeword in mLink is 23 bytes; an LDPC codeword is 9,720 bits.Used in: Chapter 9
coherence test
The check the first frame of a bulk burst must pass: how closely the received stretch matches the preamble's shape, ignoring loudness, on a 0-to-1 scale. A real preamble scores about 0.997; mLink requires at least 0.70.
command envelope
The fixed outer shape of every client command: the command name, the session number, an optional request number that the answer echoes, and the command's own parameters.
compression dictionary
A block of typical content built into every station in advance, which lets the compressor shrink even short messages well. mLink has one, of 8 KiB, made from ordinary amateur message traffic and tried for text, mail, net bulletins and standing orders.Used in: Chapter 21
congestion collapse
What happens to a shared channel when stations resend on a timer: late answers are taken for lost ones, the resends make every answer later still, and the channel fills with copies of messages that were already on their way.Used in: Chapter 20
constellation
The set of points (amplitude and phase combinations) a modulation may send, plotted on a plane. QPSK's constellation has four points, one per quadrant.Used in: Chapter 3
contact horizon
One and a half times a station's current beacon interval (15 minutes on a small net, up to 90 on a busy one): the longest it may take to hear a quiet station again. Promises to act "on next contact" last at least this long.Used in: Chapter 18, Chapter 20
convergence
A station's start-up process: ten minutes of listening, then SEEDs if nobody has been heard, ending the moment it decodes any other station. It decides only when the station sends beacons, never what it can receive.Used in: Chapter 18
courier
A station that is not a gateway, heard a pickup broadcast and holds the mail until it can hand it to a gateway, or straight to its only recipient. Couriers transmit nothing until they act.Used in: Chapter 22, Chapter 24
cross-symbol interleaver
The bulk modem's bit shuffle: the codeword is written into a 48-row by 203-column grid and each OFDM symbol sends one column, so a symbol lost to a fade becomes errors scattered across the whole codeword.Used in: Chapter 12
custody (of a mail)
Responsibility for a mail. A gateway takes custody only after the mailserver has confirmed storing the mail, and says so with one TAKEN frame; from then on the sender's station can stop worrying about it.Used in: Chapter 24
cyclic prefix (CP)
A copy of the end of each OFDM symbol placed in front of it. Echoes of the previous symbol land in the prefix, which the receiver discards. In mLink's bulk modem it is 64 samples, 5.33 ms.
dARQ
mLink's selective ARQ: the receiver keeps what it got and names what is missing in a dNAK; the sender packs only the missing bytes into new frames, starting again at the most robust rate. Bulk data is never sent again into silence.Used in: Chapter 2, Chapter 16
datum (search and rescue)
The reference point a search starts from, usually the subject's last known position.Used in: Chapter 5, Chapter 28
dead reckoning
Estimating where something is now from its last known position, course, speed and the time since. The map shows it as a hollow circle joined to the last report by a dotted line.Used in: Chapter 28
decibel (dB)
A logarithmic way of writing a power ratio: +3 dB is double, +10 dB is ten times, -10 dB is a tenth. Decibels add where ratios multiply.Used in: Chapter 3
decoder worker
A separate thread in the station that demodulates and error-corrects a completely recorded frame, so the heavy work never holds up listening. A station runs two.
defer
Staying off a part of the channel that another station has reserved, until the announced transfer (and the allowance for its reply) is over. mLink's name for what the 802.11 wireless standard calls the NAV (network allocation vector).Used in: Chapter 2, Chapter 5, Chapter 17
deferred
The outbox state of a message the station has set aside but not given up on: no relay found yet, a relay chosen but no confirmation yet, or a relay that reported failure. The station keeps it on disk and tries again when another station is heard.Used in: Chapter 2, Chapter 6, Chapter 19, Chapter 20
dNAK (selective negative acknowledgement)
The BULK-family reply listing, as a 64-bit map, which frames of a transfer are missing, so the sender re-sends only those.Used in: Chapter 2, Chapter 14, Chapter 16
dynamic-range guard
A second detection bar tied to the loudness of all the received audio, not just one region's noise. It stops faint leakage from a very loud signal elsewhere in the passband from being mistaken for a frame.Used in: Chapter 13
ECDH (elliptic-curve Diffie-Hellman)
A key-agreement method: each side combines its own private key with the other side's public key, and both arrive at the same shared secret without ever sending it.Used in: Chapter 25, Chapter 26
emergency frame
The unit of the emergency region: 11 bytes, a little over ten seconds of air. Every frame carries a two-byte header (frame number, frame count, incident number); a distress call is 1 to 15 of them sent back to back.Used in: Chapter 23
envelope byte
The first byte of every mLink message. Its bits say how the rest was packed: compressed or not, which shared compression dictionary, whether it is text, and whether and how it is encrypted.Used in: Chapter 21
equalizer (MMSE)
The receiver step that undoes the path's effect on each carrier using the channel estimate. mLink uses a minimum mean-square error (MMSE) equalizer, which holds back its correction on carriers that are close to the noise instead of amplifying the noise.Used in: Chapter 12
event loop
The daemon's central thread: it takes messages (a frame decoded, a timer tick, a send request) from one queue and handles them one at a time. Every decision about the air is made here.Used in: Chapter 29
expected red
A test scenario written to show a known misbehaviour before it is fixed. The test runner treats its failure as correct and flags it loudly if it ever passes unexpectedly.Used in: Chapter 33
fading
The rise and fall of a received signal as its echoes drift in and out of step, from fractions of a second to minutes. It can hit one part of the passband while sparing another.Used in: Chapter 3
FEC (forward error correction)
Adding computed redundancy to data before sending it so the receiver can find and fix errors without asking for a repeat.Used in: Chapter 9
FFT (fast Fourier transform)
A fast algorithm that turns a stretch of samples into the amplitude and phase of each frequency in it; the inverse FFT goes the other way. mLink's bulk modem uses a 256-point FFT at 12,000 samples per second.Used in: Chapter 12
first-frame rule
How long a station keeps overhearing a directed bulk transfer that is not for it and does not belong to a net it can hear: until about eight seconds after the RTS. If nothing of the transfer has decoded by then, it stops overhearing and may use the announce channels, staying out of the bulk region and never calling the transfer's two stations. If the first frame did decode, it listens to the end and keeps a copy for relay.Used in: Chapter 17
frame chain
The frames of one transmission in the order they go out, written in brackets, such as [presence][rts][bulk 0].Used in: Chapter 14
frame family
A group of related announce frames sharing the high half of the type byte, such as PRESENCE (0x0), RELAY (0x1) or BULK (0x2).Used in: Chapter 14
freshness window
How long, 1.32 s (two frame spacings), a PRESENCE binding stays valid on its channel after the last frame that kept the chain going. An opener arriving later than this is dropped.Used in: Chapter 14
FSK (frequency-shift keying)
Sending data by choosing which of a set of tones to transmit. RTTY uses two tones; mLink's emergency modem uses eight.Used in: Chapter 10
gateway
Any station whose link to a mailserver is switched on, registered and proven within the last ten minutes. It says so with the gateway flag in every PRESENCE it sends, and it deposits, fetches and delivers mail on behalf of stations without internet.Used in: Chapter 1, Chapter 4, Chapter 5, Chapter 23, Chapter 24, Chapter 25
gateway flag
The top bit of the first grid byte in a PRESENCE frame. A station sets it while it, or another member of its cluster, can reach the mail server over the internet.Used in: Chapter 14
geopoll
A single frame that asks "is anyone in this area?", carrying a circle (centre and radius) in place of a callsign and sent with no PRESENCE in front. Stations whose configured grid square lies inside the circle answer.Used in: Chapter 5, Chapter 18, Chapter 28
gpsd
The standard Linux service that reads a GPS receiver and shares its fixes with programs over a local network connection. The mLink station daemon takes its GPS position from it.Used in: Chapter 4, Chapter 28
Gray code
An ordering of bit patterns in which neighbours differ in exactly one bit. Labelling a constellation this way means the commonest mistake, confusing a point with its neighbour, costs one wrong bit instead of two or more.Used in: Chapter 11
guard band
Empty spectrum left between two signals so one cannot spill into the other's receiver. mLink measures its guard bands from where each signal's energy actually stops, not from the allotment lines.Used in: Chapter 8
half duplex
Able to transmit or receive, but not both at once. An amateur transceiver hears nothing while it transmits, so stations must take turns.Used in: Chapter 3
heard list
A station's record of every station it has decoded first-hand: callsign, grid, first and last heard, signal reports and the gateway flag. Only first-hand decodes create entries, and an entry is dropped after an hour of silence.Used in: Chapter 5, Chapter 18
heard through
A roster mark for a member that net control has not heard directly but listed or counted present on another member's word: a JOIN THROUGH, a number named in another member's check-in, or a roster handed over after a merge.Used in: Chapter 22
HELLO
An announce frame meaning "I recently heard this station", with a strong or weak class, minutes since heard, SNR and that station's gateway flag. It rides only on transmissions that are happening anyway.Used in: Chapter 18, Chapter 22
hidden station
A station that the receiver of a transfer can hear but you cannot. Its openers reserve nothing at your station, so you may key over it; mLink partly covers this by reserving air when it hears the receiver's dNAKs and longburst ACKs.Used in: Chapter 17, Chapter 22
HMAC (hash-based message authentication code)
A short code computed from a message and a secret key. Anyone holding the key can check the code; nobody without it can produce a valid one. It proves who made the message without hiding anything.Used in: Chapter 25
hold-off (emergency rebroadcast)
The wait, at least 5 seconds and different for each station, before a station that heard an SOS rebroadcasts it in the announce region. Slots are spaced so a later station can hear an earlier rebroadcast and drop its own.Used in: Chapter 23
hub (client)
An applet that gathers several related views under tabs in one window, such as Messages (mail folders and the composer) or Stations (heard list, QSO log, friends).Used in: Chapter 5
I and Q (in-phase and quadrature)
The two coordinates that describe a signal's amplitude and phase at each instant, as if the tone were an arrow on a circle. Receivers work with both to read phase-shift modulations.Used in: Chapter 3
impairment
Something the simulated air does to signals to imitate a real band: noise at a set SNR, a weak or one-way path, a fade, one lost frame, or interference such as carriers, static crashes, radar pulses or a voice signal.
incident (emergency)
One declared distress call. It is named on the air by a one-byte incident number plus a 16-bit check value over its decoded content; together they let every station recognise repeats, rebroadcasts and acknowledgments of the same call.Used in: Chapter 23
INET-REQ
The announce frame an off-grid station sends to ask any station in earshot to fetch internet data for it. It carries the kind of data, a session number, a freshness hint and parameters such as a position.Used in: Chapter 27
integrity check (message check)
The two-byte value (a 16-bit cyclic redundancy check) computed over the sender's callsign, the addressee's callsign and the message before compression. It is tested once, after the whole message is back together and unwrapped; a mismatch is never delivered or acknowledged. The same two bytes serve as the message's name on the air.Used in: Chapter 2, Chapter 14, Chapter 16, Chapter 21, Appendix B
interleaver
A fixed shuffle of the bits of a coded frame before transmission, undone by the receiver, so that bits next to each other on the air are far apart in the frame. It adds no redundancy and no air time.Used in: Chapter 9
internet query
A record that says a station wants a piece of internet data, such as the weather at a point, once or kept up to date, fetched either by the station itself or by asking over the air.Used in: Chapter 27
internet source
A description of one web service a station knows how to use: its address template, headers, which fields to extract, the data type and a refresh interval. A capability, not a request.Used in: Chapter 27
ionosphere
Layers of the upper atmosphere ionised by the sun that bend HF signals back to earth, making long-distance skip possible. Its behaviour changes with time of day, season and the solar cycle.Used in: Chapter 3
JSON (JavaScript object notation)
A human-readable text format for structured data, made of named fields and lists. Every command, answer and event between client and daemon is a JSON object.Used in: Chapter 30
kept partial
The receiver's saved copy of an incomplete message: received bytes in place, holes where missing bytes belong. Repair bytes are written into the holes; it is discarded after 10 minutes without a repair.Used in: Chapter 16
keyring
A station's store of key material for encryption: its own identity (if any), shared group keys, and the checked certificates of other stations. It reports what it can do but never reveals keys.Used in: Chapter 26
LDPC (low-density parity-check) code
An error-correcting code defined by a large, sparse set of parity checks and decoded by passing soft beliefs between bits and checks. mLink's bulk frames each carry one 9,720-bit LDPC codeword.Used in: Chapter 2
A running average of the SNR at which a station has been heard, in which each new reading counts for 40 percent, so that one fade cannot flip the choice of how to send. It is good for five minutes, and a fresh report from the other station of how well it hears you is used in its place.Used in: Chapter 2, Chapter 13, Chapter 15, Chapter 18
A station's second-hand picture of who hears whom, built from HELLO frames, relay OFFERs, overheard openers and relay RESULTs. It never creates heard-list entries; a row not refreshed for two hours is dropped.Used in: Chapter 5, Chapter 18, Chapter 22
LLR (log-likelihood ratio), soft bit
A number saying which way a received bit leans and how strongly; in mLink a whole number from -127 to +127, positive meaning 0 and negative meaning 1, near zero meaning unsure.Used in: Chapter 9, Chapter 12
longburst
A message of 157 to 601 bytes to one station, sent as up to four shortbursts, one per transmission, each acknowledged before the next. Used only when the link is too weak for bulk; held to one bulk frame's worth of data.Used in: Chapter 2, Chapter 15
longburst manifest
The extra announce frame at the front of a longburst's first transmission, giving the whole message's length, its check and the number of pieces to expect.Used in: Chapter 15
MAC (medium access control)
The layer of a radio network that decides who transmits when. In mLink it is the only part of the daemon that decides whether, when and on which channel a transmission goes out.Used in: Chapter 5, Chapter 29
Maidenhead grid locator
The amateur-radio way of naming a place with letters and digits, such as DM43: two letters for a 20 by 10 degree field, two digits for a 2 by 1 degree square, and optional further pairs for finer squares. Every PRESENCE carries four characters of it.Used in: Chapter 4, Chapter 28
mail key lease
The condition under which a cluster member holds the station's shared mail key: renewed by every authenticated contact with another member, discarded after seven days without one or on leaving the cluster.Used in: Chapter 31
mailkey
The 32-byte secret a registered station shares with the mailserver. Both ends work it out from public keys they have swapped; it is never transmitted. It keys the station's signed requests to the server and the sender tag on its mail.Used in: Chapter 25
mailserver (CMS, central mail server)
The radio-less mLink program on an internet host that keeps a mailbox for every callsign. Gateways deposit mail into it and fetch mail out of it for stations on the air; it also exchanges internet email and runs mailing lists and chat rooms.Used in: Chapter 1, Chapter 4, Chapter 5, Chapter 25
MARS and SHARES
The Military Auxiliary Radio System and the SHAred RESources HF radio program: US federal radio programs that many hams also serve in. They operate under their own rules, which permit encryption where amateur rules do not.Used in: Chapter 25, Chapter 26
matched filter
A search that slides a copy of a known waveform along the received audio, multiplying and summing at each position. Noise mostly cancels; the known waveform piles up into a sharp peak, so it can be found even under a lot of noise.Used in: Chapter 13
Mayday
The international voice distress call, meaning immediate threat to life. In mLink it is the 'immediate' severity class.Used in: Chapter 23
member number
A named net member's position on the roster, from 1 to 127, handed out in joining order and never reused. It sets the member's slot in a roll call.Used in: Chapter 22
members first
While a named net is alive on the frequency, stations helping their own net's traffic (relay offers, couriers, mailbox answers) take the early half of the usual answer slots and everyone else the late half.Used in: Chapter 22
message lifetime
How long a station keeps working on a message it cannot deliver yet before it takes stock: 15 minutes or the contact horizon, whichever is longer. When it runs out, a deferred message gets a new note and another lifetime, never a failure.Used in: Chapter 20
min-sum decoding
A cheap approximation used in belief propagation: a check's reply takes the product of its other members' signs and the smallest of their confidences.Used in: Chapter 9
The reference instant, 2020-04-20 00:00:00 UTC, from which every time sent on the air is counted, in most fields as whole seconds. Inside the station and toward clients, ordinary Unix time is used instead.Used in: Chapter 21, Appendix B
multipath
A signal arriving by several routes of different length, so the receiver hears it plus delayed echoes. On HF skywave the echoes typically trail by 0.5 to a few milliseconds, occasionally up to about 10 ms.Used in: Chapter 3
NB8FSK (narrow-band 8-tone frequency-shift keying)
mLink's emergency modem: one of eight tones 6.25 Hz apart between 128 and 172 Hz, 6.25 tones per second, 3 bits per tone. Slow and narrow so it can be decoded far below the noise.Used in: Chapter 10, Chapter 23
net control
The station that runs a named net: it sends the anchor once a cycle (normally every five minutes), keeps the roster, calls roll calls and sends bulletins. It carries no authority, and a member takes over if it goes quiet.Used in: Chapter 5, Chapter 22
net tag
Five bits folded from a named net's name, carried by most of the net's frames to say which net they belong to. It only narrows a frame down: no frame is acted on by the tag alone.Used in: Chapter 22
OFDM (orthogonal frequency division multiplexing)
Sending data on many closely spaced carriers at once, each changing slowly, built and separated with one FFT per symbol. mLink's bulk modem is OFDM with 28 carriers (24 data, 4 pilots) between 1617 and 2883 Hz.Used in: Chapter 2, Chapter 12
open check-in
Three slots after a roll call's final TALLY in which a station that asked to join but has no number yet can check in and be listed at once.Used in: Chapter 22
open pickup
The mailserver rule that any registered station may list and fetch any station's mailbox, so any gateway can deliver anyone's mail. Only a reported delivery moves a mail on, and the server records which station reported it.Used in: Chapter 25
operator account
A named person at a station, with a password, a role, an enabled switch and an optional tactical position. Accounts are station-wide across a cluster.Used in: Chapter 5, Chapter 7
orthogonal (carriers)
Signals that can be added together and later separated perfectly. OFDM carriers spaced exactly one over the FFT window length apart are orthogonal: each one reads as zero at every other carrier's frequency.Used in: Chapter 12
outbox
The station's durable record of everything it has been asked to send, one row per message, with a state the operator can watch, such as pending, airing, sent or deferred.Used in: Chapter 2, Chapter 6
owner (named net)
The station that opened a named net, or was handed it, or took it over. When a split heals, the owner's net continues and a stand-in hands back to it. The owner ranks the alternates and sets the cycle period and the net type, and may let another station run the net. It carries no authority beyond that.Used in: Chapter 22
Pan-Pan
The international voice urgency call: urgent, but no immediate threat to life. In mLink it is the 'urgent' severity class.Used in: Chapter 23
parity bit
An extra bit chosen so that a group of bits contains an even number of 1s; if one bit in the group flips, the count turns odd and the error shows.Used in: Chapter 9
parity-check matrix (H)
The table that defines an LDPC code: one row per check, one column per bit, with a 1 wherever a check includes a bit. A codeword is valid when every check sums to even.
Part 97
The part of the US FCC rules that governs the amateur radio service. Among other things it forbids messages encoded for the purpose of obscuring their meaning.Used in: Chapter 26
passband
The strip of audio, roughly 0 to 3000 Hz, that an SSB rig turns into radio and back. Everything mLink sends is audio in this strip.Used in: Chapter 3
pausing the air
Stopping the simulated air at an exact on-air moment so a test script can act there (submit a message, stop a station) and then resume, with the script's own delay costing no time on the air.Used in: Chapter 33
payload kind
The one-byte tag, just inside the envelope byte, that says what a message's content is (text, opaque data, mail, map overlay, certificate, internet response and so on), so the receiving station hands it to the right part of the station.Used in: Chapter 21, Chapter 28
PBKDF2 (password-based key derivation function 2)
A standard way of storing a password as a one-way fingerprint by mixing it with random salt and hashing it many times over. mLink uses 100,000 rounds of HMAC-SHA-256.Used in: Chapter 7
pickup broadcast
A mail sent to the all-stations address 0CQCQCQ while its recipients are real callsigns or outside addresses. It means "anyone who can, take this to the mailserver": any gateway that hears it deposits it, and any other station may carry it onward later.Used in: Chapter 24
pilot carrier
An OFDM carrier that sends a fixed, known value instead of data so the receiver can measure how the path changed that part of the spectrum. mLink's bulk modem has four, at 1758, 2086, 2414 and 2742 Hz.Used in: Chapter 12
POI (point of interest)
A marker you place on the World Map, with a label, notes, group, symbol and optional expiry. The station stores POIs, so everyone connected to it sees them.Used in: Chapter 5
posture (solo / organisation)
Whether a station signs people in by name. Derived automatically: no enabled accounts means solo (one station password), one or more means organisation.Used in: Chapter 7
preamble (sync)
The short, known waveform at the start of every frame whose only job is to say where the frame begins. Each region has its own: a chirp for emergency, four QPSK symbols for announce, a two-halved OFDM symbol for bulk.Used in: Chapter 11, Chapter 13
PRESENCE
The announce frame that opens every ordinary mLink transmission: the station's packed callsign, four characters of its grid locator, and a status carried in the frame's type byte. A PRESENCE on its own is a beacon.Used in: Chapter 1, Chapter 14, Chapter 18, Chapter 22, Chapter 23, Chapter 27, Chapter 28
PTT (push to talk)
The line or command that switches a transceiver from receive to transmit. mLink can key a radio by CAT command, by a serial-port control line, or by VOX.Used in: Chapter 3, Chapter 4, Chapter 14
QPSK (quadrature phase-shift keying)
Sending two bits per symbol by setting a tone to one of four phases a quarter-turn apart. mLink's announce modem is QPSK at 200 symbols per second.Used in: Chapter 11
QSL probe
A short [presence][qsl] transmission a sender uses when an expected reply or checkpoint never came. It carries no data and asks the addressee to repeat whatever verdict it holds; it is sent once before the sender gives up on the direct path.Used in: Chapter 2, Chapter 16
random back-off
A wait of random length, up to a set limit, before a retry or before acting on a moment many stations share, so that they do not all key together. In mLink most limits grow with the number of stations heard in the last 30 minutes, and each wait is picked fresh for each event.Used in: Chapter 17
rate ladder
The rule that a bulk frame's code rate follows from its position in the transfer: frame 0 at rate 1/2, frame 1 at 3/4, every later frame at 5/6, and never above the ceiling announced in the RTS.Used in: Chapter 15
reactive beacon
A PRESENCE sent as an answer to a SEED or a geopoll. Each station answers in a time slot and on an announce channel fixed by its own callsign, and stays quiet once three other stations have answered.Used in: Chapter 18
receipt roll
A roll call that follows a bulletin: its ROLL carries a tag made from the bulletin's message id, and each member's check-in says whether it holds that bulletin.Used in: Chapter 22
Reed-Solomon code (RS)
An error-correcting code that works on whole bytes. mLink's announce and emergency frames use RS(23,11): 11 bytes of content plus 12 check bytes, which lets the receiver repair up to 6 wrong bytes or report the frame unreadable.Used in: Chapter 9, Chapter 10, Chapter 11
region
A strip of a channel's audio passband that belongs to one modem: emergency (125-175 Hz), announce (200-1,500 Hz) or bulk (1,500-3,000 Hz).Used in: the Preface, Chapter 8, Chapter 13, Chapter 23
relay
Delivery of a message by a third station when the originator cannot reach the destination directly. It is asked for only after a direct attempt meets silence, and uses the REQUEST, OFFER, SELECT, FOR and RESULT frames.Used in: Chapter 2, Chapter 19, Chapter 22
reply window
The 5 seconds a sender listens for an ACK or dNAK after its transmission ends. If all three announce channels are reserved by other stations at the moment it would close, it is moved to 5 seconds after the first of those reservations ends.Used in: Chapter 16
reserved addressee
An addressee beginning with 0, which no licensed station can hold, used as a destination meaning more than one station: 0CQCQCQ for everyone, 0CQQTH for everyone with the attention of those in a stated area, and 0 plus a net name for the members of that net.Used in: Chapter 14, Chapter 22, Chapter 28
RIT (receiver incremental tuning)
A rig control that shifts the receive frequency by a small amount without moving the transmit frequency. Where the station can command it, a slow loop uses the frequency offset measured on bulk frames to keep the receiver on frequency.Used in: Chapter 13
role
What a signed-in session may change: operator (own traffic, reading, emergency), technician (how the station operates on the air) or administrator (accounts, keys, cluster membership). Each role includes the ones below it.Used in: Chapter 5, Chapter 7
roll call (named net)
Net control sends one ROLL frame and each member answers with one CHECKIN in its own numbered 1.2-second slot, followed by a TALLY of who was not accounted for, a short tail of second tries for the missing, and three open slots for stations with no number yet.Used in: Chapter 22
root-raised-cosine (RRC) shaping
A smooth pulse shape for each symbol, split between transmitter and receiver, that keeps a signal narrow while letting neighbouring symbols overlap without disturbing each other's centres. mLink's announce modem uses a roll-off of 0.35, giving a 270 Hz signal.Used in: Chapter 11
roster (named net)
Net control's list of a named net's members: callsign, member number and a few marks. It reaches the members up to three entries at a time behind each anchor; a member can also learn rows from the check-ins it hears, or ask another member for the whole list.Used in: Chapter 22
ROSTER REQUEST
A single frame with which a station asks a member of its net (one by number, or any) for the whole roster, for the net's standing orders, or for both. Each answer is one ordinary directed message.Used in: Chapter 22
RTS (request to send)
The BULK-family frame that opens a bulk transfer: frame count, top code rate, addressee and message identifier. Hearing it also tells other stations how long the bulk region will be busy.Used in: Chapter 2, Chapter 13, Chapter 14, Chapter 15, Chapter 16, Chapter 19
Safety Critical net
One of the two types of named net; the other, the default, is Casual. In a Safety Critical net, net control says again every message a member sends to the net, and a member speaks for each station that cannot hear net control: it repeats net control's anchor every cycle and relays that station's net messages both ways.Used in: Chapter 22
sample clock
In simulation, a station's sense of time worked out from the audio it has used up rather than from the computer's clock: a second is 12,000 samples. Because everything counts time this way, a busy computer makes a run slower but never changes its outcome.
sample rate
How many times per second a sound card measures (or produces) the audio voltage. mLink processes everything at 12,000 samples per second, converting automatically if the card runs faster.Used in: Chapter 3
say-again repair
The single repair round for a broadcast: a listener missing frames sends a delayed request shaped like a dNAK, the sender collects requests for 22 seconds and sends once more every frame anyone asked for.Used in: Chapter 17
Schmidl-Cox preamble
A sync symbol whose second half repeats its first, so a receiver can find it by comparing the signal with itself and can also measure frequency error. Every mLink bulk frame starts with one.Used in: Chapter 12
seat
One client connected to a station, with its operator's name. Several seats can work one station at once.Used in: Chapter 7
SEED
A kind of PRESENCE meaning "I am here; can anyone hear me?". Sent by a station that has listened for ten minutes and heard nobody; every station that hears it is asked to answer.Used in: Chapter 18
SEED-ACK
The kind of PRESENCE sent in answer to a SEED. It proves to the seeding station that its transmissions are being heard, even if its own receiver hears nothing else.Used in: Chapter 18
segment
One transmission of a long bulk transfer. A transfer longer than 10 frames is sent as segments of at most 10 frames, each after the first opened by a SEG-RTS.Used in: Chapter 16
sender tag (mail tag)
Two bytes at the end of a mail, computed with the author's mailkey, that let the mailserver check who wrote a mail that another station hands in. Not a signature: only the server can check it.Used in: Chapter 25
session
A signed-in client's standing with the daemon, identified by a session number. It carries the role and subscriptions and expires after 30 minutes without a command.Used in: Chapter 30
shortburst
A message of up to 156 bytes sent as up to 16 announce frames in one transmission, behind PRESENCE and a shortburst RTS. Frame 0 carries the message length and the check.Used in: Chapter 2, Chapter 14, Chapter 15, Chapter 27
simulated air (fake over the air, fOTA)
mLink's test harness: real station programs connected through a channel mixer instead of radios, so a test controls every path, the noise and the interference, and keeps an exact record of what was on the air.Used in: Chapter 4
slot (roll call)
The 1.2 seconds of a roll call that belong to one member number. The length is a constant every station knows, so it is carried on no frame, and a member keys its check-in exactly at the start of its own slot.Used in: Chapter 22
SNR (signal-to-noise ratio)
How strong a received signal is compared with the noise around it, usually in decibels. Meaningless without a stated noise bandwidth; mLink always uses 3 kHz (SNR@3k).Used in: Chapter 3
SNR@3k
Signal-to-noise ratio measured against the noise in a 3,000 Hz SSB bandwidth. Every SNR figure in mLink and in this book uses this one yardstick; it is within 1 dB of the figures FT8-style programs report.Used in: the Preface, Chapter 2, Chapter 3, Chapter 4, Chapter 5, Chapter 9, Chapter 10, Chapter 11, Chapter 13, Chapter 15, Chapter 18, Chapter 19, Chapter 22, Chapter 23, Chapter 24, Chapter 33, Appendix A
SOS beacon
What declaring an emergency starts: the station transmits the emergency frames at once and repeats them on its own schedule until the operator cancels, a new declaration replaces them, or an acknowledgment is heard. It survives a restart.Used in: Chapter 23
SOS mailbox
A reserved mailbox on the mail server that archives every emergency incident deposited by gateway stations. Copies also go to subscribers of the reserved 'sos' mailing list, the dispatchers.Used in: Chapter 23, Chapter 25
SQLite
A widely used database engine that keeps a whole database in one ordinary file. The station daemon keeps all its durable records in one SQLite file.
stand-in
A member that runs a named net as net control while the net's owner is out of earshot, or because the owner asked it to. Its anchors say so. An ordinary stand-in hands the net back as soon as it hears the owner, and the numbers it gave out are provisional.Used in: Chapter 22
standing orders (named net)
One mail addressed to a named net, posted by its owner or its net control, that every member keeps: what members are to know and do for as long as the net runs. Every roster entry names the current copy, and a member that lacks it asks and is handed it by another member.Used in: Chapter 22
station daemon (mlinkd)
The background program that runs an mLink station. It owns the sound card and radio, contains the modems and the protocol, keeps the station's database, and makes every on-air decision. Clients connect to it; it runs whether or not any client is open.Used in: Chapter 1, Chapter 2, Chapter 5, Chapter 29
station manager
The daemon's record keeper: the part that stores and retrieves everything in the station database. It never acts on anything itself.Used in: Chapter 29
station password
The one password every station has. With no accounts it opens the station with full control; once accounts exist it only admits walk-up guests, and only if the administrator allows them. On a new station it is mLink.Used in: Chapter 7
stream
A named feed of live updates the daemon publishes, such as mail or stations. A client subscribes by name and is sent an event whenever there is news.Used in: Chapter 30
synchronising sweep (chirp)
The 0.32 s tone that glides from 125 to 175 Hz at the start of every emergency frame. Receivers search for it to find where a frame begins; no emergency data can imitate it.Used in: Chapter 10
tactical overlay
The shared set of map objects (points, circles, lines, areas, bearing lines) that stations send to each other so every map shows the same operational picture.Used in: Chapter 5, Chapter 28
TALLY
Net control's frame at the end of a roll call saying which member numbers were not accounted for. It comes in four kinds (a list of the missing, a list of the heard, and two maps of one bit per number) and net control sends whichever says it in the fewest frames. A final TALLY ends the roll call.Used in: Chapter 22
Tanner graph
A picture of an LDPC code with bits as circles, checks as squares and a line wherever a check includes a bit. The decoder passes messages along these lines.Used in: Chapter 9
temporal binding
Crediting a frame that carries no callsign to the station whose PRESENCE was heard just before it on the same channel, or, for bulk frames, through the timing set up by the RTS that announced them.Used in: Chapter 14
tentative detection
The receiver's note that a preamble has been found on a channel: where it starts, how well it scored and, for announce frames, its phase. It is held, and may be replaced by a better-aligned one, until the whole frame has been recorded and can be handed to a decoder. Each channel has room for one.Used in: Chapter 13
thread
One independent line of work inside a running program. The station daemon gives each slow or time-critical job its own thread so none can hold up the others.
toast
A short pop-up message in the client that appears just above the taskbar and fades after a few seconds. Clicking dismisses it; a toast marked with a small arrow also opens the applet it concerns.Used in: Chapter 5
tombstone (map object)
A short record that withdraws a map object: it names the object's number, and every station that receives it deletes its copy.Used in: Chapter 28
transmission
One push-to-talk turn: the radio keys, a chain of frames goes out back to back, and the radio unkeys. The unit the mLink protocol reasons about.Used in: Chapter 2, Chapter 14
transmission policy
The ordered rule table a station uses to choose shortburst, longburst, bulk or 'unsupported' for each message, from its size, the link estimate to the addressee, whether it is a broadcast, and whether the bulk region is reserved.
tray
The right-hand end of the client's taskbar: four status icons (link to the daemon, what the station is doing, messages, emergency), the identity cell and the UTC clock, plus an Abort button while something is queued or on the air. In the phone layout the icons sit in the top bar.Used in: Chapter 5
turnaround
The 150 ms an addressee adds, on top of half a second of settling time after the computed end of the sender's transmission, before it keys its reply, so that the sender is listening again.Used in: Chapter 16
type byte
The first byte of an announce frame. Its high four bits name the frame family and its low four bits the subtype within that family.Used in: Chapter 14
UDP (user datagram protocol)
A basic internet protocol that sends self-contained packets (datagrams) with no connection to set up. Client and daemon talk in UDP datagrams.Used in: Chapter 30
USB (upper sideband)
The SSB mode in which an audio tone of f Hz is transmitted f Hz above the dial frequency. mLink runs on upper sideband, in the radio's data mode where it has one.Used in: Chapter 3
virtual net (named net)
An optional net on an mLink channel, opened by an operator under a name of up to eight characters, with an owner, a net control, a roster of numbered members and roll calls. Stations outside it work exactly as they do without one.Used in: Chapter 22
VOX (voice-operated switch)
Keying the transmitter automatically when audio arrives. Slow to react, so a station declared as VOX-keyed sends a short leader tone before each transmission.Used in: Chapter 3, Chapter 4, Chapter 29
VOX leader
A tone the station sends before every transmission when the radio is keyed by VOX, so the transmitter is fully keyed and the far receiver open before the first frame. 800 ms by default.Used in: Chapter 4, Chapter 8
walk-up guest
Someone who signs in to a station that has accounts using the station password and a name that is not an account. A guest gets the operator role, and only while the administrator allows guests.Used in: Chapter 7
warm standby
A second copy of the mailserver that keeps pulling a fresh copy of the primary's database and refuses normal requests until an operator promotes it by restarting it as a primary.Used in: Chapter 25
waterfall (cliff)
The steep curve of decode success against SNR typical of long codes: over about two decibels a bulk frame goes from never decoding to almost always.Used in: Chapter 9
WebAssembly
A format that lets compiled programs run inside a web page. The mLink web client is the desktop client built this way.
WebSocket
A standard two-way message connection that a web browser can open to a server. Browsers reach the station daemon through one.
WebSocket bridge
A small separate program, started by the daemon, that relays between browsers' WebSocket connections and the daemon's UDP interface, and serves the web client's files.Used in: Chapter 4, Chapter 30
zstd (Zstandard)
An openly published, general-purpose lossless compression algorithm. mLink compresses every message with it whenever that makes the message strictly smaller.Used in: Chapter 21
Appendix E

Further Reading

E.1 Signals and modems

T. M. Schmidl and D. C. Cox, "Robust Frequency and Timing Synchronization for OFDM," IEEE Transactions on Communications, vol. 45, no. 12, December 1997.
The preamble trick mLink's bulk receiver uses to find the start of every OFDM frame: a symbol whose two halves are identical, so the receiver can spot it by comparing the signal with a delayed copy of itself. Goes with and .
J. G. Proakis and M. Salehi, Digital Communications, 5th edition, McGraw-Hill, 2008.
The standard graduate textbook. It covers FSK, PSK, pulse shaping, OFDM, fading channels and coding under one roof. If one of the modem chapters left you wanting the equations, look here first. Goes with , Chapter 11, Chapter 12 and .

E.2 Error-correcting codes

I. S. Reed and G. Solomon, "Polynomial Codes Over Certain Finite Fields," Journal of the Society for Industrial and Applied Mathematics, vol. 8, no. 2, pp. 300–304, 1960.
The short paper that introduced Reed–Solomon codes. mLink protects every emergency and announce frame with one (23 bytes carrying 11). Goes with Section 9.3.
R. G. Gallager, Low-Density Parity-Check Codes, MIT Press, 1963.
The book of Gallager's doctoral thesis, where LDPC codes and iterative decoding were first described. It was largely forgotten for thirty years because the computers of the day couldn't decode them. mLink's bulk frames each carry one LDPC codeword. Goes with Chapter 9.
D. J. C. MacKay, "Good Error-Correcting Codes Based on Very Sparse Matrices," IEEE Transactions on Information Theory, vol. 45, no. 2, March 1999; and Information Theory, Inference, and Learning Algorithms, Cambridge University Press, 2003.
MacKay's rediscovery of LDPC codes showed they come close to the Shannon limit, which is where the steep "waterfall cliff" in bulk decoding comes from. His book is readable, and the author has made it free to read online. Its chapters on message passing are the gentlest introduction to how an LDPC decoder thinks. Goes with Section 9.4.4.
T. J. Richardson and R. L. Urbanke, "Efficient Encoding of Low-Density Parity-Check Codes," IEEE Transactions on Information Theory, vol. 47, no. 2, February 2001.
How to encode an LDPC code quickly, without the heavy matrix arithmetic the straightforward method needs. It's the practical half of the story that makes long codewords like mLink's 9,720-bit one cheap to produce, and it is the method mLink's bulk encoder uses. Goes with .

E.3 Sharing a channel

IEEE Std 802.11, Wireless LAN Medium Access Control (MAC) and Physical Layer (PHY) Specifications (any edition; for example 802.11-2020).
The Wi-Fi standard. Its distributed coordination function (DCF) is the best-known example of listen-before-talk with random back-off, and its network allocation vector (NAV) is the same idea as mLink's defer: a station that hears a reservation stays quiet for the time it announces. mLink borrows the idea, not the frame formats. Goes with .

E.4 Inside a payload

Y. Collet and M. Kucherawy, Zstandard Compression and the 'application/zstd' Media Type, RFC 8878, 2021; and the reference implementation at facebook.github.io/zstd.
The compression mLink applies to a message before it goes on the air, including a pre-trained dictionary so that even short texts shrink. Goes with Section 21.4.

E.5 Rules and the neighbours

U.S. Code of Federal Regulations, Title 47, Part 97: Amateur Radio Service; in particular §97.113 (prohibited transmissions) and §97.119 (station identification).
The rules every U.S. mLink station operates under. §97.119 is the identification rule that the callsign at the front of a transmission satisfies. §97.113 bears on how encryption and message content are handled. Operators elsewhere should read their own administration's equivalent. Goes with Section 14.8 and Section 26.1.
Winlink Global Radio Email documentation (winlink.org).
The established amateur radio email system, and the obvious thing to compare mLink with. Reading how Winlink stations connect to gateways and pass mail makes it clearer what mLink does differently: a shared channel instead of connected sessions, and mail that can move between stations without a gateway. Goes with Chapter 1, and .