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:
2026-08-20 16:06:21 +03:00
co-authored by Claude Opus 5
parent 4b715c8b03
commit 11d8e11ba5
2 changed files with 32 additions and 1 deletions
+6 -1
View File
@@ -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