Commit Graph
35 Commits
Author SHA1 Message Date
evgeny 0ee1163a0b Bind Android media queues to core lifetime and source epochs 2026-10-12 01:50:07 +02:00
evgeny 653853588a logging: preserve system diagnostics and inherit Android debug level 2026-10-07 21:21:33 +02:00
evgeny 123b47c612 Improve Android VAD lifecycle, audio settings and diagnostics 2026-10-04 14:36:52 +02:00
evgeny bdcf8b5634 Сохрани накопленные исправления аудио, async и диагностики 2026-10-02 01:49:32 +03:00
evgeny 72fee9e245 Separate core, UTUN and chat lifecycles with owned asynchronous work 2026-09-28 11:39:08 +03:00
evgeny 2f3001458f android: standby keepalive sync + rx logging during sleep 2026-09-21 21:17:35 +03:00
evgeny 9793733cd5 chatgui: диагностика воспроизведения голосовых сообщений (Windows)
- sound_manager: ma_engine_init/playRawPcm логируют через DEBUG_* (qWarning/qDebug терялись в GUI-приложении без консоли); детальный результат старта PCM (rc/is_playing/cursor)
- main: ранняя инициализация лога в GUI-потоке до SoundManager::init, чтобы диагностика инициализации попала в файл
- messagedelegate: лог клика по Play/timeline (filePath/dlState/существует ли файл)
- voiceplayback: лог заголовка opus (sr/ch/frameSamples)

