Skip to content

Latest commit

 

History

History
564 lines (391 loc) · 17 KB

File metadata and controls

564 lines (391 loc) · 17 KB

Mercury TNC Command Reference

Mercury exposes a VARA-compatible TCP TNC interface for client applications. Two TCP ports are used:

Port Default Purpose
Control port 8300 Text commands and asynchronous status lines
Data port 8301 Raw application data (binary payload)
Broadcast port 8100 KISS-framed broadcast frames (separate)

The control and data ports are base_port and base_port + 1 respectively; override with -p <base_port>. The broadcast port is independent; override with -b <port>.

All control commands and responses are CR-terminated ASCII (\r).


Commands (Client → Mercury)

Commands are sent on the control port.

MYCALL

Set the local station callsign and optional secondary callsigns.

MYCALL <callsign> [<secondary1> <secondary2> ...]\r

Response: OK\r on success, WRONG\r on error. After OK, an asynchronous REGISTERED <callsign>\r notification confirms the callsign is recognised (VARA compatibility).

The first token is the primary callsign (up to 15 characters), used as the source address for outgoing CALL and ACCEPT frames. Any additional space-separated tokens are registered as secondary callsigns — Mercury will accept incoming CALL frames addressed to any of them, up to a maximum of CALLSIGN_MAX_SECONDARY (currently 4) secondary callsigns.

Sending a new MYCALL command replaces the primary callsign and clears all previously registered secondary callsigns.

Must be set before LISTEN ON or CONNECT.

Examples:

MYCALL VK2XYZ\r
MYCALL VK2XYZ VK2XYZ-1 VK2XYZ-2\r

LISTEN

Enable or disable listening for incoming ARQ connections.

LISTEN ON\r
LISTEN OFF\r
LISTEN CQ\r

Response: OK\r on success, WRONG\r on error.

When enabled, Mercury enters the LISTENING state and will accept incoming CALL frames addressed to the local callsign (or any callsign if PUBLIC is ON).

LISTEN CQ is treated as LISTEN ON (VarAC compatibility).


PUBLIC

Accept calls addressed to any callsign (promiscuous mode).

PUBLIC ON\r
PUBLIC OFF\r

Response: OK\r on success, WRONG\r on error.

Default is OFF. When ON, Mercury accepts incoming CALL frames regardless of the destination callsign.


BW (Bandwidth)

Set the maximum ARQ bandwidth.

BW2300\r
BW500\r
BW2750\r

Response: OK\r on success, WRONG\r on error.

  • BW2300 — Full bandwidth. Allows gear-shifting up to DATAC1 (510 bytes/frame).
  • BW500 — Narrow bandwidth. Restricts the maximum payload mode to DATAC3/DATAC4.
  • BW2750 — Tactical mode token accepted for VARA compatibility. Mercury currently uses the same payload-mode ceiling as BW2300, but preserves 2750 as a negotiated/reporting token.

During connection setup, Mercury advertises the local BW token in CALL and returns the negotiated token in ACCEPT. If either side is BW500, the session stays at 500 on both ends. If both sides are wide, the session keeps the lower wide token (2300 or 2750) and CONNECTED ... BW reports that negotiated value.


COMPRESSION

No-op for VARA client compatibility.

COMPRESSION ON\r
COMPRESSION OFF\r

Response: OK\r (always).

Mercury does not use compression; this command exists so VARA-compatible clients (e.g., Pat, VarAC) can connect without errors.


CHAT

Enable chat-optimized mode (VARA compatibility).

CHAT ON\r
CHAT OFF\r

Response: OK\r on success, WRONG\r on error.

CHAT ON implicitly enables LISTEN ON, placing Mercury in the LISTENING state. This matches VARA behavior where chat applications (VarAC, VARA Chat) expect the modem to be ready for incoming connections after CHAT ON.

CHAT OFF is acknowledged but has no effect — Mercury does not currently differentiate chat and file-transfer timing.


