SmartLockerTools/Analyser/ModuleCommunication.h

251 lines
7.5 KiB
C
Raw Normal View History

2024-05-21 21:09:55 +08:00
#ifndef MODULECOMMUNICATION_H
#define MODULECOMMUNICATION_H
2024-05-24 10:23:05 +08:00
#include "DataStructure.h"
2024-05-21 21:09:55 +08:00
#include <QObject>
#include <QQmlEngine>
2024-06-13 15:41:40 +08:00
#include <QSerialPort>
2024-05-21 21:09:55 +08:00
#include <memory>
class ModuleCommunication : public QObject {
Q_OBJECT
QML_ELEMENT
2024-08-31 11:37:20 +08:00
QML_UNCREATABLE("Only created in C++...")
2024-05-21 21:09:55 +08:00
static constexpr uint32_t UsernameSize = 32;
2024-08-16 11:34:21 +08:00
static constexpr uint32_t VersionSize = 32;
2024-05-21 21:09:55 +08:00
static constexpr const char *Separator = "----------";
Q_PROPERTY(MessageId currentMessageId READ currentMessageId NOTIFY currentMessageIdChanged)
2024-08-16 11:34:21 +08:00
Q_PROPERTY(QString verison MEMBER m_verison NOTIFY verisonChanged)
Q_PROPERTY(int otaVerison MEMBER m_otaVerison NOTIFY verisonChanged)
2024-05-21 21:09:55 +08:00
public:
2024-09-05 16:36:54 +08:00
constexpr static uint16_t VendorIdentifier = 0x3346;
constexpr static uint16_t ProductIdentifier = 0x0001;
2024-10-12 17:06:50 +08:00
constexpr static uint16_t MaxUserCount = 4000;
2024-06-13 15:41:40 +08:00
constexpr static uint16_t InvalidUserId = std::numeric_limits<uint16_t>::max();
2024-05-21 21:09:55 +08:00
enum MessageId : uint8_t {
Reply = 0,
Note = 0x01,
2024-05-23 19:58:36 +08:00
Reset = 0x10,
2024-06-21 15:11:18 +08:00
GetCurrentStatus = 0x11,
2024-05-21 21:09:55 +08:00
Verify = 0x12,
2024-07-31 16:08:38 +08:00
VerifyExtended = 0x16,
2024-05-21 21:09:55 +08:00
EnrollSingle = 0x1D,
EnrollExtended = 0x1E,
2024-07-31 16:08:38 +08:00
GetImage = 0x1F, // 获取图片数据通过VerifyExtended或EnrollExtended保存的
2024-05-21 21:09:55 +08:00
DeleteUser = 0x20,
DeleteAll = 0x21,
2024-08-16 11:34:21 +08:00
GetVersion = 0x30,
2024-08-05 17:42:27 +08:00
StartOta = 0x40, // 模组进入boot模式进行ota升级
2024-07-31 16:08:38 +08:00
EnableDebug = 0x82,
GetUniqueID = 0xAC,
2024-06-20 21:28:30 +08:00
UploadImageInfo = 0xF6,
UploadImageData = 0xF7,
2024-06-13 15:41:40 +08:00
Idle = 0xFF,
2024-05-21 21:09:55 +08:00
};
Q_ENUM(MessageId)
2024-05-21 21:09:55 +08:00
2024-09-04 19:23:34 +08:00
enum class NoteId : uint8_t {
2024-05-21 21:09:55 +08:00
Ready = 0x00,
2024-06-05 12:13:10 +08:00
PalmState = 0x01,
UnknownError = 0x02,
2024-07-31 16:08:38 +08:00
DebugInfo = 0x55,
2024-08-05 17:42:27 +08:00
NoAliveImage = 0x56,
2024-09-05 16:36:54 +08:00
DeviceError = 0xF0, // 系统设备出现的错误,例如 QSerialPort
InteractWarning,
2024-05-21 21:09:55 +08:00
};
2024-09-04 19:23:34 +08:00
enum PalmState {
NoPalm = 1,
2024-09-23 19:19:10 +08:00
TooFar = 6,
2024-09-04 19:23:34 +08:00
NeedMoveToCenter = 15,
2024-09-25 17:09:00 +08:00
ManyPalm = 101, // 太多掌静脉
2024-09-04 19:23:34 +08:00
NoAlive = 122,
};
2024-05-21 21:09:55 +08:00
enum MessageStatus : uint8_t {
Success = 0,
Rejected = 1,
Aborted = 2,
Failed4Camera = 4,
Failed4UnknownReason = 5,
Failed4InvalidParam = 6,
Failed4NoMemory = 7,
Failed4UnknownUser = 8,
Failed4MaxUser = 9,
2024-09-11 15:45:19 +08:00
Failed4PalmEnrolled = 10,
2024-05-21 21:09:55 +08:00
Failed4LivenessCheck = 12,
Failed4Timeout = 13,
Failed4Authorization = 14,
Failed4ReadFile = 19,
Failed4WriteFile = 20,
Failed4NoEncrypt = 21,
PalmNotDetected = 23,
Needmore = 25,
2024-05-21 21:09:55 +08:00
};
#pragma pack(1)
2024-07-31 16:08:38 +08:00
struct VerifyRequest {
uint8_t reserved;
uint8_t timeout;
2024-05-21 21:09:55 +08:00
};
2024-09-04 19:23:34 +08:00
struct PalmStateNote {
uint16_t state;
2024-05-21 21:09:55 +08:00
// position
2024-09-04 19:23:34 +08:00
uint16_t left; // in pixel
uint16_t top;
uint16_t right;
uint16_t bottom;
2024-05-21 21:09:55 +08:00
};
2024-09-11 15:45:19 +08:00
struct EnrollRequest {
2024-05-21 21:09:55 +08:00
uint8_t username[32];
uint8_t reserved1[3];
2024-05-21 21:09:55 +08:00
uint8_t timeout;
uint8_t reserved2[4];
2024-05-21 21:09:55 +08:00
};
2024-08-16 19:05:50 +08:00
struct EnrollReply {
2024-05-21 21:09:55 +08:00
uint16_t userid;
uint8_t reserved;
2024-05-21 21:09:55 +08:00
};
2024-09-25 17:09:00 +08:00
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;
2024-09-11 15:45:19 +08:00
uint16_t imageWidth;
uint16_t imageHeight;
uint8_t imageFormat; // 0: 只有Y分量,灰度图
2024-06-05 12:13:10 +08:00
uint8_t md5[16];
2024-09-11 15:45:19 +08:00
uint8_t enrolledUsername[32];
uint16_t enrolledId; // 掌静脉库里已经存在的id
2024-09-25 17:09:00 +08:00
PalmVeinInformation palmVeinInformation;
2024-09-11 15:45:19 +08:00
uint8_t reserved[4];
2024-06-05 12:13:10 +08:00
};
struct ImageSliceRequest {
uint32_t offset;
uint32_t size;
};
struct ImageSliceReply {
uint32_t size;
uint8_t data[0];
};
2024-07-31 16:08:38 +08:00
struct VerifyReply {
2024-05-21 21:09:55 +08:00
uint16_t userid;
2024-07-01 15:07:13 +08:00
uint8_t username[UsernameSize]; // 32Bytes
uint8_t reserved[2];
2024-05-21 21:09:55 +08:00
};
2024-07-31 16:08:38 +08:00
struct VerifyExtendReply : public VerifyReply {
uint16_t image_width;
uint16_t image_height;
uint8_t image_format; // 0: 只有Y分量,灰度图
uint8_t md5[16];
2024-09-25 17:09:00 +08:00
PalmVeinInformation palmVeinInformation;
2024-07-31 16:08:38 +08:00
};
2024-06-20 21:28:30 +08:00
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];
};
2024-08-16 19:05:50 +08:00
struct UploadImageReply : public EnrollReply {};
struct UploadImageVerifyReply : public UploadImageReply {
VerifyReply result;
};
2024-08-16 11:34:21 +08:00
struct ModuleVersion {
char version[VersionSize];
uint32_t otaVersion;
};
struct ModuleId {
char id[32];
2024-10-12 17:06:50 +08:00
uint8_t userids[512]; // bit位
};
2024-05-21 21:09:55 +08:00
#pragma pack()
explicit ModuleCommunication(QObject *parent = nullptr);
2024-06-13 15:41:40 +08:00
bool open(const QString &portName, int baudRate);
2024-07-31 16:08:38 +08:00
void verify(uint8_t timeout);
2024-06-13 15:41:40 +08:00
Q_INVOKABLE void reset();
2024-05-21 21:09:55 +08:00
void enroll(const std::string &username, uint8_t timeout);
2024-06-13 15:41:40 +08:00
Q_INVOKABLE void deleteUser(uint16_t userid);
Q_INVOKABLE void deleteAll();
Q_INVOKABLE void requestUniqueId();
2024-08-16 11:34:21 +08:00
Q_INVOKABLE void requestVersion();
2024-06-05 12:13:10 +08:00
void requestEnrolledImage(uint32_t offset, uint32_t size);
2024-05-21 21:09:55 +08:00
2024-06-20 21:28:30 +08:00
void uploadImageInfo(const UploadImageInformation &info);
void uploadImageData(uint32_t offset, const uint8_t *data, uint32_t size);
2024-06-21 15:11:18 +08:00
Q_INVOKABLE void requestCurrentStatus();
2024-07-31 16:08:38 +08:00
Q_INVOKABLE void setDebugEnabled(bool enabled);
2024-08-05 17:42:27 +08:00
void startOta();
2024-06-13 15:41:40 +08:00
2024-06-20 21:28:30 +08:00
MessageId currentMessageId() const;
static std::string protocolDataFormatString(const uint8_t *data, int size);
signals:
2024-07-01 15:07:13 +08:00
/**
* @brief newVerifyResult
* @param userid
* @param username
* @param elapsed ms毫秒
*/
void newVerifyResult(uint16_t userid, const QString &username);
2024-08-07 11:45:13 +08:00
void newEnrollResult(uint16_t userid);
void newPalmFeature(const PalmFeature &feature);
2024-07-31 16:08:38 +08:00
void newImageInfo(MessageId id, uint32_t size, const uint8_t *md5);
2024-06-05 12:13:10 +08:00
void newImageSliceData(const std::vector<uint8_t> &data);
2024-09-05 16:36:54 +08:00
void errorOccurred(NoteId note, const QString &error, const QString &detailMessage = "");
2024-06-13 15:41:40 +08:00
void commandStarted(ModuleCommunication::MessageId messageId);
void commandFinished(MessageId messageId, MessageStatus status);
void currentMessageIdChanged();
2024-08-16 11:34:21 +08:00
void verisonChanged();
2024-05-22 18:03:11 +08:00
2024-05-21 21:09:55 +08:00
protected:
2024-05-22 18:03:11 +08:00
void processPackage(const uint8_t *data, uint16_t size);
2024-05-21 21:09:55 +08:00
void onReadyRead();
2024-06-13 15:41:40 +08:00
void onErrorOccurred(QSerialPort::SerialPortError error);
2024-05-21 21:09:55 +08:00
std::pair<uint8_t *, uint32_t> generateFrame(MessageId command, const uint8_t *data = nullptr, uint16_t size = 0);
void setCurrentMessageIdStatus(ModuleCommunication::MessageId messageId);
2024-06-20 21:28:30 +08:00
2024-05-21 21:09:55 +08:00
private:
std::shared_ptr<QSerialPort> m_serialPort;
2024-05-22 18:03:11 +08:00
QByteArray m_receivedBuffer;
2024-06-13 15:41:40 +08:00
MessageId m_currentMessageId = ModuleCommunication::Idle;
2024-08-16 11:34:21 +08:00
QString m_verison;
int m_otaVerison;
2024-05-21 21:09:55 +08:00
};
2024-09-25 17:09:00 +08:00
namespace std {
std::ostream &operator<<(std::ostream &stream, const ModuleCommunication::PalmState &element);
} // namespace std
2024-05-21 21:09:55 +08:00
#endif // MODULECOMMUNICATION_H