12 KiB
12 KiB
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.hsrc/DataEngine/cusdr_protocol2_io.cpp
- Added separate Protocol 2 discovery implementation:
src/DataEngine/cusdr_discoverer_P2.hsrc/DataEngine/cusdr_discoverer_P2.cpp
- Wired Protocol 2 into the existing project flow without replacing Protocol 1.
- Updated
DataIOso it delegates network start/stop and receive path to the separate Protocol 2 module when the selected device reportsprotocolVersion >= 2. - Added Protocol 2 fallback search after Protocol 1 and fixed the
Searchbutton 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
TNetworkDevicecardinsrc/cusdr_settings.hwith Protocol 2 specific fields:adcCountddcCountdspClockHziqFormatFlagsphaseWordshasAlex0hasAlex1
2. Separate board profile helper
- Added:
src/DataEngine/cusdr_protocol2_profile.hsrc/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.cppto:- 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.cppto 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.cppso 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.cppso the device list shows a summary instead of only IP address. - Updated
src/GL/cusdr_oglDisplayPanel.handsrc/GL/cusdr_oglDisplayPanel.cppso the top status display uses the real Protocol 2 model name instead of always showingHermes.
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
- board 1:
- 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
Stopwith 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().
- first through
- Updated
src/DataEngine/cusdr_protocol2_io.cppso that:Protocol2DataPath::stop()only sends the finalrun = 0High 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 = 0packet 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
DataIOis moved to its ownQThread, butDataEnginewas still calling these methods directly from another thread:sendInitFramesToNetworkDevice(...)networkDeviceStartStop(...)stop()
- Updated
src/DataEngine/cusdr_dataEngine.cppto route those calls through:QMetaObject::invokeMethod(..., Qt::BlockingQueuedConnection)
- This was done so the Protocol 2 sockets and timers are manipulated from the
DataIOthread they belong to.
2. Additional Protocol 2 stop crash findings
- User logs then showed:
QObject::killTimer: Timers cannot be stopped from another threadQObject::~QObject: Timers cannot be stopped from another threadDataEngine:: 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_dataIOSocketOncan be true whilem_dataIOSocketis never created, - but
DataIO::~DataIO()still dereferencedm_dataIOSocket.
- in Protocol 2 mode,
- 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 deletingCSoundOutwhile Protocol 2 shutdown was already in progress. - Adjusted
src/DataEngine/cusdr_dataIO.cppso:DataIO::stop()no longer deletes the sound object,CSoundOutshutdown is deferred toDataIO::~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/Protocol2DataPathand their childQObjects afterm_dataIOThread->quit().
- final deletion order of
Known Limitations / Remaining Work
- Protocol 2 implementation is still RX-only.
- Protocol 2 Alex support currently sends
Alex 0only. - Boards with
Alex1support 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/Hermesnaming 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.cppsrc/DataEngine/cusdr_discoverer_P2.cppsrc/DataEngine/cusdr_protocol2_io.cppsrc/DataEngine/cusdr_dataEngine.cppsrc/cusdr_networkWidget.cppsrc/GL/cusdr_oglDisplayPanel.cpp
- For documentation reference, use:
doc/openHPSDR Ethernet Protocol v4.3.docx
- Highest value next task:
- implement proper
Alex1/BPF2/RX2handling for Protocol 2 boards that support a second Alex register.
- implement proper
Additional Fixes On 2026-04-14
1. Protocol 2 control-timing corrections
- Re-read the local protocol document and verified the command timing requirements again:
High Priority/ C&C must be sent at least once per second,100 msis the recommended periodic rate,- packets should also be sent when relevant data changes.
- Updated
src/DataEngine/cusdr_protocol2_io.cppso Protocol 2 now reacts immediately to settings changes instead of relying only on the100 msheartbeat:- center/VFO frequency changes,
- current receiver changes,
- band changes,
- Alex config/state changes,
- sample-rate changes,
- DDC dither/random changes,
- number-of-receivers changes.
General,DDC Specific, andHigh Prioritypackets are now refreshed according to the type of change, and DDC sockets are rebuilt if the active RX count changes.
2. Protocol 2 wideband support integrated
- Re-read the
Widebandsections ofdoc/openHPSDR Ethernet Protocol v4.3.docx. - Implemented Protocol 2 wideband receive support in:
src/DataEngine/cusdr_protocol2_io.hsrc/DataEngine/cusdr_protocol2_io.cpp
- Added Protocol 2 wideband socket handling:
- bind UDP wideband receive socket on base port
1027, - receive raw ADC wideband packets,
- track per-port sequence numbers,
- reassemble a full wideband block into
io->wb_queuefor the existing wideband DSP/display pipeline.
- bind UDP wideband receive socket on base port
- Updated Protocol 2
General packetwideband fields from the document:- bytes
21..22: wideband base port1027, - byte
23: enable bit for ADC0 wideband, - bytes
24..25:512samples per packet, - byte
26:16-bit samples, - byte
27:20 msupdate rate, - byte
28: packets per frame fromSettings::getWidebandBuffers().
- bytes
- Added live handling for
widebandDataChanged(...)so Protocol 2 can enable/disable wideband by resending theGeneral packetwhile running. - When wideband is disabled, the partial Protocol 2 wideband accumulator is cleared and the wideband spectrum display is reset.
3. UI wideband button now controls the actual stream
- Investigated the existing UI and found the
Widebandbutton only showed/hid the dock widget. - It did not previously toggle the actual hardware wideband data stream.
- Updated
src/cusdr_mainWidget.cppso theWidebandbutton now:- sets
widebandData, - sets
widebandStatus, - shows/hides the dock.
- sets
- Updated dock visibility handling so manual close/open remains synchronized with both UI state and data-stream state.
- Also removed the old behavior where the button stayed disabled merely because
widebandDatawas off in the saved settings.
4. Protocol 1 live wideband toggle aligned with UI
- Updated
src/DataEngine/cusdr_dataEngine.handsrc/DataEngine/cusdr_dataEngine.cppsowidebandDataChanged(...)now reissues the legacy start command while the data engine is already running:0x03with wideband,0x01without wideband.
- Protocol 2 keeps its own separate live wideband handling inside
Protocol2DataPath, so the legacy restart command is skipped for Protocol 2 devices.
5. Build re-check
- Rebuilt after the wideband work:
make -j4- success
Current status after wideband integration
- Protocol 2 now has:
- periodic and change-driven command refresh,
- integrated wideband receive path,
- UI-triggered wideband enable/disable behavior.
- This is compile-verified.
- Runtime validation on real Protocol 2 hardware is still required for:
- actual wideband packet cadence,
- live on/off switching while running,
- board-specific wideband constraints such as fixed packets-per-frame behavior on some hardware.