更新与前板的使用串口连接
This commit is contained in:
parent
d2bccd9c49
commit
aa3e8c8223
|
@ -44,6 +44,7 @@
|
|||
<ClCompile Include="SourceCode\Network\httpClient.cpp" />
|
||||
<ClCompile Include="SourceCode\Network\mdns\mdns.c" />
|
||||
<ClCompile Include="SourceCode\RecvDataHandler\RecvDataHandler.cpp" />
|
||||
<ClCompile Include="SourceCode\RecvDataHandler\SerialRecvDataHandler.cpp" />
|
||||
<ClCompile Include="SourceCode\Widget\MainWidget.cpp">
|
||||
<DynamicSource Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">input</DynamicSource>
|
||||
<QtMocFileName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(Filename).moc</QtMocFileName>
|
||||
|
@ -54,10 +55,13 @@
|
|||
<DynamicSource Condition="'$(Configuration)|$(Platform)'=='Release|x64'">input</DynamicSource>
|
||||
<QtMocFileName Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(Filename).moc</QtMocFileName>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SourceCode\Widget\SerialPortHandler\SerialPortHandler.cpp" />
|
||||
<ClCompile Include="SourceCode\Widget\UI_Widget\UI_Widget.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include=".editorconfig" />
|
||||
<None Include="SourceCode\Json\JsonFile\allBoardFuncConfig.json" />
|
||||
<None Include="SourceCode\Json\JsonFile\allBoardTest.json" />
|
||||
<None Include="SourceCode\Json\JsonFile\backBoardFuncConfig.json" />
|
||||
<None Include="SourceCode\Json\JsonFile\backBoardOneClickTest.json" />
|
||||
<None Include="SourceCode\Json\JsonFile\backBoardTest.json" />
|
||||
|
@ -71,11 +75,9 @@
|
|||
<None Include="SourceCode\Json\JsonFile\frontBoardTest.json" />
|
||||
<None Include="SourceCode\Json\JsonFile\frontCmd_config.json" />
|
||||
<None Include="SourceCode\Json\JsonFile\frontDevInfo.json" />
|
||||
<None Include="SourceCode\Json\JsonFile\funcConfig.json" />
|
||||
<None Include="SourceCode\Json\JsonFile\getPic.json" />
|
||||
<None Include="SourceCode\Json\JsonFile\getVideo.json" />
|
||||
<None Include="SourceCode\Json\JsonFile\README.md" />
|
||||
<None Include="SourceCode\Json\JsonFile\testConfig.json" />
|
||||
<None Include="UI_config.ini" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
|
@ -87,6 +89,9 @@
|
|||
<ClInclude Include="SourceCode\Json\readJsonFile.h" />
|
||||
<ClInclude Include="SourceCode\Network\mdns\mdns.h" />
|
||||
<QtMoc Include="SourceCode\Network\mdns\MdnsServiceThread.h" />
|
||||
<QtMoc Include="SourceCode\Widget\SerialPortHandler\SerialPortHandler.h" />
|
||||
<QtMoc Include="SourceCode\Widget\SerialPortHandler\SerialPortWorker.h" />
|
||||
<QtMoc Include="SourceCode\RecvDataHandler\SerialRecvDataHandler.h" />
|
||||
<ClInclude Include="SourceCode\Widget\UI_Widget\UI_Name.h" />
|
||||
<QtMoc Include="SourceCode\LicenseGenerate\LicenseConfirmWindow.h" />
|
||||
<ClInclude Include="SourceCode\LicenseGenerate\LicenseGenerate.h" />
|
||||
|
|
|
@ -35,6 +35,12 @@
|
|||
<ClCompile Include="SourceCode\Network\mdns\mdns.c">
|
||||
<Filter>Network\mdns</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SourceCode\Widget\SerialPortHandler\SerialPortHandler.cpp">
|
||||
<Filter>Widget\SerialPortHandler</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="SourceCode\RecvDataHandler\SerialRecvDataHandler.cpp">
|
||||
<Filter>RecvDataHandler</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<QtMoc Include="SourceCode\Widget\MainWidget.h">
|
||||
|
@ -70,21 +76,24 @@
|
|||
<QtMoc Include="SourceCode\Network\mdns\MdnsServiceThread.h">
|
||||
<Filter>Network\mdns</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="SourceCode\Widget\SerialPortHandler\SerialPortHandler.h">
|
||||
<Filter>Widget\SerialPortHandler</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="SourceCode\Widget\SerialPortHandler\SerialPortWorker.h">
|
||||
<Filter>Widget\SerialPortHandler</Filter>
|
||||
</QtMoc>
|
||||
<QtMoc Include="SourceCode\RecvDataHandler\SerialRecvDataHandler.h">
|
||||
<Filter>RecvDataHandler</Filter>
|
||||
</QtMoc>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include=".editorconfig" />
|
||||
<None Include="SourceCode\Json\JsonFile\funcConfig.json">
|
||||
<Filter>Json\JsonFile</Filter>
|
||||
</None>
|
||||
<None Include="SourceCode\Json\JsonFile\getPic.json">
|
||||
<Filter>Json\JsonFile</Filter>
|
||||
</None>
|
||||
<None Include="SourceCode\Json\JsonFile\getVideo.json">
|
||||
<Filter>Json\JsonFile</Filter>
|
||||
</None>
|
||||
<None Include="SourceCode\Json\JsonFile\testConfig.json">
|
||||
<Filter>Json\JsonFile</Filter>
|
||||
</None>
|
||||
<None Include="SourceCode\Json\JsonFile\backBoardFuncConfig.json">
|
||||
<Filter>Json\JsonFile</Filter>
|
||||
</None>
|
||||
|
@ -128,6 +137,12 @@
|
|||
<None Include="SourceCode\Json\JsonFile\frontCmd_config.json">
|
||||
<Filter>Json\JsonFile</Filter>
|
||||
</None>
|
||||
<None Include="SourceCode\Json\JsonFile\allBoardTest.json">
|
||||
<Filter>Json\JsonFile</Filter>
|
||||
</None>
|
||||
<None Include="SourceCode\Json\JsonFile\allBoardFuncConfig.json">
|
||||
<Filter>Json\JsonFile</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="Widget">
|
||||
|
@ -160,6 +175,9 @@
|
|||
<Filter Include="Widget\UI_Widget">
|
||||
<UniqueIdentifier>{ca263230-ea2f-4140-82aa-19b06eca1b1e}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Widget\SerialPortHandler">
|
||||
<UniqueIdentifier>{332951b9-b26b-4d33-9f92-765d7ac250c5}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="SourceCode\Media\Media.h">
|
||||
|
|
|
@ -114,5 +114,11 @@
|
|||
"val": 0,
|
||||
"lable": "联网测试",
|
||||
"timeout": 2000
|
||||
},
|
||||
{
|
||||
"cmd": "CHANGE_THEME",
|
||||
"val": "0",
|
||||
"lable": "更新主题壁纸",
|
||||
"timeout": 2000
|
||||
}
|
||||
]
|
||||
|
|
|
@ -17,5 +17,11 @@
|
|||
"SN": "123",
|
||||
"lable": "write_UUID_SN",
|
||||
"timeout": 0
|
||||
},
|
||||
{
|
||||
"cmd": "BACK_CONFIRM_BURN",
|
||||
"val": "0",
|
||||
"lable": "Confirm_burn",
|
||||
"timeout": 0
|
||||
}
|
||||
]
|
|
@ -69,13 +69,13 @@
|
|||
"cmd": "GET_IMG",
|
||||
"val": 0,
|
||||
"lable": "左边镜头取图",
|
||||
"timeout": 0
|
||||
"timeout": 3000
|
||||
},
|
||||
{
|
||||
"cmd": "GET_IMG",
|
||||
"val": 1,
|
||||
"lable": "右边镜头取图",
|
||||
"timeout": 0
|
||||
"timeout": 3000
|
||||
},
|
||||
{
|
||||
"cmd": "TOUCH_TEST",
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
"cmd": "FACE_ENROLL_SINGLE",
|
||||
"val": 0,
|
||||
"lable": "人脸单角度注册",
|
||||
"timeout": 10000
|
||||
"timeout": 2000
|
||||
},
|
||||
{
|
||||
"cmd": "FACE_ENROLL",
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
[
|
||||
{
|
||||
"cmd": "GET_IMG",
|
||||
"val": "0",
|
||||
"val": 0,
|
||||
"lable": "取图",
|
||||
"timeout": 0
|
||||
}
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
[
|
||||
{
|
||||
"cmd": "START_VIDEO",
|
||||
"val": "1",
|
||||
"val": 1,
|
||||
"lable": "启动视频",
|
||||
"timeout": 0
|
||||
},
|
||||
{
|
||||
"cmd": "STOP_VIDEO",
|
||||
"val": "0",
|
||||
"val": 0,
|
||||
"lable": "停止视频",
|
||||
"timeout": 0
|
||||
}
|
||||
|
|
|
@ -23,12 +23,12 @@ QJsonArray readJsonArrayFromFile(const QString& filePath)
|
|||
return jsonArray;
|
||||
}
|
||||
|
||||
QJsonArray readJson_testConfig() {
|
||||
return readJsonArrayFromFile("./SourceCode/Json/JsonFile/testConfig.json");
|
||||
QJsonArray readJson_allBoardTest() {
|
||||
return readJsonArrayFromFile("./SourceCode/Json/JsonFile/allBoardTest.json");
|
||||
}
|
||||
|
||||
QJsonArray readJson_funcConfig() {
|
||||
return readJsonArrayFromFile("./SourceCode/Json/JsonFile/funcConfig.json");
|
||||
QJsonArray readJson_allBoardFuncConfig() {
|
||||
return readJsonArrayFromFile("./SourceCode/Json/JsonFile/allBoardFuncConfig.json");
|
||||
}
|
||||
|
||||
QJsonArray readJson_frontBoardOneClickTest() {
|
||||
|
|
|
@ -23,8 +23,8 @@ QJsonArray readJson_backCmd_config();
|
|||
|
||||
QJsonArray readJson_factoryProductInfo();
|
||||
|
||||
QJsonArray readJson_testConfig();
|
||||
QJsonArray readJson_funcConfig();
|
||||
QJsonArray readJson_allBoardTest();
|
||||
QJsonArray readJson_allBoardFuncConfig();
|
||||
|
||||
QJsonArray readJson_getPic();
|
||||
QJsonArray readJson_getVideo();
|
||||
|
|
|
@ -220,3 +220,73 @@ void DataHandler::showPic(QSize labelSize, int lens_n,
|
|||
qDebug() << "JPG image saved to" << rotatedImageFileName;
|
||||
}
|
||||
|
||||
void SerialDataHandler::showPic(QSize labelSize, int lens_n,
|
||||
int width, int height, int format, const QByteArray* valData)
|
||||
{
|
||||
qDebug() << "lens_n = " << lens_n;
|
||||
qDebug() << "format = " << format;
|
||||
qDebug() << "width = " << width;
|
||||
qDebug() << "height = " << height;
|
||||
qDebug() << "yuvData size = " << valData->size();
|
||||
|
||||
QImage image;
|
||||
if (format == YUV422) {
|
||||
image = convertYUV422ToQImage(*valData, width, height);
|
||||
}
|
||||
else if (format == YUV420) {
|
||||
image = convertYUV420ToQImage(*valData, width, height);
|
||||
}
|
||||
else {
|
||||
qWarning() << "Unsupported image format! Please use YUV422 or YUV420 format";
|
||||
return;
|
||||
}
|
||||
|
||||
QTransform transform;
|
||||
transform.rotate(90); // 可以调整旋转角度
|
||||
QImage rotatedImage = image.transformed(transform);
|
||||
QImage scaledImage = rotatedImage.scaled(labelSize, Qt::KeepAspectRatio);
|
||||
QPixmap pixmap = QPixmap::fromImage(scaledImage);
|
||||
if (lens_n == 0) {
|
||||
//leftLens_m_imageLabel->setPixmap(QPixmap::fromImage(scaledImage));
|
||||
emit updateLeftLensImage(pixmap);
|
||||
}
|
||||
else if (lens_n == 1) {
|
||||
//rightLens_m_imageLabel->setPixmap(QPixmap::fromImage(scaledImage));
|
||||
emit updateRightLensImage(pixmap);
|
||||
}
|
||||
else {
|
||||
qWarning() << "Unsupported image lens!";
|
||||
}
|
||||
|
||||
// 生成保存图片的目录
|
||||
QString saveDirPath = QDir::currentPath() + "/frontBoardImage";
|
||||
QDir saveDir(saveDirPath);
|
||||
if (!saveDir.exists()) {
|
||||
saveDir.mkpath(saveDirPath);
|
||||
}
|
||||
QString currentTime = QDateTime::currentDateTime().toString("yyyyMMdd_HHmmss");
|
||||
QByteArray rotatedYuvData;
|
||||
if (format == YUV422) {
|
||||
rotatedYuvData = convertQImageToYUV422(rotatedImage);
|
||||
}
|
||||
else if (format == YUV420) {
|
||||
rotatedYuvData = convertQImageToYUV420(rotatedImage);
|
||||
}
|
||||
QString yuvFileName = saveDirPath + "/" + currentTime + ".yuv";
|
||||
QFile yuvFile(yuvFileName);
|
||||
if (yuvFile.open(QIODevice::WriteOnly)) {
|
||||
yuvFile.write(rotatedYuvData);
|
||||
yuvFile.close();
|
||||
qDebug() << "YUV image saved to" << yuvFileName;
|
||||
}
|
||||
else {
|
||||
qWarning() << "Failed to save rotated YUV image to" << yuvFileName;
|
||||
}
|
||||
|
||||
// 额外:可以保存旋转后的图像为JPG或PNG格式
|
||||
QString rotatedImageFileName = saveDirPath + "/" + currentTime + ".jpg";
|
||||
rotatedImage.save(rotatedImageFileName, "JPG");
|
||||
qDebug() << "JPG image saved to" << rotatedImageFileName;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include <QDebug>
|
||||
|
||||
#include "../RecvDataHandler/RecvDataHandler.h"
|
||||
#include "../RecvDataHandler/SerialRecvDataHandler.h"
|
||||
|
||||
#define YUV420 1
|
||||
#define YUV422 2
|
||||
|
|
|
@ -106,14 +106,14 @@ QString ClientHandler::getCurrentFuncItemData() const
|
|||
{
|
||||
QString data = currentFuncItem.value("val").toString();
|
||||
qDebug() << "Getting current funcItem val:" << data;
|
||||
return data; // 返回当前项的 "data" 字段
|
||||
return data; // 返回当前项的 "val" 字段
|
||||
}
|
||||
|
||||
QString ClientHandler::getCurrentItemLable() const
|
||||
{
|
||||
QString lable = currentItem.value("lable").toString();
|
||||
qDebug() << "Getting current item lable:" << lable;
|
||||
return lable; // 返回当前项的 "data" 字段
|
||||
return lable; // 返回当前项的 "lable" 字段
|
||||
}
|
||||
|
||||
QString ClientHandler::getCurrentFuncItemLable() const
|
||||
|
@ -475,8 +475,6 @@ void ClientHandler::sendDevInfoJsonItem(const QJsonObject& jsonItem, int itemInd
|
|||
else {
|
||||
emit sendDataToSomeClient(controlClientId, itemData.toUtf8());
|
||||
}
|
||||
|
||||
|
||||
if (jsonItem.contains("timeout")) {
|
||||
int timeout = jsonItem.value("timeout").toInt();
|
||||
if (timeout > 0) {
|
||||
|
@ -553,7 +551,7 @@ void ClientHandler::sendNextItem(QJsonArray& currentOneClickedItem)
|
|||
}
|
||||
}
|
||||
else if (isManualSend) {
|
||||
emit allItemsProcessed(getClientAddress(), itemsProcessedCount);
|
||||
emit allItemsProcessed(isBackBoardOrAllBoard, getClientAddress(), itemsProcessedCount);
|
||||
// 处理完毕后重置标记
|
||||
isManualSend = false;
|
||||
isClickedSend = false;
|
||||
|
@ -582,7 +580,6 @@ void ClientHandler::RNDISClient3Data(QByteArray& data) {
|
|||
}
|
||||
|
||||
void ClientHandler::RNDISClient4Data(QByteArray& data) {
|
||||
//qDebug() << " RNDISClient4Data size:" << data.size();
|
||||
//qDebug() << " RNDISClient4Data size:" << data.size();
|
||||
isRecvVideoData = false;
|
||||
isStartVideo = false;
|
||||
|
@ -679,10 +676,10 @@ void ClientHandler::onPicRecvFinished()
|
|||
void ClientHandler::onDataReceived()
|
||||
{
|
||||
//qDebug() << "isRecvVideoData:" << isRecvVideoData;
|
||||
//qDebug() << "isPowerOnSend:" << isPowerOnSend;
|
||||
//qDebug() << "isClickedSend:" << isClickedSend;
|
||||
//qDebug() << "isSingleSend:" << isSingleSend;
|
||||
//qDebug() << "isRecvImgData:" << isRecvImgData;
|
||||
//qDebug() << "isPowerOnSend: " << isPowerOnSend;
|
||||
//qDebug() << "isClickedSend: " << isClickedSend;
|
||||
//qDebug() << "isSingleSend: " << isSingleSend;
|
||||
//qDebug() << "isRecvImgData: " << isRecvImgData;
|
||||
if (!isRecvVideoData &&
|
||||
(isRecvImgData || isPowerOnSend || isClickedSend || (isSingleSend && (currentItemIndex < currentJson.size())))) {
|
||||
QByteArray allData;
|
||||
|
@ -726,7 +723,7 @@ void ClientHandler::onDataReceived()
|
|||
}
|
||||
else {
|
||||
qDebug() << "All items processed in onDataReceived.";
|
||||
emit allItemsProcessed(getClientAddress(), currentBackBoardIndex);
|
||||
emit allItemsProcessed(isBackBoardOrAllBoard, getClientAddress(), currentBackBoardIndex);
|
||||
isPowerOnSend = false;
|
||||
}
|
||||
}
|
||||
|
@ -736,7 +733,7 @@ void ClientHandler::onDataReceived()
|
|||
}
|
||||
else {
|
||||
qDebug() << "All items processed in onDataReceived.";
|
||||
emit allItemsProcessed(getClientAddress(), currentFrontBoardIndex);
|
||||
emit allItemsProcessed(isBackBoardOrAllBoard, getClientAddress(), currentFrontBoardIndex);
|
||||
isPowerOnSend = false;
|
||||
}
|
||||
}
|
||||
|
@ -748,7 +745,7 @@ void ClientHandler::onDataReceived()
|
|||
}
|
||||
}
|
||||
else if(isClickedSend) {
|
||||
emit allItemsProcessed(getClientAddress(), itemsProcessedCount);
|
||||
emit allItemsProcessed(isBackBoardOrAllBoard, getClientAddress(), itemsProcessedCount);
|
||||
isClickedSend = false;
|
||||
//resetCurrentItemIndex();
|
||||
}
|
||||
|
@ -850,7 +847,7 @@ void ClientHandler::onTimeout()
|
|||
{
|
||||
{
|
||||
QMutexLocker locker(&mutex);
|
||||
emit statusUpdated(getClientAddress(), false, currentJson, currentJsonItem);
|
||||
emit statusUpdated(isBackBoardOrAllBoard, getClientAddress(), false, currentJson, currentJsonItem);
|
||||
//qDebug() << "isSingleSend:" << isSingleSend << "isPowerOnSend:" << isPowerOnSend;
|
||||
if (!isSingleSend && !isPowerOnSend) {
|
||||
currentItemIndex ++;
|
||||
|
@ -866,7 +863,7 @@ void ClientHandler::onTimeout()
|
|||
sendNextItem(currentJson);
|
||||
}
|
||||
else if (currentItemIndex >= backBoardOneClickTest.size()) {
|
||||
emit allItemsProcessed(getClientAddress(), itemsProcessedCount);
|
||||
emit allItemsProcessed(isBackBoardOrAllBoard, getClientAddress(), itemsProcessedCount);
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
@ -874,7 +871,7 @@ void ClientHandler::onTimeout()
|
|||
sendNextItem(currentJson);
|
||||
}
|
||||
else if (currentItemIndex >= frontBoardOneClickTest.size()) {
|
||||
emit allItemsProcessed(getClientAddress(), itemsProcessedCount);
|
||||
emit allItemsProcessed(isBackBoardOrAllBoard, getClientAddress(), itemsProcessedCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -884,7 +881,7 @@ void ClientHandler::onTimeout()
|
|||
sendDevInfoItem();
|
||||
}
|
||||
else {
|
||||
emit allItemsProcessed(getClientAddress(), currentBackBoardIndex);
|
||||
emit allItemsProcessed(isBackBoardOrAllBoard, getClientAddress(), currentBackBoardIndex);
|
||||
currentFrontBoardIndex = 0;
|
||||
currentBackBoardIndex = 0;
|
||||
isPowerOnSend = false;
|
||||
|
@ -895,7 +892,7 @@ void ClientHandler::onTimeout()
|
|||
sendDevInfoItem();
|
||||
}
|
||||
else {
|
||||
emit allItemsProcessed(getClientAddress(), currentFrontBoardIndex);
|
||||
emit allItemsProcessed(isBackBoardOrAllBoard, getClientAddress(), currentFrontBoardIndex);
|
||||
currentFrontBoardIndex = 0;
|
||||
currentBackBoardIndex = 0;
|
||||
isPowerOnSend = false;
|
||||
|
|
|
@ -112,12 +112,12 @@ signals:
|
|||
// 数据发送信号
|
||||
void sendData(const QByteArray& data, int isBoardType);
|
||||
// 状态更新信号
|
||||
void statusUpdated(const QString& client, bool success, const QJsonArray& jsonArray, int itemJsonIndex);
|
||||
void statusUpdated(int boardTpye, const QString& client, bool success, const QJsonArray& jsonArray, int itemJsonIndex);
|
||||
void HandleInvalidOperate(const QString& text);
|
||||
// 客户端断开连接信号
|
||||
void clientDisconnected(ClientHandler* handler);
|
||||
// json文件配置项发送完毕
|
||||
void allItemsProcessed(const QString& client, int itemsProcessedCount);
|
||||
void allItemsProcessed(int boardTpye, const QString& client, int itemsProcessedCount);
|
||||
// 通知主线程启动定时器
|
||||
void startTimeout(int timeout);
|
||||
void selectClientDisconnected(int client_Id);
|
||||
|
|
|
@ -23,7 +23,7 @@ public:
|
|||
|
||||
QPushButton* deleteButton = new QPushButton("删除用户", this);
|
||||
layout->addWidget(deleteButton);
|
||||
|
||||
qDebug() << "------------- DelUserWindow";
|
||||
connect(deleteButton, &QPushButton::clicked, this, &DelUserWindow::onDeleteButtonClicked);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,12 +4,13 @@
|
|||
|
||||
#include "mdns.h"
|
||||
|
||||
// 添加一个类来运行 mDNS 服务
|
||||
// 运行 mDNS 服务
|
||||
class MdnsServiceThread : public QThread {
|
||||
Q_OBJECT
|
||||
public:
|
||||
MdnsServiceThread(const QString& hostname, const QString& serviceName, int servicePort, QObject* parent = nullptr)
|
||||
MdnsServiceThread(const QString& hostname, const QString& serviceName, int servicePort, char* select_ip, QObject* parent = nullptr)
|
||||
: QThread(parent),
|
||||
m_select_ip(select_ip),
|
||||
m_hostname(hostname),
|
||||
m_serviceName(serviceName),
|
||||
m_servicePort(servicePort) {}
|
||||
|
@ -26,8 +27,9 @@ protected:
|
|||
extern volatile sig_atomic_t running; // 使用全局变量控制运行状态
|
||||
running = 1;
|
||||
|
||||
// 调用阻塞的 service_mdns 方法
|
||||
int result = service_mdns(m_hostname.toStdString().c_str(), m_serviceName.toStdString().c_str(), m_servicePort);
|
||||
//int result = service_mdns(m_hostname.toStdString().c_str(), m_serviceName.toStdString().c_str(), m_servicePort, "192.168.1.170");
|
||||
//int result = service_mdns(m_hostname.toStdString().c_str(), m_serviceName.toStdString().c_str(), m_servicePort, "172.17.128.1");
|
||||
int result = service_mdns(m_hostname.toStdString().c_str(), m_serviceName.toStdString().c_str(), m_servicePort, m_select_ip);
|
||||
if (result < 0) {
|
||||
qDebug() << "Failed to start mDNS service";
|
||||
}
|
||||
|
@ -37,6 +39,7 @@ protected:
|
|||
}
|
||||
|
||||
private:
|
||||
char* m_select_ip;
|
||||
QString m_hostname;
|
||||
QString m_serviceName;
|
||||
int m_servicePort;
|
||||
|
|
|
@ -530,7 +530,7 @@ open_client_sockets(int* sockets, int max_sockets, int port) {
|
|||
char buffer[128];
|
||||
mdns_string_t addr = ipv4_address_to_string(buffer, sizeof(buffer), saddr,
|
||||
sizeof(struct sockaddr_in));
|
||||
printf("Local IPv4 address: %.*s\n", MDNS_STRING_FORMAT(addr));
|
||||
printf("---Local IPv4 address: %.*s\n", MDNS_STRING_FORMAT(addr));
|
||||
}
|
||||
}
|
||||
} else if (unicast->Address.lpSockaddr->sa_family == AF_INET6) {
|
||||
|
@ -665,6 +665,7 @@ open_client_sockets(int* sockets, int max_sockets, int port) {
|
|||
return num_sockets;
|
||||
}
|
||||
|
||||
/*
|
||||
// Open sockets to listen to incoming mDNS queries on port 5353
|
||||
static int
|
||||
open_service_sockets(int* sockets, int max_sockets) {
|
||||
|
@ -720,6 +721,101 @@ open_service_sockets(int* sockets, int max_sockets) {
|
|||
|
||||
return num_sockets;
|
||||
}
|
||||
*/
|
||||
|
||||
static int open_service_sockets(int* sockets, int max_sockets, const char* local_ip) {
|
||||
int num_sockets = 0;
|
||||
|
||||
if (local_ip) {
|
||||
// 如果指定了 local_ip,则绑定到该地址
|
||||
struct sockaddr_in sock_addr_ipv4;
|
||||
struct sockaddr_in6 sock_addr_ipv6;
|
||||
memset(&sock_addr_ipv4, 0, sizeof(sock_addr_ipv4));
|
||||
memset(&sock_addr_ipv6, 0, sizeof(sock_addr_ipv6));
|
||||
|
||||
if (inet_pton(AF_INET, local_ip, &sock_addr_ipv4.sin_addr)) {
|
||||
sock_addr_ipv4.sin_family = AF_INET;
|
||||
sock_addr_ipv4.sin_port = htons(MDNS_PORT);
|
||||
#ifdef __APPLE__
|
||||
sock_addr_ipv4.sin_len = sizeof(struct sockaddr_in);
|
||||
#endif
|
||||
int sock = mdns_socket_open_ipv4(&sock_addr_ipv4);
|
||||
if (sock >= 0) {
|
||||
sockets[num_sockets++] = sock;
|
||||
printf("Bound to specific IPv4 address: %s\n", local_ip);
|
||||
}
|
||||
else {
|
||||
printf("Failed to bind to IPv4 address: %s\n", local_ip);
|
||||
}
|
||||
}
|
||||
else if (inet_pton(AF_INET6, local_ip, &sock_addr_ipv6.sin6_addr)) {
|
||||
sock_addr_ipv6.sin6_family = AF_INET6;
|
||||
sock_addr_ipv6.sin6_port = htons(MDNS_PORT);
|
||||
#ifdef __APPLE__
|
||||
sock_addr_ipv6.sin6_len = sizeof(struct sockaddr_in6);
|
||||
#endif
|
||||
int sock = mdns_socket_open_ipv6(&sock_addr_ipv6);
|
||||
if (sock >= 0) {
|
||||
sockets[num_sockets++] = sock;
|
||||
printf("Bound to specific IPv6 address: %s\n", local_ip);
|
||||
}
|
||||
else {
|
||||
printf("Failed to bind to IPv6 address: %s\n", local_ip);
|
||||
}
|
||||
}
|
||||
else {
|
||||
printf("Invalid local IP address: %s\n", local_ip);
|
||||
}
|
||||
}
|
||||
|
||||
if (num_sockets == 0) {
|
||||
// 如果未指定 local_ip,则绑定到所有接口
|
||||
if (num_sockets < max_sockets) {
|
||||
struct sockaddr_in sock_addr;
|
||||
memset(&sock_addr, 0, sizeof(sock_addr));
|
||||
sock_addr.sin_family = AF_INET;
|
||||
#ifdef _WIN32
|
||||
sock_addr.sin_addr = in4addr_any;
|
||||
#else
|
||||
sock_addr.sin_addr.s_addr = INADDR_ANY;
|
||||
#endif
|
||||
sock_addr.sin_port = htons(MDNS_PORT);
|
||||
#ifdef __APPLE__
|
||||
sock_addr.sin_len = sizeof(struct sockaddr_in);
|
||||
#endif
|
||||
int sock = mdns_socket_open_ipv4(&sock_addr);
|
||||
if (sock >= 0) {
|
||||
sockets[num_sockets++] = sock;
|
||||
printf("IPv4 socket opened successfully on port %d\n", MDNS_PORT);
|
||||
}
|
||||
else {
|
||||
printf("Failed to open IPv4 socket on port %d\n", MDNS_PORT);
|
||||
}
|
||||
}
|
||||
|
||||
if (num_sockets < max_sockets) {
|
||||
struct sockaddr_in6 sock_addr;
|
||||
memset(&sock_addr, 0, sizeof(sock_addr));
|
||||
sock_addr.sin6_family = AF_INET6;
|
||||
sock_addr.sin6_addr = in6addr_any;
|
||||
sock_addr.sin6_port = htons(MDNS_PORT);
|
||||
#ifdef __APPLE__
|
||||
sock_addr.sin6_len = sizeof(struct sockaddr_in6);
|
||||
#endif
|
||||
int sock = mdns_socket_open_ipv6(&sock_addr);
|
||||
if (sock >= 0) {
|
||||
sockets[num_sockets++] = sock;
|
||||
printf("IPv6 socket opened successfully on port %d\n", MDNS_PORT);
|
||||
}
|
||||
else {
|
||||
printf("Failed to open IPv6 socket on port %d\n", MDNS_PORT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return num_sockets;
|
||||
}
|
||||
|
||||
|
||||
// Send a DNS-SD query
|
||||
static int
|
||||
|
@ -862,10 +958,12 @@ send_mdns_query(mdns_query_t* query, size_t count, void* user_data) {
|
|||
}
|
||||
|
||||
// Provide a mDNS service, answering incoming DNS-SD and mDNS queries
|
||||
/*
|
||||
int
|
||||
service_mdns(const char* hostname, const char* service_name, int service_port) {
|
||||
service_mdns(const char* hostname, const char* service_name, int service_port, const char* local_ip) {
|
||||
int sockets[32];
|
||||
int num_sockets = open_service_sockets(sockets, sizeof(sockets) / sizeof(sockets[0]));
|
||||
//int num_sockets = open_service_sockets(sockets, sizeof(sockets) / sizeof(sockets[0]));
|
||||
int num_sockets = open_service_sockets(sockets, sizeof(sockets) / sizeof(sockets[0]), local_ip);
|
||||
if (num_sockets <= 0) {
|
||||
printf("Failed to open any client sockets\n");
|
||||
return -1;
|
||||
|
@ -1037,6 +1135,183 @@ service_mdns(const char* hostname, const char* service_name, int service_port) {
|
|||
mdns_socket_close(sockets[isock]);
|
||||
printf("Closed socket%s\n", num_sockets ? "s" : "");
|
||||
|
||||
return 0;
|
||||
}*/
|
||||
|
||||
int service_mdns(const char* hostname, const char* service_name, int service_port, const char* local_ip) {
|
||||
int sockets[32];
|
||||
int num_sockets = open_service_sockets(sockets, sizeof(sockets) / sizeof(sockets[0]), local_ip);
|
||||
if (num_sockets <= 0) {
|
||||
printf("Failed to open any client sockets\n");
|
||||
return -1;
|
||||
}
|
||||
printf("Opened %d socket%s for mDNS service\n", num_sockets, num_sockets ? "s" : "");
|
||||
|
||||
size_t service_name_length = strlen(service_name);
|
||||
if (!service_name_length) {
|
||||
printf("Invalid service name\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
char* service_name_buffer = malloc(service_name_length + 2);
|
||||
memcpy(service_name_buffer, service_name, service_name_length);
|
||||
if (service_name_buffer[service_name_length - 1] != '.')
|
||||
service_name_buffer[service_name_length++] = '.';
|
||||
service_name_buffer[service_name_length] = 0;
|
||||
service_name = service_name_buffer;
|
||||
|
||||
printf("Service mDNS: %s:%d\n", service_name, service_port);
|
||||
printf("Hostname: %s\n", hostname);
|
||||
|
||||
size_t capacity = 2048;
|
||||
void* buffer = malloc(capacity);
|
||||
|
||||
mdns_string_t service_string = (mdns_string_t){service_name, strlen(service_name)};
|
||||
mdns_string_t hostname_string = (mdns_string_t){hostname, strlen(hostname)};
|
||||
|
||||
char service_instance_buffer[256] = {0};
|
||||
snprintf(service_instance_buffer, sizeof(service_instance_buffer) - 1, "%.*s.%.*s",
|
||||
MDNS_STRING_FORMAT(hostname_string), MDNS_STRING_FORMAT(service_string));
|
||||
mdns_string_t service_instance_string =
|
||||
(mdns_string_t){service_instance_buffer, strlen(service_instance_buffer)};
|
||||
|
||||
char qualified_hostname_buffer[256] = {0};
|
||||
snprintf(qualified_hostname_buffer, sizeof(qualified_hostname_buffer) - 1, "%.*s.local.",
|
||||
MDNS_STRING_FORMAT(hostname_string));
|
||||
mdns_string_t hostname_qualified_string =
|
||||
(mdns_string_t){qualified_hostname_buffer, strlen(qualified_hostname_buffer)};
|
||||
|
||||
service_t service = {0};
|
||||
service.service = service_string;
|
||||
service.hostname = hostname_string;
|
||||
service.service_instance = service_instance_string;
|
||||
service.hostname_qualified = hostname_qualified_string;
|
||||
service.port = service_port;
|
||||
|
||||
if (local_ip) {
|
||||
struct sockaddr_in addr_ipv4;
|
||||
memset(&addr_ipv4, 0, sizeof(addr_ipv4));
|
||||
addr_ipv4.sin_family = AF_INET;
|
||||
if (inet_pton(AF_INET, local_ip, &addr_ipv4.sin_addr) <= 0) {
|
||||
printf("Invalid local IP address: %s\n", local_ip);
|
||||
free(service_name_buffer);
|
||||
free(buffer);
|
||||
return -1;
|
||||
}
|
||||
service.address_ipv4 = addr_ipv4;
|
||||
} else {
|
||||
service.address_ipv4 = service_address_ipv4;
|
||||
}
|
||||
|
||||
// Setup mDNS records
|
||||
service.record_ptr = (mdns_record_t){
|
||||
.name = service.service,
|
||||
.type = MDNS_RECORDTYPE_PTR,
|
||||
.data.ptr.name = service.service_instance,
|
||||
.rclass = 0,
|
||||
.ttl = 120
|
||||
};
|
||||
|
||||
service.record_srv = (mdns_record_t){
|
||||
.name = service.service_instance,
|
||||
.type = MDNS_RECORDTYPE_SRV,
|
||||
.data.srv.name = service.hostname_qualified,
|
||||
.data.srv.port = service.port,
|
||||
.data.srv.priority = 0,
|
||||
.data.srv.weight = 0,
|
||||
.rclass = 0,
|
||||
.ttl = 120
|
||||
};
|
||||
|
||||
service.record_a = (mdns_record_t){
|
||||
.name = service.hostname_qualified,
|
||||
.type = MDNS_RECORDTYPE_A,
|
||||
.data.a.addr = service.address_ipv4,
|
||||
.rclass = 0,
|
||||
.ttl = 120
|
||||
};
|
||||
|
||||
service.record_aaaa = (mdns_record_t){
|
||||
.name = service.hostname_qualified,
|
||||
.type = MDNS_RECORDTYPE_AAAA,
|
||||
.data.aaaa.addr = service.address_ipv6,
|
||||
.rclass = 0,
|
||||
.ttl = 120
|
||||
};
|
||||
|
||||
service.txt_record[0] = (mdns_record_t){
|
||||
.name = service.service_instance,
|
||||
.type = MDNS_RECORDTYPE_TXT,
|
||||
.data.txt.key = {MDNS_STRING_CONST("test")},
|
||||
.data.txt.value = {MDNS_STRING_CONST("1")},
|
||||
.rclass = 0,
|
||||
.ttl = 120
|
||||
};
|
||||
|
||||
service.txt_record[1] = (mdns_record_t){
|
||||
.name = service.service_instance,
|
||||
.type = MDNS_RECORDTYPE_TXT,
|
||||
.data.txt.key = {MDNS_STRING_CONST("other")},
|
||||
.data.txt.value = {MDNS_STRING_CONST("value")},
|
||||
.rclass = 0,
|
||||
.ttl = 120
|
||||
};
|
||||
|
||||
printf("Sending announce\n");
|
||||
mdns_record_t additional[5] = {0};
|
||||
size_t additional_count = 0;
|
||||
additional[additional_count++] = service.record_srv;
|
||||
additional[additional_count++] = service.record_a;
|
||||
additional[additional_count++] = service.txt_record[0];
|
||||
additional[additional_count++] = service.txt_record[1];
|
||||
|
||||
for (int isock = 0; isock < num_sockets; ++isock)
|
||||
mdns_announce_multicast(sockets[isock], buffer, capacity, service.record_ptr, 0, 0, additional, additional_count);
|
||||
|
||||
// Service loop
|
||||
while (running) {
|
||||
int nfds = 0;
|
||||
fd_set readfs;
|
||||
FD_ZERO(&readfs);
|
||||
for (int isock = 0; isock < num_sockets; ++isock) {
|
||||
if (sockets[isock] >= nfds)
|
||||
nfds = sockets[isock] + 1;
|
||||
FD_SET(sockets[isock], &readfs);
|
||||
}
|
||||
|
||||
struct timeval timeout;
|
||||
timeout.tv_sec = 0;
|
||||
timeout.tv_usec = 100000;
|
||||
|
||||
if (select(nfds, &readfs, 0, 0, &timeout) >= 0) {
|
||||
for (int isock = 0; isock < num_sockets; ++isock) {
|
||||
if (FD_ISSET(sockets[isock], &readfs)) {
|
||||
mdns_socket_listen(sockets[isock], buffer, capacity, service_callback, &service);
|
||||
}
|
||||
FD_SET(sockets[isock], &readfs);
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
printf("Sending goodbye\n");
|
||||
additional_count = 0;
|
||||
additional[additional_count++] = service.record_srv;
|
||||
additional[additional_count++] = service.record_a;
|
||||
additional[additional_count++] = service.txt_record[0];
|
||||
additional[additional_count++] = service.txt_record[1];
|
||||
|
||||
for (int isock = 0; isock < num_sockets; ++isock)
|
||||
mdns_goodbye_multicast(sockets[isock], buffer, capacity, service.record_ptr, 0, 0, additional, additional_count);
|
||||
|
||||
free(buffer);
|
||||
free(service_name_buffer);
|
||||
|
||||
for (int isock = 0; isock < num_sockets; ++isock)
|
||||
mdns_socket_close(sockets[isock]);
|
||||
printf("Closed socket%s\n", num_sockets > 1 ? "s" : "");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -1045,7 +1320,7 @@ service_mdns(const char* hostname, const char* service_name, int service_port) {
|
|||
static int
|
||||
dump_mdns(void) {
|
||||
int sockets[32];
|
||||
int num_sockets = open_service_sockets(sockets, sizeof(sockets) / sizeof(sockets[0]));
|
||||
int num_sockets = open_service_sockets(sockets, sizeof(sockets) / sizeof(sockets[0]), "192.168.1.170");
|
||||
if (num_sockets <= 0) {
|
||||
printf("Failed to open any client sockets\n");
|
||||
return -1;
|
||||
|
|
|
@ -177,7 +177,7 @@ struct mdns_query_t {
|
|||
};
|
||||
|
||||
int
|
||||
service_mdns(const char* hostname, const char* service_name, int service_port);
|
||||
service_mdns(const char* hostname, const char* service_name, int service_port, const char* local_ip);
|
||||
|
||||
// mDNS/DNS-SD public API
|
||||
|
||||
|
|
|
@ -176,7 +176,7 @@ void DataHandler::handleData(const QString& client, const QByteArray& recv
|
|||
(msg_id != 0x0021 || clientLastMsgId.value(client, 0) != 0x0021) &&
|
||||
(msg_id != START_VIDEO || clientLastMsgId.value(client, 0) != START_VIDEO)) {
|
||||
//qDebug() << "Emitting statusUpdated for client:" << client << "with msg_id:" << QString::number(msg_id, 16).toUpper();
|
||||
emit statusUpdated(client, success, jsonArray, itemJsonIndex);
|
||||
emit statusUpdated(1, client, success, jsonArray, itemJsonIndex);
|
||||
}
|
||||
clientLastMsgId[client] = msg_id;
|
||||
}
|
||||
|
@ -330,7 +330,7 @@ void DataHandler::handleFrontCmd(int msg_id, const QString& client, QByteArray a
|
|||
picBuffer->append(yuvData);
|
||||
showPic(labelSize, lens_n, width, height, format, picBuffer);
|
||||
QJsonObject currentTempItem = jsonArray[itemJsonIndex].toObject();
|
||||
emit statusUpdated(client, true, jsonArray, itemJsonIndex);
|
||||
emit statusUpdated(-1, client, true, jsonArray, itemJsonIndex);
|
||||
picBuffer->remove(0, picSize);
|
||||
}
|
||||
else if (yuvData.size() + picBuffer->size() > picSize) {
|
||||
|
@ -349,7 +349,7 @@ void DataHandler::handleFrontCmd(int msg_id, const QString& client, QByteArray a
|
|||
if (!isStartVideo) {
|
||||
isStartVideo = ffmpegDecoder->isStartVideo;
|
||||
if (isStartVideo) {
|
||||
emit statusUpdated(client, true, getVideoJson, 0);
|
||||
emit statusUpdated(-1, client, true, getVideoJson, 0);
|
||||
}
|
||||
}
|
||||
showVideo(client, actual_data);
|
||||
|
@ -358,7 +358,7 @@ void DataHandler::handleFrontCmd(int msg_id, const QString& client, QByteArray a
|
|||
case STOP_VIDEO:
|
||||
{
|
||||
isStartVideo = false;
|
||||
emit statusUpdated(client, true, jsonArray, itemJsonIndex);
|
||||
emit statusUpdated(-1, client, true, jsonArray, itemJsonIndex);
|
||||
/*qDebug() << "--- STOP_VIDEO Current path: " << QDir::currentPath();
|
||||
QString filePath = QDir::currentPath() + "/add1.h264";
|
||||
if (QFile::exists(filePath)) {
|
||||
|
@ -554,7 +554,7 @@ void DataHandler::handleBackCmd(int msg_id, const QString& client, QByteArray ac
|
|||
if (!isStartVideo) {
|
||||
isStartVideo = ffmpegDecoder->isStartVideo;
|
||||
if (isStartVideo) {
|
||||
emit statusUpdated(client, true, jsonArray, itemJsonIndex);
|
||||
emit statusUpdated(1, client, true, jsonArray, itemJsonIndex);
|
||||
}
|
||||
}
|
||||
QJsonObject jsonObject = jsonArray[itemJsonIndex].toObject();
|
||||
|
@ -563,7 +563,7 @@ void DataHandler::handleBackCmd(int msg_id, const QString& client, QByteArray ac
|
|||
}
|
||||
else if (jsonObject["val"] == 1) {
|
||||
isStartVideo = false;
|
||||
emit statusUpdated(client, true, jsonArray, itemJsonIndex);
|
||||
emit statusUpdated(1, client, true, jsonArray, itemJsonIndex);
|
||||
qDebug() << "--- STOP_VIDEO";
|
||||
|
||||
if (ffmpegDecoder) {
|
||||
|
|
|
@ -50,7 +50,7 @@ public slots:
|
|||
const QJsonArray& jsonArray, int itemJsonIndex);
|
||||
void getCurrentSendItem(const QString& text);
|
||||
signals:
|
||||
void statusUpdated(const QString& clientAddress, bool success, const QJsonArray& jsonArray, int itemJsonIndex);
|
||||
void statusUpdated(int boardTpye, const QString& clientAddress, bool success, const QJsonArray& jsonArray, int itemJsonIndex);
|
||||
void updateLicenseHwInfoEdit(const QString& text);
|
||||
void updateUuidHwInfoEdit(const QString& text);
|
||||
void updateLeftLensImage(const QPixmap& pixmap);
|
||||
|
|
|
@ -0,0 +1,603 @@
|
|||
// RecvDataHandler.cpp
|
||||
#include "SerialRecvDataHandler.h"
|
||||
#include "../Network/ClientHandler.h"
|
||||
|
||||
SerialDataHandler::SerialDataHandler(QLabel* videoLabel, QLabel* video_Label_back, QLineEdit* VideoResolutionEdit, QLineEdit* VideoResolutionEdit_back,
|
||||
QSize labelSize, QMap<QString, QLineEdit*>* devInfoLineEdits, int isBackBoardOrAllBoard,
|
||||
QJsonArray frontBoardOneClickTest, QJsonArray frontBoardTest, QJsonArray frontBoardFuncConfig,
|
||||
QJsonArray frontBoardDevInfoJson, QJsonArray frontBoardLicenseJson,
|
||||
QJsonArray backBoardOneClickTest, QJsonArray backBoardTest, QJsonArray backBoardFuncConfig,
|
||||
QJsonArray backBoardDevInfoJson, QJsonArray backBoardUuidJson,
|
||||
QJsonArray getPicJson, QJsonArray getVideoJson, QObject* parent)
|
||||
: QObject(parent),
|
||||
videoLabel(videoLabel),
|
||||
video_Label_back(video_Label_back),
|
||||
VideoResolutionEdit(VideoResolutionEdit),
|
||||
VideoResolutionEdit_back(VideoResolutionEdit_back),
|
||||
labelSize(labelSize),
|
||||
devInfoLineEdits(devInfoLineEdits),
|
||||
isBackBoardOrAllBoard(isBackBoardOrAllBoard),
|
||||
frontBoardOneClickTest(frontBoardOneClickTest), frontBoardTest(frontBoardTest),
|
||||
frontBoardFuncConfig(frontBoardFuncConfig), frontBoardDevInfoJson(frontBoardDevInfoJson),
|
||||
frontBoardLicenseJson(frontBoardLicenseJson),
|
||||
backBoardOneClickTest(backBoardOneClickTest), backBoardTest(backBoardTest),
|
||||
backBoardFuncConfig(backBoardFuncConfig), backBoardDevInfoJson(backBoardDevInfoJson),
|
||||
backBoardUuidJson(backBoardUuidJson), getPicJson(getPicJson), getVideoJson(getVideoJson),
|
||||
buffer(new QByteArray()), picBuffer(new QByteArray()),
|
||||
ffmpegDecoder(new FFmpegDecoder()) // 初始化FFmpeg解码器
|
||||
{
|
||||
//ffmpegDecoder->initialize(); // 初始化解码器
|
||||
clearAllRecvData();
|
||||
initializeMsgIdToCmdMap();
|
||||
qDebug() << "SerialDataHandler thread created";
|
||||
}
|
||||
|
||||
SerialDataHandler::~SerialDataHandler()
|
||||
{
|
||||
qDebug() << "DataHandler thread destroyed start......";
|
||||
if (ffmpegDecoder) {
|
||||
ffmpegDecoder->stopFFmpegDecoder();
|
||||
ffmpegDecoder->requestInterruption();
|
||||
ffmpegDecoder->wait(); // 等待解码器线程完成
|
||||
delete ffmpegDecoder;
|
||||
ffmpegDecoder = nullptr;
|
||||
}
|
||||
delete buffer;
|
||||
buffer = nullptr;
|
||||
qDebug() << "DataHandler thread destroyed";
|
||||
}
|
||||
|
||||
void SerialDataHandler::handleOpenFocusWindow(int itemIndex)
|
||||
{
|
||||
if (ffmpegDecoder) {
|
||||
ffmpegDecoder->processVideo(itemIndex); // 调用 FFmpegDecoder 的处理函数
|
||||
}
|
||||
}
|
||||
|
||||
QByteArray SerialDataHandler::hexStringToByteArray(const QString& hexString)
|
||||
{
|
||||
QByteArray byteArray;
|
||||
for (int i = 0; i < hexString.length(); i += 2) {
|
||||
byteArray.append(static_cast<char>(hexString.mid(i, 2).toUShort(nullptr, 16)));
|
||||
}
|
||||
return byteArray;
|
||||
}
|
||||
|
||||
const QString filePath_1 = "/add1.h264";
|
||||
|
||||
// 显示视频的函数
|
||||
void SerialDataHandler::showVideo(const QString& client, const QByteArray& valData)
|
||||
{
|
||||
QString h264filePath = QDir::currentPath() + filePath_1;
|
||||
static QFile file(h264filePath);
|
||||
|
||||
if (!file.isOpen()) {
|
||||
if (QFile::exists(h264filePath)) {
|
||||
QFile::remove(h264filePath);
|
||||
}
|
||||
if (!file.open(QIODevice::Append | QIODevice::WriteOnly)) {
|
||||
qWarning() << "无法打开H264文件:" << file.errorString();
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!valData.isEmpty()) {
|
||||
file.write(valData);
|
||||
file.flush(); // 刷新文件缓冲区
|
||||
}
|
||||
|
||||
if (!start_run) {
|
||||
ffmpegDecoder->initialize(); // 初始化解码器
|
||||
start_run = 1;
|
||||
ffmpegDecoder->decodeFile(h264filePath, isBackBoardOrAllBoard, videoLabel, video_Label_back, VideoResolutionEdit, VideoResolutionEdit_back);
|
||||
}
|
||||
//ffmpegDecoder->decodeFile(filePath_1, videoLabel);
|
||||
}
|
||||
|
||||
void SerialDataHandler::updateLineEdit(int msg_id, const QByteArray& actual_data) {
|
||||
QString dataStr = QString(actual_data.toHex(' '));
|
||||
//licenseHwInfoEdit->setPlainText(dataStr);
|
||||
emit updateLicenseHwInfoEdit(dataStr);
|
||||
|
||||
if (msgIdToCmdMap.contains(msg_id)) {
|
||||
QString cmd = msgIdToCmdMap[msg_id];
|
||||
if (devInfoLineEdits->contains(cmd)) {
|
||||
QLineEdit* lineEdit = devInfoLineEdits->value(cmd);
|
||||
//lineEdit->setText(dataStr);
|
||||
QMetaObject::invokeMethod(lineEdit, "setText", Qt::QueuedConnection, Q_ARG(QString, dataStr));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SerialDataHandler::clearAllRecvData() {
|
||||
allRecvData = QByteArray();
|
||||
remain = 0;
|
||||
dataLen = 0;
|
||||
}
|
||||
|
||||
void SerialDataHandler::onUpdateTimeout(bool timeoutFlag)
|
||||
{
|
||||
isTimeout = timeoutFlag;
|
||||
}
|
||||
|
||||
// 前板没有回复的话不能发送下一个,但是超时了我必须发下一个
|
||||
|
||||
// 处理接收到的数据
|
||||
void SerialDataHandler::handleData(const QString& client, const QByteArray& recvData, int msg_id,
|
||||
int currentRecvItemIndex, int currentRecvFuncItemIndex, const QString& itemData,
|
||||
const QString& funcItemData, const QJsonArray& jsonArray, int itemJsonIndex, bool timeoutFlag)
|
||||
{
|
||||
//qDebug() << "Data received from" << client << ":" << recvData;
|
||||
#if 0
|
||||
从文件中读取YUV数据
|
||||
QFile file("output_2.txt");
|
||||
if (!file.open(QIODevice::ReadOnly)) {
|
||||
qWarning() << "Failed to open file:";
|
||||
file.close();
|
||||
return;
|
||||
}
|
||||
|
||||
QByteArray recvdata = file.readAll(); // 读取文件中的数据
|
||||
file.close();
|
||||
|
||||
qDebug() << "read file data size:" << recvdata.size();
|
||||
#endif
|
||||
qDebug() << "---Received data size:" << recvData.size();
|
||||
// 将接收到的数据追加到buffer
|
||||
buffer->append(recvData);
|
||||
while (buffer->size() >= 11) { // 至少需要11个字节来解析数据头
|
||||
|
||||
if (buffer->mid(0, 11) == QByteArray::fromHex("aa55aa5538010100000000")) {
|
||||
/*for (int i = 0; i < recvData.size(); i++) {
|
||||
qDebug() << "buffer->at(" << i << "):" << QString::number(static_cast<unsigned char>(buffer->at(i)), 16).toUpper();
|
||||
}*/
|
||||
QByteArray payload;
|
||||
payload.append(static_cast<char>(0x00)); // 构造发送的数据内容
|
||||
bool heartBeat = true;
|
||||
emit sendHeartBeatData(payload, heartBeat);
|
||||
buffer->remove(0, 11); // 移除已处理的数据
|
||||
//buffer->remove(0, recvData.size()); // 移除已处理的数据
|
||||
emit statusUpdated(-2, client, true, jsonArray, itemJsonIndex);
|
||||
//break;
|
||||
continue;
|
||||
}
|
||||
else if (buffer->mid(0, 10) == QByteArray::fromHex("aa55aa55390103000000")) {
|
||||
buffer->remove(0, 13); // 移除已处理的数据
|
||||
break;
|
||||
}
|
||||
else if ((buffer->mid(0, 6) == QByteArray::fromHex("aa55aa553701")) ||
|
||||
(buffer->mid(0, 6) == QByteArray::fromHex("aa55aa551100")) ||
|
||||
(buffer->mid(0, 6) == QByteArray::fromHex("aa55aa552100"))) {
|
||||
int dataSize = (static_cast<unsigned char>(buffer->at(9)) << 24) |
|
||||
(static_cast<unsigned char>(buffer->at(8)) << 16) |
|
||||
(static_cast<unsigned char>(buffer->at(7)) << 8) |
|
||||
(static_cast<unsigned char>(buffer->at(6)));
|
||||
if (buffer->size() >= dataSize + 10)
|
||||
buffer->remove(0, dataSize + 10); // 移除已处理的数据
|
||||
break;
|
||||
}
|
||||
else if (buffer->mid(0, 4) == QByteArray::fromHex("aa55aa55")) {
|
||||
emit startTimeout(0);
|
||||
msg_id = (static_cast<unsigned char>(buffer->at(5)) << 8) |
|
||||
(static_cast<unsigned char>(buffer->at(4)));
|
||||
int dataSize = (static_cast<unsigned char>(buffer->at(9)) << 24) |
|
||||
(static_cast<unsigned char>(buffer->at(8)) << 16) |
|
||||
(static_cast<unsigned char>(buffer->at(7)) << 8) |
|
||||
(static_cast<unsigned char>(buffer->at(6)));
|
||||
qDebug() << "---Received dataSize:" << dataSize;
|
||||
//qDebug() << "---Received buffer->size():" << buffer->size();
|
||||
//qDebug() << "---msg_id:" << QString::number(msg_id, 16).toUpper();
|
||||
// 第11字节为返回 OK/NG
|
||||
bool success = (static_cast<unsigned char>(buffer->at(10)) != 0x00);
|
||||
int totalSize = 10 + dataSize; // 数据头大小(10字节) + 实际数据大小
|
||||
if (CurrentCommand == "GET_BACK_MAC") {
|
||||
//qDebug() << "--- getCommandNameFromValue:" << msg_id;
|
||||
if (!getCommandNameFromValue(msg_id)) {
|
||||
//qDebug() << "--- getCommandNameFromValue:" << msg_id;
|
||||
buffer->remove(0, buffer->size());
|
||||
emit commandError();
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (buffer->size() >= totalSize) {
|
||||
//qDebug() << "--- getCommandNameFromValue:" << msg_id;
|
||||
// 调试查看收到的前19个字节
|
||||
/*for (int i = 0; i < 11; i++) {
|
||||
qDebug() << "buffer->at(" << i << "):" << QString::number(static_cast<unsigned char>(buffer->at(i)), 16).toUpper();
|
||||
}*/
|
||||
QByteArray data = buffer->mid(11, dataSize);
|
||||
QString hexString = QString::fromUtf8(data.toHex().data());
|
||||
QByteArray actual_data = hexStringToByteArray(hexString);
|
||||
buffer->remove(0, totalSize); // 移除已处理的数据
|
||||
qDebug() << "-------------------------------------------- isTimeout:" << isTimeout;
|
||||
if (!isTimeout)
|
||||
{
|
||||
if (msg_id != 0x0040 && msg_id != START_VIDEO && msg_id != GET_IMG && msg_id != VIDEO_TEST &&
|
||||
msg_id != STOP_VIDEO) {
|
||||
qDebug() << "--- msg_id:" << QString::number(msg_id, 16).toUpper();
|
||||
qDebug() << "--- clientLastMsgId.value(client, 0):" << clientLastMsgId.value(client, 0);
|
||||
qDebug() << "--- success:" << success;
|
||||
//qDebug() << "--- itemJsonIndex:" << itemJsonIndex;
|
||||
if ((msg_id != 0x0011 || clientLastMsgId.value(client, 0) != 0x0011) &&
|
||||
(msg_id != 0x0021 || clientLastMsgId.value(client, 0) != 0x0021) &&
|
||||
(msg_id != START_VIDEO || clientLastMsgId.value(client, 0) != START_VIDEO)) {
|
||||
//qDebug() << "Emitting statusUpdated for client:" << client << "with msg_id:" << QString::number(msg_id, 16).toUpper();
|
||||
emit statusUpdated(-1, client, success, jsonArray, itemJsonIndex);
|
||||
emit recvNormalDataFlag(true);
|
||||
}
|
||||
clientLastMsgId[client] = msg_id;
|
||||
}
|
||||
handleCmd(msg_id, client, actual_data, jsonArray, itemJsonIndex);
|
||||
}
|
||||
}
|
||||
else {
|
||||
break; // 数据还不完整,等待下一次接收
|
||||
}
|
||||
}
|
||||
else {
|
||||
buffer->remove(0, 1); // 移除无效数据头
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SerialDataHandler::getCurrentSendItem(const QString& text) {
|
||||
CurrentCommand = text;
|
||||
}
|
||||
|
||||
// 初始化映射表
|
||||
std::map<QString, int> commandValueMap_serical = {
|
||||
{"FACE_ENROLL_SINGLE", FACE_ENROLL_SINGLE},
|
||||
{"FACE_ENROLL", FACE_ENROLL},
|
||||
{"HAND_ENROLL", HAND_ENROLL},
|
||||
{"FACE_VERIFY", FACE_VERIFY},
|
||||
{"HAND_VERIFY", HAND_VERIFY},
|
||||
{"DEL_USER", DEL_USER},
|
||||
{"DEL_ALLUSER", DEL_ALLUSER},
|
||||
{"GET_USER", GET_USER},
|
||||
{"GET_ALLUSER", GET_ALLUSER},
|
||||
{"PASSWD_ENROLL", PASSWD_ENROLL},
|
||||
{"IMG_ENROLL", IMG_ENROLL},
|
||||
{"GET_IMG", GET_IMG},
|
||||
{"START_VIDEO", START_VIDEO},
|
||||
{"STOP_VIDEO", STOP_VIDEO},
|
||||
{"TOUCH_TEST", TOUCH_TEST},
|
||||
{"MIC_TEST", MIC_TEST},
|
||||
{"SPK_TEST", SPK_TEST},
|
||||
{"RADAR_TEST", RADAR_TEST},
|
||||
{"NFC_TEST", NFC_TEST},
|
||||
{"PR_SWITCH", PR_SWITCH},
|
||||
{"PS_TEST", PS_TEST},
|
||||
{"BACKLIGHT", BACKLIGHT},
|
||||
{"IR_LED", IR_LED},
|
||||
{"UART_TEST", UART_TEST},
|
||||
{"PIR_TEST", PIR_TEST},
|
||||
{"FACE_VERIFY_THRES", FACE_VERIFY_THRES},
|
||||
{"FACE_THRES_LEVEL", FACE_THRES_LEVEL},
|
||||
{"FACE_LIVE_THRES", FACE_LIVE_THRES},
|
||||
{"FACE_ACC_THRES", FACE_ACC_THRES},
|
||||
{"FACE_ACC_LEVEL", FACE_ACC_LEVEL},
|
||||
{"FACE_DIS_RANGE", FACE_DIS_RANGE},
|
||||
{"FACE_ANGLE_RANGE", FACE_ANGLE_RANGE},
|
||||
|
||||
{"GET_BACK_MAC", GET_BACK_MAC},
|
||||
{"WRITE_BACK_UID_SN", WRITE_BACK_UID_SN}
|
||||
};
|
||||
|
||||
bool SerialDataHandler::getCommandNameFromValue(int receivedValue) {
|
||||
auto it = commandValueMap_serical.find(CurrentCommand);
|
||||
if (it != commandValueMap_serical.end()) {
|
||||
int expectedValue = it->second;
|
||||
if (expectedValue == receivedValue) {
|
||||
std::cout << "Match found: " << CurrentCommand.toStdString() << " corresponds to value " << std::hex << expectedValue << std::endl;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
std::cout << "Value mismatch: Expected " << std::hex << expectedValue << ", but received " << std::hex << receivedValue << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
std::cout << "Unknown command: " << CurrentCommand.toStdString() << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void SerialDataHandler::initializeMsgIdToCmdMap() {
|
||||
msgIdToCmdMap[GET_FRONT_V851_VERSION] = "GET_FRONT_V851_VERSION";
|
||||
msgIdToCmdMap[GET_FRONT_MCU_VERSION] = "GET_FRONT_MCU_VERSION";
|
||||
msgIdToCmdMap[GET_FRONT_HW_VERSION] = "GET_FRONT_HW_VERSION";
|
||||
msgIdToCmdMap[GET_FRONT_ALGO_VERSION] = "GET_FRONT_ALGO_VERSION";
|
||||
msgIdToCmdMap[GET_FRONT_SN] = "GET_FRONT_SN";
|
||||
|
||||
msgIdToCmdMap[GET_BACK_V851_VERSION] = "GET_BACK_V851_VERSION";
|
||||
msgIdToCmdMap[GET_BACK_806_VERSION] = "GET_BACK_806_VERSION";
|
||||
msgIdToCmdMap[GET_BACK_HW_VERSION] = "GET_BACK_HW_VERSION";
|
||||
}
|
||||
|
||||
void SerialDataHandler::handleCmd(int msg_id, const QString& client, QByteArray actual_data, const QJsonArray& jsonArray, int itemJsonIndex)
|
||||
{
|
||||
if (msg_id < 0x0400) {
|
||||
handleFrontCmd(msg_id, client, actual_data, jsonArray, itemJsonIndex);
|
||||
}
|
||||
else if (msg_id < 0x0500) {
|
||||
handleDevInfo(msg_id, client, actual_data);
|
||||
}
|
||||
else if (msg_id < 0x0800) {
|
||||
//handleBackCmd(msg_id, client, actual_data, jsonArray, itemJsonIndex);
|
||||
}
|
||||
}
|
||||
|
||||
void SerialDataHandler::handleFrontCmd(int msg_id, const QString& client, QByteArray actual_data, const QJsonArray& jsonArray, int itemJsonIndex)
|
||||
{
|
||||
switch (msg_id) {
|
||||
case FACE_ENROLL_SINGLE:
|
||||
{}
|
||||
break;
|
||||
case FACE_ENROLL:
|
||||
{}
|
||||
break;
|
||||
case HAND_ENROLL:
|
||||
{}
|
||||
break;
|
||||
case FACE_VERIFY:
|
||||
{}
|
||||
break;
|
||||
case HAND_VERIFY:
|
||||
{}
|
||||
break;
|
||||
case DEL_USER:
|
||||
{}
|
||||
break;
|
||||
case DEL_ALLUSER:
|
||||
{}
|
||||
break;
|
||||
case GET_USER:
|
||||
{}
|
||||
break;
|
||||
case GET_ALLUSER:
|
||||
{}
|
||||
break;
|
||||
case PASSWD_ENROLL:
|
||||
{}
|
||||
break;
|
||||
case IMG_ENROLL:
|
||||
{}
|
||||
break;
|
||||
case GET_IMG:
|
||||
{
|
||||
int lens_n = static_cast<unsigned char>(actual_data[1]);
|
||||
int width = (static_cast<unsigned char>(actual_data[3]) << 8) | static_cast<unsigned char>(actual_data[2]);
|
||||
int height = (static_cast<unsigned char>(actual_data[5]) << 8) | static_cast<unsigned char>(actual_data[4]);
|
||||
int format = static_cast<unsigned char>(actual_data[6]);
|
||||
qint32 picSize = width * height * 1.5;
|
||||
QByteArray yuvData = actual_data.mid(7);
|
||||
qDebug() << "showPic width * height * 1.5:" << picSize;
|
||||
qDebug() << "showPic picBuffer.size():" << picBuffer->size();
|
||||
qDebug() << "showPic yuvData.size():" << yuvData.size();
|
||||
if (yuvData.size() + picBuffer->size() == picSize) {
|
||||
emit picRecvFinished();
|
||||
picBuffer->append(yuvData);
|
||||
showPic(labelSize, lens_n, width, height, format, picBuffer);
|
||||
QJsonObject currentTempItem = jsonArray[itemJsonIndex].toObject();
|
||||
emit statusUpdated(-1, client, true, jsonArray, itemJsonIndex);
|
||||
picBuffer->remove(0, picSize);
|
||||
}
|
||||
else if (yuvData.size() + picBuffer->size() > picSize) {
|
||||
picBuffer->append(yuvData);
|
||||
qDebug() << "width is " << width << " height is " << height << "PIC size is" << picSize;
|
||||
qDebug() << "But recv PIC size is " << picBuffer->size();
|
||||
picBuffer->remove(0, picBuffer->size());
|
||||
}
|
||||
else {
|
||||
picBuffer->append(yuvData);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case START_VIDEO:
|
||||
{
|
||||
if (!isStartVideo) {
|
||||
isStartVideo = ffmpegDecoder->isStartVideo;
|
||||
if (isStartVideo) {
|
||||
emit statusUpdated(-1, client, true, getVideoJson, 0);
|
||||
}
|
||||
}
|
||||
showVideo(client, actual_data);
|
||||
}
|
||||
break;
|
||||
case STOP_VIDEO:
|
||||
{
|
||||
isStartVideo = false;
|
||||
emit statusUpdated(-1, client, true, jsonArray, itemJsonIndex);
|
||||
/*qDebug() << "--- STOP_VIDEO Current path: " << QDir::currentPath();
|
||||
QString filePath = QDir::currentPath() + "/add1.h264";
|
||||
if (QFile::exists(filePath)) {
|
||||
QFile file(filePath);
|
||||
if (file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
|
||||
qDebug() << "File add1.h264 cleared successfully.";
|
||||
}
|
||||
else {
|
||||
qDebug() << "Failed to clear file add1.h264:" << file.errorString();
|
||||
}
|
||||
}
|
||||
else {
|
||||
qDebug() << "File add1.h264 does not exist.";
|
||||
}*/
|
||||
}
|
||||
break;
|
||||
case TOUCH_TEST:
|
||||
{}
|
||||
break;
|
||||
case MIC_TEST:
|
||||
{}
|
||||
break;
|
||||
case SPK_TEST:
|
||||
{}
|
||||
break;
|
||||
case RADAR_TEST:
|
||||
{}
|
||||
break;
|
||||
case NFC_TEST:
|
||||
{}
|
||||
break;
|
||||
case PR_SWITCH:
|
||||
{}
|
||||
break;
|
||||
case PS_TEST:
|
||||
{}
|
||||
break;
|
||||
case BACKLIGHT:
|
||||
{}
|
||||
break;
|
||||
case IR_LED:
|
||||
{}
|
||||
break;
|
||||
case UART_TEST:
|
||||
{}
|
||||
break;
|
||||
case PIR_TEST:
|
||||
{}
|
||||
break;
|
||||
case FACE_VERIFY_THRES:
|
||||
{}
|
||||
break;
|
||||
case FACE_THRES_LEVEL:
|
||||
{}
|
||||
break;
|
||||
case FACE_LIVE_THRES:
|
||||
{}
|
||||
break;
|
||||
case FACE_ACC_THRES:
|
||||
{}
|
||||
break;
|
||||
case FACE_ACC_LEVEL:
|
||||
{}
|
||||
break;
|
||||
case FACE_DIS_RANGE:
|
||||
{}
|
||||
break;
|
||||
case FACE_ANGLE_RANGE:
|
||||
{}
|
||||
break;
|
||||
case HAND_VERIFY_THRES:
|
||||
{}
|
||||
break;
|
||||
case HANS_THRES_LEVEL:
|
||||
{}
|
||||
break;
|
||||
case HAND_LIVE_THRES:
|
||||
{}
|
||||
break;
|
||||
case USER_MAX_NUM:
|
||||
{}
|
||||
break;
|
||||
case ADMI_USER_MAX_NUM:
|
||||
{}
|
||||
break;
|
||||
case FACE_REPEAT:
|
||||
{}
|
||||
break;
|
||||
case HAND_REPEAT:
|
||||
{}
|
||||
break;
|
||||
case SET_IP:
|
||||
{}
|
||||
break;
|
||||
case SET_PORT:
|
||||
{}
|
||||
break;
|
||||
case SET_VOLUME:
|
||||
{}
|
||||
break;
|
||||
case SET_BACKLIGHT:
|
||||
{}
|
||||
break;
|
||||
case SET_RADAR_DIS:
|
||||
{}
|
||||
break;
|
||||
case SET_UART_BARTRATE:
|
||||
{}
|
||||
break;
|
||||
case SET_LOG_LEVEL:
|
||||
{}
|
||||
break;
|
||||
default:
|
||||
{}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SerialDataHandler::handleDevInfo(int msg_id, const QString& client, QByteArray actual_data)
|
||||
{
|
||||
qDebug() << "actual_data.size(): " << actual_data.size();
|
||||
qDebug() << "actual_data: " << QString::fromUtf8(actual_data.toHex().data());
|
||||
switch (msg_id) {
|
||||
case GET_FRONT_V851_VERSION:
|
||||
case GET_FRONT_MCU_VERSION:
|
||||
case GET_FRONT_HW_VERSION:
|
||||
case GET_FRONT_ALGO_VERSION:
|
||||
case GET_FRONT_SN:
|
||||
|
||||
case GET_BACK_V851_VERSION:
|
||||
case GET_BACK_806_VERSION:
|
||||
case GET_BACK_HW_VERSION:
|
||||
/*case GET_BACK_SN:
|
||||
case GET_BACK_UID:*/
|
||||
{
|
||||
// aa55aa5503041d00000048464d3231305f4b3431343234395f423230323031305f41302e302e38
|
||||
qDebug() << "GET_DEV_INFO";
|
||||
QString dataStr = QString::fromUtf8(actual_data);
|
||||
if (msgIdToCmdMap.contains(msg_id)) {
|
||||
QString cmd = msgIdToCmdMap[msg_id];
|
||||
// 删掉注释闪退,暂时还未查到原因
|
||||
qDebug() << "-----------------devInfoLineEdits-------------start";
|
||||
//qDebug() << "devInfoLineEdits belongs to thread:" << devInfoLineEdits->thread();
|
||||
qDebug() << "Current thread:" << QThread::currentThread();
|
||||
if (devInfoLineEdits->contains(cmd)) {
|
||||
QLineEdit* lineEdit = devInfoLineEdits->value(cmd);
|
||||
//lineEdit->setText(dataStr);
|
||||
QMetaObject::invokeMethod(lineEdit, "setText", Qt::QueuedConnection, Q_ARG(QString, dataStr));
|
||||
}
|
||||
qDebug() << "-----------------devInfoLineEdits-------------end";
|
||||
}
|
||||
//qDebug() << "GET_DEV_INFO msg_id:" << QString::number(msg_id, 16).toUpper();
|
||||
}
|
||||
break;
|
||||
case GET_FRONT_HW_INFO:
|
||||
{
|
||||
qDebug() << "GET_FRONT_HW_INFO";
|
||||
QStringList hexList;
|
||||
QString dataStr;
|
||||
if (actual_data.size() == PIX_HARDWARE_INFO_BYTES) {
|
||||
for (int i = 0; i < actual_data.size(); ++i) {
|
||||
hexList << QString("0x%1").arg(static_cast<unsigned char>(actual_data[i]), 2, 16, QLatin1Char('0')).toUpper().replace("0X", "0x");
|
||||
}
|
||||
dataStr = hexList.join(", ");
|
||||
}
|
||||
else
|
||||
dataStr = "前板发送的 HW INFO 数据大小不正确";
|
||||
QString displayText = dataStr;
|
||||
//licenseHwInfoEdit->setPlainText(displayText);
|
||||
emit updateLicenseHwInfoEdit(displayText);
|
||||
}
|
||||
break;
|
||||
case GET_BACK_MAC:
|
||||
{
|
||||
qDebug() << "GET_BACK_MAC";
|
||||
QString dataStr;
|
||||
if (actual_data.size() == BACK_MAC_ADDRESS_LEN) {
|
||||
for (int i = 0; i < actual_data.size(); ++i) {
|
||||
char ch = static_cast<unsigned char>(actual_data[i]);
|
||||
dataStr.append(ch);
|
||||
}
|
||||
}
|
||||
else
|
||||
dataStr = "后板发送的 MAC addr 数据大小不正确";
|
||||
QString displayText = dataStr;
|
||||
emit updateUuidHwInfoEdit(displayText);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,121 @@
|
|||
// SerialRecvDataHandler.h
|
||||
#ifndef SERIALRECVDATAHANDLER_H
|
||||
#define SERIALRECVDATAHANDLER_H
|
||||
|
||||
#include <QObject>
|
||||
#include <QByteArray>
|
||||
#include <QLabel>
|
||||
#include <QGroupBox>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
#include <QPixmap>
|
||||
#include <QBuffer>
|
||||
#include <QImage>
|
||||
#include <QVBoxLayout>
|
||||
#include <QDebug>
|
||||
#include <QFile>
|
||||
#include <QThread>
|
||||
#include <QElapsedTimer>
|
||||
#include <QLineEdit>
|
||||
#include <QTextEdit>
|
||||
|
||||
#include "../Media/Media.h"
|
||||
#include "../Media/VideoDecoder/FFmpegDecoder.h"
|
||||
#include "../LicenseGenerate/LicenseGenerate.h"
|
||||
#include "MsgTpye.h"
|
||||
|
||||
#define YUV420 1
|
||||
#define YUV422 2
|
||||
|
||||
#define BACK_MAC_ADDRESS_LEN 17
|
||||
|
||||
class SerialDataHandler : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SerialDataHandler(QLabel* videoLabel, QLabel* video_Label_back, QLineEdit* VideoResolutionEdit, QLineEdit* VideoResolutionEdit_back,
|
||||
QSize labelSize, QMap<QString, QLineEdit*>* devInfoLineEdits, int isBackBoardOrAllBoard,
|
||||
QJsonArray frontBoardOneClickTest, QJsonArray frontBoardTest, QJsonArray frontBoardFuncConfig,
|
||||
QJsonArray frontBoardDevInfoJson, QJsonArray frontBoardLicenseJson,
|
||||
QJsonArray backBoardOneClickTest, QJsonArray backBoardTest, QJsonArray backBoardFuncConfig,
|
||||
QJsonArray backBoardDevInfoJson, QJsonArray backBoardUuidJson,
|
||||
QJsonArray getPicJson, QJsonArray getVideoJson, QObject* parent = nullptr);
|
||||
~SerialDataHandler();
|
||||
|
||||
public slots:
|
||||
void handleData(const QString& client, const QByteArray& data, int msg_id, int currentRecvItemIndex,
|
||||
int currentRecvFuncItemIndex, const QString& itemData, const QString& funcItemData,
|
||||
const QJsonArray& jsonArray, int itemJsonIndex, bool timeoutFlag);
|
||||
void getCurrentSendItem(const QString& text);
|
||||
|
||||
void onUpdateTimeout(bool timeoutFlag);
|
||||
void handleOpenFocusWindow(int itemIndex);
|
||||
signals:
|
||||
void statusUpdated(int boardTpye, const QString& clientAddress, bool success, const QJsonArray& jsonArray, int itemJsonIndex);
|
||||
void updateLicenseHwInfoEdit(const QString& text);
|
||||
void updateUuidHwInfoEdit(const QString& text);
|
||||
void updateLeftLensImage(const QPixmap& pixmap);
|
||||
void updateRightLensImage(const QPixmap& pixmap);
|
||||
void updateVideoLabel(const QPixmap& pixmap);
|
||||
void updateVideoResolution(const QString& resolutionText);
|
||||
void picRecvFinished();
|
||||
void commandError();
|
||||
void sendHeartBeatData(const QByteArray& payload, int heartBeat);
|
||||
void startTimeout(int timeout);
|
||||
void recvNormalDataFlag(bool flag);
|
||||
|
||||
private:
|
||||
QJsonArray frontBoardOneClickTest; // 前板一键功能测试 JSON
|
||||
QJsonArray frontBoardTest; // 前板单项测试 JSON
|
||||
QJsonArray frontBoardFuncConfig; // 前板功能配置参数 JSON
|
||||
QJsonArray frontBoardDevInfoJson; // 前板设备信息参数 JSON
|
||||
QJsonArray frontBoardLicenseJson; // 前板license信息 JSON
|
||||
QJsonArray backBoardOneClickTest; // 后板一键功能测试 JSON
|
||||
QJsonArray backBoardTest; // 后板单项测试 JSON
|
||||
QJsonArray backBoardFuncConfig; // 后板功能配置参数 JSON
|
||||
QJsonArray backBoardDevInfoJson; // 后板设备信息参数 JSON
|
||||
QJsonArray backBoardUuidJson; // 后板UUID和SN参数 JSON
|
||||
QJsonArray getDevInfoJson; // 获取设备信息 JSON 配置
|
||||
QJsonArray getPicJson; // 发送取图指令 JSON 配置
|
||||
QJsonArray getVideoJson; // 发送拉视频指令 JSON 配置
|
||||
//QLabel* leftLens_m_imageLabel;
|
||||
//QLabel* rightLens_m_imageLabel;
|
||||
QLabel* videoLabel;
|
||||
QLabel* video_Label_back;
|
||||
QLineEdit* VideoResolutionEdit;
|
||||
QLineEdit* VideoResolutionEdit_back;
|
||||
//QTextEdit* licenseHwInfoEdit;
|
||||
QByteArray allRecvData; // 完整的一帧数据
|
||||
int remain = 0;
|
||||
int start_run = 0;
|
||||
long dataLen = 0;
|
||||
int isBackBoardOrAllBoard = 0;
|
||||
FFmpegDecoder* ffmpegDecoder;
|
||||
QByteArray* buffer;
|
||||
QByteArray* picBuffer;
|
||||
QHash<QString, unsigned char> clientLastMsgId;
|
||||
QMap<QString, QLineEdit*>* devInfoLineEdits;
|
||||
QMap<int, QString> msgIdToCmdMap;
|
||||
QSize labelSize;
|
||||
bool isStartVideo = false;
|
||||
bool isTimeout = false;
|
||||
QString CurrentCommand = "";
|
||||
|
||||
bool getCommandNameFromValue(int receivedValue);
|
||||
QByteArray hexStringToByteArray(const QString& hexString);
|
||||
void showVideo(const QString& client, const QByteArray& valData);
|
||||
void clearAllRecvData();
|
||||
void handleCmd(int msg_id, const QString& client, QByteArray actual_data, const QJsonArray& jsonArray, int itemJsonIndex);
|
||||
void handleFrontCmd(int msg_id, const QString& client, QByteArray actual_data, const QJsonArray& jsonArray, int itemJsonIndex);
|
||||
void handleDevInfo(int msg_id, const QString& client, QByteArray actual_data);
|
||||
void initializeMsgIdToCmdMap();
|
||||
void updateLineEdit(int msg_id, const QByteArray& actual_data);
|
||||
void showPic(QSize labelSize, int lens_n,
|
||||
int width, int height, int format, const QByteArray* valData);
|
||||
};
|
||||
|
||||
#endif // SERIALDATAHANDLER_H
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
|
@ -46,13 +46,20 @@
|
|||
#include <QSettings>
|
||||
#include <QImage>
|
||||
#include <QPainter>
|
||||
#include <QComboBox>
|
||||
#include <QVector>
|
||||
#include <QSerialPortInfo>
|
||||
#include <QStringList>
|
||||
#include <QSerialPort>
|
||||
|
||||
#include <winsock2.h>
|
||||
#include <iphlpapi.h>
|
||||
|
||||
#include "./UI_Widget/UI_Name.h"
|
||||
#include "./SerialPortHandler/SerialPortHandler.h"
|
||||
#include "../Json/readJsonFile.h"
|
||||
#include "../RecvDataHandler/RecvDataHandler.h"
|
||||
#include "../RecvDataHandler/SerialRecvDataHandler.h"
|
||||
#include "../LicenseGenerate/LicenseGenerate.h"
|
||||
#include "../LicenseGenerate/LicenseConfirmWindow.h"
|
||||
//#include "../Network/mdns/servicemodel.h"
|
||||
|
@ -68,20 +75,20 @@
|
|||
//#include "../Network/mdns/qmdnsengine/include/message.h"
|
||||
//#include "../Network/mdns/qmdnsengine/include/query.h"
|
||||
|
||||
#define TEST_UDP_BROADCAST 0 // 用于测试 UDP 组播实现 mdns 功能 非标准 mdns
|
||||
#define MANUAL_UPLOAD_LICENSE 0 // 打开手动上传 License的功能
|
||||
#define TEST_UDP_BROADCAST 0 // 用于测试 UDP 组播实现 mdns 功能 非标准 mdns
|
||||
#define MANUAL_UPLOAD_LICENSE 0 // 打开手动上传 License的功能
|
||||
#define START_MDNS 1
|
||||
#define FOCUS_WINDOWS_BUTTON 4 // 大窗口播放视频的按键编号
|
||||
#define TCP_CONNECT_PORT 12412 // TCP监听的端口
|
||||
#define FOCUS_WINDOWS_BUTTON 4 // 大窗口播放视频的按键编号
|
||||
#define TCP_CONNECT_PORT 12412 // TCP监听的端口
|
||||
#define GET_PIC_DATA_SIZE (480 * 640 * 1.5)
|
||||
|
||||
#define NEW_MAP 1
|
||||
|
||||
|
||||
#define FACTORY_ID "TEST" // 工厂ID
|
||||
#define LABEL "TEST_SL100_20240826" // 出货标签
|
||||
#define BATCH 1 // 出货批次
|
||||
#define MODEL "SL100" // 出货型号
|
||||
#define FACTORY_ID "TEST" // 工厂ID
|
||||
#define LABEL "TEST_SL100_20240826" // 出货标签
|
||||
#define BATCH 1 // 出货批次
|
||||
#define MODEL "SL100" // 出货型号
|
||||
|
||||
class MainWidget : public QWidget
|
||||
{
|
||||
|
@ -93,11 +100,18 @@ public:
|
|||
~MainWidget();
|
||||
|
||||
void startHttpServer(const QString& imagePath);
|
||||
void sendLicenseData(int itemIndex, const QString text);
|
||||
QByteArray hexStringToByteArray(const QString& hexString);
|
||||
|
||||
signals:
|
||||
void openFocusWindowRequested(int itemIndex);
|
||||
void serialComPortConnected();
|
||||
void requestDevInfo();
|
||||
void delUserDialogResult(const QString& userInput);
|
||||
void openFocusWindow(int itemIndex);
|
||||
|
||||
private slots:
|
||||
void onSerialDataReceived(const QByteArray& data);
|
||||
// 发送HTTP请求
|
||||
//void onSomeButtonClicked();
|
||||
// 处理HTTP响应
|
||||
|
@ -127,9 +141,9 @@ private slots:
|
|||
// 处理数据接收信号
|
||||
//void onDataReceived(const QString& client, const QByteArray& data);
|
||||
// 处理状态更新信号
|
||||
void onStatusUpdated(const QString& client, bool success, const QJsonArray& jsonArray, int itemJsonIndex);
|
||||
void onStatusUpdated(int boardTpye, const QString& client, bool success, const QJsonArray& jsonArray, int itemJsonIndex);
|
||||
// 处理所有项目处理完毕信号
|
||||
void onAllItemsProcessed(const QString& client, int itemsProcessedCount);
|
||||
void onAllItemsProcessed(int boardTpye, const QString& client, int itemsProcessedCount);
|
||||
// 处理客户端断开连接
|
||||
void onClientDisconnected(ClientHandler* handler);
|
||||
// 启动超时定时器
|
||||
|
@ -149,10 +163,14 @@ private slots:
|
|||
void onCheckConnectionStatus();
|
||||
void startClientReadTimer(int clientId);
|
||||
void stopClientReadTimer(int clientId);
|
||||
void onCheckSerialRecvStatus();
|
||||
void onShowDialog();
|
||||
#if TEST_UDP_BROADCAST
|
||||
void sendMulticastMessage();
|
||||
#endif
|
||||
|
||||
//void onIpSelectionChanged(const QString& selectedIp);
|
||||
|
||||
private:
|
||||
UI_config TOOL_UI;
|
||||
// 读取 test JSON 配置文件
|
||||
|
@ -168,6 +186,9 @@ private:
|
|||
QLabel* leftLensLabel, QLabel* rightLensLabel, QLabel* videoLabel,
|
||||
QLineEdit* VideoResolutionEdit_type);
|
||||
void addAllDeviceAreaTab(QTabWidget* mainTabWidget, const QString& tabName,
|
||||
const QJsonArray& boardTest, const QJsonArray& boardFuncConfig,
|
||||
const QString& boardTestName, const QString& boardFuncConfigName,
|
||||
const QString& boardTestTitle, const QString& boardConfigTitle,
|
||||
QLabel* leftLensLabel, QLabel* rightLensLabel, QLabel* videoLabel,
|
||||
QLineEdit* VideoResolutionEdit_type);
|
||||
QTabWidget* createMediaTabWidget(QLabel* leftLensLabel, QLabel* rightLensLabel, QLabel* videoLabel,
|
||||
|
@ -196,6 +217,8 @@ private:
|
|||
void FactoryToolSendPostComfirmToHttpServer(const QString& mac_addr, const QString& uuid);
|
||||
void FactoryToolSendGetUuidToHttpServer(const QString& mac_addr);
|
||||
void FactoryToolSendGetLicenseToHttpServer(const QString& hw_info);
|
||||
|
||||
char* getSelectedIp() const;
|
||||
|
||||
QTcpServer* server; // TCP 服务器
|
||||
HttpClient* httpClient; // HTTP 服务器
|
||||
|
@ -212,8 +235,8 @@ private:
|
|||
QJsonArray backBoardUuidJson; // 后板UUID JSON
|
||||
QJsonArray backBoardCmdConfigJson;
|
||||
QJsonArray factoryProductInfo; // 整机:工厂生产信息
|
||||
QJsonArray testJsonConfig; // 功能测试区 JSON 配置
|
||||
QJsonArray funcJsonConfig; // 功能配置区 JSON 配置
|
||||
QJsonArray allBoardTest; // 整机测试区 JSON 配置
|
||||
QJsonArray allBoardFuncConfig; // 整机功能配置区 JSON 配置
|
||||
QJsonArray getDevInfoJson; // 获取设备信息 JSON 配置
|
||||
QJsonArray getPicJson; // 发送取图指令 JSON 配置
|
||||
QJsonArray getVideoJson; // 发送拉视频指令 JSON 配置
|
||||
|
@ -225,14 +248,17 @@ private:
|
|||
QThreadPool threadPool; // 线程池
|
||||
QMutex mutex; // 互斥锁
|
||||
int nextClientId; // 新增的客户端编号
|
||||
int nextSerialId; // 新增的客户端编号
|
||||
int currentIndex = 0; // 新增的客户端编号
|
||||
int connectedClientsCount = 0; // 连接客户端的数量
|
||||
int isRequestSuccessful = 0; // GET请求是否成功
|
||||
int isBackBoardOrAllBoard = 0;
|
||||
bool manualSend; // 判断是否是手动触发的发送
|
||||
bool deviceConnected = false; // 判断是否有设备连接过
|
||||
bool isSendingAll; // 一键功能测试 状态
|
||||
bool checkBoxState = true;
|
||||
bool isReplyOrTimeout = true;
|
||||
bool checkBoxState = true;
|
||||
bool isReplyOrTimeout = true;
|
||||
bool isFirstSendDevInfo = true;
|
||||
|
||||
QJsonObject licenseDataArray; // 用于保存从服务器获取的 data 字段对象
|
||||
|
||||
|
@ -243,12 +269,17 @@ private:
|
|||
QVector<QPushButton*> getBackVideoButtons;
|
||||
QVector<QPushButton*> getAllVideoButtons;
|
||||
QList<ClientHandler*> clients; // 客户端处理器集合
|
||||
QList<SerialPortHandler*> serialPorts; // 客户端处理器集合
|
||||
QMap<int, QTimer*> clientTimers; // 每个客户端的定时器
|
||||
QMap<int, QTimer*> serialTimers; // 每个串口端的定时器
|
||||
QMap<QString, QLineEdit*> devInfoLineEdits;// msg_id 和对应的 QLineEdit 的映射关系
|
||||
QMap<QString, QLineEdit*> productInfoLineEdits;
|
||||
|
||||
QString cur_mac_addr;
|
||||
QString cur_UUID;
|
||||
QCheckBox* saveCheckBox; // 保存文件复选框
|
||||
QPushButton* selectFileButton; // Save Log 按键
|
||||
QPushButton* serialConnectButton; // 串口连接按键
|
||||
QPushButton* clearLogButton; // clear Log 按键
|
||||
QLineEdit* filePathLineEdit; // 文件路径显示
|
||||
QLineEdit* VideoResolutionEdit; // 视频分辨率显示
|
||||
|
@ -272,24 +303,28 @@ private:
|
|||
QTabWidget* tabWidget; // 标签页
|
||||
QWidget* functionTestArea; // 功能测试区
|
||||
QWidget* functionConfigArea; // 功能配置区
|
||||
QComboBox* ipComboBox;
|
||||
QComboBox* serialComPortComboBox;
|
||||
|
||||
int lastClickedGetPicCamIndex; // 记录上一次点击取图的摄像头的按键索引
|
||||
int lastClickedGetPicDevIndex; // 记录上一次点击取图的设备的按键索引
|
||||
int lastClickedGetVideoCamIndex; // 记录上一次点击拉视频的摄像头的按键索引
|
||||
int lastClickedGetVideoDevIndex; // 记录上一次点击拉视频的设备的按键索引
|
||||
|
||||
|
||||
//QTimer* serialTimer;
|
||||
QTimer* threadStatusTimer; // 检查线程状态的定时器
|
||||
QTimer* connectionStatusCheckTimer; // 检查连接状态的定时器
|
||||
QMap<int, DataHandler*> dataHandlers;
|
||||
QMap<int, DataHandler*> dataHandlers;
|
||||
QMap<int, SerialDataHandler*> serialDataHandlers;
|
||||
QMap<int, QThread*> clientThreads;
|
||||
QMap<int, QTimer*> clientReadTimers;
|
||||
QMap<int, ClientHandler*> clients_1;
|
||||
|
||||
//ServiceProvider* mServiceProvider;
|
||||
QTimer* mdnsTimer;
|
||||
void startMdnsService();
|
||||
void startMdnsService(char* select_ip);
|
||||
void stopMdnsService();
|
||||
void sendSerialData(const QByteArray& data, bool heartBeat);
|
||||
#if TEST_UDP_BROADCAST
|
||||
QUdpSocket* multicastSocket;
|
||||
QTimer* multicastTimer;
|
||||
|
@ -302,6 +337,9 @@ private:
|
|||
void setupHttpServer(); // 初始化 HTTP 服务器
|
||||
void handleHttpRequest(QTcpSocket* clientSocket); // 处理 HTTP 请求
|
||||
MdnsServiceThread* mdnsThread; // mDNS 线程指针
|
||||
SerialPortHandler* serialPortHandler;
|
||||
//QTimer* portDetectionTimer;
|
||||
//QThread* thread;
|
||||
};
|
||||
|
||||
#endif // MAINWIDGET_H
|
||||
|
|
|
@ -0,0 +1,894 @@
|
|||
// SerialPortHandler.cpp
|
||||
#include "SerialPortHandler.h"
|
||||
|
||||
SerialPortHandler::SerialPortHandler(QComboBox* comPortComboBox, QPushButton* connectButton,
|
||||
QJsonArray frontBoardOneClickTest, QJsonArray frontBoardTest, QJsonArray frontBoardFuncConfig,
|
||||
QJsonArray frontBoardDevInfoJson, QJsonArray frontBoardLicenseJson,
|
||||
QJsonArray backBoardOneClickTest, QJsonArray backBoardTest, QJsonArray backBoardFuncConfig, QJsonArray backBoardDevInfoJson,
|
||||
QJsonArray backBoardUuidJson, QJsonArray getPicJson, QJsonArray getVideoJson, QObject* parent)
|
||||
: QObject(parent), comPortComboBox(comPortComboBox), connectButton(connectButton), worker(nullptr), serialPort(nullptr),
|
||||
frontBoardOneClickTest(frontBoardOneClickTest), frontBoardTest(frontBoardTest),
|
||||
frontBoardFuncConfig(frontBoardFuncConfig), frontBoardDevInfoJson(frontBoardDevInfoJson),
|
||||
frontBoardLicenseJson(frontBoardLicenseJson),
|
||||
backBoardOneClickTest(backBoardOneClickTest), backBoardTest(backBoardTest),
|
||||
backBoardFuncConfig(backBoardFuncConfig), backBoardDevInfoJson(backBoardDevInfoJson),
|
||||
backBoardUuidJson(backBoardUuidJson), getPicJson(getPicJson), getVideoJson(getVideoJson),
|
||||
currentItemIndex(0), isManualSend(false), isSingleSend(false), isClickedSend(false),
|
||||
isFirstDataReceived(true),
|
||||
isDataStuck(false), dataProcessingActive(false), isRecvVideoData(true),
|
||||
currentFrontBoardIndex(0), currentLicenseIndex(0)
|
||||
{
|
||||
serialPort = new QSerialPort();
|
||||
serialPort->setParent(nullptr);
|
||||
|
||||
serialTimer = nullptr;
|
||||
//serialTimer->moveToThread(QThread::currentThread());
|
||||
//connect(serialTimer, &QTimer::timeout, this, &SerialPortHandler::onTimeout);
|
||||
|
||||
portDetectionTimer = nullptr;
|
||||
//portDetectionTimer->moveToThread(QThread::currentThread());
|
||||
//connect(portDetectionTimer, &QTimer::timeout, this, &SerialPortHandler::updateAvailablePorts);
|
||||
//portDetectionTimer->start(2000); // 每2秒检测一次串口
|
||||
|
||||
// 初始化串口端口
|
||||
updateAvailablePorts();
|
||||
|
||||
// 连接按钮点击时的处理
|
||||
connect(connectButton, &QPushButton::clicked, this, &SerialPortHandler::toggleConnection);
|
||||
//connect(serialPort, &QSerialPort::errorOccurred, this, &SerialPortHandler::handleSerialError);
|
||||
}
|
||||
|
||||
SerialPortHandler::~SerialPortHandler()
|
||||
{
|
||||
if (serialTimer) {
|
||||
serialTimer->stop();
|
||||
delete serialTimer;
|
||||
serialTimer = nullptr;
|
||||
}
|
||||
|
||||
if (portDetectionTimer) {
|
||||
portDetectionTimer->stop();
|
||||
delete portDetectionTimer;
|
||||
portDetectionTimer = nullptr;
|
||||
}
|
||||
if (worker) {
|
||||
worker->stop();
|
||||
worker->wait(); // 确保线程已停止
|
||||
delete worker;
|
||||
worker = nullptr;
|
||||
}
|
||||
if (serialPort->isOpen()) {
|
||||
serialPort->close();
|
||||
}
|
||||
}
|
||||
|
||||
void SerialPortHandler::initializeSerialPort()
|
||||
{
|
||||
serialPort = new QSerialPort(this); // 在目标线程中创建
|
||||
serialPort->setParent(nullptr); // 保证没有父对象,避免跨线程的问题
|
||||
connect(serialPort, &QSerialPort::errorOccurred, this, &SerialPortHandler::handleSerialError, Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
void SerialPortHandler::initializeTimers()
|
||||
{
|
||||
// 确保定时器在当前线程中创建
|
||||
serialTimer = new QTimer(this);
|
||||
serialTimer->setSingleShot(true);
|
||||
//serialTimer->moveToThread(this->thread());
|
||||
connect(serialTimer, &QTimer::timeout, this, &SerialPortHandler::onTimeout);
|
||||
|
||||
portDetectionTimer = new QTimer();
|
||||
//portDetectionTimer->moveToThread(this->thread());
|
||||
connect(portDetectionTimer, &QTimer::timeout, this, &SerialPortHandler::updateAvailablePorts);
|
||||
QMetaObject::invokeMethod(portDetectionTimer, "start", Qt::QueuedConnection, Q_ARG(int, 2000));
|
||||
qDebug() << "Current thread in initializeTimers:" << QThread::currentThread();
|
||||
qDebug() << "SerialPortHandler thread:" << this->thread();
|
||||
qDebug() << "serialTimer thread:" << serialTimer->thread();
|
||||
qDebug() << "portDetectionTimer thread:" << portDetectionTimer->thread();
|
||||
}
|
||||
|
||||
void SerialPortHandler::OnStartTimeout(int timeout)
|
||||
{
|
||||
qDebug() << "---------------> onStartTimeout timeout :" << timeout;
|
||||
qDebug() << "Current thread:" << QThread::currentThread();
|
||||
qDebug() << "serialTimer thread:" << serialTimer->thread();
|
||||
// 确保在正确线程中启动或停止定时器
|
||||
if (timeout > 0) {
|
||||
qDebug() << QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz");
|
||||
//QMetaObject::invokeMethod(serialTimer, "start", Qt::QueuedConnection, Q_ARG(int, timeout));
|
||||
QMetaObject::invokeMethod(serialTimer, "start", Qt::DirectConnection, Q_ARG(int, timeout));
|
||||
}
|
||||
else {
|
||||
//QMetaObject::invokeMethod(serialTimer, "stop", Qt::QueuedConnection);
|
||||
QMetaObject::invokeMethod(serialTimer, "stop", Qt::DirectConnection);
|
||||
}
|
||||
qDebug() << "---------------> onStartTimeout end ";
|
||||
}
|
||||
|
||||
void SerialPortHandler::handleSerialError(QSerialPort::SerialPortError error)
|
||||
{
|
||||
if (error == QSerialPort::ResourceError) {
|
||||
qDebug() << "Serial port error occurred. Disconnecting.";
|
||||
disconnectPort();
|
||||
emit serialComPortDisconnected();
|
||||
}
|
||||
}
|
||||
|
||||
void SerialPortHandler::onSendHeartBeatData(const QByteArray& data, bool heartBeat) {
|
||||
QByteArray prefix;
|
||||
QDataStream stream(&prefix, QIODevice::WriteOnly);
|
||||
stream.setByteOrder(QDataStream::LittleEndian);
|
||||
|
||||
// 构造前缀
|
||||
stream << quint32(0x55AA55AA); // 固定前缀
|
||||
stream << quint16(0x0138); // 回复心跳
|
||||
stream << quint32(data.size()); // 数据长度
|
||||
prefix.append(data); // 将实际数据追加到前缀后
|
||||
|
||||
qDebug() << "Send heartBeat data:----->" << prefix.toHex();
|
||||
if (serialPort->isOpen()) {
|
||||
serialPort->write(prefix);
|
||||
serialPort->flush(); // 确保数据立即发送
|
||||
}
|
||||
else {
|
||||
qDebug() << "Serial port is not open!";
|
||||
}
|
||||
}
|
||||
|
||||
void SerialPortHandler::sendData(const QByteArray& data, bool heartBeat) {
|
||||
QByteArray prefix;
|
||||
QDataStream stream(&prefix, QIODevice::WriteOnly);
|
||||
stream.setByteOrder(QDataStream::LittleEndian);
|
||||
|
||||
// 构造前缀
|
||||
stream << quint32(0x55AA55AA); // 固定前缀
|
||||
if (heartBeat) {
|
||||
stream << quint16(0x0138); // 回复心跳
|
||||
}
|
||||
else {
|
||||
stream << quint16(0x0420); // 回复产测指令
|
||||
}
|
||||
stream << quint32(data.size()); // 数据长度
|
||||
prefix.append(data); // 将实际数据追加到前缀后
|
||||
qDebug() << "heartBeat:----->" << heartBeat;
|
||||
qDebug() << "Send data:----->" << prefix.toHex();
|
||||
if (serialPort->isOpen()) {
|
||||
serialPort->write(prefix);
|
||||
serialPort->flush(); // 确保数据立即发送
|
||||
}
|
||||
else {
|
||||
qDebug() << "Serial port is not open!";
|
||||
}
|
||||
}
|
||||
|
||||
void SerialPortHandler::handleSerialData(const QByteArray& data) {
|
||||
//qDebug() << "------------------------ Received data:" << data;
|
||||
//qDebug() << "Received data (HEX):" << data.toHex(' ').toUpper();
|
||||
//emit serialDataReceived(data); // 转发信号给主线程或 UI
|
||||
}
|
||||
|
||||
void SerialPortHandler::updateAvailablePorts() {
|
||||
QStringList currentPorts;
|
||||
foreach(const QSerialPortInfo & info, QSerialPortInfo::availablePorts()) {
|
||||
currentPorts.append(info.portName());
|
||||
qDebug() << "info.portName(): " << info.portName();
|
||||
}
|
||||
|
||||
//qDebug() << "Available ports: " << currentPorts;
|
||||
|
||||
// 检查已连接的端口是否仍然有效
|
||||
if (serialPort->isOpen()) {
|
||||
QString connectedPort = serialPort->portName();
|
||||
bool portStillExists = false;
|
||||
foreach(const QSerialPortInfo & info, QSerialPortInfo::availablePorts()) {
|
||||
if (info.portName() == connectedPort) {
|
||||
portStillExists = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// 如果已连接的端口不再有效,则断开连接
|
||||
if (!portStillExists) {
|
||||
qDebug() << "Connected port no longer available: " << connectedPort;
|
||||
disconnectPort();
|
||||
}
|
||||
}
|
||||
|
||||
// 保存当前选择的端口(在更新串口列表前)
|
||||
QString currentSelectedPort = comPortComboBox->currentText();
|
||||
|
||||
// 如果当前下拉框的串口与新检测到的串口不匹配,则更新下拉框
|
||||
if (currentPorts != comPortList) {
|
||||
comPortComboBox->clear();
|
||||
comPortComboBox->addItems(currentPorts);
|
||||
comPortList = currentPorts; // 更新已检测到的串口列表
|
||||
}
|
||||
|
||||
// 如果当前连接的端口仍然有效,则保持选中该端口
|
||||
if (currentPorts.contains(currentSelectedPort)) {
|
||||
comPortComboBox->setCurrentText(currentSelectedPort);
|
||||
}
|
||||
}
|
||||
|
||||
void SerialPortHandler::toggleConnection() {
|
||||
if (serialPort->isOpen()) {
|
||||
disconnectPort();
|
||||
emit serialComPortDisconnected();
|
||||
}
|
||||
else {
|
||||
isBackBoardOrAllBoard = 0;
|
||||
if(connectPort() == 1)
|
||||
emit serialComPortConnected();
|
||||
}
|
||||
}
|
||||
|
||||
int SerialPortHandler::connectPort() {
|
||||
int ret = 0;
|
||||
QString selectedPort = comPortComboBox->currentText();
|
||||
if (selectedPort.isEmpty()) {
|
||||
return ret; // 如果没有选择串口,直接返回
|
||||
}
|
||||
serialPort->setPortName(selectedPort);
|
||||
if (serialPort->open(QIODevice::ReadWrite)) {
|
||||
ret = 1;
|
||||
connectButton->setText("断开连接");
|
||||
comPortComboBox->setEnabled(false);
|
||||
// 启动工作线程并绑定 readyRead 信号
|
||||
if (!worker) {
|
||||
worker = new SerialPortWorker(serialPort, this);
|
||||
//connect(serialPort, &QSerialPort::readyRead, worker, &SerialPortWorker::handleReadyRead);
|
||||
connect(serialPort, &QSerialPort::readyRead, this, &SerialPortHandler::onDataReceived);
|
||||
//connect(worker, &SerialPortWorker::serialPortdataReceived, this, &SerialPortHandler::handleSerialData);
|
||||
}
|
||||
worker->startWorker();
|
||||
}else {
|
||||
qDebug() << "Failed to open serial port";
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void SerialPortHandler::disconnectPort() {
|
||||
if (worker) {
|
||||
worker->stop();
|
||||
disconnect(serialPort, &QSerialPort::readyRead, worker, &SerialPortWorker::handleReadyRead);
|
||||
delete worker; // 释放 worker
|
||||
worker = nullptr; // 确保重新连接时可以创建新的 worker
|
||||
}
|
||||
if (serialPort->isOpen()) {
|
||||
serialPort->close();
|
||||
}
|
||||
connectButton->setText("连接");
|
||||
comPortComboBox->setEnabled(true);
|
||||
}
|
||||
|
||||
//void SerialPortHandler::startReadVideoDataTimer(int client_Id)
|
||||
//{
|
||||
// //emit startReadTimer(clientId);
|
||||
// emit startReadTimer(client_Id);
|
||||
// qDebug() << "------ startClientReadTimer clientId:" << clientId;
|
||||
//}
|
||||
//
|
||||
//void SerialPortHandler::stopReadVideoDataTimer(int client_Id)
|
||||
//{
|
||||
// //emit stopReadTimer(clientId);
|
||||
// emit stopReadTimer(client_Id);
|
||||
//}
|
||||
|
||||
// 重置索引
|
||||
void SerialPortHandler::resetCurrentItemIndex()
|
||||
{
|
||||
currentItemIndex = 0;
|
||||
currentFuncItemIndex = 0;
|
||||
itemsProcessedCount = 0;
|
||||
//OnStartTimeout(0);
|
||||
emit startTimeout(0);
|
||||
}
|
||||
|
||||
void SerialPortHandler::onPicRecvFinished()
|
||||
{
|
||||
/*if (currentJson != getPicJson && currentJson != frontBoardTest) {
|
||||
currentItemIndex++;
|
||||
itemsProcessedCount++;
|
||||
qDebug() << "------> onPicRecvFinished :" << __FUNCTION__;
|
||||
sendNextItem(currentJson);
|
||||
}*/
|
||||
}
|
||||
|
||||
void SerialPortHandler::onCommandError() {
|
||||
//isCommandError = true;
|
||||
}
|
||||
|
||||
QString SerialPortHandler::getCurrentItemData() const
|
||||
{
|
||||
QString data = currentItem.value("data").toString();
|
||||
qDebug() << "Getting current item data:" << data;
|
||||
return data; // 返回当前项的 "data" 字段
|
||||
}
|
||||
|
||||
QString SerialPortHandler::getCurrentFuncItemData() const
|
||||
{
|
||||
QString data = currentFuncItem.value("val").toString();
|
||||
qDebug() << "Getting current funcItem val:" << data;
|
||||
return data; // 返回当前项的 "val" 字段
|
||||
}
|
||||
|
||||
QString SerialPortHandler::getCurrentItemLable() const
|
||||
{
|
||||
QString lable = currentItem.value("lable").toString();
|
||||
qDebug() << "Getting current item lable:" << lable;
|
||||
return lable; // 返回当前项的 "lable" 字段
|
||||
}
|
||||
|
||||
QString SerialPortHandler::getCurrentFuncItemLable() const
|
||||
{
|
||||
QString lable = currentFuncItem.value("lable").toString();
|
||||
//qDebug() << "Getting current funcItem lable:" << lable;
|
||||
return lable; // 返回当前项的 "data" 字段
|
||||
}
|
||||
|
||||
void SerialPortHandler::sendJsonItem(const QJsonArray& jsonArray, int itemIndex, const QString text, const QString backBoardSn, const QString& itemType)
|
||||
{
|
||||
//startReadVideoDataTimer(preVideoClientId);
|
||||
currentJson = jsonArray;
|
||||
currentJsonItem = itemIndex;
|
||||
QMutexLocker locker(&mutex);
|
||||
if (itemType == "License") {
|
||||
|
||||
}
|
||||
isSingleSend = true;
|
||||
isClickedSend = true;
|
||||
isRecvImgData = false;
|
||||
if (jsonArray == backBoardTest) {
|
||||
QJsonObject tempItem = jsonArray[itemIndex].toObject();
|
||||
if (tempItem["cmd"] == "VIDEO_TEST") {
|
||||
if (tempItem["val"] == 0) {
|
||||
isSingleSend = false;
|
||||
isClickedSend = false;
|
||||
isRecvVideoData = true;
|
||||
isStartVideo = true;
|
||||
//startReadVideoDataTimer(isBackBoardOrAllBoard);
|
||||
}
|
||||
else if (tempItem["val"] == 1) {
|
||||
isRecvVideoData = false;
|
||||
isStartVideo = false;
|
||||
//stopReadVideoDataTimer(isBackBoardOrAllBoard);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (itemType == "handleVideo") {
|
||||
if (itemIndex == 0) {
|
||||
isSingleSend = false;
|
||||
isClickedSend = false;
|
||||
}
|
||||
else {
|
||||
//stopReadVideoDataTimer(preVideoClientId);
|
||||
}
|
||||
}
|
||||
if (itemType == "getPic") {
|
||||
isSingleSend = false;
|
||||
isClickedSend = false;
|
||||
isRecvImgData = true;
|
||||
}
|
||||
if (itemType == "Uuid") {
|
||||
|
||||
}
|
||||
qDebug() << "itemIndex:" << itemIndex;
|
||||
qDebug() << "jsonArray.size():" << jsonArray.size();
|
||||
if (itemIndex >= 0 && itemIndex < jsonArray.size()) {
|
||||
currentItemIndex = (itemType == "test") ? itemIndex : 0;
|
||||
//currentItemIndex = itemIndex;
|
||||
currentFuncItemIndex = (itemType == "func") ? itemIndex : 0;
|
||||
currentItem = jsonArray[itemIndex].toObject();
|
||||
if (!text.isEmpty() && currentItem.contains("val")) {
|
||||
QJsonValue originalValue = currentItem["val"];
|
||||
qDebug() << "text:" << text;
|
||||
if (originalValue.isDouble()) {
|
||||
bool ok;
|
||||
double doubleValue = text.toDouble(&ok);
|
||||
if (ok) {
|
||||
currentItem["val"] = doubleValue;
|
||||
}
|
||||
else {
|
||||
qWarning() << "Text conversion to double failed, original value is kept.";
|
||||
}
|
||||
}
|
||||
else if (originalValue.isString()) {
|
||||
currentItem["val"] = text;
|
||||
}
|
||||
}
|
||||
else if (!text.isEmpty() && currentItem.contains("UUID") && currentItem.contains("SN")) {
|
||||
QJsonValue originalUUID = currentItem["UUID"];
|
||||
QJsonValue originalSN = currentItem["SN"];
|
||||
qDebug() << "UUID:" << text;
|
||||
qDebug() << "SN:" << backBoardSn;
|
||||
if (originalUUID.isDouble()) {
|
||||
bool ok;
|
||||
double doubleValue = text.toDouble(&ok);
|
||||
if (ok) {
|
||||
currentItem["UUID"] = doubleValue;
|
||||
}
|
||||
else {
|
||||
qWarning() << "Text conversion to double failed, original value is kept.";
|
||||
}
|
||||
}
|
||||
else if (originalUUID.isString()) {
|
||||
currentItem["UUID"] = text;
|
||||
}
|
||||
if (originalSN.isDouble()) {
|
||||
bool ok;
|
||||
double doubleValue = backBoardSn.toDouble(&ok);
|
||||
if (ok) {
|
||||
currentItem["SN"] = doubleValue;
|
||||
}
|
||||
else {
|
||||
qWarning() << "backBoardSn conversion to double failed, original value is kept.";
|
||||
}
|
||||
}
|
||||
else if (originalSN.isString()) {
|
||||
currentItem["SN"] = backBoardSn;
|
||||
}
|
||||
}
|
||||
QString itemData = QJsonDocument(currentItem).toJson();
|
||||
emit currentSendItem(currentItem["cmd"].toString());
|
||||
isTimeout = false;
|
||||
emit updateTimeout(isTimeout);
|
||||
// 发送 JSON
|
||||
sendData(itemData.toUtf8(), 0);
|
||||
if (currentItem.contains("timeout")) {
|
||||
qDebug() << "sendJsonItem currentItem.contains(\"timeout\")";
|
||||
int timeout = currentItem.value("timeout").toInt();
|
||||
if (timeout > 0) {
|
||||
//OnStartTimeout(timeout);
|
||||
emit startTimeout(timeout);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 发送获取设备信息按键
|
||||
void SerialPortHandler::sendGetDevInfoItem(int itemIndex)
|
||||
{
|
||||
sendJsonItem(getDevInfoJson, itemIndex, "", "", "devInfo");
|
||||
}
|
||||
|
||||
// 发送取图按键
|
||||
void SerialPortHandler::sendGetPicItem(int itemIndex, int GetPicCamIndex)
|
||||
{
|
||||
sendJsonItem(getPicJson, itemIndex, QString::number(GetPicCamIndex), "", "getPic");
|
||||
}
|
||||
|
||||
// 发送拉视频按键
|
||||
void SerialPortHandler::sendGetVideoItem(int itemIndex, int GetVideoCamIndex)
|
||||
{
|
||||
qDebug() << "sendGetVideoItem itemIndex:" << itemIndex;
|
||||
isRecvVideoData = true;
|
||||
isStartVideo = true;
|
||||
qDebug() << " isRecvVideoData:" << isRecvVideoData;
|
||||
sendJsonItem(getVideoJson, itemIndex, QString::number(GetVideoCamIndex), "", "handleVideo");
|
||||
}
|
||||
|
||||
// 发送License处理按键
|
||||
void SerialPortHandler::sendLicenseItem(int itemIndex, const QString text)
|
||||
{
|
||||
if (isBackBoardOrAllBoard != 0) {
|
||||
emit HandleInvalidOperate("当前连接的是后板或整机,请勿操作前板页面的按键!!!");
|
||||
return;
|
||||
}
|
||||
else {
|
||||
if (itemIndex < 0 || itemIndex >= frontBoardLicenseJson.size()) {
|
||||
qDebug() << "Invalid itemIndex";
|
||||
return;
|
||||
}
|
||||
sendJsonItem(frontBoardLicenseJson, itemIndex, text, "", "License");
|
||||
}
|
||||
}
|
||||
|
||||
void SerialPortHandler::sendFrontFuncItem(int itemIndex, const QString text)
|
||||
{
|
||||
if (isBackBoardOrAllBoard != 0) {
|
||||
emit HandleInvalidOperate("当前连接的是后板或整机,请勿操作前板页面的按键!!!");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
//qDebug() << "sendFuncItem Text:" << text;
|
||||
sendJsonItem(frontBoardFuncConfig, itemIndex, text, "", "func");
|
||||
}
|
||||
}
|
||||
|
||||
//void SerialPortHandler::onDelUserDialogResult(const QString& input)
|
||||
//{
|
||||
// //userInput = input; // 存储用户输入
|
||||
// emit DelUserDialogResultReceived(input); // 通知事件循环退出
|
||||
//}
|
||||
|
||||
void SerialPortHandler::sendFrontItem(int itemIndex)
|
||||
{
|
||||
/*if (isBackBoardOrAllBoard != 0) {
|
||||
emit HandleInvalidOperate("当前连接的是后板或整机,请勿操作前板页面的按键!!!");
|
||||
return;
|
||||
}
|
||||
else*/
|
||||
{
|
||||
QString text = "";
|
||||
QJsonObject currentItem = frontBoardTest[itemIndex].toObject();
|
||||
if (currentItem.contains("cmd") && currentItem["cmd"].toString() == "IMG_ENROLL") {
|
||||
QString downloadUrl;
|
||||
QEventLoop loop;
|
||||
emit startImageSharing(IMG_ENROLL_W, IMG_ENROLL_H, "enroll", [&downloadUrl, &loop](QString responseUrl) {
|
||||
//qDebug() << "Received response from slot:" << responseUrl;
|
||||
downloadUrl = responseUrl; // 更新局部变量
|
||||
loop.quit(); // 退出事件循环
|
||||
});
|
||||
//loop.exec(); // 等待回调执行完成
|
||||
if (!downloadUrl.isEmpty()) {
|
||||
qDebug() << "Image available at:" << downloadUrl;
|
||||
}
|
||||
text = downloadUrl;
|
||||
}
|
||||
else if (currentItem.contains("cmd") && currentItem["cmd"].toString() == "DEL_USER") {
|
||||
QEventLoop loop;
|
||||
QString userInput = "";
|
||||
DelUserWindow dialog;
|
||||
if (dialog.exec() == QDialog::Accepted) {
|
||||
QString userInput = dialog.getUserInput();
|
||||
if (!userInput.isEmpty() && currentItem.contains("val")) {
|
||||
text = userInput;
|
||||
}
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if (currentItem.contains("cmd") && currentItem["cmd"].toString() == "PASSWD_ENROLL") {
|
||||
PasswordEnrollWindow dialog;
|
||||
if (dialog.exec() == QDialog::Accepted) {
|
||||
text = dialog.getPassword();
|
||||
}
|
||||
else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
sendJsonItem(frontBoardTest, itemIndex, text, "", "test");
|
||||
}
|
||||
}
|
||||
|
||||
void SerialPortHandler::sendDevInfoJsonItem(const QJsonObject& jsonItem, int itemIndex)
|
||||
{
|
||||
qDebug() << "sendDevInfoJsonItem Current thread:" << QThread::currentThread();
|
||||
QMutexLocker locker(&mutex);
|
||||
isPowerOnSend = true;
|
||||
qDebug() << "itemIndex:" << itemIndex;
|
||||
qDebug() << "jsonItem.size():" << jsonItem.size();
|
||||
currentItem = jsonItem;
|
||||
QString itemData = QJsonDocument(jsonItem).toJson();
|
||||
//emit sendData(itemData.toUtf8());
|
||||
// 发送 JSON
|
||||
sendData(itemData.toUtf8(), 0);
|
||||
if (jsonItem.contains("timeout")) {
|
||||
int timeout = jsonItem.value("timeout").toInt();
|
||||
if (timeout > 0) {
|
||||
//OnStartTimeout(timeout);
|
||||
emit startTimeout(timeout);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// 如果没有 timeout 字段,则不设置超时处理,一直等待数据接收
|
||||
}
|
||||
}
|
||||
|
||||
void SerialPortHandler::sendDevInfoItem()
|
||||
{
|
||||
qDebug() << "----------- currentFrontBoardIndex:" << currentFrontBoardIndex;
|
||||
qDebug() << "----------- currentFrontBoardIndex:" << currentFrontBoardIndex;
|
||||
qDebug() << "----------- currentFrontBoardIndex:" << currentFrontBoardIndex;
|
||||
qDebug() << "----------- currentFrontBoardIndex:" << currentFrontBoardIndex;
|
||||
qDebug() << "----------- currentFrontBoardIndex:" << currentFrontBoardIndex;
|
||||
currentJson = frontBoardDevInfoJson;
|
||||
currentJsonItem = currentFrontBoardIndex;
|
||||
if (currentFrontBoardIndex < frontBoardDevInfoJson.size()) {
|
||||
sendDevInfoJsonItem(frontBoardDevInfoJson[currentFrontBoardIndex++].toObject(), 1);
|
||||
}
|
||||
else
|
||||
isPowerOnSend = false;
|
||||
}
|
||||
|
||||
void SerialPortHandler::sendNextItem(QJsonArray& currentOneClickedItem)
|
||||
{
|
||||
QMutexLocker locker(&mutex);
|
||||
isClickedSend = true;
|
||||
//qDebug() << "------> locker(&mutex) :" << itemsProcessedCount;
|
||||
qDebug() << "------> currentItemIndex :" << currentItemIndex;
|
||||
qDebug() << "------> currentOneClickedItem.size() :" << currentOneClickedItem.size();
|
||||
if (currentItemIndex < currentOneClickedItem.size()) {
|
||||
currentJson = currentOneClickedItem;
|
||||
currentJsonItem = currentItemIndex;
|
||||
currentItem = currentOneClickedItem[currentItemIndex].toObject();
|
||||
QString itemData = QJsonDocument(currentItem).toJson();
|
||||
//qDebug() << "Sending item index:" << currentItemIndex << "data:" << itemData;
|
||||
if (currentItem.contains("cmd") && currentItem["cmd"].toString() == "DEL_USER") {
|
||||
QString userInput;
|
||||
// 使用 QMetaObject::invokeMethod 将窗口操作移到主线程
|
||||
QMetaObject::invokeMethod(QApplication::instance(), [&userInput]() {
|
||||
DelUserWindow dialog;
|
||||
if (dialog.exec() == QDialog::Accepted) {
|
||||
userInput = dialog.getUserInput();
|
||||
}
|
||||
}, Qt::BlockingQueuedConnection); // 阻塞子线程,直到窗口操作完成
|
||||
|
||||
if (!userInput.isEmpty() && currentItem.contains("val")) {
|
||||
currentItem["val"] = userInput;
|
||||
itemData = QJsonDocument(currentItem).toJson();
|
||||
}
|
||||
else {
|
||||
return; // 用户取消或输入无效,直接返回
|
||||
}
|
||||
}
|
||||
isTimeout = false;
|
||||
emit updateTimeout(isTimeout);
|
||||
// 发送 JSON
|
||||
sendData(itemData.toUtf8(), 0);
|
||||
if (currentItem.contains("timeout")) {
|
||||
int timeout = currentItem.value("timeout").toInt();
|
||||
if (timeout > 0) {
|
||||
//OnStartTimeout(timeout);
|
||||
emit startTimeout(timeout);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// 如果没有 timeout 字段,则不设置超时处理,一直等待数据接收
|
||||
}
|
||||
}
|
||||
else if (isManualSend) {
|
||||
emit allItemsProcessed(isBackBoardOrAllBoard, "", itemsProcessedCount);
|
||||
// 处理完毕后重置标记
|
||||
isManualSend = false;
|
||||
isClickedSend = false;
|
||||
// 重置索引
|
||||
resetCurrentItemIndex();
|
||||
}
|
||||
}
|
||||
|
||||
void SerialPortHandler::onRecvNormalDataFlag(bool flag)
|
||||
{
|
||||
|
||||
if (!(protocolDataFlag = flag)) {
|
||||
return;
|
||||
}
|
||||
/*if (isPowerOnSend && protocolDataFlag) {
|
||||
if (currentFrontBoardIndex < frontBoardDevInfoJson.size()) {
|
||||
qDebug() << "-----" << QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz");
|
||||
sendDevInfoItem();
|
||||
}
|
||||
else {
|
||||
qDebug() << "All items processed in onDataReceived.";
|
||||
emit allItemsProcessed(isBackBoardOrAllBoard, "", currentFrontBoardIndex);
|
||||
isPowerOnSend = false;
|
||||
}
|
||||
protocolDataFlag = false;
|
||||
}*/
|
||||
QJsonObject currentTempItem = currentJson[currentItemIndex].toObject();
|
||||
if (!isSingleSend && !isPowerOnSend && (currentTempItem["cmd"] != "GET_IMG")) {
|
||||
qDebug() << "------------------- onRecvNormalDataFlag ";
|
||||
currentItemIndex ++;
|
||||
itemsProcessedCount ++;
|
||||
}
|
||||
if (isSingleSend) {
|
||||
if (currentTempItem["cmd"] != "GET_IMG") {
|
||||
isSingleSend = false;
|
||||
}
|
||||
isClickedSend = false;
|
||||
}
|
||||
else if (isPowerOnSend) {
|
||||
if (currentFrontBoardIndex < frontBoardDevInfoJson.size()) {
|
||||
qDebug() << "-----" << QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz");
|
||||
sendDevInfoItem();
|
||||
}
|
||||
else {
|
||||
qDebug() << "All items processed in onDataReceived.";
|
||||
emit allItemsProcessed(isBackBoardOrAllBoard, "", currentFrontBoardIndex);
|
||||
currentFrontBoardIndex = 0;
|
||||
isPowerOnSend = false;
|
||||
}
|
||||
}
|
||||
else if (isClickedSend && (currentItemIndex < currentJson.size())) {
|
||||
// 判断是否是取图或者其他会接收很多数据的指令
|
||||
if (currentTempItem["cmd"] != "GET_IMG") {
|
||||
sendNextItem(currentJson);
|
||||
}
|
||||
}
|
||||
else if (isClickedSend) {
|
||||
emit allItemsProcessed(isBackBoardOrAllBoard, "", itemsProcessedCount);
|
||||
isClickedSend = false;
|
||||
//resetCurrentItemIndex();
|
||||
}
|
||||
protocolDataFlag = false;
|
||||
}
|
||||
|
||||
void SerialPortHandler::onDataReceived()
|
||||
{
|
||||
qDebug() << "isRecvVideoData:" << isRecvVideoData;
|
||||
qDebug() << "isPowerOnSend:" << isPowerOnSend;
|
||||
qDebug() << "isClickedSend:" << isClickedSend;
|
||||
qDebug() << "isSingleSend:" << isSingleSend;
|
||||
qDebug() << "isRecvImgData:" << isRecvImgData;
|
||||
#if 1
|
||||
if (!isRecvVideoData &&
|
||||
(isRecvImgData || isPowerOnSend || isClickedSend || (isSingleSend && (currentItemIndex < currentJson.size())))) {
|
||||
QByteArray allData;
|
||||
#if 1
|
||||
while (serialPort->bytesAvailable() > 0) {
|
||||
qint64 bytesAvailableBefore = serialPort->bytesAvailable();
|
||||
//qDebug() << "Bytes available before read:" << bytesAvailableBefore << "clientId:" << clientId;
|
||||
QByteArray buffer;
|
||||
buffer.resize(qMin(bytesAvailableBefore, qint64(5 * 1024))); // 每次读取最多 5KB
|
||||
qint64 bytesRead = serialPort->read(buffer.data(), buffer.size());
|
||||
if (bytesRead > 0) {
|
||||
buffer.resize(bytesRead);
|
||||
allData.append(buffer);
|
||||
//qint64 bytesAvailableAfter = serialPort->bytesAvailable();
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (currentJson != getVideoJson)
|
||||
allData = serialPort->readAll();
|
||||
#endif
|
||||
getCurrentItemLable();
|
||||
//qDebug() << "------- currentItem.value(timeout):" << currentItem.value("timeout").toInt();
|
||||
if ((currentItem.contains("timeout")) || (currentFuncItem.contains("timeout"))) {
|
||||
qDebug() << "currentItem.contains(timeout):" << currentItem.contains("timeout");
|
||||
//OnStartTimeout(0);
|
||||
}
|
||||
QJsonObject currentTempItem = currentJson[currentItemIndex].toObject();
|
||||
//qDebug() << "---Received allData size:" << allData.size();
|
||||
if (!allData.isEmpty()) {
|
||||
emit dataReceived("", allData, 0xFF, currentItemIndex, currentFuncItemIndex, getCurrentItemLable(), "", currentJson, currentJsonItem, isTimeout);
|
||||
/*if (!isSingleSend && !isPowerOnSend && (currentTempItem["cmd"] != "GET_IMG")) {
|
||||
currentItemIndex ++;
|
||||
itemsProcessedCount ++;
|
||||
}*/
|
||||
}
|
||||
/*if (isSingleSend) {
|
||||
if (currentTempItem["cmd"] != "GET_IMG") {
|
||||
isSingleSend = false;
|
||||
}
|
||||
isClickedSend = false;
|
||||
}
|
||||
else if (isPowerOnSend && protocolDataFlag) {
|
||||
if (currentFrontBoardIndex < frontBoardDevInfoJson.size()) {
|
||||
qDebug() << "-----" << QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz");
|
||||
sendDevInfoItem();
|
||||
}
|
||||
else {
|
||||
qDebug() << "All items processed in onDataReceived.";
|
||||
emit allItemsProcessed(isBackBoardOrAllBoard, "", currentFrontBoardIndex);
|
||||
isPowerOnSend = false;
|
||||
}
|
||||
protocolDataFlag = false;
|
||||
}
|
||||
else if (isClickedSend && (currentItemIndex < currentJson.size())) {
|
||||
// 判断是否是取图或者其他会接收很多数据的指令
|
||||
if (currentTempItem["cmd"] != "GET_IMG") {
|
||||
sendNextItem(currentJson);
|
||||
}
|
||||
}
|
||||
else if (isClickedSend) {
|
||||
emit allItemsProcessed(isBackBoardOrAllBoard, "", itemsProcessedCount);
|
||||
isClickedSend = false;
|
||||
//resetCurrentItemIndex();
|
||||
}*/
|
||||
}
|
||||
else if (isRecvVideoData && (!dataProcessingActive)) {
|
||||
dataProcessingActive = true;
|
||||
if ((isBackBoardOrAllBoard == 0) && !isStartVideo) {
|
||||
isRecvVideoData = false;
|
||||
}
|
||||
QTimer::singleShot(0, this, &SerialPortHandler::processPendingData);
|
||||
}
|
||||
else
|
||||
#endif
|
||||
if (!isRecvVideoData && !isRecvImgData) {
|
||||
/*if (preVideoClientId == clientId) {
|
||||
qDebug() << "-----------------" << preVideoClientId << "isRecvVideoData:" << isRecvVideoData;
|
||||
}*/
|
||||
//getCurrentItemLable();
|
||||
QByteArray AllData = serialPort->readAll();
|
||||
if (isCommandError) {
|
||||
isCommandError = false;
|
||||
//emit dataReceived("", AllData, 0xFF, currentItemIndex, currentFuncItemIndex, "", "", currentJson, currentJsonItem);
|
||||
}
|
||||
emit dataReceived("", AllData, 0xFF, currentItemIndex, currentFuncItemIndex, "", "", currentJson, currentJsonItem, isTimeout);
|
||||
}
|
||||
}
|
||||
|
||||
void SerialPortHandler::processPendingData()
|
||||
{
|
||||
if (dataProcessingActive) {
|
||||
int maxIterations = 10; // 每次处理的最大次数
|
||||
QByteArray allData;
|
||||
while (serialPort->bytesAvailable() > 0 && maxIterations-- > 0) {
|
||||
qint64 bytesAvailableBefore = serialPort->bytesAvailable();
|
||||
//qDebug() << "Bytes available before read:" << bytesAvailableBefore << "clientId:" << clientId;
|
||||
// 分块读取数据,避免一次性读取过多数据
|
||||
QByteArray buffer;
|
||||
buffer.resize(qMin(bytesAvailableBefore, qint64(5 * 1024))); // 每次读取最多 5KB
|
||||
qint64 bytesRead = serialPort->read(buffer.data(), buffer.size());
|
||||
|
||||
if (bytesRead > 0) {
|
||||
buffer.resize(bytesRead);
|
||||
//qDebug() << "buffer.data():" << buffer.data();
|
||||
allData.append(buffer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (!allData.isEmpty()) {
|
||||
emit dataReceived("", allData, 0xFF, currentItemIndex, currentFuncItemIndex, "", "", currentJson, currentJsonItem, isTimeout);
|
||||
}
|
||||
|
||||
// 如果还有数据需要处理,继续调度处理任务
|
||||
if (serialPort->bytesAvailable() > 0) {
|
||||
QTimer::singleShot(0, this, &SerialPortHandler::processPendingData);
|
||||
}
|
||||
else {
|
||||
dataProcessingActive = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SerialPortHandler::onTimeout()
|
||||
{
|
||||
qDebug() << "----------- onTimeout ----------";
|
||||
qDebug() << "-----" << QDateTime::currentDateTime().toString("yyyy-MM-dd HH:mm:ss.zzz");
|
||||
//OnStartTimeout(0);
|
||||
//emit startTimeout(0);
|
||||
{
|
||||
QMutexLocker locker(&mutex);
|
||||
emit statusUpdated(isBackBoardOrAllBoard, "", false, currentJson, currentJsonItem);
|
||||
//qDebug() << "isSingleSend:" << isSingleSend << "isPowerOnSend:" << isPowerOnSend;
|
||||
if (!isSingleSend && !isPowerOnSend) {
|
||||
qDebug() << "------------------- onTimeout ";
|
||||
currentItemIndex ++;
|
||||
itemsProcessedCount ++;
|
||||
}
|
||||
}
|
||||
if (isSingleSend) {
|
||||
qDebug() << "----------- isTimeout set true----------";
|
||||
isTimeout = true;
|
||||
emit updateTimeout(isTimeout);
|
||||
isSingleSend = false;
|
||||
isClickedSend = false;
|
||||
}
|
||||
else if (isClickedSend) {
|
||||
if (isBackBoardOrAllBoard) {
|
||||
if (currentItemIndex < backBoardOneClickTest.size()) {
|
||||
sendNextItem(currentJson);
|
||||
}
|
||||
else if (currentItemIndex >= backBoardOneClickTest.size()) {
|
||||
emit allItemsProcessed(isBackBoardOrAllBoard, "", itemsProcessedCount);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (currentItemIndex < frontBoardOneClickTest.size()) {
|
||||
sendNextItem(currentJson);
|
||||
}
|
||||
else if (currentItemIndex >= frontBoardOneClickTest.size()) {
|
||||
emit allItemsProcessed(isBackBoardOrAllBoard, "", itemsProcessedCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (isPowerOnSend) {
|
||||
if (currentFrontBoardIndex < frontBoardDevInfoJson.size()) {
|
||||
sendDevInfoItem();
|
||||
}
|
||||
else {
|
||||
emit allItemsProcessed(isBackBoardOrAllBoard, "", currentFrontBoardIndex);
|
||||
currentFrontBoardIndex = 0;
|
||||
isPowerOnSend = false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
qDebug() << "" << __FUNCTION__ << "------> itemsProcessedCount:" << itemsProcessedCount << "currentItemIndex:" << currentItemIndex;
|
||||
|
||||
}
|
|
@ -0,0 +1,170 @@
|
|||
// SerialPortHandler.h
|
||||
#include <QSerialPort>
|
||||
#include <QSerialPortInfo>
|
||||
#include <QTimer>
|
||||
#include <QStringList>
|
||||
#include <QComboBox>
|
||||
#include <QPushButton>
|
||||
#include <QDebug>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QMutex>
|
||||
#include <QEventLoop>
|
||||
#include <QApplication>
|
||||
|
||||
#include "SerialPortWorker.h"
|
||||
#include "../../Network/DelUserWindows.h"
|
||||
#include "../../Network/ImageEnrollWindow.h"
|
||||
#include "../../Network/PasswordEnrollWindow.h"
|
||||
|
||||
#define TEST_TCP_MOVE_TO_MAIN 0
|
||||
#define GET_PIC_DATA_SIZE (480 * 640 * 1.5)
|
||||
#define IMG_ENROLL_W 480
|
||||
#define IMG_ENROLL_H 640
|
||||
#define CHANGE_THEME_W 720
|
||||
#define CHANGE_THEME_H 1280
|
||||
|
||||
class SerialPortHandler : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SerialPortHandler(QComboBox* comPortComboBox, QPushButton* connectButton,
|
||||
QJsonArray frontBoardOneClickTest, QJsonArray frontBoardTest, QJsonArray frontBoardFuncConfig,
|
||||
QJsonArray frontBoardDevInfoJson, QJsonArray frontBoardLicenseJson,
|
||||
QJsonArray backBoardOneClickTest, QJsonArray backBoardTest, QJsonArray backBoardFuncConfig, QJsonArray backBoardDevInfoJson,
|
||||
QJsonArray backBoardUuidJson, QJsonArray getPicJson, QJsonArray getVideoJson,
|
||||
QObject* parent = nullptr);
|
||||
~SerialPortHandler();
|
||||
|
||||
void sendData(const QByteArray& data, bool heartBeat);
|
||||
void onPicRecvFinished();
|
||||
void onCommandError();
|
||||
|
||||
void sendDevInfoItem();
|
||||
|
||||
void sendJsonItem(const QJsonArray& jsonArray, int itemIndex, const QString text, const QString backBoardSn, const QString& itemType);
|
||||
// 发送获取设备信息按键
|
||||
void sendGetDevInfoItem(int itemIndex);
|
||||
// 发送取图按键
|
||||
void sendGetPicItem(int itemIndex, int GetPicCamIndex);
|
||||
// 发送拉视频流按键
|
||||
void sendGetVideoItem(int itemIndex, int GetVideoCamIndex);
|
||||
// 发送License处理按键
|
||||
void sendLicenseItem(int itemIndex, const QString text);
|
||||
// 发送下一个功能配置 JSON 项目
|
||||
void sendFrontFuncItem(int itemIndex, QString text);
|
||||
// 处理发送单独指令
|
||||
void sendFrontItem(int itemIndex);
|
||||
// 发送下一个 JSON 项目
|
||||
void sendNextItem(QJsonArray& currentOneClickedItem);
|
||||
// 获取json文件中当前发送的 data 字段项
|
||||
QString getCurrentItemData() const;
|
||||
// 获取json文件中当前发送的 lable 字段项
|
||||
QString getCurrentItemLable() const;
|
||||
// 获取功能 json文件中当前发送的 data 字段项
|
||||
QString getCurrentFuncItemData() const;
|
||||
// 获取功能 json文件中当前发送的 lable 字段项
|
||||
QString getCurrentFuncItemLable() const;
|
||||
// 重置索引
|
||||
void resetCurrentItemIndex();
|
||||
|
||||
|
||||
|
||||
public slots:
|
||||
void handleSerialError(QSerialPort::SerialPortError error);
|
||||
void updateAvailablePorts();
|
||||
void toggleConnection();
|
||||
int connectPort();
|
||||
void disconnectPort();
|
||||
void handleSerialData(const QByteArray& data);
|
||||
// 处理数据接收
|
||||
void onDataReceived();
|
||||
// 处理超时
|
||||
void onTimeout();
|
||||
void onSendHeartBeatData(const QByteArray& data, bool heartBeat);
|
||||
void processPendingData();
|
||||
void OnStartTimeout(int timeout);
|
||||
|
||||
void initializeSerialPort();
|
||||
void initializeTimers();
|
||||
|
||||
void onRecvNormalDataFlag(bool flag);
|
||||
//void onDelUserDialogResult(const QString& input);
|
||||
|
||||
signals:
|
||||
void serialDataReceived(const QByteArray& data);
|
||||
void serialComPortConnected();
|
||||
void serialComPortDisconnected();
|
||||
void HandleInvalidOperate(const QString& text);
|
||||
// 通知主线程启动定时器
|
||||
void startTimeout(int timeout);
|
||||
void currentSendItem(const QString& text);
|
||||
// 状态更新信号
|
||||
void statusUpdated(int boardTpye, const QString& client, bool success, const QJsonArray& jsonArray, int itemJsonIndex);
|
||||
// json文件配置项发送完毕
|
||||
void allItemsProcessed(int boardTpye, const QString& client, int itemsProcessedCount);
|
||||
// 数据接收信号
|
||||
void dataReceived(const QString& client, const QByteArray& data, unsigned char msg_id, int currentRecvItemIndex,
|
||||
int currentRecvFuncItemIndex, const QString& itemData, const QString& funcItemData,
|
||||
const QJsonArray& jsonArray, int itemJsonIndex, bool isTimeout);
|
||||
void startImageSharing(int width, int height, QString img_type, std::function<void(QString)> callback);
|
||||
void updateTimeout(bool isTimeout);
|
||||
void requestShowDialog();
|
||||
void dialogResultReceived(const QString& input);
|
||||
|
||||
private:
|
||||
QJsonArray frontBoardOneClickTest; // 前板一键功能测试 JSON
|
||||
QJsonArray frontBoardTest; // 前板单项测试 JSON
|
||||
QJsonArray frontBoardFuncConfig; // 前板功能配置参数 JSON
|
||||
QJsonArray frontBoardDevInfoJson; // 前板设备信息参数 JSON
|
||||
QJsonArray frontBoardLicenseJson; // 前板license信息 JSON
|
||||
QJsonArray backBoardOneClickTest; // 后板一键功能测试 JSON
|
||||
QJsonArray backBoardTest; // 后板单项测试 JSON
|
||||
QJsonArray backBoardFuncConfig; // 后板功能配置参数 JSON
|
||||
QJsonArray backBoardDevInfoJson; // 后板设备信息参数 JSON
|
||||
QJsonArray backBoardUuidJson; // 后板UUID和SN参数 JSON
|
||||
QJsonArray jsonConfig; // 测试区 JSON 配置
|
||||
QJsonArray funcJsonConfig; // 功能区 JSON 配置
|
||||
QJsonArray getDevInfoJson; // 获取设备信息 JSON 配置
|
||||
QJsonArray getPicJson; // 发送取图指令 JSON 配置
|
||||
QJsonArray getVideoJson; // 发送拉视频指令 JSON 配置
|
||||
QJsonArray currentJson; // 当前处理的json
|
||||
|
||||
int currentJsonItem = -1;
|
||||
int currentItemIndex; // 当前处理的测试 JSON 项目索引
|
||||
int currentFuncItemIndex; // 当前处理的功能 JSON 项目索引
|
||||
int isBackBoardOrAllBoard = -1;
|
||||
int itemsProcessedCount; // 跟踪处理项目的数量
|
||||
QJsonObject currentItem; // 测试 json文件中当前发送的项
|
||||
QJsonObject currentFuncItem; // 功能 json文件中当前发送的项
|
||||
QMutex mutex; // 互斥锁,用于线程安全
|
||||
bool isManualSend; // 判断是否是手动触发的发送
|
||||
bool isSingleSend; // 单独点击按键发送的标志
|
||||
bool isClickedSend; // 点击按键发送的标志,没有点击不接收数据
|
||||
bool isRecvVideoData;
|
||||
bool isRecvImgData = false;
|
||||
bool isStartVideo = false;
|
||||
bool isPowerOnSend = false; // 上电发送设备信息
|
||||
bool isCommandError = false;
|
||||
bool isFirstDataReceived;
|
||||
bool isDataStuck;
|
||||
bool dataProcessingActive;
|
||||
bool protocolDataFlag = false;
|
||||
bool isTimeout = false;
|
||||
|
||||
int currentFrontBoardIndex; // 当前发送的前板设备信息项的索引
|
||||
int currentLicenseIndex;
|
||||
|
||||
QComboBox* comPortComboBox;
|
||||
QPushButton* connectButton;
|
||||
QSerialPort* serialPort;
|
||||
QTimer* portDetectionTimer;
|
||||
QTimer* serialTimer;
|
||||
QStringList comPortList; // 当前已检测到的串口列表
|
||||
SerialPortWorker* worker;
|
||||
|
||||
|
||||
void sendDevInfoJsonItem(const QJsonObject& jsonItem, int itemIndex);
|
||||
};
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
#ifndef SERIALPORTWORKER_H
|
||||
#define SERIALPORTWORKER_H
|
||||
|
||||
#include <QThread>
|
||||
#include <QSerialPort>
|
||||
#include <QByteArray>
|
||||
|
||||
class SerialPortWorker : public QThread {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SerialPortWorker(QSerialPort* serialPort, QObject* parent = nullptr)
|
||||
: QThread(parent), serialPort(serialPort), running(true) {}
|
||||
|
||||
~SerialPortWorker() override {
|
||||
stop(); // 确保线程退出
|
||||
}
|
||||
|
||||
void startWorker() {
|
||||
running = true;
|
||||
}
|
||||
|
||||
void stop() {
|
||||
running = false;
|
||||
if (serialPort->isOpen()) {
|
||||
serialPort->close();
|
||||
}
|
||||
}
|
||||
|
||||
signals:
|
||||
void serialPortdataReceived(const QByteArray& data);
|
||||
|
||||
public slots:
|
||||
void handleReadyRead() {
|
||||
if (running && serialPort->isOpen()) {
|
||||
QByteArray data = serialPort->readAll();
|
||||
emit serialPortdataReceived(data);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
QSerialPort* serialPort;
|
||||
bool running;
|
||||
};
|
||||
|
||||
#endif // SERIALPORTWORKER_H
|
|
@ -28,7 +28,9 @@ struct UI_config {
|
|||
QString BACK_TEST_ITEM; // "后板测试项"
|
||||
QString BACK_CONFID_ITEM; // "后板配置项"
|
||||
QString IMAGE_DISPLAY_TAB; // "图像显示区"
|
||||
QString VIDEO_DISPLAY_TAB; // "视频显示区"
|
||||
QString VIDEO_DISPLAY_TAB; // "视频显示区"
|
||||
QString ALL_TEST_ITEM; // "整机测试项"
|
||||
QString ALL_CONFID_ITEM; // "整机配置项"
|
||||
QString LEFT_LENS; // "左边镜头"
|
||||
QString RIGHT_LENS; // "右边镜头"
|
||||
QString CAT_EYE_LENS_RGB; // "猫眼镜头(RGB)"
|
||||
|
|
|
@ -42,11 +42,11 @@ UI_config loadConfig(const QString& filePath)
|
|||
UI_config config;
|
||||
QMap<QString, QString> settings = parseIniFile(filePath);
|
||||
// 可直接修改 UI_config.ini 文件
|
||||
// 如果删除 UI_config.ini 文件中的 Labels 项,则使用如下代码的默认命名配置
|
||||
// 如果删除 UI_config.ini 文件中的 Labels 项,则使用如下代码中的默认命名配置
|
||||
// Labels 项 默认命名配置
|
||||
config.SL100_FACTORY_TOOL_W = settings.value("Window/width", "1340").toInt();
|
||||
config.SL100_FACTORY_TOOL_H = settings.value("Window/height", "900").toInt();
|
||||
config.TOOL_VERSION = settings.value("Labels/tool_version", "SL100 工厂产测工具 - V0.0.10");
|
||||
config.TOOL_VERSION = settings.value("Labels/tool_version", "SL100 工厂产测工具 - V0.0.16");
|
||||
config.START_LISTENING = settings.value("Labels/start_listening", "开始监听\n(Start Listening...)");
|
||||
config.ONE_CLICKED_TEST = settings.value("Labels/one_clicked_test", "一键功能测试");
|
||||
config.FRONT_BOARD_NAME = settings.value("Labels/front_board_name", "前 板");
|
||||
|
@ -65,6 +65,8 @@ UI_config loadConfig(const QString& filePath)
|
|||
config.BACK_CONFID_ITEM = settings.value("Labels/back_config_item", "后板配置项");
|
||||
config.IMAGE_DISPLAY_TAB = settings.value("Labels/image_display_tab", "图像显示区");
|
||||
config.VIDEO_DISPLAY_TAB = settings.value("Labels/video_display_tab", "视频显示区");
|
||||
config.ALL_TEST_ITEM = settings.value("Labels/all_test_item", "整机测试项");
|
||||
config.ALL_CONFID_ITEM = settings.value("Labels/all_config_item", "整机配置项");
|
||||
config.LEFT_LENS = settings.value("Labels/left_lens", "左边镜头");
|
||||
config.RIGHT_LENS = settings.value("Labels/right_lens", "右边镜头");
|
||||
config.CAT_EYE_LENS_RGB = settings.value("Labels/cat_eye_lens_rgb", "猫眼镜头(RGB)");
|
||||
|
@ -498,6 +500,9 @@ void MainWidget::addDeviceAreaTab(QTabWidget* mainTabWidget, const QString& tabN
|
|||
|
||||
// 创建整机区域布局
|
||||
void MainWidget::addAllDeviceAreaTab(QTabWidget* mainTabWidget, const QString& tabName,
|
||||
const QJsonArray& boardTest, const QJsonArray& boardFuncConfig,
|
||||
const QString& boardTestName, const QString& boardFuncConfigName,
|
||||
const QString& boardTestTitle, const QString& boardConfigTitle,
|
||||
QLabel* leftLensLabel, QLabel* rightLensLabel, QLabel* video_Label,
|
||||
QLineEdit* VideoResolutionEdit_type)
|
||||
{
|
||||
|
@ -506,9 +511,9 @@ void MainWidget::addAllDeviceAreaTab(QTabWidget* mainTabWidget, const QString& t
|
|||
QGroupBox* allProductInfoGroupBox = new QGroupBox(TOOL_UI.ALL_PRODUCT_INFO, this);
|
||||
QFormLayout* formLayout = new QFormLayout(allProductInfoGroupBox);
|
||||
for (const QJsonValue& value : factoryProductInfo) {
|
||||
QJsonObject item = value.toObject();
|
||||
QString label = item["lable"].toString();
|
||||
QString cmd = item["cmd"].toString();
|
||||
QJsonObject item = value.toObject();
|
||||
QString label = item["lable"].toString();
|
||||
QString cmd = item["cmd"].toString();
|
||||
QLabel* itemLabel = new QLabel(label, this);
|
||||
QLineEdit* itemLineEdit = new QLineEdit(this);
|
||||
itemLineEdit->setReadOnly(false);
|
||||
|
@ -516,13 +521,23 @@ void MainWidget::addAllDeviceAreaTab(QTabWidget* mainTabWidget, const QString& t
|
|||
formLayout->addRow(itemLabel, itemLineEdit);
|
||||
productInfoLineEdits[cmd] = itemLineEdit;
|
||||
}
|
||||
|
||||
QTabWidget* boardTabWidget = new QTabWidget(this);
|
||||
boardTabWidget->setFixedSize(900, 315);
|
||||
QWidget* functionTestTab = createFunctionTestTab(boardTest, boardTestName);
|
||||
QWidget* functionConfigTab = createFunctionConfigTab(boardFuncConfig, boardFuncConfigName);
|
||||
boardTabWidget->addTab(functionTestTab, boardTestTitle);
|
||||
boardTabWidget->addTab(functionConfigTab, boardConfigTitle);
|
||||
|
||||
groupBoxLayout->addWidget(allProductInfoGroupBox, 1);
|
||||
groupBoxLayout->addWidget(allDeviceInfoGroupBox, 1);
|
||||
|
||||
QTabWidget* mediaTabWidget = createMediaTabWidget(leftLensLabel, rightLensLabel, video_Label, VideoResolutionEdit_type, tabName);
|
||||
QWidget* allDevAreaTab = new QWidget(this);
|
||||
QVBoxLayout* allDevLayout = new QVBoxLayout(allDevAreaTab);
|
||||
allDevLayout->addLayout(groupBoxLayout, 5);
|
||||
allDevLayout->addWidget(mediaTabWidget, 3);
|
||||
allDevLayout->addLayout(groupBoxLayout, 2);
|
||||
allDevLayout->addWidget(boardTabWidget, 4);
|
||||
allDevLayout->addWidget(mediaTabWidget, 4);
|
||||
mainTabWidget->addTab(allDevAreaTab, tabName);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
#include "./Widget/MainWidget.h"
|
||||
#include <QApplication>
|
||||
#include <QItemSelection>
|
||||
#include <QItemSelectionModel>
|
||||
#include <windows.h>
|
||||
#include <iostream>
|
||||
#include <QDebug>
|
||||
|
@ -22,6 +24,11 @@ int main(int argc, char* argv[]) {
|
|||
//closeConsole(); // 调用函数关闭控制台窗口
|
||||
//FreeConsole(); // 关闭控制台窗口
|
||||
QApplication app(argc, argv);
|
||||
|
||||
// **注册 QItemSelection 和 SelectionFlags 以支持 QueuedConnection**
|
||||
qRegisterMetaType<QItemSelection>("QItemSelection");
|
||||
qRegisterMetaType<QItemSelectionModel::SelectionFlags>("QItemSelectionModel::SelectionFlags");
|
||||
|
||||
qDebug() << "Current working directory:" << QDir::currentPath();
|
||||
//QIcon appIcon("./app_icon.ico");
|
||||
//app.setWindowIcon(appIcon);
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
device ID: 1 - Item 1: 后板V851版本: ---> NG
|
||||
device ID: 1 - Item 2: 后板806版本: ---> NG
|
||||
device ID: 1 - Item 3: 后板硬件版本: ---> NG
|
||||
device ID:-1 ---> All 3 items test completed !!!
|
||||
device ID: 2 - Item 1: 后板V851版本: ---> NG
|
||||
device ID: 2 - Item 2: 后板806版本: ---> NG
|
||||
device ID: 2 - Item 3: 后板硬件版本: ---> NG
|
||||
device ID:-2 ---> All 3 items test completed !!!
|
|
@ -1,4 +0,0 @@
|
|||
device ID: 1 - Item 1: 后板V851版本: ---> NG
|
||||
device ID: 1 - Item 2: 后板806版本: ---> NG
|
||||
device ID: 1 - Item 3: 后板硬件版本: ---> NG
|
||||
device ID:-1 ---> All 3 items test completed !!!
|
|
@ -1,4 +0,0 @@
|
|||
device ID: 1 - Item 1: 后板V851版本: ---> NG
|
||||
device ID: 1 - Item 2: 后板806版本: ---> NG
|
||||
device ID: 1 - Item 3: 后板硬件版本: ---> NG
|
||||
device ID:-1 ---> All 3 items test completed !!!
|
|
@ -1,4 +0,0 @@
|
|||
device ID: 1 - Item 1: 后板V851版本: ---> NG
|
||||
device ID: 1 - Item 2: 后板806版本: ---> NG
|
||||
device ID: 1 - Item 3: 后板硬件版本: ---> NG
|
||||
device ID:-1 ---> All 3 items test completed !!!
|
|
@ -1,4 +0,0 @@
|
|||
device ID: 1 - Item 1: 后板V851版本: ---> NG
|
||||
device ID: 1 - Item 2: 后板806版本: ---> NG
|
||||
device ID: 1 - Item 3: 后板硬件版本: ---> NG
|
||||
device ID:-1 ---> All 3 items test completed !!!
|
|
@ -1,4 +0,0 @@
|
|||
device ID: 1 - Item 1: 后板V851版本: ---> NG
|
||||
device ID: 1 - Item 2: 后板806版本: ---> NG
|
||||
device ID: 1 - Item 3: 后板硬件版本: ---> NG
|
||||
device ID:-1 ---> All 3 items test completed !!!
|
|
@ -1,4 +0,0 @@
|
|||
device ID: 1 - Item 1: 后板V851版本: ---> NG
|
||||
device ID: 1 - Item 2: 后板806版本: ---> NG
|
||||
device ID: 1 - Item 3: 后板硬件版本: ---> NG
|
||||
device ID:-1 ---> All 3 items test completed !!!
|
|
@ -1,4 +0,0 @@
|
|||
device ID: 1 - Item 1: 后板V851版本: ---> NG
|
||||
device ID: 1 - Item 2: 后板806版本: ---> NG
|
||||
device ID: 1 - Item 3: 后板硬件版本: ---> NG
|
||||
device ID:-1 ---> All 3 items test completed !!!
|
|
@ -1,4 +0,0 @@
|
|||
device ID: 1 - Item 1: 后板V851版本: ---> NG
|
||||
device ID: 1 - Item 2: 后板806版本: ---> NG
|
||||
device ID: 1 - Item 3: 后板硬件版本: ---> NG
|
||||
device ID:-1 ---> All 3 items test completed !!!
|
|
@ -1,4 +0,0 @@
|
|||
device ID: 1 - Item 1: 后板V851版本: ---> NG
|
||||
device ID: 1 - Item 2: 后板806版本: ---> NG
|
||||
device ID: 1 - Item 3: 后板硬件版本: ---> NG
|
||||
device ID:-1 ---> All 3 items test completed !!!
|
|
@ -1,4 +0,0 @@
|
|||
device ID: 1 - Item 1: 后板V851版本: ---> NG
|
||||
device ID: 1 - Item 2: 后板806版本: ---> NG
|
||||
device ID: 1 - Item 3: 后板硬件版本: ---> NG
|
||||
device ID:-1 ---> All 3 items test completed !!!
|
|
@ -1,4 +0,0 @@
|
|||
device ID: 1 - Item 1: 后板V851版本: ---> NG
|
||||
device ID: 1 - Item 2: 后板806版本: ---> NG
|
||||
device ID: 1 - Item 3: 后板硬件版本: ---> NG
|
||||
device ID:-1 ---> All 3 items test completed !!!
|
|
@ -1,4 +0,0 @@
|
|||
device ID: 1 - Item 1: 后板V851版本: ---> NG
|
||||
device ID: 1 - Item 2: 后板806版本: ---> NG
|
||||
device ID: 1 - Item 3: 后板硬件版本: ---> NG
|
||||
device ID:-1 ---> All 3 items test completed !!!
|
|
@ -1,4 +0,0 @@
|
|||
device ID: 1 - Item 1: 后板V851版本: ---> NG
|
||||
device ID: 1 - Item 2: 后板806版本: ---> NG
|
||||
device ID: 1 - Item 3: 后板硬件版本: ---> NG
|
||||
device ID:-1 ---> All 3 items test completed !!!
|
|
@ -1,4 +0,0 @@
|
|||
device ID: 1 - Item 1: 后板V851版本: ---> NG
|
||||
device ID: 1 - Item 2: 后板806版本: ---> NG
|
||||
device ID: 1 - Item 3: 后板硬件版本: ---> NG
|
||||
device ID:-1 ---> All 3 items test completed !!!
|
|
@ -1,4 +0,0 @@
|
|||
device ID: 1 - Item 1: 后板V851版本: ---> NG
|
||||
device ID: 1 - Item 2: 后板806版本: ---> NG
|
||||
device ID: 1 - Item 3: 后板硬件版本: ---> NG
|
||||
device ID:-1 ---> All 3 items test completed !!!
|
|
@ -1,4 +0,0 @@
|
|||
device ID: 1 - Item 1: 后板V851版本: ---> NG
|
||||
device ID: 1 - Item 2: 后板806版本: ---> NG
|
||||
device ID: 1 - Item 3: 后板硬件版本: ---> NG
|
||||
device ID:-1 ---> All 3 items test completed !!!
|
|
@ -1,4 +0,0 @@
|
|||
device ID: 1 - Item 1: 后板V851版本: ---> NG
|
||||
device ID: 1 - Item 2: 后板806版本: ---> NG
|
||||
device ID: 1 - Item 3: 后板硬件版本: ---> NG
|
||||
device ID:-1 ---> All 3 items test completed !!!
|
|
@ -1,4 +0,0 @@
|
|||
device ID: 1 - Item 1: 后板V851版本: ---> NG
|
||||
device ID: 1 - Item 2: 后板806版本: ---> NG
|
||||
device ID: 1 - Item 3: 后板硬件版本: ---> NG
|
||||
device ID:-1 ---> All 3 items test completed !!!
|
|
@ -1,4 +0,0 @@
|
|||
device ID: 1 - Item 1: 后板V851版本: ---> NG
|
||||
device ID: 1 - Item 2: 后板806版本: ---> NG
|
||||
device ID: 1 - Item 3: 后板硬件版本: ---> NG
|
||||
device ID:-1 ---> All 3 items test completed !!!
|
|
@ -1,8 +0,0 @@
|
|||
device ID: 1 - Item 1: 后板V851版本: ---> NG
|
||||
device ID: 1 - Item 2: 后板806版本: ---> NG
|
||||
device ID: 1 - Item 3: 后板硬件版本: ---> NG
|
||||
device ID:-1 ---> All 3 items test completed !!!
|
||||
device ID: 2 - Item 1: 后板V851版本: ---> NG
|
||||
device ID: 2 - Item 2: 后板806版本: ---> NG
|
||||
device ID: 2 - Item 3: 后板硬件版本: ---> NG
|
||||
device ID:-2 ---> All 3 items test completed !!!
|
|
@ -1,12 +0,0 @@
|
|||
device ID: 1 - Item 1: 后板V851版本: ---> NG
|
||||
device ID: 1 - Item 2: 后板806版本: ---> NG
|
||||
device ID: 1 - Item 3: 后板硬件版本: ---> NG
|
||||
device ID:-1 ---> All 3 items test completed !!!
|
||||
device ID: 2 - Item 1: 后板V851版本: ---> NG
|
||||
device ID: 2 - Item 2: 后板806版本: ---> NG
|
||||
device ID: 2 - Item 3: 后板硬件版本: ---> NG
|
||||
device ID:-2 ---> All 3 items test completed !!!
|
||||
device ID: 3 - Item 1: 后板V851版本: ---> NG
|
||||
device ID: 3 - Item 2: 后板806版本: ---> NG
|
||||
device ID: 3 - Item 3: 后板硬件版本: ---> NG
|
||||
device ID:-3 ---> All 3 items test completed !!!
|
|
@ -1,4 +0,0 @@
|
|||
device ID: 1 - Item 1: 后板V851版本: ---> NG
|
||||
device ID: 1 - Item 2: 后板806版本: ---> NG
|
||||
device ID: 1 - Item 3: 后板硬件版本: ---> NG
|
||||
device ID:-1 ---> All 3 items test completed !!!
|
|
@ -1,8 +0,0 @@
|
|||
device ID: 1 - Item 1: 后板V851版本: ---> NG
|
||||
device ID: 1 - Item 2: 后板806版本: ---> NG
|
||||
device ID: 1 - Item 3: 后板硬件版本: ---> NG
|
||||
device ID:-1 ---> All 3 items test completed !!!
|
||||
device ID: 2 - Item 1: 后板V851版本: ---> NG
|
||||
device ID: 2 - Item 2: 后板806版本: ---> NG
|
||||
device ID: 2 - Item 3: 后板硬件版本: ---> NG
|
||||
device ID:-2 ---> All 3 items test completed !!!
|
|
@ -1,12 +0,0 @@
|
|||
device ID: 1 - Item 1: 后板V851版本: ---> NG
|
||||
device ID: 1 - Item 2: 后板806版本: ---> NG
|
||||
device ID: 1 - Item 3: 后板硬件版本: ---> NG
|
||||
device ID:-1 ---> All 3 items test completed !!!
|
||||
device ID: 2 - Item 1: 后板V851版本: ---> NG
|
||||
device ID: 2 - Item 2: 后板806版本: ---> NG
|
||||
device ID: 2 - Item 3: 后板硬件版本: ---> NG
|
||||
device ID:-2 ---> All 3 items test completed !!!
|
||||
device ID: 3 - Item 1: 后板V851版本: ---> NG
|
||||
device ID: 3 - Item 2: 后板806版本: ---> NG
|
||||
device ID: 3 - Item 3: 后板硬件版本: ---> NG
|
||||
device ID:-3 ---> All 3 items test completed !!!
|
|
@ -1,6 +0,0 @@
|
|||
device ID: 2 - Item 1: 前板V851版本: ---> OK
|
||||
device ID: 2 - Item 2: 前板MCU版本: ---> OK
|
||||
device ID: 2 - Item 3: 前板硬件版本: ---> OK
|
||||
device ID: 2 - Item 4: 算法版本: ---> OK
|
||||
device ID: 2 - Item 5: SN号: ---> OK
|
||||
device ID:-2 ---> All 5 items test completed !!!
|
|
@ -1,8 +0,0 @@
|
|||
device ID: 1 - Item 0: ---> NG
|
||||
device ID: 1 - Item 1: 进入产测模式 ---> NG
|
||||
device ID: 1 - Item 2: 前板V851版本: ---> NG
|
||||
device ID: 1 - Item 3: 前板MCU版本: ---> NG
|
||||
device ID: 1 - Item 4: 前板硬件版本: ---> NG
|
||||
device ID: 1 - Item 5: 算法版本: ---> NG
|
||||
device ID: 1 - Item 6: SN号: ---> NG
|
||||
device ID:-1 ---> All 6 items test completed !!!
|
|
@ -1,7 +0,0 @@
|
|||
device ID: 1 - Item 1: 进入产测模式 ---> OK
|
||||
device ID: 1 - Item 2: 前板V851版本: ---> NG
|
||||
device ID: 1 - Item 3: 前板MCU版本: ---> NG
|
||||
device ID: 1 - Item 4: 前板硬件版本: ---> NG
|
||||
device ID: 1 - Item 5: 算法版本: ---> NG
|
||||
device ID: 1 - Item 6: SN号: ---> NG
|
||||
device ID:-1 ---> All 6 items test completed !!!
|
|
@ -1,4 +0,0 @@
|
|||
device ID: 1 - Item 1: 后板V851版本: ---> NG
|
||||
device ID: 1 - Item 2: 后板806版本: ---> NG
|
||||
device ID: 1 - Item 3: 后板硬件版本: ---> NG
|
||||
device ID:-1 ---> All 3 items test completed !!!
|
|
@ -1,4 +0,0 @@
|
|||
device ID: 1 - Item 1: 后板V851版本: ---> NG
|
||||
device ID: 1 - Item 2: 后板806版本: ---> NG
|
||||
device ID: 1 - Item 3: 后板硬件版本: ---> NG
|
||||
device ID:-1 ---> All 3 items test completed !!!
|
|
@ -1,4 +0,0 @@
|
|||
device ID: 1 - Item 1: 后板V851版本: ---> NG
|
||||
device ID: 1 - Item 2: 后板806版本: ---> NG
|
||||
device ID: 1 - Item 3: 后板硬件版本: ---> NG
|
||||
device ID:-1 ---> All 3 items test completed !!!
|
|
@ -1,6 +0,0 @@
|
|||
device ID: 1 - Item 1: 前板V851版本: ---> NG
|
||||
device ID: 1 - Item 2: 前板MCU版本: ---> NG
|
||||
device ID: 1 - Item 3: 前板硬件版本: ---> NG
|
||||
device ID: 1 - Item 4: 算法版本: ---> NG
|
||||
device ID: 1 - Item 5: SN号: ---> NG
|
||||
device ID:-1 ---> All 5 items test completed !!!
|
|
@ -1,6 +0,0 @@
|
|||
device ID: 1 - Item 1: 前板V851版本: ---> NG
|
||||
device ID: 1 - Item 2: 前板MCU版本: ---> NG
|
||||
device ID: 1 - Item 3: 前板硬件版本: ---> NG
|
||||
device ID: 1 - Item 4: 算法版本: ---> NG
|
||||
device ID: 1 - Item 5: SN号: ---> NG
|
||||
device ID:-1 ---> All 5 items test completed !!!
|
|
@ -1,6 +0,0 @@
|
|||
device ID: 1 - Item 1: 前板V851版本: ---> NG
|
||||
device ID: 1 - Item 2: 前板MCU版本: ---> NG
|
||||
device ID: 1 - Item 3: 前板硬件版本: ---> NG
|
||||
device ID: 1 - Item 4: 算法版本: ---> NG
|
||||
device ID: 1 - Item 5: SN号: ---> NG
|
||||
device ID:-1 ---> All 5 items test completed !!!
|
|
@ -1,6 +0,0 @@
|
|||
device ID: 1 - Item 1: 前板V851版本: ---> NG
|
||||
device ID: 1 - Item 2: 前板MCU版本: ---> NG
|
||||
device ID: 1 - Item 3: 前板硬件版本: ---> NG
|
||||
device ID: 1 - Item 4: 算法版本: ---> NG
|
||||
device ID: 1 - Item 5: SN号: ---> NG
|
||||
device ID:-1 ---> All 5 items test completed !!!
|
|
@ -1,6 +0,0 @@
|
|||
device ID: 1 - Item 1: 前板V851版本: ---> NG
|
||||
device ID: 1 - Item 2: 前板MCU版本: ---> NG
|
||||
device ID: 1 - Item 3: 前板硬件版本: ---> NG
|
||||
device ID: 1 - Item 4: 算法版本: ---> NG
|
||||
device ID: 1 - Item 5: SN号: ---> NG
|
||||
device ID:-1 ---> All 5 items test completed !!!
|
|
@ -1,6 +0,0 @@
|
|||
device ID: 1 - Item 1: 前板V851版本: ---> NG
|
||||
device ID: 1 - Item 2: 前板MCU版本: ---> NG
|
||||
device ID: 1 - Item 3: 前板硬件版本: ---> NG
|
||||
device ID: 1 - Item 4: 算法版本: ---> NG
|
||||
device ID: 1 - Item 5: SN号: ---> NG
|
||||
device ID:-1 ---> All 5 items test completed !!!
|
|
@ -1,6 +0,0 @@
|
|||
device ID: 1 - Item 1: 前板V851版本: ---> NG
|
||||
device ID: 1 - Item 2: 前板MCU版本: ---> NG
|
||||
device ID: 1 - Item 3: 前板硬件版本: ---> NG
|
||||
device ID: 1 - Item 4: 算法版本: ---> NG
|
||||
device ID: 1 - Item 5: SN号: ---> NG
|
||||
device ID:-1 ---> All 5 items test completed !!!
|
|
@ -1,6 +0,0 @@
|
|||
device ID: 1 - Item 1: 前板V851版本: ---> NG
|
||||
device ID: 1 - Item 2: 前板MCU版本: ---> NG
|
||||
device ID: 1 - Item 3: 前板硬件版本: ---> NG
|
||||
device ID: 1 - Item 4: 算法版本: ---> NG
|
||||
device ID: 1 - Item 5: SN号: ---> NG
|
||||
device ID:-1 ---> All 5 items test completed !!!
|
|
@ -1,6 +0,0 @@
|
|||
device ID: 1 - Item 1: 前板V851版本: ---> NG
|
||||
device ID: 1 - Item 2: 前板MCU版本: ---> NG
|
||||
device ID: 1 - Item 3: 前板硬件版本: ---> NG
|
||||
device ID: 1 - Item 4: 算法版本: ---> NG
|
||||
device ID: 1 - Item 5: SN号: ---> NG
|
||||
device ID:-1 ---> All 5 items test completed !!!
|
|
@ -1,6 +0,0 @@
|
|||
device ID: 1 - Item 1: 前板V851版本: ---> NG
|
||||
device ID: 1 - Item 2: 前板MCU版本: ---> NG
|
||||
device ID: 1 - Item 3: 前板硬件版本: ---> NG
|
||||
device ID: 1 - Item 4: 算法版本: ---> NG
|
||||
device ID: 1 - Item 5: SN号: ---> NG
|
||||
device ID:-1 ---> All 5 items test completed !!!
|
|
@ -1,6 +0,0 @@
|
|||
device ID: 1 - Item 1: 前板V851版本: ---> NG
|
||||
device ID: 1 - Item 2: 前板MCU版本: ---> NG
|
||||
device ID: 1 - Item 3: 前板硬件版本: ---> NG
|
||||
device ID: 1 - Item 4: 算法版本: ---> NG
|
||||
device ID: 1 - Item 5: SN号: ---> NG
|
||||
device ID:-1 ---> All 5 items test completed !!!
|
|
@ -1,6 +0,0 @@
|
|||
device ID: 1 - Item 1: 前板V851版本: ---> NG
|
||||
device ID: 1 - Item 2: 前板MCU版本: ---> NG
|
||||
device ID: 1 - Item 3: 前板硬件版本: ---> NG
|
||||
device ID: 1 - Item 4: 算法版本: ---> NG
|
||||
device ID: 1 - Item 5: SN号: ---> NG
|
||||
device ID:-1 ---> All 5 items test completed !!!
|
|
@ -1,6 +0,0 @@
|
|||
device ID: 1 - Item 1: 前板V851版本: ---> NG
|
||||
device ID: 1 - Item 2: 前板MCU版本: ---> NG
|
||||
device ID: 1 - Item 3: 前板硬件版本: ---> NG
|
||||
device ID: 1 - Item 4: 算法版本: ---> NG
|
||||
device ID: 1 - Item 5: SN号: ---> NG
|
||||
device ID:-1 ---> All 5 items test completed !!!
|
|
@ -1,6 +0,0 @@
|
|||
device ID: 1 - Item 1: 前板V851版本: ---> NG
|
||||
device ID: 1 - Item 2: 前板MCU版本: ---> NG
|
||||
device ID: 1 - Item 3: 前板硬件版本: ---> NG
|
||||
device ID: 1 - Item 4: 算法版本: ---> NG
|
||||
device ID: 1 - Item 5: SN号: ---> NG
|
||||
device ID:-1 ---> All 5 items test completed !!!
|
|
@ -1,6 +0,0 @@
|
|||
device ID: 1 - Item 1: 前板V851版本: ---> NG
|
||||
device ID: 1 - Item 2: 前板MCU版本: ---> NG
|
||||
device ID: 1 - Item 3: 前板硬件版本: ---> NG
|
||||
device ID: 1 - Item 4: 算法版本: ---> NG
|
||||
device ID: 1 - Item 5: SN号: ---> NG
|
||||
device ID:-1 ---> All 5 items test completed !!!
|
|
@ -1,4 +0,0 @@
|
|||
device ID: 1 - Item 1: 后板V851版本: ---> NG
|
||||
device ID: 1 - Item 2: 后板806版本: ---> NG
|
||||
device ID: 1 - Item 3: 后板硬件版本: ---> NG
|
||||
device ID:-1 ---> All 3 items test completed !!!
|
|
@ -1,8 +0,0 @@
|
|||
device ID: 1 - Item 1: 后板V851版本: ---> NG
|
||||
device ID: 1 - Item 2: 后板806版本: ---> NG
|
||||
device ID: 1 - Item 3: 后板硬件版本: ---> NG
|
||||
device ID:-1 ---> All 3 items test completed !!!
|
||||
device ID: 1 - Item 1: 后板V851版本: ---> NG
|
||||
device ID: 1 - Item 2: 后板806版本: ---> NG
|
||||
device ID: 1 - Item 3: 后板硬件版本: ---> NG
|
||||
device ID:-1 ---> All 3 items test completed !!!
|
|
@ -0,0 +1,6 @@
|
|||
device ID: 1 - Item 1: 前板V851版本: ---> OK
|
||||
device ID: 1 - Item 2: 前板MCU版本: ---> OK
|
||||
device ID: 1 - Item 3: 前板硬件版本: ---> OK
|
||||
device ID: 1 - Item 4: 算法版本: ---> OK
|
||||
device ID: 1 - Item 5: SN号: ---> OK
|
||||
device ID:-1 ---> All 5 items test completed !!!
|
|
@ -0,0 +1,6 @@
|
|||
device ID: 1 - Item 1: 前板V851版本: ---> OK
|
||||
device ID: 1 - Item 2: 前板MCU版本: ---> OK
|
||||
device ID: 1 - Item 3: 前板硬件版本: ---> OK
|
||||
device ID: 1 - Item 4: 算法版本: ---> OK
|
||||
device ID: 1 - Item 5: SN号: ---> OK
|
||||
device ID:-1 ---> All 5 items test completed !!!
|
|
@ -0,0 +1,6 @@
|
|||
device ID: 1 - Item 1: 前板V851版本: ---> OK
|
||||
device ID: 1 - Item 2: 前板MCU版本: ---> OK
|
||||
device ID: 1 - Item 3: 前板硬件版本: ---> OK
|
||||
device ID: 1 - Item 4: 算法版本: ---> OK
|
||||
device ID: 1 - Item 5: SN号: ---> OK
|
||||
device ID:-1 ---> All 5 items test completed !!!
|
|
@ -0,0 +1,6 @@
|
|||
device ID: 1 - Item 1: 前板V851版本: ---> OK
|
||||
device ID: 1 - Item 2: 前板MCU版本: ---> OK
|
||||
device ID: 1 - Item 3: 前板硬件版本: ---> OK
|
||||
device ID: 1 - Item 4: 算法版本: ---> OK
|
||||
device ID: 1 - Item 5: SN号: ---> OK
|
||||
device ID:-1 ---> All 5 items test completed !!!
|
|
@ -0,0 +1,6 @@
|
|||
device ID: 1 - Item 1: 前板V851版本: ---> OK
|
||||
device ID: 1 - Item 2: 前板MCU版本: ---> OK
|
||||
device ID: 1 - Item 3: 前板硬件版本: ---> OK
|
||||
device ID: 1 - Item 4: 算法版本: ---> OK
|
||||
device ID: 1 - Item 5: SN号: ---> OK
|
||||
device ID:-1 ---> All 5 items test completed !!!
|
|
@ -0,0 +1,6 @@
|
|||
device ID: 1 - Item 1: 前板V851版本: ---> OK
|
||||
device ID: 1 - Item 2: 前板MCU版本: ---> OK
|
||||
device ID: 1 - Item 3: 前板硬件版本: ---> OK
|
||||
device ID: 1 - Item 4: 算法版本: ---> OK
|
||||
device ID: 1 - Item 5: SN号: ---> OK
|
||||
device ID:-1 ---> All 5 items test completed !!!
|
|
@ -0,0 +1,6 @@
|
|||
device ID: 1 - Item 1: 前板V851版本: ---> OK
|
||||
device ID: 1 - Item 2: 前板MCU版本: ---> OK
|
||||
device ID: 1 - Item 3: 前板硬件版本: ---> OK
|
||||
device ID: 1 - Item 4: 算法版本: ---> OK
|
||||
device ID: 1 - Item 5: SN号: ---> OK
|
||||
device ID:-1 ---> All 5 items test completed !!!
|
|
@ -0,0 +1,6 @@
|
|||
device ID: 1 - Item 1: 前板V851版本: ---> OK
|
||||
device ID: 1 - Item 2: 前板MCU版本: ---> OK
|
||||
device ID: 1 - Item 3: 前板硬件版本: ---> OK
|
||||
device ID: 1 - Item 4: 算法版本: ---> OK
|
||||
device ID: 1 - Item 5: SN号: ---> OK
|
||||
device ID:-1 ---> All 5 items test completed !!!
|
|
@ -0,0 +1,6 @@
|
|||
device ID: 1 - Item 1: 前板V851版本: ---> OK
|
||||
device ID: 1 - Item 2: 前板MCU版本: ---> OK
|
||||
device ID: 1 - Item 3: 前板硬件版本: ---> OK
|
||||
device ID: 1 - Item 4: 算法版本: ---> OK
|
||||
device ID: 1 - Item 5: SN号: ---> OK
|
||||
device ID:-1 ---> All 5 items test completed !!!
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue