CatHub / architecture Software architecture note

CatHub engineering documentation

CatHub Architecture: Shared Control of a Radio and WinKeyer

CatHub allows applications using OmniRig, Hamlib NET, native CAT serial interfaces, virtual WinKeyer interfaces, and typed APIs to safely share one physical station.

Document type
Software architecture note
Scope
CatHub radio control, CW keying, client endpoints, and station-wide transmit safety
Examples
Illustrative Windows station using a Kenwood TS-590, a WinKeyer, and com0com virtual pairs

1. Executive summary

A station can run several programs that expect exclusive access to the same radio or keyer. Those programs use different protocols and have different authority. CatHub places one coordination boundary between the software and the physical devices.

CatHub is the sole owner of the radio control link and physical WinKeyer. Client applications connect to private serial or loopback network endpoints that match the protocol they already understand. Inside the daemon, separate radio and WinKeyer brokers serialize work, maintain shared state, apply endpoint permissions, and use one station-wide push-to-talk (PTT) lease.

The design lets existing applications continue to use OmniRig, Hamlib NET, vendor CAT commands, or the WinKeyer host protocol. It does not make the physical serial ports shareable. It replaces direct hardware access with explicit, managed endpoints.

2. Problem and scope

A modern amateur radio station often combines a panadapter, logger, digital-mode program, manufacturer control application, and logging engine. The transceiver and WinKeyer each expose one stateful hardware connection, while every application behaves as though it owns that connection.

OmniRig coordinates programs that use its automation API. Hamlib's rigctld coordinates programs that use Hamlib NET. A native CAT program still requires a serial port. Legacy CW software can require a physical-looking WinKeyer port. These coordinators do not share station-wide state or transmit ownership.

Existing approachWhat it coordinatesBoundaryRole with CatHub
OmniRigPrograms using the OmniRig automation API.Native serial CAT and Hamlib NET clients cannot use that API directly.Remains a coordinator for its clients and connects to a private CatHub serial endpoint.
Hamlib rigctldPrograms using the rigctld-compatible TCP protocol.Programs requiring a COM port or vendor CAT dialect cannot connect to its socket.Hamlib-aware programs connect to dedicated CatHub network endpoints.
Direct serial CATOne program speaking a supported vendor command set.Serial ports are normally exclusive, and independent command streams cannot be safely combined.Each program receives a private virtual COM pair backed by a CatHub serial endpoint.
Direct WinKeyer accessOne host session using the stateful WinKeyer byte protocol.Client state, buffered Morse, status bytes, and maintenance replies cannot be interleaved safely.Legacy programs use private virtual endpoints. Native clients use a typed loopback API.
Table 1. Existing coordinators solve compatibility within a client group, not across the complete station.

CatHub's scope begins where separate interface-specific coordinators stop: shared hardware ownership, state, scheduling, permissions, and transmit safety.

3. Goals and non-goals

Goals

  • Keep one authoritative owner for each physical hardware connection.
  • Support simultaneous serial CAT, Hamlib NET, OmniRig, WinKeyer serial, and typed API clients.
  • Normalize modeled radio operations into shared state and propagate changes from any client or the radio front panel.
  • Preserve per-session command order while prioritizing PTT and interactive writes over background reads.
  • Apply explicit read, write, PTT, control, and configuration permissions at each endpoint.
  • Return the station to receive when a client disconnects or a transmit safety limit expires.
  • Keep radio-specific behavior behind backend capabilities and client-specific behavior behind endpoint dialects.

Non-goals

  • Replacing OmniRig, Hamlib, loggers, digital-mode applications, or manufacturer control software.
  • Implementing every Hamlib operation or every vendor CAT command in the universal state model.
  • Automatically detecting a client program or dialect from arbitrary command traffic.
  • Allowing several applications to open one physical or virtual serial endpoint.
  • Supporting simultaneous transmit owners.
  • Providing remote, cross-host station access in the current deployment model.
  • Claiming support for radio families or WinKeyer behaviors that have not been implemented and tested.

