diff --git a/AGENTS.md b/AGENTS.md index 3a5eaccf..92cb29f3 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -233,7 +233,7 @@ warn / error - ошибки и предупреждения (аномалии). Актуальные имена и константы — в `lib/debug_config.h`, текстовые имена — в `lib/debug_config.c`. Основные: `sys`, `connection`, `etcp`, `crypto`, `config`, `tun`, `routing`, `timers`, `bgp`, `socket`, `control`, `dump`, `traffic`, `debug`, `general`, `nat`, `keepalive`, `etcp_route`, -`media`, `etcp_dump`, `chat`, `chat_sync`, `member_sync`, `proxy`, `video`, `reality`, `dm`, `call`, `radio`. +`media`, `etcp_dump`, `chat`, `chat_sync`, `member_sync`, `proxy`, `video`, `reality`, `dm`, `call`, `radio`, `vad`, `aec`. UASYNC/LL_QUEUE/MEMORY/TIMING объединены в SYS, NORMALIZER/BBR — в ETCP; старые числовые списки не использовать. ### Настройка отладки @@ -275,35 +275,44 @@ UASYNC/LL_QUEUE/MEMORY/TIMING объединены в SYS, NORMALIZER/BBR — в ### Directory Structure ``` -├── lib/ # Core libraries, SQLite, libopus/liblmdb +├── lib/ # uasync, очереди, SQLite, Opus, SpeexDSP, Silero VAD, SoundTouch, LMDB ├── src/ # Main source code -│ ├── transport_layer/ # ETCP, crypto, STCP, normalizer, NCD, BBR +│ ├── transport_layer/ # ETCP, сессии, crypto, STCP/REALITY, SOCKS-клиент, NCD, BBR │ ├── routing_layer/ # Routing, группы/BGP, recovery, conn_mgr, etcp_router │ ├── chat/ # P2P чат, join, db_sync, merkle_sync, member_sync -│ ├── dm/ # Личные сообщения и mailbox +│ ├── dm/ # Личные сообщения, E2E-вложения и offline-mailbox │ ├── call/ # Звонки и общий голосовой стек │ ├── radio/ # Групповая PTT-рация │ ├── proxy/ # SOCKS5, TCP/UDP/ICMP прокси │ ├── lwip_tcp/ # Встроенный lwIP TCP стек -│ ├── media_delivery/ # Доставка медиафайлов -│ ├── media_async/ # Фоновые задачи медиа -│ └── *.c/h # utun, config, TUN, firewall, NAT, NTP, control +│ ├── media_delivery/ # Блоки медиа каналов и передача неизменяемых файлов +│ ├── media_async/ # Фоновые задачи, метаданные вложений, подготовка голоса/видео +│ ├── video/ # Пробинг и транскодирование видео через FFmpeg +│ ├── dnsmasq/ # Архив исходников для встроенной сборки dnsmasq +│ └── *.c/h # utun, instance, config, TUN, firewall, NAT, NTP, control, broadcast ├── tests/ # Состав тестов и цели запуска: tests/Makefile.am ├── doc/ # Technical Specifications ├── tools/ # Auxiliary tools │ ├── etcpmon/ # GUI монитор ETCP │ ├── chatgui/ # GUI чат (Qt 6 с Qt 5 fallback, сборка CMake) │ ├── chatgui-android/ # Android P2P чат (Jetpack Compose + libutun_lite) +│ ├── logreceiver/ # Приём UDP-логов Android +│ ├── chat_tcp_test/ # Сценарий проверки чата через TCP +│ ├── lightsout/ # Отдельная игра Lights Out на Qt +│ ├── lightsout-android/ # Android-версия Lights Out │ ├── tdesktop-dev/ # Референс: Telegram Desktop (только для изучения) │ ├── proxy/ # UDP прокси для тестов -│ └── bping/ # BPing (bandwidth ping) +│ ├── bping/ # BPing (bandwidth ping) +│ └── chatcli # Headless CLI; описание команд — chatcli_commands.txt ├── tinycrypt/ # TinyCrypt crypto library (external) -├── net_emulator/ # Network emulator (delays, loss, reordering) -└── c2/ # Test instance 2 (конфиг и бинарник для тестов) +└── net_emulator/ # Network emulator (delays, loss, reordering) ``` ### File Overview +Пути ниже относительны к каталогу секции; `name.c/h` означает пару `.c` и `.h`. +Перечислены модули проекта; внутренние файлы сторонних библиотек сгруппированы по каталогам. + **Core (src/)** - `utun.c` - Main program entry point, CLI parsing, daemon mode - `utun_instance.c/h` - Создание ядра и независимый жизненный цикл UTUN/чата, владение общими ресурсами @@ -326,6 +335,7 @@ UASYNC/LL_QUEUE/MEMORY/TIMING объединены в SYS, NORMALIZER/BBR — в - `etcp.c/h` - ETCP protocol implementation (inflight queues, retrans, ACK, RTT/jitter) - `etcp_api.c/h` - ETCP public API (send/recv/bind callbacks) - `etcp_connections.c/h` - Socket and link management, INIT handshake, keepalive, PING/PONG +- `etcp_session.c/h` - Согласование эпох ETCP-сессии через HELLO/CHALLENGE/CONFIRM и проверка принадлежности DATA сессии - `etcp_loadbalancer.c/h` - Multi-link load balancing with traffic shaper - `etcp_debug.c/h` - ETCP packet dump/formatting - `etcp_dump.c/h` - ETCP дамп/декодирование пакетов @@ -342,11 +352,13 @@ UASYNC/LL_QUEUE/MEMORY/TIMING объединены в SYS, NORMALIZER/BBR — в - `stcp_server.c/h` - STCP сервер - `stcp_client.c/h` - STCP клиент - `stcp_link.c/h` - STCP линк-уровень +- `socks_client.c/h` - Исходящий SOCKS5-транспорт: TCP CONNECT и UDP ASSOCIATE с переподключением control-сокета - `node_conn_direct.c/h` - Общий прямой транспорт к пиру с отдельным handle каждого владельца; обновление линков по адресам узла - `socket_monitor.c/h` - Socket state monitoring - `reality.c/h` - REALITY-style TLS ClientHello/ServerHello камуфляж для STCP - `reality_fingerprint.c/h` - Статические отпечатки (cipher suites, groups, ALPN) для REALITY-камуфляжа - `reality_relay.c/h` - Релей неавторизованных клиентов на реальный HTTPS-сайт +- `call_ring.c/h` - Кольцевой трейс контрольных точек освобождения ETCP/STCP-ресурсов для диагностики teardown/UAF **BBR (src/transport_layer/BBR/)** - `bbr_v3.c` - BBR congestion control algorithm v3 @@ -355,10 +367,10 @@ UASYNC/LL_QUEUE/MEMORY/TIMING объединены в SYS, NORMALIZER/BBR — в - `routing.c/h` - Routing table (local) - `route_lib.c/h` - Routing library - `route6_lib.c/h` - IPv6 routing -- `route_ping.c/h` - Route ping probing (NAT check, liveness) +- `route_ping.c/h` - Пинг цели через явно выбранного BGP-посредника для NAT-проверки - `route_connectivity.c/h` - Route connectivity checks - `topo_group.c/h` - Сессии UTUN/CHAT (JOIN/ACCEPT, эпохи, READY), групповые запросы, NODEINFO/WITHDRAW и владение NCD -- `topo_group_connect.c/h` - Подбор пиров CHAT-группы: исторические → суперузлы/публичные → локальные; отменяемые запросы до READY +- `topo_group_connect.c/h` - Подбор пиров CHAT-группы по роли: суперузлы → desktop → mobile; история/RTT внутри класса, backoff и standby burst - `topo_group_invite.c/h` - Получение описания канала через INVITE_INFO_REQ/RESP; добавление мембера реализовано в chat_join/chat_sync - `topo_node.c/h` - Node management (модель узла: TOPO_NODE/TOPO_GROUP_NODE, сериализация, node_registry) - `topo_node_sqlite.c/h` - SQLite persistence for nodes @@ -366,6 +378,7 @@ UASYNC/LL_QUEUE/MEMORY/TIMING объединены в SYS, NORMALIZER/BBR — в - `conn_mgr.h` + `conn_mgr_core.c`/`conn_mgr_indirect.c`/`conn_mgr_monitor.c` + `conn_mgr_priv.h` — Connection Manager (handle-based API, 3-phase DIR/REV/IND) - `etcp_router.c/h` - ETCP router/multiplexer (мультиплексирование каналов, transit forwarding) - `nat_detection.c/h` - NAT type detection +- `sock_match.c/h` - Классификация локальных сокетов и адресов пира, отбор совместимых пар для прямого подключения - `route_crypto.c/h` - Пред/пост-обработка SVC_ROUTE пакетов (encrypt-then-sign) **Chat (src/chat/)** — децентрализованный P2P чат: сообщения и участники автоматически синхронизируются между всеми узлами канала без центрального сервера. @@ -390,12 +403,42 @@ UASYNC/LL_QUEUE/MEMORY/TIMING объединены в SYS, NORMALIZER/BBR — в - `invite_build.c/h` - Сборка invite-ссылок utun:// (выбор лучшего узла + адреса) - `invite_link.c/h` - Кодирование utun://: версия, пароль, channel_id, join_key, Reality-параметры, ключ и адреса узла +**Личные сообщения (src/dm/)** + +- `dm_core.c/h` - Беседы двух узлов, подписанные E2E-сообщения, SQLite/outbox, доставка через router/mailbox и квитанции +- `dm_crypto.c/h` - Вывод ID беседы и ключа X25519, AES-256-CCM сообщений и потоковое шифрование/проверка медиа +- `dm_mailbox.c/h` - Offline-очередь суперузла: хранение подписанных сообщений и повтор доставки до квитанции получателя +- `dm_media.c/h` - Подготовка, доставка и публикация E2E-вложений; ciphertext-хранилище и отдельные квитанции файлов +- `dm_media_priv.h` - Внутренние SQL/control-операции для dm_media и dm_mailbox_media +- `dm_mailbox_media.c/h` - Сохраняемые задания суперузла для размещения медиа, доставки метаданных и удаления копий до DELETE_ACK + +**Звонки (src/call/)** + +- `call.c/h` - Сигналинг и медиа P2P-звонка через ETCP-router, состояния звонка и оптимизация пути через conn_mgr +- `call_proto.h` - Wire-формат сигналинга и медиа, треки/кодеки, причины завершения +- `call_audio.c/h` - Общий аудио-движок: кодирование/декодирование Opus, jitter-буфер и тоны, API feed/pull PCM +- `call_jitter.cpp/h` - FIFO кодированных Opus-кадров, адаптивный запас и SoundTouch time-stretch при воспроизведении +- `call_jitter_window.h` - Окно из десяти секундных интервалов для оценки глубины очереди и изменения задержки доставки +- `call_tones.c/h` - Генерация PCM-тонов паузы и завершения звонка +- `call_headless.c/h` - Отдельный TCP-аудиосокет headless-клиента: обмен PCM; сигналинг остаётся на control-сокете + +**Рация (src/radio/)** + +- `radio.c/h` - Передача Opus по CHAT-группе, подписки, дедупликация и пересылка по ветвям с подписчиками +- `radio_proto.h` - Wire-формат PTT: источник, поток, seq, FIN и hop-list против циклов +- `radio_audio.c/h` - Общий аудио-движок: независимые RX/TX, Opus, микширование источников, ручной PTT и VAD-автомат +- `radio_jitter.cpp/h` - Буфер кодированных кадров каждого источника с pre-roll и SoundTouch time-stretch на pull +- `radio_vad.h` - Ресемплинг 48→16 кГц и автомат авто-PTT с подтверждением речи, задержкой завершения и учётом занятого канала +- `radio_headless.c/h` - TCP-аудиосокет headless-рации: PCM и команды начала/конца PTT + **Прокси (src/proxy/)** -- `socks_proxy.c/h` - SOCKS5 прокси + +- `proxy_protocol.h` - Общий TCP-протокол и управление потоком: CONNECTED, DATA, кредит WINDOW, упорядоченный FIN +- `socks_proxy.c/h` - Клиентские SOCKS5 CONNECT и HTTP proxy/CONNECT, DNS и передача потока выбранному exit-узлу - `udp_proxy.c/h` - UDP прокси - `icmp_proxy.c/h` - ICMP прокси -- `tcp_proxy_server.c/h` - TCP прокси (серверная сторона) -- `tcp_proxy_client.c/h` - TCP прокси (клиентская сторона) +- `tcp_proxy_server.c/h` - Exit-сторона TCP-прокси: реальные исходящие сокеты, потоки по (peer, stream_id), окна и half-close +- `tcp_proxy_client.c/h` - Клиентская сторона TCP-прокси: адаптер TUN/lwIP и обмен с настроенным exit через ETCP-router **lwIP TCP (src/lwip_tcp/)** - `lwip_tcp.c/h` - lwIP TCP стек @@ -404,31 +447,39 @@ UASYNC/LL_QUEUE/MEMORY/TIMING объединены в SYS, NORMALIZER/BBR — в - `lwip_tcp_priv.h`, `lwip_tcp_opts.h` - Внутренние настройки lwIP **Media Delivery (src/media_delivery/)** -- `media_delivery.c/h` + `media_delivery_proto.h` - Доставка медиафайлов, протокол -- `media_download.c/h` - Скачивание медиа -- `media_index.c/h` - Индексация медиафайлов +- `media_delivery.c/h` - Доставка блоков медиа каналов, учёт держателей, репликация доступности между суперузлами и relay +- `media_delivery_proto.h` - Кодограммы канального медиа: QUERY, BLOCK_REQ/CHUNK/DONE, HAVE_BLOCK и SUPER_REPL +- `media_download.c/h` - Загрузка блоков с выбором держателей, failover, контролем простоя, проверкой подписей и сборкой файла +- `media_index.c/h` - Индекс media_files: UUID, хеши и подписи блоков, асинхронная регистрация и удаление медиа канала +- `file_transfer.c/h` - Передача неизменяемого файла между заданными узлами; авторизация lookup и владение CM handle до завершения **Media Async (src/media_async/)** - `media_async.c/h` - Фоновые crypto/file-задачи: work в pthread, done в uasync; destroy ждёт workers и завершает ожидающие callbacks с CANCELLED +- `attachment.c/h` - Общие метаданные file/voice/video, проверка и компактная wire-сериализация +- `voice_file.c/h` - Worker-кодирование PCM в контейнер Opus с длительностью и waveform для desktop/Android +- `attachment_send.c/h` - Асинхронная подготовка голоса/видео и отправка в зафиксированный канал или DM **Libraries (lib/)** - `u_async.c/h` - Async event loop (epoll/poll/select, timers via timeout_heap) - `ll_queue.c/h` - Двусвязная очередь одного uasync-потока с callbacks, хеш-индексом и ожиданием свободного места -- `memory_pool.c/h` - Fast object pool allocator (pre-allocated blocks) +- `memory_pool.c/h` - Пул объектов: ленивое выделение и повторное использование, до 64 свободных объектов в кеше - `debug_config.c/h` - Debug logging system (levels, categories, dual output, runtime config) - `timeout_heap.c/h` - Min-heap for timer management (used by u_async) - `mem.c/h` - Memory wrappers with leak tracking (`u_malloc`/`u_free`/`u_calloc`/`u_strdup`) - `serialize.c/h` - Binary serialization utilities - `swm_min.c/h` - Sliding window minimum (for RTT min tracking) -- `getmyip.c/h` - Get local IP / default route detection +- `getmyip.c/h` - Локальный IP, который ОС выберет для UDP к заданному адресу (bind/connect/getsockname) - `myip.c` - My IP helper (no header) - `socket_compat.c/h` - Cross-platform socket compatibility (Linux/FreeBSD/Windows) - `platform_compat.c/h` - Cross-platform compatibility layer (byte order, time, random) - `radix.c/h` - Radix tree for IP routing lookups -- `tcp_io.c/h` - TCP I/O abstraction (Windows IOCP, Linux epoll) +- `tcp_io.c/h` - Неблокирующий TCP поверх uasync/ll_queue: backpressure, FIN/close и callbacks - `sqlite3.c/h` - SQLite3 amalgamation (embedded database) - `opus_codec.c/h` - Opus audio codec wrapper - `audio_compressor.c/h` - Audio dynamic range compressor +- `speex_aec.c/h` - Эхоподавление SpeexDSP: согласование playback/capture PCM через линию задержки и диагностика её заполнения +- `silero_vad.c/h` - Стриминговый VAD через ONNX Runtime: окна 512 отсчётов, 16 кГц моно, вероятность речи и сброс состояния +- `silero_vad_model.inc` - Встроенная ONNX-модель Silero VAD для silero_vad_create_default - `json_flat.c/h` - Flat JSON parser - `strbuf.c/h` - Безопасный растущий printf-буфер (замена snprintf-цепочек) - `async_dns.c/h` - Асинхронный (неблокирующий) DNS-резолвер A-записей поверх uasync, адаптер над libdns @@ -437,6 +488,8 @@ UASYNC/LL_QUEUE/MEMORY/TIMING объединены в SYS, NORMALIZER/BBR — в - `dr_mp3.h` - MP3-декодер (single-header, на базе minimp3) - `liblmdb/` - Встраиваемый key-value store LMDB - `libopus/` - Встраиваемый кодек Opus +- `speexdsp/` - Встроенные исходники эхоканселлера SpeexDSP и KISS FFT +- `soundtouch-master/` - SoundTouch: изменение темпа аудио в jitter-буферах звонка и рации - `wintun.h` - Wintun API header for Windows TUN driver **Memory Pools in UTUN_INSTANCE:** @@ -616,7 +669,7 @@ cmake .. && make -j4 | Файл | Назначение | |------|-----------| | `main.cpp` | Точка входа, инициализация QApplication | -| `mainwindow.h/cpp` | Главное окно, QSplitter (ChannelList \| MessageList \| AccountList), трей | +| `mainwindow.h/cpp` | Главное окно, списки каналов/DM/участников, сообщения, трей, события ядра и окна звонков | | `chatview.h/cpp` | QListView с фоновым изображением, hover-сигнал, drag-to-select | | `messagelist.h/cpp` | Модель сообщений из БД, обновления доставки/медиа, анимации, состояние просмотра канала | | `messagedelegate.h/cpp` | QStyledItemDelegate: бабблы, текст, цитаты, реакции, оверлей анимаций | @@ -646,10 +699,22 @@ cmake .. && make -j4 | `storagesettingspage.h/cpp` | Страница настроек хранилища | | `soundsettingspage.h/cpp` | Страница настроек звука | | `audiodevicesettingspage.h/cpp` | Страница настроек аудиоустройств | -| `sound_manager.h/cpp` | Управление звуками/уведомлениями | -| `audiorecorder.h/cpp` | Запись голосовых сообщений (захват аудио) | -| `voicemessageencoder.h/cpp` | Кодирование голосовых сообщений (Opus) | +| `sound_manager.h/cpp` | Общий miniaudio-контекст, уведомления/PCM, микширование голоса, маршруты устройств и восстановление | +| `audio_device.h/cpp` | Жизненный цикл miniaudio-устройства, прогресс callbacks, пауза и повтор запуска после сбоя | +| `audio_event_queue.h` | Ограниченная очередь PCM/команд с несколькими producers и резервом для управляющих событий | +| `audio_frame_ring.h` | Предвыделенное SPSC-кольцо кадров переменной длины под mutex; при переполнении удаляет старейший | +| `voice_audio_io.h/cpp` | Workers захвата/AEC и воспроизведения; упорядочивание PCM/PTT/mute и итоговый render-reference | +| `audiorecorder.h/cpp` | Захват голосовых сообщений, worker обработки PCM, компрессор, индикатор уровня и передача записи задаче | +| `voicemessageencoder.h/cpp` | Выбор Opus preset и создание медиа-каталога; кодирование выполняет общий voice_file | | `voiceplayback.h/cpp` | Воспроизведение голосовых сообщений | +| `callwindow.h/cpp` | Окно звонка: состояния, управление, путь соединения и статистика аудио | +| `call_audio_engine.h/cpp` | Desktop-контур звонка: захват, VoiceAudioIo, общий выход SoundManager и завершение аудиосессии | +| `radio_audio_engine.h/cpp` | Desktop-контур рации: независимые захват/прослушивание, PTT/VAD и подключение к общему выходу | +| `radiopanel.h/cpp` | Панель активной рации: выбор аудиоустройств, VAD, PTT и состояние передачи из ядра | +| `radiosettingspage.h/cpp` | Настройки рации и запись глобальных сочетаний PTT | +| `ptt_hotkey_manager.h/cpp` | Глобальный PTT: физические клавиши Windows/X11, системный портал Wayland | +| `ptt_key_chord.h` | Хранение физических сочетаний с отдельными левыми/правыми модификаторами и запись одновременного нажатия | +| `ptt_portal.h/cpp` | D-Bus-сессия GlobalShortcuts для Wayland, настройка сочетаний и обработка нажатий/отпусканий | | `media_blocks.h/cpp` | Чтение/сборка фрагментированных медиафайлов | | `imageviewer_window.h/cpp` | Окно просмотра изображений | | `videoplayer_engine.h/cpp` | Движок декодирования видео | @@ -659,10 +724,26 @@ cmake .. && make -j4 | `debug_ui.h` | Отладочный UI | ### Другие поддиректории + - `db/` — `db_manager.h/cpp`: доступ GUI к данным nodes, channels, msg_, peers_ и состоянию интерфейса; копия `db/sqlite3.c/h` не используется текущей CMake-целью, SQLite берётся из `lib/` -- `transport/` — интеграция с uTun: `gui_bridge.h/gui_bridge_impl.cpp` (Qt signal-based обмен), `node_config.h/cpp` (конфиг узла), `config_updater.h/cpp` (правка конфига), `utun_node.h/cpp` (обёртка узла), `miniaudio_impl.c` (single-header miniaudio в отдельной единице трансляции). Chat-логика (`chat_core`, `chat_sync` и т.д.) компилируется напрямую из `src/chat/`, роутинг — из `src/routing_layer/` (см. `libutun/CMakeLists.txt`) +- `transport/` — интеграция GUI с ядром; файлы перечислены ниже +- `libutun/CMakeLists.txt` — состав и зависимости CMake-сборки общего ядра из `src/` и `lib/` +- `CMakeLists.txt` — приложение vibechat, Qt-зависимости, ресурсы и цели GUI-тестов +- `tests/` — проверки аудиоустройств и восстановления, голосового тракта, jitter-буферов, PTT, кодирования и GUI-компонентов - `resources/` — `bg.jpg`, `chatgui.qrc` (встраивает 5 TGS в бинарник), `animations/*.tgs` +- `zxing-cpp/` — встроенная библиотека QR-кодов; `third_party/qhotkey/` — исходники QHotkey + +### Интеграция с ядром (transport/) + +| Файл | Назначение | +|------|-----------| +| `gui_bridge.h` / `gui_bridge_impl.cpp` | Команды GUI → uasync и события ядра → Qt-сигналы | +| `utun_node.h/cpp` | Запуск и остановка ядра/чата в выделенном uasync-потоке | +| `node_config.h/cpp` | Загрузка и сохранение конфигурации узла | +| `config_updater.h/cpp` | Изменение настроек в конфиге | +| `miniaudio_impl.c` | Реализация single-header miniaudio в отдельной единице трансляции | +| `audio_diagnostics.h/cpp` | Диагностика этапов аудио и событий backend; записывает метаданные без PCM | ### Система анимированных эмодзи @@ -756,6 +837,7 @@ void lottie_animation_destroy(Lottie_Animation *anim); --- ## Key Documentation Files + - `doc/service_lifecycle.md` — ядро, независимые сервисы, владение ресурсами и остановка - `doc/node_snapshot.md` — подписанная запись узла, timestamp, SQLite и обновление NCD - `doc/etcp_protocol.txt` — ETCP: кодограммы, ACK, handshake, keepalive @@ -765,6 +847,12 @@ void lottie_animation_destroy(Lottie_Animation *anim); - `src/routing_layer/topo_group.h` — протокол групповой сессии и критерий READY - `tests/test_chat_join_e2e.c`, `tests/test_topo_recovery.c`, `tests/test_services.c` — проверки join, recovery и жизненного цикла - `doc/dm_arch.md`, `doc/chat_call_arch.md` — личные сообщения и звонки +- `doc/proxy_protocol.md` — TCP/UDP/ICMP-прокси, управление окнами, half-close и проверки +- `doc/lwip_nuances.md` — особенности адаптированного lwIP TCP-стека +- `doc/linux_audio_recovery.md` — диагностика аудиотракта Linux, контракты владения и восстановление устройств +- `src/media_delivery/file_transfer.h`, `src/dm/dm_media.h` — контракты передачи файлов и E2E-вложений DM +- `src/call/call_audio.h`, `src/radio/radio_audio.h` — API общего голосового стека и правила потоков +- `tools/chatcli_commands.txt` — команды headless CLI, в том числе DM, звонки и рация ## Список задач по проекту @@ -785,6 +873,29 @@ C-библиотека `utun_lite` собирает `lib/` и `src/` по `libut **Подробная инструкция:** `tools/chatgui-android/AGENTS.md` **Chat-модули:** все файлы из `src/chat/` (описаны выше в секции «Chat») компилируются в `libutun_lite`. +### Основные файлы native-слоя + +Пути относительны к `tools/chatgui-android/`; UI и Android-сервисы описаны в локальном `AGENTS.md`. + +| Файл | Назначение | +|------|-----------| +| `libutun_lite/utun_sources.cmake` | Общий список исходников ядра для Android и headless | +| `libutun_lite/CMakeLists.txt` | Сборка native-библиотеки и зависимостей | +| `libutun_lite/instance_lite.c/h` | Запуск ядра/чата по INI-тексту и управление отдельным uasync-потоком | +| `libutun_lite/utun_config_api.c/h` | Провайдер конфигурации: callbacks Kotlin и значения для native-слоя | +| `libutun_lite/standby.c/h` | Фоновый duty-cycle, таймеры активных интервалов и ожидание пробуждения | +| `libutun_lite/invite_link_c.c/h` | Старая копия C-кодека; .c исключён из UTUN_SOURCES, рабочий код — src/chat/invite_link.c/h | +| `libutun_lite/attachment_sender.c/h` | Отправка файлов в канал через chat_msg_submit и канальный медиа-индекс | +| `libutun_lite/photo_sender.c/h` | Отправка фотографий в канал с MIME-типом и размерами изображения | +| `libutun_lite/video_sender.c/h` | Отправка видео через общий механизм подготовки вложений | +| `libutun_lite/voice_recorder.c/h` | Накопление PCM записи, компрессор и отправка голоса через общий attachment_send | +| `jni_bridge/android_jni_bridge.c/h` | JNI-команды и callbacks между Kotlin и C-ядром, события и аудио API | +| `jni_bridge/android_udp_log.c/h` | Потокобезопасный буфер UDP-логов с flush-таймером в потоке ядра | +| `headless/headless_main.c` | Отдельный каркас control-loop; сам не запускает ядро/чат | +| `headless/headless_control.c/h` | Каркас control-сокета; часть команд — заглушки, рабочий API — src/chat/chat_headless_control.c/h | +| `app/src/main/cpp/CMakeLists.txt` | NDK-сборка библиотеки приложения | +| `libutun_lite/tests/test_standby.c` | Проверка duty-cycle и жизненного цикла standby | + ## Runtime - После autotools-сборки бинарник — `src/utun`. Запуск из корня с TUN: `sudo ./src/utun -f -c utun.cfg`. - Старый `utun_start.sh` ожидает `./utun` в корне. `utun_stop.sh` делает `killall -9 utun`, а не штатную остановку одного экземпляра. diff --git a/lib/audio_compressor.h b/lib/audio_compressor.h index 30c6e55f..42c64acf 100644 --- a/lib/audio_compressor.h +++ b/lib/audio_compressor.h @@ -1,3 +1,9 @@ +/* audio_compressor — адаптивное усиление int16 PCM (моно/стерео) с общей огибающей каналов. + * create → configure → обработка → destroy; объект использует один владелец, блокировок нет. + * Запись: push принимает произвольные порции, flush завершает хвост и lookahead; output принадлежит объекту. + * Поток: process_frame обрабатывает ровно sample_rate*block_duration_ms/1000*channels отсчётов, + * требует нулевого lookahead и пустого входного накопителя; in/out могут совпадать. + * count/output_size — interleaved отсчёты, не байты и не кадры на канал. Выключение даёт исходный PCM. */ #ifndef AUDIO_COMPRESSOR_H #define AUDIO_COMPRESSOR_H @@ -19,7 +25,7 @@ typedef struct { float max_gain_db; float rise_rate_per_sec; float release_rate_per_sec; /* скорость плавного снижения gain (0 = авто: rise*5) */ - float target_level; + float target_level; /* Линейная амплитуда огибающей, не дБ; 0 задаёт default 0.25. */ } audio_compressor_config_t; struct audio_compressor* audio_compressor_create(void); @@ -35,9 +41,11 @@ void audio_compressor_reset(struct audio_compressor* ac); void audio_compressor_set_enabled(struct audio_compressor* ac, int enabled); int audio_compressor_is_enabled(const struct audio_compressor* ac); +/* push копирует вход; push/flush возвращают 0 / -1. Ошибка накопления требует reset перед повтором. */ int audio_compressor_push(struct audio_compressor* ac, const int16_t* samples, size_t count); int audio_compressor_flush(struct audio_compressor* ac); +/* Указатель действителен до изменения/освобождения выходного буфера; вызывающий его не освобождает. */ const int16_t* audio_compressor_output(const struct audio_compressor* ac); size_t audio_compressor_output_size(const struct audio_compressor* ac); diff --git a/lib/debug_config.h b/lib/debug_config.h index 3b58a6b6..0f48edee 100644 --- a/lib/debug_config.h +++ b/lib/debug_config.h @@ -80,7 +80,7 @@ typedef int debug_category_t; /* Debug configuration structure */ typedef struct { debug_level_t level; // Global debug level (default: ERROR) - debug_level_t category_levels[DEBUG_CATEGORY_COUNT]; // Per-category levels (0 = disabled) + debug_level_t category_levels[DEBUG_CATEGORY_COUNT]; // Уровень категории: NONE наследует общий, DISABLED выключает int timestamp_enabled; // Include timestamps in output int function_name_enabled; // Include function names int file_line_enabled; // Include file:line info @@ -99,18 +99,19 @@ extern debug_config_t g_debug_config; void debug_config_init(void); /* Set debug level */ -// итоговый level = max (global level - здесь задается, category level) +// Общий уровень применяется к категориям с уровнем NONE. void debug_set_level(debug_level_t level); -/* Set debug level for specific category (0 = disabled, otherwise uses that level) */ +/* Уровень категории заменяет общий; NONE наследует его, DISABLED подавляет вывод. */ void debug_set_category_level(debug_category_t category, debug_level_t level); -/* Enable/disable specific categories */ +/* enable фиксирует текущий общий уровень; disable возвращает к наследованию (NONE). + * Для полного выключения использовать debug_set_category_level(cat, DEBUG_LEVEL_DISABLED). */ void debug_enable_category(debug_category_t category); void debug_disable_category(debug_category_t category); void debug_set_categories(debug_category_t categories); -/* Set masks directly */ +/* Установка уровня одной категории (аргумент categories — индекс, не битовая маска). */ void debug_set_masks(debug_category_t categories, debug_level_t level); /* Configure output options */ @@ -126,7 +127,7 @@ int debug_reopen_log(void); void debug_enable_console(int enable); -// IP address to string (static buffer, single-threaded) +// IP/sockaddr в строку: результат возвращается по значению, освобождать не требуется. typedef struct { char str[54]; // INET6_ADDRSTRLEN(45) + 6chars (:port) + \0 } ip_str_t; diff --git a/lib/json_flat.h b/lib/json_flat.h index f99e8d13..55401eb0 100644 --- a/lib/json_flat.h +++ b/lib/json_flat.h @@ -2,7 +2,10 @@ * @file json_flat.h * @brief Парсер плоского JSON без вложенности: {"key":"value",...} * - * Только строковые значения. Callback получает полные строки без обрезания. + * Только строковые значения и обычные escapes; \uXXXX не поддерживается. + * Callback получает полные key/value, действительные только до его возврата. + * parse возвращает 0 при успехе/остановке callback, -1 при ошибке; остановка не проверяет остаток ввода. + * get ищет первый ключ и копирует значение с NUL, при малом буфере обрезает; 0 найден, -1 ошибка/нет ключа. */ #ifndef JSON_FLAT_H diff --git a/lib/ll_queue.h b/lib/ll_queue.h index 1f581054..971a63e3 100644 --- a/lib/ll_queue.h +++ b/lib/ll_queue.h @@ -1,6 +1,10 @@ #ifndef LL_QUEUE_H #define LL_QUEUE_H +/* Очередь одного uasync-потока; наличие pthread-заголовков не делает её межпоточной. + * put может синхронно вызвать consumer/waiter. Держать владельцев живыми до завершения callbacks, + * waiter handle обнулять целиком и отменять до освобождения; entry и dgram освобождаются отдельно. */ + #ifdef __cplusplus extern "C" { #endif @@ -306,7 +310,6 @@ void queue_waiter_cancel(struct ll_queue* q, struct queue_waiter_handle* h); * @brief Добавляет элемент в конец очереди (FIFO). * @param q очередь * @param entry элемент - * @param id идентификатор для поиска * @return 0 — успех, -1 — превышен лимит (элемент освобождён) */ int queue_data_put(struct ll_queue* q, struct ll_entry* entry); @@ -315,7 +318,6 @@ int queue_data_put(struct ll_queue* q, struct ll_entry* entry); * @brief Добавляет элемент в начало очереди (LIFO, высокий приоритет). * @param q очередь * @param entry элемент - * @param id идентификатор * @return 0 — успех, -1 — превышен лимит (элемент освобождён) */ int queue_data_put_first(struct ll_queue* q, struct ll_entry* entry); diff --git a/lib/mem.h b/lib/mem.h index 29c63030..e19284c8 100644 --- a/lib/mem.h +++ b/lib/mem.h @@ -1,6 +1,9 @@ /** - * Memory management layer - * Provides wrappers for malloc/realloc/calloc/free with error handling + * mem — выделение памяти с защитными полями, местом аллокации и учётом живых блоков. + * Использовать u_malloc/u_calloc/u_realloc/u_strdup и парный u_free; обычный free к этим блокам неприменим. + * Макросы передают LOCATION автоматически. OOM возвращает NULL; обнаруженное повреждение завершает процесс. + * realloc при ошибке сохраняет старый блок, при size=0 освобождает его. + * Отчёт u_report_unfreed_blocks вызывать после остановки потоков, меняющих список аллокаций. */ #ifndef MEM_H #define MEM_H diff --git a/lib/memory_pool.h b/lib/memory_pool.h index dfe1cd2c..09727c76 100644 --- a/lib/memory_pool.h +++ b/lib/memory_pool.h @@ -1,4 +1,9 @@ -// memory_pool.h +/* memory_pool — повторное использование блоков фиксированного размера в одном потоке. + * init создаёт пустой пул; alloc выделяет блок по требованию или берёт свободный и обнуляет payload. + * free проверяет защитный хвост и возвращает не более MEMORY_POOL_MAX_FREE блоков в кеш. + * object_size должен вмещать void*: свободный блок хранит next в начале payload. + * Перед destroy вернуть все выданные блоки: destroy освобождает только кеш и сам пул. + * name заимствован до destroy; блок возвращать только своему пулу, внутренней синхронизации нет. */ #ifndef MEMORY_POOL_H #define MEMORY_POOL_H @@ -40,6 +45,7 @@ size_t memory_pool_get_total_free_blocks(void); #define memory_pool_alloc(pool) memory_pool_alloc_impl(pool, PLOCATION) #define memory_pool_free(pool, obj) memory_pool_free_impl(pool, obj, PLOCATION) +/* Проверяет присутствие в кеше свободных блоков; не определяет состояние уже освобождённого через u_free блока. */ int memory_pool_is_freed(struct memory_pool* pool, void* obj); diff --git a/lib/opus_codec.h b/lib/opus_codec.h index 73aa6521..7c4e60f6 100644 --- a/lib/opus_codec.h +++ b/lib/opus_codec.h @@ -1,3 +1,9 @@ +/* opus_codec — владеющие обёртки encoder/decoder libopus для int16 interleaved PCM. + * create принимает частоту и 1/2 канала; неположительная частота → 48000, неверные каналы → моно. + * Encoder/decoder имеют состояние потока; каждому нужен один последовательный владелец. + * frame_samples — отсчёты НА КАНАЛ: PCM вмещает frame_samples*channels элементов. + * encode возвращает байты Opus, decode — отсчёты на канал; отрицательное значение означает ошибку. + * out_cap — байты; decode с data=NULL/len=0 использует PLC libopus. Освобождение — соответствующим destroy. */ #ifndef OPUS_CODEC_H #define OPUS_CODEC_H diff --git a/lib/platform_compat.h b/lib/platform_compat.h index 1a555272..c14bd3aa 100644 --- a/lib/platform_compat.h +++ b/lib/platform_compat.h @@ -1,5 +1,7 @@ /** - * Platform compatibility layer for POSIX functions on Windows + * platform_compat — общие заголовки POSIX/Windows и адаптеры отсутствующих POSIX-функций. + * Также предоставляет криптографический random_bytes, адреса интерфейсов, выбор default route + * и классификацию публичных IPv4. Сокетные типы/ошибки и nonblocking API — в socket_compat.h. */ #ifndef PLATFORM_COMPAT_H diff --git a/lib/serialize.h b/lib/serialize.h index 56dfc426..b698bba2 100644 --- a/lib/serialize.h +++ b/lib/serialize.h @@ -22,17 +22,20 @@ * • Все динамические данные (строки, массивы, списки) выделяются через u_malloc. * • При encode длина переменных полей кодируется всегда 2 байтами (uint16_t, big-endian). * • Для linked list в буфере сохраняется только количество узлов + сырые данные узлов - * (next-указатели НЕ сериализуются, они восстанавливаются при decode). + * (включая байты next/padding; decode заменяет next восстановленными ссылками). * • serialize_decode принимает буфер БЕЗ заголовка. * • serialize_free освобождает ВСЮ структуру и все вложенные динамические объекты. - * • Поля в schema.fields должны идти в порядке возрастания offset. - * • max_size (если > 0) — жёсткий лимит размера выходного буфера. + * • Поля кодируются в порядке schema.fields; фиксированные данные копируются без смены endian. + * • max_size (если > 0) — лимит encode; header при header_len > 0 обязателен. + * • Переменные counts ограничены 65535; elem_size=1 добавляет NUL и для byte-массивов. + * • Linked nodes копируются целиком, без рекурсивного кодирования вложенных указателей. + * • Этот формат зависит от ABI сырых полей; сериализация не нормализует размер/выравнивание структур. * * @example * // 1. Описание структуры * typedef struct Node { * uint32_t value; - * struct Node* next; // next по offset = 4 + * struct Node* next; // положение задаётся offsetof(Node, next) * } Node; * * typedef struct { diff --git a/lib/silero_vad.h b/lib/silero_vad.h index 1e374d48..a45ca0ef 100644 --- a/lib/silero_vad.h +++ b/lib/silero_vad.h @@ -3,7 +3,7 @@ * * Запускает официальную стриминговую модель silero_vad.onnx (v5, ~2.3 МБ), * которая по окну аудио возвращает вероятность наличия речи [0..1]. - * Рекуррентное состояние (GRU) хранится внутри объекта и переносится между + * Рекуррентное состояние модели хранится внутри объекта и переносится между * вызовами. Обёртка также хранит 64 последних отсчёта аудио и добавляет их * перед новым окном: ONNX получает 576 отсчётов, публичный API принимает 512. * diff --git a/lib/socket_compat.h b/lib/socket_compat.h index f7e154cd..e0d18864 100644 --- a/lib/socket_compat.h +++ b/lib/socket_compat.h @@ -1,6 +1,7 @@ /** - * Socket compatibility layer for cross-platform support (POSIX / Windows) - * MSYS2 UCRT64 compatible + * Единые socket_t, коды ошибок и wrappers сокетов POSIX/Windows (включая MSYS2 UCRT64). + * platform_init/cleanup обслуживают Winsock; UDP/nonblocking/options/sendto/recvfrom — операции ОС. + * Созданные сокеты закрывает владелец через socket_close_wrapper; event loop находится в u_async.h. */ #ifndef SOCKET_COMPAT_H diff --git a/lib/speex_aec.h b/lib/speex_aec.h index d5aa8025..f58bb1a1 100644 --- a/lib/speex_aec.h +++ b/lib/speex_aec.h @@ -5,6 +5,9 @@ * перед кодированием. Работает на interleaved int16 PCM, 1/2 канала, частота 48000 (можно * 8000/16000/32000/48000), кадр 20 мс (960 сэмплов @48 кГц). * + * Объект не имеет внутренних блокировок: feed/process/reset/get_stats выполняет один владелец + * либо вызывающий сериализует их общей блокировкой. Аппаратные callbacks сами AEC не вызывают. + * * Модель использования (duplex-контур звонка): * - рендер (far-end, то что пошло в динамик) → speex_aec_feed_playback(); * - захват (near-end, микрофон) → speex_aec_process_capture(). diff --git a/lib/swm_min.h b/lib/swm_min.h index d9237340..200d751b 100644 --- a/lib/swm_min.h +++ b/lib/swm_min.h @@ -1,4 +1,5 @@ -/* sliding_window_min.h */ +/* swm_min — минимум последних window_size целых значений (окно по числу добавлений, не по времени). + * create → add/get_min → destroy; память окна выделяется при create, внутренняя синхронизация отсутствует. */ #ifndef SLIDING_WINDOW_MIN_H #define SLIDING_WINDOW_MIN_H diff --git a/lib/timeout_heap.c b/lib/timeout_heap.c index e91cf50b..e47b3c32 100644 --- a/lib/timeout_heap.c +++ b/lib/timeout_heap.c @@ -28,7 +28,6 @@ TimeoutHeap *timeout_heap_create(size_t initial_capacity) { DEBUG_DEBUG(DEBUG_CATEGORY_ETCP, "Creating TH3..."); h->size = 0; h->capacity = initial_capacity; - h->freed_count = 0; h->user_data = NULL; h->free_callback = NULL; return h; diff --git a/lib/timeout_heap.h b/lib/timeout_heap.h index 182eccca..295ed04b 100644 --- a/lib/timeout_heap.h +++ b/lib/timeout_heap.h @@ -1,4 +1,9 @@ -// timeout_heap.h +/* timeout_heap — min-heap таймеров для uasync; сам не измеряет время и не вызывает таймеры. + * Владелец задаёт абсолютные expiration в одной шкале и извлекает готовые записи через peek/pop. + * cancel помечает запись; её data передаётся free_callback при последующей очистке или destroy. + * Без free_callback data не освобождается. Успешный pop передаёт data вызывающему. + * index_ptr, если задан, должен жить до удаления записи; heap обновляет индекс при перестановках. + * Все операции одного heap выполняются в одном потоке, внутренней синхронизации нет. */ #ifndef TIMEOUT_HEAP_H #define TIMEOUT_HEAP_H @@ -11,7 +16,7 @@ extern "C" { #include // For uint64_t #include // For size_t -typedef uint64_t TimeoutTime; // e.g., milliseconds since epoch or from now +typedef uint64_t TimeoutTime; // Абсолютное время в шкале владельца (uasync использует timebase: 0.1 мс). typedef struct { TimeoutTime expiration; // Sort key (smaller = earlier) @@ -26,7 +31,6 @@ struct TimeoutHeap { TimeoutEntry *heap; // Dynamic array size_t size; // Current number of elements size_t capacity; // Allocated size - size_t freed_count; // Number of freed timer nodes void* user_data; // User data for free callback void (*free_callback)(void* user_data, void* data); // Callback to free data }; @@ -48,7 +52,7 @@ void timeout_heap_destroy(TimeoutHeap *h); * Set a callback function to free data when deleted nodes are removed. * @param h The heap. * @param user_data User data passed to callback. - * @param callback Callback function (if NULL, data is freed with free()). + * @param callback Освобождает data отменённых записей и всех записей при destroy; NULL оставляет data владельцу. */ void timeout_heap_set_free_callback(TimeoutHeap *h, void* user_data, void (*callback)(void* user_data, void* data)); @@ -57,6 +61,7 @@ void timeout_heap_set_free_callback(TimeoutHeap *h, void* user_data, void (*call * @param h The heap. * @param expiration The expiration time. * @param data User data associated with the timeout. + * @param index_ptr Optional pointer to a live size_t updated with the entry's zero-based heap index. * @return 0 on success, -1 on allocation failure. */ int timeout_heap_push(TimeoutHeap *h, TimeoutTime expiration, void *data, size_t *index_ptr); @@ -88,15 +93,10 @@ int timeout_heap_pop(TimeoutHeap *h, TimeoutEntry *out); */ int timeout_heap_cancel(TimeoutHeap *h, TimeoutTime expiration, void *data); +/* Отмена по сохранённому индексу; data защищает от отмены чужой записи. 0 / -1, освобождение отложено. */ int timeout_heap_cancel_at(TimeoutHeap *h, size_t index, void *data); -/** - * Get the number of freed timer nodes. - * @param h The heap. - * @return Count of freed timer nodes. - */ -size_t timeout_heap_get_freed_count(TimeoutHeap *h); - +/* Число записей, включая ещё не извлечённые отменённые; NULL → 0. */ size_t timeout_heap_get_size(TimeoutHeap *h); diff --git a/lib/u_async.h b/lib/u_async.h index 82414795..1089a3e4 100644 --- a/lib/u_async.h +++ b/lib/u_async.h @@ -1,6 +1,8 @@ -// uasync.h - -// модуль асинхронных операций. добавляем сокеты и таймауты и mainloop их обслуживает. +/* Цикл событий одного потока: сокеты (epoll/poll/select), таймеры и FIFO call_soon. + * create → регистрация callbacks → poll/mainloop → destroy вне callbacks после остановки владельцев. + * Таймауты задаются в timebase 0.1мс; arg принадлежит вызывающему, освобождает его callback/владелец. + * API сокетов/таймеров используется в потоке loop. Из другого потока — post/post_reserved и wakeup; + * публикация не продлевает время жизни ua/arg, их освобождение нужно согласовать с остановкой producers. */ #ifndef UASYNC_H #define UASYNC_H diff --git a/src/broadcast.h b/src/broadcast.h index 96605faf..0096f59f 100644 --- a/src/broadcast.h +++ b/src/broadcast.h @@ -1,3 +1,8 @@ +/* broadcast — рассылка данных соседям topo-группы с пересылкой и дедупликацией UUID. + * Контекст и кеш увиденных UUID принадлежат группе; TTL — срок хранения UUID, не счётчик сетевых хопов. + * init_instance регистрирует общий ETCP-диспетчер, init(group) создаёт состояние отдельной группы. + * Все вызовы/callbacks — uasync-поток; recv получает заимствованные uuid/data только на время callback. + * send копирует данные и возвращает 0 / -1; 0 не подтверждает доставку каждому участнику. */ #ifndef BROADCAST_H #define BROADCAST_H diff --git a/src/chat/chat_core_priv.h b/src/chat/chat_core_priv.h index 2047b7aa..78159fd6 100644 --- a/src/chat/chat_core_priv.h +++ b/src/chat/chat_core_priv.h @@ -1,8 +1,8 @@ /* * chat_core_priv.h — внутренний заголовок для под-модулей chat_core * - * Предоставляет доступ к глобальному состоянию g_cc и общим хелперам. - * Не включать извне chat/ — только для chat_core*.c. + * Предоставляет per-instance chat_core_ctx через CC(inst), общие SQL/сериализационные хелперы + * и внутренние операции частей chat_core/member_sync. Не включать извне chat/. */ #ifndef CHAT_CORE_PRIV_H @@ -73,7 +73,7 @@ static inline size_t b64_decode(const char* src, size_t src_len, uint8_t* dst, s return out; } -/* ── Глобальное состояние (определено в chat_core.c) ── */ +/* ── Состояние одного экземпляра (создаётся в chat_core.c) ── */ struct ms_props_cbk; /* member_sync.c */ struct ms_apply_cbk; /* member_sync.c */ diff --git a/src/chat/chat_headless_control.h b/src/chat/chat_headless_control.h index 58338c5b..2289ab8e 100644 --- a/src/chat/chat_headless_control.h +++ b/src/chat/chat_headless_control.h @@ -6,8 +6,10 @@ * Response: {"id":N,"ok":true,"data":{...}} | {"id":N,"ok":false,"error":"..."} * Event: {"event":"",...} * - * Commands: ping, status, channels, members, messages, send, invite, - * invite_nodes, connect, create_channel, subscribe, quit + * Команды каналов, DM, звонков/рации и настроек — в tools/chatcli_commands.txt; + * диспетчер реализации — chat_headless_control.c. Аудио PCM использует отдельные call/radio_headless сокеты. + * init регистрирует listener и события chat_event, destroy закрывает клиентов и снимает подписку. + * Все вызовы и команды исполняются в uasync-потоке экземпляра. */ #ifndef CHAT_HEADLESS_CONTROL_H #define CHAT_HEADLESS_CONTROL_H diff --git a/src/chat/invite_build.h b/src/chat/invite_build.h index 1d3f1cec..cbfb70fd 100644 --- a/src/chat/invite_build.h +++ b/src/chat/invite_build.h @@ -3,7 +3,7 @@ * * Общий модуль для всех GUI (desktop chatgui, Android, headless CLI). * Логика выбора «лучшего узла» перенесена из tools/chatgui-android/jni_bridge. - * Работает в uasync-потоке, использует общий контекст g_cc. + * Работает в uasync-потоке, использует chat_core_ctx конкретного UTUN_INSTANCE. */ #ifndef INVITE_BUILD_H #define INVITE_BUILD_H diff --git a/src/chat/invite_link.h b/src/chat/invite_link.h index 14811738..4cbfe603 100644 --- a/src/chat/invite_link.h +++ b/src/chat/invite_link.h @@ -1,8 +1,11 @@ /* * invite_link.h — invite-ссылки utun:// для каналов * - * Формат: utun:// + base64(version | password? | channel_id | [header | pubkey | addrs]+) - * Совместим с десктопной (Qt) и Android (Kotlin) версиями. + * Версия 0x03: utun:// + base64(version | pass_len/password | channel_id | join_key | + * reality_has/params | блоки pubkey/addrs). ID/port кодируются big-endian; nodeId выводится из pubkey. + * Общий формат с desktop Qt и Android Kotlin. Сам кодек не подключает узел и не регистрирует join_key. + * decode: 0/-1; encode: длина base64 без utun:// и NUL/-1; serialize_addrs: число байтов/-1. + * Буферы предоставляет вызывающий; encode завершает строку NUL. */ #ifndef INVITE_LINK_H #define INVITE_LINK_H diff --git a/src/config_parser.h b/src/config_parser.h index fded04b8..8e264ab2 100644 --- a/src/config_parser.h +++ b/src/config_parser.h @@ -1,4 +1,7 @@ -// config_parser.h - Configuration parser for utun application +/* INI-конфигурация ядра: слушающие сокеты, исходящие пиры, сети/подсети и настройки сервисов. + * parse_config читает файл, parse_config_from_buf — текст; filename задаёт источник в диагностике. + * Успех возвращает выделенную utun_config со списками; освобождение — только free_config. + * Парсер заполняет модель, запуск сетевых ресурсов выполняет utun_instance. */ #ifndef CONFIG_PARSER_H #define CONFIG_PARSER_H diff --git a/src/config_updater.h b/src/config_updater.h index 283f434f..fc7ecf19 100644 --- a/src/config_updater.h +++ b/src/config_updater.h @@ -1,4 +1,5 @@ -// config_updater.h - Configuration file updater +/* Обеспечивает идентичность X25519/node_id в INI-файле: проверяет поля и сохраняет исправленные ключи. + * config_ensure_keys_and_node_id меняет файл на диске; bytes_to_hex только форматирует буфер вызывающего. */ #ifndef CONFIG_UPDATER_H #define CONFIG_UPDATER_H diff --git a/src/dm/dm_core.h b/src/dm/dm_core.h index 7487874d..61fc2398 100644 --- a/src/dm/dm_core.h +++ b/src/dm/dm_core.h @@ -1,7 +1,8 @@ /* * dm_core.h — прямой p2p чат между двумя пользователями (DM) * - * Отдельная подсистема (НЕ канал): без TOPO_GROUP/member_sync/merkle. + * Личная беседа не создаёт отдельную TOPO_GROUP и не синхронизируется через member_sync/Merkle. + * Для доставки использует маршрут из общей CHAT-группы участников. * - conv_id и content_key детерминированно выводятся обеими сторонами * из своих ключей и pubkey пира (см. dm_crypto.h) — без переговоров. * - сообщения идут через etcp_router (прямое соединение или релей), diff --git a/src/eim_nat.h b/src/eim_nat.h index b8d5aac3..90623108 100644 --- a/src/eim_nat.h +++ b/src/eim_nat.h @@ -1,3 +1,9 @@ +/* eim_nat — таблица Endpoint-Independent Mapping для IPv4 TCP/UDP и ICMP echo. + * init_ctx создаёт состояние из global_config; при отключённом NAT оставляет initialized=0. + * egress/ingress меняют IP/порты и checksums на месте, не отправляют пакеты и не владеют TUN/ETCP. + * Перед обработкой нужен инициализированный ctx; вызовы последовательны в uasync-потоке. + * gateway/internal IP — host order, internal_port — network order, внешний порт — host order. + * src_conn заимствован; срок жизни и выбор транспорта обратной отправки контролирует nat_transport. */ #ifndef EIM_NAT_H #define EIM_NAT_H @@ -31,7 +37,7 @@ struct eim_nat_entry { struct ETCP_CONN* src_conn; // cached connection for sendback }; -// Pure NAT engine state (no transport/TUN/ETCP fields) +// Состояние преобразования; TUN и транспортные ресурсы принадлежат nat_transport. struct eim_nat_ctx { uint32_t gateway_ip; uint16_t port_start; @@ -47,8 +53,11 @@ struct global_config; int eim_nat_init_ctx(struct eim_nat_ctx* ctx, const struct global_config* g); void eim_nat_destroy_ctx(struct eim_nat_ctx* ctx); +/* 0 — обработано или пакет не подлежит NAT, -1 — ошибка; буфер принадлежит вызывающему. */ int eim_nat_egress(struct eim_nat_ctx* ctx, uint8_t* ip_data, size_t ip_len, uint64_t src_node_id, struct ETCP_CONN* src_conn); +/* out_entry изменяется только при найденном mapping; заранее установить *out_entry=NULL. + * Запись заимствована у ctx. 0 само по себе не означает, что пакет был преобразован. */ int eim_nat_ingress(struct eim_nat_ctx* ctx, uint8_t* ip_data, size_t ip_len, struct eim_nat_entry** out_entry); diff --git a/src/firewall.h b/src/firewall.h index ce11c98a..62a9def3 100644 --- a/src/firewall.h +++ b/src/firewall.h @@ -1,4 +1,7 @@ -// firewall.h - Firewall rules for utun +/* firewall — список разрешённых пар IPv4/порт из global_config, без изменения системного firewall. + * init/обнуление → load_rules (копия и сортировка правил) → check → free; контекст использует один поток. + * check: 1 разрешено, 0 запрещено; port=0 в правиле разрешает все порты IP, bypass_all разрешает всё. + * IP и порт передавать в host order, как в CFG_FIREWALL_RULE. */ #ifndef FIREWALL_H #define FIREWALL_H diff --git a/src/lwip_tcp/lwip_pbuf.h b/src/lwip_tcp/lwip_pbuf.h index ab7b9a87..33389182 100644 --- a/src/lwip_tcp/lwip_pbuf.h +++ b/src/lwip_tcp/lwip_pbuf.h @@ -1,4 +1,7 @@ -// lwip_pbuf.h — simplified packet buffer (PBUF_RAM only) +/* Буферы TCP-пакетов: одна RAM-аллокация с запасом перед payload и ручным refcount. + * alloc создаёт ref=1; free уменьшает ссылки всех элементов цепочки и освобождает элементы с ref=0. + * header сдвигает payload в пределах запаса; header_force не проверяет запас при добавлении. + * chain только связывает элементы, без увеличения refcount и пересчёта tot_len. Синхронизации нет. */ #ifndef LWIP_PBUF_H #define LWIP_PBUF_H diff --git a/src/lwip_tcp/lwip_tcp.h b/src/lwip_tcp/lwip_tcp.h index 8bb1bf94..3e6be6a6 100644 --- a/src/lwip_tcp/lwip_tcp.h +++ b/src/lwip_tcp/lwip_tcp.h @@ -1,4 +1,7 @@ -// lwip_tcp.h — lwIP TCP public API (adapted for uTun) +/* Адаптированный lwIP TCP для TUN-прокси: TCP-состояния, retransmit, окна и callbacks потоков. + * init создаёт контекст с uasync-таймером; input получает TCP-сегмент после IPv4-заголовка, + * output callback передаёт сегмент внешнему IP/TUN-слою. destroy освобождает PCB и таймер. + * API и callbacks требуют последовательного выполнения; input использует общий рабочий контекст. */ #ifndef LWIP_TCP_H #define LWIP_TCP_H @@ -85,7 +88,7 @@ typedef err_t (*tcp_poll_fn) (void *arg, struct tcp_pcb *pcb); typedef void (*tcp_err_fn) (void *arg, err_t err); typedef err_t (*tcp_connected_fn)(void *arg, struct tcp_pcb *pcb, err_t err); -// Output callback — called when TCP wants to send an IP packet +// Output callback получает TCP-сегмент и IP адреса отдельно; IPv4-заголовок строит вызывающий слой. typedef err_t (*tcp_output_fn)(void *arg, struct pbuf *p, uint32_t src_ip, uint32_t dst_ip); #define TCP_TRACE_SIZE 384 diff --git a/src/lwip_tcp/lwip_tcp_opts.h b/src/lwip_tcp/lwip_tcp_opts.h index 1bfdba6c..5dd9abe6 100644 --- a/src/lwip_tcp/lwip_tcp_opts.h +++ b/src/lwip_tcp/lwip_tcp_opts.h @@ -1,4 +1,5 @@ -// lwip_tcp_opts.h — hardcoded TCP configuration (no #ifdefs) +/* Параметры встроенного TCP: MSS, окна, лимиты повторов и таймеры в миллисекундах. + * Используются lwip_tcp/in/out; runtime-интервал и пределы RTO меняет lwip_tcp_set_timer. */ #ifndef LWIP_TCP_OPTS_H #define LWIP_TCP_OPTS_H diff --git a/src/lwip_tcp/lwip_tcp_priv.h b/src/lwip_tcp/lwip_tcp_priv.h index 8b0b1cea..4da61c3d 100644 --- a/src/lwip_tcp/lwip_tcp_priv.h +++ b/src/lwip_tcp/lwip_tcp_priv.h @@ -1,4 +1,5 @@ -// lwip_tcp_priv.h — lwIP TCP internal API +/* Внутренний API адаптированного lwIP TCP: wire TCP header, сегменты, контекст и межфайловые функции. + * Используется lwip_tcp/in/out; внешние пользователи включают lwip_tcp.h. */ #ifndef LWIP_TCP_PRIV_H #define LWIP_TCP_PRIV_H diff --git a/src/media_async/attachment.h b/src/media_async/attachment.h index f0342d91..99b113eb 100644 --- a/src/media_async/attachment.h +++ b/src/media_async/attachment.h @@ -1,6 +1,8 @@ -/* Общие метаданные готового вложения. Подготовка не знает адресата и транспорта. - * PM шифрует компактный wire-формат; GUI получает разобранные поля. - * encode/decode возвращают длину/0 или -1; неизвестные типы и лишние байты запрещены. */ +/* attachment — общие метаданные file/voice/video, без хранения файла, адресата и транспорта. + * validate/decode возвращают 0 / -1, encode — число записанных байтов / -1. + * Формат: kind:1, name_len:2, duration_ms:4, width:2, height:2, UTF-8 basename, waveform:100 только для voice. + * Числа big-endian; имя 1..255 байт без разделителей пути, лишние wire-байты запрещены. + * Caller владеет struct/буферами; DM шифрует эти метаданные, GUI получает разобранные поля. */ #ifndef ATTACHMENT_H #define ATTACHMENT_H #include diff --git a/src/media_async/attachment_send.h b/src/media_async/attachment_send.h index c7cc6e1b..469f3517 100644 --- a/src/media_async/attachment_send.h +++ b/src/media_async/attachment_send.h @@ -1,7 +1,10 @@ -/* Подготовить голос/видео и отправить в зафиксированную беседу. Вызывать trampoline +/* attachment_send — подготовить голос/видео и отправить в зафиксированный канал или DM. Вызывать trampoline * через uasync_post. Request и PCM/compressor переходят во владение задачи; * pcm_release освобождает pcm_owner, NULL означает PCM из u_malloc. - * Qt/Android используют общий результат подготовки, доставка остаётся в chat/dm. */ + * Qt/Android используют общий результат подготовки, доставка остаётся в chat/dm. + * req выделяется u_calloc; caller заполняет target/is_dm, info и source либо PCM. inst должен жить до done. + * Подготовка выполняется в media_async worker, публикация и attachment-события — в uasync. + * output/id/error заполняет задача; temporary_source разрешает удалить принадлежащий приложению source. */ #ifndef ATTACHMENT_SEND_H #define ATTACHMENT_SEND_H #include "attachment.h" @@ -12,14 +15,14 @@ extern "C" { #endif struct attachment_send_req { struct UTUN_INSTANCE* inst; - char target[64]; + char target[64]; /* Десятичный channel_id либо conv_id без префикса dm:, зафиксированный до подготовки. */ int is_dm; struct attachment_info info; uint8_t id[16]; char source[1024], output[1024]; int transcode, temporary_source; const int16_t* pcm; - size_t pcm_count; + size_t pcm_count; /* Для voice: int16, 48 кГц моно, число отсчётов. */ void* pcm_owner; void (*pcm_release)(void* owner); struct audio_compressor* compressor; diff --git a/src/media_async/voice_file.h b/src/media_async/voice_file.h index 0c66136c..3ce3fd72 100644 --- a/src/media_async/voice_file.h +++ b/src/media_async/voice_file.h @@ -1,6 +1,9 @@ -/* Существующий контейнер Opus голосовых Qt/Android. Вызывать только в worker. +/* voice_file — кодирование PCM в общий контейнер Opus голосовых сообщений Qt/Android. Вызывать только в worker. * PCM принадлежит вызывающему; encode заполняет duration/waveform по реально - * записанным кадрам. При ошибке неполный файл удаляется. */ + * записанным кадрам. При ошибке неполный файл удаляется; возврат 0 / -1. + * count — число interleaved int16 отсчётов; rate — 8/12/16/24/48 kHz, channels — 1/2, preset — 0..2. + * Пишутся полные кадры по 20мс (хвост отбрасывается), минимум 500мс, максимум 24ч. + * name задаёт caller; encode устанавливает kind=VOICE и обнуляет width/height. */ #ifndef VOICE_FILE_H #define VOICE_FILE_H #include "attachment.h" diff --git a/src/media_delivery/media_delivery.h b/src/media_delivery/media_delivery.h index 076cd9be..344121ea 100644 --- a/src/media_delivery/media_delivery.h +++ b/src/media_delivery/media_delivery.h @@ -1,4 +1,8 @@ -// media_delivery.h — распространение медиа (аудио/видео стриминг) +/* media_delivery — канальные медиафайлы: поиск держателей блоков, выдача/relay и репликация доступности. + * Суперузлы обмениваются block_availability, держатели отдают подписанные блоки, media_download собирает файл. + * init создаёт per-instance состояние, bind подключает протокол к router; destroy отменяет сетевую работу. + * Все операции — uasync-поток; долгие файловые/crypto-задачи выполняет media_async. + * E2E-файлы личных бесед используют dm_media/file_transfer, а не канальную таблицу доступности. */ #ifndef MEDIA_DELIVERY_H #define MEDIA_DELIVERY_H diff --git a/src/media_delivery/media_delivery_proto.h b/src/media_delivery/media_delivery_proto.h index a94a47ea..f5bd8385 100644 --- a/src/media_delivery/media_delivery_proto.h +++ b/src/media_delivery/media_delivery_proto.h @@ -1,4 +1,6 @@ -// media_delivery_proto.h — протокольные структуры media_delivery +/* media_delivery_proto — wire-структуры и подкоманды доставки блоков медиа CHAT-группы. + * Описывает запросы держателей, чанки, подтверждения наличия и репликацию между суперузлами. + * Это формат payload сервиса router, без группового маршрутизационного заголовка; обработчики — media_delivery/download. */ #ifndef MEDIA_DELIVERY_PROTO_H #define MEDIA_DELIVERY_PROTO_H diff --git a/src/media_delivery/media_download.h b/src/media_delivery/media_download.h index 31b6b7f7..99f8ce41 100644 --- a/src/media_delivery/media_download.h +++ b/src/media_delivery/media_download.h @@ -1,4 +1,7 @@ -// media_download.h — скачивание блоков медиа +/* media_download — загрузка канального файла по media_index_result: QUERY держателей → блоки → проверка/сборка. + * Состояние хранит inst->media_delivery; каждый подключённый держатель удерживается через CM handle. + * Старт копирует метаданные result; callbacks и обработчики — uasync-поток, файловая проверка — media_async. + * Failover/таймер простоя ограничивают повторы; done сообщает результат, а не гарантирует доставку другим участникам. */ #ifndef MEDIA_DOWNLOAD_H #define MEDIA_DOWNLOAD_H diff --git a/src/media_delivery/media_index.h b/src/media_delivery/media_index.h index b1c1a5bc..b9cebadc 100644 --- a/src/media_delivery/media_index.h +++ b/src/media_delivery/media_index.h @@ -1,4 +1,7 @@ -// media_index.h — таблица media_files + регистрация медиа с async-обработкой +/* media_index — индекс блоков канального файла в SQLite media_files: UUID, SHA256, Ed25519-подписи и location. + * init создаёт таблицу; register_async копирует/хеширует/подписывает файл в worker, затем commit и callback в uasync. + * db/ma/ua заимствованы и должны жить до завершения; доступ к БД выполняется в потоке ядра. + * Результат callback заимствован только до возврата. result_free освобождает block_ids/block_sigs, но не саму структуру. */ #ifndef MEDIA_INDEX_H #define MEDIA_INDEX_H @@ -40,6 +43,7 @@ int media_index_register_downloaded(sqlite3* db, const uint8_t* media_id, const const char* location, uint64_t node_id, int64_t file_size, int64_t chunk_size, int chunk, int64_t offset); +/* Callback может быть синхронным при отказе запуска. err=0 даёт result, иначе result=NULL. */ void media_index_register_async( struct media_async* ma, struct UASYNC* ua, sqlite3* db, uint64_t node_id, const uint8_t* ed25519_privkey, diff --git a/src/nat_transport.h b/src/nat_transport.h index 7d7b956e..d28f6336 100644 --- a/src/nat_transport.h +++ b/src/nat_transport.h @@ -1,4 +1,7 @@ -// nat_transport.h — NAT transport layer (TUN + ETCP protocol handling) +/* IPv4 NAT через отдельный TUN и сервис ETCP_RT_ID_NAT в UTUN-router. + * nat_via_node_id задаёт удалённого провайдера; при 0 узел сам выполняет eim_nat для клиентов. + * init создаёт TUN/обработчики по nat_enabled; destroy снимает их и освобождает ресурсы. + * Контекст принадлежит UTUN_INSTANCE; очереди и callbacks работают в uasync. */ #ifndef NAT_TRANSPORT_H #define NAT_TRANSPORT_H diff --git a/src/ntp_node_time.h b/src/ntp_node_time.h index b53f9e1e..e6334885 100644 --- a/src/ntp_node_time.h +++ b/src/ntp_node_time.h @@ -1,3 +1,7 @@ +/* ntp_node_time — обмен временем с прямыми ETCP-пирами, дополнение к интернет-NTP. + * Несинхронизированный узел принимает коррекцию синхронизированного пира с оценкой половины RTT, + * затем передаёт время остальным; при последующих сообщениях сравнивает изменение смещения для диагностики. + * init привязывает ETCP_ID_NTP_TIME и подписку на соединения, destroy удаляет их; все вызовы — uasync. */ #ifndef NTP_NODE_TIME_H #define NTP_NODE_TIME_H diff --git a/src/ntp_time.h b/src/ntp_time.h index ad3d2aa4..5237aeb4 100644 --- a/src/ntp_time.h +++ b/src/ntp_time.h @@ -1,3 +1,8 @@ +/* ntp_time — асинхронные UDP NTP-запросы с DNS и периодическим повтором в uasync-потоке ядра. + * Не меняет часы ОС: хранит local_time - ntp_time в instance->ntp.offset_us. + * get_us/get_seconds возвращают скорректированное wall-clock время; до синхронизации — локальное. + * init читает config и планирует первый цикл, destroy отменяет DNS/сокет/таймеры. + * synced означает наличие коррекции (в том числе полученной от пира), reachable — результат интернет-NTP. */ #ifndef NTP_TIME_H #define NTP_TIME_H diff --git a/src/proxy/icmp_proxy.h b/src/proxy/icmp_proxy.h index 7af4a68d..cdef2e14 100644 --- a/src/proxy/icmp_proxy.h +++ b/src/proxy/icmp_proxy.h @@ -1,4 +1,7 @@ -// icmp_proxy.h — ICMP echo (ping) прокси: клиент ↔ exit через etcp_router +/* IPv4 ICMP echo через UTUN-router: exit отправляет ping через raw socket, сопоставляет reply + * по собственному wire id/seq и восстанавливает исходные id/seq клиента. Запросы ограничены таймаутом. + * init/destroy и callbacks — в uasync; контекст принадлежит inst, роль берётся из tcp_proxy_server.enabled. + * test_loopback возвращает виртуальные ответы без сетевой отправки и предназначен для тестов. */ #ifndef ICMP_PROXY_H #define ICMP_PROXY_H diff --git a/src/proxy/socks_proxy.h b/src/proxy/socks_proxy.h index ee59d132..a8246d24 100644 --- a/src/proxy/socks_proxy.h +++ b/src/proxy/socks_proxy.h @@ -1,4 +1,6 @@ -// socks_proxy.h — SOCKS5 / HTTP CONNECT proxy (client side) +/* Локальные SOCKS5 CONNECT и HTTP proxy/CONNECT: DNS, handshake и передача TCP через удалённый exit. + * tcp_proxy_client владеет listener и списками соединений; их callbacks выполняются в uasync. + * init_listen заимствует указатели на списки/счётчики до close_listen; закрытие listener не освобождает клиентов. */ #ifndef SOCKS_PROXY_H #define SOCKS_PROXY_H @@ -81,13 +83,13 @@ struct listen_ctx* socks_proxy_init_listen(struct UASYNC* ua, const char* addr_s struct UTUN_INSTANCE* inst, uint64_t via_node_id, int is_http); // Закрыть слушающий сокет и освободить listen_ctx. -// sock_out получает значение сокета (для последующего close). +// Если sock_out задан, в него записывается SOCKET_INVALID: сокет уже закрыт. void socks_proxy_close_listen(struct UASYNC* ua, struct listen_ctx* ctx, socket_t* sock_out); // Найти соединение по stream_id struct socks_proxy_conn* socks_proxy_find_conn(struct socks_proxy_conn* head, uint32_t stream_id); -// Обработать входящее ETCP сообщение (DATA/CLOSE/ERROR/FIN) +// Обработать ответ exit: CONNECTED/DATA/WINDOW_UPDATE/CLOSE/ERROR/FIN. // Возвращает 1 если обработано, 0 если stream_id не найден int socks_proxy_handle_etcp(struct socks_proxy_conn** head, int* count, uint32_t stream_id, uint8_t subcmd, diff --git a/src/proxy/tcp_proxy_client.h b/src/proxy/tcp_proxy_client.h index 45717624..c4a6dd7f 100644 --- a/src/proxy/tcp_proxy_client.h +++ b/src/proxy/tcp_proxy_client.h @@ -1,4 +1,7 @@ -// tcp_proxy_client.h — TCP прокси-клиент: стек lwIP TCP → ETCP → удалённый exit узел +/* Клиент TCP-прокси: принимает IPv4 с отдельного TUN через lwIP либо TCP от SOCKS/HTTP listener. + * Передаёт потоки через UTUN-router на via_node_id; proxy_flow обеспечивает окно и backpressure. + * create/destroy и callbacks — в uasync. Владеет созданными TUN/lwIP/listener/потоками, + * заимствует inst/ua/mappings до destroy. Без tun_name/tun_ip может работать только SOCKS/HTTP. */ #ifndef TCP_PROXY_CLIENT_H #define TCP_PROXY_CLIENT_H diff --git a/src/proxy/tcp_proxy_server.h b/src/proxy/tcp_proxy_server.h index a72abed6..4c0b60c3 100644 --- a/src/proxy/tcp_proxy_server.h +++ b/src/proxy/tcp_proxy_server.h @@ -1,4 +1,7 @@ -// tcp_proxy_server.h — TCP прокси-сервер (exit node) +/* Exit TCP-прокси: принимает CONNECT/DATA через UTUN-router и открывает обычный TCP к назначению. + * Поток определяется парой peer_node_id/stream_id; proxy_flow согласует окна и half-close. + * init учитывает tcp_proxy_server_enabled в конфиге; destroy закрывает потоки и общий UDP/ICMP-прокси. + * Состояние принадлежит UTUN_INSTANCE, операции и callbacks выполняются в его uasync-потоке. */ #ifndef TCP_PROXY_SERVER_H #define TCP_PROXY_SERVER_H diff --git a/src/proxy/udp_proxy.h b/src/proxy/udp_proxy.h index be33c33d..937fe5fe 100644 --- a/src/proxy/udp_proxy.h +++ b/src/proxy/udp_proxy.h @@ -1,4 +1,6 @@ -// udp_proxy.h — UDP датаграммный прокси: клиент ↔ exit через etcp_router +/* UDP из TUN через UTUN-router: клиент отправляет REQUEST, exit открывает сокет для кортежа адресов + * и возвращает REPLY. Потоки exit удаляются по таймауту неактивности. + * init/destroy и callbacks — в uasync; контекст принадлежит inst, роль берётся из tcp_proxy_server.enabled. */ #ifndef UDP_PROXY_H #define UDP_PROXY_H diff --git a/src/radio/radio_audio.h b/src/radio/radio_audio.h index 97ed33f1..00b065a0 100644 --- a/src/radio/radio_audio.h +++ b/src/radio/radio_audio.h @@ -75,7 +75,7 @@ int radio_audio_vad_mode(void); /* Текущее состояние передачи: ручной PTT либо сработавший VAD. */ int radio_audio_transmitting(void); -/* uasync-поток: принятый Opus-кадр источника (декодируем + кладём в ring). */ +/* uasync-поток: копируем Opus-кадр в jitter источника; декодирование/растяжение — на pull в RX-потоке. */ void radio_audio_on_frame(struct UTUN_INSTANCE* inst, uint64_t group_id, uint64_t src_node_id, uint16_t stream_id, uint16_t seq, uint8_t fin, const uint8_t* opus, int len, void* arg); diff --git a/src/routing_layer/conn_mgr_priv.h b/src/routing_layer/conn_mgr_priv.h index 67adcd9c..66343118 100644 --- a/src/routing_layer/conn_mgr_priv.h +++ b/src/routing_layer/conn_mgr_priv.h @@ -1,3 +1,7 @@ +/* conn_mgr_priv — внутренние состояния, wire-команды и общие операции трёх частей conn_mgr. + * core управляет handles и попытками, indirect — согласованием посредников, monitor — оценкой/обновлением путей. + * Все структуры принадлежат менеджеру topo-группы и используются в его uasync-потоке. + * Сервисы подключаются через conn_mgr.h; поля ENTRY/CANDIDATE не являются внешним API. */ #ifndef CONN_MGR_PRIV_H #define CONN_MGR_PRIV_H diff --git a/src/routing_layer/route6_lib.h b/src/routing_layer/route6_lib.h index 0f685c85..8b40ab99 100644 --- a/src/routing_layer/route6_lib.h +++ b/src/routing_layer/route6_lib.h @@ -1,3 +1,7 @@ +/* route6_lib — локальная IPv6-таблица подсетей на BSD radix с longest-prefix lookup. + * Очередь индексирует записи по node_id для удаления всех подсетей узла; TOPO_GROUP_NODE заимствован. + * create/insert/lookup/delete/destroy — в одном uasync-потоке; маршруты удалять до освобождения узла. + * addr — 16 сетевых байтов. Результат lookup принадлежит таблице и живёт до удаления записи/destroy. */ #ifndef ROUTE6_LIB_H #define ROUTE6_LIB_H @@ -13,36 +17,7 @@ extern "C" { #include "../lib/u_async.h" -/* -Диапазон Назначение -::/128 Неопределенный адрес (unspecified). Используется до назначения адреса интерфейсу. -::1/128 Адрес обратной петли (loopback), аналог 127.0.0.1 в IPv4. -2000::/3 Глобально маршрутизируемые (Global Unicast) адреса. Основное адресное пространство Интернета. -fc00::/7 Уникальные локальные адреса (ULA), аналог частных IPv4 (10.0.0.0/8, 192.168.0.0/16). На практике обычно используется fd00::/8. -fe80::/10 Локальные канальные адреса (Link-Local). Автоматически назначаются интерфейсам и работают только в пределах одного сегмента сети. Не маршрутизируются. -ff00::/8 Multicast-адреса. Используются вместо широковещания (broadcast), которого в IPv6 нет. -100::/64 Адреса для протокола Discard-Only. Предназначены для тестирования и отладки. -64:ff9b::/96 Префикс для трансляции IPv4↔IPv6 (NAT64). -64:ff9b:1::/48 Расширенный префикс NAT64. -2001:db8::/32 Зарезервирован для документации и примеров. Не используется в Интернете. -2002::/16 6to4-адреса (устаревший механизм перехода с IPv4 на IPv6). -2001::/32 Teredo (устаревшая технология туннелирования IPv6 через IPv4). -::ffff:0:0/96 IPv4-mapped IPv6 addresses. Используются ОС для представления IPv4-адресов в IPv6 API. -Адреса узлов сети формируются по следующему принципу: -FCxx:xxxx:xxxx:xxxx : yyyy:yyyy:yyyy:yyyy - local network: x = network id, y - node id. - -- network id --- ---- node id ------ - -FDxx/8 - опциональные ipv6 подсети узлов /64 (если нужно) - -В разных node_groups общие: -- nodelists с их настройками (глобальная таблица) -- одинаковые линки между nodes (т.к. только один линк между парой узлов) - -- При маршрутизации используем только узлы - - -*/ // таблица маршрутизации IPv6 на radix tree + ll_queue (поиск по node_id для удаления) diff --git a/src/routing_layer/route_connectivity.h b/src/routing_layer/route_connectivity.h index 4dd18313..0a112a1c 100644 --- a/src/routing_layer/route_connectivity.h +++ b/src/routing_layer/route_connectivity.h @@ -1,3 +1,7 @@ +/* route_connectivity — прямые UDP/TCP-пробы адресов узла для оценки достижимости и RTT. + * probe_node запускает серии из подходящих локальных сокетов и обновляет nq->connectivity; + * результат используется топологией, сама проба не создаёт READY-сессию группы. + * Состояние привязано к TOPO_GROUP_NODE: отменить пробы до удаления узла/группы. Все операции — uasync. */ #ifndef ROUTE_CONNECTIVITY_H #define ROUTE_CONNECTIVITY_H diff --git a/src/routing_layer/route_lib.h b/src/routing_layer/route_lib.h index 6533930a..a9a2a57d 100644 --- a/src/routing_layer/route_lib.h +++ b/src/routing_layer/route_lib.h @@ -1,3 +1,8 @@ +/* route_lib — локальная IPv4-таблица подсетей UTUN, отсортированный массив без пересечения маршрутов. + * create → insert/add_local_subnet → lookup → delete/destroy; все операции в одном uasync-потоке. + * network/dest_ip/parse_subnet — host order; только is_local_subnet принимает network order. + * TOPO_GROUP_NODE заимствован: удалить его маршруты до освобождения узла. + * lookup возвращает элемент массива, действительный до следующего изменения таблицы. */ #ifndef ROUTE_LIB_H #define ROUTE_LIB_H @@ -32,7 +37,7 @@ typedef enum { * Структура представляет собой отдельную запись в таблице маршрутизации с детальной информацией о маршруте. */ struct ROUTE_ENTRY { - uint32_t network; // Сетевой адрес (big-endian) + uint32_t network; // Сетевой адрес в host order uint8_t prefix_length; // Длина префикса подсети struct TOPO_GROUP_NODE* v_node_info; // узел владелец этих маршрутов. null если - локальный маршрут. }; @@ -78,7 +83,7 @@ void route_table_destroy(struct ROUTE_TABLE *table); * @brief Вставляет в таблицу маршрутизации все подсети для указанного узла * @param node узел, все маршруты которого нужно добавить * - * @return true если вставка/обновление успешно + * @return true если подсети добавлены; false при отсутствии подсетей, пересечении или ошибке выделения памяти */ bool route_insert(struct ROUTE_TABLE *table, struct TOPO_GROUP_NODE *node); @@ -94,7 +99,7 @@ void route_delete(struct ROUTE_TABLE *table, struct TOPO_GROUP_NODE *node); * @brief Выполняет поиск маршрута для заданного IP-адреса * * @param table Указатель на таблицу маршрутизации - * @param dest_ip Целевой IP-адрес + * @param dest_ip Целевой IPv4-адрес в host order * @return найденный маршрут или NULL */ struct ROUTE_ENTRY* route_lookup(struct ROUTE_TABLE *table, uint32_t dest_ip); @@ -110,7 +115,7 @@ void route_table_print(const struct ROUTE_TABLE *table); * @brief Парсит строку подсети в сетевой адрес и длину префикса * * @param subnet_str Строка подсети (например, "192.168.1.0/24") - * @param network Указатель для сохранения сетевого адреса + * @param network Указатель для сохранения адреса в host order * @param prefix_length Указатель для сохранения длины префикса * @return 0 при успехе, -1 при ошибке */ diff --git a/src/routing_layer/routing.h b/src/routing_layer/routing.h index 45620e82..49c73adc 100644 --- a/src/routing_layer/routing.h +++ b/src/routing_layer/routing.h @@ -1,4 +1,7 @@ -// routing.h - Centralized routing module for utun +/* routing — обмен IPv4-пакетами UTUN между локальным TUN и сервисом DATA ETCP-router. + * create создаёт таблицу, bind регистрирует DATA после инициализации router; set_tun подключает очередь TUN. + * route_pkt принимает [cmd:1][IPv4...] и забирает entry/dgram; все вызовы выполняются в uasync-потоке. + * Групповые пути ведёт topo_group, пересылку через промежуточные узлы — etcp_router. */ #ifndef ROUTING_H #define ROUTING_H @@ -36,22 +39,20 @@ int routing_bind(struct UTUN_INSTANCE* instance); void routing_destroy(struct UTUN_INSTANCE* instance); /** - * @brief Register ETCP connection with routing - * Called from pn_init() to register connection's normalizer output queue + * @brief Исторический вызов из pn_init: сейчас только диагностический no-op, очереди не регистрирует * @param etcp ETCP connection */ void routing_add_conn(struct ETCP_CONN* etcp); /** - * @brief Unregister ETCP connection from routing - * Called from pn_deinit() to unregister connection's normalizer output queue + * @brief Исторический вызов из pn_deinit: сейчас только диагностический no-op * @param etcp ETCP connection */ void routing_del_conn(struct ETCP_CONN* etcp); /** * @brief Set TUN interface for routing - * Called from utun_instance_init() after tun_init() + * Вызывается при подключении TUN к UTUN-сервису * @param instance UTUN instance with configured tun */ void routing_set_tun(struct UTUN_INSTANCE* instance); diff --git a/src/routing_layer/topo_node_sqlite.h b/src/routing_layer/topo_node_sqlite.h index d6263e4c..92c5c4c1 100644 --- a/src/routing_layer/topo_node_sqlite.h +++ b/src/routing_layer/topo_node_sqlite.h @@ -1,3 +1,8 @@ +/* topo_node_sqlite — хранение подписанных снимков узлов, адресов, каналов и блоков мемберов в общей SQLite. + * Модель/проверка подписей/registry — topo_node и member_sync; этот модуль реализует SQL-операции в uasync-потоке. + * snapshot_put проверяет подпись и сохраняет только более свежий timestamp; node_load предпочитает snapshot. + * db/groups заимствованы. Возвращённый TOPO_NODE без registry ref: передать registry либо уничтожить через topo_node_destroy. + * Массивы out_ids/out_ch_ids/out_peers принадлежат вызывающему и освобождаются u_free. */ #ifndef TOPO_NODE_SQLITE_H #define TOPO_NODE_SQLITE_H @@ -101,8 +106,8 @@ void topo_node_sqlite_update_rtt(sqlite3* db, uint64_t node_id, uint16_t rtt); * @param groups нужен для выделения адресов из memory_pool * @return TOPO_NODE* или NULL если узел не найден/нет адресов * - * Загружает pubkey, name из nodes, IPv4/UDP-адреса из node_addresses. - * Вызывающий должен передать владение через topo_node_registry_acquire(). + * Сначала загружает и проверяет подписанный snapshot; при его отсутствии собирает сведения nodes/node_addresses. + * Вызывающий передаёт владение через topo_node_registry_acquire() либо вызывает topo_node_destroy(). */ struct TOPO_NODE* topo_node_sqlite_node_load(sqlite3* db, struct TOPO_GROUPS* groups, uint64_t node_id); diff --git a/src/transport_layer/crc32.h b/src/transport_layer/crc32.h index 89c55cb5..4512de80 100644 --- a/src/transport_layer/crc32.h +++ b/src/transport_layer/crc32.h @@ -1,3 +1,8 @@ +/* crc32 — табличный CRC-32 с отражённым полиномом 0xEDB88320. + * calc для непустого блока начинает с UINT32_MAX и инвертирует результат. + * calc_ex/update возвращают внутренний CRC без финальной инверсии: для потока начать с UINT32_MAX, + * последовательно update и в конце инвертировать. NULL/пустой calc → UINT32_MAX, update → исходный CRC. + * Таблица общая, без блокировки: при нескольких потоках выполнить init до их запуска. */ #ifndef CRC32_H #define CRC32_H @@ -25,4 +30,4 @@ uint32_t crc32_update(uint32_t crc, const uint8_t *data, size_t len); #ifdef __cplusplus } #endif -#endif // CRC32_H \ No newline at end of file +#endif // CRC32_H diff --git a/src/transport_layer/etcp_bbr.h b/src/transport_layer/etcp_bbr.h index 941842b5..15210157 100644 --- a/src/transport_layer/etcp_bbr.h +++ b/src/transport_layer/etcp_bbr.h @@ -1,3 +1,7 @@ +/* etcp_bbr — модель congestion control одного ETCP-линка: состояния BBR, окно и pacing rate. + * ETCP собирает bbr_rate_sample из ACK/потерь и вызывает init/main/note_loss/tx_start в uasync-потоке. + * Модуль не отправляет пакеты: возвращённые лимиты применяет линк/loadbalancer. + * cwnd/inflight/delivered — байты, interval/rtt — микросекунды, pacing_rate — байты в секунду. */ #pragma once #include diff --git a/src/transport_layer/etcp_connect.h b/src/transport_layer/etcp_connect.h index 9a6b586c..817c5715 100644 --- a/src/transport_layer/etcp_connect.h +++ b/src/transport_layer/etcp_connect.h @@ -8,178 +8,22 @@ struct ETCP_CONN; struct TOPO_GROUP_NODE; typedef void (*etcp_connect_callback_t)(void* arg, struct ETCP_CONN* conn, int type); -/** - * ============================================================================ - * etcp_connect() — асинхронное подключение к удалённому узлу - * ============================================================================ - * - * Инициирует (или находит существующее) ETCP-соединение к узлу. - * Вызов неблокирующий: коллбэк cb вызывается асинхронно по мере прохождения - * фаз установки соединения. - * - * @param inst UTUN_INSTANCE - * @param node узел-адресат (TOPO_GROUP_NODE). Из node->node берутся: - * - node_id — идентификатор узла (0 = вычислить из pubkey) - * - public_key — X25519 pubkey (32 байта) - * - v4_addrs / v6_addrs — адреса для создания линков - * @param cb коллбэк (etcp_connect_callback_t) - * @param arg пользовательский аргумент, передаваемый в cb - * @param flags битовая маска интересующих фаз: ETCP_CONNECT_EARLY(1) | - * ETCP_CONNECT_LATE(2) - * @return 0 при успехе, -1 при ошибке (до вызова коллбэка) - * - * - * ---- Деривация node_id ---- - * - * Если node->node->node_id == 0, он вычисляется из public_key: - * node_id = SHA256(pubkey, 32)[0..7] & 0x7FFFFFFFFFFFFFFF - * - * Требования к ключу: - * - public_key не NULL - * - не все 32 байта нулевые - * Иначе — возврат -1 без вызова коллбэка. - * - * Вычисленный node_id сохраняется обратно в node->node->node_id. - * - * - * ---- Индексация соединения ---- - * - * Сразу после etcp_connection_create() conn->peer_node_id устанавливается - * в node_id, что позволяет etcp_conn_queue_set_ready() (при инициализации - * первого линка) переиндексировать запись в очереди inst->connections - * с key=0 на key=node_id. - * - * До переиндексации соединение находится в очереди с key=0 и доступно - * только через connect_find() в pending_connects или по совпадению адреса. - * - * - * ---- Поиск существующего соединения ---- - * - * Перед созданием нового conn выполняется поиск: - * - * a. instance_find_conn(inst, node_id) — активное соединение в очереди - * inst->connections (UDP) или inst->tcp_connections (TCP) - * b. connect_find(inst, node_id) — контекст в inst->pending_connects - * - * Возможные комбинации: - * - * 1. conn && ctx — уже подключается - * ├─ ctx->done (таймаут уже сработал) → cb(arg, NULL, 0) сразу - * └─ иначе → cb добавляется в ctx->cb_list (ждёт своей фазы) - * - * 2. !conn && ctx — контекст есть, но conn был удалён (редкий случай) - * → cb добавляется в ctx->cb_list - * - * 3. conn && !ctx — соединение рабочее, контекста нет (входящее/серверное) - * ├─ conn->state == 0 (pending, ещё не инициализирован): - * │ → создаётся ctx с connect_init_cb, initial_timer - * │ → ctx добавляется в pending_connects - * │ → ожидание инициализации в обычном порядке - * │ - * └─ conn->state == 1 (ready, уже проинициализирован): - * → connect_deliver(ctx, ETCP_CONNECT_LATE) сразу - * → контекст освобождается; готовность топологии принадлежит группе - * - * 4. !conn && !ctx — новое подключение (основной путь) - * → etcp_connection_create(inst, NULL) - * → conn->peer_node_id = node_id (индексация deferred до queue_set_ready) - * → sc_init_ctx + sc_set_peer_public_key — настройка крипто - * → connect_create_links_v4/v6 — создание UDP + TCP линков - * → initial_timer = uasync_set_timeout(connect_timeout_tb, ...) - * → ctx добавляется в pending_connects - * - * - * ---- Фазы доставки коллбэков ---- - * - * connect_init_cb (вызывается при conn->initialized, первый линк отдал рукопожатие): - * - * Подсчитывается total_links и up_links (link_state == 3): - * - * ├─ total_links == 1: один линк — EARLY не нужен - * │ → connect_deliver(ctx, ETCP_CONNECT_LATE) — сразу LATE - * │ → ctx освобождается - * │ - * ├─ up_links == total_links: все линки уже UP (link_state==3) - * │ → connect_deliver(ctx, ETCP_CONNECT_LATE) — сразу LATE - * │ → ctx освобождается - * │ - * └─ иначе (часть линков UP, часть ещё в handshake): - * → connect_deliver(ctx, ETCP_CONNECT_EARLY) — уведомить о доступности - * → initial_timer отменяется - * → запускается settle_timer = min_rtt * 8 (clamped [500ms, 2s] в 0.1ms) - * - * connect_settle_timeout_cb (settle-таймер): - * ├─ Закрывает неинициализированные линки (!link->initialized) - * ├─ Закрывает TCP-линк если !tcp_ready - * ├─ Убирает connect_init_cb из conn->cbks - * └─ connect_deliver(ctx, ETCP_CONNECT_LATE) → ctx освобождается - * - * connect_initial_timeout_cb (initial_timer): - * ├─ ctx->done = 1 - * ├─ Закрывает TCP-линк - * ├─ connect_deliver(ctx, 0) → cb(arg, NULL, 0) для всех - * ├─ etcp_connection_close(conn) — закрывает соединение - * └─ ctx освобождается - * - * - * ---- Ошибки ---- - * - * Коллбэк вызывается с type=0, conn=NULL в случаях: - * - initial_timer истёк (ни один линк не инициализировался) - * - все линки были закрыты до завершения handshake - * - ошибка аллокации / крипто на этапе создания - * - * - * ---- Штатное закрытие исходящих соединений ---- - * - * Пути завершения ctx: - * - * 1. Таймаут установки (connect_initial_timeout_cb): - * stcp_link_close(tcp_link) → etcp_connection_close(conn) → connect_cancel(ctx) - * - * 2. Settle таймаут (connect_settle_timeout_cb): - * stcp_link_close(tcp_link) (если !tcp_ready) → connect_cancel(ctx) - * - * 3. Штатное закрытие через utun_instance_destroy(): - * utun_instance_destroy(inst) - * ├── etcp_connection_close(conn) для всех conn - * │ Фаза 1 (detach): закрыть линки, удалить из inst->connections, state=2 - * │ Фаза 2 (deferred): uasync_call_soon(ua, conn, etcp_connection_free_deferred) - * │ - * ├── while (immediate_queue_head) uasync_poll(ua, 0) - * │ └── etcp_connection_free_resources(conn) - * │ ├── drain_and_free_queue(*) - * │ ├── etcp_connect_cancel_for_conn(inst, conn) - * │ └── u_free(etcp) - * │ - * └── memory_pool_destroy(pkt/ack/data) - * - * ============================================================================ - */ +/* Внутренний установщик прямого ETCP-транспорта; владельцы используют node_conn_direct.h. + * node->node_id должен находиться в node_registry: оттуда берутся ключ и IPv4/IPv6 адреса. + * Подключение создаёт UDP/STCP-линки либо подписывает callback на текущую попытку к тому же узлу. + * Все вызовы/callbacks — в uasync. flags — непустая маска ETCP_CONNECT_EARLY/LATE (etcp_api.h). + * EARLY означает появление транспорта; LATE — завершение выбора линков. Они не означают READY группы. + * При одном/полностью готовом наборе линков обе запрошенные фазы выдаются подряд; + * иначе после EARLY ждём settle 0.5..2с и удаляем неинициализированные линки. + * Для уже готового соединения callback вызывается внутри etcp_connect, до возврата. + * conn в callback заимствован. type=0/conn=NULL — отказ; initial timeout закрывает соединение. + * Возврат 0 означает принятую попытку/выданный результат; -1 — ошибка, причём некоторые + * ошибки создания также вызывают cb(NULL,0). Обработчик должен учитывать оба способа отказа. */ int etcp_connect(struct UTUN_INSTANCE* instance, struct TOPO_GROUP_NODE* node, etcp_connect_callback_t cb, void* arg, uint8_t flags); -/* - * ============================================================================ - * etcp_connect_cancel_for_conn() - * ============================================================================ - * - * Аналог приватного connect_cancel(), но ищет ETCP_CONNECT ctx по совпадению - * ctx->conn == conn (а не по указателю на ctx). - * - * Делает: - * 1. Удаляет ctx из inst->pending_connects - * 2. ctx->done = 1; ctx->conn = NULL - * 3. uasync_cancel_timeout(initial_timer / settle_timer) - * 4. u_free(ctx) - * - * НЕ закрывает ctx->tcp_link (чужая ответственность). - * - * Вызывается ТОЛЬКО из etcp_connection_free_resources (фаза 2 deferred cleanup). - * НЕ вызывать из mainloop / uasync_poll callbacks — conn уже может быть в state=2. - * - * ============================================================================ - */ +/* Снять таймеры/контекст по conn без уведомления callbacks. Только teardown соединения, + * когда connect_init_cb больше не может быть вызван; транспорт освобождает вызывающий слой. */ void etcp_connect_cancel_for_conn(struct UTUN_INSTANCE* inst, struct ETCP_CONN* conn); /* Полная отмена pending-коннекта по node_id: снимает коллбэки с conn (conn остаётся diff --git a/src/transport_layer/etcp_debug.h b/src/transport_layer/etcp_debug.h index 2b540d51..c599410c 100644 --- a/src/transport_layer/etcp_debug.h +++ b/src/transport_layer/etcp_debug.h @@ -1,3 +1,6 @@ +/* etcp_debug — форматирование IPv4 в host order и диагностический разбор секций ETCP_DGRAM. + * ip_to_string возвращает строку по значению. dump_pkt_sections пишет DEBUG категории dump, + * не меняет пакет и не проверяет его криптографию; состояние pkt/link читается в uasync-потоке. */ #ifndef ETCP_DEBUG_H #define ETCP_DEBUG_H diff --git a/src/transport_layer/etcp_dump.h b/src/transport_layer/etcp_dump.h index b0c775fb..1aff231b 100644 --- a/src/transport_layer/etcp_dump.h +++ b/src/transport_layer/etcp_dump.h @@ -1,3 +1,6 @@ +/* etcp_dump — снимки состояния ETCP-соединений/линков, очередей и сокетов экземпляра. + * Вызывается в uasync-потоке, пишет DEBUG категории etcp_dump; не меняет состояние и не владеет объектами. + * conn_state выводит один conn, all_conns/sockets — соответствующие списки, all — оба списка. */ #ifndef ETCP_DUMP_H #define ETCP_DUMP_H diff --git a/src/transport_layer/etcp_loadbalancer.h b/src/transport_layer/etcp_loadbalancer.h index 47c578ea..c9cd364c 100644 --- a/src/transport_layer/etcp_loadbalancer.h +++ b/src/transport_layer/etcp_loadbalancer.h @@ -1,4 +1,6 @@ -// etcp_loadbalancer.h - Load Balancer for ETCP Channels +/* etcp_loadbalancer — выбор доступного линка одного ETCP_CONN с учётом cwnd, inflight и pacing/shaper. + * select_link возвращает заимствованный готовый линк или NULL. send шифрует/отправляет пакет и учитывает shaper, + * link_ready пробуждает packet_request_fn после снятия ограничений; все вызовы — uasync-поток соединения. */ #ifndef ETCP_LOADBALANCER_H #define ETCP_LOADBALANCER_H @@ -20,13 +22,13 @@ struct ETCP_LINK* etcp_loadbalancer_select_link(struct ETCP_CONN* etcp); // Когда линк снова ready (timer или link_ready) - loadbalancer должен вызвать ETCP_CONN->packet_request_fn(etcp) -//void etcp_loadbalancer_update_after_send(struct ETCP_LINK* link, size_t pkt_size); - это надо заменить на: +// Передать dgram с установленным link: после отправки (включая ошибку сокета) возвращает dgram в pkt_pool. void etcp_loadbalancer_send(struct ETCP_DGRAM* dgram); // сообщаем в loadbalancer о готовности линка (вызывается из таймера, ACK, изменения лимита) void loadbalancer_link_ready(struct ETCP_LINK* link); -// проверяет все условия блокировки отправки (включая inflight_bytes) +// Проверяет готовность shaper (burst разрешён); cwnd/inflight учитывает select_link отдельно. int loadbalancer_link_can_send(struct ETCP_LINK* link); // Получить состояние связи ETCP: 1 - есть живой линк, 0 - все недоступны @@ -36,4 +38,4 @@ int etcp_loadbalancer_get_link_status(struct ETCP_CONN* etcp); } #endif -#endif // ETCP_LOADBALANCER_H \ No newline at end of file +#endif // ETCP_LOADBALANCER_H diff --git a/src/transport_layer/etcp_session.h b/src/transport_layer/etcp_session.h index d7c56a5d..cf29f2c6 100644 --- a/src/transport_layer/etcp_session.h +++ b/src/transport_layer/etcp_session.h @@ -1,3 +1,7 @@ +/* etcp_session — подтверждение эпох одного ETCP_CONN, чтобы старые DATA не попадали в новый поток. + * HELLO/CHALLENGE/CONFIRM отправляются по инициализированным линкам, вне надёжного потока/normalizer. + * Обработчик вызывается после проверки защиты пакета; принадлежность сессии проверяет accept_data. + * Состояние и retry-таймер принадлежат ETCP_CONN. Все вызовы — его uasync-поток; перед teardown нужен cancel. */ #ifndef ETCP_SESSION_H #define ETCP_SESSION_H #include @@ -11,11 +15,16 @@ struct ETCP_CONN; #define ETCP_SESSION_HEADER_SIZE 17 #define ETCP_SESSION_CONTROL_SIZE 25 -/* Authenticated link control, independent of the reliable stream and its normalizer. */ +/* Запустить обязательное подтверждение; при таймауте неподтверждённое соединение закрывается. */ void etcp_session_start(struct ETCP_CONN* conn); +/* Предложить ненулевую эпоху пира для challenge; это ещё не разрешает приём DATA новой эпохи. */ void etcp_session_observe(struct ETCP_CONN* conn, uint64_t peer_epoch); +/* Отменить retry и сбросить candidate/cookie; подтверждённые reset_id/peer_reset_id сохраняются. */ void etcp_session_cancel(struct ETCP_CONN* conn); +/* 1 — control распознан (в том числе отброшен как ошибочный), 0 — не control. Буфер остаётся у вызывающего. */ int etcp_session_receive(struct ETCP_CONN* conn, const uint8_t* data, size_t len); +/* Записать 17-байтный заголовок code/sender/target; epochs — big-endian, cookie/body добавляет вызывающий. */ void etcp_session_encode(uint8_t* data, uint8_t code, uint64_t sender, uint64_t target); +/* 1 — DATA принадлежит готовой текущей сессии, 0 — ошибочная/старая. Заголовок не снимает, поток не обрабатывает. */ int etcp_session_accept_data(struct ETCP_CONN* conn, const uint8_t* data, size_t len); #endif diff --git a/src/transport_layer/packet_dump.h b/src/transport_layer/packet_dump.h index c722246d..a3b4eb9d 100644 --- a/src/transport_layer/packet_dump.h +++ b/src/transport_layer/packet_dump.h @@ -1,3 +1,6 @@ +/* packet_dump — текстовая сводка IPv4-пакета: адреса, транспортные поля и короткий hex-фрагмент. + * Принимает IP-пакет без ETCP-заголовка. Результат в общем static-буфере перезаписывается каждым вызовом; + * его не освобождать, для хранения скопировать. Модуль не потокобезопасен и сам в лог не пишет. */ #ifndef PACKET_DUMP_H #define PACKET_DUMP_H diff --git a/src/transport_layer/pkt_normalizer.h b/src/transport_layer/pkt_normalizer.h index cdc071c2..f3ffbb6f 100644 --- a/src/transport_layer/pkt_normalizer.h +++ b/src/transport_layer/pkt_normalizer.h @@ -1,4 +1,8 @@ -// pkt_normalizer.h (упрощенная версия) +/* pkt_normalizer — упаковка кодограмм сервисов в надёжный байтовый поток ETCP и обратная сборка. + * input принимает целые кодограммы, packer добавляет длину и делит поток под MTU; + * unpacker читает etcp->output_queue и выдаёт целые кодограммы в output/etcp_int_recv. + * Содержимое cmd сервисов непрозрачно для normalizer. Контекст принадлежит ETCP_CONN, + * владеет своими очередями/частичными буферами/ожиданием backpressure; все вызовы — uasync. */ #ifndef PKT_NORMALIZER_H #define PKT_NORMALIZER_H @@ -11,14 +15,7 @@ extern "C" { #include "../lib/u_async.h" #include -/* -формат кодограмм: -cmd = 0 - пакет для передачи адресату (далее содержимое пакета) -cmd = 1 - элемент роутинг-таблицы (далее один маршрут) -cmd = 2 - запрос роутинг-таблицы (без данных) - - -*/ +/* Формат входной кодограммы: [cmd:1][данные сервиса...]; максимальная длина — PKTNORM_MAX_DGRAM_SIZE. */ #define PKTNORM_MAX_DGRAM_SIZE 16384 @@ -78,4 +75,4 @@ void pn_unpacker_reset_state(struct PKTNORM* pn); #ifdef __cplusplus } #endif -#endif // PKT_NORMALIZER_H \ No newline at end of file +#endif // PKT_NORMALIZER_H diff --git a/src/transport_layer/secure_channel.h b/src/transport_layer/secure_channel.h index 9ded9a62..b359dc69 100644 --- a/src/transport_layer/secure_channel.h +++ b/src/transport_layer/secure_channel.h @@ -1,4 +1,9 @@ -// secure_channel.h +/* secure_channel — криптографические операции транспорта, без сокетов и сетевого handshake. + * Инициализировать локальные X25519-ключи → init_ctx → set_peer_public_key → encrypt/decrypt. + * ctx заимствует SC_MYKEYS до конца использования; состояние счётчиков и stream-объекты имеют одного владельца. + * Пакеты: AES-128-CCM над plaintext+CRC32; выход = nonce(13)+ciphertext+tag(16). + * Отдельные API дают обфускацию ключа, потоковый AES-CTR и Ed25519; CTR сам по себе не аутентифицирует данные. + * Возврат SC_OK / отрицательный SC_ERR_*; caller владеет входными/выходными буферами. */ #ifndef SECURE_CHANNEL_H #define SECURE_CHANNEL_H @@ -66,7 +71,9 @@ sc_status_t sc_init_local_keys(struct SC_MYKEYS *mykeys, const char *public_key, sc_status_t sc_set_peer_public_key(sc_context_t *ctx, const uint8_t *peer_public_key, int mode);// mode: 0-bin 1-hex key format sc_status_t sc_compute_public_key_from_private(const uint8_t *private_key, uint8_t *public_key); -// Криптографические операции +/* Выходные длины только заполняются, не задают capacity! Для encrypt выделить plaintext_len+33 байта, + * для decrypt — ciphertext_len-33. Пустой plaintext запрещён; decrypt проверяет CCM tag и CRC. + * Проверка повторного посещения/эпохи транспорта находится выше этого модуля. */ sc_status_t sc_encrypt(sc_context_t *ctx, const uint8_t *plaintext, size_t plaintext_len, uint8_t *ciphertext, size_t *ciphertext_len); sc_status_t sc_decrypt(sc_context_t *ctx, const uint8_t *ciphertext, size_t ciphertext_len, uint8_t *plaintext, size_t *plaintext_len); diff --git a/src/transport_layer/socket_monitor.h b/src/transport_layer/socket_monitor.h index 3ee18f36..cb357566 100644 --- a/src/transport_layer/socket_monitor.h +++ b/src/transport_layer/socket_monitor.h @@ -1,3 +1,7 @@ +/* socket_monitor — наблюдение за адресами интерфейсов и маршрутами ОС для ETCP-сокетов. + * init подключает уведомления ОС к uasync экземпляра; изменения обновляют interface_addr и сетевое состояние. + * auto_socket отдельно создаёт/удаляет сокеты. destroy отключает наблюдение до освобождения экземпляра. + * Публичные операции и изменения ETCP_SOCKET — в потоке uasync. */ #ifndef SOCKET_MONITOR_H #define SOCKET_MONITOR_H diff --git a/src/transport_layer/stcp.h b/src/transport_layer/stcp.h index 40ff8de0..f9307b96 100644 --- a/src/transport_layer/stcp.h +++ b/src/transport_layer/stcp.h @@ -1,4 +1,8 @@ -// stcp.h — Streaming TCP: shared structures, constants, connection lifecycle +/* stcp — зашифрованное фреймирование поверх TCP: handshake ключей/эпох, AES-CTR поток и CRC кадров. + * Этот заголовок — внутренние структуры и I/O; создание исходящих/входящих соединений — client/server, + * интеграция с ETCP_LINK — stcp_link.h. Все операции одного соединения выполняются в uasync-потоке. + * do_close закрывает I/O и вызывает on_close; окончательное освобождение зависит от владельца conn. + * recv_on_chunk получает заимствованный буфер только на время callback; rx_queue получает отдельную копию. */ #ifndef STCP_H #define STCP_H @@ -163,12 +167,12 @@ int stcp_frame_decrypt(uint8_t *data, size_t len, struct sc_stream_state *strea void stcp_pending_queue(struct stcp_conn *c, const uint8_t *data, size_t len); void stcp_pending_clear(struct stcp_conn *c); -// takes ownership of data (must be u_malloc'd, will be u_free'd) +// data из u_malloc: 0 — отправлен и освобождён, 1 — принят для досылки; -1 оставляет data вызывающему. int stcp_try_send(struct stcp_conn *c, uint8_t *data, size_t len); void stcp_write_cb(socket_t sock, void *arg); void stcp_flush_pending(struct stcp_conn *c); -// unified recv: read from TCP, grow recv_buf, calls stcp_recv_try. returns 1=data, 0=wait, -1=error/closed +// Читает TCP в recv_buf: 1 — новые байты, 0 — ждать, -1 — ошибка/закрыто. Разбор через stcp_recv_try вызывает владелец. int stcp_conn_read(struct stcp_conn *c); // set next expected chunk: need=0+streaming=1 enters DATA stream mode diff --git a/src/transport_layer/stcp_client.h b/src/transport_layer/stcp_client.h index ef84638b..25078307 100644 --- a/src/transport_layer/stcp_client.h +++ b/src/transport_layer/stcp_client.h @@ -1,4 +1,7 @@ -// stcp_client.h — STCP client: connect, handshake +/* stcp_client — асинхронные TCP connect и STCP-handshake, с опциональными SOCKS5 и REALITY. + * connect возвращает владеющий handle или NULL; готовность DATA сообщает ready_cb, закрытие — close_cb. + * get_conn заимствует conn из handle. destroy отменяет подключение/закрывает conn и делает handle недействительным. + * Все API/callbacks — uasync-поток; TCP-ping использует отдельный короткий handshake и не создаёт ETCP-сессию. */ #ifndef STCP_CLIENT_H #define STCP_CLIENT_H diff --git a/src/transport_layer/stcp_link.h b/src/transport_layer/stcp_link.h index 3ca8acef..35dd5ae3 100644 --- a/src/transport_layer/stcp_link.h +++ b/src/transport_layer/stcp_link.h @@ -1,4 +1,8 @@ -// stcp_link.h — STCP link management (TCP connection via STCP protocol) +/* stcp_link — адаптер STCP-соединения к ETCP_LINK: handshake, очереди DATA, ready/close callbacks. + * Серверный путь создаёт входящие линки, connect запускает исходящий для заданного ETCP_LINK. + * send копирует data в tx_queue (0 / -1); ready означает готовность STCP, не READY topo-группы. + * close гасит callback внезапного разрыва и откладывает teardown; после close handle не использовать. + * API и callbacks — uasync-поток. Указатели get_* заимствованы; адреса peer/local используют static-буферы. */ #ifndef STCP_LINK_H #define STCP_LINK_H diff --git a/src/transport_layer/stcp_server.h b/src/transport_layer/stcp_server.h index d9371f90..51f104d6 100644 --- a/src/transport_layer/stcp_server.h +++ b/src/transport_layer/stcp_server.h @@ -1,4 +1,7 @@ -// stcp_server.h — STCP server: listen, accept, handshake +/* stcp_server — TCP listener и входящий STCP-handshake для одного UTUN_INSTANCE. + * create → connect_cb для готовых conn → destroy; сервер владеет listener и списком принятых соединений. + * destroy закрывает также принятые conn и вызывает их close callbacks; все операции — uasync-поток. + * set_reality включает TLS-камуфляж и relay неавторизованных клиентов; результат conn callback заимствован. */ #ifndef STCP_SERVER_H #define STCP_SERVER_H diff --git a/src/tun_if.h b/src/tun_if.h index 21d26277..49d5ea63 100644 --- a/src/tun_if.h +++ b/src/tun_if.h @@ -1,4 +1,8 @@ -// tun_if.h - Cross-platform TUN interface management for utun +/* Кроссплатформенный TUN: init создаёт интерфейс и очереди, close освобождает их. + * output_queue несёт TUN → ядро, input_queue — ядро → TUN; формат очереди: префикс(1) + IP-пакет. + * tun_write принимает тот же префикс и пропускает его при записи; tun_inject_packet принимает чистый IP. + * Основной API — в uasync; Windows read-thread передаёт пакеты через tun_packet_handler. + * test_mode использует очереди вместо устройства ОС. */ #ifndef TUN_IF_H #define TUN_IF_H diff --git a/tools/chatgui-android/AGENTS.md b/tools/chatgui-android/AGENTS.md index 3fc0575a..3e854d3e 100644 --- a/tools/chatgui-android/AGENTS.md +++ b/tools/chatgui-android/AGENTS.md @@ -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 diff --git a/tools/chatgui-android/headless/headless_control.h b/tools/chatgui-android/headless/headless_control.h index 33472bc4..d9ef0d96 100644 --- a/tools/chatgui-android/headless/headless_control.h +++ b/tools/chatgui-android/headless/headless_control.h @@ -1,32 +1,9 @@ -/* - * headless_control.h — JSON control socket for uTun headless mode - * - * JSON line protocol: - * Request: {"id":N,"cmd":"",...params} - * Response: {"id":N,"ok":true,"data":{...}} | {"id":N,"ok":false,"error":"..."} - * Event: {"event":"",...} - * - * 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 diff --git a/tools/chatgui-android/jni_bridge/android_jni_bridge.h b/tools/chatgui-android/jni_bridge/android_jni_bridge.h index 18c8fca2..7e2faf20 100644 --- a/tools/chatgui-android/jni_bridge/android_jni_bridge.h +++ b/tools/chatgui-android/jni_bridge/android_jni_bridge.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, diff --git a/tools/chatgui-android/libutun_lite/attachment_sender.h b/tools/chatgui-android/libutun_lite/attachment_sender.h index c58b032a..1447f5dc 100644 --- a/tools/chatgui-android/libutun_lite/attachment_sender.h +++ b/tools/chatgui-android/libutun_lite/attachment_sender.h @@ -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 diff --git a/tools/chatgui-android/libutun_lite/instance_lite.h b/tools/chatgui-android/libutun_lite/instance_lite.h index 826e8812..e6aee213 100644 --- a/tools/chatgui-android/libutun_lite/instance_lite.h +++ b/tools/chatgui-android/libutun_lite/instance_lite.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] секции diff --git a/tools/chatgui-android/libutun_lite/invite_link_c.h b/tools/chatgui-android/libutun_lite/invite_link_c.h index f5c3b879..2e58b0ba 100644 --- a/tools/chatgui-android/libutun_lite/invite_link_c.h +++ b/tools/chatgui-android/libutun_lite/invite_link_c.h @@ -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); diff --git a/tools/chatgui-android/libutun_lite/photo_sender.h b/tools/chatgui-android/libutun_lite/photo_sender.h index a5f6e9db..7bb84c9f 100644 --- a/tools/chatgui-android/libutun_lite/photo_sender.h +++ b/tools/chatgui-android/libutun_lite/photo_sender.h @@ -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 diff --git a/tools/chatgui-android/libutun_lite/utun_config_api.h b/tools/chatgui-android/libutun_lite/utun_config_api.h index e8482e36..2d9f8f9e 100644 --- a/tools/chatgui-android/libutun_lite/utun_config_api.h +++ b/tools/chatgui-android/libutun_lite/utun_config_api.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 diff --git a/tools/chatgui-android/libutun_lite/video_sender.h b/tools/chatgui-android/libutun_lite/video_sender.h index e34d0cba..0a4543f9 100644 --- a/tools/chatgui-android/libutun_lite/video_sender.h +++ b/tools/chatgui-android/libutun_lite/video_sender.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 diff --git a/tools/chatgui-android/libutun_lite/voice_recorder.h b/tools/chatgui-android/libutun_lite/voice_recorder.h index 1416e7a3..157e1982 100644 --- a/tools/chatgui-android/libutun_lite/voice_recorder.h +++ b/tools/chatgui-android/libutun_lite/voice_recorder.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 diff --git a/tools/chatgui/db/db_manager.h b/tools/chatgui/db/db_manager.h index 8dd71a00..230326dc 100644 --- a/tools/chatgui/db/db_manager.h +++ b/tools/chatgui/db/db_manager.h @@ -1,3 +1,7 @@ +/* SQLite-представление данных для desktop UI: каналы/сообщения/узлы, локальные имена и диагностика БД. + * setDb заимствует handle ядра, destructor закрывает свои statement-курсоры, но не SQLite. + * Перед уничтожением БД закрыть курсоры и сбросить ссылку. Сетевые и подписанные изменения идут через chat_core; + * методы чтения возвращают самостоятельные Qt-значения. */ #ifndef DB_MANAGER_H #define DB_MANAGER_H @@ -120,7 +124,7 @@ public: QList getAccounts(bool contactsOnly = false) const; AccountRow getAccount(quint64 nodeId) const; - /* ── UI state (read-only используем QSettings, оставлен для совместимости) ── */ + /* ── Чтение UI state из SQLite ── */ QString getUiState(const QString& key) const; int getUiStateInt(const QString& key, int defaultVal) const; diff --git a/tools/chatgui/src/accountdelegate.h b/tools/chatgui/src/accountdelegate.h index 9263852d..06a84a3b 100644 --- a/tools/chatgui/src/accountdelegate.h +++ b/tools/chatgui/src/accountdelegate.h @@ -1,3 +1,4 @@ +/* Отрисовка строки участника AccountList: аватар, имя, online и служебные значки. */ #pragma once #include diff --git a/tools/chatgui/src/accountlist.h b/tools/chatgui/src/accountlist.h index b5ac2465..268c3ebd 100644 --- a/tools/chatgui/src/accountlist.h +++ b/tools/chatgui/src/accountlist.h @@ -1,3 +1,5 @@ +/* Панель участников выбранного канала и live-диагностика выбранного узла. + * Получает события bridge в GUI-потоке; запросы звонка и PM отдаёт через signals. */ #pragma once #include diff --git a/tools/chatgui/src/animtimer.h b/tools/chatgui/src/animtimer.h index f0eea177..ce6ef822 100644 --- a/tools/chatgui/src/animtimer.h +++ b/tools/chatgui/src/animtimer.h @@ -1,3 +1,5 @@ +/* Общий GUI-таймер анимированных emoji: регистрирует LottieIcon и выдаёт ticked. + * play запускает минимум PlaybackMs; shutdown останавливает таймер и очищает регистрацию. */ #pragma once #include diff --git a/tools/chatgui/src/audiodevicesettingspage.h b/tools/chatgui/src/audiodevicesettingspage.h index 89294751..9ba0a4db 100644 --- a/tools/chatgui/src/audiodevicesettingspage.h +++ b/tools/chatgui/src/audiodevicesettingspage.h @@ -1,3 +1,5 @@ +/* Настройки capture/playback, Opus, компрессора, AEC и рации; тест микрофона и динамика. + * loadFromDb заполняет форму, applyAndSave применяет выбранные значения. */ #pragma once #include #include diff --git a/tools/chatgui/src/audiorecorder.h b/tools/chatgui/src/audiorecorder.h index b6ea30fe..992b0136 100644 --- a/tools/chatgui/src/audiorecorder.h +++ b/tools/chatgui/src/audiorecorder.h @@ -1,3 +1,6 @@ +/* Запись голосового сообщения: capture 48 kHz mono → очередь → worker PCM/компрессора. + * GUI управляет init/start/stop/shutdown; meterOnly измеряет уровень без накопления записи. + * takeRecording передаёт остановленные PCM/компрессор в attachment_send_req для фоновой подготовки. */ #pragma once #include diff --git a/tools/chatgui/src/channeldelegate.h b/tools/chatgui/src/channeldelegate.h index f4a1531f..05b3dfe3 100644 --- a/tools/chatgui/src/channeldelegate.h +++ b/tools/chatgui/src/channeldelegate.h @@ -1,3 +1,4 @@ +/* Роли модели и отрисовка ChannelList: канал/PM, последнее сообщение, unread и кнопки действий. */ #pragma once #include diff --git a/tools/chatgui/src/channellist.h b/tools/chatgui/src/channellist.h index efa832bd..764de1ba 100644 --- a/tools/chatgui/src/channellist.h +++ b/tools/chatgui/src/channellist.h @@ -1,3 +1,5 @@ +/* Список каналов и PM с unread/online; загружает данные DbManager и принимает обновления bridge. + * Выбор и действия пользователя передаёт наружу signals; виджет используется в GUI-потоке. */ #pragma once #include diff --git a/tools/chatgui/src/channelsettingsdialog.h b/tools/chatgui/src/channelsettingsdialog.h index 9328de7d..df09fe10 100644 --- a/tools/chatgui/src/channelsettingsdialog.h +++ b/tools/chatgui/src/channelsettingsdialog.h @@ -1,3 +1,4 @@ +/* Локальные настройки выбранного канала: autoplay голосовых, звук сообщений и режим PTT. */ #pragma once #include diff --git a/tools/chatgui/src/chatview.h b/tools/chatgui/src/chatview.h index f96d9cec..2490e75c 100644 --- a/tools/chatgui/src/chatview.h +++ b/tools/chatgui/src/chatview.h @@ -1,3 +1,5 @@ +/* Вид истории сообщений: фон, выделение строк/текста, копирование и прокрутка вниз. + * MessageDelegate рисует содержимое; ChatView обрабатывает мышь и клавиатуру. */ #pragma once #include diff --git a/tools/chatgui/src/creategroupdialog.h b/tools/chatgui/src/creategroupdialog.h index f947d05a..1f112763 100644 --- a/tools/chatgui/src/creategroupdialog.h +++ b/tools/chatgui/src/creategroupdialog.h @@ -1,3 +1,4 @@ +/* Диалог ввода имени нового канала. groupName возвращает имя для создания канала вызывающим кодом. */ #pragma once #include diff --git a/tools/chatgui/src/debug_ui.h b/tools/chatgui/src/debug_ui.h index 153f7201..ae0a0a6c 100644 --- a/tools/chatgui/src/debug_ui.h +++ b/tools/chatgui/src/debug_ui.h @@ -1,3 +1,4 @@ +/* Макросы логирования GUI через общий debug_config, категория GENERAL. */ #pragma once extern "C" { diff --git a/tools/chatgui/src/emoji.h b/tools/chatgui/src/emoji.h index 046e71ef..c63ecf02 100644 --- a/tools/chatgui/src/emoji.h +++ b/tools/chatgui/src/emoji.h @@ -1,3 +1,5 @@ +/* Каталог Unicode/анимированных emoji и соответствие Unicode → ресурс анимации. + * detectEmojiOnly возвращает 1..3 для текста только из emoji/пробелов; иначе 0. */ #pragma once #include diff --git a/tools/chatgui/src/emojipanel.h b/tools/chatgui/src/emojipanel.h index 2a4a0351..7f39d324 100644 --- a/tools/chatgui/src/emojipanel.h +++ b/tools/chatgui/src/emojipanel.h @@ -1,3 +1,4 @@ +/* Панель выбора emoji по категориям; выбранный Unicode передаётся в composer через emojiSelected. */ #pragma once #include diff --git a/tools/chatgui/src/emojitabbar.h b/tools/chatgui/src/emojitabbar.h index 7489447f..353fdfce 100644 --- a/tools/chatgui/src/emojitabbar.h +++ b/tools/chatgui/src/emojitabbar.h @@ -1,3 +1,4 @@ +/* Отрисовка вкладок категорий EmojiPanel с собственным стилем выбранной вкладки. */ #pragma once #include diff --git a/tools/chatgui/src/flagpainter.h b/tools/chatgui/src/flagpainter.h index afb14cf5..d2c28c34 100644 --- a/tools/chatgui/src/flagpainter.h +++ b/tools/chatgui/src/flagpainter.h @@ -1,3 +1,4 @@ +/* Отрисовка флагов участника (supernode/admin/moder/deleted) и отдельного значка storage. */ #ifndef FLAGPAINTER_H #define FLAGPAINTER_H diff --git a/tools/chatgui/src/imageviewer_window.h b/tools/chatgui/src/imageviewer_window.h index 48101f99..a2f22322 100644 --- a/tools/chatgui/src/imageviewer_window.h +++ b/tools/chatgui/src/imageviewer_window.h @@ -1,3 +1,5 @@ +/* Окно просмотра локального изображения: масштаб колесом, перенос мышью и fullscreen. + * loadFile загружает изображение; closed сообщает владельцу о закрытии окна. */ #pragma once #include diff --git a/tools/chatgui/src/inputbar.h b/tools/chatgui/src/inputbar.h index 7abe87a0..86e9f684 100644 --- a/tools/chatgui/src/inputbar.h +++ b/tools/chatgui/src/inputbar.h @@ -1,3 +1,6 @@ +/* Composer канала/PM: текст, emoji, запись голосового и выбор вложений. + * Контекст target фиксируется в запросе вложения; подготовку и отправку выполняет ядро. + * Переданный submitAttachment request должен принять и освободить обработчик сигнала. */ #pragma once #include diff --git a/tools/chatgui/src/invite_link.h b/tools/chatgui/src/invite_link.h index 17e21243..b9b808e9 100644 --- a/tools/chatgui/src/invite_link.h +++ b/tools/chatgui/src/invite_link.h @@ -1,3 +1,5 @@ +/* Qt-кодек utun://: channelId/joinKey, пароль, Reality и адреса connection-узла. + * decodeInviteLink возвращает ошибку в InviteData.error; подключения выполняет UtunNode/chat_sync. */ #pragma once #include diff --git a/tools/chatgui/src/inviteby.h b/tools/chatgui/src/inviteby.h index c8b68e2d..887d0514 100644 --- a/tools/chatgui/src/inviteby.h +++ b/tools/chatgui/src/inviteby.h @@ -1,3 +1,4 @@ +/* Диалог приглашения узла по его utun:// ссылке в текущий канал; ждёт результата ядра через bridge. */ #pragma once #include diff --git a/tools/chatgui/src/invitedialog.h b/tools/chatgui/src/invitedialog.h index aa12bcbf..4c6921f9 100644 --- a/tools/chatgui/src/invitedialog.h +++ b/tools/chatgui/src/invitedialog.h @@ -1,3 +1,5 @@ +/* Диалог выдачи invite-ссылки и QR: запрашивает кандидатов и зарегистрированную ссылку у ядра. + * requestId связывает асинхронный ответ с текущим запросом; URL отображается после LINK_READY. */ #pragma once #include diff --git a/tools/chatgui/src/joindialog.h b/tools/chatgui/src/joindialog.h index 4fba54a1..8dc88ed3 100644 --- a/tools/chatgui/src/joindialog.h +++ b/tools/chatgui/src/joindialog.h @@ -1,3 +1,5 @@ +/* Диалог входа в канал по utun://: проверяет ссылку, отправляет запрос ядру и ждёт CONNECT_RESULT. + * joined сообщает об успешном входе, а не только о создании транспорта к connection-узлу. */ #pragma once #include diff --git a/tools/chatgui/src/lottieicon.h b/tools/chatgui/src/lottieicon.h index a167741f..5be28979 100644 --- a/tools/chatgui/src/lottieicon.h +++ b/tools/chatgui/src/lottieicon.h @@ -1,3 +1,5 @@ +/* Обёртка rlottie для TGS: распаковывает анимацию, хранит текущий кадр и рисует QImage. + * Воспроизведение координирует AnimTimer; объект освобождает свой animation handle. */ #pragma once #include diff --git a/tools/chatgui/src/mainwindow.h b/tools/chatgui/src/mainwindow.h index e890418c..2a908134 100644 --- a/tools/chatgui/src/mainwindow.h +++ b/tools/chatgui/src/mainwindow.h @@ -1,3 +1,5 @@ +/* Главное окно desktop-чата: связывает списки, bridge-события, UtunNode, media и звонки. + * Координирует запуск/остановку ядра, tray и отдельные окна; UI-обработчики работают в GUI-потоке. */ #pragma once #include diff --git a/tools/chatgui/src/media_blocks.h b/tools/chatgui/src/media_blocks.h index 168ec776..752baf52 100644 --- a/tools/chatgui/src/media_blocks.h +++ b/tools/chatgui/src/media_blocks.h @@ -1,3 +1,6 @@ +/* Локальное чтение медиа из целого файла или набора блоков по localAttrs. + * readRange/readAll читают доступные данные; assembleAndCleanup собирает файл и удаляет фрагменты. + * media_split_to_blocks по умолчанию удаляет исходник после разбиения; сетевую загрузку модуль не выполняет. */ #pragma once #include diff --git a/tools/chatgui/src/memberlistmodel.h b/tools/chatgui/src/memberlistmodel.h index 6f2f8266..b0901df8 100644 --- a/tools/chatgui/src/memberlistmodel.h +++ b/tools/chatgui/src/memberlistmodel.h @@ -1,3 +1,5 @@ +/* Qt-модель участников канала: ленивый кэш строк, обновления CHAT_EVT_MEMBER_* и RTT. + * События bridge применяются в GUI-потоке; данные строки доступны через Qt roles. */ #ifndef MEMBERLISTMODEL_H #define MEMBERLISTMODEL_H diff --git a/tools/chatgui/src/memberpropsdialog.h b/tools/chatgui/src/memberpropsdialog.h index 244261fd..31b00de0 100644 --- a/tools/chatgui/src/memberpropsdialog.h +++ b/tools/chatgui/src/memberpropsdialog.h @@ -1,3 +1,4 @@ +/* Диалог имени и прав участника канала; сохранение подписанных изменений и передача admin-ключа через ядро. */ #pragma once #include diff --git a/tools/chatgui/src/messagedelegate.h b/tools/chatgui/src/messagedelegate.h index db8c8981..85be5b79 100644 --- a/tools/chatgui/src/messagedelegate.h +++ b/tools/chatgui/src/messagedelegate.h @@ -1,3 +1,5 @@ +/* Роли модели сообщений и отрисовка text/voice/file/image/video, статусов и progress. + * Рассчитывает геометрию для ChatView и обрабатывает действия по media-элементам строки. */ #pragma once #include diff --git a/tools/chatgui/src/messagelist.h b/tools/chatgui/src/messagelist.h index 78b74661..136d9960 100644 --- a/tools/chatgui/src/messagelist.h +++ b/tools/chatgui/src/messagelist.h @@ -1,3 +1,5 @@ +/* История и composer выбранного канала/PM: модель сообщений, позиция чтения, загрузки и воспроизведение. + * Применяет события bridge в GUI-потоке; сетевые операции передаёт ядру. */ #pragma once #include diff --git a/tools/chatgui/src/qrcode_utils.h b/tools/chatgui/src/qrcode_utils.h index bff756e1..2d70db87 100644 --- a/tools/chatgui/src/qrcode_utils.h +++ b/tools/chatgui/src/qrcode_utils.h @@ -1,3 +1,4 @@ +/* Генерация QR и распознавание штрихкодов из QImage через ZXingQt. Ошибка генерации — пустой QImage. */ #pragma once #include diff --git a/tools/chatgui/src/renamedialog.h b/tools/chatgui/src/renamedialog.h index c00fd556..87eee228 100644 --- a/tools/chatgui/src/renamedialog.h +++ b/tools/chatgui/src/renamedialog.h @@ -1,3 +1,4 @@ +/* Локальное переименование участника: сохраняет local_nick в таблице peers канала для этого UI. */ #pragma once #include diff --git a/tools/chatgui/src/sound_manager.h b/tools/chatgui/src/sound_manager.h index 6bf162ac..f26975eb 100644 --- a/tools/chatgui/src/sound_manager.h +++ b/tools/chatgui/src/sound_manager.h @@ -1,3 +1,6 @@ +/* Общий miniaudio-контекст и выход desktop-приложения: звуки событий, PCM и голосовые потоки. + * GUI управляет устройствами и playback-сессиями; output смешивает звук и отдаёт reference для AEC. + * init/shutdown ограничивают время жизни контекста; зависимые capture devices закрываются перед его сбросом. */ #pragma once #include diff --git a/tools/chatgui/src/soundsettingspage.h b/tools/chatgui/src/soundsettingspage.h index 450c92bc..eef6f29f 100644 --- a/tools/chatgui/src/soundsettingspage.h +++ b/tools/chatgui/src/soundsettingspage.h @@ -1,3 +1,4 @@ +/* Форма звуков уведомлений: общий enable/volume и индивидуальные настройки событий SoundManager. */ #pragma once #include diff --git a/tools/chatgui/src/storagesettingspage.h b/tools/chatgui/src/storagesettingspage.h index fc07d81f..f37966cf 100644 --- a/tools/chatgui/src/storagesettingspage.h +++ b/tools/chatgui/src/storagesettingspage.h @@ -1,3 +1,5 @@ +/* Настройки media-хранилища: автозагрузка, лимит файла и общий размер. + * applyAndSave сохраняет значения и передаёт их chat_setting через uasync. */ #pragma once #include diff --git a/tools/chatgui/src/voicemessageencoder.h b/tools/chatgui/src/voicemessageencoder.h index 2290f28e..b1b682f6 100644 --- a/tools/chatgui/src/voicemessageencoder.h +++ b/tools/chatgui/src/voicemessageencoder.h @@ -1,3 +1,5 @@ +/* GUI-настройка preset голосовых (0 Low, 1 Standard, 2 High) и создание media-каталога. + * Кодирование PCM в Opus выполняет общий voice_file через attachment_send. */ #pragma once #include diff --git a/tools/chatgui/src/voiceplayback.h b/tools/chatgui/src/voiceplayback.h index 7ddcd1f9..efb22e20 100644 --- a/tools/chatgui/src/voiceplayback.h +++ b/tools/chatgui/src/voiceplayback.h @@ -1,3 +1,7 @@ +/* Воспроизведение собственного Opus-файла voice_file: worker декодирует PCM, SoundManager проигрывает. + * Управление — в GUI-потоке; ready(duration,id) вызывается там же, 0 означает ошибку/busy. + * cancelPending подавляет результат, не останавливая worker; уничтожение context также подавляет callback. + * decodeOpusFile синхронно возвращает число кадров или -1; это отдельный API для worker. */ #pragma once #include diff --git a/tools/chatgui/transport/gui_bridge.h b/tools/chatgui/transport/gui_bridge.h index c73bdb33..884203a3 100644 --- a/tools/chatgui/transport/gui_bridge.h +++ b/tools/chatgui/transport/gui_bridge.h @@ -1,3 +1,7 @@ +/* Мост desktop GUI ↔ ядро: post копирует бинарное событие в Qt-очередь, callbacks работают в GUI. + * post_uasync_fn передаёт функцию и arg без копирования в сетевой поток; arg освобождает обработчик. + * Регистрация callbacks и UI-состояние принадлежат GUI. Полученный inst заимствован; + * чтение указателя не гарантирует время жизни объекта при stop/finalize. */ #ifndef GUI_BRIDGE_H #define GUI_BRIDGE_H @@ -71,13 +75,14 @@ void gui_bridge_set_uasync(struct UASYNC* ua); Читается GUI-потоком через gui_bridge_get_inst() для сборки trampoline-аргументов. */ void gui_bridge_set_inst(struct UTUN_INSTANCE* inst); -/* Текущий UTUN_INSTANCE (NULL пока не создан). Безопасно из любого потока. */ +/* Текущий заимствованный UTUN_INSTANCE (NULL пока не создан/после сброса моста). */ struct UTUN_INSTANCE* gui_bridge_get_inst(void); /* uasync → GUI: уведомление (fire-and-forget, через Qt::QueuedConnection) */ void gui_bridge_post(int event_type, const uint8_t* data, int data_len); -/* GUI → uasync: выполнить функцию в uasync-потоке */ +/* GUI → uasync: передать fn(arg). Проверить готовность заранее: без ua запрос отбрасывается, + * функция не вызывается и arg не освобождается мостом. */ void gui_bridge_post_uasync_fn(void (*fn)(void*), void* arg); /* Проверить готовность uasync (g_ua != NULL) */ diff --git a/tools/chatgui/transport/node_config.h b/tools/chatgui/transport/node_config.h index 2e58d932..7cef90ee 100644 --- a/tools/chatgui/transport/node_config.h +++ b/tools/chatgui/transport/node_config.h @@ -1,4 +1,6 @@ -// node_config.h — Simplified INI config manager for embedded uTun node +/* Desktop INI-конфиг узла: идентичность, listen/client-секции, control и GUI-настройки. + * load читает и проверяет значения; create генерирует конфиг/ключи; save обновляет известные поля + * существующего файла, saveFull перезаписывает файл из модели. Запуск ядра выполняет UtunNode. */ #ifndef NODE_CONFIG_H #define NODE_CONFIG_H diff --git a/tools/chatgui/transport/utun_node.h b/tools/chatgui/transport/utun_node.h index b3080405..8ad72fec 100644 --- a/tools/chatgui/transport/utun_node.h +++ b/tools/chatgui/transport/utun_node.h @@ -1,4 +1,8 @@ -// utun_node.h — C++ wrapper for embedded uTun node (runs in dedicated thread) +/* Desktop-владелец встроенного ядра: читает INI, создаёт uasync и запускает core/chat в std::thread. + * requestStop сигнализирует завершение, stop ждёт поток; worker уничтожает instance, + * finalize после завершения worker освобождает uasync и сбрасывает ссылку GUI-моста. + * instance возвращает заимствованный указатель: операции ядра отправлять в uasync через gui_bridge, + * согласовав время жизни с остановкой/перезапуском узла. */ #ifndef UTUN_NODE_H #define UTUN_NODE_H