Andy Taylor
|
c2406d9f11
|
Remove wxWidgets, port to standalone C++17 with cross-platform support
Replace the wxWidgets dependency with standard C++17 throughout the
entire codebase, producing a clean, portable, thoroughly reviewed CLI
daemon that builds on Linux, Windows, and macOS without any GUI toolkit.
== Removed ==
- GUI application and config editor (DStarRepeaterFrame, DStarRepeaterConfig/)
- GUI widget library (GUICommon/)
- Windows USB drivers (WindowsUSB/)
- Visual Studio solutions and project files (.sln, .vcxproj)
- NSIS installer scripts, platform-specific makefiles
- wxWidgets-specific files (LogEvent, LogRedirect, GMSKModemWinUSB)
- Dead code: unused GUI constants, vestigial command methods, unused
DTMF/queue constants in non-TRX thread variants
== Core conversion (all source files) ==
- wxString -> std::string, wxArrayString -> std::vector<std::string>
- wxFloat32 -> float, wxUint8/16/32 -> uint8_t/16_t/32_t
- wxThread -> std::thread, wxMutex -> std::mutex
- wxStopWatch -> std::chrono::steady_clock
- wxRegEx -> std::regex, wxDynLib -> dlopen/dlsym
- wxFFile -> FILE*, wxTextFile -> std::ifstream
- WX_DECLARE_STRING_HASH_MAP -> std::unordered_map
- volatile -> std::atomic for ring buffer and cross-thread flags
- NULL -> nullptr throughout
== INI config format (MMDVMHost compatible) ==
- [Section]/Key=Value INI format replaces flat key=value
- Config file path is the single required command-line argument:
dstarrepeaterd <config-file>
- [Log] section: FilePath, FileLevel, DisplayLevel, MQTTLevel
(levels 0-6 matching MMDVMHost convention)
- [Paths] section: Data and Audio directories from config
- [Whitelist]/[Blacklist]/[Greylist] file paths from config
- All compile-time path defines (CONF_DIR, LOG_DIR) removed
- Example config: Data/dstarrepeater.ini.example
== Build system ==
- Plain g++ -std=c++17, no wx-config dependency
- Defaults: release build, MQTT on, GPIO auto-detected
- GPIO auto-detection checks uname -s (Linux only) and uname -m
(arm/aarch64) to avoid false match on macOS Apple Silicon
- Zero warnings with -Wall on GCC 13
- Verified on Ubuntu 24.04, Debian Trixie, and Alpine 3.21
== Install layout ==
- Binary: /usr/bin/dstarrepeaterd
- AMBE voice data: /usr/share/dstarrepeater/
- Config directory: /etc/dstarrepeater/ (created on install)
- Example config: /etc/dstarrepeater/dstarrepeater.ini.example
== Cross-platform support ==
- EndianCompat.h: byte-swap functions for Linux, macOS, and Windows
- Serial ports: Win32 CreateFile/ReadFile/WriteFile alongside POSIX
- Sockets: Winsock2 with RAII WSAStartup alongside POSIX
- Sound card: PortAudio for Windows/macOS, ALSA for Linux
- All platform code is additive (#ifdef _WIN32), no Linux code changed
== Standalone logger ==
- Thread-safe file logger with std::mutex and daily UTC rotation
- Level-based filtering for file, display (stdout), and MQTT sinks
- LogLevel enum matches MMDVMHost numbering (1=Debug through 6=Fatal)
- Thread-safe gmtime via gmtime_r/gmtime_s
- Atomic singleton for safe cross-thread access
== Display-Driver MQTT compatibility ==
- All JSON messages match Display-Driver's expected format exactly
- D-Star start/end/lost events with callsigns and source (rf/net)
- BER updates during active RF
- DVAP RSSI signal strength publishing
- Slow-data text forwarding
- MMDVM idle mode transitions
- JSON escaping on all callsign/text fields from over-the-air data
- JSON schema: schema.json with validated $defs structure
== Security and safety fixes ==
- All cross-thread bool flags: std::atomic<bool>
- MQTTConnection m_connected and DVAP m_signal/m_squelchOpen: atomic
- RingBuffer: std::atomic<unsigned int> for ARM correctness
- All sprintf -> snprintf to prevent buffer overflows
- JSON escaping for all MQTT output from untrusted sources
- DVTOOLFileWriter filename sanitization (path traversal prevention)
- Thread-safe localtime_r/localtime_s in DVTOOLFileWriter
- GatewayProtocolHandler: bounded string from network buffer
- Integer underflow guards in protocol handler readData()
- Buffer bounds checks in writePoll()/writeRegister()
- MMDVM printDebug() minimum length guards
- PID file: /var/run with O_NOFOLLOW, PID written for systemd
- Exception-safe createThread() with full cleanup on failure
- Deprecated gethostbyname() replaced with getaddrinfo()
- CRLF stripping in callsign list loader
- Infinite loop exits in DVAP resync() and serial getResponse()
- Null guards in SoundCardReaderWriter::close()
- RingBuffer::hasSpace() off-by-one fixed
== Memory safety ==
- Delete protocol handler, modem, controller on open()/start() failure
- Thread destructors clean up all owned objects with null-after-delete
- Callsign lists properly deleted in TX/RX/TXRX thread no-op setters
- BeaconUnit buffer allocation matched to actual write size (DV_FRAME)
- Null dereference fix in endOfNetworkData() for network-first streams
== Functional fixes ==
- Restored DTMF command execution (system() via checkControl())
- Fixed getControl() parameter order (commands 3-6 were swapped)
- Fixed getStatus() argument order in idle branch (BER was at wrong
position, causing MQTT to report garbage BER when idle)
- Added missing GMSK interface type config parsing
- Fixed IcomController uninitialized buffer and sync check order
- Fixed SplitController format string vulnerability
- Fixed DVAPController dumpPackets() dead loop
- Inline const arrays in DStarDefines.h (ODR compliance)
== Documentation ==
- Comprehensive comments added to all source files
- README.md: quick start, dependency tables, usage guide
- CONFIGURATION.md: complete INI format reference
- MQTT.md: updated for INI config, Display-Driver integration
- BUILD.md: per-platform instructions (Linux, Windows, macOS)
- CHANGELOG.md: version history, newest first
- schema.json: JSON schema for all MQTT messages
Version bumped to 20260319.
|
4 months ago |