#ifndef MODULECOMMUNICATION_H #define MODULECOMMUNICATION_H #include "DataStructure.h" #include #include #include #include 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::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 &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 generateFrame(MessageId command, const uint8_t *data = nullptr, uint16_t size = 0); void setCurrentMessageIdStatus(ModuleCommunication::MessageId messageId); private: std::shared_ptr m_serialPort; QByteArray m_receivedBuffer; MessageId m_currentMessageId = ModuleCommunication::Idle; }; #endif // MODULECOMMUNICATION_H