mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 20:37:33 +00:00
fix(tci): выключение TUNE не забывало хозяина эфира — уход клиента рубил чужую передачу
Задний фронт передачи ловился только по rfTransmitting, а выключение TUN гасит эфир изнутри SetTune: там SetMOX(False) шлёт rfTransmitting, пока FTuning ещё True (флаг сбрасывается строкой ниже, см. RadioController.SetTune), поэтому TxNow оставался True и ForgetTxOwner не звался. Следующий за этим Changed(rfTuning) обработчик игнорировал вовсе. Итог: клиент сделал «tune:0,true» и стал хозяином эфира, оператор выключил TUN кнопкой (тогда сброс в DispatchCommand не срабатывает — команды-то не было), позже нажал PTT сам, а когда сокет клиента закрылся, HandleDisconnect → StopTxOf всё ещё видел его хозяином и снимал ОПЕРАТОРСКУЮ передачу. Ровно то, что комментарий у ForgetTxOwner обещает не допускать. Теперь фронт ловится и по rfTuning. На стенде — сценарий целиком: клиент поднимает TUN, оператор гасит его сам и встаёт в эфир, уход клиента передачу не трогает (негативный контроль: с прежним условием проверка падает). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+6
-1
@@ -3599,7 +3599,12 @@ begin
|
||||
// SetMOX, который её и читает. Итог на живом железе: клиент на слайсе
|
||||
// поднимал эфир, а модуляция шла с микрофона оператора, то есть в эфир —
|
||||
// тишина.
|
||||
if (Field = rfTransmitting) and (FController <> nil) then
|
||||
// ★Слушаем и rfTuning: выключение TUN гасит эфир изнутри SetTune, где
|
||||
// SetMOX(False) шлёт rfTransmitting, пока FTuning ещё True (сброс флага идёт
|
||||
// строкой ниже). Заднего фронта по одному rfTransmitting тут не видно, и
|
||||
// хозяин эфира оставался протухшим: уход того клиента когда-нибудь потом
|
||||
// снимал уже чужую — операторскую — передачу.
|
||||
if (Field in [rfTransmitting, rfTuning]) and (FController <> nil) then
|
||||
begin
|
||||
TxNow := FController.FTransmitting or FController.FTuning;
|
||||
if FLastTxOn and (not TxNow) then
|
||||
|
||||
@@ -2217,6 +2217,32 @@ begin
|
||||
Sleep(300);
|
||||
Check('после ухода клиента источник снят', not Ctrl.TCIMicRequested);
|
||||
Check('после ухода клиента MOX снят', not Ctrl.FTransmitting);
|
||||
|
||||
// ── TUN: хозяин эфира забывается и на выключении TUNE ──
|
||||
// Клиент поднял TUN, оператор погасил его САМ (кнопкой, не командой TCI),
|
||||
// а потом сам же встал на передачу. Уход клиента не имеет права снять эту
|
||||
// чужую передачу: хозяина эфира обязано было забыть ещё выключение TUN.
|
||||
// ★Задний фронт ловился только по rfTransmitting, а SetTune(False) шлёт
|
||||
// его, пока FTuning ещё True, — владелец оставался протухшим навсегда.
|
||||
C2 := TRawClient.Create;
|
||||
try
|
||||
Check('TUN: клиент подключился', C2.Connect(PORT));
|
||||
C2.WaitText('ready;', 2000);
|
||||
C2.SendText('tune:0,true;');
|
||||
C2.WaitText('tune:', 1000);
|
||||
Check('TUN: эфир поднят клиентом', Ctrl.FTuning and Ctrl.FTransmitting);
|
||||
Ctrl.SetTune(False); // оператор гасит TUN сам
|
||||
Ctrl.SetMOX(True); // и сам встаёт на передачу
|
||||
Check('TUN: оператор в эфире', Ctrl.FTransmitting);
|
||||
C2.Close_;
|
||||
Sleep(300);
|
||||
Check('TUN: уход клиента не снял чужую передачу', Ctrl.FTransmitting);
|
||||
Ctrl.SetMOX(False);
|
||||
finally
|
||||
C2.Close_;
|
||||
C2.Free;
|
||||
end;
|
||||
|
||||
Ctrl.FWDSPReady := False;
|
||||
finally
|
||||
if C <> nil then begin C.Close_; C.Free; end;
|
||||
|
||||
Reference in New Issue
Block a user