110 lines
9.0 KiB
C
110 lines
9.0 KiB
C
/*
|
||
* chat_sync — связь чат-сервиса с транспортом и группами.
|
||
* Отслеживает пиров, запускает member_sync, поддерживает кеш каналов и статус в GUI.
|
||
* UP/REINIT/пробуждение восстанавливают только общие каналы соответствующего пира.
|
||
* Отложенные запросы объединяются по (канал, пир); активными обменами и обновлениями владеет Merkle.
|
||
* Вход по ссылке держит отдельный NCD handle до результата join, а не только до UP.
|
||
* JOIN_INFO_REQ → JOIN_INFO_RESP → JOIN_REQUEST → JOIN_READY; правила — в chat_join.h.
|
||
* Жизненным циклом управляет chat_service_start/stop. Вызовы — в потоке uasync.
|
||
* Вход из GUI/JNI через отдельный chat_join_port, который копирует ссылку и удерживает очередь до close.
|
||
* Кеш строится полным снимком БД (до65536 каналов/пиров на канал);ошибка сохраняет прежний снимок.
|
||
* Callback UI может удалить канал: обходы уведомлений используют собственные копии ID.
|
||
*/
|
||
|
||
#ifndef CHAT_SYNC_H
|
||
#define CHAT_SYNC_H
|
||
|
||
#ifdef __cplusplus
|
||
extern "C" {
|
||
#endif
|
||
|
||
#include <stdint.h>
|
||
#include <stddef.h>
|
||
|
||
struct UTUN_INSTANCE;
|
||
|
||
/* etcp service IDs (direct P2P): ETCP_ID_CHAT_SYNC / ETCP_ID_MEMBER_SYNC
|
||
* (etcp_bind, см. etcp_api.h) */
|
||
|
||
/* Управление JOIN, приглашениями и настройкой звука; история сообщений — в db_sync/Merkle. */
|
||
#define CS_MSG_ERROR 0x07
|
||
#define CS_MSG_CHANNEL_INVITE 0x0F /* push-invite: inviter → joiner */
|
||
/* В JOIN_INFO_REQ pass_len обязателен даже при пустом пароле (0); password передаётся без NUL. */
|
||
#define CS_MSG_JOIN_INFO_REQ 0x10 /* joiner → connection: {join_key:8, pass_len:1, password:pass_len} */
|
||
#define CS_MSG_JOIN_INFO_RESP 0x11 /* connection → joiner: channel info + connection's member record */
|
||
#define CS_MSG_JOIN_REQUEST 0x12 /* joiner → connection: {join_key:8, member...} */
|
||
#define CS_MSG_JOIN_READY 0x13 /* connection → joiner: {group_id:8} */
|
||
#define CS_MSG_SOUND_SETTING 0x14 /* peer → server: {sound_on:1} — per-chat play sound on message */
|
||
#define CS_MSG_SERVER_JOIN_REQ 0x15 /* client → server: operation:8BE, add_key:32, link_len:2BE, CHANNEL-link */
|
||
#define CS_MSG_SERVER_JOIN_RESULT 0x16 /* server → client: operation:8BE, result:4BE (CHAT_CONNECT_*) */
|
||
|
||
/* Управление JOIN (INFO_REQ/RESP, REQUEST, READY, ERROR): после type идёт attempt_id:8BE,
|
||
* затем payload, описанный выше. Ненулевой случайный ID новый для каждой локальной попытки;
|
||
* ответы проверяются по (peer, group, attempt_id, phase). CHANNEL_INVITE переносит предложение
|
||
* с join_key; получатель создаёт собственный attempt_id при принятии предложения. */
|
||
|
||
/* SERVER_JOIN_REQ: add_key проверяется до обычного chat_sync_join_link. CHANNEL-link обязан
|
||
* относиться к group_id заголовка и вести на отправителя: JOIN использует уже открытый транспорт.
|
||
* operation_id не является attempt_id серверного JOIN. RESULT возвращается после его завершения;
|
||
* повторы активного operation_id не создают второй JOIN. Клиент держит NCD до RESULT/общего deadline.
|
||
* Обычный CHANNEL_INVITE сервер не принимает: этот путь не проверяет серверный add_key. */
|
||
|
||
/* ── Public API ── */
|
||
|
||
/* Создать контекст,обработчики/подписки и первый кеш поверх готового chat_core. 0/-1;повтор допустим.
|
||
* Ошибка обязательной подписки/таймера/первого кеша откатывает runtime;данные БД сохраняются. */
|
||
int chat_sync_init(struct UTUN_INSTANCE* inst);
|
||
/* uasync: закрыть приём команд и отменить локальный JOIN до остановки workers. */
|
||
void chat_sync_quiesce(struct UTUN_INSTANCE* inst);
|
||
/* uasync: отменить только активный request; чужая попытка сохраняется. */
|
||
void chat_sync_cancel_join(struct UTUN_INSTANCE* inst, uint64_t request);
|
||
/* Отменить ожидания, синхронизацию и таймеры, освободить контекст; данные каналов сохраняются. */
|
||
void chat_sync_destroy(struct UTUN_INSTANCE* inst);
|
||
|
||
/* Локальная попытка JOIN: uasync. Отрицательный возврат — отказ запуска без события;
|
||
* 0 — запущено, CHAT_EVT_CONNECT_RESULT ровно один раз, включая stop/delete.
|
||
* request=0 — без адресата UI; ненулевые ID вызывающий не переиспользует до завершения.
|
||
* link заимствован до возврата; request — корреляция интерфейса, не сетевой attempt_id. */
|
||
#define CHAT_CONNECT_ERROR -1
|
||
#define CHAT_CONNECT_TIMEOUT 2
|
||
#define CHAT_CONNECT_INVALID -7
|
||
#define CHAT_CONNECT_BUSY -8
|
||
#define CHAT_CONNECT_CANCELLED -9
|
||
#define CHAT_CONNECT_AUTH -10
|
||
int chat_sync_join_link(struct UTUN_INSTANCE* inst, uint64_t request, const char* link, size_t len);
|
||
/* Единый формат результата: peer:8,result:4,channel:8,request:8, native; только uasync. */
|
||
void chat_sync_join_result(struct UTUN_INSTANCE* inst, uint64_t request, uint64_t channel, uint64_t peer, int result);
|
||
|
||
/* uasync: пригласить адресата в свой channel. SERVER-ссылка запускает запрос с add_key и обычным
|
||
* приглашением через self; успех возвращает сервер после своего JOIN. CHANNEL — обычный push-invite.
|
||
* Те же правила запуска/результата; серверная ссылка не является приглашением в канал. */
|
||
int chat_sync_offer_link(struct UTUN_INSTANCE* inst, uint64_t request, uint64_t channel, const char* link, size_t len);
|
||
|
||
/* Пригласить target_node_id в канал ch_id (inviter → joiner).
|
||
Отправляет CS_MSG_CHANNEL_INVITE с описанием канала, подписями/профилем инвайтера и join_key. */
|
||
void chat_sync_invite_to_channel(struct UTUN_INSTANCE* inst, const char* ch_id, uint64_t target_node_id);
|
||
|
||
/* Принять сохранённое приглашение (до4 пар канал/инвайтер). Успешный запуск убирает его из очереди;
|
||
* BUSY/отказ запуска сохраняет предложение. Описание/участник проверяются и сохраняются только в JOIN_INFO_RESP. */
|
||
void chat_sync_accept_invite(struct UTUN_INSTANCE* inst, uint64_t channel_id, uint64_t inviter_node_id);
|
||
|
||
/* Убрать пару из очереди предложений без сетевого ответа;освободившийся слот можно использовать повторно. */
|
||
void chat_sync_deny_invite(struct UTUN_INSTANCE* inst, uint64_t channel_id, uint64_t inviter_node_id);
|
||
|
||
/* Снять паузу и сбросить задержки повторных попыток во всех кешированных каналах с автоматическим планировщиком.
|
||
Планировщик пересматривает подключения; работающие соединения сохраняются.
|
||
Вызывается из auto_socket при появлении/изменении сетевой связности. */
|
||
void chat_sync_retry_channels_on_socket_change(struct UTUN_INSTANCE* inst);
|
||
|
||
/* Отменить JOIN,waiters,предложения и отложенные запросы канала;немедленно убрать его из кеша (локальное удаление).
|
||
* Активные Merkle-сессии отменяет вызывающий код через member_sync_cancel_channel(). */
|
||
void chat_sync_on_channel_deleted(struct UTUN_INSTANCE* inst, const char* ch_id);
|
||
|
||
/* Разослать всем подключённым пирам канала смену per-chat настройки «play sound on message». */
|
||
void chat_sync_broadcast_sound_setting(struct UTUN_INSTANCE* inst, const char* ch_id, int on);
|
||
|
||
#ifdef __cplusplus
|
||
}
|
||
#endif
|
||
#endif /* CHAT_SYNC_H */
|