Files
ewsdr/doc/CAT_STATUS.md
T
ew8bakandClaude Opus 5 2d15da0462 feat(cat): CAT-порт на каждый слайс + Auto TX (эталон SmartSDR CAT)
Внешняя программа управляет отдельным слайсом как отдельным трансивером
через свой TCP-порт. COM-порты и 19090 остаются за главным приёмником
(слайс A) и не тронуты.

Протокол не дублируется: TCATEngine — чистый парсер поверх записи
callback'ов TCATContext, TCATTcpServer — транспорт поверх движка, поэтому
слайс-CAT = тот же движок с другим контекстом. Новый TCATSliceEndpoint
(движок + TCP-сервер на слот), массивом владеет TCATAdapter. Привязка к
СЛОТУ (буква B..G), не к Id: порт живёт, даже когда слайса нет (PS0).

Auto TX = «Auto Switch TX Slice» из SmartSDR CAT. Вся логика в одной точке
— TRadioController.RequestSliceTx, исполняется в потоке контроллера:
  • пока кто-то уже в эфире (любой источник) — заявка игнорируется,
    перехвата передачи нет никогда;
  • без Auto TX слайс передаёт, только если уже выбран TX-источником;
  • RX; снимает только СВОЮ передачу;
  • TX-источник после отпускания остаётся на слайсе (как в SmartSDR).
На флаге слайса бейдж TX → AutoTX.

Частота слайса — TuneSliceInBand: свобода в пределах ВКЛЮЧЁННОГО диапазона
(трансвертер → его FreqBegin/FreqEnd, иначе band-план), другой диапазон —
отказ. Вне захваченной полосы окно DDC переезжает: доп. пан — центром на
цель (rfPanFreq → UI перекладывает флаги/шапку/зум-бар), пан 0 — центр
посередине между целью и главным VFO и только если оба влезают (общее
железное окно, главный приёмник не оглушаем).

Настройки: вкладка Slices (enable/порт 19091../Auto TX на слайс), персист
в секции cat + device-blob.

Попутно:
  • ZZFL/ZZFH больше не заглушки — новые callback'и кромок фильтра
    (у главного nil → прежний дефолт режима), хелпер SignedPad;
  • FilterIdxFor, AGCModeToUI, BoardUtils.BandEdges;
  • DSP-состояние слайса (NR/NB/SNB/ANF) зеркалится в TCtrlSlice — флаг
    слайса рисовал нули и AGC главного;
  • FUIReady в TMainForm.OnControllerState: адаптеры, создаваемые по ходу
    FormCreate, больше не могут уронить старт рендером до постройки
    виджетов (на этом падал Auto TX из настроек).

Проверено вживую: все порты 19091..19096 слушают, PS;/ZZFA;/MD;/ID;/SM0;/
ZZTX; отвечают; старт со всеми включёнными слайсами чист под gdb.
Документ — doc/CAT_SLICES.md.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-25 13:56:36 +03:00

14 KiB
Raw Blame History

CAT-система EWSDR — статус реализации

Ветка разработки: feature/cat-commands-expansion. Дата последнего обновления: 2026-06-26.

Документ описывает текущее состояние CAT-подсистемы EWSDR: архитектуру, полный перечень реализованных команд, осознанные заглушки и план дальнейших работ. За эталон протокола взят Thetis / PowerSDR (CATParser.cs, CATCommands.cs, CATStructs.xml) — диалект Kenwood TS-2000 + расширения ZZ*.


1. Архитектура

CAT-транспорты ──► TCATEngine (парсер протокола) ──► TCATContext ──► TCATAdapter ──► TRadioController
  serial (4×)         CATEngine.pas                  (callbacks)      CATAdapter.pas      (ядро)
  TCP-сервер          разбор/формат команд                            мост, маршалинг
Файл Назначение
CATEngine.pas (~2270 строк) Движок протокола: разбор <PREFIX><SUFFIX>;, формирование ответов, реализации всех команд Kenwood + ZZ*. Зависит только от RTL.
CATAdapter.pas (~445 строк) Мост к TRadioController. Строит TCATContext: геттеры читают поля контроллера напрямую (CAT-поток, read-only), сеттеры/команды маршалятся в поток контроллера через FController.Invoke. Владеет движком + транспортами.
CATSerial.pas (~313 строк) Менеджер до 4 последовательных портов (виртуальные COM-пары для rigctld/N1MM/WSJT-X).
CATTcp.pas (~507 строк) TCP-сервер (Thetis-совместимый), управление клиентами по GUID (ZZGA/ZZGR).

1.1 Принципы

  • CAT — равноправный клиент контроллера наряду с WebAdapter и GUI. Никаких обращений к MainForm. Только TRadioController.
  • Потокобезопасность. Геттеры читают поля контроллера напрямую (атомарное чтение в CAT-потоке). Сеттеры пишут параметр в scratch-поля (FSyncFreq/FSyncInt/FSyncBool) и зовут FController.Invoke(@SyncXxx) — GUI исполняет через TThread.Synchronize, демон — своей очередью.
  • TCATContext — плоская запись callback'ов (Get*/Set*/Do*). Чтобы пробросить новую возможность контроллера в CAT, достаточно: (1) добавить callback в запись, (2) реализовать в адаптере геттер/сеттер/sync, (3) зарегистрировать в TCATAdapter.Create, (4) переписать тело команды в движке.
  • Формат команд:
    SET:  <PREFIX><SUFFIX>;     (suffix = значение)
    GET:  <PREFIX>;             (suffix пустой)
    Resp: <PREFIX><VALUE>;
    Err:  ?;  (неверный формат)  |  E;  (ошибка выполнения)
    
    Расширенные ZZ* дублируют Kenwood-команды и добавляют то, чего в Kenwood нет.

1.2 Статистика покрытия (ZZ-команды)

Кол-во
Всего ZZ* в Thetis 315
Реально реализовано в EWSDR 98
Заглушки (отвечают валидным dummy, функции нет) ~211
Совсем не обрабатываются (вернут ?;) 7

Большинство заглушек закрыть нечем — в EWSDR физически отсутствует соответствующий тракт (см. §4).


2. Что сделано

2.1 Реализованные команды Kenwood (одиночный префикс)

Команда Функция Маппинг на контроллер
FA / FB VFO A / B частота (11 цифр, Гц) Set/GetVfoA, Set/GetVfoB
FR приёмный VFO (0/1) Set/GetActiveVfo
FT передающий VFO / split ZZSP
FW / SH / SL ширина фильтра (индекс пресета) Set/GetFilterIdx
MD режим (Kenwood-код) Set/GetMode
GT режим AGC (0=FAST…4=OFF) Set/GetAGCMode
AG громкость AF Set/GetVolume
PC мощность TX 0100 % Set/GetDriveLevel
NB шумоподавитель (NB) Set/GetNBMode
NT автонотч (ANF) Set/GetANFEnabled
SM S-метр (шкала Kenwood 00000030) GetSMeter
IF составной статус (37 байт) freq/mode/tx/split
ID идентификатор (TS-2000 = 019) const
PS питание/состояние GetRunning
TX / RX передача / приём SetTransmitting
BU / BD смена диапазона ±1 DoBandUp/Down
UP / DN / RU / RD шаг настройки ±1 DoTuneUp/Down
SQ шумоподавитель FM (шкала 0–255) Set/GetSquelchLevel+On
CN / CT CTCSS тон / вкл Set/GetCTCSSTone, …On
OF / OS репитер: offset / направление Set/GetFMRptOffset, …Dir

2.2 Реализованные расширенные ZZ* (выборочно, наиболее значимые)

VFO/режим/фильтр: ZZFA ZZFB ZZFI ZZFL ZZFH ZZFM ZZMD ZZFT ZZSP, диапазоны: ZZBS ZZBU ZZBD ZZBA ZZBI ZZBM, AGC/громкость/мощность: ZZGT ZZAG ZZPC ZZPD ZZAR, шумодав/нотч: ZZNA ZZNB ZZNR ZZNS ZZNT ZZNL ZZNN, FM: ZZSQ ZZSO ZZTA ZZTB ZZST, CTUN: ZZCN, S-метр/телеметрия: ZZSM, шаги VFO: ZZAU ZZBP ZZSU ZZSA ZZSB, передача: ZZTX ZZRX, сервис: ZZID ZZRV ZZGA ZZGR.

2.3 Сделано в ветке feature/cat-commands-expansion

Все команды ниже были заглушками и стали рабочими — функционал в TRadioController уже существовал, но не был проброшен в CAT.

Группа 1 — Split TX

  • ZZSP, FT — split (TX на VFO-B), FR — выбор приёмного VFO, split-байт в составном IF.
  • В TRadioController добавлен публичный метод SetSplit(TxOnB) (флаг FSplitTxB + PushNetworkState + Changed(rfActiveVfo)). TX-частоту радио берёт из ActiveTXFreqHz (учитывает split).

Группа 2 — FM Squelch

  • SQ (шкала Kenwood 0255), ZZSQ (0100 %), ZZSO (вкл/выкл).
  • Маппинг: SetFMSquelch / SetFMSquelchLevel. Уровень>0 включает шумоподавитель.

Группа 3 — FM CTCSS

  • CT/ZZTA (вкл/выкл), CN (1-based тон 0138), ZZTB (0-based 0037).
  • Маппинг: SetFMCTCSS / SetFMCTCSSTone, таблица CTCSS_TONES[38].

Группа 4 — FM-репитер

  • OF (offset, 9 цифр Гц), OS (направление).
  • Трансляция направлений Kenwood (0=simplex,1=+,2=) ↔ внутренние RPT_NONE/MINUS/PLUS. Маппинг: SetFMRpt / SetFMRptOffset.

Группа 5 — FM tuning step

  • ZZST (индекс 0003: 6.25/12.5/20/25 кГц). Маппинг: SetFMStep.

Доп. команды (вторая итерация)