Попутные правки:
- u_async: фикс двойного close wakeup_pipe (eventfd/Windows)
- chat_core: NULL-guard в get_db/is_initialized
- android: sqlite открывается в utun_instance_init, cleanup stale-потока без утечки fd
- android SettingsScreen: компактная раскладка имени интерфейса
2026-09-21 18:59:04 +03:00
evgeny 01987a75d0 chatgui: verify FFmpeg DLL deployment + fix dependency resolution order 2026-09-21 11:52:21 +03:00
evgeny 73fe99b33f dm: прямой обмен сообщениями (DM) + soundtouch + архитектура звонков
- src/dm/: dm_core/dm_crypto/dm_mailbox — прямой обмен сообщениями (DM)
- lib/soundtouch-master/: vendored SoundTouch (изменение темпа/высоты аудио)
- doc/dm_arch.md, doc/chat_call_arch.md: архитектура DM и звонков
- tests: test_dm.c, test_dm_e2e.c
- chat: рефакторинг chat_* модулей, member_sync, invite_build
- chatgui/chatgui-android: синхронизация с новым API чата
- lib/u_async, debug_config, utun_instance: сопутствующие изменения
2026-09-15 21:09:17 +03:00
evgeny 7c8d65db78 chat: локальное удаление канала (Android) + db_sync инстансы в куче 2026-09-13 22:08:33 +03:00
evgeny 6c9a47b201 media_delivery: диагностика маршрутизации md_send/md_dl_send/router_deliver (conn, subcmd, no-route) + тест test_media_delivery_chat 2026-09-11 23:48:31 +03:00
evgeny 5b31a765c2 chatgui-android: auto_sockets=android — сокеты из конфига, лёгкое обновление без полного рестарта
- auto_sockets три-режимный: off/system/android; android берёт сокеты из [server] конфига
- auto_socket_reload_config: reconcile сокетов (remove→create) по имени+addr:port, сохранение портов
- etcp_create_server_socket вынесен из init_sockets; stcp_server_list_find_by_sock
- instance_lite_update_sockets + JNI nativeUpdateSockets + NativeLib.updateSockets
- NetworkChangeMonitor: updateSockets вместо restart; порты сохраняются при смене сети
2026-09-09 17:34:46 +03:00
evgeny 7dee49ce63 android: мониторинг смены сети — NetworkChangeMonitor, перезапуск ядра при смене интерфейса 2026-08-17 21:03:05 +03:00
evgeny b203a48063 android: standby duty-cycle в фоне — defer ping/reconnect/probe через standby_wait
standby.h/c: duty-cycle ACTIVE/SLEEP, standby_wait() будит в burst сразу,
в SLEEP — до следующего burst; notify_network_activity для раннего пробуждения.
Интеграция (по флагу UTUN_HAVE_STANDBY, десктоп без изменений):
- conn_mgr: bg_ping/candidate_ping в SLEEP defer через standby_wait
- route_connectivity: probe_node откладывается (PROBE_STATUS_DEFERRED)
- topo_group_connect: пауза между попытками — активный режим 1с, фон standby_wait
- jni_bridge/ConfigProvider/NetworkActivityMonitor: set_active + сетевая активность
- chat_setting: standby_active_sec/sleep_sec/min_sleep_sec
+ юнит-тест test_standby (31 проверок)
2026-08-14 12:28:56 +03:00
evgeny 54ad03185b topo_group_connect: infinite auto-connect cycle with pause + connecting nodes notification
- client_activity: desktop/server now ACTIVE by default, only mobile starts STANDBY
- topo_group_connect: endless Phase1→2→3→1 cycle until connected
- Pause between failed Phase2/3 attempts: 1s active, 30s standby
- on_down always triggers cycle_restart when active_conn_count=0
- re-init destroys previous state and starts fresh
- CHAT_EVT_CONNECTING_NODES event notifies GUI of current connecting nodes
- Android: ConfigProvider default mode='auto', PTT fix, UDP log timer fix
2026-08-12 18:05:44 +03:00
evgeny 5d02a6d419 android: debug categories from GUI, fix poll log format, event loop sleeps until traffic
- android_jni_bridge: utun_bridge_set_debug_level actually calls debug_set_level / debug_set_category_level_by_name (was stub)
- SettingsScreen: CATEGORIES updated to match current g_debug_categories from debug_config.c
- ConfigProvider: persist category levels in [debug] section of generated INI config
- u_async: poll() log uses computed timeout_ms instead of confusing %d.%dms format
- u_async: timeout_node char name[16] → const char* name (no truncation, smaller struct)
- memory_pool: pool alloc/free debug logs moved from DEBUG to TRACE
- instance_lite: poll timeout changed from 10ms (100tb) to infinite (-1) — sleeps until traffic
- instance_lite: removed useless heartbeat timer
2026-08-12 09:02:19 +03:00
evgeny 0f1bd3d120 keepalive handshake: device_type + keepalive negotiation in UDP/TCP INIT
- Добавлен device_type (1 байт, CLIENT_TYPE_*) в INIT_REQUEST и INIT_RESPONSE
- Добавлен keepalive_interval (2 байта) в INIT_RESPONSE
- STCP handshake расширен с 43 до 46 байт (device_type+keepalive)
- negotiate_keepalive(): оба desktop/server → min, иначе (есть mobile) → max
- keepalive_interval вынесен в UTUN_INSTANCE для использования в handshake
- stcp_client_connect() принимает device_type и keepalive_interval
- peer_device_type/peer_keepalive_interval передаются через stcp_link в ETCP_LINK
2026-08-11 11:16:27 +03:00
evgeny 7f901c01e1 etcp: переупорядочить close + защита state==2 во всех API-точках; topo: правильная очистка group nodes и registry; chat/member: новый модуль member_sync; chatgui: обновления транспорта и UI 2026-08-09 12:39:53 +03:00
evgeny b2e4aadbf0 e2e: AES-128-CCM encryption via BGP router (ROUTER_FLAG_ENCRYPTED), ECDH key per peer-pair from NODEINFO pubkeys, cache 8 entries
- etcp_router.h/c: new flag ROUTER_FLAG_ENCRYPTED (0x04), etcp_route_send_encrypted(), inflight/retrans/send_q support
- utun_instance.h: e2e_ctx_cache[8] — per-peer sc_context_t cache with derived session key
- topo_node.c: topo_node_sign_self() — single point for Ed25519 self-signing of NODEINFO
- topo_node.c: fix stale x25519_self_sig after address update (topo_node_sign_self call)
- nat_detection.c: fix stale x25519_self_sig after in-place socket meta modification
- test_etcp_router_unit: 5 E2E tests (basic round-trip, no NODEINFO drop, tampered, cache reuse, ENCRYPTED+SIGNED combined)
- builds clean, 70/70 tests pass
2026-08-09 08:19:20 +03:00
evgeny 38c9f229bc stcp: ed25519 pubkey exchange in handshake, fix instance destroy segfault, fix chat_tcp_test
- u_async.c: process immediate_queue BEFORE epoll_wait in uasync_poll
- stcp_link.c: defensive NULL etcp_conn/etcp_link in stcp_link_close
- utun_instance.c: move stcp_server_list_destroy_all to Phase J (before ETCP),
  add deferred drain in both Phase J and L
