完成框架目录和模块重构;新增核心、单例、工具、加密及框架 SDK;统一任务、相机和 RPC 接口,并增加离线检测、相机标定、备份恢复、版本管理、崩溃守护和心跳监控功能。
104 lines
3.0 KiB
C++
104 lines
3.0 KiB
C++
#ifndef PYFINS_RPC_FRAME_CODEC_H
|
|
#define PYFINS_RPC_FRAME_CODEC_H
|
|
|
|
#include <QByteArray>
|
|
#include <QList>
|
|
#include <QString>
|
|
#include <QtEndian>
|
|
|
|
// Shared binary protocol used by the pyRpcFins binary RPC server.
|
|
// [magic "ERPC":4][payload length:4][request id:4][command:2][payload]
|
|
class RpcFrameCodec
|
|
{
|
|
public:
|
|
static const quint32 Magic = 0x45525043; // "ERPC"
|
|
static const int HeaderSize = 14;
|
|
static const quint32 MaxPayloadSize = 64u * 1024u * 1024u;
|
|
|
|
enum CmdType {
|
|
CmdInit = 1,
|
|
CmdExecute = 2,
|
|
CmdIsConnected = 3,
|
|
RespOk = 0x0100,
|
|
RespError = 0x0101,
|
|
};
|
|
|
|
struct Frame {
|
|
quint32 id = 0;
|
|
quint16 cmd = 0;
|
|
QByteArray payload;
|
|
};
|
|
|
|
static QByteArray build(quint32 id, quint16 cmd, const QByteArray& payload)
|
|
{
|
|
QByteArray out;
|
|
out.resize(HeaderSize);
|
|
uchar* header = reinterpret_cast<uchar*>(out.data());
|
|
qToBigEndian<quint32>(Magic, header);
|
|
qToBigEndian<quint32>(static_cast<quint32>(payload.size()), header + 4);
|
|
qToBigEndian<quint32>(id, header + 8);
|
|
qToBigEndian<quint16>(cmd, header + 12);
|
|
out.append(payload);
|
|
return out;
|
|
}
|
|
|
|
static QByteArray requestPayload(const QString& module,
|
|
const QString& text = QString())
|
|
{
|
|
QByteArray payload = module.toUtf8();
|
|
if (!text.isEmpty()) {
|
|
payload.append('\n');
|
|
payload.append(text.toUtf8());
|
|
}
|
|
return payload;
|
|
}
|
|
|
|
void append(const QByteArray& chunk) { buffer_.append(chunk); }
|
|
void clear() { buffer_.clear(); }
|
|
|
|
QList<Frame> takeFrames()
|
|
{
|
|
QList<Frame> frames;
|
|
const QByteArray magicBytes("ERPC", 4);
|
|
for (;;) {
|
|
const int magicIndex = buffer_.indexOf(magicBytes);
|
|
if (magicIndex < 0) {
|
|
if (buffer_.size() > 3) {
|
|
buffer_ = buffer_.right(3);
|
|
}
|
|
break;
|
|
}
|
|
if (magicIndex > 0) {
|
|
buffer_.remove(0, magicIndex);
|
|
}
|
|
if (buffer_.size() < HeaderSize) {
|
|
break;
|
|
}
|
|
|
|
const uchar* header = reinterpret_cast<const uchar*>(buffer_.constData());
|
|
const quint32 payloadLength = qFromBigEndian<quint32>(header + 4);
|
|
if (payloadLength > MaxPayloadSize) {
|
|
buffer_.remove(0, 1);
|
|
continue;
|
|
}
|
|
const qint64 frameSize = static_cast<qint64>(HeaderSize) + payloadLength;
|
|
if (buffer_.size() < frameSize) {
|
|
break;
|
|
}
|
|
|
|
Frame frame;
|
|
frame.id = qFromBigEndian<quint32>(header + 8);
|
|
frame.cmd = qFromBigEndian<quint16>(header + 12);
|
|
frame.payload = buffer_.mid(HeaderSize, static_cast<int>(payloadLength));
|
|
buffer_.remove(0, static_cast<int>(frameSize));
|
|
frames.append(frame);
|
|
}
|
|
return frames;
|
|
}
|
|
|
|
private:
|
|
QByteArray buffer_;
|
|
};
|
|
|
|
#endif // PYFINS_RPC_FRAME_CODEC_H
|