4. System context

From an operator's perspective, CatHub is a local station service. Applications connect to CatHub instead of opening the physical device ports. CatHub then coordinates all radio-control and CW-keying traffic.

Figure 1. CatHub system context.All software interfaces terminate at CatHub. Only CatHub opens the physical station devices.

5. Architecture overview

The detailed topology separates the protocol expected by each application from the backend used to control the hardware. Radio-control clients converge on one radio broker. CW clients converge on a separate WinKeyer broker. Both brokers use the same station transmit boundary.

Application or existing interface CatHub component Physical hardware
Figure 2. Detailed CatHub topology.Client-specific adapters remain at the edge. Shared state and scheduling sit inside the brokers, while the physical devices remain single-owner resources.

Hardware ownership is the major architecture boundary. Applications can use different transports and protocols. No application bypasses the applicable device broker.

6. Components and responsibilities

CatHub separates volatile hardware and client protocols from the shared station model. This keeps new radio backends and client dialects at the edges rather than spreading device-specific rules through the scheduler.

ComponentPrimary responsibilityImportant boundary
Endpoint adaptersAccept serial, Hamlib NET, virtual WinKeyer, or typed gRPC clients. Create client sessions. Frame and parse requests.An endpoint fixes the protocol, permissions, and compatibility policy before a client connects.
Client dialectsTranslate supported CAT commands into shared operations and format protocol-specific replies or events.Dialects use shared state and capabilities, not a concrete radio backend.
Radio brokerSerialize radio operations, preserve per-session FIFO order, prioritize interactive work, and reconnect the hardware transport.Only this actor submits work to the active radio backend.
Radio backendImplement modeled operations and native passthrough for a physical radio or an upstream rigctld process.Radio-specific behavior is isolated behind backend capabilities.
Shared radio stateStore modeled VFO, frequency, mode, split, RIT/XIT, meter, power, and PTT state with freshness metadata.All modeled mutations and downstream change notifications pass through this state.
Poller and event fan-outCoalesce baseline polling, consume native push events, update shared state, and notify interested endpoints.Native push reduces polling for each covered field. It does not disable polling for uncovered fields.
WinKeyer brokerVirtualize client sessions, preserve client profiles, schedule atomic CW jobs, route status, and isolate maintenance.Client bytes and commands are never interleaved inside another client's active job.
Hardware actorsOwn the physical radio or WinKeyer transport and recover it with bounded backoff after failure.Client endpoints remain available while a physical device reconnects.
PTT leaseGrant one station-wide transmit owner across CAT PTT and WinKeyer activity.A conflicting owner is rejected rather than allowed to contend.
Transmit watchdogsEnforce radio PTT and WinKeyer maximum-transmit durations and force a safe return to receive.The timeout is a hard transmit ceiling, not a generic client-idle timeout.
ConfigurationDefine hardware, endpoints, transports, dialects, permissions, compatibility views, polling, and safety limits.Invalid or unsafe combinations fail validation before hardware is opened.
Table 2. CatHub component responsibilities and architectural boundaries.

7. Interfaces and connection topology

The following map uses one illustrative Windows station. Port numbers are examples, not required defaults. A serial application opens the application side of its own virtual pair. CatHub opens the other side and the physical hardware ports.

