/* * chat_sync — связь чат-сервиса с транспортом и группами. * Отслеживает пиров, запускает member_sync, поддерживает кеш каналов и статус в GUI. * Вход по ссылке держит отдельный NCD handle до результата join, а не только до UP. * JOIN_INFO_REQ → JOIN_INFO_RESP → JOIN_REQUEST → JOIN_READY; правила — в chat_join.h. * Жизненным циклом управляет chat_service_start/stop. Вызовы — в потоке uasync, * кроме явно отмеченной обёртки, которая копирует аргументы и постит работу в этот поток. */ #ifndef CHAT_SYNC_H #define CHAT_SYNC_H #ifdef __cplusplus extern "C" { #endif #include #include struct UTUN_INSTANCE; struct UASYNC; /* etcp service IDs (direct P2P): ETCP_ID_CHAT_SYNC / ETCP_ID_MEMBER_SYNC * (etcp_bind, см. etcp_api.h) */ /* Message types */ #define CS_MSG_INIT_SYNC 0x01 #define CS_MSG_INIT_RESP 0x02 #define CS_MSG_SEND_DATA 0x03 #define CS_MSG_PUSH 0x04 #define CS_MSG_ACK_PUSH 0x05 #define CS_MSG_SYNC_DONE 0x06 #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 */ /* Protocol constants */ #define CS_SEND_DATA_MAX 32 #define CS_MAX_SPARSE 16 #define CS_PEER_TIMEOUT_MS 5000 /* Sync states per channel */ #define CS_SYNC_NONE 0 #define CS_SYNC_IN_PROGRESS 1 #define CS_SYNC_DONE 2 /* ── Public API ── */ /* Создать контекст, обработчики join и member_sync. 0/-1; повтор допустим. */ int chat_sync_init(struct UTUN_INSTANCE* inst); /* Отменить ожидания join, синхронизацию и таймеры; не удаляет данные каналов. */ void chat_sync_destroy(struct UTUN_INSTANCE* inst); /* Сейчас пустая функция. Для подключения использовать chat_core_connect_node с каналом. */ void chat_sync_connect_node(struct UTUN_INSTANCE* inst, uint64_t node_id); /* Подключиться к пиру по данным invite-ссылки (вызывается из uasync-потока). join_key — 64-битный ключ входа из ссылки (регистрируется инвайтером на connection-узле). password может быть NULL — тогда передаётся пустой пароль. */ void chat_sync_connect_from_invite(struct UTUN_INSTANCE* inst, uint64_t channel_id, uint64_t node_id, const uint8_t* pubkey_bin, const uint8_t* addrs_data, int addr_count, int addrs_data_len, const char* password, uint64_t join_key); /* Пригласить target_node_id в канал ch_id с адресами из invite-ссылки (inviter → joiner). Принимает pubkey и адреса целевого узла. Если соединения ещё нет — строит TOPO_NODE с адресами, удерживает NCD для join, и по UP отправляет CS_MSG_CHANNEL_INVITE. Если соединение уже есть — отправляет CHANNEL_INVITE сразу. Копирует pubkey_bin и addrs_data (вызывающий может освободить после возврата). Вызов из любого потока — внутри постит в uasync. */ void chat_sync_invite_to_channel_with_addrs( struct UTUN_INSTANCE* inst, const char* ch_id, uint64_t target_node_id, const uint8_t* pubkey_bin, const uint8_t* addrs_data, int addr_count, int addrs_data_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); /* Принять входящее приглашение — продолжить протокол из chat_join.h. */ 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); /* Присоединиться к каналу через уже подключённый узел (uasync-поток). Соединение с target_node_id должно быть установлено (links_up && initialized). Протокол: JOIN_INFO_REQ → JOIN_INFO_RESP → JOIN_REQUEST → JOIN_READY (chat_join.h). Канал (DB + TOPO_GROUP) создаётся локально при получении JOIN_INFO_RESP; это само по себе не даёт членства на других узлах. */ void chat_sync_join_channel(struct UTUN_INSTANCE* inst, const char* ch_id, uint64_t target_node_id); /* Снять паузу и сбросить задержки повторных попыток во всех кешированных каналах с автоматическим планировщиком. Планировщик пересматривает подключения; работающие соединения сохраняются. Вызывается из auto_socket при появлении/изменении сетевой связности. */ void chat_sync_retry_channels_on_socket_change(struct UTUN_INSTANCE* inst); /* Немедленно убрать канал из кеша chat_sync (локальное удаление канала), * чтобы cs_on_conn_status не запускал member_sync для удалённого ns до следующего refresh. */ 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 */