diff --git a/TCIAdapter.pas b/TCIAdapter.pas index c4fcd73..df5fee6 100644 --- a/TCIAdapter.pas +++ b/TCIAdapter.pas @@ -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 diff --git a/test/tci/tcitest.pas b/test/tci/tcitest.pas index 51e6516..88ec04d 100644 --- a/test/tci/tcitest.pas +++ b/test/tci/tcitest.pas @@ -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;