SmartLockerTools/Analyser/ModuleCommunication.h
2024-07-23 20:03:19 +08:00

186 lines
5.6 KiB
C++

#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
static constexpr uint32_t UsernameSize = 32;
static constexpr const char *Separator = "----------";
Q_PROPERTY(MessageId currentMessageId READ currentMessageId NOTIFY currentMessageIdChanged)
public:
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,
EnrollSingle = 0x1D,
EnrollExtended = 0x1E,
GetEnrolledImage = 0x1F,
DeleteUser = 0x20,
DeleteAll = 0x21,
GetUniqueID = 0xAC,
UploadImageInfo = 0xF6,
UploadImageData = 0xF7,
Idle = 0xFF,
};
Q_ENUM(MessageId)
enum NoteId : uint8_t {
Ready = 0x00,
PalmState = 0x01,
UnknownError = 0x02,
};
enum MessageStatus : uint8_t {
Success = 0,
Rejected = 1,
Aborted = 2,
Failed4Camera = 4,
Failed4UnknownReason = 5,
Failed4InvalidParam = 6,
Failed4NoMemory = 7,
Failed4UnknownUser = 8,
Failed4MaxUser = 9,
Failed4FaceEnrolled = 10,
Failed4LivenessCheck = 12,
Failed4Timeout = 13,
Failed4Authorization = 14,
Failed4ReadFile = 19,
Failed4WriteFile = 20,
Failed4NoEncrypt = 21,
Needmore = 25,
};
#pragma pack(1)
struct VerifyInfo {
uint8_t powerDownRightAway; // power down right away after verifying
uint8_t timeout; // timeout, unit second, default 10s
};
struct VerifyNoteInfo {
int16_t state; // corresponding to PALM_STATE_*
// position
int16_t left; // in pixel
int16_t top;
int16_t right;
int16_t bottom;
// pose
int16_t yaw; // up and down in vertical orientation
int16_t pitch; // right or left turned in horizontal orientation
int16_t roll; // slope
};
struct EnrollData {
uint8_t username[32];
uint8_t skipSave = 0;
uint8_t timeout;
};
struct EnrollDataReply {
uint16_t userid;
uint8_t face_direction; // depleted, user ignore this field
};
struct EnrollExtendedReply {
uint16_t userid;
uint16_t image_width;
uint16_t image_height;
uint8_t image_format; // 0: 只有Y分量,灰度图
uint8_t md5[16];
};
struct ImageSliceRequest {
uint32_t offset;
uint32_t size;
};
struct ImageSliceReply {
uint32_t size;
uint8_t data[0];
};
struct VerifyDataReply {
uint16_t userid;
uint8_t username[UsernameSize]; // 32Bytes
uint16_t elapsed; // 此时识别耗时时间
};
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 ModuleId {
char id[32];
};
#pragma pack()
explicit ModuleCommunication(QObject *parent = nullptr);
bool open(const QString &portName, int baudRate);
Q_INVOKABLE void verify(uint8_t timeout);
Q_INVOKABLE void reset();
void enroll(const std::string &username, bool persistence, uint8_t timeout);
void enrollExtended(const std::string &username, bool persistence, uint8_t timeout);
Q_INVOKABLE void deleteUser(uint16_t userid);
Q_INVOKABLE void deleteAll();
Q_INVOKABLE void requestUniqueId();
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();
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 newPalmFeature(const PalmFeature &feature);
void newEnrolledImageInfo(uint32_t size, const uint8_t *md5);
void newImageSliceData(const std::vector<uint8_t> &data);
void errorOccurred(const QString &error);
void commandStarted(ModuleCommunication::MessageId messageId);
void commandFinished(MessageId messageId, MessageStatus status);
void currentMessageIdChanged();
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;
};
#endif // MODULECOMMUNICATION_H