ClientApplication endpointCatHub endpointProtocol or dialectExample authority
HDSDR through OmniRigCOM11COM10TS-2000 CATRead, frequency write
N1MM radio controlCOM21COM20TS-590 CAT, single-VFO viewRead, write, PTT
ARCP-590COM31COM30TS-590 CAT with passthroughRead, write, PTT, configuration write
Read-only logger127.0.0.1:4532TCP listener :4532Hamlib NETRead
WSJT-X127.0.0.1:4533TCP listener :4533Hamlib NET, single-VFO viewRead, write, PTT
Log4OM127.0.0.1:4534TCP listener :4534Hamlib NET, single-VFO viewRead, write
JS8Call127.0.0.1:4535TCP listener :4535Hamlib NET, single-VFO viewRead, write, PTT
N1MM CWCOM41COM40WinKeyer host protocol, 1200 baud 8-N-2Status, send, control, PTT
WKToolsCOM43COM42WinKeyer maintenanceStatus, control, configuration write
Typed CW client127.0.0.1:50071Loopback gRPC serviceTyped WinKeyer APINamed jobs, speed, status, cancel, abort
Table 3. Example client-to-CatHub connection map. Every serial client has a private virtual pair.

Virtual serial pairs

A com0com pair on Windows, or a PTY pair on Linux, acts as a null-modem cable. Bytes from one endpoint appear at the other. The pair does not make an endpoint shareable. CatHub and the application must open opposite sides.

In a serial endpoint configuration, transport is the port CatHub opens. application_transport records the paired application port. This value gives operator guidance and setup metadata. CatHub does not open it.

Figure 3. Example serial connection paths.The application-side, CatHub-side, and physical hardware ports are distinct. Reversing the two sides of a virtual pair causes an exclusive-open conflict.
Operator warning

Never configure an application to open CatHub's transport port or a physical hardware port. The application must open its assigned application_transport port.

8. Runtime behavior

CatHub handles radio commands and CW jobs through separate schedulers because the protocols have different state and ordering rules. The following scenarios show the important runtime paths.

8.1 CAT command and state propagation

A client command is parsed under the policy of its configured endpoint. Modeled operations update the shared state through the serialized radio path. Replies and spontaneous changes are then formatted for each client dialect.

Figure 4. CAT request and state-update sequence.Per-session FIFO ordering is preserved. Across ready session heads, PTT and interactive writes take priority over routine reads and baseline polling.

The result is one coherent station view. Each front-panel or client change updates the same model. CatHub can report that change to each compatible client without additional radio polls.

8.2 Atomic CW scheduling

The WinKeyer protocol mixes client configuration, status, buffered commands, and Morse data. CatHub therefore schedules complete typed jobs and leased raw streams rather than forwarding bytes from several clients at once.

Figure 5. Atomic CW scheduling sequence.No other client's bytes or profile commands are inserted inside an active job. Physical paddle break-in retains the keyer's native priority.

The result is deterministic CW. Typed jobs remain atomic, a virtual serial client keeps its own protocol state, and maintenance replies remain private to the maintenance owner.

8.3 PTT arbitration and recovery

Radio CAT PTT and WinKeyer transmission compete for one station resource. The first authorized client to transmit acquires a lease. Other clients receive a busy or failed-precondition response until the owner releases it.

Figure 6. Station-wide PTT lease lifecycle.The lease prevents simultaneous transmit owners and provides a single place to enforce fail-safe return to receive.

9. Safety and failure behavior

Failure handling is part of the architecture rather than an application convention. CatHub keeps safety decisions in the brokers that own the physical devices.