P2P

No-op for VARA client compatibility.

P2P\r

Response: OK\r (always).


CONNECT

Initiate an ARQ connection to a remote station.

CONNECT <mycall> <theircall>\r

Response: OK\r if the command was accepted, WRONG\r on error.

Mercury will transmit CALL frames on DATAC13, advertising the local BW token, and wait for an ACCEPT carrying the negotiated session BW. On success, the asynchronous response CONNECTED <sourcecall> <destcall> <bandwidth>\r is sent on the control port, preserving the same call order as the original CONNECT command on both peers.

Example:

CONNECT AAAA BBBB\r

CQFRAME

Transmit a compact DATAC13 CQ frame.

CQFRAME <sourcecall> <bandwidth>\r

<bandwidth> must be one of 500, 2300, or 2750.

Response: OK\r if the command was accepted, WRONG\r on error.

For VARA compatibility, Mercury also emits PENDING\r when the CQ frame starts transmitting and CANCELPENDING\r once that CQ transmission is done.


DISCONNECT

Terminate the current ARQ session.

DISCONNECT\r

Response: OK\r if the command was accepted, WRONG\r on error.

Mercury sends DISCONNECT frames to the peer. Once complete, the asynchronous response DISCONNECTED\r is sent on the control port.


ABORT

Dirty disconnect — immediately flush all buffers and terminate the session without air-side teardown. The remote peer will time out.

ABORT\r

Response: OK\r if the command was accepted, WRONG\r on error.

Unlike DISCONNECT, ABORT does not send any over-the-air DISCONNECT frames and clears all pending TX data immediately.


VERSION

Query the modem identification string.

VERSION\r

Response: A VARA-compatible version string on the control port.

This command exists for VARA-compatible clients (e.g., VarAC) that check the modem version at startup.


IGNOREKISSDCD

No-op for VARA client compatibility.

IGNOREKISSDCD\r

Response: OK\r (always).


BUFFER

Query the number of bytes pending in the ARQ transmit buffer.

BUFFER\r

Response: BUFFER <bytes>\r on the control port.


SN

Query the last measured signal-to-noise ratio.

SN\r

Response: SN <value>\r (e.g., SN 8.2\r) on the control port.


BITRATE

Query the current throughput estimate.

BITRATE\r

Response: BITRATE (<speed_level>) <bps> BPS\r on the control port.


RETRIES

Override the amount of retries Mercury will try to connect or retry a transmission before giving up. Setting to 0 should revert to the defined values in datalink_arq/arq_protocol.h.

RETRIES 10\r

CALLINT

Override the interval in whole seconds between successive CALL/ACCEPT frame retries during connection setup. This has no effect on other control frame timing (keepalive, disconnect, turn request) or on data frame retry timing once a session is established.

Send 0 to restore the compiled default (7 seconds). The minimum enforced value is 4 seconds; values below 4 are clamped to 4 to avoid firing a retry before a valid ACCEPT can return over the air.

CALLINT 5\r
CALLINT 0\r

Response: OK\r on success, WRONG\r on error.


TUNE

Key the transmitter and hold a steady 1000 Hz tone, so an antenna tuner can find a match — and so an operator has a known reference to set drive against. Same syntax as VARA HF / VARA SAT.

TUNE -15\r      key TX, tone at -15 dBFS
TUNE ?\r        report the current drive level
TUNE OFF\r      stop the tone and unkey

The level is absolute dBFS at the sound card, in the range -60 to 0. It deliberately does not pass through the modulator TX gain (tx_gain): TUNE -15 means −15 dBFS, not −15 dBFS scaled by whatever the modulator gain happens to be — otherwise it would be useless as a reference for setting that very gain.

Re-issuing TUNE <level> while a carrier is already running changes the level and restarts the safety timer, which is what adjusting drive on a live tuner requires.

