SmartLockerTools/Analyser/ModuleCommunication.h
2024-08-12 10:20:37 +08:00

203 lines
6.2 KiB
C++
Raw 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
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,
VerifyExtended = 0x16,
EnrollSingle = 0x1D,
EnrollExtended = 0x1E,
GetImage = 0x1F, // 获取图片数据通过VerifyExtended或EnrollExtended保存的
DeleteUser = 0x20,
DeleteAll = 0x21,
StartOta = 0x40, // 模组进入boot模式进行ota升级
EnableDebug = 0x82,
GetUniqueID = 0xAC,
UploadImageInfo = 0xF6,
UploadImageData = 0xF7,
Idle = 0xFF,
};
Q_ENUM(MessageId)
enum NoteId : uint8_t {
Ready = 0x00,
PalmState = 0x01,
UnknownError = 0x02,
DebugInfo = 0x55,
NoAliveImage = 0x56,
};
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,
PalmNotDetected = 23,
Needmore = 25,
};
#pragma pack(1)
struct VerifyRequest {
uint8_t save_image;
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 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];
};
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);
void verify(uint8_t timeout);
void verifyExtended(bool captureImage, 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();
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(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