You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

128 lines
3.8 KiB

#include "gui_bridge.h"
#include <QObject>
#include <QMetaObject>
#include <QByteArray>
#include <QDebug>
#include <cstring>
extern "C" {
#include "../../../lib/u_async.h"
#include "../../../lib/mem.h"
}
/* ── Внутренний объект-приёмник в GUI-потоке ── */
class GuiBridgeReceiver : public QObject {
Q_OBJECT
public:
void* ua = nullptr;
GuiBridgeReceiver(QObject* parent = nullptr) : QObject(parent) {}
Q_INVOKABLE void processPost(int eventType, QByteArray data);
};
static GuiBridgeReceiver* g_receiver = nullptr;
static gui_connect_result_fn g_connect_result_cb = nullptr;
static gui_msg_received_fn g_msg_received_cb = nullptr;
static struct UASYNC* g_ua = nullptr;
/* ── GuiBridgeReceiver implementation ── */
void GuiBridgeReceiver::processPost(int eventType, QByteArray data) {
const uint8_t* d = (const uint8_t*)data.constData();
int dlen = data.size();
switch (eventType) {
case GUI_EVT_MSG_RECEIVED:
if (dlen >= 2) {
uint8_t chLen = d[0];
if (dlen >= 1 + chLen) {
QString chId = QString::fromUtf8((const char*)d + 1, chLen);
qDebug("gui_bridge: MSG_RECEIVED ch=%s", qPrintable(chId));
if (g_msg_received_cb) g_msg_received_cb((const char*)d + 1, chLen);
} else {
qWarning("gui_bridge: MSG_RECEIVED invalid data length %d", dlen);
}
} else {
qWarning("gui_bridge: MSG_RECEIVED data too short %d", dlen);
}
break;
case GUI_EVT_CONNECT_RESULT:
if (dlen >= 12) {
uint64_t nodeId; int result;
memcpy(&nodeId, d, 8); memcpy(&result, d + 8, 4);
qDebug("gui_bridge: CONNECT_RESULT node=0x%016llx result=%d",
(unsigned long long)nodeId, result);
if (g_connect_result_cb) g_connect_result_cb(nodeId, result);
} else {
qWarning("gui_bridge: CONNECT_RESULT data too short %d", dlen);
}
break;
case GUI_EVT_NEW_PEER:
if (dlen >= 8) {
uint64_t nodeId; memcpy(&nodeId, d, 8);
qDebug("gui_bridge: NEW_PEER node=0x%016llx", (unsigned long long)nodeId);
} else {
qWarning("gui_bridge: NEW_PEER data too short %d", dlen);
}
break;
case GUI_EVT_CHANNEL_UPDATED:
if (dlen >= 2) {
uint8_t chLen = d[0];
if (dlen >= 1 + chLen) {
QString chId = QString::fromUtf8((const char*)d + 1, chLen);
qDebug("gui_bridge: CHANNEL_UPDATED ch=%s", qPrintable(chId));
}
} else {
qWarning("gui_bridge: CHANNEL_UPDATED data too short %d", dlen);
}
break;
default:
qWarning("gui_bridge: unknown event type %d", eventType);
break;
}
}
/* ── C API ── */
extern "C" {
void gui_bridge_init(void) {
g_receiver = new GuiBridgeReceiver();
g_receiver->ua = g_ua;
}
void gui_bridge_set_uasync(struct UASYNC* ua) {
g_ua = ua;
if (g_receiver) g_receiver->ua = ua;
}
void gui_bridge_post(int event_type, const uint8_t* data, int data_len) {
if (!g_receiver) return;
QByteArray d;
if (data_len > 0) d = QByteArray((const char*)data, data_len);
QMetaObject::invokeMethod(g_receiver, "processPost",
Qt::QueuedConnection,
Q_ARG(int, event_type),
Q_ARG(QByteArray, d));
}
void gui_bridge_post_uasync_fn(void (*fn)(void*), void* arg) {
if (g_ua && fn) uasync_post(g_ua, fn, arg);
}
void gui_bridge_set_connect_result_cb(gui_connect_result_fn cb) {
g_connect_result_cb = cb;
}
void gui_bridge_set_msg_received_cb(gui_msg_received_fn cb) {
g_msg_received_cb = cb;
}
} /* extern "C" */
#include "gui_bridge_impl.moc"