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.
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 approach | What it coordinates | Boundary | Role with CatHub |
|---|---|---|---|
| OmniRig | Programs 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 rigctld | Programs 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 CAT | One 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 access | One 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. |
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.
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.
- parses client dialects
- maintains shared radio state
- serializes reads and writes
- applies endpoint permissions
- leases PTT ownership
- keeps client profiles separate
- queues complete CW jobs
- prevents byte interleaving
- fans out device status
- grants exclusive maintenance
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.
| Component | Primary responsibility | Important boundary |
|---|---|---|
| Endpoint adapters | Accept 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 dialects | Translate 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 broker | Serialize 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 backend | Implement modeled operations and native passthrough for a physical radio or an upstream rigctld process. | Radio-specific behavior is isolated behind backend capabilities. |
| Shared radio state | Store 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-out | Coalesce 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 broker | Virtualize 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 actors | Own the physical radio or WinKeyer transport and recover it with bounded backoff after failure. | Client endpoints remain available while a physical device reconnects. |
| PTT lease | Grant one station-wide transmit owner across CAT PTT and WinKeyer activity. | A conflicting owner is rejected rather than allowed to contend. |
| Transmit watchdogs | Enforce 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. |
| Configuration | Define hardware, endpoints, transports, dialects, permissions, compatibility views, polling, and safety limits. | Invalid or unsafe combinations fail validation before hardware is opened. |
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.
| Client | Application endpoint | CatHub endpoint | Protocol or dialect | Example authority |
|---|---|---|---|---|
| HDSDR through OmniRig | COM11 | COM10 | TS-2000 CAT | Read, frequency write |
| N1MM radio control | COM21 | COM20 | TS-590 CAT, single-VFO view | Read, write, PTT |
| ARCP-590 | COM31 | COM30 | TS-590 CAT with passthrough | Read, write, PTT, configuration write |
| Read-only logger | 127.0.0.1:4532 | TCP listener :4532 | Hamlib NET | Read |
| WSJT-X | 127.0.0.1:4533 | TCP listener :4533 | Hamlib NET, single-VFO view | Read, write, PTT |
| Log4OM | 127.0.0.1:4534 | TCP listener :4534 | Hamlib NET, single-VFO view | Read, write |
| JS8Call | 127.0.0.1:4535 | TCP listener :4535 | Hamlib NET, single-VFO view | Read, write, PTT |
| N1MM CW | COM41 | COM40 | WinKeyer host protocol, 1200 baud 8-N-2 | Status, send, control, PTT |
| WKTools | COM43 | COM42 | WinKeyer maintenance | Status, control, configuration write |
| Typed CW client | 127.0.0.1:50071 | Loopback gRPC service | Typed WinKeyer API | Named jobs, speed, status, cancel, abort |
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.
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.
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.
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.
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.
| Condition | CatHub behavior | Operational result |
|---|---|---|
| Permission denied | Reject 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 leased | Reject the conflicting PTT or CW request as busy. | Only one client controls station transmit at a time. |
| Transmit ceiling reached | Force receive or key-up, release the lease, and record the safety action. | A crashed or wedged client cannot hold continuous transmit indefinitely. |
| PTT owner disconnects | Unkey 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 cancelled | Remove 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 fails | Keep 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 fails | Cancel 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 begins | Require 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 shutdown | Attempt 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 input | Reject 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. |
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
# 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
# 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
- Create one virtual serial pair for each serial CAT or legacy WinKeyer application.
- Configure the physical radio and WinKeyer ports. Do not give these ports to a client application.
- Configure CatHub's side of every virtual pair as
transportand record the application side asapplication_transport. - Create separate loopback listeners when network clients require different permissions or compatibility views.
- Validate the configuration with CatHub's dry-run mode before opening hardware.
- Start CatHub, then point each application at its assigned application-side COM port or loopback TCP endpoint.
- 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.
| Area | Current implementation | Limitation or qualification |
|---|---|---|
| Radio backends | Native 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 dialects | TS-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 NET | Modeled 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 views | Optional 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 passthrough | Same-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. |
| WinKeyer | Physical 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 exposure | Hamlib 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 scale | One configured radio and one optional physical WinKeyer per CatHub instance. | Multi-radio orchestration is not part of the current runtime. |
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
- Multi-client CAT hub design and multi-client WinKeyer broker design.
- CatHub operator setup and release and compatibility policy.
- OmniRig product documentation.
- Hamlib rigctld manual.
- Microsoft documentation for communications resource handles.
- com0com project documentation.
- Implementation:
serial_endpoint.rs,hamlib_net.rs, the radiodialectmodules, and thewinkeyermodules.