ConditionCatHub behaviorOperational result
Permission deniedReject the request using the client protocol's error form and log the endpoint and operation.Read-only or restricted clients cannot tune, key, or change persistent settings.
PTT already leasedReject the conflicting PTT or CW request as busy.Only one client controls station transmit at a time.
Transmit ceiling reachedForce receive or key-up, release the lease, and record the safety action.A crashed or wedged client cannot hold continuous transmit indefinitely.
PTT owner disconnectsUnkey immediately during session teardown and release only that owner's lease.The transmitter returns to receive without waiting for the maximum-duration ceiling.
CW job cancelledRemove the requesting client's queued jobs. An authorized active abort clears the physical buffer and forces key-up.Cancellation is scoped and does not remove another client's queued work.
Radio transport failsKeep client endpoints open, mark shared state stale, reject mutations, and retry the backend with backoff.Clients can distinguish cached status from live control. Service resumes after reconnect.
WinKeyer transport failsCancel queued work, release station PTT, mark status disconnected, and reopen the port with bounded backoff.No queued Morse resumes unexpectedly after a hardware interruption.
WinKeyer maintenance beginsRequire no active or queued transmission, clear and dekey, close the normal host session, and grant exclusive access.Disruptive administrative commands cannot interleave with normal sending.
Graceful shutdownAttempt radio RX, clear the keyer buffer, force key-up, close the physical keyer host session, and release PTT.An orderly service stop leaves hardware in a safe receive state.
Malformed or oversized inputReject invalid values, bound in-progress frames, and close or resynchronize the offending session as appropriate.Bad client input cannot grow buffers without limit or silently coerce unsafe commands.
Table 4. Safety and failure contracts.
Implementation detail

The transmit watchdog limits continuous transmission. It is not an inactivity timer. Digital-mode applications can key PTT without more CAT traffic until completion.

10. Configuration and deployment

Operators configure physical devices first. Then they create one endpoint for each application or authority group. The examples use standalone CatHub section names. Managed TOML documents can put the same sections under cat_hub.

10.1 Physical hardware and safety limits

TOML - example physical device configuration
# Physical ports are opened only by CatHub.
[radio]
backend = "ts590"
model = "TS-590SG"
transport = "serial"
port = "COM4"
baud = 57600

[poll]
baseline_ms = 200
heartbeat_ms = 2000

[ptt]
max_tx_ms = 300000

[events]
native_push = true

[winkeyer]
port = "COM3"
baud = 1200
max_tx_ms = 30000
api_bind = "127.0.0.1:50071"

10.2 Application endpoints

TOML - example serial, network, and WinKeyer endpoints
# CatHub opens COM10. OmniRig opens the paired COM11.
[[serial_endpoint]]
name = "hdsdr-omnirig"
transport = "COM10"
application_transport = "COM11"
baud = 115200
dialect = "ts2000"
perms = ["read", "frequency_write"]

# A separate loopback listener expresses WSJT-X authority.
[[hamlib_net]]
name = "wsjtx"
bind = "127.0.0.1:4533"
single_vfo = true
perms = ["read", "write", "ptt"]

# CatHub opens COM40. N1MM opens the paired COM41.
[[winkeyer_endpoint]]
name = "n1mm-cw"
transport = "COM40"
application_transport = "COM41"
baud = 1200
primary = true
perms = ["status", "send", "control", "ptt"]

10.3 Operator deployment sequence

  1. Create one virtual serial pair for each serial CAT or legacy WinKeyer application.
  2. Configure the physical radio and WinKeyer ports. Do not give these ports to a client application.
  3. Configure CatHub's side of every virtual pair as transport and record the application side as application_transport.
  4. Create separate loopback listeners when network clients require different permissions or compatibility views.
  5. Validate the configuration with CatHub's dry-run mode before opening hardware.
  6. Start CatHub, then point each application at its assigned application-side COM port or loopback TCP endpoint.
  7. Bench-test read, tune, mode, PTT, CW, cancellation, disconnect, and watchdog behavior before on-air use.

11. Current implementation and limitations

The preceding sections describe the architecture. This section identifies what the current CatHub implementation supports and where the general design remains intentionally bounded.