- stcp.h/c: STCP_HS_ENC_CLIENT 6→38, STCP_HS_ENC_SERVER 7→39,
  exchange ed25519_pubkey in both handshake directions
- etcp_connections.c: copy peer_ed25519 from STCP to ETCP_CONN in
  etcp_link_enter_ready_tcp; guard link->etcp in tcp_link_close_cb
- chat_sync.c: fix lk->conn NULL dereference for TCP links
- test_stcp.c: update stcp_server_create/stcp_client_connect callsites
- tools/chat_tcp_test: change transport udp→tcp
2026-08-07 00:48:27 +03:00
evgeny d773f1724a refactor: STCP connections as ETCP links (is_tcp)
- Add is_tcp, tcp_link, tcp_reconnect_* fields to ETCP_LINK
- Remove transport_link from ETCP_CONN, add tcp_link_count
- stcp_link: replace embedded etcp_conn with pointer; add etcp_link backpointer
- stcp_link: link_rx_cb routes ETCP data to etcp_conn_input
- stcp_link: call on_close_cb in close
- New TCP functions: etcp_link_enter_ready_tcp, etcp_tcp_link_start_connect,
  etcp_tcp_link_start_reconnect, tcp_link_close_cb, etcp_tcp_send
- etcp_link_new: handle NULL conn for TCP links; skip enter_init for TCP
- etcp_link_close: close stcp_link for TCP
- etcp_encrypt_send: redirect TCP to etcp_tcp_send (skips AES-CCM)
- tcp_server_on_link: create ETCP_LINK(is_tcp=1) + enter_ready_tcp
- etcp_connect: TCP addrs -> etcp_tcp_link_start_connect
- Remove ctx->tcp_link/tcp_ready
- test_stcp_traffic: find stcp_link via links->is_tcp instead of transport_link
- 66/68 tests pass; 2 STCP tests expected to fail (integration not complete)
2026-08-06 22:14:32 +03:00
evgeny dfe9d36783 wip: STCP TCP chat integration — diagnostics, invite TCP fallback, test infra 2026-08-06 18:41:41 +03:00
evgeny dc8c9f7875 fix: cm_invite_pending — deferred free + cancelled guard
Корень краша: cm_handle_invite_info_resp вызывал cm_invite_cleanup(inv)
без unlink из invite_list — висячий указатель при conn_mgr_destroy → SIGSEGV.

Механизм защиты:
- cancelled:1 в cm_invite_pending — блокирует все коллбэки после cancel
- cm_invite_cancel: cancelled=1 первой строкой, deferred free через uasync_post
- Все коллбэки (NCD, TCP ready/close, overall timer): guard + DEBUG_WARN
- Success path: temp_nq=NULL (передача владения), вызов cm_invite_cancel
- INV_CANCEL логи: skip (NULL) / done — видно что реально сделано
2026-08-06 10:54:56 +03:00
evgeny 38eb51c679 fix: Android event handler lost after restart — g_event_handler now preserved
Root cause: instance_lite_restart was creating new thread without
re-setting g_event_handler, causing all chat events (CHANNEL_UPDATED,
CONNECT_RESULT, etc.) to be silently dropped after app restart.

Fixes:
- instance_lite_restart: save/restore g_event_handler across hard restart
- instance_thread restart loop: re-call chat_event_set_handler after uasync_create
- utun_bridge_restart: call instance_lite_set_event_handler before restart
- AppEventHandler SharedFlow replay: 1 → 16 to not lose early init events
- ViewModel: added diagnostic logging for channel/connect events
- Keep diagnostic logs in instance_lite (set_handler, chat_event_forward NULL check)
- instance_event_handler: removed static for cross-block forward declaration
2026-08-06 00:06:28 +03:00
evgeny be0e76c9a6 debug: реорганизация категорий — SYS(1), ETCP(4) расширен, CONNECTION(3) очищен; fix stcp_client.c sock_err до connect()
Категории:
- DEBUG_CATEGORY_SYS=1: u_async + ll_queue + memory + timing (было 4)
- DEBUG_CATEGORY_ETCP=4: ETCP + normalizer + BBR (было 3)
- DEBUG_CATEGORY_CONNECTION=3: только события статуса линка/подключения (INFO)
- DEBUG_CATEGORY_KEEPALIVE=21: только периодический мониторинг (DEBUG)
- Удалены: NORMALIZER, BBR, CONNECTIVITY
- Устаревшие DB_SYNC → CHAT_SYNC + MEMBER_SYNC (предыдущий коммит)

