SmartLockerTools/Analyser/ModuleCommunication.h
2024-09-25 17:09:00 +08:00

254 lines
7.9 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#ifndef MODULECOMMUNICATION_H
#define MODULECOMMUNICATION_H
#include "DataStructure.h"
#include <QObject>
#include <QQmlEngine>
#include <QSerialPort>
#include <memory>
class ModuleCommunication : public QObject {
Q_OBJECT
QML_ELEMENT
QML_UNCREATABLE("Only created in C++...")
static constexpr uint32_t UsernameSize = 32;
static constexpr uint32_t VersionSize = 32;
static constexpr const char *Separator = "----------";
Q_PROPERTY(MessageId currentMessageId READ currentMessageId NOTIFY currentMessageIdChanged)
Q_PROPERTY(QString verison MEMBER m_verison NOTIFY verisonChanged)
Q_PROPERTY(int otaVerison MEMBER m_otaVerison NOTIFY verisonChanged)
public:
constexpr static uint16_t VendorIdentifier = 0x3346;
constexpr static uint16_t ProductIdentifier = 0x0001;
constexpr static uint16_t InvalidUserId = std::numeric_limits<uint16_t>::max();
enum MessageId : uint8_t {
Reply = 0,
Note = 0x01,
Reset = 0x10,
GetCurrentStatus = 0x11,
Verify = 0x12,
VerifyExtended = 0x16,
EnrollSingle = 0x1D,
EnrollExtended = 0x1E,
GetImage = 0x1F, // 获取图片数据通过VerifyExtended或EnrollExtended保存的
DeleteUser = 0x20,
DeleteAll = 0x21,
GetVersion = 0x30,
StartOta = 0x40, // 模组进入boot模式进行ota升级
EnableDebug = 0x82,
GetUniqueID = 0xAC,
UploadImageInfo = 0xF6,
UploadImageData = 0xF7,
Idle = 0xFF,
};
Q_ENUM(MessageId)
enum class NoteId : uint8_t {
Ready = 0x00,
PalmState = 0x01,
UnknownError = 0x02,
DebugInfo = 0x55,
NoAliveImage = 0x56,
DeviceError = 0xF0, // 系统设备出现的错误,例如 QSerialPort
InteractWarning,
};
enum PalmState {
NoPalm = 1,
TooFar = 6,
NeedMoveToCenter = 15,
ManyPalm = 101, // 太多掌静脉
NoAlive = 122,
};
enum MessageStatus : uint8_t {
Success = 0,
Rejected = 1,
Aborted = 2,
Failed4Camera = 4,
Failed4UnknownReason = 5,
Failed4InvalidParam = 6,
Failed4NoMemory = 7,
Failed4UnknownUser = 8,
Failed4MaxUser = 9,
Failed4PalmEnrolled = 10,
Failed4LivenessCheck = 12,
Failed4Timeout = 13,
Failed4Authorization = 14,
Failed4ReadFile = 19,
Failed4WriteFile = 20,
Failed4NoEncrypt = 21,
PalmNotDetected = 23,
Needmore = 25,
};
#pragma pack(1)
struct VerifyRequest {
uint8_t save_image;
uint8_t timeout; // timeout, unit second, default 10s
};
struct PalmStateNote {
uint16_t state;
// position
uint16_t left; // in pixel
uint16_t top;
uint16_t right;
uint16_t bottom;
};
struct EnrollRequest {
uint8_t username[32];
uint8_t strictMode = 0;
uint8_t excludeMode = 0; // 掌静脉库里面是否已经存在 0:不进行验证 1:只进行比对 2:如果存在,则现在不予录入
uint8_t skipSave = 0;
uint8_t timeout;
uint8_t reserved[4];
};
struct EnrollReply {
uint16_t userid;
uint8_t operation;
};
struct PalmVeinInformation {
uint16_t x1;
uint16_t y1;
uint16_t x2;
uint16_t y2;
uint16_t detectionProbability;
uint16_t quality;
};
struct EnrollExtendedReply {
uint16_t userid;
uint16_t imageWidth;
uint16_t imageHeight;
uint8_t imageFormat; // 0: 只有Y分量,灰度图
uint8_t md5[16];
uint8_t enrolledUsername[32];
uint16_t enrolledId; // 掌静脉库里已经存在的id
PalmVeinInformation palmVeinInformation;
uint8_t reserved[4];
};
struct ImageSliceRequest {
uint32_t offset;
uint32_t size;
};
struct ImageSliceReply {
uint32_t size;
uint8_t data[0];
};
struct VerifyReply {
uint16_t userid;
uint8_t username[UsernameSize]; // 32Bytes
uint16_t elapsed; // 此时识别耗时时间
};
struct VerifyExtendReply : public VerifyReply {
uint16_t image_width;
uint16_t image_height;
uint8_t image_format; // 0: 只有Y分量,灰度图
uint8_t md5[16];
PalmVeinInformation palmVeinInformation;
};
struct UploadImageInformation {
uint8_t operation; // 0:图片录入掌静脉
uint8_t format; // 0: 灰度图(纯Y分量)
uint16_t width;
uint16_t height;
uint32_t size;
uint8_t md5[16]; // 图片内容 md5 值
char username[32];
};
struct UploadImageDataSlice {
uint32_t offset;
uint32_t size;
uint8_t reserved[4]; // 预留
uint8_t data[0];
};
struct UploadImageReply : public EnrollReply {};
struct UploadImageVerifyReply : public UploadImageReply {
VerifyReply result;
};
struct ModuleVersion {
char version[VersionSize];
uint32_t otaVersion;
};
struct ModuleId {
char id[32];
};
#pragma pack()
explicit ModuleCommunication(QObject *parent = nullptr);
bool open(const QString &portName, int baudRate);
void verify(uint8_t timeout);
void verifyExtended(bool captureImage, uint8_t timeout);
Q_INVOKABLE void reset();
void enroll(const std::string &username, bool strictMode, uint8_t excludeMode, bool persistence, uint8_t timeout);
void enrollExtended(const std::string &username, bool strictMode, uint8_t excludeMode, bool persistence,
uint8_t timeout);
Q_INVOKABLE void deleteUser(uint16_t userid);
Q_INVOKABLE void deleteAll();
Q_INVOKABLE void requestUniqueId();
Q_INVOKABLE void requestVersion();
void requestEnrolledImage(uint32_t offset, uint32_t size);
void uploadImageInfo(const UploadImageInformation &info);
void uploadImageData(uint32_t offset, const uint8_t *data, uint32_t size);
Q_INVOKABLE void requestCurrentStatus();
Q_INVOKABLE void setDebugEnabled(bool enabled);
void startOta();
MessageId currentMessageId() const;
static std::string protocolDataFormatString(const uint8_t *data, int size);
signals:
/**
* @brief newVerifyResult
* @param userid
* @param username
* @param elapsed ms毫秒
*/
void newVerifyResult(uint16_t userid, const QString &username, uint16_t elapsed);
void newEnrollResult(uint16_t userid);
void newPalmFeature(const PalmFeature &feature);
void newImageInfo(MessageId id, uint32_t size, const uint8_t *md5);
void newImageSliceData(const std::vector<uint8_t> &data);
void errorOccurred(NoteId note, const QString &error, const QString &detailMessage = "");
void commandStarted(ModuleCommunication::MessageId messageId);
void commandFinished(MessageId messageId, MessageStatus status);
void currentMessageIdChanged();
void verisonChanged();
protected:
void processPackage(const uint8_t *data, uint16_t size);
void onReadyRead();
void onErrorOccurred(QSerialPort::SerialPortError error);
std::pair<uint8_t *, uint32_t> generateFrame(MessageId command, const uint8_t *data = nullptr, uint16_t size = 0);
void setCurrentMessageIdStatus(ModuleCommunication::MessageId messageId);
private:
std::shared_ptr<QSerialPort> m_serialPort;
QByteArray m_receivedBuffer;
MessageId m_currentMessageId = ModuleCommunication::Idle;
QString m_verison;
int m_otaVerison;
};
namespace std {
std::ostream &operator<<(std::ostream &stream, const ModuleCommunication::PalmState &element);
} // namespace std
#endif // MODULECOMMUNICATION_H