Published document · Markdown source · part of the specifications index. Experimental drafts can change section numbers; archived revisions are linked from the specifications index.

Protocol compatibility #

Compatibility contract: the pinned fldigi implementation (v4.1.23, 61b97f41…) and the published FSQ documentation by ZL1BPU/ZL2AFP.

Key reference facts (from the Gate 0 audit):

Directed-command reference (from the pinned fldigi implementation) #

Semantics verified against the parse_* bodies in the vendored fsq.cxx. Wire form: DEST<trigger>[args], sent inside a directed frame.

TriggerWire exampleMeaningRemote behavior (fldigi)
(space)w4ijg helloChat textDisplays the message
?w4ijg?Signal reportReplies snr=<estimate>
$w4ijg$Heard-list queryReplies Heard: + its heard list (multi-line)
@w4ijg@Location queryReplies with its QTH text
&w4ijg&Station-message queryReplies with its QTC text
^w4ijg^Version queryReplies fldigi <version>
*w4ijg*Wake stationEnables its monitor (SELCAL) and acks; works even when "asleep"
!w4ijg! textRepeatEchoes the text to everyone immediately, undirected (call:XX text, two spaces). OpenJSQ 1.0.7 matches byte for byte when text follows ("repeat my message", JSQ_PUBLIC_PROTOCOL_SPEC.md §79.7), when the operator allows it; with no text it repeats its own last transmission to the requester (§79). fldigi reads the first word of the echoed text as an address (it strips the spaces), so text such as allcall#[f]x would be obeyed by every fldigi station: OpenJSQ refuses to echo it ("not repeating commands"); fldigi echoes it
~w4ijg~ textDelayed repeatEchoes the text to everyone after 15 s. OpenJSQ 1.0.7 matches when text follows (§79.7); ~30 (a bare number) repeats its last transmission after that delay (§79.4). OpenJSQ's own ~{N}text delay form is sent only to stations whose capability record says they repeat for others, never to fldigi
#w4ijg#[name.txt]textStore message/fileWrites text to name.txt (default <sender>.txt), acks
+w4ijg+[name.txt]Read message/fileSends the stored file's contents back
|w4ijg|textAlertPops an alert dialog with the text
>w4ijg>FasterSteps its FSQ speed up one notch, confirms new baud
<w4ijg<SlowerSteps its FSQ speed down one notch, confirms
;via;dest textRelayvia retransmits to dest, inserting [origin]
[dest[origin] textRelayed markerMarks traffic relayed from origin; relayed queries answered via the relay path
%w4ijg%SImage transferStarts image RX (mode letter selects size) — OpenJSQ parses the trigger and answers nothing; no image service is transmitted by this release
=w4ijg= hello, w4ijg=?Local only, do not relay (OpenJSQ, JSQ_PUBLIC_PROTOCOL_SPEC.md §56.4)fldigi has no dispatch for =: it does not reply and shows the text, including the displaced trigger as the body's first character. The frame stays DIRECTED because = is in OpenJSQ's trigger set (is_trigger, transports/fsq_legacy/src/fsq_legacy.cpp), so the header walk stops on it and the destination and sender CRC are intact
-—UnsupportedNothing: fldigi 4.1.23's case '-' is break;//parse_minus();, so the frame is dropped without a reply. OpenJSQ never sends - as a trigger; since 1.0.7 a -1..-15 after a plain callsign is part of the address (below)

= is an OpenJSQ addition, not an fldigi mapping: nothing in the pinned implementation emits it and nothing there answers it. It is the one character in OpenJSQ's trigger set that was both free and safe — { is taken by the wide-mode structured envelopes, \ is not in the set at all (it would be absorbed into the destination and turn the frame undirected), and - is now part of call-n addresses (below). The real trigger is displaced one position into the body, and a receiver un-displaces it before applying any rule in this table.

allcall frames only honor space, *, #, %, [ (no query amplification storms). OpenJSQ mirrors this table in DirectedCommand and the session's compose logic; every mapping is unit-tested.

SSID-style names, call-n (OpenJSQ 1.0.7) #

OpenJSQ reads w4ijg-7 hi as chat to the one station W4IJG-7 when the text before the - is a plain callsign of 3 to 6 letters and digits, the number is 1 to 15 with no leading zero, and a trigger, a space or the end of the frame follows it. Everything else - a / call, allcall, cqcqcq, a group, -0, -01, -16, -1x - splits at the - exactly as fldigi splits it. A plain callsign or a /suffix behaves exactly as before. The rule and the CRC-16 tie-break are JSQ_TRANSPORT_SERVICE_SPEC.md §33.1.1.

What the pinned fldigi (4.1.23) does with these names, from fsq.cxx and from the round trips in third_party/fldigi-fsq/tests/test_fsq_roundtrip.cpp:

Unverified with FSQCall.

Forms (ICS-213 and similar) #

Forms are structured text riding the existing transports: transmitted as a directed message or stored at the remote station via #[formfile]. The serialized layout (field labels + values, flmsg-compatible where feasible) is a UX/application-layer concern — see DESKTOP_UX.md. No modem or protocol changes are required to carry forms.

This document grows into the full field-by-field compatibility spec as the fixture corpus expands. Fixture expectations are the ground truth; do not silently update them (see CONTRIBUTING.md).