1. Executive Summary

1.1 Project Overview

SunMRRC is a mobile-first browser remote-control system for SunSDR2 DX. It provides a web UI, WebSocket control/audio channels, direct UDP communication with the radio, IQ stream demodulation, browser audio playback, S-meter estimation, and a compact waterfall display.

The current codebase is intentionally narrower than the older MRRC documentation it replaced. It is no longer a Tornado/Hamlib/PyAudio-centric design; it is a FastAPI/Uvicorn service that imports shared SunSDR2 DX protocol and DSP modules from ../web_control and serves a dedicated mobile UI from static/.

1.2 Current Design Goals

Goal Target Current Evidence
Mobile-first operation iPhone/mobile browser as primary UI static/index.html, static/mobile.css, static/mobile.js
Secure iOS runtime HTTPS/WSS secure context _find_ssl() in server.py, STATUS.md HTTPS notes
Direct SunSDR control No rigctld dependency for this app SunSDR2DXClient imported from ../web_control/sunsdr_direct.py
Real-time RX IQ UDP to browser speaker _process_iq_stream(), StreamProcessor, /WSaudioRX
Visual signal awareness S-meter (exponentially smoothed) plus accumulated/contrast-stretched waterfall getSignalLevel:*, /WSspectrum, waterfall-canvas
Safe PTT handling Avoid stuck TX states ptt_manager.js, tx_button.js, setPTT handling
DSP configurability Runtime WDSP controls setWDSP* commands and AudioDemodulator WDSP setters

1.3 Implemented Core Features

Feature Status Description
Static mobile PWA-style UI Implemented Mobile layout with safe-area support, manifest, service worker, bottom PTT area
Control WebSocket Implemented /WSCTRX handles PING, frequency, mode, PTT, tune, gain, filter, WDSP commands
RX audio WebSocket Implemented /WSaudioRX broadcasts tagged dual-codec frames (0x00=PCM, 0x01=Opus 16 kHz mono); default Opus
TX voice modulation Verified /WSaudioTX mic frames β†’ SAB ring buffer (zero main-thread path) β†’ Opus β†’ Python Hilbert SSB (sole path, WDSP C-chain removed) β†’ 300 Hz HPF β†’ tanh soft-limiter β†’ 24-bit IQ β†’ 0xFFFD TX stream; verified 37 dB SNR, 96% SSB efficiency, zero audio dropouts; IQ peak ~0.69, RMS ~0.68 at 100% drive
TX power / drive control Implemented Device DRIVE command (0x0017) with per-band power; TX_IQ_PEAK=1.0 (full scale), TX_DRIVE_GAIN=2.8, client preamp=1.5 with tanh soft limiter
TX audio EQ Implemented Client-side Web Audio EQ (DEFAULT/MEDIUM/STRONG/RAGCHEW presets), compressor (3:1), anti-alias lowpass; gain-staged for clean SSB envelope; SAB ring buffer bypasses main thread for zero-copy audio path; COEP credentialless headers enable SharedArrayBuffer
Per-band power UI Implemented Menu β†’ Band Power panel + /api/band_power (persisted to band_power.json)
Spectrum WebSocket Implemented /WSspectrum broadcasts compact uint8 FFT rows; browser accumulates frames (~38 Hz β†’ ~3.8 Hz) and renders with adaptive noise-floor contrast
SunSDR2 DX UDP control Implemented Boot/connect sequence and parameter commands through shared direct protocol module
IQ stream processing Implemented UDP 50002 IQ decode, DSP feed, audio extraction, spectrum extraction
Memory channel API Implemented /api/mem_channels GET/POST with JSON persistence (mem_channels.json)
WDSP runtime control Conditional Active when libwdsp is available through wdsp_wrapper
HTTPS auto-start Implemented Uvicorn starts with TLS when cert/key files exist
Restart automation Implemented restart.sh cleans exact working-directory server process and listening port

1.4 Explicit Capability Boundaries

Capability Boundary
TX power telemetry Device sends 0x1F00 in all modes. Verified field offsets (2026-06-25): off30 f32 = forward power watts (PEP), off16 u16/10 = supply voltage, off18 f32 = PA temp Β°C. Device has NO reverse-power field β†’ cannot compute SWR.
ATR-1000 Frontend hooks and status placeholders exist; /WSATR1000 endpoint accepts connections but does not interface with real tuner hardware. Only available SWR source.
Recordings recordings.html page exists; server-side RX MP3 capture via ffmpeg pipe; CW/FT8 menu links were removed (target pages absent)
Authentication Password-based session auth implemented (login page, _auth_tokens, sunmrrc_auth cookie, 30-day validity); all routes and WS endpoints require token

1.5 Architecture Layers

Client Layer
  Mobile browser UI, Web Audio API, WebSocket clients, service worker

Application Layer
  FastAPI app, static file serving, WebSocket endpoints, client fan-out

Signal Layer
  IQ packet intake, spectrum processor, audio demodulator, optional WDSP chain

Device Layer
  SunSDR2 DX UDP control and stream protocol

1.6 Current Project Status

As of 2026-06-30, the RX chain is healthy and the iOS secure-context blocker is resolved via HTTPS/WSS startup (expected mobile entry https://radio.vlsc.net:8889). The TX voice path is fully verified: browser mic β†’ Web Audio EQ/compressor β†’ SAB ring buffer (zero-main-thread) β†’ Opus (worker-owned WebSocket) β†’ server 300 Hz HPF (reclaims ~15% PA headroom from sub-300 Hz waste band) β†’ Python Hilbert SSB (sole path β€” WDSP C-chain removed) β†’ 24-bit IQ β†’ 0xFFFD TX stream. Verified metrics: 37 dB SNR, 96% SSB efficiency, zero audio dropouts (SAB path eliminates main-thread jitter). IQ peak ~0.69, RMS ~0.68 at 100% drive (TX_DRIVE_GAIN=2.8). TX power is set by device DRIVE (0x0017) per band via /api/band_power. Device telemetry provides forward watts, supply voltage, and PA temperature (no SWR β€” see AD-011). COEP credentialless headers enable SharedArrayBuffer for the SAB ring. Remaining open work: control-network configurability (fixed LAN IPs) and ATR-1000 backend endpoint.