mercury - Initial refactoring for the Mercury plug-and-play support in EmComm Tools. Moved to a model where ARQ, broadcast, and user-defined mode are the only options

This commit is contained in:
thetechprepper
2026-08-26 10:11:40 -07:00
parent 77fa9e7c0d
commit 486c284fe4
4 changed files with 502 additions and 37 deletions
@@ -0,0 +1,159 @@
; Author : Gaston Gonzalez
; Date : 26 August 2026
; Purpose : Mercury ARQ configration for EmComm Tools
[main]
ui_enabled = false
ui_port = 10000
ui_protocol = ws
waterfall_enabled = false
; Use hamlib rig control over the local network
radio_model = 2
radio_device = 127.0.0.1:4532
radio_serial_speed = 0
; Plug-and-play audio support
; Note: input|output_device are set by et-mercury
;input_device =
;output_device =
capture_channel = left
sound_system = alsa
; Keep same TCP control and data ports for VARA HF compatibility
arq_tcp_base_port = 8300
broadcast_tcp_port = 8100
; Logging
verbose = false
; FreeDV modem verbosity level, 0 to 3 (default: 0)
freedv_verbosity = 0
; Hamlib radio log level, 0 to 6 (default: 0)
; 0=NONE, 1=BUG, 2=ERR, 3=WARN, 4=VERBOSE, 5=TRACE, 6=CACHE
hamlib_log_level = 0
[audio]
; TX audio gain in dB applied to modulator output samples (default: 0.0).
; 0.0 dB = no change. Use this to set Mercury's TX level independently
; of the host audio mixer, so other modems sharing the radio aren't
; disturbed when you tune Mercury's drive. Saturation is applied at the
; int32 PCM ceiling so any value clips cleanly.
; Range: -20.0 .. +20.0 (values outside are clamped).
tx_gain_db = 0.0
; TX keying delay in milliseconds (default: 10), waited after PTT ON before
; audio is written to the playback device on TX. The default covers the
; local radio relay's switch time. Increase this if your host app drives
; PTT off Mercury's "PTT ON" TNC notification and needs more time to
; actually key the radio (e.g. a slow serial/CAT relay) — otherwise the
; start of the transmission can be clipped before the radio is keyed.
; Range: 0 .. 2000 (values outside are clamped).
tx_delay_ms = 10
[arq]
; ARQ link no-progress disconnect budget (seconds, default: 180).
; When data-retry slots exhaust on a frame, Mercury no longer disconnects
; immediately — it resets the retry counter and forces a payload-mode
; downgrade. The link only drops when wall-clock since the last ACK that
; advanced the sequence number exceeds this budget, OR when the keepalive
; miss limit is reached (5 * 20s = 100s by default). 180s sits just above
; the keepalive timeout as a safety net for the asymmetric case where peer
; keepalives still arrive but our TX direction has gone one-way. Raise
; this for ultra-marginal NVIS work where forward progress can take longer.
no_progress_timeout_s = 180
; Absolute cap (seconds, default: 30) on how long an application DISCONNECT
; may stay deferred while Mercury drains the last queued TX bytes. When the
; host (e.g. BPQ32) ends a BBS forwarding session, Mercury finishes sending
; any buffered data, then completes a clean air-side DISCONNECT handshake.
; This cap guarantees the link always tears down within the window even if
; the session is stuck ping-ponging — preventing the rig from being keyed
; indefinitely after the host has already disconnected. On a healthy link
; the drain finishes in seconds, so this only bites on a stuck session.
disconnect_drain_timeout_s = 30
; Number of DATA-frame retries before a downgrade cycle (default 10, range 1..64).
; Affects the data plane only; connection-setup (CALL/ACCEPT) retries keep their
; short defaults so a failed connect gives up quickly. Use the RETRIES TNC
; command at runtime to widen CALL/ACCEPT/DATA retries together.
data_retry_slots = 10
; Seconds to hold the lower mode after a forced downgrade (default 6, range 0..60).
mode_hold_after_downgrade_s = 6
; Clean ACKs required to step the speed ladder up one level (default 2, range 1..16).
ladder_up_successes = 2
; Consecutive retries that force a one-step downgrade (default 2, range 1..16).
retry_downgrade_threshold = 2
; IRS response guard after decoding a frame, in ms (default 700, range 200..3000).
; Raise if your radio's TX-to-RX switch is slow and you lose ACKs.
channel_guard_ms = 700
; ISS guard before resuming DATA TX after an ACK, in ms (default 900, range 200..3000).
iss_post_ack_guard_ms = 900
; Keepalive transmit interval in seconds (default 20, range 5..120).
keepalive_interval_s = 20
; Missed keepalives before the link is dropped (default 5, range 2..20).
keepalive_miss_limit = 5
; Seconds to hold the peer's payload mode after activity before reverting
; (default 15, range 1..120). Reduce (e.g. 8-10) if you see long gaps between
; turns; this also scales the IRS inactivity probe (hold x 5).
peer_payload_hold_s = 8
; Control-mode-only startup window in seconds (default 10, range 2..60).
; Only DATAC16 is used until the link is proven stable; raise if the initial
; handshake (e.g. UUCP) times out before the first data frames get through.
startup_max_s = 10
[channel]
; Channel-busy (occupancy) detector. Mercury classifies the HF channel as
; busy/clear from the RX spectrum and reports transitions to the host with
; VARA-compatible "BUSY ON" / "BUSY OFF" notifications on the control port.
;
; OFF by default, deliberately. Mercury itself never gates transmission on it,
; but the hosts that consume these notifications do: BPQ32 and Winlink hold
; transmissions while BUSY is asserted, so a detector that fires on noise, or on
; a station you are already in QSO with, stops the station transmitting and
; strands traffic in the queue. That is field experience on HF, not theory, and
; it is why VARA ships with busy detection off as well.
;
; Turn it on if you scan: it is then the only early warning a host gets, since
; everything else waits for a full frame to decode (3.7 s for a connect request)
; and a scanning host cannot hold its dwell that long. Expect to tune the
; thresholds below per band and noise environment before trusting it.
busy_detect = false
; Passband peak level, in dB above the tracked noise floor, required to call the
; channel BUSY (default 10, range 3..40). Lower = more sensitive.
busy_threshold_db = 10
; Release hysteresis in dB: the channel is only declared CLEAR once the peak
; falls below (busy_threshold_db - this) (default 3, range 0..20).
busy_hysteresis_db = 3
; Milliseconds the peak must stay above threshold before asserting BUSY
; (debounce against transients; default 300, range 0..5000).
busy_on_debounce_ms = 300
; Milliseconds the peak must stay below the release level before declaring CLEAR
; (hang time; default 1500, range 0..10000).
busy_hang_ms = 1500
[tnc]
; IAMALIVE interval sent on the TNC control port to tell connected clients
; the TNC is still alive. Valid range: 5..600 seconds. (default: 60)
keepalive_s = 60
; Interval between BUFFER reports sent to the TNC control port, telling
; clients how many bytes are queued for TX. Valid range: 100..10000 ms. (default: 1000)
buffer_report_ms = 1000
@@ -0,0 +1,159 @@
; Author : Gaston Gonzalez
; Date : 26 August 2026
; Purpose : Mercury broadcast configration for EmComm Tools
[main]
ui_enabled = false
ui_port = 10000
ui_protocol = ws
waterfall_enabled = false
; Use hamlib rig control over the local network
radio_model = 2
radio_device = 127.0.0.1:4532
radio_serial_speed = 0
; Plug-and-play audio support
; Note: input|output_device are set by et-mercury
;input_device =
;output_device =
capture_channel = left
sound_system = alsa
; Keep same TCP control and data ports for VARA HF compatibility
arq_tcp_base_port = 8300
broadcast_tcp_port = 8100
; Logging
verbose = false
; FreeDV modem verbosity level, 0 to 3 (default: 0)
freedv_verbosity = 0
; Hamlib radio log level, 0 to 6 (default: 0)
; 0=NONE, 1=BUG, 2=ERR, 3=WARN, 4=VERBOSE, 5=TRACE, 6=CACHE
hamlib_log_level = 0
[audio]
; TX audio gain in dB applied to modulator output samples (default: 0.0).
; 0.0 dB = no change. Use this to set Mercury's TX level independently
; of the host audio mixer, so other modems sharing the radio aren't
; disturbed when you tune Mercury's drive. Saturation is applied at the
; int32 PCM ceiling so any value clips cleanly.
; Range: -20.0 .. +20.0 (values outside are clamped).
tx_gain_db = 0.0
; TX keying delay in milliseconds (default: 10), waited after PTT ON before
; audio is written to the playback device on TX. The default covers the
; local radio relay's switch time. Increase this if your host app drives
; PTT off Mercury's "PTT ON" TNC notification and needs more time to
; actually key the radio (e.g. a slow serial/CAT relay) — otherwise the
; start of the transmission can be clipped before the radio is keyed.
; Range: 0 .. 2000 (values outside are clamped).
tx_delay_ms = 10
[arq]
; ARQ link no-progress disconnect budget (seconds, default: 180).
; When data-retry slots exhaust on a frame, Mercury no longer disconnects
; immediately — it resets the retry counter and forces a payload-mode
; downgrade. The link only drops when wall-clock since the last ACK that
; advanced the sequence number exceeds this budget, OR when the keepalive
; miss limit is reached (5 * 20s = 100s by default). 180s sits just above
; the keepalive timeout as a safety net for the asymmetric case where peer
; keepalives still arrive but our TX direction has gone one-way. Raise
; this for ultra-marginal NVIS work where forward progress can take longer.
no_progress_timeout_s = 180
; Absolute cap (seconds, default: 30) on how long an application DISCONNECT
; may stay deferred while Mercury drains the last queued TX bytes. When the
; host (e.g. BPQ32) ends a BBS forwarding session, Mercury finishes sending
; any buffered data, then completes a clean air-side DISCONNECT handshake.
; This cap guarantees the link always tears down within the window even if
; the session is stuck ping-ponging — preventing the rig from being keyed
; indefinitely after the host has already disconnected. On a healthy link
; the drain finishes in seconds, so this only bites on a stuck session.
disconnect_drain_timeout_s = 30
; Number of DATA-frame retries before a downgrade cycle (default 10, range 1..64).
; Affects the data plane only; connection-setup (CALL/ACCEPT) retries keep their
; short defaults so a failed connect gives up quickly. Use the RETRIES TNC
; command at runtime to widen CALL/ACCEPT/DATA retries together.
data_retry_slots = 10
; Seconds to hold the lower mode after a forced downgrade (default 6, range 0..60).
mode_hold_after_downgrade_s = 6
; Clean ACKs required to step the speed ladder up one level (default 2, range 1..16).
ladder_up_successes = 2
; Consecutive retries that force a one-step downgrade (default 2, range 1..16).
retry_downgrade_threshold = 2
; IRS response guard after decoding a frame, in ms (default 700, range 200..3000).
; Raise if your radio's TX-to-RX switch is slow and you lose ACKs.
channel_guard_ms = 700
; ISS guard before resuming DATA TX after an ACK, in ms (default 900, range 200..3000).
iss_post_ack_guard_ms = 900
; Keepalive transmit interval in seconds (default 20, range 5..120).
keepalive_interval_s = 20
; Missed keepalives before the link is dropped (default 5, range 2..20).
keepalive_miss_limit = 5
; Seconds to hold the peer's payload mode after activity before reverting
; (default 15, range 1..120). Reduce (e.g. 8-10) if you see long gaps between
; turns; this also scales the IRS inactivity probe (hold x 5).
peer_payload_hold_s = 8
; Control-mode-only startup window in seconds (default 10, range 2..60).
; Only DATAC16 is used until the link is proven stable; raise if the initial
; handshake (e.g. UUCP) times out before the first data frames get through.
startup_max_s = 10
[channel]
; Channel-busy (occupancy) detector. Mercury classifies the HF channel as
; busy/clear from the RX spectrum and reports transitions to the host with
; VARA-compatible "BUSY ON" / "BUSY OFF" notifications on the control port.
;
; OFF by default, deliberately. Mercury itself never gates transmission on it,
; but the hosts that consume these notifications do: BPQ32 and Winlink hold
; transmissions while BUSY is asserted, so a detector that fires on noise, or on
; a station you are already in QSO with, stops the station transmitting and
; strands traffic in the queue. That is field experience on HF, not theory, and
; it is why VARA ships with busy detection off as well.
;
; Turn it on if you scan: it is then the only early warning a host gets, since
; everything else waits for a full frame to decode (3.7 s for a connect request)
; and a scanning host cannot hold its dwell that long. Expect to tune the
; thresholds below per band and noise environment before trusting it.
busy_detect = false
; Passband peak level, in dB above the tracked noise floor, required to call the
; channel BUSY (default 10, range 3..40). Lower = more sensitive.
busy_threshold_db = 10
; Release hysteresis in dB: the channel is only declared CLEAR once the peak
; falls below (busy_threshold_db - this) (default 3, range 0..20).
busy_hysteresis_db = 3
; Milliseconds the peak must stay above threshold before asserting BUSY
; (debounce against transients; default 300, range 0..5000).
busy_on_debounce_ms = 300
; Milliseconds the peak must stay below the release level before declaring CLEAR
; (hang time; default 1500, range 0..10000).
busy_hang_ms = 1500
[tnc]
; IAMALIVE interval sent on the TNC control port to tell connected clients
; the TNC is still alive. Valid range: 5..600 seconds. (default: 60)
keepalive_s = 60
; Interval between BUFFER reports sent to the TNC control port, telling
; clients how many bytes are queued for TX. Valid range: 100..10000 ms. (default: 1000)
buffer_report_ms = 1000
@@ -0,0 +1,159 @@
; Author : Gaston Gonzalez
; Date : 26 August 2026
; Purpose : Mercury custom configration for EmComm Tools
[main]
ui_enabled = false
ui_port = 10000
ui_protocol = ws
waterfall_enabled = false
; Use hamlib rig control over the local network
radio_model = 2
radio_device = 127.0.0.1:4532
radio_serial_speed = 0
; Plug-and-play audio support
; Note: input|output_device are set by et-mercury
;input_device =
;output_device =
capture_channel = left
sound_system = alsa
; Keep same TCP control and data ports for VARA HF compatibility
arq_tcp_base_port = 8300
broadcast_tcp_port = 8100
; Logging
verbose = false
; FreeDV modem verbosity level, 0 to 3 (default: 0)
freedv_verbosity = 0
; Hamlib radio log level, 0 to 6 (default: 0)
; 0=NONE, 1=BUG, 2=ERR, 3=WARN, 4=VERBOSE, 5=TRACE, 6=CACHE
hamlib_log_level = 0
[audio]
; TX audio gain in dB applied to modulator output samples (default: 0.0).
; 0.0 dB = no change. Use this to set Mercury's TX level independently
; of the host audio mixer, so other modems sharing the radio aren't
; disturbed when you tune Mercury's drive. Saturation is applied at the
; int32 PCM ceiling so any value clips cleanly.
; Range: -20.0 .. +20.0 (values outside are clamped).
tx_gain_db = 0.0
; TX keying delay in milliseconds (default: 10), waited after PTT ON before
; audio is written to the playback device on TX. The default covers the
; local radio relay's switch time. Increase this if your host app drives
; PTT off Mercury's "PTT ON" TNC notification and needs more time to
; actually key the radio (e.g. a slow serial/CAT relay) — otherwise the
; start of the transmission can be clipped before the radio is keyed.
; Range: 0 .. 2000 (values outside are clamped).
tx_delay_ms = 10
[arq]
; ARQ link no-progress disconnect budget (seconds, default: 180).
; When data-retry slots exhaust on a frame, Mercury no longer disconnects
; immediately — it resets the retry counter and forces a payload-mode
; downgrade. The link only drops when wall-clock since the last ACK that
; advanced the sequence number exceeds this budget, OR when the keepalive
; miss limit is reached (5 * 20s = 100s by default). 180s sits just above
; the keepalive timeout as a safety net for the asymmetric case where peer
; keepalives still arrive but our TX direction has gone one-way. Raise
; this for ultra-marginal NVIS work where forward progress can take longer.
no_progress_timeout_s = 180
; Absolute cap (seconds, default: 30) on how long an application DISCONNECT
; may stay deferred while Mercury drains the last queued TX bytes. When the
; host (e.g. BPQ32) ends a BBS forwarding session, Mercury finishes sending
; any buffered data, then completes a clean air-side DISCONNECT handshake.
; This cap guarantees the link always tears down within the window even if
; the session is stuck ping-ponging — preventing the rig from being keyed
; indefinitely after the host has already disconnected. On a healthy link
; the drain finishes in seconds, so this only bites on a stuck session.
disconnect_drain_timeout_s = 30
; Number of DATA-frame retries before a downgrade cycle (default 10, range 1..64).
; Affects the data plane only; connection-setup (CALL/ACCEPT) retries keep their
; short defaults so a failed connect gives up quickly. Use the RETRIES TNC
; command at runtime to widen CALL/ACCEPT/DATA retries together.
data_retry_slots = 10
; Seconds to hold the lower mode after a forced downgrade (default 6, range 0..60).
mode_hold_after_downgrade_s = 6
; Clean ACKs required to step the speed ladder up one level (default 2, range 1..16).
ladder_up_successes = 2
; Consecutive retries that force a one-step downgrade (default 2, range 1..16).
retry_downgrade_threshold = 2
; IRS response guard after decoding a frame, in ms (default 700, range 200..3000).
; Raise if your radio's TX-to-RX switch is slow and you lose ACKs.
channel_guard_ms = 700
; ISS guard before resuming DATA TX after an ACK, in ms (default 900, range 200..3000).
iss_post_ack_guard_ms = 900
; Keepalive transmit interval in seconds (default 20, range 5..120).
keepalive_interval_s = 20
; Missed keepalives before the link is dropped (default 5, range 2..20).
keepalive_miss_limit = 5
; Seconds to hold the peer's payload mode after activity before reverting
; (default 15, range 1..120). Reduce (e.g. 8-10) if you see long gaps between
; turns; this also scales the IRS inactivity probe (hold x 5).
peer_payload_hold_s = 8
; Control-mode-only startup window in seconds (default 10, range 2..60).
; Only DATAC16 is used until the link is proven stable; raise if the initial
; handshake (e.g. UUCP) times out before the first data frames get through.
startup_max_s = 10
[channel]
; Channel-busy (occupancy) detector. Mercury classifies the HF channel as
; busy/clear from the RX spectrum and reports transitions to the host with
; VARA-compatible "BUSY ON" / "BUSY OFF" notifications on the control port.
;
; OFF by default, deliberately. Mercury itself never gates transmission on it,
; but the hosts that consume these notifications do: BPQ32 and Winlink hold
; transmissions while BUSY is asserted, so a detector that fires on noise, or on
; a station you are already in QSO with, stops the station transmitting and
; strands traffic in the queue. That is field experience on HF, not theory, and
; it is why VARA ships with busy detection off as well.
;
; Turn it on if you scan: it is then the only early warning a host gets, since
; everything else waits for a full frame to decode (3.7 s for a connect request)
; and a scanning host cannot hold its dwell that long. Expect to tune the
; thresholds below per band and noise environment before trusting it.
busy_detect = false
; Passband peak level, in dB above the tracked noise floor, required to call the
; channel BUSY (default 10, range 3..40). Lower = more sensitive.
busy_threshold_db = 10
; Release hysteresis in dB: the channel is only declared CLEAR once the peak
; falls below (busy_threshold_db - this) (default 3, range 0..20).
busy_hysteresis_db = 3
; Milliseconds the peak must stay above threshold before asserting BUSY
; (debounce against transients; default 300, range 0..5000).
busy_on_debounce_ms = 300
; Milliseconds the peak must stay below the release level before declaring CLEAR
; (hang time; default 1500, range 0..10000).
busy_hang_ms = 1500
[tnc]
; IAMALIVE interval sent on the TNC control port to tell connected clients
; the TNC is still alive. Valid range: 5..600 seconds. (default: 60)
keepalive_s = 60
; Interval between BUFFER reports sent to the TNC control port, telling
; clients how many bytes are queued for TX. Valid range: 100..10000 ms. (default: 1000)
buffer_report_ms = 1000
+25 -37
View File
@@ -2,7 +2,7 @@
#
# Author : Gaston Gonzalez
# Date : 16 July 2026
# Updated : 12 August 2026
# Updated : 26 August 2026
# Purpose : Wrapper script for starting Mercury with PnP support
#
# Preconditions:
@@ -10,26 +10,16 @@
#
# Postconditions:
# 1. Mercury started with sane defaults
#
# Notes:
#
# Mercury supports many modulation types and configuration options. To
# keep usage simple, only three modulation settings have been configured
# that map to a combination of reliability and speed for most general
# purpose applications.
#
# The DATAC17 and QAM16C2 modes are documented on the RETICULUM.md
# documenation on the mercury GitHub project, but are not yet supported
# in version 1.9.9. Disabling these options from now.
ET_MERCURY_HOME="${HOME}/.local/share/emcomm-tools/mercury"
ET_MERCURY_LOG="${ET_MERCURY_HOME}/session.log"
usage() {
echo "usage: $(basename $0) <mode>"
echo " <mode>"
echo " reliability - Max reliability (Slower Speed) [DATAC1]"
echo " balanced - Balanced (Reliability and Speed) [DATAC17]"
echo " fast - Fast (Low Reliability) [QAM16C2]"
echo " winlink - Used for Winlink [DATAC3]"
echo " arq - Automatic Retry Request mode (Winlink)"
echo " broadcast - Broadcast mode (Reticulum)"
echo " custom - User defined mode for custom settings"
}
if [[ $# -ne 1 ]]; then
@@ -41,21 +31,17 @@ fi
MODE="$1"
case "${MODE}" in
reliability)
MODE_INDEX="0"
arq)
ET_MERCURY_INI="${ET_MERCURY_HOME}/mercury.arq.ini"
OPTS=""
;;
winlink)
MODE_INDEX="1"
broadcast)
ET_MERCURY_INI="${ET_MERCURY_HOME}/mercury.broadcast.ini"
OPTS="-m 0 -b 8100"
;;
balanced)
MODE_INDEX="9"
et-log "Mode not yet supported."
exit 1
;;
fast)
MODE_INDEX="10"
et-log "Mode not yet supported."
exit 1
custom)
ET_MERCURY_INI="${ET_MERCURY_HOME}/mercury.custom.ini"
OPTS=""
;;
*)
et-log "Can't started Mercury modem. Mode not supported."
@@ -64,8 +50,15 @@ case "${MODE}" in
;;
esac
[[ -z ${ET_LOG_DIR} ]] && ET_LOG_DIR="${HOME}/.local/share/emcomm-tools"
[[ ! -e ${ET_LOG_DIR} ]] && mkdir -p ${ET_LOG_DIR}
if [[ ! -e ${ET_MERCURY_HOME} ]]; then
et-log "ET_MERCURY_HOME does not exist at ${ET_MERCURY_HOME}. Exiting"
exit 1
fi
if [[ ! -e ${ET_MERCURY_INI} ]]; then
et-log "Mercury configuration file not found at ${ET_MERCURY_INI}. Exiting"
exit 1
fi
start() {
update_config
@@ -80,12 +73,7 @@ start() {
ALSA_DEVICE=$(et-system-info et-audio-card)
# Mercury implemented support for rigctld oddly. Even though the rigctld IP and port are
# specified with the -A option, the code will not trigger the PTT unless a rig model
# is specified. We can specify model '2' (network mode) with the -R option to ensure that
# the PTT conditional code blocks for hamlib are called. This explains why earlier tests
# only worked with the DigiRig Lite as it has an internal VOX circuit.
CMD="mercury -m ${MODE_INDEX} -i plughw:${ALSA_DEVICE} -o plughw:${ALSA_DEVICE} -A 127.0.0.1:4532 -R 2"
CMD="mercury -C ${ET_MERCURY_INI} -L ${ET_MERCURY_LOG} -i plughw:${ALSA_DEVICE} -o plughw:${ALSA_DEVICE} ${OPTS}"
et-log "Starting Mercury in mode ${MODE} with: '${CMD}'"
echo