The carrier always stops by itself after 60 seconds. A tuning carrier is the one transmission with no protocol underneath it, so nothing else bounds it: a host that crashes, forgets TUNE OFF, or simply drops the control socket would otherwise leave the radio keyed — cooking the finals and jamming the channel. Do not rely on the timer for normal operation; send TUNE OFF when the tuner is done.

TUNE is refused (WRONG\r) when:

  • the level is outside -60 .. 0 dBFS, or is not a number;
  • an ARQ link is currently connected, or a burst is in flight — a tuning carrier and a data burst must never key the radio at the same time.

While the carrier is up, ARQ transmissions are suppressed; TUNE OFF (or the timer) restores normal operation. The usual PTT ON\r / PTT OFF\r asynchronous lines bracket the carrier exactly as they do a data burst.

Response: OK\r on success, WRONG\r on error. TUNE ? replies TUNE <level>\r (for example TUNE -15\r).


Asynchronous Responses (Mercury → Client)

These are sent on the control port without a preceding command.

Response Meaning
PENDING\r Incoming connect request or outgoing CQ TX started
CANCELPENDING\r Pending incoming connect cancelled or outgoing CQ TX completed
CONNECTED <sourcecall> <destcall> <bandwidth>\r ARQ session established
CQFRAME <sourcecall> <bandwidth>\r Compact CQ frame decoded
DISCONNECTED\r ARQ session ended
PTT ON\r Radio transmitter keyed
PTT OFF\r Radio transmitter unkeyed
BUFFER <bytes>\r TX buffer level update (periodic)
SN <value>\r SNR update
BUSY ON\r Channel became occupied (busy detector)
BUSY OFF\r Channel became clear (busy detector)
BITRATE (<level>) <bps> BPS\r Throughput update
IAMALIVE\r Heartbeat (sent periodically while idle)
REGISTERED <callsign>\r Callsign registration confirmed (after MYCALL)

PENDING

Sent when Mercury detects an incoming ARQ connect request addressed to the local station. This is an early warning so VARA-compatible host applications can suspend scanning or other idle activity while the link setup is in progress.

Mercury also sends PENDING\r when an outgoing CQFRAME actually begins transmitting so VARA clients can treat CQ send as an in-progress operation.

CANCELPENDING

Sent when a previously pending incoming connect request does not complete and Mercury returns to the idle/listening state.

Mercury also sends CANCELPENDING\r when an outgoing CQFRAME transmission finishes, which matches the lifecycle expected by VARA clients such as varim.

CONNECTED

Sent when a session is successfully established (either outgoing CONNECT or incoming CALL accepted). The <bandwidth> value is the negotiated session BW token from the CALL / ACCEPT exchange (500, 2300, or 2750). If either peer is BW500, both sides report 500. If both peers stay wide, Mercury reports the lower of the two wide tokens, preserving 2750 only when both sides advertised it. <sourcecall> is always the station that initiated the session, and <destcall> is always the station that was called.

CQFRAME

Sent when Mercury decodes a compact DATAC13 CQ frame on the air. <sourcecall> is the transmitting station and <bandwidth> is the BW token advertised inside that CQ frame (500, 2300, or 2750).

BUSY ON / BUSY OFF

Emitted by the optional channel-busy (occupancy) detector when it observes the HF channel transition between clear and occupied, using VARA's exact wording so existing VARA-compatible hosts (VarAC, BPQ32, Winlink) act on them unchanged. Edge-triggered: BUSY ON\r on clear→busy, BUSY OFF\r on busy→clear.

The detector is enabled by default and can be turned off via the [channel] section of mercury.ini (busy_detect = false); its sensitivity/timing knobs (busy_threshold_db, busy_hysteresis_db, busy_on_debounce_ms, busy_hang_ms) typically need on-air tuning per band/noise environment. When disabled, these notifications are never sent. See mercury.ini.example.

