viktorиClaude Opus 4.8 cb4e8a9bb1 панель: многостраничная, Last Heard, SSE, контроль доступа
Панель:
 • шесть страниц с маршрутизацией по хэшу: Обзор, Last Heard, Хотспоты,
   Группы, Доступ, Настройки;
 • журнал приходит живым потоком (SSE) вместо опроса раз в две секунды;
 • Last Heard: кто, куда, когда, сколько, через какой хотспот;
 • в таблице хотспотов — ВСЁ, что устройство сообщает в RPTC.

Контроль доступа (два независимых уровня, их легко перепутать):
 • хотспот пускается по паролю — у каждого может быть свой, плюс режим
   «только из списка» и отключение конкретного устройства;
 • абонент (поле src, владелец рации) допускается белым/чёрным списком с
   поддержкой диапазонов. Встроено в штатный хук guard ядра.

Два бага по дороге:
 • поля RPTC читались как colorcode/latitude/longitude, а разборщик отдаёт
   color_code/lat/lon — половина таблицы молча пустовала;
 • столбец «описание» на деле содержит СТРАНУ: именно туда Pi-Star кладёт
   country. Переименован.

tests/test_access.py 20/20, tests/test_panel.py 31/31 (включая наполнение
Last Heard настоящим рукопожатием и голосовым вызовом по UDP).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XvX94Vwy7vXWEuiFm1g9Av
2026-07-29 01:32:46 +09:00

DMR-сервер

Простой Homebrew/MMDVM мастер для внутренней сети: несколько хотспотов Pi-Star, веб-панель с группами и живым журналом, попугай (эхотест) на TG 9990.

Ноль зависимостей — только python3 (3.10+). На Debian 13 действует PEP 668, и pip install в систему запрещён; venv ради пары библиотек — лишний слой, который однажды сломается. Поэтому всё на stdlib.

Установка

sudo bash install.sh

Ставит код в /opt/dmr-server, конфиг в /etc/dmr-server/config.json, заводит юнит systemd под отдельным пользователем и печатает адрес панели с паролем. Повторный запуск безопасен — конфиг не перезаписывается.

Настройка Pi-Star

Configuration → DMR Master: адрес сервера, порт 62031, пароль — значение passphrase из конфига (обязательно смени умолчание passw0rd).

Что умеет

  • Рукопожатие Homebrew: RPTL → RPTACK+salt → RPTK → RPTC → RPTPING/MSTPONG.
  • Групповые вызовы: кадр от одного хотспота уходит всем остальным, если TG есть в списке групп.
  • Приватные вызовы: туда, где абонента слышали последним; если не слышали ни разу — всем хотспотам (как в HBlink4).
  • Попугай на 9990, групповой и приватный: записывает передачу и проигрывает обратно.
  • Панель: список хотспотов, добавление/удаление групп, последние вызовы, живой журнал, принудительное отключение хотспота.

Проверка

python3 tests/test_e2e.py

Поднимает настоящий мастер и говорит с ним по UDP кадрами, которые шлёт MMDVMHost: рукопожатие, отказ по неверному паролю, keepalive, доставка группового вызова между двумя хотспотами, отсутствие эха отправителю, фильтр по разрешённым группам, приват. Проверяет и то, что легко испортить: длину кадра 55 байт, переписывание peer_id, дословную копию stream_id и неизменность бёрста.

Устройство

Файл Что делает
dmrsrv/analyzer.py разбор и сборка кадров Homebrew/DMR
dmrsrv/server.py ядро мастера: рукопожатие, реестр хотспотов, маршрут в эфир
dmrsrv/router.py кому пересылать кадр + подстановка peer_id получателя
dmrsrv/parrot.py эхотест 9990
dmrsrv/dmr_voice.py, bptc.py пересборка LC — нужна только приватному попугаю
dmrsrv/panel.py веб-панель на http.server
dmrsrv/config.py конфиг с атомарным сохранением
dmrsrv/state.py состояние и журнал для панели

Ядро протокола форкнуто из viktor/dmrhubv2 (~1300 строк из 31700) — там оно уже обкатано на живом эфире. Отрезаны портал, БД, мосты, алерты, динамические подписки.

Перед правкой протокола прочти docs/PROTOCOL.md. Спецификация 2015 года врёт в нескольких местах, включая собственный тест-вектор auth-хеша; там записано, где именно и почему прав код, а не бумажка.

Ограничения

  • Один сервер = одна сеть, без транков между серверами (OpenBridge не реализован).
  • Группы статические, из панели. Динамических подписок через RPTO нет.
  • Панель по HTTP с Basic-авторизацией — рассчитана на доверенную внутреннюю сеть. Наружу выставлять только за HTTPS-прокси.
S
Описание
Простой Homebrew/MMDVM DMR-мастер на stdlib для Pi-Star: группы, панель, попугай 9990
Readme
121 KiB
Languages
Python 97%
Shell 3%