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: сопутствующие изменения
This commit is contained in:
evgeny committed 2026-09-15 21:09:17 +03:00
1 parent 761f64cf76
commit 73fe99b33f
123 files changed
+14095 -1270

No files matched your search

+5 -2
View File
@@ -90,6 +90,7 @@ void UtunNode::stop() {
}
void UtunNode::finalize() {
gui_bridge_set_inst(nullptr);
if (m_ua) { uasync_destroy(m_ua, 0); m_ua = nullptr; }
m_instance = nullptr;
m_running = false;
@@ -234,6 +235,7 @@ void UtunNode::runLoop() {
/* set ua for gui_bridge before init, so GUI can post */
gui_bridge_set_uasync(ua);
gui_bridge_set_inst(m_instance);
if (utun_instance_init(m_instance) != 0) {
QMetaObject::invokeMethod(this, [this] { emit error("utun_instance_init failed"); });
@@ -254,14 +256,15 @@ void UtunNode::runLoop() {
utun_add_nodeinfo_cbk(m_instance, gui_nodeinfo_cb_impl, nullptr);
/* Bridge chat events to GUI via gui_bridge */
chat_event_set_handler([](int type, const uint8_t* data, int len) {
chat_event_set_handler(m_instance, [](struct UTUN_INSTANCE* inst, int type, const uint8_t* data, int len) {
(void)inst;
gui_bridge_post(type, data, len);
});
/* Initialize chat_core (DB) and chat_sync (channel/message P2P sync) */
chat_core_init(m_instance, QString(m_dbPath + "/chats.db").toUtf8().constData());
chat_sync_init(m_instance);
chat_core_sync_my_addresses();
chat_core_sync_my_addresses(m_instance);
DEBUG_DEBUG(DEBUG_CATEGORY_GENERAL, "chat_core + chat_sync initialized");
DEBUG_DEBUG(DEBUG_CATEGORY_GENERAL, "utun_node: entering poll loop");