AreaCurrent implementationLimitation or qualification
Radio backendsNative Kenwood TS-590, upstream rigctld, and loopback test backends.The native TS-590 backend is the first certified reference. Other radio families require additional backends or a validated rigctld pairing.
Serial CAT dialectsTS-590, transparent TS-590, and TS-2000 client dialects.Direct serial means a supported dialect over a private pair, not arbitrary serial protocol acceptance.
Hamlib NETModeled read/write operations, PTT, split and VFO queries, power queries, capability handshake, and raw CAT escape operations used by tested clients.CatHub does not reimplement every Hamlib feature. Tested client transcripts define compatibility.
Compatibility viewsOptional single-VFO presentation for serial and Hamlib NET endpoints.A single-VFO endpoint rejects real split enablement. WSJT-X must use Fake It instead of Rig split.
Native passthroughSame-family rich TS-590 commands can pass through under command classification and permissions.An upstream rigctld backend provides modeled control, not transparent vendor-command fidelity.
WinKeyerPhysical 1200 baud host session, virtual serial endpoints, typed gRPC jobs and events, profiles, status fan-out, cancellation, abort, and exclusive maintenance.Assume only implemented and validated WinKeyer behavior. CatHub restricts maintenance authority.
Network exposureHamlib NET and typed APIs bind to loopback in the supported deployment model.Cross-host remote operation, authentication, and network security are outside the current scope.
Station scaleOne configured radio and one optional physical WinKeyer per CatHub instance.Multi-radio orchestration is not part of the current runtime.
Table 5. Current implementation status and architectural limits.

12. Design decisions and tradeoffs

CatHub is the sole hardware owner.
Exclusive ownership controls ordering, recovery, and safety in one process. Each application must connect to a CatHub endpoint. Thus, the station requires CatHub.
Each serial client receives a private virtual pair.
A private pair provides unambiguous protocol, permissions, client-session cleanup, and outbound event routing. It consumes more virtual port names than attempting to share one pair, but avoids an unsafe and generally unsupported multi-open arrangement.
Radio and WinKeyer use separate brokers.
CAT is request/state oriented, while WinKeyer is a stateful byte protocol with buffered Morse, profiles, and private maintenance replies. Separate schedulers keep those ordering rules explicit. They still share the station PTT lease because both can cause transmission.
CatHub maintains shared radio state instead of only forwarding bytes.
Shared state coalesces polling, fans out front-panel and client changes, translates between dialects, and supports consistent reads. The cost is a modeled state surface with freshness and invalidation rules, plus passthrough for rich commands outside that model.
Endpoints use explicit configuration.
Explicit dialects and permissions give predictable fail-closed behavior. An incorrect endpoint does not start automatic dialect detection. The client receives only the authority of that endpoint.
Compatibility views are endpoint policy.
A single-VFO view lets applications with simplified assumptions operate against either physical VFO without changing radio state. The view intentionally hides capabilities, such as real split, that it cannot represent honestly.

13. Glossary and references

Glossary

CAT
Computer-aided transceiver control: commands and responses used to read or change radio state.
Dialect
A specific command vocabulary and reply format presented to a client, such as Kenwood TS-590 or TS-2000 CAT.
Transport
The mechanism that carries bytes, such as a physical serial port, virtual COM endpoint, PTY, or TCP socket.
Endpoint
A configured CatHub listener or serial path with a fixed protocol, permissions, and compatibility policy.
Virtual COM pair
Two linked virtual serial endpoints. One process opens each endpoint. Bytes written to one side arrive at the other.
Client session
One live connection to an endpoint, with its own internal ID, ordering, PTT ownership, queues, and disconnect cleanup.
Hamlib NET
The rigctld-compatible TCP protocol used by Hamlib-aware applications to control a radio.
OmniRig
A Windows automation component that allows compatible applications to share configured radio instances.
WinKeyer
A hardware CW keyer with a stateful host serial protocol, buffered Morse sending, status, speed, and configuration commands.
PTT lease
CatHub's single-owner grant allowing one client session to place the station in transmit.

References

  1. Multi-client CAT hub design and multi-client WinKeyer broker design.
  2. CatHub operator setup and release and compatibility policy.
  3. OmniRig product documentation.
  4. Hamlib rigctld manual.
  5. Microsoft documentation for communications resource handles.
  6. com0com project documentation.
  7. Implementation: serial_endpoint.rs, hamlib_net.rs, the radio dialect modules, and the winkeyer modules.