docs: update file inventory and module header contracts
Refresh both AGENTS guides and clarify module purpose, usage, ownership, threading, return values and wire formats in headers. Remove the unused timeout_heap freed_count field and unimplemented getter.
This commit is contained in:
1 parent
c19eff67f6
commit
a97e8bcc1f
118 files changed
+628
-406
No files matched your search
@@ -19,8 +19,12 @@ tools/chatgui-android/
|
||||
│ ├── instance_lite.h/c # жизненный цикл (старт/стоп/рестарт, ключи)
|
||||
│ ├── utun_config_api.h/c # конфиг-провайдер (Kotlin → C)
|
||||
│ ├── invite_link_c.h/c # старая копия парсера; .c не входит в UTUN_SOURCES
|
||||
│ ├── voice_recorder.h/c # запись голосовых (PCM→Opus→канал)
|
||||
│ └── attachment_sender.h/c # отправка файлов в канал
|
||||
│ ├── voice_recorder.h/c # накопление PCM; voice/file подготовка через общий attachment_send
|
||||
│ ├── attachment_sender.h/c # отправка обычных файлов в канал
|
||||
│ ├── photo_sender.h/c # отправка готовых изображений в канал
|
||||
│ ├── video_sender.h/c # готовый MP4 → attachment_send (канал/PM)
|
||||
│ ├── standby.h/c # фоновые ACTIVE/SLEEP интервалы и отменяемое ожидание
|
||||
│ └── tests/test_standby.c # тесты duty-cycle
|
||||
│
|
||||
├── headless/ # CLI для Linux (тестирование без Android)
|
||||
│ ├── CMakeLists.txt
|
||||
@@ -28,7 +32,8 @@ tools/chatgui-android/
|
||||
│ └── headless_control.c/h # управляющий TCP-сокет (JSON/text протокол)
|
||||
│
|
||||
├── jni_bridge/ # JNI прослойка C ↔ Kotlin
|
||||
│ └── android_jni_bridge.c/h # C API + JNI-функции (компилятся только для Android)
|
||||
│ ├── android_jni_bridge.c/h # C API; JNI-функции — только Android
|
||||
│ └── android_udp_log.c/h # UDP-лог: общий буфер, flush в uasync
|
||||
│
|
||||
├── app/ # Android приложение (Gradle + NDK + Compose)
|
||||
│ ├── build.gradle.kts
|
||||
@@ -45,20 +50,24 @@ tools/chatgui-android/
|
||||
│ │ │ ├── InviteLink.kt # парсер utun://base64blob
|
||||
│ │ │ ├── ConfigProvider.kt # конфиг из DataStore
|
||||
│ │ │ ├── LogManager.kt # лог-менеджер
|
||||
│ │ │ └── ServerEntry.kt # модели данных
|
||||
│ │ │ ├── ServerEntry.kt # модель listen-сокета
|
||||
│ │ │ ├── CallAudioEngine.kt # capture/playback звонка через native voice stack
|
||||
│ │ │ ├── RadioAudioEngine.kt # capture/playback и PTT рации
|
||||
│ │ │ └── UtunConnectionService.kt # Android Telecom ConnectionService для P2P-звонков
|
||||
│ │ ├── viewmodel/
|
||||
│ │ │ └── ChatViewModel.kt # StateFlow для UI
|
||||
│ │ ├── ui/screens/
|
||||
│ │ │ ├── ChannelListScreen.kt # список каналов + join/create
|
||||
│ │ │ ├── ChatScreen.kt # сообщения + ввод
|
||||
│ │ │ ├── JoinChannelDialog.kt # диалог подключения по invite
|
||||
│ │ │ ├── QrScanScreen.kt # CameraX + ML Kit QR-сканер
|
||||
│ │ │ ├── QrScannerPreview.kt # CameraX + ML Kit QR-сканер
|
||||
│ │ │ ├── SettingsScreen.kt # настройки
|
||||
│ │ │ └── LogScreen.kt # лог-просмотр
|
||||
│ │ ├── ui/components/
|
||||
│ │ │ └── MessageBubble.kt # бабблы сообщений + InputBar
|
||||
│ │ └── headless/
|
||||
│ │ └── HeadlessService.kt # фоновый сервис
|
||||
│ │ ├── HeadlessService.kt # foreground-service фонового ядра
|
||||
│ │ └── BootReceiver.kt # запуск фонового сервиса после загрузки устройства
|
||||
│ └── res/
|
||||
│
|
||||
└── doc/ # документация
|
||||
@@ -263,15 +272,27 @@ port=9999
|
||||
- `../../src/chat/invite_link.c/h` — Общий C-код формата invite-ссылок; Android разбирает ссылки в `data/InviteLink.kt`.
|
||||
Старый `libutun_lite/invite_link_c.c` не компилируется текущим списком источников
|
||||
- `libutun_lite/utun_config_api.h/c` — Поставщик конфигурации из Kotlin в C-ядро через callback-интерфейс (get_string, get_int64, get_int)
|
||||
- `libutun_lite/voice_recorder.h/c` — Запись голосовых сообщений: накопление PCM-сэмплов с компрессором, кодирование в Opus-файл, отправка в канал через chat_core
|
||||
- `libutun_lite/voice_recorder.h/c` — Накопление PCM 48 kHz mono с компрессором; stop передаёт запись в общий attachment_send для фонового кодирования и публикации в канал/PM
|
||||
- `src/call/call_audio.h/c` (+ `voice_jitter.cpp`, `call_tones.c`, SoundTouch) — единый голосовой стек звонка (`libutun_voice`), собирается через `src/call/voice_sources.cmake`; Opus encode (PCM→peer) и decode + адаптивный джиттер-буфер + time-stretch (PCM отдаётся через `nativeCallAudioPull`). Аудио I/O в Kotlin (AudioRecord/AudioTrack)
|
||||
- `libutun_lite/attachment_sender.h/c` — Отправка файлов в канал: копирование в media-директорию и регистрация через chat_core (media_index → db_sync)
|
||||
- `libutun_lite/photo_sender.h/c` — Отправка готового изображения в канал с MIME-типом и размерами; подготовка картинки выполняется в Android
|
||||
- `libutun_lite/video_sender.h/c` — Отправка подготовленного MP4 в канал/PM через attachment_send; задача владеет временным cache-файлом
|
||||
- `libutun_lite/standby.h/c` — ACTIVE/SLEEP интервалы фонового режима, callbacks смены фазы и отменяемые wait handles
|
||||
- `jni_bridge/android_udp_log.h/c` — Потокобезопасный буфер логов; timer flush привязан к текущему uasync и снимается при restart
|
||||
- `libutun_lite/utun_sources.cmake` — Общий список источников: `lib/*.c` и рекурсивный `src/*.c` подхватываются автоматически;
|
||||
файлы самой обёртки перечислены в `_cfg_src`, исключения — через `list(FILTER/REMOVE_ITEM)`
|
||||
|
||||
### Kotlin-слой
|
||||
- `data/NativeLib.kt` — Kotlin-обёртка над C-библиотекой: все вызовы из Kotlin транслируются в JNI-функции
|
||||
- `data/CallAudioEngine.kt` — Аудио-движок звонка: AudioRecord/AudioTrack, audio-focus, потоки захвата (feed) / воспроизведения (pull из C-стека)
|
||||
- `data/RadioAudioEngine.kt` — Аудио-движок рации: AudioRecord/AudioTrack, feed/pull native-стека и управление capture/PTT
|
||||
- `data/RadioPttHolds.kt` — Отдельные владельцы ручного PTT: кнопка, overlay и volume-клавиши; отпускание одного не снимает остальные
|
||||
- `data/RadioOverlayService.kt` — Плавающее окно PTT поверх других приложений
|
||||
- `data/ConversationTarget.kt` — Типизированный target канала/PM для асинхронных операций
|
||||
- `data/AudioRecorderManager.kt` — Android-захват PCM голосового сообщения и управление native voice_recorder
|
||||
- `data/CallController.kt` / `CallState.kt` — Управление состоянием и действиями P2P-звонка
|
||||
- `data/CallAudioRouter.kt` — Выбор аудиомаршрута звонка: earpiece/speaker/headset
|
||||
- `data/TelecomCallManager.kt` / `UtunConnection.kt` / `UtunConnectionService.kt` — Интеграция P2P-звонков с Android Telecom
|
||||
- `data/ChatRepository.kt` — Хранилище данных: буферизация сообщений и каналов между C-ядром и UI через StateFlow
|
||||
- `data/InviteLink.kt` — Разбор invite-ссылок: извлекает ID канала, публичный ключ, адреса для подключения
|
||||
- `data/ConfigProvider.kt` — Настройки DataStore и генерация INI-текста для запуска C-ядра
|
||||
@@ -279,8 +300,15 @@ port=9999
|
||||
- `viewmodel/ChatViewModel.kt` — ViewModel: StateFlow-состояние для UI (список каналов, сообщения, статус)
|
||||
- `ui/screens/ChannelListScreen.kt` — Главный экран: список каналов, кнопки Join (по invite-ссылке) и Create
|
||||
- `ui/screens/ChatScreen.kt` — Экран чата: список сообщений + поле ввода
|
||||
- `ui/screens/DmChatScreen.kt` — Экран личной беседы
|
||||
- `ui/screens/MemberListScreen.kt` — Участники канала и действия над выбранным участником
|
||||
- `ui/screens/CallScreen.kt` / `IncomingCallDialog.kt` — Активный и входящий звонок
|
||||
- `ui/screens/PhotoRecordScreen.kt` / `VideoRecordScreen.kt` — Съёмка и подготовка media через CameraX
|
||||
- `ui/screens/PhotoViewerScreen.kt` / `VideoPlayerScreen.kt` — Просмотр локальных изображений и видео
|
||||
- `ui/screens/InviteLinkDialog.kt` — Выдача invite-ссылки и QR
|
||||
- `ui/screens/FirstLaunchScreen.kt` — Первичная настройка приложения
|
||||
- `ui/screens/JoinChannelDialog.kt` — Диалог подключения к каналу: ввод/вставка invite-ссылки, предпросмотр, кнопка Connect
|
||||
- `ui/screens/QrScanScreen.kt` — QR-сканер для invite-ссылок (CameraX + ML Kit)
|
||||
- `ui/screens/QrScannerPreview.kt` — QR-сканер для invite-ссылок (CameraX + ML Kit)
|
||||
- `MainActivity.kt` — Точка входа Android-приложения: навигация между экранами, QrScan → JoinDialog flow
|
||||
|
||||
### Headless
|
||||
|
||||
@@ -1,32 +1,9 @@
|
||||
/*
|
||||
* headless_control.h — JSON control socket for uTun headless mode
|
||||
*
|
||||
* JSON line protocol:
|
||||
* Request: {"id":N,"cmd":"<command>",...params}
|
||||
* Response: {"id":N,"ok":true,"data":{...}} | {"id":N,"ok":false,"error":"..."}
|
||||
* Event: {"event":"<type>",...}
|
||||
*
|
||||
* Commands:
|
||||
* ping — alive check
|
||||
* status — node info, uptime, connections
|
||||
* connect — STCP connect to peer
|
||||
* disconnect — STCP disconnect
|
||||
* connections — list active connections
|
||||
* create_channel — create chat channel
|
||||
* channels — list channels
|
||||
* send — send message to channel
|
||||
* messages — get messages from channel
|
||||
* debug_level — get/set debug levels
|
||||
* subscribe — subscribe to events
|
||||
* join — join channel via invite link
|
||||
* quit — disconnect client
|
||||
*
|
||||
* Events (after subscribe):
|
||||
* log — {"event":"log","level":"info","cat":"ETCP","msg":"..."}
|
||||
* msg — {"event":"msg","ch":"id","author":"hex","ts":123}
|
||||
* peer_online/offline
|
||||
* channel_created/joined
|
||||
*/
|
||||
/* Каркас TCP-управления Android headless: init → регулярный poll → destroy в одном потоке.
|
||||
* ua сейчас не используется; основной рабочий API чата — src/chat/chat_headless_control.h.
|
||||
* JSON line: {"id":N,"cmd":"..."} → {"id":N,"ok":true,"data":...} либо error.
|
||||
* ping/status/connections/debug_level возвращают заглушки; subscribe/quit управляют клиентом.
|
||||
* join/chat_setting обращаются к запущенному instance_lite; прочие команды дают not implemented.
|
||||
* event/broadcast_log отправляют JSON подписанным клиентам. Этот модуль сам ядро не запускает. */
|
||||
#ifndef HEADLESS_CONTROL_H
|
||||
#define HEADLESS_CONTROL_H
|
||||
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
* android_jni_bridge.h — JNI bridge API (C side)
|
||||
*
|
||||
* Provides lifecycle management and callbacks between C core and Kotlin.
|
||||
* For Android, compiled via NDK into libutun_lite.so.
|
||||
* NDK собирает bridge вместе с ядром в libutun.so. Действия передаются в uasync;
|
||||
* callbacks логов/событий вызываются из native-потоков, UI переносит их в свой поток.
|
||||
*/
|
||||
#ifndef ANDROID_JNI_BRIDGE_H
|
||||
#define ANDROID_JNI_BRIDGE_H
|
||||
@@ -51,7 +52,8 @@ void utun_bridge_create_channel(const char* name, const char* channel_id);
|
||||
void utun_bridge_connect_node(const char* address, int port, const char* pubkey_hex);
|
||||
|
||||
/* Join channel via invite link.
|
||||
addr_data format: family(1) + socketId(1) + address(4|16) + port(2 BE) per addr */
|
||||
addrs_data — результат invite_serialize_addrs: Reality-префикс и
|
||||
family(1) + socketId(1) + proto(1) + address(4|16) + port(2 BE) для каждого адреса. */
|
||||
void utun_bridge_join_channel(uint64_t channel_id, uint64_t node_id,
|
||||
const uint8_t* pubkey_bin,
|
||||
const uint8_t* addrs_data, int addr_count,
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/* Android-обёртка отправки обычного файла в канал через chat_core_submit_trampoline.
|
||||
* Строит имя назначения в db_path/media/channel_id, копирование/индексацию выполняет media_index.
|
||||
* 0 = запрос поставлен в uasync, -1 = отказ подготовки. Исходный файл нужен до завершения media-задачи. */
|
||||
#ifndef ATTACHMENT_SENDER_H
|
||||
#define ATTACHMENT_SENDER_H
|
||||
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
/*
|
||||
* instance_lite.h — lightweight uTun instance lifecycle for Android
|
||||
*
|
||||
* Kotlin generates INI config text, passes to instance_lite_start().
|
||||
* C side parses it, creates uasync+ETCP+bgp+chat stack, runs in a pthread.
|
||||
* Mirrors UtunNode::runLoop() from tools/chatgui/transport/utun_node.cpp.
|
||||
* Android-владелец одного ядра: INI из Kotlin → pthread с uasync → core_start + chat_service_start.
|
||||
* UTUN-сервис не запускается. Поток владеет instance/ua; UI передаёт работу через uasync.
|
||||
* Полученные handles заимствованы и могут смениться при restart; сохранять их между рестартами нельзя.
|
||||
*/
|
||||
#ifndef INSTANCE_LITE_H
|
||||
#define INSTANCE_LITE_H
|
||||
@@ -17,14 +15,12 @@ extern "C" {
|
||||
struct UASYNC;
|
||||
struct UTUN_INSTANCE;
|
||||
|
||||
/* Start full uTun stack from INI config text.
|
||||
* Creates a pthread for uasync event loop.
|
||||
* Returns 0 on success, -1 on error.
|
||||
* Config format: same as utun INI (see node_config.cpp saveFull). */
|
||||
/* Копирует INI и запускает поток. 0 = поток создан либо уже запущен, -1 = ошибка запуска.
|
||||
* Готовность самого ядра появляется позже: проверять is_running и события инициализации. */
|
||||
int instance_lite_start(const char* config_text);
|
||||
|
||||
/* Signal stop and wait for thread to exit.
|
||||
* Calls chat_sync_destroy, chat_core_destroy, utun_instance_destroy, uasync_destroy. */
|
||||
/* Сигнализировать stop и дождаться потока; поток уничтожает instance, затем uasync.
|
||||
* Вызывать с управляющего потока при существующем instance, не из callback ядра. */
|
||||
void instance_lite_stop(void);
|
||||
|
||||
/* Returns non-zero if instance is running. */
|
||||
@@ -44,9 +40,8 @@ void instance_lite_set_event_handler(instance_lite_event_fn handler);
|
||||
* Call from any thread. Keys are regenerated asynchronously. */
|
||||
void instance_lite_regenerate_keys(void);
|
||||
|
||||
/* Restart the instance internally (no thread kill). Stops chat_sync/chat_core,
|
||||
* re-parses config, regenerates keys if needed, reopens DB, re-inits.
|
||||
* Posts to uasync thread — restart happens asynchronously. */
|
||||
/* Копирует INI, будит poll-loop и пересоздаёт instance и uasync внутри worker.
|
||||
* Если ядро не работает, выполняет stop/start. Обновление асинхронное; старые handles утрачивают силу. */
|
||||
void instance_lite_restart(const char* new_config_text);
|
||||
|
||||
/* Лёгкое обновление сокетов (auto_sockets=android): перечитывает [server] секции
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/* Старая отдельная копия C-кодека utun://; invite_link_c.c исключён из текущего UTUN_SOURCES.
|
||||
* Рабочее общее API — src/chat/invite_link.h, Qt/Kotlin используют тот же формат версии 0x03.
|
||||
* Эти структуры не следует смешивать с InviteData общего API. */
|
||||
#ifndef INVITE_LINK_C_H
|
||||
#define INVITE_LINK_C_H
|
||||
|
||||
@@ -48,17 +51,17 @@ struct InviteDataC {
|
||||
};
|
||||
|
||||
/* decode utun://base64 link string, returns 0 on success, -1 on error.
|
||||
error buffer must be at least 256 bytes */
|
||||
error_buf необязателен, текст ошибки ограничивается error_buf_size. */
|
||||
int invite_link_decode(const char* link, size_t link_len, struct InviteDataC* out,
|
||||
char* error_buf, size_t error_buf_size);
|
||||
|
||||
/* encode invite data to utun://base64 string.
|
||||
password may be NULL (v1 format, no password).
|
||||
out buffer must be large enough (~512 bytes safe).
|
||||
returns written length (excluding null), or -1 on error */
|
||||
password=NULL означает пустой пароль в версии 0x03.
|
||||
out_size включает utun://, base64 и NUL; недостаточная ёмкость даёт -1.
|
||||
returns base64 length (excluding prefix and null), or -1 on error */
|
||||
int invite_link_encode(const struct InviteDataC* data, const char* password, char* out, size_t out_size);
|
||||
|
||||
/* serialize per-addr format for chat_sync_connect_from_invite():
|
||||
/* serialize for chat_sync_connect_from_invite(): Reality-префикс + адреса:
|
||||
family(1) + socketId(1) + proto(1) + address(4|16) + port(2 BE)
|
||||
returns total bytes written, or -1 if buf too small */
|
||||
int invite_serialize_addrs(const struct InviteDataC* data, uint8_t* buf, size_t buf_size);
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
/* Отправка уже подготовленного изображения в канал: MIME выбирается по расширению, width/height даёт caller.
|
||||
* Не декодирует и не масштабирует изображение; ставит копирование/индексацию в chat_core/media_index.
|
||||
* 0 = запрос поставлен в uasync, -1 = отказ. src_file_path должен существовать до завершения задачи. */
|
||||
#ifndef PHOTO_SENDER_H
|
||||
#define PHOTO_SENDER_H
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
/*
|
||||
* utun_config_api.h — configuration provider API for Android
|
||||
*
|
||||
* C core requests config values from Kotlin via callbacks.
|
||||
* For headless, a stub provider reads from environment variables.
|
||||
* For Android, JNI bridge sets callbacks that query Kotlin DataStore.
|
||||
* Callback-провайдер отдельных настроек native-обёртки. Без провайдера/accessor возвращает default.
|
||||
* Основной конфиг ядра передаётся INI-текстом в instance_lite_start, а не через этот интерфейс.
|
||||
* set_provider заимствует таблицу callbacks; она и возвращаемые строки должны жить во время вызовов.
|
||||
* Провайдер установить до запуска потребителей: синхронизации внутри модуля нет.
|
||||
*/
|
||||
#ifndef UTUN_CONFIG_API_H
|
||||
#define UTUN_CONFIG_API_H
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
/* Отправка подготовленного MP4 в канал или dm:conv_id через общий attachment_send.
|
||||
* Android передаёт duration_ms/width/height; повторного транскодирования здесь нет. db_path не используется.
|
||||
* 0 = запрос поставлен в uasync, -1 = отказ. Передаётся владение временным cache-файлом:
|
||||
* задача удаляет src_file_path после подготовки. Результат публикации приходит событием ядра. */
|
||||
#ifndef VIDEO_SENDER_H
|
||||
#define VIDEO_SENDER_H
|
||||
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/* Android-накопитель голосового: init → start(target,48000,1) → feed PCM int16 → stop либо cancel.
|
||||
* target — channel_id либо dm:conv_id. feed копирует count mono-сэмплов; управление защищено mutex.
|
||||
* stop отсоединяет PCM/компрессор и ставит attachment_send в uasync: encode/file работа идёт в worker.
|
||||
* stop=0 означает постановку подготовки либо отбрасывание записи короче 500мс, не доставку сообщения.
|
||||
* deinit освобождает текущую запись; завершение сетевой отправки отслеживается событиями ядра. */
|
||||
#ifndef VOICE_RECORDER_H
|
||||
#define VOICE_RECORDER_H
|
||||
|
||||
|
||||
Reference in new issue
Block a user