Fix IQ data flow: send HP Run=1 before DDC/DUC Specific packets

The emulator (and real hardware) creates ddc_specific_thread (port 1025),
duc_specific_thread (port 1026), and rx_thread[0..3] (ports 1035+) only
after receiving HP Run=1. Previously ConfigureDDCs and SendDUCSpecific
were sent before SetRunAndFreq(True), so both packets arrived at closed
ports and were silently dropped — ddcenable remained -1, rx_thread slept
forever, no IQ data ever arrived, and the 5-second timeout fired Run=0.

Fix: reorder DoConnectDevice to send Run=1 first, then DDC/DUC Specific.
Also add keepalive resend of the cached DDC Specific packet every 500 ms
for the first 5 seconds after start, to handle thread-startup races on
real hardware over the network.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-28 13:31:39 +03:00
co-authored by Claude Sonnet 4.6
parent cd0cf21876
commit 055873a43a
2 changed files with 25 additions and 4 deletions
+17
View File
@@ -121,6 +121,11 @@ type
FPortDUCIQ: Word;
FDirectIP: string; // для unicast discovery
// Кэш DDC Specific — keepalive повторно шлёт первые 5 сек после старта
FCachedDDCSpec: TDDCSpecificPacket;
FCachedDDCValid: Boolean;
FResendCount: Integer;
// Текущее состояние для построения HP пакетов
FCurrentRXFreq: Double;
FCurrentTXFreq: Double;
@@ -398,6 +403,15 @@ begin
if not FNet.FConnected then Continue;
// Отправляем полный HP с частотами и ALEX — как piHPSDR
FNet.SendFullHP;
// Повторно отправляем DDC Specific первые 5 сек после Run=1 (каждые 500 мс).
// ddc_specific_thread на эмуляторе/железе стартует ПОСЛЕ получения Run=1,
// поэтому первый ConfigureDDCs может прийти раньше чем порт 1025 откроется.
if FNet.FRunning and FNet.FCachedDDCValid then
begin
Inc(FNet.FResendCount);
if (FNet.FResendCount <= 100) and (FNet.FResendCount mod 10 = 2) then
FNet.SendDDCSpecific(FNet.FCachedDDCSpec);
end;
end;
end;
@@ -914,6 +928,9 @@ begin
end;
SendDDCSpecific(Pkt);
FCachedDDCSpec := Pkt;
FCachedDDCValid := True;
FResendCount := 0;
end;
procedure THPSDRNetwork.SendDUCSpecific(const Pkt: TDUCSpecificPacket);