First stable release. tncd is no longer beta — the AGWPE bridge, AX.25 v2.0 connected-mode state machine, UI-frame passthrough, multi-port operation, Bluetooth SPP, and security hardening from the 0.11.x series are all considered feature-complete and field-tested.
Tested
- Kantronics KPC+ family (KPC-3+ / KPC-9612+) — OTA-verified at 1200 baud
serial; programmatic KISS init via
INTFACE KISS\r\nRESET\rwithinit_delay = 2.0
Security Hardening
- Default
listen_hostchanged from0.0.0.0to127.0.0.1— prevents unauthenticated remote access to the AGWPE server. Set to0.0.0.0in config if remote access is needed. - Maximum AGWPE payload size limit (64 KB) — disconnects clients sending oversized frames to prevent memory exhaustion
- Maximum concurrent AX.25 connections limit (64) — prevents unbounded connection state accumulation
- Outbound queue cap (512 entries per connection) — prevents memory exhaustion
from rapid
Dframe sends
Bug Fixes
- Fix incoming SABM handling at connection limit: send DM (reject) instead of UA followed by DM, per AX.25 §2.3.4
New Features
- Native Bluetooth SPP via BlueZ D-Bus Profile API — connects directly to
Bluetooth TNCs without
rfcommortncd-rfcomm - New
type = bluetoothconnection type in[client]config - Auto-reconnect with exponential backoff for Bluetooth connections (configurable via
reconnect,reconnect_delay,reconnect_max_delay) - RFCOMM channel auto-detection via SDP — no manual channel configuration needed
- SABM retransmission via T1 timer during connection setup (AX.25 6.3.1)
Bug Fixes
- Disconnect existing BLE auto-connection before SPP connect to prevent
br-connection-page-timeouton dual-mode devices (e.g. Mobilinkd TNC3) - Run
ConnectProfilein a background thread to avoid blocking asyncio on the expected D-Bus NoReply - Fix
blocking_start()serial port guard: only accesstransport.serialfortype = serialconnections
Packaging
- Nix:
bluetoothSupportoption on package, auto-enabled by NixOS module whenbluetooth.enable = true - Arch PKGBUILD updated with
python-dbusandpython-gobjectdependencies - Deprecated
tncd-rfcommhelper (still included, will be removed in a future release)
Tested
- Full Winlink CMS round-trip with 10KB binary attachment over Mobilinkd TNC3 Bluetooth SPP via KU0HN-10 gateway at 1200 baud
Bug Fixes
- Fix
init_stringserial probe: pause asyncio reader during KISS mode entry to avoid consuming the TNC's response - Fix
init_stringto use the same serial connection (no re-open) and probe for command mode before sending - Fix HUPCL termios flag: prevent DTR reset on serial port close, which was kicking TNCs out of KISS mode
Tested
- Kenwood TS-2000 built-in TNC: full OTA Winlink session at 1200 baud via
init_string - Kenwood TH-D7A: OTA PASS with
init_stringprobe
New Features
- AX.25 spec compliance: RNR (Receive Not Ready) flow control, FRMR (Frame Reject) handling, N2 retry limit with automatic disconnect
- Raw KISS serial spy for debugging TNC communication
- Implicit connect on lost UA: if remote sends I-frames during CONNECTING state, promote to CONNECTED (the UA was lost OTA)
Bug Fixes
- T1 poll-then-retransmit: first expiry sends RR poll only, second consecutive expiry also retransmits unacked I-frames (avoids flooding slow TNC buffers)
Tested
- Mobilinkd TNC4: full OTA Winlink session via USB at 1200 baud
Bug Fixes
- Fix download stall in AX.25 connected mode caused by duplicate RR responses flooding the half-duplex TX buffer
_send_rr_guarded()suppresses duplicate RR F=1 with same N(R) within 3s- Defer poll response via
call_soonto let queued I-frames advancerecv_seqnofirst - I-frame coalescing in
_drain_outboundmerges adjacent small payloads up to 256 bytes - Y-frame reports
unacked + queued(matches Direwolf, fixes PAT flow control) - Guard against backwards N(R) from retransmitted frames
- Send DM for I-frames to unknown connections (clears stale sessions after restart)
Bug Fixes
- Retransmit unacked I-frames when remote polls with RR P=1
- Fix
tncd-rfcommservice PATH to include bluez binaries
Packaging
- NixOS module imported from nix-ham-packages
- Switched to nix-ham-packages overlay (removed local
nix/overlay.nix) - Removed stale OBS packaging (releases now use Cloudflare Pages)
New Features
- Dynamic T1/T2 timers calculated from over-the-air baud rate
(
ota_baudrateconfig option) - Piggybacked N(R) acknowledgement fix for connected mode
- Direwolf compatibility verified (KISS-over-TCP and PTY modes)
Tested
- First successful OTA Winlink session at 1200 baud
Bug Fixes
- Fix incoming connected mode: SABME rejection (mod-128 not supported), owner assignment from registered callsigns, correct AGWPE notification format
Other
- Added user-focused documentation website
- Tabbed install section with NixOS, macOS, and Windows instructions
New Features
- AX.25 connected mode: window flow control, immediate RR, T1 retransmit timer
- End-to-end test suite with PipeWire audio cross-linking, Direwolf pairs, PAT P2P messaging, and KISS PTY mode
Other
- Cloudflare Pages deployment for package repository and website
- Cross-compiled .deb and .rpm packages for amd64, i386, armhf, arm64, riscv64
Initial Release
- AGWPE-to-KISS bridge with serial and TCP KISS support
- AX.25 UI (unproto) frame forwarding
- Multiple simultaneous AGWPE client support
- Bluetooth RFCOMM helper (
tncd-rfcomm)