CONNECTION+INFO — только: Connection UP/DOWN, Link UP/down, Link initialized/added,
  NAT address init/changed, init server/client.
CONNECTION+DEBUG — retry, collision, reinit, socket register.
KEEPALIVE — init_timer SUPPRESSED, timer started, keepalive skipped.
REINIT — ETCP+INFO.
Connection status changed — GENERAL (пользовательский callback).
Dedup link_status: if(old_link_status) перед Link down.
Убран дублирующий Conn:%s из Link down, добавлен link_id в client added link.
Молчаливые ошибки: +DEBUG_ERROR в 15 местах (merkle_sync, member_sync, db_sync).

Fix: stcp_client.c — socket_get_error() вызывался ДО connect(), проверяя
застарелое errno вместо ошибки connect(). Неблокирующий connect() возвращает
-1+EINPROGRESS (норма), но сравнивался с мусором → ложный FAIL.
Все 4 STCP-теста исправлены (68/68 pass).
2026-08-05 10:43:32 +03:00
evgeny 8023f6ee70 stcp: separate v4/v6 sockets, protocol byte in chat addr format, error on bind fail
- stcp_server_create: support AF_INET and AF_INET6 V6ONLY=1 (no dual-stack)
- Add listen_family to stcp_link_config
- init_sockets: return error (not partial) on any bind failure
- add chat_core_sync_my_addresses() call at chatgui startup
- collect_my_addrs: add proto byte (1=UDP, 2=TCP) to binary format
- chat_sync.c JOIN/WELCOME/PEER_UPSERT: read proto byte, write protocol column
- member_sync.c: read proto byte, dynamic protocol bind
- topo_node.c: debug logs for nodeinfo changed detection
- node_config.cpp: type=public for all servers
2026-08-03 20:35:46 +03:00
evgeny e1e54df4f4 fix: invite не затирает имя узла, имя читается из member_sync peers.userinfo
- conn_mgr_core.c: убрана запись node_name из cm_handle_invite_info_resp
- topo_node_sqlite.c: name в nodes не перезаписывается пустой строкой
- android_jni_bridge.c: bridge_get_node_name читает peers_<ch>.userinfo если nodes.name пуст
2026-08-03 18:50:11 +03:00
evgeny ddf696bcf6 refactor: TCP socket addresses — sync to chat DB, topo_node, config file single source
- chat: collect_my_addrs extends to TCP + IPv6, chat_core_sync_my_addresses writes TCP addrs
- topo_node: replace CFG_SERVER with TCP_SOCKET for TCP addresses, simplify NAT logic
- etcp_connections: add IPv6 interface addr resolution for TCP sockets
- Android: INI config file as single source of truth for servers, remove JSON/Gson
- Android: filter temporary IPv6 addresses, fix restart with socket cleanup
- instance_lite: sync addresses after socket creation, proper restart cleanup
2026-08-03 13:57:42 +03:00
evgeny 740ed2a93a fix: NCD UAF, conn_mgr invite protocol, node_id derivation, link reuse
node_conn_direct:
- ncd_init_cb: skip UP when links_up==0, ncd_up_cb delivers when link comes up
- close/force_close: handle_count safety checks, callback clearing
- open/open_node case 2: create links on reused dead conn
- ncd_create_links: skip duplicate link on same conn (stale->etcp==conn)
- set_callback: optional callback change on live handle

conn_mgr:
- cm_ncd_callback: DOWN only delivers event (handle stays alive)
- cm_ncd_callback: TIMEOUT force_close BEFORE cm_deliver_event
- cm_deliver_event: read handle fields to locals before callback (reentrany-safe)
- INVITE_INFO_REQ/RESP: add duplicate cmd byte for direct-send protocol
- cm_handle_invite_info_resp: search invite by group_id in channel conn_mgr

