From fd8f6e27d164c06d1abf38f972c4eb31241e0b0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=92=D0=B8=D0=BA=D1=82=D0=BE=D1=80?= Date: Thu, 20 Aug 2026 04:18:33 +0900 Subject: [PATCH] =?UTF-8?q?docs:=20=D0=BF=D0=BE=D0=B4=D1=80=D0=BE=D0=B1?= =?UTF-8?q?=D0=BD=D1=8B=D0=B9=20README=20(=D1=80=D0=B0=D0=B7=D0=B1=D0=BE?= =?UTF-8?q?=D1=80=20=D0=BF=D1=80=D0=BE=D0=B5=D0=BA=D1=82=D0=B0=20=D0=BF?= =?UTF-8?q?=D1=80=D0=B8=20=D0=BF=D0=B5=D1=80=D0=B5=D0=BD=D0=BE=D1=81=D0=B5?= =?UTF-8?q?=20=D0=B2=20Gitea)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Старый README сохранён как README.upstream.md. --- README.md | 85 ++++++++++++++++++++++++++++++++++++---------- README.upstream.md | 24 +++++++++++++ 2 files changed, 92 insertions(+), 17 deletions(-) create mode 100644 README.upstream.md diff --git a/README.md b/README.md index 8f698e1..2c4aa99 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,75 @@ -# SMKDMR XLX Client +# SMKDMR XLX Client — Android-клиент подключения к XLX-рефлектору -Android-клиент для подключения к XLX-серверу. +Заготовка мобильного приложения на Kotlin/Jetpack Compose для подключения смартфона к XLX-рефлектору (мультипротокольный рефлектор XLX, используемый в DMR-сетях) без хотспота и радиостанции. Сейчас приложение содержит один экран: ввод адреса и порта рефлектора, выбор комнаты/модуля, позывного и DMR ID, отправку тестовой UDP-датаграммы и режим PTT, который передаёт сырой PCM-звук с микрофона по UDP. -## Сейчас готово +Полноценным DMR-клиентом приложение не является и в текущем виде стать не может: как прямо сказано в тексте на главном экране, для настоящего DMR нужны вокодер AMBE+2 и кадры протокола MMDVM Homebrew, ни того ни другого в коде нет. Проект — испытательный стенд для будущего транспортного слоя. -- Базовый Android-проект на Kotlin и Jetpack Compose. -- Первый экран подключения. -- Выбор IP/домена XLX-сервера. -- Выбор порта. -- Выбор комнаты/модуля. -- Простая валидация ввода. +## Стек -## Следующий этап +- Kotlin, Jetpack Compose (Material 3, Compose BOM 2026.01.00), `activity-compose`. +- Android Gradle Plugin 9.0.1, Kotlin Compose compiler plugin 2.2.21, Gradle Kotlin DSL. +- `compileSdk`/`targetSdk` 36, `minSdk` 26, applicationId `ru.smkdmr.xlxclient`. +- Android SDK напрямую: `AudioRecord` (PCM 16 бит, 8 кГц, моно), `DatagramSocket`/`DatagramPacket`, `kotlinx.coroutines`. +- Внешнее «железо»/сеть: XLX-рефлектор по UDP (в тестовом профиле — порт 62030, модуль F). -1. Добавить модель настроек подключения. -2. Сохранять последний сервер, порт и комнату локально. -3. Реализовать транспортный слой XLX. -4. Добавить экран состояния соединения. -5. Добавить журнал событий подключения. +## Структура -## Сборка +| Путь | Назначение | +|---|---| +| `settings.gradle.kts` | Имя проекта `SMKDMR`, модуль `:app`, репозитории google/mavenCentral. | +| `build.gradle.kts` | Корневой файл: объявление плагинов AGP и Compose compiler. | +| `app/build.gradle.kts` | Конфигурация модуля: SDK, версия `0.1.0`, Compose, зависимости. | +| `app/src/main/AndroidManifest.xml` | Разрешения `INTERNET` и `RECORD_AUDIO`, единственная activity-лаунчер. | +| `app/src/main/java/ru/smkdmr/xlxclient/MainActivity.kt` | Весь код приложения (469 строк): экран `XlxConnectionScreen`, выпадающий список комнат `RoomPicker`, блок статуса, функция `sendUdpProbe`, класс `UdpVoiceTestClient` с фоновым потоком записи и отправки звука. | +| `app/src/main/res/values/styles.xml` | Тема `Theme.SMKDMR`. | +| `app/proguard-rules.pro` | Пустая заготовка. | +| `README.upstream.md` | Прежний README автора. | -Откройте проект в Android Studio и выполните сборку модуля `app`. +## Как запустить + +Gradle wrapper в репозитории отсутствует (`gradlew`, `gradle/wrapper/` не закоммичены), поэтому сборка из командной строки «как есть» невозможна. + +Способ из авторского README: + +1. Открыть каталог проекта в Android Studio (версия с поддержкой AGP 9.0.1). +2. Дать среде синхронизировать Gradle и создать wrapper. +3. Собрать и запустить модуль `app` на устройстве или эмуляторе с Android 8.0+. + +После установки wrapper'а сборка из консоли: `./gradlew :app:assembleDebug`. + +На экране: заполнить IP/домен, порт, комнату, позывной и DMR ID, кнопкой «Проверить UDP подключение» отправить пробную датаграмму, удержанием кнопки PTT — начать передачу PCM-потока. При первом нажатии PTT запрашивается разрешение на микрофон. + +## Конфигурация + +Файлов настроек, переменных окружения и сохранения состояния нет. Параметры вводятся на экране и живут только в памяти процесса (`rememberSaveable`). Значения по умолчанию зашиты константами в `MainActivity.kt`: + +| Константа | Назначение | Значение | +|---|---|---| +| `TEST_HOST` | Адрес рефлектора | `212.3.149.253` (тот же адрес, что у XLX 391 / SMK в репозитории `pistar`) | +| `TEST_PORT` | UDP-порт | `62030` (порт DMR master для MMDVM) | +| `TEST_ROOM` | Комната/модуль | `F` (по подписи в UI — тестовый модуль) | +| `TEST_CALLSIGN` | Позывной | `PHOENIX` | +| `TEST_DMR_ID` | DMR ID | `1030217` | +| `AUDIO_SAMPLE_RATE` | Частота дискретизации | `8000` | +| `AUDIO_PACKET_SIZE` | Размер аудиопакета, байт | `320` | +| `defaultRooms` | Список модулей в выпадающем списке | `A`–`H` | + +Формат отправляемых пакетов — самодельный текстовый: `SMKDMR-PROBE|CALL=…|ID=…|ROOM=…` для пробы и заголовок `SMKDMR-PCM|CALL=…|ID=…|ROOM=…|SEQ=…|` плюс сырой PCM для PTT. Протоколом XLX/MMDVM это не является, рефлектор такие пакеты отбросит. + +## Состояние + +Прототип одного дня, работа не продолжена. Все 17 коммитов сделаны 2026-05-08, последний коммит — 2026-05-08. Версия приложения `0.1.0`. + +Из заявленного в авторском README сделаны только экран подключения и валидация ввода; далее добавлен экспериментальный режим PTT с передачей PCM по UDP. + +## Что не доделано + +- Нет транспортного слоя XLX/DMR: не реализованы кадры MMDVM Homebrew (login/RPTL, RPTK, DMRD), нет вокодера AMBE+2, нет приёма входящего звука и воспроизведения. Передаётся несовместимый самодельный формат. +- Нет обратной связи о соединении: `sendUdpProbe` считает отправку датаграммы успехом, ответ не читается (`soTimeout` выставлен, но `receive` не вызывается). Экрана состояния соединения и журнала событий, заявленных в авторском README, нет. +- Нет модели настроек и сохранения последнего сервера/порта/комнаты между запусками — соответствующие пункты плана автора не выполнены. +- Весь код в одном файле `MainActivity.kt`, архитектурного разделения (ViewModel, репозиторий) нет. +- Не закоммичен Gradle wrapper, из-за чего сборка вне Android Studio невозможна; нет CI. +- Тестов нет ни одного, при этом в зависимостях объявлен `androidTestImplementation(composeBom)`. +- Нет иконки приложения (ссылки на launcher-иконки удалены отдельным коммитом), нет строковых ресурсов и локализации — тексты зашиты в код по-русски. +- В коде остались личные тестовые данные: реальный IP рефлектора, позывной и DMR ID, подставляемые в поля по умолчанию. +- Маркеров TODO/FIXME в коде нет. diff --git a/README.upstream.md b/README.upstream.md new file mode 100644 index 0000000..8f698e1 --- /dev/null +++ b/README.upstream.md @@ -0,0 +1,24 @@ +# SMKDMR XLX Client + +Android-клиент для подключения к XLX-серверу. + +## Сейчас готово + +- Базовый Android-проект на Kotlin и Jetpack Compose. +- Первый экран подключения. +- Выбор IP/домена XLX-сервера. +- Выбор порта. +- Выбор комнаты/модуля. +- Простая валидация ввода. + +## Следующий этап + +1. Добавить модель настроек подключения. +2. Сохранять последний сервер, порт и комнату локально. +3. Реализовать транспортный слой XLX. +4. Добавить экран состояния соединения. +5. Добавить журнал событий подключения. + +## Сборка + +Откройте проект в Android Studio и выполните сборку модуля `app`.