BUSY ON is the earliest notification a host can act on: it follows the carrier by roughly the debounce time (~0.3 s by default), whereas PENDING cannot be sent until a whole connect request has decoded — 3.74 s in the DATAC16 control mode. A host that scans channels needs the former to hold its dwell long enough to receive the latter.

DISCONNECTED

Sent when the session ends, either by local DISCONNECT, remote DISCONNECT, or timeout.

BUFFER

Sent periodically during data transfer. The value reflects the number of application bytes still queued for transmission. When it reaches 0, all data has been acknowledged by the peer.

IAMALIVE

Sent periodically on the control port as a keepalive to detect broken TCP connections.

REGISTERED

Sent when a callsign is set via MYCALL, confirming the callsign is licensed (VARA compatibility). Arrives after the OK\r response to MYCALL. Also sent on client reconnect if a callsign is already set.

REGISTERED is per call sign, so MYCALL emits one line for the primary and one for each secondary it accepted, in the order given:

MYCALL AAAA BBBB CCCC\r
OK\r
REGISTERED AAAA\r
REGISTERED BBBB\r
REGISTERED CCCC\r

Secondaries beyond the four Mercury can hold are dropped, and dropped ones are not acknowledged — the host would otherwise address a callsign this station never answers.


Data Port

The data port (base_port + 1, default 8301) carries raw application payload. Bytes written to the data port are queued for ARQ transmission; bytes received from the remote station are delivered on the data port.

No framing is needed — Mercury handles segmentation internally. The data port only carries payload when a session is CONNECTED.


Broadcast Port

The broadcast port (default 8100) is independent of ARQ and uses KISS framing. One-way broadcast frames are sent/received as fixed-size KISS-encoded packets matching the modem's payload size.

Three client framings are accepted, distinguished by the KISS command byte:

  • 0x00 (standard KISS data / VARA "AX.25 standard") and 0x01 (VARA "AX.25 7-char callsign", used by VarAC): Mercury injects its 1-byte broadcast header plus a 2-byte payload-length prefix, zero-pads to the modem frame size, and records which of the two framings the sender used in a header extension bit (BCAST_EXT_KISS_STD). The receiving side delivers exactly the original payload with the sender's command byte — so VarAC↔VarAC traffic stays 0x01 and standard-KISS clients (e.g. Reticulum, see RETICULUM.md) get 0x00.
  • 0x02 (CMD_DATA, used by hermes-broadcast): the frame is passed raw — the client supplies its own broadcast header, and receivers with a CMD_DATA client get the full unmodified frame back.

Payloads larger than the modem frame (minus 3 bytes of header+length) are truncated (0x00/0x01) or discarded (0x02) — the broadcast plane does not fragment.


Typical Session Flow

Client                          Mercury
  |                                |
  |--- (TCP connect to 8300) ---->|
  |--- (TCP connect to 8301) ---->|
  |                                |
  |--- MYCALL AAAA\r ------------>|
  |<-- OK\r ----------------------|
  |<-- REGISTERED AAAA\r ---------|
  |                                |
  |--- LISTEN ON\r -------------->|
  |<-- OK\r ----------------------|
  |                                |
  |--- BW2300\r ------------------>|
  |<-- OK\r ----------------------|
  |                                |
  |--- CONNECT AAAA BBBB\r ------>|
  |<-- OK\r ----------------------|
  |                                |  (RF: CALL/ACCEPT exchange)
  |<-- CONNECTED AAAA BBBB 2300\r |
  |                                |
  |--- (write data to 8301) ----->|  (RF: DATA frames)
  |<-- BUFFER 2404\r -------------|
  |<-- PTT ON\r ------------------|
  |<-- PTT OFF\r ------------------|
  |<-- BUFFER 0\r ----------------|
  |                                |
  |<-- (read data from 8301) -----|  (received from remote)
  |                                |
  |--- DISCONNECT\r -------------->|
  |<-- OK\r ----------------------|
  |<-- DISCONNECTED\r ------------|

See Also