Android:
- node_id computed by sc_derive_node_id_from_pubkey in C, not Kotlin
- utun_bridge_join_channel: recompute node_id, log mismatch
- invite_link_c: compute nodeId from pubkey via sc_derive_node_id_from_pubkey
- NativeLib.deriveNodeId, InviteLink.kt uses C function
2026-08-03 09:51:06 +03:00
evgeny c2191aad3b chat: user-friendly INFO logs for invite/connect flow
- chat_sync.c: invite entry, JOINED/TIMEOUT messages
- conn_mgr_core.c: invite start (addrs+udp+tcp), NCD UP/DOWN/TIMEOUT,
  TCP connect/ready/close, membership check send/receive/confirm/deny,
  overall timeout
- node_conn_direct.c: NCD event names instead of numbers
2026-08-02 20:32:01 +03:00
evgeny e751e6ee69 android: voice messages + attachments architecture plan, build fixes 2026-07-28 23:07:23 +03:00
evgeny f8d7c21a79 Android: unify DB access via JNI/JSON, fix instance lifecycle, add restart + health check
- ChatRepository: remove SQLiteDatabase (READONLY 2nd handle), use JNI→shared g_cc.db (FULLMUTEX, like desktop)
- instance_lite: simplify start/stop lifecycle — start no longer waits for init, stop waits for thread exit with timeout, add internal restart (no thread kill)
- Restart trampoline: reinit UDP log target on config change
- Health check: ping/uasync_post round-trip every 3s, red dot on stall
- Settings: Restart instance button
- Fix: g_inst check instead of g_running for is_running()
- Fix: SharedFlow replay=1 + proactive DB_READY check in ViewModel
2026-07-28 21:13:11 +03:00
evgeny 0216b0bf50 android: utun shutdown diagnostics + non-blocking stop + logreceiver doc
- instance_lite: cleanup moved to uasync thread (self-detach), events on start/stop
- udp_log: cancel_timer before uasync_destroy, flush on stop, stopping flag
- jni_bridge: fixed UDP stop order (cancel_timer → destroy → flush)
- instance_lite: u_report_unfreed_blocks at all shutdown paths
- chat_event: CHAT_EVT_SERVICE_STARTED/STOPPED for GUI notifications
- AGENTS: logreceiver section
2026-07-28 17:06:09 +03:00
evgeny 064bed06f2 android: fix key regeneration, Clear DB, uasync eventfd, udp log from config
- jni_on_event: fix JNI_EDETACHED — AttachCurrentThread/DetachCurrentThread
- u_async.c: pipe→eventfd for reliable cross-thread wakeup
  add process_posted_tasks in poll() path, fix EINTR (saved_errno)
- bridge_debug_hook: keep udp_log_write, remove mutex from udp_log
- memory_pool.c: alloc/free logs INFO→DEBUG (reduce spam)
- instance_lite.c: chat_event_set_handler before ensure_keys,
  KEYS_GENERATED events, fchmod 0600 on keys.conf,
  UDP log from config [log_udp] section, regenerate_trampoline
- config_parser: parse [log_udp] ip/port
- NativeLib.kt: remove callbacksSet, simplify init/stop/destroy
- ChatViewModel.kt: unified event callback in init, pubKey StateFlow,
  requestRegenerateKeys, clearState fix
- SettingsScreen.kt: pubKey.collectAsState(), Clear DB via restart()
- HeadlessService.kt: remove setUdpLogTarget (now from config)
- android_udp_log.c: simplified — no mutex, buffer+send+timer in one thread
- utun_instance.c: NULL-check tcp_connections before destroy
- chat_event.h: +CHAT_EVT_KEYS_GENERATED 11, -NODE_CHANGED
- logreceiver: UDP log receiver tool
2026-07-28 16:29:33 +03:00
evgeny 5276c1288c android: real utun instance + SQLite channels + reactive logs + QR join
- instance_lite.h/c: full uTun stack from INI config text
  (keygen, uasync, UTUN_INSTANCE, SQLite, chat_core/sync, BGP, etcp_router)
- jni_bridge: nativeStart/Stop, nativeJoinChannel → chat_sync_connect_from_invite,
  nativeSubscribeLogs, C logs → logcat + Kotlin LogManager
- Kotlin: direct read-only SQLite queries (channels, messages),
  ViewModel with live event callbacks, reactive LogScreen (tail -f),
  CameraX QR scanner with proper lifecycle, JoinChannelDialog
- HeadlessService: generates INI config from Kotlin settings → C instance
2026-07-28 00:01:57 +03:00