# cudaSDR Protocol 2 Worklog Date: 2026-04-13 This file records the Protocol 2 related work completed in this repository so future sessions can quickly restore context. ## Implemented Earlier In This Session History - Added separate openHPSDR Protocol 2 transport implementation: - `src/DataEngine/cusdr_protocol2_io.h` - `src/DataEngine/cusdr_protocol2_io.cpp` - Added separate Protocol 2 discovery implementation: - `src/DataEngine/cusdr_discoverer_P2.h` - `src/DataEngine/cusdr_discoverer_P2.cpp` - Wired Protocol 2 into the existing project flow without replacing Protocol 1. - Updated `DataIO` so it delegates network start/stop and receive path to the separate Protocol 2 module when the selected device reports `protocolVersion >= 2`. - Added Protocol 2 fallback search after Protocol 1 and fixed the `Search` button path so manual search also tries Protocol 2. - Added initial RX-only Alex support for Protocol 2: - General packet enables Alex. - High Priority packet sends `Alex 0`. - Filters switch automatically by band/frequency using existing Alex settings. ## Implemented Today ### 1. Device capability model for Protocol 2 - Extended `TNetworkDevicecard` in `src/cusdr_settings.h` with Protocol 2 specific fields: - `adcCount` - `ddcCount` - `dspClockHz` - `iqFormatFlags` - `phaseWords` - `hasAlex0` - `hasAlex1` ### 2. Separate board profile helper - Added: - `src/DataEngine/cusdr_protocol2_profile.h` - `src/DataEngine/cusdr_protocol2_profile.cpp` - This helper maps Protocol 2 board ID to default hardware capabilities and human-readable model name. - It also provides a summary string for UI device lists. ### 3. Discovery improvements for Protocol 2 - Updated `src/DataEngine/cusdr_discoverer_P2.cpp` to: - use board profiles, - fill the new capability fields in `TNetworkDevicecard`, - parse extra discovery reply fields from the documentation: - byte 20: number of implemented DDCs, - byte 21: frequency vs phase word, - byte 22: supported IQ/endian formats. - Updated `src/DataEngine/cusdr_discoverer_P1.cpp` to initialize the new fields to safe defaults for Protocol 1 devices. ### 4. Protocol 2 initialization based on actual device profile - Updated `src/DataEngine/cusdr_protocol2_io.cpp`: - fixed General packet bit handling, - enabled phase-word mode where required, - selected IQ format only when the discovery flags say it is supported, - used discovered/default ADC count in the DDC Specific packet, - routed DDCs across ADCs, - limited receiver count to hardware DDC count, - used board DSP clock to compute phase words, - preserved RX-only behavior. ### 5. Data engine behavior for Protocol 2 devices - Updated `src/DataEngine/cusdr_dataEngine.cpp` so Protocol 2 devices: - are treated as modern integrated hardware instead of legacy Mercury/Penelope stacks, - automatically clamp receiver count to discovered DDC count, - publish Hermes firmware field from the Protocol 2 discovery result for existing UI/status paths, - enable Alex UI only if the selected Protocol 2 board profile says Alex is present. ### 6. UI modernization for Protocol 2 devices - Updated `src/cusdr_networkWidget.cpp` so the device list shows a summary instead of only IP address. - Updated `src/GL/cusdr_oglDisplayPanel.h` and `src/GL/cusdr_oglDisplayPanel.cpp` so the top status display uses the real Protocol 2 model name instead of always showing `Hermes`. ### 7. Documentation-driven corrections made today - Re-read local documentation: - `doc/openHPSDR Ethernet Protocol v4.3.docx` - Corrected Protocol 2 board naming and assumptions from the document: - board 1: `Hermes / ANAN-10/100` - board 2: `Hermes / ANAN-10E/100B` - board 5: `Orion MkII / ANAN-7/8000DLE` - board 10: `Saturn / ANAN-G2` - Corrected one important capability assumption: - board 2 no longer auto-enables Alex RX support, because the document indicates no Alex receive filters for that board. ## Build Status - Full build completed successfully: - `make -j4` - Output binary: - `bin/cudaSDR` ## Additional Fix Applied Later Today ### Protocol 2 stop path hardening - Investigated the stop path after a reported crash when pressing `Stop` with a Protocol 2 device. - Confirmed that the shutdown flow was effectively hitting Protocol 2 stop twice: - first through `DataEngine::stop() -> DataIO::networkDeviceStartStop(0)`, - then again through `DataIO::stop() -> Protocol2DataPath::stop()`. - Updated `src/DataEngine/cusdr_protocol2_io.cpp` so that: - `Protocol2DataPath::stop()` only sends the final `run = 0` High Priority packet if the path was actually running, - `networkDeviceStartStop(0)` returns immediately if Protocol 2 is already stopped, - `closeSockets()` explicitly disconnects timer and socket signals before deletion. - This removes the most obvious duplicate-stop race and reduces the chance of a timer/socket callback firing during teardown. - Build was re-checked after this fix: - `make -j4` - success ### Still needs runtime verification - This stop-path fix is compile-verified but still needs validation on real Protocol 2 hardware. - If the transceiver still does not stop cleanly, the next thing to verify is whether the specific board expects more than a single `High Priority run = 0` packet before socket teardown. ## Additional Investigation And Fixes After Emulator Testing ### 1. Cross-thread DataIO control calls - Emulator testing showed that Protocol 2 startup and shutdown were still unreliable. - Investigation found that `DataIO` is moved to its own `QThread`, but `DataEngine` was still calling these methods directly from another thread: - `sendInitFramesToNetworkDevice(...)` - `networkDeviceStartStop(...)` - `stop()` - Updated `src/DataEngine/cusdr_dataEngine.cpp` to route those calls through: - `QMetaObject::invokeMethod(..., Qt::BlockingQueuedConnection)` - This was done so the Protocol 2 sockets and timers are manipulated from the `DataIO` thread they belong to. ### 2. Additional Protocol 2 stop crash findings - User logs then showed: - `QObject::killTimer: Timers cannot be stopped from another thread` - `QObject::~QObject: Timers cannot be stopped from another thread` - `DataEngine:: data IO thread not yet finished...` - This indicated there were still object-lifetime issues during teardown, not only packet-order issues. ### 3. DataIO destructor bug in Protocol 2 mode - Found a concrete bug in `src/DataEngine/cusdr_dataIO.cpp`: - in Protocol 2 mode, `m_dataIOSocketOn` can be true while `m_dataIOSocket` is never created, - but `DataIO::~DataIO()` still dereferenced `m_dataIOSocket`. - Fixed destructor logic so the legacy socket is only closed/deleted when the pointer is valid. - This was a direct segfault candidate in Protocol 2 shutdown. ### 4. Sound output teardown issue - Found that `DataIO::stop()` was stopping and deleting `CSoundOut` while Protocol 2 shutdown was already in progress. - Adjusted `src/DataEngine/cusdr_dataIO.cpp` so: - `DataIO::stop()` no longer deletes the sound object, - `CSoundOut` shutdown is deferred to `DataIO::~DataIO()`. - This was done to reduce cross-thread/timer teardown problems during the live stop sequence. ### Current status after these fixes - Build re-checked successfully after each change: - `make -j4` - Protocol 2 stop handling is more robust than before, but user testing still shows there may be at least one remaining shutdown/lifetime issue. - Most likely next area: - final deletion order of `DataIO` / `Protocol2DataPath` and their child `QObject`s after `m_dataIOThread->quit()`. ## Known Limitations / Remaining Work - Protocol 2 implementation is still RX-only. - Protocol 2 Alex support currently sends `Alex 0` only. - Boards with `Alex1` support such as Orion MkII / SATURN are not yet fully mapped to the second Alex register according to Appendix D. - Full XML or extended hardware-description discovery modes (`board 254/255`) are not implemented. - Wideband Protocol 2 path is still not integrated. - Some UI sections still conceptually assume old `Metis/Hermes` naming internally even though the visible device/model handling is now better. ## Good Starting Points For Next Session - If continuing Protocol 2 work, read these files first: - `src/DataEngine/cusdr_protocol2_profile.cpp` - `src/DataEngine/cusdr_discoverer_P2.cpp` - `src/DataEngine/cusdr_protocol2_io.cpp` - `src/DataEngine/cusdr_dataEngine.cpp` - `src/cusdr_networkWidget.cpp` - `src/GL/cusdr_oglDisplayPanel.cpp` - For documentation reference, use: - `doc/openHPSDR Ethernet Protocol v4.3.docx` - Highest value next task: - implement proper `Alex1/BPF2/RX2` handling for Protocol 2 boards that support a second Alex register.