Команда Что Примечание
ZZSO Squelch on/off завершает группу squelch
ZZNT ANF on/off раньше ошибочно был алиасом NB
ZZCN CTUN (click-tune) RX1 новый callback Get/SetCTunSetCTun
ZZAR RX1 AGC-T / RF gain (±nnn) новый callback Get/SetAGCTopSetAGCTop (кламп 20120 dB)
ZZAU/ZZBP сдвиг VFO A/B вверх на шаг nn (0014) исправлен баг: были заалиашены на ZZFA/ZZAP
ZZSU шаг активного VFO вверх DoTuneUp

Шкала шагов ZZAU/ZZBPStepIdxToHz (зеркало Thetis Step2Freq): 1 Гц, 10, 25, 50, 100, 250, 500, 1к, 5к, 9к, 10к, 100к, 250к, 500к, 1 МГц.

Новые callback'и в TCATContext (этой ветки): split, squelch on/level, CTCSS on/tone, FM repeater dir/offset, FM step, AGC-T, CTUN.


3. Что нужно сделать (актуально / есть чем закрыть)

Эти команды — заглушки, но соответствующая функция в EWSDR уже есть или легко добавляется. Приоритетные кандидаты:

Команда(ы) Что Чем закрыть Сложность
ZZCU загрузка CPU (read) телеметрия процесса низкая
ZZMY / ZZQR / ZZQS / ZZQM память каналов (запись/чтение/quick) ChannelStore уже есть средняя
ZZFD FM-девиация (radio button) нужен публичный SetFMDeviation (сейчас только поле FFMDeviation) низкая
ZZDM / ZZDA / ZZPO / ZZDY режим/усреднение/пик/порог спектра UI-параметры спектра средняя
ZZAS RX2 AGC-T — только при появлении RX2

Прежде чем реализовывать новую команду, сверяйся с форматом поля в Thetis/.../CAT/CATStructs.xml (<nsetparms> / <ngetparms>) и телом метода в CATCommands.cs, чтобы ширина/знак значения совпадали.

3.1 Совсем не обрабатываются (вернут ?;)

ZZCU (CPU), ZZDY (DX threshold), ZZPK/ZZPL (речевой компрессор), ZZQA/ZZQB (Quick Play/Rec), ZZVF (VAC stereo). Из них реалистично добавить только ZZCU и (частично) ZZDY.


4. Осознанные заглушки (закрывать нечем)

Команды отвечают валидным dummy-значением для совместимости с управляющим ПО (rigctld, N1MM, WSJT-X, Log4OM), но функции в EWSDR нет. Это ~70 % всех заглушек.

Область Команды (примеры) Причина
Второй приёмник RX2 / sub-RX ZZAB ZZAS ZZBA ZZMB ZZOB, ext BF BG BR DO DQ DR OF OG OH OL SG SH SS один приёмник
TX-DSP тракт mic gain ZZMG/MG, монитор ZZMO/MO, TX-EQ ZZEB/ER/ET, компрессор ZZPK/ZZPL/CF CI CL CM, two-tone ZZUS, VAC ZZVB/ZZVF нет обработки передачи
CW-кейер / CWX ZZKM ZZKS ZZKY ZZCB ZZCD ZZCS, KY KS нет кейера
RTTY / DIGI ZZRA ZZRL, ext RF RH RM RS RY нет RTTY-движка
RIT / XIT RT XT RC RU RD (как RIT), ext RB RF RH нет смещения приёма
Diversity ZZDA(div) ZZDB, ext DA нет диверсити-приёма
Спектр/водопад (внутр.) ext SV SW SX SY SZ WT WU WV WW не управляется по CAT

5. Транспорты

CAT дополнительных слайсов (свой TCP-порт на слайс B..G + Auto TX) вынесен в отдельный документ: CAT_SLICES.md. Тот же движок, другой контекст; транспорты ниже принадлежат главному приёмнику (слайс A).

  • Serial (CATSerial.pas): до 4 портов, параметры (порт/скорость/биты/ чётность/стоп) из TGlobalSettings.CATSerial*, применяются TCATAdapter.ApplySettings. На текущей платформе сборки может быть {$DEFINE CAT_SERIAL_STUB} (см. начало файла) — проверить перед релизом.
  • TCP (CATTcp.pas): сервер на CATTcpPort, включается флагом CATTcpEnabled. Клиенты идентифицируются GUID через ZZGA/ZZGR.

6. Как добавить новую CAT-команду (чек-лист)

  1. Сверить формат в CATStructs.xml + CATCommands.cs (Thetis).
  2. Если нужна новая возможность контроллера — есть ли публичный метод/поле в TRadioController? Если нет — добавить (по образцу SetSplit).
  3. В CATEngine.pas: добавить callback(и) в TCATContext, SafeGet*-хелпер для GET, переписать тело команды (CmdXX или ZZXX).
  4. В CATAdapter.pas: геттер (чтение FController.F*), сеттер + SyncXX (через Invoke), регистрация в TCATAdapter.Create.
  5. Если команда ZZ* ещё не в диспетчере — добавить ветку else if ext = '..'.
  6. Сборка-проверка: lazbuild -B --ws=qt6 ewsdr.lpr (GUI-граф включает CAT; headless-демон ewsdrd CAT не содержит).