Also known as: LSF, LICH, link setup frame, link information channel
M17 Link Information is the metadata layer of the M17 digital voice/data protocol — an open, Codec2-based amateur mode developed by the M17 Project.1 It answers “who is transmitting to whom, in what mode” through the Link Setup Frame (LSF): source and destination addresses, a TYPE field, and a META block. The LSF travels two ways — as a dedicated frame at the head of a transmission, and, crucially, as the LICH (Link Information CHannel) embedded in every stream frame — so a receiver that tunes in mid-transmission still recovers the link metadata within about a quarter-second.
Link Setup Frame
The LSF is 240 bits (30 bytes) packed MSB-first:
| Field | Bits | Meaning |
|---|---|---|
| DST | 48 | Destination address (base-40 callsign, BROADCAST, or reserved) |
| SRC | 48 | Source address |
| TYPE | 16 | Mode/type flags — stream vs packet, data mode, CAN |
| META | 112 | 14-byte META block (nonce / GNSS / extended callsign) |
| CRC | 16 | CRC-16 over DST…META |
The TYPE field is bit-packed: bit 0 selects stream vs packet mode; bits 1–2 give the data mode (1 = data, 2 = voice, 3 = voice + data); and bits 7–10 hold the CAN (Channel Access Number). The trailing CRC-16 uses polynomial 0x5935, initial value 0xFFFF, MSB-first, no final XOR — a bad CRC leaves the fields populated for display but flags the decode as unverified.
Base-40 addresses
M17 encodes a callsign into a 48-bit integer using a base-40 codec (there is no separate
alphabet page — the whole scheme is this: an index-0..39 alphabet
" ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-/.", where index 0 is the blank/terminator and the
rest are the callsign characters). Decoding repeatedly takes addr % 40 as the next character
and divides by 40, then reverses the result. Three address values are special: all-ones
(0xFFFFFFFFFFFF) decodes to BROADCAST; zero is the reserved empty address; and any value
above 40⁹ (0xEE6B28000000) is not a base-40 callsign and reads as #RESERVED. Because the
codec is reversible and compact, a 9-character callsign fits in the 48-bit address field with
room to spare.
LICH mechanism
A receiver joining mid-transmission cannot wait for the next LSF frame, so M17 also carries the LSF inside every stream frame’s LICH. Each stream frame’s 96-bit LICH is four Golay(24,12) codewords — 96 coded bits protecting a 48-bit chunk. That chunk’s top 40 bits are one-sixth of the LSF, and a 3-bit counter names its position. Six consecutive chunks (one per stream frame, spanning six frames) reassemble the full 240-bit LSF, at which point its CRC is checked. Any LICH with an uncorrectable Golay codeword is dropped, and the assembler simply waits for that chunk to repeat on the next pass — a form of forward error correction plus temporal redundancy that lets link metadata survive a marginal 4-FSK channel.
In practice
M17 frames open with a 16-bit sync word that also names the frame type: 0x55F7 for the dedicated LSF frame, 0xFF5D for a stream (voice/data) frame, and 0x75FF for a packet frame. GopherTrunk implements the LICH route (Golay only, no convolutional machinery), so it recovers link metadata without decoding the Codec2 audio. The Golay generator and field parse are validated end-to-end against a synthetic encoder; the exact Golay matrix of real M17 traffic is flagged as best-effort pending confirmation against a live capture.
Relevance to SDR
internal/radio/m17/m17.go holds the LSF parse, the base-40 address codec, and the CRC-16
(ParseLSF, DecodeAddress, CRC16); lich.go holds the LICH reassembler that Golay-decodes
the four codewords per frame and stitches the six chunks into an LSF. Together they let
GopherTrunk surface an M17 transmission’s source, destination, and mode on the bus as soon as
six stream frames have passed.
Sources
-
M17 Protocol Specification — the M17 Project’s data-link layer reference for the LSF, LICH, base-40 codec, and sync words. ↩