Files
utun2/tools/chatgui-android/libutun_lite/instance_lite.h
T

118 lines
11 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
* Android-владелец одного ядра: INI из Kotlin → pthread с uasync → core_start + chat_service_start.
* UTUN выключен по умолчанию; [gui] utun_enabled=yes включает его явно. Поток владеет instance/ua; UI передаёт работу через uasync.
* С UTUN_WITH_VOICE worker регистрирует call_audio до SERVICE_STARTED и снимает привязку перед уничтожением ядра.
* Полученные handles заимствованы и могут смениться при restart; сохранять их между рестартами нельзя.
* Start/stop/restart сериализованы внутри владельца pthread. Вызовы по сырым handles сериализует frontend:
* атомарный getter не удерживает ресурс от уничтожения. JOIN использует отдельный защищённый port.
*/
#ifndef INSTANCE_LITE_H
#define INSTANCE_LITE_H
#include <stdint.h>
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
struct UASYNC;
struct UTUN_INSTANCE;
struct utun_config;
/* Копирует INI и запускает поток. 0 = поток создан либо уже запущен, -1 = ошибка запуска.
* Готовность самого ядра появляется позже: проверять is_running и события инициализации.
* Startup/restart читает идентичность из keys.conf, если он есть (она старше снимка INI в очереди).
* Формат: public_key=<64 HEX> LF private_key=<64 HEX> LF; ошибка чтения/пары запрещает запуск.
* Без файла используются ключи INI; при их отсутствии сначала сохраняется новая пара. */
int instance_lite_start(const char* config_text);
/* Остановить и собрать joinable worker, включая инициализацию до появления instance и уже завершившийся startup.
* Блокирует до полного cleanup/pthread_join; каждые 2с ожидания пишет предупреждение, поток не отсоединяет.
* Worker снимает media-привязки, уничтожает instance, затем uasync.
* Управляющий frontend предварительно останавливает аудио I/O и освобождает DSP звонка.
* Вызывать вне UI и callbacks ядра. Без worker повторный вызов безопасен и сразу возвращается.
* 0 — worker полностью собран/отсутствует; -1 — ошибка join/недопустимый поток, callbacks освобождать нельзя. */
int instance_lite_stop(void);
/* 1 — instance опубликован и завершил запуск сервисов, 0 — ещё не готов либо остановлен; это не проверка сети. */
int instance_lite_is_running(void);
/* Текущий заимствованный uasync, NULL до create/после destroy; ненулевой handle ещё не означает готовность ядра. */
struct UASYNC* instance_lite_get_uasync(void);
/* Текущий заимствованный instance, NULL до create/после снятия; может быть ненулевым во время инициализации. */
struct UTUN_INSTANCE* instance_lite_get_instance(void);
/* Потокобезопасный JOIN через удержанный port: копирует len байтов ссылки, request ненулевой.
* 0 — принят, результат CHAT_EVT_CONNECT_RESULT с тем же request; <0 — отказ без события.
* Не требует от caller удерживать inst/ua; при stop/restart port закрывается. */
int instance_lite_join_link(uint64_t request, const char* link, size_t len);
/* Любой поток: добавить выбранный локальный channel на сервер по SERVER-ссылке.
* 0 — команда принята, результат CONNECT_RESULT с request; <0 — отказ без события. */
int instance_lite_add_server(uint64_t request, uint64_t channel, const char* link, size_t len);
/* События CHAT_EVT_* из native-потока; data заимствован только на вызов, формат зависит от type (не всегда JSON).
* Установить до start; callback и его окружение должны жить до завершения worker. NULL отключает доставку. */
typedef void (*instance_lite_event_fn)(int type, const uint8_t* data, int len);
void instance_lite_set_event_handler(instance_lite_event_fn handler);
/* Создать X25519-пару и атомарно сохранить в config->global.db_path/keys.conf с правами 0600.
* config — разобранный конфиг с непустым db_path; caller исключает параллельную смену идентичности.
* 0 — файл и каталог синхронизированы, ключи/node_id config обновлены; -1 — config не изменён, ошибка залогирована.
* До rename прежний файл сохраняется; при ошибке sync каталога после rename файл уже заменён (published=1 в логе).
* Не меняет работающее ядро; для новой идентичности его нужно пересоздать. */
int instance_lite_generate_keys(struct utun_config* config);
/* Принять INI для полной смены идентичности в worker: сохранить новую пару и пересоздать ядро/сервисы.
* Нужен готовый core; frontend предварительно останавливает media workers/DSP. 0 — копия INI принята, -1 — отказ с логом.
* Ошибка разбора/сохранения оставляет прежнее ядро; успех даёт KEYS_GENERATED (64 HEX) и SERVICE_STARTED.
* Последний ещё не взятый worker запрос restart/regenerate заменяет предыдущий. */
int instance_lite_regenerate_keys(const char* config_text);
/* Frontend: поставить ACTIVE (active!=0) / STANDBY (0) без заимствования сырого uasync.
* 0 — задача зарезервирована и поставлена живому worker; -1 — ядро не готово/останавливается, ошибка памяти или неверный поток.
* При stop ожидающая команда может отмениться. Результат применения/stream hold логируется в потоке ядра. */
int instance_lite_set_active(int active);
/* Frontend: поставить состояние SIM (0 UNKNOWN/1 IDLE/2 BUSY) и маску call_policy (0..31) живому worker.
* 0 — данные скопированы в задачу под защитой времени жизни uasync; -1 — неверные аргументы/поток, неготовое ядро или OOM.
* Применение асинхронно в текущем ядре; stop/restart может отменить ожидающую команду, освободив её данные.
* После SERVICE_STARTED frontend повторно отправляет актуальные state/policy. */
int instance_lite_set_phone_state(int state, unsigned policy);
#define INSTANCE_LITE_RADIO_SETTINGS_COUNT 7
/* Результат атомарной проверки/применения в worker; request_id возвращается без изменения.
* Callback живёт до join; из него нельзя синхронно останавливать worker. */
typedef void (*instance_lite_radio_configured_fn)(int64_t request_id, int success);
/* Frontend: копирует 7 читаемых int: enabled, mode, levelOn, levelOff, hangoverMs, vadThreshold, vadGain.
* 0 — копия поставлена живому worker под защитой владельца; -1 — неготовое ядро, OOM, NULL values/callback или неверный поток.
* В worker все поля проверяются и применяются целиком; configured(request_id, 1/0) означает успех/отказ без частичного изменения.
* Stop/restart может отменить ожидающий снимок без callback, освободив всё выделение. Новый запуск аудио присылает актуальный снимок. */
int instance_lite_configure_radio(int64_t request_id, const int* values, instance_lite_radio_configured_fn configured);
/* Копирует INI, будит poll-loop и пересоздаёт instance и uasync внутри worker.
* До остановки проверяет конфиг и сохраняет отсутствующие ключи; отказ оставляет прежнее ядро.
* При инициализации ставит запрос в очередь; при завершившемся worker делает join/start.
* Обновление асинхронное; старые handles утрачивают силу.
* Stop имеет приоритет перед ожидающим restart. Последний ещё не взятый worker запрос заменяет предыдущий. */
void instance_lite_restart(const char* new_config_text);
/* Лёгкое обновление сокетов (auto_sockets=android): перечитывает [server] секции
* из нового конфига и сверяет сокеты без полного рестарта. Posts to uasync thread.
* Если ядро не запущено — только логирует ошибку и дропает вызов. */
void instance_lite_update_sockets(const char* config_text);
/* Поставить локальный ping в uasync (не сетевой). is_responsive=1 после исполнения последнего ping;
* до первого ping/при остановке возвращает 0. Встроенного ожидания и проверки таймаута нет. */
void instance_lite_ping(void);
int instance_lite_is_responsive(void);
/* Асинхронные снимки: CHAT_EVT_CONN_LIST и CHAT_EVT_CONN_METRICS; peer_node_id — ID интересующего пира. */
void instance_lite_collect_conn_list(void);
void instance_lite_collect_conn_metrics(uint64_t peer_node_id);
#ifdef __cplusplus
}
#endif
#endif /* INSTANCE_LITE_H */