Skip to content

Implement native SmartCAT TCP server — full FlexRadio and TS-2000 dialect support #2962

Description

@K5PTB

Request preparation

  • I used an AI assistant to help structure this request
  • I checked for existing issues covering the same feature

This is Phase 2 of a two-phase external-control roadmap. Phase 1 — a complete rigctld implementation (Hamlib NET rigctl protocol) — is tracked in #2379.

A reference implementation is complete and available on branch feat/smartcat-tcp-server. It is pending integration testing with MacLoggerDX, fldigi, and N1MM before a PR is submitted.

What

A native SmartCAT TCP server embedded in AetherSDR that speaks the FlexRadio CAT dialect (ZZ-extension commands) and, for external programs that don't support FlexRadio specifically, the Kenwood TS-2000 dialect as a compatibility fallback. Each TCP port is independently configured with a dialect, VFO-A slice, and optional VFO-B slice. External logging and digital-mode programs connect to these ports exactly as they would to a supported FlexRadio or Kenwood transceiver.

Why

AetherSDR already exposes a partial CAT/TCP endpoint but the existing implementation is incomplete, causing connection failures with real-world software (see #2538). The broader problem:

  • Some external programs (fldigi, CQRLOG, MacLoggerDX) can use the Hamlib rigctld path covered by Phase 1. Others — notably N1MM Logger and similar contest tools — do not support rigctld and instead connect via the Kenwood TS-2000 CAT protocol or the FlexRadio ZZ-extension dialect directly.
  • Without a complete implementation, users must run a third-party CAT bridge alongside AetherSDR, reintroducing the Windows dependency the project is trying to eliminate.
  • The FlexRadio ZZ-extension dialect gives per-slice precision and bi-directional sync that the base TS-2000 dialect lacks, and is the native interface for software that targets FlexRadio transceivers explicitly.

How Other Clients Do It

  • SmartSDR for Windows ships a companion application called SmartCAT that provides Kenwood TS-2000 CAT TCP ports for external programs. It is a separate app, not integrated into the main SmartSDR UI.
  • SmartSDR for macOS integrates CAT TCP ports directly into the application. Ports are configured individually with a selectable dialect — rigctld, TS-2000, or FlexRadio CAT — and services are only created for ports that are explicitly enabled. This is the closest analogue to what AetherSDR should do.
  • Thetis / OpenHPSDR exposes a TS-2000/TS-480 CAT interface on a configurable TCP port, widely used with N1MM and similar contest software.

Suggested Behavior

The CAT Control applet (already present in the AppletPanel) is the sole configuration and status point — no separate dialog is needed, consistent with SmartSDR for macOS:

  • Docked (collapsed) state: shows only an enable/disable toggle button. No ports are opened until the applet is enabled.
  • Expanded / popped-out state: reveals up to 8 configuration rows, one per port. Each row configures:
    • Port number
    • Dialect: TS-2000 | FlexCAT
    • VFO A: slice selector
    • VFO B: slice selector (optional, for split or SO2R)
    • Enable/disable toggle
    • Connected-client count (live status)
  • Services are only created for ports that are individually enabled — matching SmartSDR for macOS behavior.
  • Once enabled, external software connects and exchanges semicolon-delimited CAT commands (FA;FA00014225000;). AI mode (AI1;) pushes unsolicited FA... / MD... messages to the client on every slice change.

Protocol Hints

The implementation follows the FlexRadio SmartSDR CAT User Guide, Rev 4.1.5, available at https://www.flexradio.com/documentation/smartsdr-cat-user-guide-pdf/

The CAT protocol is semicolon-framed. Queries end with ; and receive one response ending with ;. Unknown commands return ?;.

Tier-1 commands (TS-2000 dialect — maps directly to existing model layer):

Command Maps to
FA / FB SliceModel::rfFrequency, setRfFrequency()
MD SliceModel::mode, setMode() (Kenwood 1-digit encoding)
IF 35-char composite body (freq, step, RIT, XIT, TX state, mode, split)
AI Unsolicited push on slice changes
FT SliceModel::txEnabled (split)
TX / RX RadioModel::isTransmitting() / interlock
PS Always PS1 (radio is on if connected)
ID Model-number table from SmartSDR CAT guide Rev 4.1.5

Tier-2 commands (audio, AGC, power, RIT/XIT, CW, noise):

AG (audio gain), GT (AGC mode), PC (RF power), NB (noise blanker), KS (CW speed), PT (CW pitch), KY (CW send/busy), RT/RG/RC/RD/RU (RIT), XT/XG/XC (XIT)

FlexCAT ZZ-extension commands (prefix ZZ, FlexCAT dialect only):

ZZFA/ZZFB (freq), ZZMD/ZZME (mode, 2-digit codes), ZZIF/ZZAI/ZZSW/ZZSM (status/AI/split/S-meter), ZZAG/ZZGT/ZZPC/ZZMG (audio/AGC/power/mic), ZZRT/ZZRG/ZZRC/ZZRD/ZZRU (RIT), ZZXS/ZZXG/ZZXC (XIT), ZZNR/ZZNL/ZZBI/ZZFR (NR/NB/binaural/VFO swap)

Acceptance Criteria

  • MacLoggerDX, fldigi, and N1MM Logger all connect, display live frequency and mode, and achieve bidirectional sync — frequency and mode changes in either AetherSDR or the external program are immediately reflected in both (MacLoggerDX bidirectional sync via rigctld confirmed; TS-2000 and FlexCAT ports extend this to programs that do not support Hamlib)
  • ZZFA / ZZMD / ZZIF round-trip correctly on a FlexCAT port; AI push delivers FA... / MD... messages within 200 ms of a slice change
  • All tier-1 and tier-2 commands return correct values; no ?; returned for valid set commands
  • Multiple simultaneous clients on the same port each receive correct independent responses
  • No regression to the existing rigctld server, TCI server, or FlexRadio protocol flow
  • Integration test suite (smartcat_ts2000_test / smartcat_flexcat_test) passes cleanly; reference implementation available on branch feat/smartcat-tcp-server

Metadata

Metadata

Assignees

No one assigned

    Labels

    GUIUser interfaceNew FeatureNew feature requestexternal devicesFlexControl, MIDI, serial port, USB peripheralsmaintainer-reviewRequires maintainer review before any action is takenprotocolSmartSDR protocol

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions