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:
1 parent
761f64cf76
commit
73fe99b33f
123 files changed
+14095
-1270
No files matched your search
@@ -273,10 +273,10 @@ void AccountList::showMemberDetail(quint64 nodeId) {
|
||||
|
||||
void AccountList::requestMemberDetail() {
|
||||
if (m_detailNodeId == 0) return;
|
||||
void* arg = u_malloc(sizeof(uint64_t));
|
||||
struct chat_node_arg* arg = (struct chat_node_arg*)u_malloc(sizeof(struct chat_node_arg));
|
||||
if (!arg) { DEBUG_WARN(DEBUG_CATEGORY_DEBUG, "AccountList: req alloc failed"); return; }
|
||||
uint64_t nid = m_detailNodeId;
|
||||
memcpy(arg, &nid, sizeof(nid));
|
||||
arg->inst = gui_bridge_get_inst();
|
||||
arg->node_id = m_detailNodeId;
|
||||
gui_bridge_post_uasync_fn(chat_core_collect_member_detail_trampoline, arg);
|
||||
}
|
||||
|
||||
@@ -482,6 +482,7 @@ void AccountList::onMemberContextMenu(const QPoint& pos) {
|
||||
struct chat_connect_node_req* r = (struct chat_connect_node_req*)u_malloc(sizeof(*r));
|
||||
if (!r) return;
|
||||
memset(r, 0, sizeof(*r));
|
||||
r->inst = gui_bridge_get_inst();
|
||||
strncpy(r->ch_id, m_channelId.toUtf8().constData(), sizeof(r->ch_id) - 1);
|
||||
r->node_id = nodeId;
|
||||
gui_bridge_post_uasync_fn(chat_core_connect_node_trampoline, r);
|
||||
|
||||
@@ -193,9 +193,11 @@ void AudioDeviceSettingsPage::applyAndSave() {
|
||||
size_t klen = strlen(key), vlen = (size_t)v.size();
|
||||
size_t total = klen + 1 + vlen + 1;
|
||||
if (total > 256) return;
|
||||
void* arg = u_malloc(total);
|
||||
memcpy(arg, key, klen + 1);
|
||||
memcpy((char*)arg + klen + 1, v.constData(), vlen + 1);
|
||||
struct save_ui_state_arg* arg = (struct save_ui_state_arg*)u_malloc(sizeof(struct save_ui_state_arg));
|
||||
if (!arg) return;
|
||||
arg->inst = gui_bridge_get_inst();
|
||||
memcpy(arg->data, key, klen + 1);
|
||||
memcpy(arg->data + klen + 1, v.constData(), vlen + 1);
|
||||
gui_bridge_post_uasync_fn(chat_core_save_ui_state_trampoline, arg);
|
||||
};
|
||||
saveKey("audio_output_device", outIdx);
|
||||
@@ -219,9 +221,11 @@ void AudioDeviceSettingsPage::applyAndSave() {
|
||||
QByteArray v = QByteArray::number(val);
|
||||
size_t nlen = strlen(name), vlen = (size_t)v.size(), total = nlen + 1 + vlen + 1;
|
||||
if (total > 256) return;
|
||||
void* arg = u_malloc(total);
|
||||
memcpy(arg, name, nlen + 1);
|
||||
memcpy((char*)arg + nlen + 1, v.constData(), vlen + 1);
|
||||
struct chat_setting_arg* arg = (struct chat_setting_arg*)u_malloc(sizeof(struct chat_setting_arg));
|
||||
if (!arg) return;
|
||||
arg->inst = gui_bridge_get_inst();
|
||||
memcpy(arg->data, name, nlen + 1);
|
||||
memcpy(arg->data + nlen + 1, v.constData(), vlen + 1);
|
||||
gui_bridge_post_uasync_fn(chat_core_set_setting_trampoline, arg);
|
||||
};
|
||||
postChat(m_configPath, "opus_codec_preset", codecPreset);
|
||||
|
||||
@@ -93,9 +93,11 @@ void ChannelSettingsDialog::onSave() {
|
||||
size_t klen = (size_t)keyBA.size(), vlen = (size_t)valBA.size();
|
||||
size_t total = klen + 1 + vlen + 1;
|
||||
if (total <= 256) {
|
||||
void* arg = u_malloc(total);
|
||||
memcpy(arg, keyBA.constData(), klen + 1);
|
||||
memcpy((char*)arg + klen + 1, valBA.constData(), vlen + 1);
|
||||
struct save_ui_state_arg* arg = (struct save_ui_state_arg*)u_malloc(sizeof(struct save_ui_state_arg));
|
||||
if (!arg) return;
|
||||
arg->inst = gui_bridge_get_inst();
|
||||
memcpy(arg->data, keyBA.constData(), klen + 1);
|
||||
memcpy(arg->data + klen + 1, valBA.constData(), vlen + 1);
|
||||
gui_bridge_post_uasync_fn(chat_core_save_ui_state_trampoline, arg);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -103,7 +103,7 @@ void ConnMonitorWindow::hideEvent(QHideEvent* event) {
|
||||
void ConnMonitorWindow::onTimerTick() {
|
||||
if (m_details->textCursor().hasSelection()) return;
|
||||
if (QApplication::mouseButtons()) return;
|
||||
gui_bridge_post_uasync_fn(chat_core_collect_conn_list_trampoline, nullptr);
|
||||
gui_bridge_post_uasync_fn(chat_core_collect_conn_list_trampoline, gui_bridge_get_inst());
|
||||
if (m_selectedNodeId) requestMetricsForSelected();
|
||||
}
|
||||
|
||||
@@ -115,9 +115,10 @@ void ConnMonitorWindow::onConnSelected(QListWidgetItem* current, QListWidgetItem
|
||||
}
|
||||
|
||||
void ConnMonitorWindow::requestMetricsForSelected() {
|
||||
void* arg = u_malloc(sizeof(uint64_t));
|
||||
struct chat_node_arg* arg = (struct chat_node_arg*)u_malloc(sizeof(struct chat_node_arg));
|
||||
if (!arg) return;
|
||||
memcpy(arg, &m_selectedNodeId, sizeof(uint64_t));
|
||||
arg->inst = gui_bridge_get_inst();
|
||||
arg->node_id = m_selectedNodeId;
|
||||
gui_bridge_post_uasync_fn(chat_core_collect_conn_metrics_trampoline, arg);
|
||||
}
|
||||
|
||||
|
||||
@@ -182,7 +182,7 @@ void InviteByLinkDialog::onSendInvite() {
|
||||
QByteArray addrsBuf = serializeInviteAddrs(d);
|
||||
|
||||
chat_sync_invite_to_channel_with_addrs(
|
||||
chat_core_get_inst(), m_channelId.toUtf8().constData(), targetNodeId,
|
||||
gui_bridge_get_inst(), m_channelId.toUtf8().constData(), targetNodeId,
|
||||
(const uint8_t*)d.pubkey.constData(),
|
||||
(const uint8_t*)addrsBuf.constData(), d.addrs.size(), addrsBuf.size());
|
||||
|
||||
|
||||
@@ -89,8 +89,11 @@ ShareInviteDialog::ShareInviteDialog(const QString& channelId, DbManager* db, QW
|
||||
});
|
||||
|
||||
/* запросить кандидатов; линк строится после их прихода */
|
||||
QByteArray chBytes = m_channelId.toUtf8();
|
||||
gui_bridge_post_uasync_fn(chat_invite_candidates_trampoline, u_strdup(chBytes.constData()));
|
||||
struct chat_invite_cand_req* creq = (struct chat_invite_cand_req*)u_calloc(1, sizeof(*creq));
|
||||
if (!creq) return;
|
||||
creq->inst = gui_bridge_get_inst();
|
||||
strncpy(creq->ch_id, m_channelId.toUtf8().constData(), sizeof(creq->ch_id) - 1);
|
||||
gui_bridge_post_uasync_fn(chat_invite_candidates_trampoline, creq);
|
||||
}
|
||||
|
||||
ShareInviteDialog::~ShareInviteDialog() {
|
||||
@@ -111,6 +114,7 @@ void ShareInviteDialog::requestLink(uint64_t targetNodeId) {
|
||||
return;
|
||||
}
|
||||
memset(req, 0, sizeof(*req));
|
||||
req->inst = gui_bridge_get_inst();
|
||||
QByteArray chBytes = m_channelId.toUtf8();
|
||||
strncpy(req->ch_id, chBytes.constData(), sizeof(req->ch_id) - 1);
|
||||
req->target_node_id = targetNodeId;
|
||||
|
||||
@@ -193,7 +193,7 @@ void JoinDialog::onConnectClicked() {
|
||||
int addrCount = d.addrs.size();
|
||||
const char* pass = d.password.isEmpty() ? NULL : d.password.toUtf8().constData();
|
||||
|
||||
chat_sync_connect_from_invite(d.channelId, nodeId,
|
||||
chat_sync_connect_from_invite(gui_bridge_get_inst(), d.channelId, nodeId,
|
||||
(const uint8_t*)d.pubkey.constData(),
|
||||
(const uint8_t*)addrsBuf.constData(), addrCount, addrsBuf.size(), pass, d.joinKey);
|
||||
}
|
||||
|
||||
@@ -62,9 +62,11 @@ static void postUiStateKv(const char* key, const QString& value) {
|
||||
QByteArray val = value.toUtf8();
|
||||
size_t klen = strlen(key), vlen = (size_t)val.size(), total = klen + 1 + vlen + 1;
|
||||
if (total > 256) return;
|
||||
void* arg = u_malloc(total);
|
||||
memcpy(arg, key, klen + 1);
|
||||
memcpy((char*)arg + klen + 1, val.constData(), vlen + 1);
|
||||
struct save_ui_state_arg* arg = (struct save_ui_state_arg*)u_malloc(sizeof(struct save_ui_state_arg));
|
||||
if (!arg) return;
|
||||
arg->inst = gui_bridge_get_inst();
|
||||
memcpy(arg->data, key, klen + 1);
|
||||
memcpy(arg->data + klen + 1, val.constData(), vlen + 1);
|
||||
gui_bridge_post_uasync_fn(chat_core_save_ui_state_trampoline, arg);
|
||||
}
|
||||
|
||||
@@ -369,7 +371,7 @@ void MainWindow::setupBridgeCallbacks() {
|
||||
gui_bridge_set_channel_peers_online_cb(onChannelPeersOnlineCallback);
|
||||
gui_bridge_set_db_ready_cb([]() {
|
||||
if (!s_mainWindow || !s_mainWindow->m_db) return;
|
||||
s_mainWindow->m_db->setDb(chat_core_get_db());
|
||||
s_mainWindow->m_db->setDb(chat_core_get_db(gui_bridge_get_inst()));
|
||||
s_mainWindow->m_channelList->loadChannels();
|
||||
s_mainWindow->restoreWindowGeometry();
|
||||
QString lastCid = s_mainWindow->m_db->getUiState("last_channel_id");
|
||||
@@ -424,9 +426,12 @@ void MainWindow::setupConnects() {
|
||||
m_currentChannelId = channelId;
|
||||
m_messageList->loadChannel(channelId);
|
||||
m_accountList->setChannel(channelId);
|
||||
QByteArray cidBA = channelId.toUtf8();
|
||||
char* cid = u_strdup(cidBA.constData());
|
||||
if (cid) gui_bridge_post_uasync_fn(chat_core_connect_channel_trampoline, cid);
|
||||
struct chat_create_auto_arg* arg = (struct chat_create_auto_arg*)u_calloc(1, sizeof(*arg));
|
||||
if (arg) {
|
||||
arg->inst = gui_bridge_get_inst();
|
||||
snprintf(arg->name, sizeof(arg->name), "%s", channelId.toUtf8().constData());
|
||||
gui_bridge_post_uasync_fn(chat_core_connect_channel_trampoline, arg);
|
||||
}
|
||||
});
|
||||
connect(m_channelList, &ChannelList::inviteRequested, this, &MainWindow::showShareInviteDialog);
|
||||
connect(m_channelList, &ChannelList::inviteByLinkRequested, this, &MainWindow::showInviteByLinkDialog);
|
||||
@@ -671,7 +676,15 @@ void MainWindow::onCreateGroupRequested() {
|
||||
if (name.isEmpty()) return;
|
||||
|
||||
char* name_copy = u_strdup(name.toUtf8().constData());
|
||||
if (name_copy) gui_bridge_post_uasync_fn(chat_core_create_channel_auto_trampoline, name_copy);
|
||||
if (name_copy) {
|
||||
struct chat_create_auto_arg* arg = (struct chat_create_auto_arg*)u_malloc(sizeof(*arg));
|
||||
if (arg) {
|
||||
arg->inst = gui_bridge_get_inst();
|
||||
snprintf(arg->name, sizeof(arg->name), "%s", name_copy);
|
||||
gui_bridge_post_uasync_fn(chat_core_create_channel_auto_trampoline, arg);
|
||||
}
|
||||
u_free(name_copy);
|
||||
}
|
||||
|
||||
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "MainWindow: create group request posted name=%s", qPrintable(name));
|
||||
}
|
||||
@@ -734,6 +747,7 @@ void MainWindow::autoPlayCheckNewMessage(const QString& channelId) {
|
||||
u_malloc(sizeof(struct attachment_dl_req));
|
||||
if (!req) return;
|
||||
memset(req, 0, sizeof(*req));
|
||||
req->inst = gui_bridge_get_inst();
|
||||
strncpy(req->channel_id, channelId.toUtf8().constData(), sizeof(req->channel_id) - 1);
|
||||
req->msg_id = msg.id;
|
||||
gui_bridge_post_uasync_fn(chat_core_attachment_download_trampoline, req);
|
||||
@@ -787,6 +801,7 @@ void MainWindow::autoPlayTimerTick() {
|
||||
u_malloc(sizeof(struct attachment_dl_req));
|
||||
if (!req) return;
|
||||
memset(req, 0, sizeof(*req));
|
||||
req->inst = gui_bridge_get_inst();
|
||||
strncpy(req->channel_id, item.channelId.toUtf8().constData(), sizeof(req->channel_id) - 1);
|
||||
req->msg_id = item.msgId;
|
||||
gui_bridge_post_uasync_fn(chat_core_attachment_download_trampoline, req);
|
||||
|
||||
@@ -66,8 +66,11 @@ void MemberListModel::setChannel(const QString& channelId, bool isOwner) {
|
||||
endResetModel();
|
||||
|
||||
if (!channelId.isEmpty()) {
|
||||
char* ch = u_strdup(channelId.toUtf8().constData());
|
||||
gui_bridge_post_uasync_fn(chat_core_request_member_list_trampoline, ch);
|
||||
struct chat_member_list_req* req = (struct chat_member_list_req*)u_calloc(1, sizeof(*req));
|
||||
if (!req) return;
|
||||
req->inst = gui_bridge_get_inst();
|
||||
strncpy(req->ch_id, channelId.toUtf8().constData(), sizeof(req->ch_id) - 1);
|
||||
gui_bridge_post_uasync_fn(chat_core_request_member_list_trampoline, req);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,8 +80,11 @@ void MemberListModel::refresh() {
|
||||
|
||||
void MemberListModel::refreshRtt() {
|
||||
if (m_channelId.isEmpty()) return;
|
||||
char* ch = u_strdup(m_channelId.toUtf8().constData());
|
||||
gui_bridge_post_uasync_fn(chat_core_request_member_rtt_trampoline, ch);
|
||||
struct chat_member_list_req* req = (struct chat_member_list_req*)u_calloc(1, sizeof(*req));
|
||||
if (!req) return;
|
||||
req->inst = gui_bridge_get_inst();
|
||||
strncpy(req->ch_id, m_channelId.toUtf8().constData(), sizeof(req->ch_id) - 1);
|
||||
gui_bridge_post_uasync_fn(chat_core_request_member_rtt_trampoline, req);
|
||||
}
|
||||
|
||||
quint64 MemberListModel::nodeIdAt(int row) const {
|
||||
|
||||
@@ -198,6 +198,7 @@ void MemberPropsDialog::onSave() {
|
||||
u_calloc(1, sizeof(struct chat_member_tags_req));
|
||||
if (!req) { accept(); return; }
|
||||
|
||||
req->inst = gui_bridge_get_inst();
|
||||
QByteArray ch_id_utf8 = m_channelId.toUtf8();
|
||||
strncpy(req->ch_id, ch_id_utf8.constData(), sizeof(req->ch_id) - 1);
|
||||
req->node_id = m_nodeId;
|
||||
@@ -226,6 +227,7 @@ void MemberPropsDialog::onTransferAdmin() {
|
||||
u_calloc(1, sizeof(struct chat_transfer_admin_req));
|
||||
if (!req) return;
|
||||
|
||||
req->inst = gui_bridge_get_inst();
|
||||
QByteArray ch_id_utf8 = m_channelId.toUtf8();
|
||||
strncpy(req->ch_id, ch_id_utf8.constData(), sizeof(req->ch_id) - 1);
|
||||
req->target_node_id = m_nodeId;
|
||||
|
||||
@@ -101,6 +101,7 @@ bool MessageDelegate::editorEvent(QEvent *event, QAbstractItemModel *model,
|
||||
u_malloc(sizeof(struct attachment_dl_req));
|
||||
if (!req) return false;
|
||||
memset(req, 0, sizeof(*req));
|
||||
req->inst = gui_bridge_get_inst();
|
||||
strncpy(req->channel_id, chId.toUtf8().constData(), sizeof(req->channel_id) - 1);
|
||||
req->msg_id = msgId;
|
||||
gui_bridge_post_uasync_fn(chat_core_attachment_download_trampoline, req);
|
||||
@@ -127,6 +128,7 @@ bool MessageDelegate::editorEvent(QEvent *event, QAbstractItemModel *model,
|
||||
u_malloc(sizeof(struct attachment_dl_req));
|
||||
if (!req) return false;
|
||||
memset(req, 0, sizeof(*req));
|
||||
req->inst = gui_bridge_get_inst();
|
||||
strncpy(req->channel_id, chId.toUtf8().constData(), sizeof(req->channel_id) - 1);
|
||||
req->msg_id = msgId;
|
||||
gui_bridge_post_uasync_fn(chat_core_attachment_download_trampoline, req);
|
||||
@@ -151,6 +153,7 @@ bool MessageDelegate::editorEvent(QEvent *event, QAbstractItemModel *model,
|
||||
u_malloc(sizeof(struct attachment_dl_req));
|
||||
if (!req) return false;
|
||||
memset(req, 0, sizeof(*req));
|
||||
req->inst = gui_bridge_get_inst();
|
||||
strncpy(req->channel_id, chId.toUtf8().constData(), sizeof(req->channel_id) - 1);
|
||||
req->msg_id = msgId;
|
||||
gui_bridge_post_uasync_fn(chat_core_attachment_download_trampoline, req);
|
||||
@@ -178,6 +181,7 @@ bool MessageDelegate::editorEvent(QEvent *event, QAbstractItemModel *model,
|
||||
u_malloc(sizeof(struct attachment_dl_req));
|
||||
if (!req) return false;
|
||||
memset(req, 0, sizeof(*req));
|
||||
req->inst = gui_bridge_get_inst();
|
||||
strncpy(req->channel_id, chId.toUtf8().constData(), sizeof(req->channel_id) - 1);
|
||||
req->msg_id = msgId;
|
||||
gui_bridge_post_uasync_fn(chat_core_attachment_download_trampoline, req);
|
||||
|
||||
@@ -39,7 +39,6 @@ extern "C" {
|
||||
#include "../../lib/u_async.h"
|
||||
#include "../../lib/mem.h"
|
||||
#include "../../lib/debug_config.h"
|
||||
struct save_ui_state_arg { char data[256]; };
|
||||
void chat_core_save_ui_state_trampoline(void* arg);
|
||||
}
|
||||
|
||||
@@ -364,6 +363,7 @@ MessageList::MessageList(DbManager* db, AudioRecorder* recorder, QWidget *parent
|
||||
struct chat_msg_submit* req = (struct chat_msg_submit*)
|
||||
u_malloc(sizeof(struct chat_msg_submit) + textData.size());
|
||||
memset(req, 0, sizeof(*req));
|
||||
req->inst = gui_bridge_get_inst();
|
||||
snprintf(req->channel_id, sizeof(req->channel_id), "%s",
|
||||
m_currentChannelId.toUtf8().constData());
|
||||
snprintf(req->content_type, sizeof(req->content_type), "text/plain");
|
||||
@@ -384,6 +384,7 @@ MessageList::MessageList(DbManager* db, AudioRecorder* recorder, QWidget *parent
|
||||
struct chat_msg_submit* req = (struct chat_msg_submit*)
|
||||
u_malloc(sizeof(struct chat_msg_submit) + textData.size());
|
||||
memset(req, 0, sizeof(*req));
|
||||
req->inst = gui_bridge_get_inst();
|
||||
snprintf(req->channel_id, sizeof(req->channel_id), "%s",
|
||||
m_currentChannelId.toUtf8().constData());
|
||||
snprintf(req->content_type, sizeof(req->content_type), "audio/opus");
|
||||
@@ -407,6 +408,7 @@ MessageList::MessageList(DbManager* db, AudioRecorder* recorder, QWidget *parent
|
||||
struct chat_msg_submit* req = (struct chat_msg_submit*)
|
||||
u_malloc(sizeof(struct chat_msg_submit) + textData.size());
|
||||
memset(req, 0, sizeof(*req));
|
||||
req->inst = gui_bridge_get_inst();
|
||||
snprintf(req->channel_id, sizeof(req->channel_id), "%s",
|
||||
m_currentChannelId.toUtf8().constData());
|
||||
snprintf(req->content_type, sizeof(req->content_type), "application/octet-stream");
|
||||
@@ -430,6 +432,7 @@ MessageList::MessageList(DbManager* db, AudioRecorder* recorder, QWidget *parent
|
||||
struct chat_msg_submit* req = (struct chat_msg_submit*)
|
||||
u_malloc(sizeof(struct chat_msg_submit) + textData.size());
|
||||
memset(req, 0, sizeof(*req));
|
||||
req->inst = gui_bridge_get_inst();
|
||||
snprintf(req->channel_id, sizeof(req->channel_id), "%s",
|
||||
m_currentChannelId.toUtf8().constData());
|
||||
snprintf(req->content_type, sizeof(req->content_type), "video/mp4");
|
||||
@@ -470,6 +473,7 @@ MessageList::MessageList(DbManager* db, AudioRecorder* recorder, QWidget *parent
|
||||
struct chat_msg_submit* req = (struct chat_msg_submit*)
|
||||
u_malloc(sizeof(struct chat_msg_submit) + textData.size());
|
||||
memset(req, 0, sizeof(*req));
|
||||
req->inst = gui_bridge_get_inst();
|
||||
snprintf(req->channel_id, sizeof(req->channel_id), "%s",
|
||||
m_currentChannelId.toUtf8().constData());
|
||||
snprintf(req->content_type, sizeof(req->content_type), "%s", ct.toUtf8().constData());
|
||||
@@ -669,6 +673,7 @@ void MessageList::saveChannelState() {
|
||||
if (total > 256) return;
|
||||
struct save_ui_state_arg* arg = (struct save_ui_state_arg*)u_malloc(sizeof(struct save_ui_state_arg));
|
||||
if (!arg) return;
|
||||
arg->inst = gui_bridge_get_inst();
|
||||
memcpy(arg->data, key.constData(), keyLen + 1);
|
||||
memcpy(arg->data + keyLen + 1, valStr.constData(), valLen + 1);
|
||||
gui_bridge_post_uasync_fn(chat_core_save_ui_state_trampoline, arg);
|
||||
@@ -762,6 +767,7 @@ void MessageList::updateReadPosition() {
|
||||
if (total > 256) return;
|
||||
struct save_ui_state_arg* arg = (struct save_ui_state_arg*)u_malloc(sizeof(struct save_ui_state_arg));
|
||||
if (!arg) return;
|
||||
arg->inst = gui_bridge_get_inst();
|
||||
memcpy(arg->data, key.constData(), keyLen + 1);
|
||||
memcpy(arg->data + keyLen + 1, valStr.constData(), valLen + 1);
|
||||
gui_bridge_post_uasync_fn(chat_core_save_ui_state_trampoline, arg);
|
||||
@@ -897,6 +903,7 @@ void MessageList::onMessageContextMenu(const QPoint& pos) {
|
||||
u_malloc(sizeof(struct attachment_dl_req));
|
||||
if (!req) return;
|
||||
memset(req, 0, sizeof(*req));
|
||||
req->inst = gui_bridge_get_inst();
|
||||
strncpy(req->channel_id, chId.toUtf8().constData(), sizeof(req->channel_id) - 1);
|
||||
req->msg_id = msgId;
|
||||
gui_bridge_post_uasync_fn(chat_core_attachment_download_trampoline, req);
|
||||
|
||||
@@ -223,8 +223,12 @@ void SettingsDialog::onSave() {
|
||||
|
||||
/* update name in uTun if changed */
|
||||
if (nameChanged) {
|
||||
char* name_copy = u_strdup(newName.toUtf8().constData());
|
||||
if (name_copy) gui_bridge_post_uasync_fn(chat_core_update_my_name_trampoline, name_copy);
|
||||
struct update_my_name_arg* arg = (struct update_my_name_arg*)u_calloc(1, sizeof(*arg));
|
||||
if (arg) {
|
||||
arg->inst = gui_bridge_get_inst();
|
||||
snprintf(arg->name, sizeof(arg->name), "%s", newName.toUtf8().constData());
|
||||
gui_bridge_post_uasync_fn(chat_core_update_my_name_trampoline, arg);
|
||||
}
|
||||
m_oldNickname = newName;
|
||||
}
|
||||
|
||||
@@ -273,9 +277,11 @@ void SettingsDialog::onSave() {
|
||||
size_t klen = strlen(key), vlen = (size_t)val.size();
|
||||
size_t total = klen + 1 + vlen + 1;
|
||||
if (total <= 256) {
|
||||
void* arg = u_malloc(total);
|
||||
memcpy(arg, key, klen + 1);
|
||||
memcpy((char*)arg + klen + 1, val.constData(), vlen + 1);
|
||||
struct save_ui_state_arg* arg = (struct save_ui_state_arg*)u_malloc(sizeof(struct save_ui_state_arg));
|
||||
if (!arg) return;
|
||||
arg->inst = gui_bridge_get_inst();
|
||||
memcpy(arg->data, key, klen + 1);
|
||||
memcpy(arg->data + klen + 1, val.constData(), vlen + 1);
|
||||
gui_bridge_post_uasync_fn(chat_core_save_ui_state_trampoline, arg);
|
||||
}
|
||||
}
|
||||
@@ -291,9 +297,11 @@ void SettingsDialog::onSave() {
|
||||
QByteArray val = QByteArray::number(v);
|
||||
size_t klen = strlen(key), vl = (size_t)val.size(), total = klen + 1 + vl + 1;
|
||||
if (total <= 256) {
|
||||
void* arg = u_malloc(total);
|
||||
memcpy(arg, key, klen + 1);
|
||||
memcpy((char*)arg + klen + 1, val.constData(), vl + 1);
|
||||
struct save_ui_state_arg* arg = (struct save_ui_state_arg*)u_malloc(sizeof(struct save_ui_state_arg));
|
||||
if (!arg) return;
|
||||
arg->inst = gui_bridge_get_inst();
|
||||
memcpy(arg->data, key, klen + 1);
|
||||
memcpy(arg->data + klen + 1, val.constData(), vl + 1);
|
||||
gui_bridge_post_uasync_fn(chat_core_save_ui_state_trampoline, arg);
|
||||
}
|
||||
if (!m_configPath.isEmpty()) {
|
||||
@@ -308,9 +316,11 @@ void SettingsDialog::onSave() {
|
||||
QByteArray val = QByteArray::number(v);
|
||||
size_t klen = strlen(key), vl = (size_t)val.size(), total = klen + 1 + vl + 1;
|
||||
if (total <= 256) {
|
||||
void* arg = u_malloc(total);
|
||||
memcpy(arg, key, klen + 1);
|
||||
memcpy((char*)arg + klen + 1, val.constData(), vl + 1);
|
||||
struct save_ui_state_arg* arg = (struct save_ui_state_arg*)u_malloc(sizeof(struct save_ui_state_arg));
|
||||
if (!arg) return;
|
||||
arg->inst = gui_bridge_get_inst();
|
||||
memcpy(arg->data, key, klen + 1);
|
||||
memcpy(arg->data + klen + 1, val.constData(), vl + 1);
|
||||
gui_bridge_post_uasync_fn(chat_core_save_ui_state_trampoline, arg);
|
||||
}
|
||||
if (!m_configPath.isEmpty()) {
|
||||
|
||||
@@ -156,9 +156,11 @@ void SoundSettingsPage::applyAndSave() {
|
||||
size_t klen = strlen(k), vlen = strlen(v);
|
||||
size_t total = klen + 1 + vlen + 1;
|
||||
if (total > 256) continue;
|
||||
void* arg = u_malloc(total);
|
||||
memcpy(arg, k, klen + 1);
|
||||
memcpy((char*)arg + klen + 1, v, vlen + 1);
|
||||
struct save_ui_state_arg* arg = (struct save_ui_state_arg*)u_malloc(sizeof(struct save_ui_state_arg));
|
||||
if (!arg) continue;
|
||||
arg->inst = gui_bridge_get_inst();
|
||||
memcpy(arg->data, k, klen + 1);
|
||||
memcpy(arg->data + klen + 1, v, vlen + 1);
|
||||
gui_bridge_post_uasync_fn(chat_core_save_ui_state_trampoline, arg);
|
||||
}
|
||||
}
|
||||
@@ -172,9 +174,11 @@ void SoundSettingsPage::applyAndSave() {
|
||||
size_t klen = strlen(keys[j]), vlen = vals[j].size();
|
||||
size_t total = klen + 1 + vlen + 1;
|
||||
if (total > 256) continue;
|
||||
void* arg = u_malloc(total);
|
||||
memcpy(arg, keys[j], klen + 1);
|
||||
memcpy((char*)arg + klen + 1, vals[j].constData(), vlen + 1);
|
||||
struct save_ui_state_arg* arg = (struct save_ui_state_arg*)u_malloc(sizeof(struct save_ui_state_arg));
|
||||
if (!arg) continue;
|
||||
arg->inst = gui_bridge_get_inst();
|
||||
memcpy(arg->data, keys[j], klen + 1);
|
||||
memcpy(arg->data + klen + 1, vals[j].constData(), vlen + 1);
|
||||
gui_bridge_post_uasync_fn(chat_core_save_ui_state_trampoline, arg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ void StatusPage::updateClock() {
|
||||
void StatusPage::refreshStatus() {
|
||||
updateClock();
|
||||
m_textEdit->setPlainText("Loading...");
|
||||
gui_bridge_post_uasync_fn(chat_core_collect_status_trampoline, NULL);
|
||||
gui_bridge_post_uasync_fn(chat_core_collect_status_trampoline, gui_bridge_get_inst());
|
||||
}
|
||||
|
||||
void StatusPage::onRefreshClicked() {
|
||||
|
||||
@@ -17,9 +17,11 @@ static void saveUiStateInt(const char* key, int val) {
|
||||
QByteArray v = QByteArray::number(val);
|
||||
size_t klen = strlen(key), vlen = (size_t)v.size(), total = klen + 1 + vlen + 1;
|
||||
if (total > 256) return;
|
||||
void* arg = u_malloc(total);
|
||||
memcpy(arg, key, klen + 1);
|
||||
memcpy((char*)arg + klen + 1, v.constData(), vlen + 1);
|
||||
struct save_ui_state_arg* arg = (struct save_ui_state_arg*)u_malloc(sizeof(struct save_ui_state_arg));
|
||||
if (!arg) return;
|
||||
arg->inst = gui_bridge_get_inst();
|
||||
memcpy(arg->data, key, klen + 1);
|
||||
memcpy(arg->data + klen + 1, v.constData(), vlen + 1);
|
||||
gui_bridge_post_uasync_fn(chat_core_save_ui_state_trampoline, arg);
|
||||
}
|
||||
|
||||
@@ -28,9 +30,11 @@ void postChatSetting(const QString& configPath, const char* name, int val) {
|
||||
QByteArray v = QByteArray::number(val);
|
||||
size_t nlen = strlen(name), vlen = (size_t)v.size(), total = nlen + 1 + vlen + 1;
|
||||
if (total > 256) return;
|
||||
void* arg = u_malloc(total);
|
||||
memcpy(arg, name, nlen + 1);
|
||||
memcpy((char*)arg + nlen + 1, v.constData(), vlen + 1);
|
||||
struct chat_setting_arg* arg = (struct chat_setting_arg*)u_malloc(sizeof(struct chat_setting_arg));
|
||||
if (!arg) return;
|
||||
arg->inst = gui_bridge_get_inst();
|
||||
memcpy(arg->data, name, nlen + 1);
|
||||
memcpy(arg->data + nlen + 1, v.constData(), vlen + 1);
|
||||
gui_bridge_post_uasync_fn(chat_core_set_setting_trampoline, arg);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ extern "C" {
|
||||
struct UASYNC;
|
||||
struct TOPO_GROUP;
|
||||
struct TOPO_GROUP_NODE;
|
||||
struct UTUN_INSTANCE;
|
||||
|
||||
/* ── Типы уведомлений uasync→GUI (fire-and-forget) ── */
|
||||
|
||||
@@ -53,6 +54,13 @@ void gui_bridge_init(void);
|
||||
/* Установить uasync (вызывается из UtunNode после создания ua) */
|
||||
void gui_bridge_set_uasync(struct UASYNC* ua);
|
||||
|
||||
/* Установить UTUN_INSTANCE (вызывается из UtunNode после создания instance).
|
||||
Читается GUI-потоком через gui_bridge_get_inst() для сборки trampoline-аргументов. */
|
||||
void gui_bridge_set_inst(struct UTUN_INSTANCE* inst);
|
||||
|
||||
/* Текущий UTUN_INSTANCE (NULL пока не создан). Безопасно из любого потока. */
|
||||
struct UTUN_INSTANCE* gui_bridge_get_inst(void);
|
||||
|
||||
/* uasync → GUI: уведомление (fire-and-forget, через Qt::QueuedConnection) */
|
||||
void gui_bridge_post(int event_type, const uint8_t* data, int data_len);
|
||||
|
||||
|
||||
@@ -49,6 +49,7 @@ static gui_admin_key_received_fn g_admin_key_received_cb = nullptr;
|
||||
static gui_invite_link_ready_fn g_invite_link_ready_cb = nullptr;
|
||||
static gui_invite_candidates_fn g_invite_candidates_cb = nullptr;
|
||||
static struct UASYNC* g_ua = nullptr;
|
||||
static struct UTUN_INSTANCE* g_inst = nullptr;
|
||||
|
||||
/* ── GuiBridgeReceiver implementation ── */
|
||||
|
||||
@@ -255,6 +256,14 @@ void gui_bridge_set_uasync(struct UASYNC* ua) {
|
||||
if (g_receiver) g_receiver->ua = ua;
|
||||
}
|
||||
|
||||
void gui_bridge_set_inst(struct UTUN_INSTANCE* inst) {
|
||||
g_inst = inst;
|
||||
}
|
||||
|
||||
struct UTUN_INSTANCE* gui_bridge_get_inst(void) {
|
||||
return g_inst;
|
||||
}
|
||||
|
||||
void gui_bridge_post(int event_type, const uint8_t* data, int data_len) {
|
||||
if (!g_receiver) { DEBUG_WARN(DEBUG_CATEGORY_DEBUG, "gui_bridge_post: g_receiver=NULL, dropping event %d", event_type); return; }
|
||||
|
||||
|
||||
@@ -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");
|
||||
|
||||
Reference in new issue
Block a user