实现通过cdc进行升级。
This commit is contained in:
parent
5009528f3a
commit
c6554704ac
@ -2,6 +2,7 @@
|
||||
#include "AsyncEvent.h"
|
||||
#include "BoostLog.h"
|
||||
#include "CategoryLogSinkBackend.h"
|
||||
#include "CdcUpdater.h"
|
||||
#include "Configuration.h"
|
||||
#include "Database.h"
|
||||
#include "DateTime.h"
|
||||
@ -300,6 +301,9 @@ void Application::onNewImageInfo(ModuleCommunication::MessageId messageId, uint3
|
||||
m_communication->requestEnrolledImage(0, ImageSliceSize);
|
||||
m_palmYImageBuffer.clear();
|
||||
m_startUploadTime = system_clock::now();
|
||||
if (messageId == ModuleCommunication::Note) {
|
||||
emit newStatusTip(Error, "活体未通过照片");
|
||||
}
|
||||
}
|
||||
|
||||
void Application::onNewImageSliceData(const std::vector<uint8_t> &data) {
|
||||
@ -312,6 +316,9 @@ void Application::onNewImageSliceData(const std::vector<uint8_t> &data) {
|
||||
} else {
|
||||
auto username = m_palmUsername.toStdString();
|
||||
auto way = (m_palmImageId == ModuleCommunication::VerifyExtended) ? "verify" : "enroll";
|
||||
if (m_palmImageId == ModuleCommunication::Note) {
|
||||
way = "no_alive";
|
||||
}
|
||||
LOG(info) << "request finished, username: " << username
|
||||
<< ", elapsed: " << duration_cast<milliseconds>(system_clock::now() - m_startUploadTime);
|
||||
std::ostringstream oss;
|
||||
@ -382,3 +389,20 @@ void Application::onVerifyTimeout() {
|
||||
m_communication->verify(120);
|
||||
}
|
||||
}
|
||||
|
||||
void Application::startOta(const QString &path) {
|
||||
LOG(info) << "start ota, ota path: " << path.toStdString();
|
||||
m_updater = std::make_shared<CdcUpdater>();
|
||||
connect(m_updater.get(), &CdcUpdater::deviceDiscovered, this, &Application::onCdcDeviceDiscovered);
|
||||
connect(m_updater.get(), &CdcUpdater::updateFinished, this, &Application::updateFinished);
|
||||
connect(m_updater.get(), &CdcUpdater::progressChanged, this, &Application::otaProgressChanged);
|
||||
connect(m_updater.get(), &CdcUpdater::message, this, &Application::otaMessage);
|
||||
|
||||
m_communication->startOta();
|
||||
m_updater->start(path);
|
||||
}
|
||||
|
||||
void Application::onCdcDeviceDiscovered(const QSerialPortInfo &info) {
|
||||
auto status = m_updater->open(info);
|
||||
LOG(info) << "open cdc port: " << info.portName().toStdString() << ", status: " << status;
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ class Database;
|
||||
class VideoPlayer;
|
||||
class VideoFrameProvider;
|
||||
class QTimer;
|
||||
class CdcUpdater;
|
||||
|
||||
class Application : public QObject {
|
||||
Q_OBJECT
|
||||
@ -44,6 +45,7 @@ public:
|
||||
Q_INVOKABLE bool openUVC(const QString &deviceName);
|
||||
Q_INVOKABLE void close();
|
||||
Q_INVOKABLE void closeUVC();
|
||||
Q_INVOKABLE void startOta(const QString &path);
|
||||
Q_INVOKABLE void verify(bool captureImage, uint8_t timeout);
|
||||
Q_INVOKABLE void enroll(const QString &username, bool persistence, uint8_t timeout);
|
||||
Q_INVOKABLE void enrollExtended(const QString &username, bool persistence, uint8_t timeout);
|
||||
@ -69,6 +71,9 @@ signals:
|
||||
void newVideoFrame();
|
||||
void newLog(const QString &log);
|
||||
void newStatusTip(TipType type, const QString &tip);
|
||||
void updateFinished();
|
||||
void otaMessage(const QString &text);
|
||||
void otaProgressChanged(int32_t progress);
|
||||
|
||||
protected:
|
||||
Application(int &argc, char **argv);
|
||||
@ -80,10 +85,13 @@ protected:
|
||||
void onCommandStarted(ModuleCommunication::MessageId messageId);
|
||||
void onCommandFinished(ModuleCommunication::MessageId messageId, ModuleCommunication::MessageStatus status);
|
||||
void onVerifyTimeout();
|
||||
void onCdcDeviceDiscovered(const QSerialPortInfo &info);
|
||||
void onUpdateFinished();
|
||||
|
||||
private:
|
||||
std::shared_ptr<QGuiApplication> m_app;
|
||||
std::shared_ptr<ModuleCommunication> m_communication;
|
||||
std::shared_ptr<CdcUpdater> m_updater;
|
||||
std::shared_ptr<Database> m_database;
|
||||
|
||||
bool m_persistenceMode = true; // 模组持续识别
|
||||
|
@ -29,6 +29,7 @@ qt_add_qml_module(Analyser
|
||||
qml/ConnectionItem.qml
|
||||
qml/OperationItem.qml
|
||||
qml/StatusTip.qml
|
||||
qml/OtaPage.qml
|
||||
RESOURCES
|
||||
resources/successfull.svg
|
||||
resources/warning.svg
|
||||
|
@ -159,6 +159,11 @@ void ModuleCommunication::setDebugEnabled(bool enabled) {
|
||||
m_serialPort->write(reinterpret_cast<const char *>(frameData), frameSize);
|
||||
}
|
||||
|
||||
void ModuleCommunication::startOta() {
|
||||
auto [frameData, frameSize] = generateFrame(StartOta);
|
||||
m_serialPort->write(reinterpret_cast<const char *>(frameData), frameSize);
|
||||
}
|
||||
|
||||
void ModuleCommunication::requestUniqueId() {
|
||||
auto [frameData, frameSize] = generateFrame(GetUniqueID);
|
||||
m_serialPort->write(reinterpret_cast<const char *>(frameData), frameSize);
|
||||
@ -346,6 +351,11 @@ void ModuleCommunication::processPackage(const uint8_t *data, uint16_t size) {
|
||||
LOG_CAT(info, GUI) << "模组日志: " << message;
|
||||
break;
|
||||
}
|
||||
case NoAliveImage: {
|
||||
LOG(info) << "no alive image";
|
||||
emit newImageInfo(Note, 600 * 800, nullptr);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
LOG(warning) << "unknown note command: 0x" << (static_cast<int>(noteId) & 0xff)
|
||||
<< ", data: " << protocolDataFormatString(data, size);
|
||||
|
@ -28,6 +28,7 @@ public:
|
||||
GetImage = 0x1F, // 获取图片数据,通过VerifyExtended或EnrollExtended保存的
|
||||
DeleteUser = 0x20,
|
||||
DeleteAll = 0x21,
|
||||
StartOta = 0x40, // 模组进入boot模式进行ota升级
|
||||
EnableDebug = 0x82,
|
||||
GetUniqueID = 0xAC,
|
||||
UploadImageInfo = 0xF6,
|
||||
@ -41,6 +42,7 @@ public:
|
||||
PalmState = 0x01,
|
||||
UnknownError = 0x02,
|
||||
DebugInfo = 0x55,
|
||||
NoAliveImage = 0x56,
|
||||
};
|
||||
enum MessageStatus : uint8_t {
|
||||
Success = 0,
|
||||
@ -161,6 +163,7 @@ public:
|
||||
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);
|
||||
|
@ -70,7 +70,6 @@ void VideoPlayer::run() {
|
||||
if (status == 0) {
|
||||
QImage image;
|
||||
image.loadFromData(packet->data, packet->size);
|
||||
image.mirror(false, true);
|
||||
if (!image.isNull() && m_callback) m_callback(image);
|
||||
} else {
|
||||
char message[256] = {0};
|
||||
|
@ -160,6 +160,10 @@ ColumnLayout {
|
||||
text: "ID查询"
|
||||
onClicked: App.module.requestUniqueId()
|
||||
}
|
||||
Button {
|
||||
text: "OTA升级"
|
||||
onClicked: loader.active = true
|
||||
}
|
||||
Row {
|
||||
Text {
|
||||
text: qsTr("日志")
|
||||
@ -171,4 +175,18 @@ ColumnLayout {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: loader
|
||||
source: "OtaPage.qml"
|
||||
active: false
|
||||
onLoaded: {
|
||||
if (loader.item && loader.item.open) {
|
||||
loader.item.open();
|
||||
loader.item.onClose = ()=>{
|
||||
loader.active= false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
115
Analyser/qml/OtaPage.qml
Normal file
115
Analyser/qml/OtaPage.qml
Normal file
@ -0,0 +1,115 @@
|
||||
import QtCore
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import QtQuick.Layouts
|
||||
import QtQuick.Dialogs
|
||||
import Analyser
|
||||
|
||||
Popup {
|
||||
id: root
|
||||
parent: Overlay.overlay
|
||||
anchors.centerIn: Overlay.overlay
|
||||
width: 500
|
||||
height: 200
|
||||
modal: true
|
||||
focus: true
|
||||
closePolicy: Popup.CloseOnEscape
|
||||
property var onClose
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
anchors.margins: 10
|
||||
spacing: 10
|
||||
|
||||
RowLayout {
|
||||
Layout.alignment: Qt.AlignRight
|
||||
Button {
|
||||
text: "关闭"
|
||||
onClicked: root.close()
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: 10
|
||||
TextField {
|
||||
id: otaFile
|
||||
Layout.fillWidth: true
|
||||
placeholderText: "请选择升级文件或将文件拖入工具中"
|
||||
}
|
||||
Button {
|
||||
text: "选择"
|
||||
onClicked: fileDialog.open()
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
spacing: 10
|
||||
ProgressBar {
|
||||
id:progressBar
|
||||
Layout.fillWidth: true
|
||||
from: 0
|
||||
to:100
|
||||
value: 0.0
|
||||
}
|
||||
Text {
|
||||
id:progressText
|
||||
text: "0%"
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
}
|
||||
}
|
||||
|
||||
RowLayout {
|
||||
Text {
|
||||
id: otaMessage
|
||||
text: "请选择升级文件,点击开始按钮升级模组"
|
||||
wrapMode: Text.Wrap
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
verticalAlignment: Text.AlignVCenter
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
Button {
|
||||
text: "开始"
|
||||
Layout.alignment: Qt.AlignRight
|
||||
onClicked: {
|
||||
otaMessage.color = "black"
|
||||
App.startOta(otaFile.text)
|
||||
enabled = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onClosed: {
|
||||
if (onClose)
|
||||
onClose()
|
||||
}
|
||||
|
||||
FileDialog {
|
||||
id: fileDialog
|
||||
nameFilters: ["OTA文件 (*.Pkg)"]
|
||||
currentFolder: StandardPaths.standardLocations(
|
||||
StandardPaths.DesktopLocation)[0]
|
||||
onAccepted: {
|
||||
var fileUrl = fileDialog.selectedFile.toString()
|
||||
var localFilePath = fileUrl.startsWith(
|
||||
"file:///") ? fileUrl.substring(8) : fileUrl
|
||||
otaFile.text = localFilePath
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: App
|
||||
function onUpdateFinished() {
|
||||
otaMessage.text = "OTA升级完成"
|
||||
otaMessage.color = "green"
|
||||
}
|
||||
function onOtaMessage(message) {
|
||||
otaMessage.text = message
|
||||
}
|
||||
function onOtaProgressChanged(progress){
|
||||
progressBar.value = progress;
|
||||
progressText.text = `${progress}%`
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -5,7 +5,7 @@ import Analyser
|
||||
|
||||
Window {
|
||||
width: 1120
|
||||
height: 640
|
||||
height: 680
|
||||
visible: true
|
||||
title: qsTr(Qt.application.name + " " + Qt.application.version)
|
||||
|
||||
|
@ -6,7 +6,6 @@ find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS Widgets SerialPort)
|
||||
|
||||
set(PROJECT_SOURCES OtaUpdate.rc
|
||||
main.cpp
|
||||
CdcUpdater.h CdcUpdater.cpp
|
||||
Widget.cpp
|
||||
Widget.h
|
||||
)
|
||||
@ -18,7 +17,6 @@ qt_add_executable(SmartLockerUpdater
|
||||
|
||||
target_link_libraries(SmartLockerUpdater
|
||||
PRIVATE Peripheral
|
||||
PRIVATE Encrypt
|
||||
PRIVATE Qt${QT_VERSION_MAJOR}::Widgets
|
||||
PRIVATE Qt${QT_VERSION_MAJOR}::SerialPort
|
||||
)
|
||||
|
@ -1,5 +1,11 @@
|
||||
find_package(QT NAMES Qt6 Qt5 REQUIRED COMPONENTS SerialPort)
|
||||
find_package(Qt${QT_VERSION_MAJOR} REQUIRED COMPONENTS SerialPort)
|
||||
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
|
||||
add_library(Peripheral
|
||||
DeviceDiscovery.h DeviceDiscovery.cpp
|
||||
CdcUpdater.h CdcUpdater.cpp
|
||||
)
|
||||
|
||||
target_include_directories(Peripheral
|
||||
@ -8,8 +14,10 @@ target_include_directories(Peripheral
|
||||
|
||||
target_link_libraries(Peripheral
|
||||
PUBLIC Universal
|
||||
PRIVATE Encrypt
|
||||
PRIVATE Mfreadwrite
|
||||
PRIVATE Mf
|
||||
PRIVATE mfplat
|
||||
PRIVATE mfuuid
|
||||
PRIVATE Qt${QT_VERSION_MAJOR}::SerialPort
|
||||
)
|
||||
|
@ -106,7 +106,8 @@ void CdcUpdater::transferBin() {
|
||||
auto readSize = m_ifs->gcount();
|
||||
|
||||
if (readSize > 0) {
|
||||
m_progress += (99 - m_progressBeforeTranster) * static_cast<float>(m_packetIndex) / m_totalPackageSize;
|
||||
m_progress = m_progressBeforeTranster +
|
||||
(99 - m_progressBeforeTranster) * static_cast<float>(m_packetIndex) / m_totalPackageSize;
|
||||
if (m_progress > 99) m_progress = 99;
|
||||
emit progressChanged(m_progress);
|
||||
|
||||
@ -138,7 +139,7 @@ void CdcUpdater::onReadyRead() {
|
||||
if (command == EnterUpgradeReply) {
|
||||
write(GetVersion);
|
||||
emit progressChanged(++m_progress);
|
||||
message("获取模组OTA版本......");
|
||||
emit message("获取模组OTA版本......");
|
||||
} else if (command == GetVersionReply) {
|
||||
LOG(info) << "device ota version: 0x" << std::hex << (static_cast<int>(data[4]) & 0xff);
|
||||
int fileSize = std::filesystem::file_size(m_path);
|
||||
@ -150,7 +151,7 @@ void CdcUpdater::onReadyRead() {
|
||||
content[2] = 0x14;
|
||||
write(StartUpgrade, content.data(), content.size());
|
||||
emit progressChanged(++m_progress);
|
||||
message("模组进入升级状态......");
|
||||
emit message("模组进入升级状态......");
|
||||
} else if (command == StartUpgradeReply) {
|
||||
std::ifstream ifs(m_path, std::ifstream::binary);
|
||||
char buffer[4096] = {0};
|
Loading…
Reference in New Issue
Block a user