diff --git a/FactoryTestTool/SourceCode/Json/JsonFile/backBoardUuid.json b/FactoryTestTool/SourceCode/Json/JsonFile/backBoardUuid.json index 27cfdfa..f20451a 100644 --- a/FactoryTestTool/SourceCode/Json/JsonFile/backBoardUuid.json +++ b/FactoryTestTool/SourceCode/Json/JsonFile/backBoardUuid.json @@ -2,19 +2,19 @@ { "cmd": "GET_BACK_MAC", "val": 0, - "lable": "获取后板MAC地址", + "lable": "get_MAC_addr", "timeout": 0 }, { - "cmd": "GET_BACK_UUID", + "cmd": "GET_BACK_UUID_SN", "val": 0, - "lable": "获取UUID", + "lable": "get_UUID_SN", "timeout": 0 }, { - "cmd": "GET_BACK_SN", + "cmd": "WRITE_BACK_UUID_SN", "val": 0, - "lable": "获取SN", + "lable": "write_UUID_SN", "timeout": 0 } ] \ No newline at end of file diff --git a/FactoryTestTool/SourceCode/Json/JsonFile/backDevInfo.json b/FactoryTestTool/SourceCode/Json/JsonFile/backDevInfo.json index c4382f1..091897b 100644 --- a/FactoryTestTool/SourceCode/Json/JsonFile/backDevInfo.json +++ b/FactoryTestTool/SourceCode/Json/JsonFile/backDevInfo.json @@ -16,23 +16,5 @@ "val": 0, "lable": "后板硬件版本:", "timeout": 2000 - }, - { - "cmd": "GET_BACK_MAC", - "val": 0, - "lable": "后板MAC地址:", - "timeout": 2000 - }, - { - "cmd": "GET_BACK_SN", - "val": 0, - "lable": "SN号:", - "timeout": 2000 - }, - { - "cmd": "GET_BACK_UUID", - "val": 0, - "lable": "UUID:", - "timeout": 2000 } ] diff --git a/FactoryTestTool/SourceCode/Json/JsonFile/frontBoardFuncConfig.json b/FactoryTestTool/SourceCode/Json/JsonFile/frontBoardFuncConfig.json index 7967ad9..48f0583 100644 --- a/FactoryTestTool/SourceCode/Json/JsonFile/frontBoardFuncConfig.json +++ b/FactoryTestTool/SourceCode/Json/JsonFile/frontBoardFuncConfig.json @@ -124,5 +124,11 @@ "val": 1, "lable": "设置log等级", "timeout": 2000 + }, + { + "cmd": "SET_ALL_DATA_RESET", + "val": "0", + "lable": "前板恢复出厂", + "timeout": 2000 } ] diff --git a/FactoryTestTool/SourceCode/Json/JsonFile/getPic.json b/FactoryTestTool/SourceCode/Json/JsonFile/getPic.json index 646a43f..4d92a5e 100644 --- a/FactoryTestTool/SourceCode/Json/JsonFile/getPic.json +++ b/FactoryTestTool/SourceCode/Json/JsonFile/getPic.json @@ -1,8 +1,8 @@ [ { - "cmd": "get_YUV", - "val": 1, - "lable": "雷达测试", - "timeout": 2000 + "cmd": "GET_IMG", + "val": "0", + "lable": "取图", + "timeout": 0 } ] diff --git a/FactoryTestTool/SourceCode/Json/JsonFile/getVideo.json b/FactoryTestTool/SourceCode/Json/JsonFile/getVideo.json index 7b73bed..5909032 100644 --- a/FactoryTestTool/SourceCode/Json/JsonFile/getVideo.json +++ b/FactoryTestTool/SourceCode/Json/JsonFile/getVideo.json @@ -1,13 +1,13 @@ [ { "cmd": "START_VIDEO", - "val": 1, + "val": "1", "lable": "启动视频", "timeout": 0 }, { "cmd": "STOP_VIDEO", - "val": 1, + "val": "0", "lable": "停止视频", "timeout": 0 } diff --git a/FactoryTestTool/SourceCode/Media/Media.cpp b/FactoryTestTool/SourceCode/Media/Media.cpp index 14d5068..a0311e5 100644 --- a/FactoryTestTool/SourceCode/Media/Media.cpp +++ b/FactoryTestTool/SourceCode/Media/Media.cpp @@ -72,51 +72,47 @@ QImage convertYUV420ToQImage(const QByteArray& yuv420Data, int width, int height return image; } -// 显示图片的函数 void showPic(QLabel* leftLens_m_imageLabel, QLabel* rightLens_m_imageLabel, const QString& client, const QByteArray& valData) { - int lens_n = static_cast(valData[3]); - int width = (static_cast(valData[5]) << 8) | static_cast(valData[4]); - int height = (static_cast(valData[7]) << 8) | static_cast(valData[6]); - int format = static_cast(valData[8]); + int lens_n = static_cast(valData[0]); + int width = (static_cast(valData[2]) << 8) | static_cast(valData[1]); + int height = (static_cast(valData[4]) << 8) | static_cast(valData[3]); + int format = static_cast(valData[5]); qDebug() << "lens_n = " << lens_n; qDebug() << "format = " << format; qDebug() << "width = " << width; qDebug() << "height = " << height; - QByteArray yuvData = valData.mid(9); - + QByteArray yuvData = valData.mid(6); qDebug() << "yuvData size = " << yuvData.size(); + QImage image; if (format == YUV422) { - QImage image = convertYUV422ToQImage(yuvData, width, height); - QImage scaledImage = image.scaled(leftLens_m_imageLabel->size(), Qt::KeepAspectRatio); - if (lens_n == 0) { - leftLens_m_imageLabel->setPixmap(QPixmap::fromImage(scaledImage)); - rightLens_m_imageLabel->setPixmap(QPixmap::fromImage(scaledImage)); - } - else if (lens_n == 1) { - rightLens_m_imageLabel->setPixmap(QPixmap::fromImage(scaledImage)); - } - else { - qWarning() << "Unsupported image lens!"; - } + image = convertYUV422ToQImage(yuvData, width, height); } else if (format == YUV420) { - QImage image = convertYUV420ToQImage(yuvData, width, height); - QImage scaledImage = image.scaled(leftLens_m_imageLabel->size(), Qt::KeepAspectRatio); - if (lens_n == 0) { - leftLens_m_imageLabel->setPixmap(QPixmap::fromImage(scaledImage)); - } - else if (lens_n == 1) { - rightLens_m_imageLabel->setPixmap(QPixmap::fromImage(scaledImage)); - } - else { - qWarning() << "Unsupported image lens!"; - } + image = convertYUV420ToQImage(yuvData, width, height); } else { qWarning() << "Unsupported image format!"; + return; + } + + // 旋转图像90度 + QTransform transform; + transform.rotate(90); // 可以调整旋转角度 + QImage rotatedImage = image.transformed(transform); + + QImage scaledImage = rotatedImage.scaled(leftLens_m_imageLabel->size(), Qt::KeepAspectRatio); + if (lens_n == 0) { + leftLens_m_imageLabel->setPixmap(QPixmap::fromImage(scaledImage)); + //rightLens_m_imageLabel->setPixmap(QPixmap::fromImage(scaledImage)); + } + else if (lens_n == 1) { + rightLens_m_imageLabel->setPixmap(QPixmap::fromImage(scaledImage)); + } + else { + qWarning() << "Unsupported image lens!"; } } diff --git a/FactoryTestTool/SourceCode/Media/VideoDecoder/FFmpegDecoder.cpp b/FactoryTestTool/SourceCode/Media/VideoDecoder/FFmpegDecoder.cpp index 63a0b82..270f516 100644 --- a/FactoryTestTool/SourceCode/Media/VideoDecoder/FFmpegDecoder.cpp +++ b/FactoryTestTool/SourceCode/Media/VideoDecoder/FFmpegDecoder.cpp @@ -37,11 +37,11 @@ void FFmpegDecoder::initialize() avformat_network_init(); } -void FFmpegDecoder::decodeFile(const QString& filePath, QLabel* videoLabel) +void FFmpegDecoder::decodeFile(const QString& filePath, QLabel* videoDisplayLabel) { QMutexLocker locker(&mutex); this->filePath = filePath; - this->videoLabel = videoLabel; + this->videoLabel = videoDisplayLabel; if (!isRunning()) { qDebug() << "Starting decoder thread"; start(NormalPriority); @@ -69,6 +69,13 @@ void FFmpegDecoder::run() QLabel* currentVideoLabel = videoLabel; QSize labelSize = currentVideoLabel->size(); mutex.unlock(); + + if (labelSize.width() <= 0 || labelSize.height() <= 0) { + // 自动调整 QLabel 大小 + labelSize = QSize(800, 600); // 例如设置为默认大小 + currentVideoLabel->setFixedSize(labelSize); + qDebug() << "Adjusting video label size to: Width =" << labelSize.width() << ", Height =" << labelSize.height(); + } qDebug() << "Video label size: Width =" << labelSize.width() << ", Height =" << labelSize.height(); if (!file.open(QIODevice::ReadOnly)) { @@ -107,6 +114,8 @@ void FFmpegDecoder::run() break; } + qDebug() << "H264 video resolution: Width =" << frame->width << ", Height =" << frame->height; + QImage img = avFrameToQImage(frame); QImage scaledImage = img.scaled(labelSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); currentVideoLabel->setPixmap(QPixmap::fromImage(scaledImage)); @@ -184,7 +193,7 @@ bool FFmpegDecoder::initializeFFmpeg(const QString& filePath) return false; } - frame = av_frame_alloc(); + frame = av_frame_alloc(); packet = av_packet_alloc(); return true; diff --git a/FactoryTestTool/SourceCode/Media/VideoDecoder/FFmpegDecoder.h b/FactoryTestTool/SourceCode/Media/VideoDecoder/FFmpegDecoder.h index 811ed7f..54219fa 100644 --- a/FactoryTestTool/SourceCode/Media/VideoDecoder/FFmpegDecoder.h +++ b/FactoryTestTool/SourceCode/Media/VideoDecoder/FFmpegDecoder.h @@ -12,6 +12,9 @@ #include #include #include +#include +#include + #include "RingBuffer.h" extern "C" { diff --git a/FactoryTestTool/SourceCode/Network/ClientHandler.cpp b/FactoryTestTool/SourceCode/Network/ClientHandler.cpp index 39c7c70..2371a26 100644 --- a/FactoryTestTool/SourceCode/Network/ClientHandler.cpp +++ b/FactoryTestTool/SourceCode/Network/ClientHandler.cpp @@ -8,7 +8,7 @@ ClientHandler::ClientHandler(QTcpSocket* socket, QJsonArray frontBoardOneClickTest, QJsonArray frontBoardTest, QJsonArray frontBoardFuncConfig, QJsonArray frontBoardDevInfoJson, QJsonArray frontBoardLicenseJson, QJsonArray backBoardOneClickTest, QJsonArray backBoardTest, QJsonArray backBoardFuncConfig, - QJsonArray backBoardDevInfoJson, + QJsonArray backBoardDevInfoJson, QJsonArray backBoardUuidJson, QJsonArray getPicJson, QJsonArray getVideoJson, int clientId, QObject* parent) : QObject(parent), socket(socket), frontBoardOneClickTest(frontBoardOneClickTest), frontBoardTest(frontBoardTest), @@ -16,7 +16,7 @@ ClientHandler::ClientHandler(QTcpSocket* socket, frontBoardLicenseJson(frontBoardLicenseJson), backBoardOneClickTest(backBoardOneClickTest), backBoardTest(backBoardTest), backBoardFuncConfig(backBoardFuncConfig), backBoardDevInfoJson(backBoardDevInfoJson), - getPicJson(getPicJson), getVideoJson(getVideoJson), + backBoardUuidJson(backBoardUuidJson), getPicJson(getPicJson), getVideoJson(getVideoJson), currentItemIndex(0), clientId(clientId), isManualSend(false), isSingleSend(false), isClickedSend(false), size(0), isFirstDataReceived(true), processDataFunction(nullptr), @@ -35,15 +35,17 @@ ClientHandler::~ClientHandler() { qDebug() << "ClientHandler destroyed for clientId:" << clientId; } -void ClientHandler::startReadVideoDataTimer() +void ClientHandler::startReadVideoDataTimer(int client_Id) { - emit startReadTimer(clientId); + //emit startReadTimer(clientId); + emit startReadTimer(client_Id); //qDebug() << "------ startClientReadTimer clientId:" << clientId; } -void ClientHandler::stopReadVideoDataTimer() +void ClientHandler::stopReadVideoDataTimer(int client_Id) { - emit stopReadTimer(clientId); + //emit stopReadTimer(clientId); + emit stopReadTimer(client_Id); } qint64 getFreeMemory() { @@ -121,18 +123,30 @@ void ClientHandler::sendDataToClient(const QByteArray& data) void ClientHandler::sendJsonItem(const QJsonArray& jsonArray, int itemIndex, const QString text, const QString& itemType) { + currentJson = jsonArray; + currentJsonItem = itemIndex; QMutexLocker locker(&mutex); if (itemType == "License") { } isSingleSend = true; isClickedSend = true; + isRecvImgData = false; if (itemType == "handleVideo") { - if(itemIndex == 0) - isRecvVideoData = 1; - else - isRecvVideoData = 0; - startReadVideoDataTimer(); + if (itemIndex == 0) { + qDebug() << "0 itemIndex: " << itemIndex; + isSingleSend = false; + isClickedSend = false; + } + else { + qDebug() << "!0 itemIndex: " << itemIndex; + stopReadVideoDataTimer(preVideoClientId); + } + } + if (itemType == "getPic") { + isSingleSend = false; + isClickedSend = false; + isRecvImgData = true; } qDebug() << "itemIndex:" << itemIndex; qDebug() << "jsonArray.size():" << jsonArray.size(); @@ -197,17 +211,7 @@ void ClientHandler::sendLicenseItem(int itemIndex, const QString text) qDebug() << "Invalid itemIndex"; return; } - QJsonObject item = frontBoardLicenseJson[itemIndex].toObject(); - QString label = item["lable"].toString(); - if (label == "write_license") { - LicenseConfirmWindow dialog("你确定要发送此授权项吗?"); - if (dialog.exec() == QDialog::Accepted) { - sendJsonItem(frontBoardLicenseJson, itemIndex, text, "License"); - } - } - else { - sendJsonItem(frontBoardLicenseJson, itemIndex, text, "License"); - } + sendJsonItem(frontBoardLicenseJson, itemIndex, text, "License"); } void ClientHandler::sendUuidItem(int itemIndex, const QString text) @@ -333,14 +337,6 @@ void ClientHandler::sendDevInfoJsonItem(const QJsonObject& jsonItem, int itemInd } } -//void ClientHandler::sendLicenseItem() -//{ -// if (currentLicenseIndex < frontBoardLicenseJson.size()) { -// -// currentLicenseIndex ++; -// } -//} - void ClientHandler::sendDevInfoItem() { // 前板 @@ -371,6 +367,9 @@ void ClientHandler::sendNextItem() isClickedSend = true; qDebug() << "------> locker(&mutex) :" << itemsProcessedCount; if (currentItemIndex < frontBoardOneClickTest.size()) { + currentJson = frontBoardOneClickTest; + currentJsonItem = currentItemIndex; + currentItem = frontBoardOneClickTest[currentItemIndex].toObject(); QString itemData = QJsonDocument(currentItem).toJson(); //qDebug() << "Sending item index:" << currentItemIndex << "data:" << itemData; @@ -411,19 +410,29 @@ void ClientHandler::sendNextItem() } void ClientHandler::RNDISClient1Data(QByteArray& data) { - qDebug() << " RNDISClient1Data size:" << data.size(); + //qDebug() << " RNDISClient1Data size:" << data.size(); + isRecvVideoData = false; + isStartVideo = false; } void ClientHandler::RNDISClient2Data(QByteArray& data) { - qDebug() << " RNDISClient2Data size:" << data.size(); + //qDebug() << " RNDISClient2Data size:" << data.size(); + isRecvVideoData = true; + isStartVideo = true; + //qDebug() << " isRecvVideoData:" << isRecvVideoData; } void ClientHandler::RNDISClient3Data(QByteArray& data) { - qDebug() << " RNDISClient3Data size:" << data.size(); + //qDebug() << " RNDISClient3Data size:" << data.size(); + isRecvVideoData = false; + isStartVideo = false; } void ClientHandler::RNDISClient4Data(QByteArray& data) { //qDebug() << " RNDISClient4Data size:" << data.size(); + //qDebug() << " RNDISClient4Data size:" << data.size(); + isRecvVideoData = false; + isStartVideo = false; } bool ClientHandler::RNDISFirstData(QByteArray& data) { @@ -431,9 +440,9 @@ bool ClientHandler::RNDISFirstData(QByteArray& data) { //int clientType = data.at(0); // 根据实际数据格式提取标识 bool ret = true; unsigned char clientType = static_cast(data[10]); - qDebug() << " clientType :" << clientType; + //qDebug() << " clientType :" << clientType; QByteArray tmpdata = data.left(11); - qDebug() << " tmpdata :" << tmpdata.toHex().data(); + //qDebug() << " clientType :" << clientType << " tmpdata :" << tmpdata.toHex().data(); switch (clientType) { case 0x01: processDataFunction = &ClientHandler::RNDISClient1Data; @@ -441,12 +450,15 @@ bool ClientHandler::RNDISFirstData(QByteArray& data) { socket->setReadBufferSize(20 * 1024); break; case 0x02: + qDebug() << " clientId :" << clientId; processDataFunction = &ClientHandler::RNDISClient2Data; socket->setReadBufferSize(100 * 1024); data = data.mid(11); (this->*processDataFunction)(data); setThreadPriority(QThread::HighPriority); preVideoClientId = clientId; + //qDebug() << " clientType :" << clientType << " preVideoClientId :" << preVideoClientId << " tmpdata :" << tmpdata.toHex().data(); + startReadVideoDataTimer(preVideoClientId); break; case 0x03: processDataFunction = &ClientHandler::RNDISClient3Data; @@ -503,12 +515,13 @@ void ClientHandler::setThreadPriority(QThread::Priority priority) { void ClientHandler::onDataReceived() { // 接收其他数据 添加区分 视频与其他数据 的标志位 - qDebug() << "isRecvVideoData:" << isRecvVideoData; - qDebug() << "isPowerOnSend:" << isPowerOnSend; - qDebug() << "isClickedSend:" << isClickedSend; - qDebug() << "isSingleSend:" << isSingleSend; + //qDebug() << "isRecvVideoData:" << isRecvVideoData; + //qDebug() << "isPowerOnSend:" << isPowerOnSend; + //qDebug() << "isClickedSend:" << isClickedSend; + //qDebug() << "isSingleSend:" << isSingleSend; + //qDebug() << "isRecvImgData:" << isRecvImgData; if (!isRecvVideoData && - (isPowerOnSend || isClickedSend || (isSingleSend && (currentItemIndex < frontBoardTest.size())))) { + (isRecvImgData || isPowerOnSend || isClickedSend || (isSingleSend && (currentItemIndex < frontBoardTest.size())))) { QByteArray allData; while (socket->bytesAvailable() > 0) { qint64 bytesAvailableBefore = socket->bytesAvailable(); @@ -527,7 +540,7 @@ void ClientHandler::onDataReceived() } if (!allData.isEmpty()) { //emit dataReceived(getClientAddress(), allData, 0xFF, currentItemIndex, currentFuncItemIndex, "", ""); - emit dataReceived(getClientAddress(), allData, 0xFF, currentItemIndex, currentFuncItemIndex, getCurrentItemLable(), ""); + emit dataReceived(getClientAddress(), allData, 0xFF, currentItemIndex, currentFuncItemIndex, getCurrentItemLable(), "", currentJson, currentJsonItem); if (!isSingleSend && !isPowerOnSend) { currentItemIndex ++; itemsProcessedCount ++; @@ -566,11 +579,19 @@ void ClientHandler::onDataReceived() // 接收视频流数据 isRecvVideoData 置 0 else if (isRecvVideoData && (!dataProcessingActive)) { dataProcessingActive = true; - isRecvVideoData = false; + if (!isStartVideo) { + isRecvVideoData = false; + } QTimer::singleShot(0, this, &ClientHandler::processPendingData); } - else { + else if(!isRecvVideoData && !isRecvImgData){ + if (preVideoClientId == clientId) { + qDebug() << "-----------------" << preVideoClientId << "isRecvVideoData:" << isRecvVideoData; + } + socket->readAll(); + //QByteArray data = socket->readAll(); + //qDebug() << "Received data:" << data; } } @@ -591,6 +612,7 @@ void ClientHandler::processPendingData() if (bytesRead > 0) { buffer.resize(bytesRead); + //qDebug() << "buffer.data():" << buffer.data(); allData.append(buffer); qint64 bytesAvailableAfter = socket->bytesAvailable(); /*qDebug() << "--1--Received data size:" << buffer.size() << "clientId:" << clientId @@ -626,7 +648,7 @@ void ClientHandler::processPendingData() } if (!allData.isEmpty()) { - emit dataReceived(getClientAddress(), allData, 0xFF, currentItemIndex, currentFuncItemIndex, "", ""); + emit dataReceived(getClientAddress(), allData, 0xFF, currentItemIndex, currentFuncItemIndex, "", "", currentJson, currentJsonItem); } // 如果还有数据需要处理,继续调度处理任务 @@ -668,7 +690,7 @@ void ClientHandler::onTimeout() //QString itemData = currentItem.value("data").toString(); //emit statusUpdated(socket->peerAddress().toString(), currentItemIndex, false, itemData); emit statusUpdated(getClientAddress(), currentItemIndex + 1, currentFuncItemIndex + 1, - false, getCurrentItemLable(), getCurrentFuncItemLable()); + false, getCurrentItemLable(), getCurrentFuncItemLable(), currentJson, currentJsonItem); if (!isSingleSend && !isPowerOnSend) { currentItemIndex ++; itemsProcessedCount ++; diff --git a/FactoryTestTool/SourceCode/Network/ClientHandler.h b/FactoryTestTool/SourceCode/Network/ClientHandler.h index a661d01..26959c8 100644 --- a/FactoryTestTool/SourceCode/Network/ClientHandler.h +++ b/FactoryTestTool/SourceCode/Network/ClientHandler.h @@ -32,13 +32,14 @@ public: explicit ClientHandler(QTcpSocket* socket, QJsonArray frontBoardOneClickTest, QJsonArray frontBoardTest, QJsonArray frontBoardFuncConfig, QJsonArray frontBoardDevInfoJson, QJsonArray frontBoardLicenseJson, QJsonArray backBoardOneClickTest, QJsonArray backBoardTest, QJsonArray backBoardFuncConfig, QJsonArray backBoardDevInfoJson, - QJsonArray getPicJson, QJsonArray getVideoJson, + QJsonArray backBoardUuidJson, QJsonArray getPicJson, QJsonArray getVideoJson, int clientId, QObject* parent = nullptr); ~ClientHandler(); - + int preVideoClientId = 0; + int controlClientId = 0; void sendDevInfoItem(); - + //int preVideoClientId = 0; bool isData_Stuck() const; //static int pre_H264_clientId; // 预览H264的客户端ID QTcpSocket* getSocket() const { return socket; } @@ -87,13 +88,15 @@ public: signals: // 数据接收信号 void dataReceived(const QString& client, const QByteArray& data, unsigned char msg_id, int currentRecvItemIndex, - int currentRecvFuncItemIndex, const QString& itemData, const QString& funcItemData); + int currentRecvFuncItemIndex, const QString& itemData, const QString& funcItemData, + const QJsonArray& jsonArray, int itemJsonIndex); void handleData(QByteArray& data); // 数据发送信号 void sendData(const QByteArray& data); // 状态更新信号 void statusUpdated(const QString& client, int itemIndex, int funcItemIndex, - bool success, const QString& itemData, const QString& funcItemData); + bool success, const QString& itemData, const QString& funcItemData, + const QJsonArray& jsonArray, int itemJsonIndex); // 客户端断开连接信号 void clientDisconnected(ClientHandler* handler); // json文件配置项发送完毕 @@ -116,8 +119,8 @@ public slots: void onTimeoutRead(); void checkConnectionStatus(); // 定期检查连接状态 void processPendingData(); - void startReadVideoDataTimer(); - void stopReadVideoDataTimer(); + void startReadVideoDataTimer(int client_Id); + void stopReadVideoDataTimer(int client_Id); private: QTcpSocket* socket; // 客户端 socket @@ -130,16 +133,19 @@ private: 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 clientId; // 新增的客户端编号 - int preVideoClientId = 0; - int controlClientId = 1; + + int itemsProcessedCount; // 跟踪处理项目的数量 QJsonObject currentItem; // 测试 json文件中当前发送的项 QJsonObject currentFuncItem; // 功能 json文件中当前发送的项 @@ -148,6 +154,8 @@ private: bool isSingleSend; // 单独点击按键发送的标志 bool isClickedSend; // 点击按键发送的标志,没有点击不接收数据 bool isRecvVideoData; + bool isRecvImgData = false; + bool isStartVideo = false; bool isPowerOnSend = false; // 上电发送设备信息 //QTimer* timeoutTimer; // 超时定时器 diff --git a/FactoryTestTool/SourceCode/Network/httpClient.cpp b/FactoryTestTool/SourceCode/Network/httpClient.cpp index 7e4bb5d..4cb9340 100644 --- a/FactoryTestTool/SourceCode/Network/httpClient.cpp +++ b/FactoryTestTool/SourceCode/Network/httpClient.cpp @@ -11,7 +11,7 @@ HttpClient::HttpClient(QObject* parent) void HttpClient::sendPostRequest(const QNetworkRequest& request, const QByteArray& jsonData) { - qDebug() << "jsonData" << jsonData.data(); + qDebug() << "jsonData" << jsonData; networkManager->post(request, jsonData); } diff --git a/FactoryTestTool/SourceCode/RecvDataHandler/RecvDataHandler.cpp b/FactoryTestTool/SourceCode/RecvDataHandler/RecvDataHandler.cpp index 34d1ca7..04551c3 100644 --- a/FactoryTestTool/SourceCode/RecvDataHandler/RecvDataHandler.cpp +++ b/FactoryTestTool/SourceCode/RecvDataHandler/RecvDataHandler.cpp @@ -3,13 +3,24 @@ #include "../Network/ClientHandler.h" DataHandler::DataHandler(QLabel* leftLens_imageLabel, QLabel* rightLens_imageLabel, QLabel* videoLabel, - QTextEdit* licenseHwInfoEdit, QMap* devInfoLineEdits, QObject* parent) + QTextEdit* licenseHwInfoEdit, QMap* devInfoLineEdits, + 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), leftLens_m_imageLabel(leftLens_imageLabel), rightLens_m_imageLabel(rightLens_imageLabel), videoLabel(videoLabel), licenseHwInfoEdit(licenseHwInfoEdit), devInfoLineEdits(devInfoLineEdits), + frontBoardOneClickTest(frontBoardOneClickTest), frontBoardTest(frontBoardTest), + frontBoardFuncConfig(frontBoardFuncConfig), frontBoardDevInfoJson(frontBoardDevInfoJson), + frontBoardLicenseJson(frontBoardLicenseJson), + backBoardOneClickTest(backBoardOneClickTest), backBoardTest(backBoardTest), + backBoardFuncConfig(backBoardFuncConfig), backBoardDevInfoJson(backBoardDevInfoJson), + backBoardUuidJson(backBoardUuidJson), getPicJson(getPicJson), getVideoJson(getVideoJson), ffmpegDecoder(new FFmpegDecoder()), // 初始化FFmpeg解码器 buffer(new QByteArray()) { @@ -90,12 +101,12 @@ void DataHandler::clearAllRecvData() { // 处理接收到的数据 void DataHandler::handleData(const QString& client, const QByteArray& recvData, int msg_id, int currentRecvItemIndex, int currentRecvFuncItemIndex, - const QString& itemData, const QString& funcItemData) + const QString& itemData, const QString& funcItemData, const QJsonArray& jsonArray, int itemJsonIndex) { //qDebug() << "Data received from" << client << ":" << recvData; #if 0 - 从文件中读取YUV数据 - QFile file("output_2.txt"); + 从文件中读取YUV数据 + QFile file("output_2.txt"); if (!file.open(QIODevice::ReadOnly)) { qWarning() << "Failed to open file:"; file.close(); @@ -120,29 +131,43 @@ void DataHandler::handleData(const QString& client, const QByteArray& recvData, (static_cast(buffer->at(8)) << 16) | (static_cast(buffer->at(7)) << 8) | (static_cast(buffer->at(6))); + //qDebug() << "---Received dataSize:" << dataSize; + //qDebug() << "---msg_id:" << QString::number(msg_id, 16).toUpper(); + //qDebug() << "---(static_cast(buffer->at(10)):" << static_cast(buffer->at(10)); + //qDebug() << "---(static_cast(buffer->at(11)):" << static_cast(buffer->at(11)); + //qDebug() << "---(static_cast(buffer->at(12)):" << static_cast(buffer->at(12)); + //qDebug() << "---(static_cast(buffer->at(13)):" << static_cast(buffer->at(13)); + //qDebug() << "---(static_cast(buffer->at(14)):" << static_cast(buffer->at(14)); + //qDebug() << "---(static_cast(buffer->at(15)):" << static_cast(buffer->at(15)); // 第11字节为返回 OK/NG - bool success = (static_cast(buffer->at(10)) == 0x00); - //int totalSize = 10 + dataSize + 1; // 数据头大小(10字节) + success + 实际数据 - int totalSize = 10 + dataSize; // 数据头大小(10字节) + 实际数据大小 + bool success = (static_cast(buffer->at(10)) == 0x00); + int totalSize = 10 + dataSize; // 数据头大小(10字节) + 实际数据大小 if (buffer->size() >= totalSize) { // 去掉前面 11 字节 - QByteArray data = buffer->mid(11, dataSize); + QByteArray data = buffer->mid(11, dataSize); //QByteArray data = buffer->mid(10, dataSize); - QString hexString = QString::fromUtf8(data.toHex().data()); + QString hexString = QString::fromUtf8(data.toHex().data()); QByteArray actual_data = hexStringToByteArray(hexString); //qDebug() << "---Received hexString:" << hexString; buffer->remove(0, totalSize); // 移除已处理的数据 - // 暂时设置 NG - // 同一个client仅当 msg_id 不连续为 0x11/0x21 或第一次处理时才执行 emit statusUpdated - if ((msg_id != 0x0011 || clientLastMsgId.value(client, 0) != 0x0011) && - (msg_id != 0x0021 || clientLastMsgId.value(client, 0) != 0x0021)){ - qDebug() << "Emitting statusUpdated for client:" << client << "with msg_id:" << QString::number(msg_id, 16).toUpper(); - emit statusUpdated(client, currentRecvItemIndex + 1, currentRecvFuncItemIndex + 1, - true, itemData, funcItemData); - } - clientLastMsgId[client] = msg_id; - handleCmd(msg_id, client, actual_data); + if(msg_id != 0x0040 && msg_id != START_VIDEO) { + //if (msg_id != 0x0040) { + qDebug() << "--- msg_id:" << msg_id; + qDebug() << "--- clientLastMsgId.value(client, 0):" << clientLastMsgId.value(client, 0); + // 同一个client仅当 msg_id 不连续为 0x11/0x21 或第一次处理时才执行 emit statusUpdated + 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(client, currentRecvItemIndex + 1, currentRecvFuncItemIndex + 1, + true, itemData, funcItemData, jsonArray, itemJsonIndex); + } + clientLastMsgId[client] = msg_id; + qDebug() << "--- client:" << client; + qDebug() << "--- clientLastMsgId[client]:" << clientLastMsgId[client]; + } + handleCmd(msg_id, client, actual_data); } else { break; // 数据还不完整,等待下一次接收 @@ -154,6 +179,7 @@ void DataHandler::handleData(const QString& client, const QByteArray& recvData, } } + void DataHandler::initializeMsgIdToCmdMap() { msgIdToCmdMap[GET_FRONT_V851_VERSION] = "GET_FRONT_V851_VERSION"; msgIdToCmdMap[GET_FRONT_MCU_VERSION] = "GET_FRONT_MCU_VERSION"; @@ -256,12 +282,12 @@ void DataHandler::handleFrontCmd(int msg_id, const QString& client, QByteArray a break; case GET_IMG: { - + showPic(leftLens_m_imageLabel, rightLens_m_imageLabel, client, actual_data); } break; case START_VIDEO: { - + showVideo(client, actual_data); } break; case STOP_VIDEO: diff --git a/FactoryTestTool/SourceCode/RecvDataHandler/RecvDataHandler.h b/FactoryTestTool/SourceCode/RecvDataHandler/RecvDataHandler.h index d83b5dd..f3d6c71 100644 --- a/FactoryTestTool/SourceCode/RecvDataHandler/RecvDataHandler.h +++ b/FactoryTestTool/SourceCode/RecvDataHandler/RecvDataHandler.h @@ -34,18 +34,38 @@ class DataHandler : public QObject public: explicit DataHandler(QLabel* leftLens_imageLabel, QLabel* rightLens_imageLabel, QLabel* videoLabel, - QTextEdit* licenseHwInfoEdit, QMap* devInfoLineEdits, QObject* parent = nullptr); + QTextEdit* licenseHwInfoEdit, QMap* devInfoLineEdits, + 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); ~DataHandler(); public slots: void handleData(const QString& client, const QByteArray& data, int msg_id, int currentRecvItemIndex, - int currentRecvFuncItemIndex, const QString& itemData, const QString& funcItemData); + int currentRecvFuncItemIndex, const QString& itemData, const QString& funcItemData, + const QJsonArray& jsonArray, int itemJsonIndex); signals: void statusUpdated(const QString& clientAddress, int currentItemIndex, int currentFuncItemIndex, - bool success, const QString& currentItemLabel, const QString& currentFuncItemLabel); + bool success, const QString& currentItemLabel, const QString& currentFuncItemLabel, + const QJsonArray& jsonArray, int itemJsonIndex); 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; diff --git a/FactoryTestTool/SourceCode/Widget/MainWidget.cpp b/FactoryTestTool/SourceCode/Widget/MainWidget.cpp index 66f2708..2ff610d 100644 --- a/FactoryTestTool/SourceCode/Widget/MainWidget.cpp +++ b/FactoryTestTool/SourceCode/Widget/MainWidget.cpp @@ -80,7 +80,7 @@ MainWidget::MainWidget(QWidget* parent) : ClientHandler* handler = new ClientHandler(socket, frontBoardOneClickTest, frontBoardTest, frontBoardFuncConfig, frontBoardDevInfoJson, frontBoardLicenseJson, backBoardOneClickTest, backBoardTest, backBoardFuncConfig, backBoardDevInfoJson, - getPicJson, getVideoJson, clientId, nullptr); + backBoardUuidJson, getPicJson, getVideoJson, clientId, nullptr); // 将 ClientHandler 移动到线程池中的线程 handler->moveToThread(thread); @@ -119,18 +119,22 @@ MainWidget::MainWidget(QWidget* parent) : clients.append(handler); clients_1[clientId] = handler; clientThreads[clientId] = thread; - connect(handler, &ClientHandler::statusUpdated, this, &MainWidget::onStatusUpdated); - connect(handler, &ClientHandler::clientDisconnected, this, &MainWidget::onClientDisconnected); - connect(handler, &ClientHandler::allItemsProcessed, this, &MainWidget::onAllItemsProcessed); + connect(handler, &ClientHandler::statusUpdated, this, &MainWidget::onStatusUpdated); + connect(handler, &ClientHandler::clientDisconnected, this, &MainWidget::onClientDisconnected); + connect(handler, &ClientHandler::allItemsProcessed, this, &MainWidget::onAllItemsProcessed); connect(handler, &ClientHandler::selectClientDisconnected, this, &MainWidget::onDisconnectClient); // 创建 DataHandler 对象并连接信号 - DataHandler* dataHandler = new DataHandler(leftLens_imageLabel, rightLens_imageLabel, videoLabel, licenseHwInfoEdit, &devInfoLineEdits, this); - connect(handler, &ClientHandler::dataReceived, dataHandler, &DataHandler::handleData); - connect(dataHandler, &DataHandler::statusUpdated, this, &MainWidget::onStatusUpdated); + DataHandler* dataHandler = new DataHandler(leftLens_imageLabel, rightLens_imageLabel, videoLabel, licenseHwInfoEdit, &devInfoLineEdits, + frontBoardOneClickTest, frontBoardTest, frontBoardFuncConfig, + frontBoardDevInfoJson, frontBoardLicenseJson, + backBoardOneClickTest, backBoardTest, backBoardFuncConfig, backBoardDevInfoJson, + backBoardUuidJson, getPicJson, getVideoJson, this); + connect(handler, &ClientHandler::dataReceived, dataHandler, &DataHandler::handleData); + connect(dataHandler, &DataHandler::statusUpdated, this, &MainWidget::onStatusUpdated); - connect(handler, &ClientHandler::startReadTimer, this, &MainWidget::startClientReadTimer); - connect(handler, &ClientHandler::stopReadTimer, this, &MainWidget::stopClientReadTimer); + connect(handler, &ClientHandler::startReadTimer, this, &MainWidget::startClientReadTimer); + connect(handler, &ClientHandler::stopReadTimer, this, &MainWidget::stopClientReadTimer); // 创建和管理定时器 QTimer* readTimer = new QTimer(this); @@ -244,9 +248,10 @@ void MainWidget::onHttpRequestError(const QString& errorString) isRequestSuccessful = 2; } -QString generateRandomRequestID() { +// 生成随机字符串 +QString generateRandomRequestID(int minBitStr, int maxBitStr) { const QString possibleCharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.~"; - int length = QRandomGenerator::global()->bounded(1, 33); // 生成长度在1到32之间 + int length = QRandomGenerator::global()->bounded(minBitStr, maxBitStr); // 生成长度在minBitStr到maxBitStr之间 QString randomString; for (int i = 0; i < length; ++i) { int index = QRandomGenerator::global()->bounded(possibleCharacters.size()); @@ -256,6 +261,7 @@ QString generateRandomRequestID() { return randomString; } +// 哈希256 转 base64 QString HmacSha256ToBase64(const QString& data, const QString& secret) { QByteArray keyBytes = secret.toUtf8(); QByteArray dataBytes = data.toUtf8(); @@ -319,7 +325,7 @@ void prepareRequestHeaders(QNetworkRequest& request, const QString& sign, const // GET 请求 void sendGetRequest(HttpClient* httpClient, const QUrl& url, const QMap& params, const QString& secret) { - QString request_id = generateRandomRequestID(); + QString request_id = generateRandomRequestID(1, 33); qDebug() << "request_id:" << request_id; QUrl modifiedUrl = url; QUrlQuery query; @@ -337,7 +343,7 @@ void sendGetRequest(HttpClient* httpClient, const QUrl& url, const QMap& params, const QJsonObject& jsonData, const QString& secret) { - QString request_id = generateRandomRequestID(); + QString request_id = generateRandomRequestID(1, 33); qDebug() << "request_id:" << request_id; QString sign = calculateSignature(params, "POST", secret, request_id, QString::number(QDateTime::currentSecsSinceEpoch())); qDebug() << "sendPostRequest URL:" << url.toString(); @@ -357,7 +363,6 @@ void MainWidget::FactoryToolSendGetUuidToHttpServer(const QString& mac_addr) { {"batch", "1"}, {"mac", mac_addr} }; - QString secret = "rCeOzwisLFLasvlt"; sendGetRequest(httpClient, url, params, secret); } @@ -423,12 +428,14 @@ void MainWidget::FactoryToolSendPostTestToHttpServer() { // POST 图语 License 上报 void MainWidget::FactoryToolSendPostLicenseToHttpServer(const QString& hardware_info, const QString& license_info) { QUrl url("http://admin.hassecurity.cn/v1/algorithmKey"); - QString UTC_time = QString::number(QDateTime::currentSecsSinceEpoch()); + + + qint64 UTC_time = QDateTime::currentSecsSinceEpoch(); + QMap params = { {"id", hardware_info}, {"key", license_info}, - {"time", UTC_time}, - {"type", "TUYU"} + {"time", QString::number(UTC_time)} }; QJsonObject jsonData = { @@ -565,6 +572,7 @@ void MainWidget::setupUI() leftLayout->setStretch(1, 200); saveCheckBox = new QCheckBox("", this); + saveCheckBox->setChecked(true); selectFileButton = new QPushButton("Save", this); selectFileButton->setFixedSize(45, 28); clearLogButton = new QPushButton("Clear", this); @@ -585,10 +593,6 @@ void MainWidget::setupUI() // 读取 JSON 配置文件 readJsonConfig(); - /*QGroupBox* groupBox = createLicenseGroupBox(); - leftLayout->addWidget(groupBox); - leftLayout->setStretch(3, 1);*/ - QWidget* leftContainer = new QWidget(this); leftContainer->setLayout(leftLayout); leftContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); @@ -657,7 +661,7 @@ void MainWidget::setupUI() setLayout(mainLayout); setWindowTitle("SL100 工厂产测工具 - V0.0.1"); - resize(1340, 1000); + resize(1340, 900); connect(startServerButton, &QPushButton::clicked, this, &MainWidget::onStartServerClicked); connect(sendAllButton, &QPushButton::clicked, this, &MainWidget::onSendAllClicked); @@ -682,19 +686,29 @@ void MainWidget::onclearLogButtonClicked() void MainWidget::onSaveCheckBoxStateChanged(int state) { - if (state == Qt::Checked) { - saveStatusListToFile(filePathLineEdit->text()); - } + if (state == Qt::Checked) checkBoxState = true; + else checkBoxState = false; } void MainWidget::saveStatusListToFile(const QString& filePath) { - if (filePath.isEmpty()) { - return; + QString actualFilePath = filePath; + if (actualFilePath.isEmpty()) { + QString defaultDirPath = QDir::currentPath() + "/TestLog"; + QDir dir(defaultDirPath); + if (!dir.exists()) { + if (!dir.mkpath(defaultDirPath)) { + qWarning() << "Failed to create directory:" << defaultDirPath; + return; + } + } + QString currentTime = QDateTime::currentDateTime().toString("yyyyMMdd_HHmmss"); + actualFilePath = defaultDirPath + "/" + currentTime + ".txt"; } - QFile file(filePath); + QFile file(actualFilePath); if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { + qWarning() << "Failed to open file:" << actualFilePath; return; } @@ -755,6 +769,24 @@ void MainWidget::onDisconnectClient(int clientId) void MainWidget::onClientDisconnected(ClientHandler* handler) { int clientId = handler->getClientId(); + qDebug() << " preVideoClientId :" << handler->preVideoClientId; + qDebug() << " clientId :" << clientId; + if (handler->preVideoClientId == clientId) { + qDebug() << "Current path: " << QDir::currentPath(); + QString filePath = QDir::currentPath() + "/add1.h264"; + if (QFile::exists(filePath)) { + QFile file(filePath); + if (file.open(QIODevice::WriteOnly | QIODevice::Truncate)) { // 使用 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."; + } + } if (clientTimers.contains(clientId)) { QTimer* timer = clientTimers[clientId]; timer->stop(); @@ -771,8 +803,10 @@ void MainWidget::onClientDisconnected(ClientHandler* handler) // 更新连接数并更新按键文本 connectedClientsCount--; + qDebug() << " connectedClientsCount :" << connectedClientsCount; if (nextClientId <= 2) nextClientId--; deviceConnected = true; + updateServerButtonText(); } @@ -829,6 +863,7 @@ void MainWidget::onLicenseButtonClicked() } qDebug() << "isRequestSuccessful:" << isRequestSuccessful; if (isRequestSuccessful == 2) { + isRequestSuccessful = 0; return; } else if(isRequestSuccessful == 1) { @@ -839,6 +874,7 @@ void MainWidget::onLicenseButtonClicked() licenseKey = formatLicenseKey(licenseKey); licenseHwInfoEdit->setPlainText(licenseKey); qDebug() << "HTTP Server License is:" << licenseKey; + isRequestSuccessful = 0; return; } } @@ -856,13 +892,19 @@ void MainWidget::onLicenseButtonClicked() QByteArray dataByteArray = QByteArray::fromHex(dataStr.toUtf8()); memcpy(hardware_info, dataByteArray.data(), qMin(dataByteArray.size(), PIX_HARDWARE_INFO_BYTES)); //unsigned char hardware_info[PIX_HARDWARE_INFO_BYTES] = { 0x46,0x0b,0x5d,0x11,0x58,0x17,0x4d,0x5e,0x55,0x5c,0x51,0x4a,0x5a,0x07,0x59,0x4c,0x5f,0x45,0x5b,0x5f,0x5a,0x45,0x1c,0x5a,0x45,0x43,0x44,0x47,0x51,0x5e,0x44,0x30 }; - LicenseConfirmWindow dialog("你确定要获取此授权吗?"); + LicenseConfirmWindow dialog("你确定要获取此授权吗?\n请确认你的hw_info是否正确"); if (dialog.exec() == QDialog::Accepted) { -#if 0 - licenseGenerate(hardware_info, license_info); +#if !MANUAL_UPLOAD_LICENSE + if (!(licenseGenerate(hardware_info, license_info))) { + qDebug() << "从U盘获取License失败" ; + isRequestSuccessful = 0; + licenseHwInfoEdit->setPlainText("从U盘获取License失败,请检查U盘是否插入电脑!!!"); + return; + } QString licenseInfoHex = QByteArray(reinterpret_cast(license_info), PIX_LICENCE_BYTES).toHex().toUpper(); #else - unsigned char license_info_1[PIX_LICENCE_BYTES] = { 0x07, 0xe8, 0xf3, 0x80, 0xa8, 0x07, 0x72, 0xa1, 0x17, 0xfe, 0xda, 0x67, 0xbd, 0x4a, 0x5a, 0xb5, 0xbb, 0x8b, 0x2d, 0xb2, 0xbf, 0x89, 0x74, 0xe5, 0xb0, 0x99, 0x70, 0x74, 0x3c, 0x6f, 0xf8, 0x82, 0x79, 0xab, 0x31, 0x9c, 0xdf, 0xe8, 0x9e, 0x75, 0x8f, 0x42, 0xb3, 0xcf, 0x00, 0x60, 0xa0, 0x38, 0xa4, 0xb8, 0xbe, 0xa6, 0x5d, 0x9f, 0x8b, 0x41, 0xf3, 0x0a, 0x69, 0xf6, 0x50, 0x94, 0x3f, 0xd0, 0xa5, 0xee, 0x88, 0x20, 0x93, 0x9a, 0x1c, 0xe9, 0x64, 0xd3, 0xaf, 0x9f, 0xc7, 0x66, 0x00, 0x7d, 0x7d, 0x68, 0xf1, 0xa4, 0xe1, 0x58, 0x00, 0x1d, 0x03, 0x0d, 0x40, 0x08, 0xa4, 0xcc, 0x0b, 0xd8, 0x19, 0x70, 0x9a, 0x83, 0x81, 0xbf, 0x27, 0x35, 0xb8, 0xec, 0x59, 0xa8, 0xd0, 0x03, 0xdb, 0xf6, 0xcf, 0x83, 0xaa, 0x0e, 0xfc, 0x95, 0x29, 0x77, 0xec, 0x89, 0xc5, 0x79, 0x10, 0x40, 0xd8, 0xbb }; + //unsigned char license_info_1[PIX_LICENCE_BYTES] = { 0x07, 0xe8, 0xf3, 0x80, 0xa8, 0x07, 0x72, 0xa1, 0x17, 0xfe, 0xda, 0x67, 0xbd, 0x4a, 0x5a, 0xb5, 0xbb, 0x8b, 0x2d, 0xb2, 0xbf, 0x89, 0x74, 0xe5, 0xb0, 0x99, 0x70, 0x74, 0x3c, 0x6f, 0xf8, 0x82, 0x79, 0xab, 0x31, 0x9c, 0xdf, 0xe8, 0x9e, 0x75, 0x8f, 0x42, 0xb3, 0xcf, 0x00, 0x60, 0xa0, 0x38, 0xa4, 0xb8, 0xbe, 0xa6, 0x5d, 0x9f, 0x8b, 0x41, 0xf3, 0x0a, 0x69, 0xf6, 0x50, 0x94, 0x3f, 0xd0, 0xa5, 0xee, 0x88, 0x20, 0x93, 0x9a, 0x1c, 0xe9, 0x64, 0xd3, 0xaf, 0x9f, 0xc7, 0x66, 0x00, 0x7d, 0x7d, 0x68, 0xf1, 0xa4, 0xe1, 0x58, 0x00, 0x1d, 0x03, 0x0d, 0x40, 0x08, 0xa4, 0xcc, 0x0b, 0xd8, 0x19, 0x70, 0x9a, 0x83, 0x81, 0xbf, 0x27, 0x35, 0xb8, 0xec, 0x59, 0xa8, 0xd0, 0x03, 0xdb, 0xf6, 0xcf, 0x83, 0xaa, 0x0e, 0xfc, 0x95, 0x29, 0x77, 0xec, 0x89, 0xc5, 0x79, 0x10, 0x40, 0xd8, 0xbb }; + unsigned char license_info_1[PIX_LICENCE_BYTES] = { 0x6a, 0x70, 0xc0, 0x40, 0xc9, 0x20, 0xf5, 0xd2, 0x78, 0xac, 0x05, 0x80, 0xa6, 0xcf, 0x3f, 0xd5, 0x72, 0xf6, 0xc3, 0x82, 0x11, 0x0d, 0x56, 0x37, 0xb3, 0x87, 0x19, 0x13, 0x79, 0xa5, 0x9b, 0x37, 0xf2, 0xab, 0xcb, 0xa3, 0xea, 0xc4, 0x45, 0xc6, 0xae, 0xc4, 0xa4, 0x72, 0xe9, 0x36, 0x1e, 0xbe, 0x78, 0xd6, 0xcd, 0x85, 0xd, 0x63, 0x93, 0x7a, 0x84, 0x9a, 0x31, 0x99, 0xe1, 0x09, 0xc1, 0xfa, 0xbe, 0x32, 0x42, 0xc5, 0xc9, 0x89, 0x03, 0x7e, 0x81, 0xe5, 0x25, 0xf, 0x4d, 0x68, 0x9d, 0x53, 0xd1, 0x04, 0x29, 0x34, 0x53, 0x09, 0x22, 0x5, 0x29, 0xce, 0xb1, 0xc9, 0x01, 0xed, 0x2a, 0xd2, 0x16, 0xfb, 0x3c, 0x27, 0xba, 0x4a, 0x69, 0x10, 0x3a, 0x54, 0x5a, 0x8f, 0xca, 0x47, 0x8d, 0x34, 0x2b, 0x57, 0xad, 0x27, 0x9a, 0x15, 0x37, 0x86, 0x60, 0xd6, 0x34, 0xd8, 0x32, 0xee, 0x9c, 0x46 }; QString licenseInfoHex = QByteArray(reinterpret_cast(license_info_1), PIX_LICENCE_BYTES).toHex().toUpper(); #endif qDebug() << "上报服务器 licenseInfoHex:" << licenseInfoHex; @@ -871,13 +913,17 @@ void MainWidget::onLicenseButtonClicked() QString licenseInfoStr; printf("U盘 Get License is\n"); for (int j = 0; j < PIX_LICENCE_BYTES; ++j) { - //printf("0x%02x, ", license_info[j]); - //licenseInfoStr.append(QString::asprintf("0x%02x, ", license_info[j])); +#if !MANUAL_UPLOAD_LICENSE + printf("0x%02x, ", license_info[j]); + licenseInfoStr.append(QString::asprintf("0x%02x, ", license_info[j])); +#else printf("0x%02x, ", license_info_1[j]); licenseInfoStr.append(QString::asprintf("0x%02x, ", license_info_1[j])); +#endif } printf("\n"); licenseHwInfoEdit->setPlainText(licenseInfoStr); + isRequestSuccessful = 0; } } else { @@ -908,15 +954,14 @@ void MainWidget::onLicenseButtonClicked() dataStr = dataStr.replace("0x", "").replace(" ", ""); // 去掉0x和空格 QByteArray dataByteArray = QByteArray::fromHex(dataStr.toUtf8()); memcpy(license_info, dataByteArray.data(), qMin(dataByteArray.size(), PIX_LICENCE_BYTES)); - //qDebug() << "hardware_info:" << QByteArray(reinterpret_cast(hardware_info), PIX_HARDWARE_INFO_BYTES).toHex(); - //licenseGenerate(hardware_info, license_info); QString licenseInfoStr; for (int j = 0; j < PIX_LICENCE_BYTES; ++j) { licenseInfoStr.append(QString::asprintf("0x%02x, ", license_info[j])); } - //printf("\n"); dataStr = QByteArray(reinterpret_cast(license_info), PIX_LICENCE_BYTES).toHex(); qDebug() << "license_info:" << dataStr; + dataStr = dataByteArray.toBase64(); + qDebug() << "Base64 Encoded:" << dataStr; } #endif for (ClientHandler* handler : clients) { @@ -932,41 +977,6 @@ void MainWidget::onLicenseButtonClicked() } } -//void MainWidget::onLicenseButtonClicked() -//{ -// if (connectedClientsCount) { -// QPushButton* button = qobject_cast(sender()); -// if (button) { -// int index = button->property("licenseIndex").toInt(); -// if (index >= 0 && index < frontBoardLicenseJson.size()) { -// QJsonObject jsonObject = frontBoardLicenseJson[index].toObject(); -// //QString jsonString = QJsonDocument(jsonObject).toJson(QJsonDocument::Compact); -// //qDebug() << "license Button clicked, sending JSON:" << jsonString; -// unsigned char license_info[PIX_LICENCE_BYTES] = { 0 }; -// if (jsonObject["lable"].toString() == "get_license") { -// LicenseConfirmWindow dialog("你确定要获取此授权吗?"); -// if (dialog.exec() == QDialog::Accepted) -// licenseGenerate(license_info, license_info); -// } -// else { -// if (jsonObject["lable"].toString() == "write_license") { -// LicenseConfirmWindow dialog("你确定要发送此授权吗?"); -// if (dialog.exec() == QDialog::Accepted) -// licenseGenerate(license_info, license_info); -// } -// for (ClientHandler* handler : clients) { -// handler->sendLicenseItem(index); -// } -// } -// } -// } -// } -// else { -// QListWidgetItem* listItem = new QListWidgetItem(QString("No device is connected !!!"), statusListWidget); -// listItem->setBackground(Qt::red); -// } -//} - void MainWidget::onUuidButtonClicked() { if (connectedClientsCount) { @@ -975,17 +985,27 @@ void MainWidget::onUuidButtonClicked() int index = button->property("UuidIndex").toInt(); if (index >= 0 && index < backBoardUuidJson.size()) { QJsonObject jsonObject = backBoardUuidJson[index].toObject(); - //QString jsonString = QJsonDocument(jsonObject).toJson(QJsonDocument::Compact); - //qDebug() << "license Button clicked, sending JSON:" << jsonString; - unsigned char license_info[PIX_LICENCE_BYTES] = { 0 }; - if (jsonObject["lable"].toString() == "get_license") { - + QString dataStr = ""; + if (jsonObject["lable"].toString() == "get_UUID_SN") { + QString sendToHttpServerDataStr = UuidHwInfoEdit->toPlainText(); + qDebug() << "sendToHttpServerDataStr:" << sendToHttpServerDataStr; + // 测试随机生成8-12位字符串 + sendToHttpServerDataStr = generateRandomRequestID(8, 13); + FactoryToolSendGetUuidToHttpServer(sendToHttpServerDataStr); + while (isRequestSuccessful == 0) { + QCoreApplication::processEvents(); // 防止阻塞UI线程 + } + qDebug() << "isRequestSuccessful:" << isRequestSuccessful; + if (isRequestSuccessful == 2) { + return; + } + else if (isRequestSuccessful == 1) { + + } } else { - if (jsonObject["lable"].toString() == "write_license") { - LicenseConfirmWindow dialog("你确定要发送此授权吗?"); - if (dialog.exec() == QDialog::Accepted) - licenseGenerate(license_info, license_info); + if (jsonObject["lable"].toString() == "write_UUID_SN") { + } for (ClientHandler* handler : clients) { handler->sendUuidItem(index, ""); @@ -1094,7 +1114,10 @@ void MainWidget::onSendGetDevInfoClicked() } else { for (ClientHandler* handler : clients) { - handler->sendGetDevInfoItem(itemIndex); + if (handler->getClientId() == handler->controlClientId) { + handler->sendGetDevInfoItem(itemIndex); + break; + } } } } @@ -1125,7 +1148,7 @@ void MainWidget::onSendGetPicClicked() } else { if (itemIndex - 2 >= connectedClientsCount) { - QListWidgetItem* listItem = new QListWidgetItem(QString("No device %1 is connected !!!").arg(itemIndex - 1), statusListWidget); + QListWidgetItem* listItem = new QListWidgetItem(QString("This device is not connected !!!"), statusListWidget); listItem->setBackground(Qt::red); } else { @@ -1136,7 +1159,10 @@ void MainWidget::onSendGetPicClicked() lastClickedGetPicDevIndex = itemIndex; //QMutexLocker locker(&mutex); for (ClientHandler* handler : clients) { - handler->sendGetPicItem(itemIndex - 2, lastClickedGetPicCamIndex); + if (handler->getClientId() == handler->controlClientId) { + handler->sendGetPicItem(itemIndex - 2, lastClickedGetPicCamIndex); + break; + } } } } @@ -1169,18 +1195,24 @@ void MainWidget::onSendGetVideoClicked() } else { if (itemIndex - 6 >= connectedClientsCount) { - QListWidgetItem* listItem = new QListWidgetItem(QString("No device %1 is connected !!!").arg(itemIndex - 4), statusListWidget); + QListWidgetItem* listItem = new QListWidgetItem(QString("This device is not connected !!!").arg(itemIndex - 4), statusListWidget); listItem->setBackground(Qt::red); } else { + //qDebug() << "lastClickedGetVideoDevIndex:" << lastClickedGetVideoDevIndex; + //qDebug() << "itemIndex:" << itemIndex; button->setStyleSheet("background-color: green;"); if (lastClickedGetVideoDevIndex != -1 && lastClickedGetVideoDevIndex != itemIndex) { - getVideoButtons[lastClickedGetVideoDevIndex]->setStyleSheet(""); + //qDebug() << "itemIndex:" << itemIndex; + getVideoButtons[lastClickedGetVideoDevIndex - 2]->setStyleSheet(""); } lastClickedGetVideoDevIndex = itemIndex; //QMutexLocker locker(&mutex); for (ClientHandler* handler : clients) { - handler->sendGetVideoItem(itemIndex - 5, 1); + if (handler->getClientId() == handler->controlClientId) { + handler->sendGetVideoItem(itemIndex - 5, lastClickedGetVideoCamIndex); + break; + } } getVideoButtons[2]->setEnabled(true); } @@ -1220,8 +1252,11 @@ void MainWidget::onSendAllClicked() for (ClientHandler* handler : clients) { // 重置索引 handler->resetCurrentItemIndex(); - handler->sendNextItem(); - //handler->sendDevInfoItem(); + if (handler->getClientId() == handler->controlClientId) { + handler->sendNextItem(); + //handler->sendDevInfoItem(); + break; + } } } else { @@ -1246,9 +1281,12 @@ void MainWidget::onSendFrontFuncItemClicked() QPushButton* button = qobject_cast(sender()); int itemIndex = button->property("frontBoardFuncConfig").toInt(); for (ClientHandler* handler : clients) { - QString text = frontFuncConfigLineEdit->text(); - qDebug() << "Text in frontFuncConfigLineEdit:" << text; - handler->sendFrontFuncItem(itemIndex, text); + if (handler->getClientId() == handler->controlClientId) { + QString text = frontFuncConfigLineEdit->text(); + qDebug() << "Text in frontFuncConfigLineEdit:" << text; + handler->sendFrontFuncItem(itemIndex, text); + break; + } } } else { @@ -1263,9 +1301,12 @@ void MainWidget::onSendBackFuncItemClicked() QPushButton* button = qobject_cast(sender()); int itemIndex = button->property("backBoardFuncConfig").toInt(); for (ClientHandler* handler : clients) { - QString text = backFuncConfigLineEdit->text(); - qDebug() << "Text in backFuncConfigLineEdit:" << text; - handler->sendBackFuncItem(itemIndex, text); + if (handler->getClientId() == handler->controlClientId) { + QString text = backFuncConfigLineEdit->text(); + qDebug() << "Text in backFuncConfigLineEdit:" << text; + handler->sendBackFuncItem(itemIndex, text); + break; + } } } else { @@ -1282,7 +1323,10 @@ void MainWidget::onSendFrontItemClicked() QPushButton* button = qobject_cast(sender()); int itemIndex = button->property("frontBoardTest").toInt(); for (ClientHandler* handler : clients) { - handler->sendFrontItem(itemIndex); + if (handler->getClientId() == handler->controlClientId) { + handler->sendFrontItem(itemIndex); + break; + } } } else { @@ -1298,7 +1342,10 @@ void MainWidget::onSendBackItemClicked() QPushButton* button = qobject_cast(sender()); int itemIndex = button->property("backBoardTest").toInt(); for (ClientHandler* handler : clients) { - handler->sendBackItem(itemIndex); + if (handler->getClientId() == handler->controlClientId) { + handler->sendBackItem(itemIndex); + break; + } } } else { @@ -1309,9 +1356,11 @@ void MainWidget::onSendBackItemClicked() // 处理状态更新信号 void MainWidget::onStatusUpdated(const QString& client, int itemIndex, int FuncItemIndex, - bool success, const QString& itemData, const QString& funcItemData) + bool success, const QString& itemData, const QString& funcItemData, + const QJsonArray& jsonArray, int itemJsonIndex) { int clientId = -1; + QString label; // 遍历所有的 ClientHandler,找到匹配的 client for (ClientHandler* handler : clients) { if (handler->getClientAddress() == client) { @@ -1327,26 +1376,44 @@ void MainWidget::onStatusUpdated(const QString& client, int itemIndex, int FuncI } //qDebug() << "itemIndex :" << itemIndex; //qDebug() << "FuncItemIndex:" << FuncItemIndex; - if (itemIndex > 0) { - QListWidgetItem* listItem = new QListWidgetItem(QString("device ID: %1 - Item %2: %3 ---> %4") - .arg(clientId) - .arg(itemIndex) - .arg(itemData) // data 字段 - .arg(success ? "OK" : "NG"), statusListWidget); + //if (itemIndex > 0) { + // QListWidgetItem* listItem = new QListWidgetItem(QString("device ID: %1 - Item %2: %3 ---> %4") + // .arg(clientId) + // .arg(itemIndex) + // .arg(itemData) // data 字段 + // .arg(success ? "OK" : "NG"), statusListWidget); - listItem->setBackground(success ? Qt::green : Qt::red); - statusListWidget->addItem(listItem); - } - else if (FuncItemIndex > 0) { - QListWidgetItem* listItem = new QListWidgetItem(QString("device ID: %1 - funcItem %2: %3 ---> %4") - .arg(clientId) - .arg(FuncItemIndex) - .arg(funcItemData) // data 字段 - .arg(success ? "OK" : "NG"), statusListWidget); + // listItem->setBackground(success ? Qt::green : Qt::red); + // statusListWidget->addItem(listItem); + //} + //else if (FuncItemIndex > 0) { + // QListWidgetItem* listItem = new QListWidgetItem(QString("device ID: %1 - funcItem %2: %3 ---> %4") + // .arg(clientId) + // .arg(FuncItemIndex) + // .arg(funcItemData) // data 字段 + // .arg(success ? "OK" : "NG"), statusListWidget); - listItem->setBackground(success ? Qt::green : Qt::red); - statusListWidget->addItem(listItem); + // listItem->setBackground(success ? Qt::green : Qt::red); + // statusListWidget->addItem(listItem); + //} + + + qDebug() << "itemJsonIndex :" << itemJsonIndex; + if (itemJsonIndex >= 0 && itemJsonIndex < jsonArray.size()) { + QJsonObject jsonObject = jsonArray.at(itemJsonIndex).toObject(); + if (jsonObject.contains("lable")) { + label = jsonObject["lable"].toString(); + qDebug() << "label :" << label; + } } + QListWidgetItem* listItem = new QListWidgetItem(QString("device ID: %1 - Item %2: %3 ---> %4") + .arg(clientId) + .arg(itemJsonIndex + 1) + .arg(label) // data 字段 + .arg(success ? "OK" : "NG"), statusListWidget); + listItem->setBackground(success ? Qt::green : Qt::red); + statusListWidget->addItem(listItem); + statusListWidget->scrollToBottom(); } @@ -1373,6 +1440,8 @@ void MainWidget::onAllItemsProcessed(const QString& client, int itemsProcessedCo QListWidgetItem* listItem = new QListWidgetItem(QString("device ID:-%1 ---> All %2 items test completed !!!") .arg(clientId) .arg(itemsProcessedCount), statusListWidget); + if(checkBoxState) + saveStatusListToFile(filePathLineEdit->text()); statusListWidget->addItem(listItem); statusListWidget->scrollToBottom(); } diff --git a/FactoryTestTool/SourceCode/Widget/MainWidget.h b/FactoryTestTool/SourceCode/Widget/MainWidget.h index 87dd8db..970bf71 100644 --- a/FactoryTestTool/SourceCode/Widget/MainWidget.h +++ b/FactoryTestTool/SourceCode/Widget/MainWidget.h @@ -53,10 +53,11 @@ #include "../Network/httpClient.h" #include "FocusWindow.h" -// 用于测试 UDP 组播实现 mdns 功能 非标准 mdns -#define TEST_UDP_BROADCAST 0 -#define TCP_CONNECT_PORT 12412 +#define TEST_UDP_BROADCAST 0 // 用于测试 UDP 组播实现 mdns 功能 非标准 mdns +#define MANUAL_UPLOAD_LICENSE 0 // 打开手动上传 License的功能 + +#define TCP_CONNECT_PORT 12412 // TCP监听的端口 class MainWidget : public QWidget { @@ -96,7 +97,8 @@ private slots: //void onDataReceived(const QString& client, const QByteArray& data); // 处理状态更新信号 void onStatusUpdated(const QString& client, int itemIndex, int funcItemIndex, - bool success, const QString& itemData, const QString& funcItemData); + bool success, const QString& itemData, const QString& funcItemData, + const QJsonArray& jsonArray, int itemJsonIndex); // 处理所有项目处理完毕信号 void onAllItemsProcessed(const QString& client, int itemsProcessedCount); // 处理客户端断开连接 @@ -179,6 +181,7 @@ private: bool manualSend; // 判断是否是手动触发的发送 bool deviceConnected = false; // 判断是否有设备连接过 bool isSendingAll; // 一键功能测试 状态 + bool checkBoxState = true; QJsonObject licenseDataArray; // 用于保存从服务器获取的 data 字段对象 diff --git a/FactoryTestTool/SourceCode/Widget/UI_Widget/UI_Widget.cpp b/FactoryTestTool/SourceCode/Widget/UI_Widget/UI_Widget.cpp index 091c401..87f72a5 100644 --- a/FactoryTestTool/SourceCode/Widget/UI_Widget/UI_Widget.cpp +++ b/FactoryTestTool/SourceCode/Widget/UI_Widget/UI_Widget.cpp @@ -16,7 +16,7 @@ QGroupBox* MainWidget::createLicenseGroupBox() //licenseHwInfoEdit->setReadOnly(true); licenseHwInfoEdit->setReadOnly(false); - licenseHwInfoEdit->setPlaceholderText("1. 点击“get_hw_info”可以获取hw info并显示在此处\n2. 可将hw info输入此处, 点击“get_license”获取License并显示在此处\n3. 点击“write_license”可将License直接写入前板"); + licenseHwInfoEdit->setPlaceholderText("1. 点击“get_hw_info”可以获取hw info并显示在此处\n2. 可将hw info输入此处, 点击“get_license”获取License并显示在此处\n3. 点击“write_license”可将License写入前板"); licenseHwInfoEdit->setFixedHeight(80); QVBoxLayout* groupBoxLayout_license = new QVBoxLayout; @@ -81,8 +81,9 @@ QGroupBox* MainWidget::createBackConnectServerGroupBox() connect(button, &QPushButton::clicked, this, &MainWidget::onUuidButtonClicked); } - UuidHwInfoEdit->setReadOnly(true); - UuidHwInfoEdit->setPlaceholderText("1. 点击“获取后板MAC地址”会将后板MAC地址显示在此处\n2. 可将后板MAC地址输入到此处,点击“获取UUID”显示在此处\n"); + //UuidHwInfoEdit->setReadOnly(true); + UuidHwInfoEdit->setReadOnly(false); + UuidHwInfoEdit->setPlaceholderText("1. 点击“get_MAC_addr”从后板获取MAC地址显示在此处\n2. 可将后板MAC地址输入到此处,点击“get_UUID_SN”获取UUID和SN并显示在此处\n3. 点击“write_UUID_SN”可将UUID和SN写入前板"); UuidHwInfoEdit->setFixedHeight(80); QVBoxLayout* groupBoxLayout_uuid = new QVBoxLayout; @@ -243,14 +244,13 @@ QWidget* MainWidget::createVideoDisplayTab() { QWidget* videoDisplayTab = new QWidget(this); QVBoxLayout* videoDisplayLayout = new QVBoxLayout(videoDisplayTab); - QVBoxLayout* videoButtonsColumnLayout = new QVBoxLayout; for (int i = 0; i < 6; ++i) { QHBoxLayout* videoButtonsRowLayout = new QHBoxLayout; for (int j = 0; j < 2; ++j) { QPushButton* button; if (i == 0 && j == 0) { - button = new QPushButton(QString("IR"), this); + button = new QPushButton(QString("左边镜头"), this); button->setFixedSize(73, 50); videoButtonsRowLayout->addWidget(button); button->setProperty("getVideoIndex", i * 2 + j); @@ -259,7 +259,7 @@ QWidget* MainWidget::createVideoDisplayTab() continue; } else if (i == 0 && j == 1) { - button = new QPushButton(QString("RGB"), this); + button = new QPushButton(QString("右边镜头"), this); button->setFixedSize(73, 50); videoButtonsRowLayout->addWidget(button); button->setProperty("getVideoIndex", i * 2 + j); @@ -279,8 +279,15 @@ QWidget* MainWidget::createVideoDisplayTab() getVideoButtons.append(button); break; // 跳出内层循环,只添加一个按键 } - - button = new QPushButton(QString("Device %1").arg(i * 2 + j - 3), this); + if (i >= 2 && i <= 5) { + if(j == 0) + button = new QPushButton(QString("Device %1\n打开视频").arg(i - 1), this); + else if(j == 1) + button = new QPushButton(QString("Device %1\n关闭视频").arg(i - 1), this); + } + else { + button = new QPushButton(QString("Device %1").arg(i * 2 + (j * 1 - 1) - 3), this); + } button->setFixedSize(73, 50); videoButtonsRowLayout->addWidget(button); button->setProperty("getVideoIndex", i * 2 + j + 1); @@ -292,6 +299,7 @@ QWidget* MainWidget::createVideoDisplayTab() QHBoxLayout* videoAndButtonsLayout = new QHBoxLayout; videoLabel = new QLabel(this); + videoLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); videoAndButtonsLayout->addLayout(videoButtonsColumnLayout, 1); videoAndButtonsLayout->addWidget(videoLabel, 6); videoDisplayLayout->addLayout(videoAndButtonsLayout); diff --git a/FactoryTestTool/TestLog/20240828_185905.txt b/FactoryTestTool/TestLog/20240828_185905.txt new file mode 100644 index 0000000..b6fe3a1 --- /dev/null +++ b/FactoryTestTool/TestLog/20240828_185905.txt @@ -0,0 +1,12 @@ +device ID: 1 - Item 1: Ƕע ---> NG +device ID: 1 - Item 2: Ƕע ---> NG +device ID: 1 - Item 3: ƾע ---> NG +device ID: 1 - Item 4: ʶ ---> NG +device ID: 1 - Item 5: ƾʶ ---> NG +device ID: 1 - Item 6: ɾû ---> NG +device ID: 1 - Item 7: ɾû ---> NG +device ID: 1 - Item 8: ȡû ---> NG +device ID: 1 - Item 9: ȡû ---> NG +device ID: 1 - Item 10: ע ---> NG +device ID: 1 - Item 11: ͼƬע ---> NG +device ID:-1 ---> All 25 items test completed !!! diff --git a/FactoryTestTool/TestLog/20240828_190217.txt b/FactoryTestTool/TestLog/20240828_190217.txt new file mode 100644 index 0000000..cc4c5dc --- /dev/null +++ b/FactoryTestTool/TestLog/20240828_190217.txt @@ -0,0 +1,24 @@ +device ID: 1 - Item 1: Ƕע ---> NG +device ID: 1 - Item 2: Ƕע ---> NG +device ID: 1 - Item 3: ƾע ---> NG +device ID: 1 - Item 4: ʶ ---> NG +device ID: 1 - Item 5: ƾʶ ---> NG +device ID: 1 - Item 6: ɾû ---> NG +device ID: 1 - Item 7: ɾû ---> NG +device ID: 1 - Item 8: ȡû ---> NG +device ID: 1 - Item 9: ȡû ---> NG +device ID: 1 - Item 10: ע ---> NG +device ID: 1 - Item 11: ͼƬע ---> NG +device ID:-1 ---> All 25 items test completed !!! +device ID: 1 - Item 1: Ƕע ---> NG +device ID: 1 - Item 2: Ƕע ---> NG +device ID: 1 - Item 3: ƾע ---> NG +device ID: 1 - Item 4: ʶ ---> NG +device ID: 1 - Item 5: ƾʶ ---> NG +device ID: 1 - Item 6: ɾû ---> NG +device ID: 1 - Item 7: ɾû ---> NG +device ID: 1 - Item 8: ȡû ---> NG +device ID: 1 - Item 9: ȡû ---> NG +device ID: 1 - Item 10: ע ---> NG +device ID: 1 - Item 11: ͼƬע ---> NG +device ID:-1 ---> All 25 items test completed !!! diff --git a/FactoryTestTool/add1.h264 b/FactoryTestTool/add1.h264 index 7774d65..231a279 100644 Binary files a/FactoryTestTool/add1.h264 and b/FactoryTestTool/add1.h264 differ diff --git a/enc_temp_folder/607132b251dbd6363a3d2dcafd72eaa6/MainWidget.h b/enc_temp_folder/607132b251dbd6363a3d2dcafd72eaa6/MainWidget.h deleted file mode 100644 index 3a4eb8e..0000000 --- a/enc_temp_folder/607132b251dbd6363a3d2dcafd72eaa6/MainWidget.h +++ /dev/null @@ -1,231 +0,0 @@ -// MainWidget.h -#pragma once -#ifndef MAINWIDGET_H -#define MAINWIDGET_H - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "../Json/readJsonFile.h" -#include "../RecvDataHandler/RecvDataHandler.h" -#include "../LicenseGenerate/LicenseGenerate.h" -#include "../LicenseGenerate/LicenseConfirmWindow.h" -#include "../Network/mdns/servicemodel.h" -#include "../Network/ClientHandler.h" -#include "../Network/httpClient.h" -#include "FocusWindow.h" - -// 用于测试 UDP 组播实现 mdns 功能 非标准 mdns -#define TEST_UDP_BROADCAST 0 - -#define TCP_CONNECT_PORT 12412 - -class MainWidget : public QWidget -{ - Q_OBJECT - -public: - // 构造函数 - explicit MainWidget(QWidget* parent = nullptr); - ~MainWidget(); - -private slots: - // 发送HTTP请求 - //void onSomeButtonClicked(); - // 处理HTTP响应 - void onHttpRequestFinished(const QJsonObject& response); - // 处理HTTP错误 - void onHttpRequestError(const QString& errorString); - // 处理开始服务器按钮点击事件 - void onStartServerClicked(); - // 处理发送获取设备信息按键点击事件 - void onSendGetDevInfoClicked(); - // 处理发送取图按键点击事件 - void onSendGetPicClicked(); - // 处理发送拉视频流按键点击事件 - void onSendGetVideoClicked(); - void onLicenseButtonClicked(); - void onUuidButtonClicked(); - // 处理一键发送按钮点击事件 - void onSendAllClicked(); - // 处理单独发送项按钮点击事件 - void onSendFrontItemClicked(); - void onSendBackItemClicked(); - // 处理单独发送功能配置项按钮点击事件 - void onSendFrontFuncItemClicked(); - void onSendBackFuncItemClicked(); - // 处理数据接收信号 - //void onDataReceived(const QString& client, const QByteArray& data); - // 处理状态更新信号 - void onStatusUpdated(const QString& client, int itemIndex, int funcItemIndex, - bool success, const QString& itemData, const QString& funcItemData); - // 处理所有项目处理完毕信号 - void onAllItemsProcessed(const QString& client, int itemsProcessedCount); - // 处理客户端断开连接 - void onClientDisconnected(ClientHandler* handler); - // 启动超时定时器 - void onStartTimeout(int clientId, int timeout); - // 为了使滚动条在最下面,不用手动鼠标下拉 - void scrollToBottom(); - // 处理点击 Save Log 按键 - void onSelectFileButtonClicked(); - // 处理点击 Clear Log 按键 - void onclearLogButtonClicked(); - // 处理复选框的状态 - void onSaveCheckBoxStateChanged(int state); - // 处理打开调焦的大窗口 - void onOpenFocusWindowClicked(); - void printThreadPoolInfo(); - void onCheckThreadStatus(); - void onCheckConnectionStatus(); - void startClientReadTimer(int clientId); - void stopClientReadTimer(int clientId); -#if TEST_UDP_BROADCAST - void sendMulticastMessage(); -#endif - -private: - // 读取 test JSON 配置文件 - void readJsonConfig(); - // 设置 UI - void setupUI(); - QGroupBox* createLicenseGroupBox(); - QGroupBox* createFrontDeviceInfoGroupBox(); - QGroupBox* createBackDeviceInfoGroupBox(); - QWidget* createFunctionTestTab(const QJsonArray& BoardFuncTest, const QString& propertyName); - QWidget* createFunctionConfigTab(const QJsonArray& BoardFuncConfig, const QString& propertyName); - QWidget* createImageDisplayTab(); - QWidget* createVideoDisplayTab(); - QGroupBox* createBackConnectServerGroupBox(); - // 保存日志到文件 - void saveStatusListToFile(const QString& filePath); - // 用于更新按键文本的函数 - void updateServerButtonText(); - void onDisconnectClient(int clientId); - void setupTimerForThreadPoolInfo(); - void sendDataToClient(int clientId, const QByteArray& data); - //void FactoryToolSendPostFactoryInfotoHttpServer(); - void FactoryToolSendPostTestToHttpServer(); - void FactoryToolSendPostLicenseToHttpServer(const QString& hardware_info, const QString& license_info); - void FactoryToolSendPostComfirmToHttpServer(); - void FactoryToolSendGetUuidToHttpServer(); - void FactoryToolSendGetLicenseToHttpServer(const QString& hw_info); - - QTcpServer* server; // TCP 服务器 - HttpClient* httpClient; // HTTP 服务器 - 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 JSON - QJsonArray testJsonConfig; // 功能测试区 JSON 配置 - QJsonArray funcJsonConfig; // 功能配置区 JSON 配置 - QJsonArray getDevInfoJson; // 获取设备信息 JSON 配置 - QJsonArray getPicJson; // 发送取图指令 JSON 配置 - QJsonArray getVideoJson; // 发送拉视频指令 JSON 配置 - QVBoxLayout* mainLayout; // 主布局 - QListWidget* statusListWidget; // 状态列表 - QPushButton* startServerButton; // 开始服务器按键 - QPushButton* focusWindowsButton; // 调焦窗口按键 - QPushButton* sendAllButton; // 一键发送按键 - QThreadPool threadPool; // 线程池 - QMutex mutex; // 互斥锁 - int nextClientId; // 新增的客户端编号 - int connectedClientsCount = 0; // 连接客户端的数量 - int isRequestSuccessful = 0; // GET请求是否成功 - bool manualSend; // 判断是否是手动触发的发送 - bool deviceConnected = false; // 判断是否有设备连接过 - bool isSendingAll; // 一键功能测试 状态 - - QJsonObject licenseDataArray; // 用于保存从服务器获取的 data 字段对象 - - QVector itemButtons; // 项目按键集合 - QVector funcItemButtons; // 功能配置项目按键集合 - QVector getPicButtons; // 保存两个取图的摄像头的按键的指针 - QVector getVideoButtons; // 保存拉视频设备的按键的指针 - QList clients; // 客户端处理器集合 - QMap clientTimers; // 每个客户端的定时器 - QMap devInfoLineEdits;// msg_id 和对应的 QLineEdit 的映射关系 - - QCheckBox* saveCheckBox; // 保存文件复选框 - QPushButton* selectFileButton; // Save Log 按键 - QPushButton* clearLogButton; // clear Log 按键 - QLineEdit* filePathLineEdit; // 文件路径显示 - QLabel* leftLens_imageLabel; // 左边镜头图像显示 - QLabel* rightLens_imageLabel; // 右边镜头图像显示 - QLabel* videoLabel; // 视频显示 - QLineEdit* frontFuncConfigLineEdit; // 前板功能配置编辑框 - QLineEdit* backFuncConfigLineEdit; // 后板功能配置编辑框 - QTextEdit* licenseHwInfoEdit; // 获取license的硬件信息 - QTextEdit* UuidHwInfoEdit; // Uuid的硬件信息 - MainWidget* mainWidget; - QTabWidget* tabWidget; // 标签页 - QWidget* functionTestArea; // 功能测试区 - QWidget* functionConfigArea; // 功能配置区 - - int lastClickedGetPicCamIndex; // 记录上一次点击取图的摄像头的按键索引 - int lastClickedGetPicDevIndex; // 记录上一次点击取图的设备的按键索引 - int lastClickedGetVideoCamIndex; // 记录上一次点击拉视频的摄像头的按键索引 - int lastClickedGetVideoDevIndex; // 记录上一次点击拉视频的设备的按键索引 - - - QTimer* threadStatusTimer; // 检查线程状态的定时器 - QTimer* connectionStatusCheckTimer; // 检查连接状态的定时器 - QMap clientThreads; - QMap clientReadTimers; - QMap clients_1; - - ServiceProvider* mServiceProvider; - QTimer* mdnsTimer; - void startMdnsService(); - void stopMdnsService(); -#if TEST_UDP_BROADCAST - QUdpSocket* multicastSocket; - QTimer* multicastTimer; -#endif -}; - -#endif // MAINWIDGET_H diff --git a/enc_temp_folder/a6281ae8e18e4bb4212986158077fa/MainWidget.cpp b/enc_temp_folder/a6281ae8e18e4bb4212986158077fa/MainWidget.cpp deleted file mode 100644 index b60f6f8..0000000 --- a/enc_temp_folder/a6281ae8e18e4bb4212986158077fa/MainWidget.cpp +++ /dev/null @@ -1,1383 +0,0 @@ - // MainWidget.cpp -#include "MainWidget.h" - - -void onThreadFinished(QThread* thread, ClientHandler* handler) -{ - qDebug() << "Thread finished. Deleting handler and thread."; - handler->deleteLater(); - thread->deleteLater(); -} - -// 初始化 UI 组件和服务器 -MainWidget::MainWidget(QWidget* parent) : - QWidget(parent), - nextClientId(1), - manualSend(false), - isSendingAll(false), - lastClickedGetPicCamIndex(-1), - lastClickedGetPicDevIndex(-1), - lastClickedGetVideoCamIndex(-1), - lastClickedGetVideoDevIndex(-1), - mServiceProvider(new ServiceProvider(this)), - mdnsTimer(new QTimer(this)), - httpClient(new HttpClient(this)) -#if TEST_UDP_BROADCAST - ,multicastSocket(new QUdpSocket(this)), - multicastTimer(new QTimer(this)) -#endif -{ - leftLens_imageLabel = new QLabel(this); - rightLens_imageLabel = new QLabel(this); - videoLabel = new QLabel(this); - frontFuncConfigLineEdit = new QLineEdit(this); - backFuncConfigLineEdit = new QLineEdit(this); - licenseHwInfoEdit = new QTextEdit(this); - UuidHwInfoEdit = new QTextEdit(this); - - setupUI(); - // 打印线程池状态信息 - setupTimerForThreadPoolInfo(); - server = new QTcpServer(this); - - //FactoryToolSendGetUuidToHttpServer(); - //FactoryToolSendGetLicenseToHttpServer(); - //FactoryToolSendPostComfirmToHttpServer(); - //FactoryToolSendPostTestToHttpServer(); - //FactoryToolSendPostLicenseToHttpServer(); - - connect(server, &QTcpServer::newConnection, this, [this]() { - // 检查是否有挂起的连接 - while (server->hasPendingConnections()) { - QTcpSocket* socket = server->nextPendingConnection(); - int clientId = nextClientId++; - qDebug() << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"; - qDebug() << "> A client is connected. ID:" << clientId; - qDebug() << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>"; - - stopMdnsService(); - connectedClientsCount++; - updateServerButtonText(); - - QTimer* timer = new QTimer(this); - timer->setSingleShot(true); - clientTimers[clientId] = timer; - - // 连接定时器超时信号到槽函数 - connect(timer, &QTimer::timeout, this, [this, clientId]() { - //qDebug() << "Timeout occurred for client ID:" << clientId; - for (ClientHandler* handler : clients) { - if (handler->getClientId() == clientId) { - bool invoked = QMetaObject::invokeMethod(handler, "onTimeout", Qt::DirectConnection); - if (!invoked) { - qWarning() << "Failed to invoke onTimeout for client ID:" << clientId; - } - } - } - }); - - QThread* thread = new QThread(this); - ClientHandler* handler = new ClientHandler(socket, frontBoardOneClickTest, frontBoardTest, frontBoardFuncConfig, - frontBoardDevInfoJson, frontBoardLicenseJson, - backBoardOneClickTest, backBoardTest, backBoardFuncConfig, backBoardDevInfoJson, - getPicJson, getVideoJson, clientId, nullptr); - - // 将 ClientHandler 移动到线程池中的线程 - handler->moveToThread(thread); - - // 当线程结束时删除 handler - connect(thread, &QThread::finished, this, [=]() { - onThreadFinished(thread, handler); - }); - - // 将sendData信号连接到主线程中的槽上 - connect(handler, &ClientHandler::sendData, this, [socket](const QByteArray& data) { - /*socket->write(data); - socket->flush();*/ - //qDebug() << "---------------------data.size():" << data.size(); - QByteArray prefix; - QDataStream stream(&prefix, QIODevice::WriteOnly); - stream.setByteOrder(QDataStream::LittleEndian); - stream << quint32(0x55AA55AA); - stream << quint16(0x0420); - stream << quint32(data.size()); - prefix.append(data); - - qDebug() << "Sending data:" << prefix.toHex(); - - socket->write(prefix); - socket->flush(); - }); - - connect(handler, &ClientHandler::startTimeout, this, [this, clientId](int timeout) { - this->onStartTimeout(clientId, timeout); - }); - - // 启动新的线程 - thread->start(); - - clients.append(handler); - clients_1[clientId] = handler; - clientThreads[clientId] = thread; - connect(handler, &ClientHandler::statusUpdated, this, &MainWidget::onStatusUpdated); - connect(handler, &ClientHandler::clientDisconnected, this, &MainWidget::onClientDisconnected); - connect(handler, &ClientHandler::allItemsProcessed, this, &MainWidget::onAllItemsProcessed); - connect(handler, &ClientHandler::selectClientDisconnected, this, &MainWidget::onDisconnectClient); - - // 创建 DataHandler 对象并连接信号 - DataHandler* dataHandler = new DataHandler(leftLens_imageLabel, rightLens_imageLabel, videoLabel, licenseHwInfoEdit, &devInfoLineEdits, this); - connect(handler, &ClientHandler::dataReceived, dataHandler, &DataHandler::handleData); - connect(dataHandler, &DataHandler::statusUpdated, this, &MainWidget::onStatusUpdated); - - connect(handler, &ClientHandler::startReadTimer, this, &MainWidget::startClientReadTimer); - connect(handler, &ClientHandler::stopReadTimer, this, &MainWidget::stopClientReadTimer); - - // 创建和管理定时器 - QTimer* readTimer = new QTimer(this); - connect(readTimer, &QTimer::timeout, handler, &ClientHandler::onTimeoutRead); - // readTimer->start(10); // 每 10ms 触发一次 - // 将定时器存储到哈希表中,方便管理 - clientReadTimers[clientId] = readTimer; - - connect(handler, &ClientHandler::sendDataToSomeClient, this, &MainWidget::sendDataToClient); - } - }); - - connect(httpClient, &HttpClient::requestFinished, this, &MainWidget::onHttpRequestFinished); - connect(httpClient, &HttpClient::requestError, this, &MainWidget::onHttpRequestError); - - threadStatusTimer = new QTimer(this); - connect(threadStatusTimer, &QTimer::timeout, this, &MainWidget::onCheckThreadStatus); - //threadStatusTimer->start(100); // 每100ms检查一次线程状态 - - connectionStatusCheckTimer = new QTimer(this); - connect(connectionStatusCheckTimer, &QTimer::timeout, this, &MainWidget::onCheckConnectionStatus); - //connectionStatusCheckTimer->start(100); // 每100ms检查一次连接状态 - - connect(mdnsTimer, &QTimer::timeout, this, &MainWidget::startMdnsService); - -#if TEST_UDP_BROADCAST - // 设置组播地址 - QHostAddress groupAddress("224.0.0.251"); - quint16 port = 5353; - - // 绑定UDP套接字 - if (!multicastSocket->bind(QHostAddress::AnyIPv4, port, QUdpSocket::ShareAddress | QUdpSocket::ReuseAddressHint)) { - qWarning() << "Failed to bind multicast socket"; - } - - // 加入组播组 - bool joined = multicastSocket->joinMulticastGroup(groupAddress); - if (!joined) { - qWarning() << "Failed to join multicast group"; - } - - // 定期发送组播消息 - connect(multicastTimer, &QTimer::timeout, this, &MainWidget::sendMulticastMessage); - multicastTimer->start(1000); // 每秒发送一次组播消息 -#endif -} - -MainWidget::~MainWidget() -{ -#if TEST_UDP_BROADCAST - multicastTimer->stop(); - multicastSocket->leaveMulticastGroup(QHostAddress("224.0.0.251")); - multicastSocket->close(); -#endif - if (mdnsTimer->isActive()) { - mdnsTimer->stop(); - } - delete mdnsTimer; - stopMdnsService(); - for (auto timer : clientReadTimers) { - timer->stop(); - delete timer; - } - clientReadTimers.clear(); - for (ClientHandler* handler : clients) { - handler->deleteLater(); - } - server->close(); - - for (auto thread : clientThreads) { - thread->quit(); - thread->wait(); - delete thread; - } - clientThreads.clear(); - - for (auto handler : clients_1) { - handler->deleteLater(); - } - clients_1.clear(); - - for (auto timer : clientTimers) { - timer->stop(); - delete timer; - } - clientTimers.clear(); - - if (server->isListening()) { - server->close(); - } - qDebug() << "MainWidget destroyed"; -} - -// 服务器响应 -void MainWidget::onHttpRequestFinished(const QJsonObject& response) -{ - isRequestSuccessful = 0; - if (response.contains("msg") && response["msg"].toString() == "ok") { - if (response.contains("data") && response["data"].isObject()) { - licenseDataArray = response["data"].toObject(); - isRequestSuccessful = 1; - } - } - else - isRequestSuccessful = 2; -} - -void MainWidget::onHttpRequestError(const QString& errorString) -{ - qWarning() << "HTTP request failed:" << errorString; - isRequestSuccessful = 2; -} - -QString generateRandomRequestID() { - const QString possibleCharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.~"; - int length = QRandomGenerator::global()->bounded(1, 33); // 生成长度在1到32之间 - QString randomString; - for (int i = 0; i < length; ++i) { - int index = QRandomGenerator::global()->bounded(possibleCharacters.size()); - randomString.append(possibleCharacters.at(index)); - } - qDebug() << "randomString request_id:" << randomString; - return randomString; -} - -QString HmacSha256ToBase64(const QString& data, const QString& secret) { - QByteArray keyBytes = secret.toUtf8(); - QByteArray dataBytes = data.toUtf8(); - - // 使用 HMAC-SHA256 计算哈希值 - QByteArray hash = QMessageAuthenticationCode::hash(dataBytes, keyBytes, QCryptographicHash::Sha256); - qDebug() << "secret:" << secret; - qDebug() << "hash (hex):" << hash.toHex(); - qDebug() << "hash.toBase64():" << hash.toHex().toBase64(); - // 将哈希值编码为 Base64 字符串 - return hash.toHex().toBase64(); -} - -// 计算签名 -QString calculateSignature(const QMap& params, const QString& httpMethod, const QString& secret, const QString& request_id, const QString& timestamp) { - // 1. 按字典序排序参数 - QList> sortedParams; - for (auto it = params.begin(); it != params.end(); ++it) { - qDebug() << it.key() << ":" << it.value(); - sortedParams.append(qMakePair(it.key(), it.value())); - } - std::sort(sortedParams.begin(), sortedParams.end()); - qDebug() << "Sorted Params:"; - for (const auto& param : sortedParams) { - qDebug() << param.first << ":" << param.second; - } - - // 2. URL 编码参数 - QString canonicalizedQueryString; - for (auto& param : sortedParams) { - if (!canonicalizedQueryString.isEmpty()) { - canonicalizedQueryString += "&"; - } - canonicalizedQueryString += QUrl::toPercentEncoding(param.first) + "=" + QUrl::toPercentEncoding(param.second); - } - qDebug() << "URL Canonicalized Query String:" << canonicalizedQueryString; - - // 3. 构造 BaseString - //QString baseString = params["batch"] + params["label"] + params["model"] + params["request_id"] + params["timestamp"] + params["factory_id"]; - QString baseString = "240830SL100LabelSL100" + request_id + timestamp + "TEST"; - qDebug() << "baseString:" << baseString; - - // 4. 构造 stringToSign - QString stringToSign = httpMethod + "&" + baseString + "&" + canonicalizedQueryString.replace("+", "%20"); - qDebug() << "stringToSign:" << stringToSign; - // 5. 计算签名 - return HmacSha256ToBase64(stringToSign, secret); -} - -// 请求头 -void prepareRequestHeaders(QNetworkRequest& request, const QString& sign, const QString& request_id) { - request.setRawHeader("factory_id", "TEST"); - request.setRawHeader("label", "SL100Label"); - request.setRawHeader("batch", QString::number(240830).toUtf8()); - request.setRawHeader("model", "SL100"); - request.setRawHeader("timestamp", QString::number(QDateTime::currentSecsSinceEpoch()).toUtf8()); - request.setRawHeader("request_id", request_id.toUtf8()); - request.setRawHeader("sign", sign.toUtf8()); - request.setRawHeader("Content-Type", "application/json"); -} - -// GET 请求 -void sendGetRequest(HttpClient* httpClient, const QUrl& url, const QMap& params, const QString& secret) { - QString request_id = generateRandomRequestID(); - qDebug() << "request_id:" << request_id; - QUrl modifiedUrl = url; - QUrlQuery query; - for (auto it = params.begin(); it != params.end(); ++it) { - query.addQueryItem(it.key(), it.value()); - } - modifiedUrl.setQuery(query.query()); - QString sign = calculateSignature(params, "GET", secret, request_id, QString::number(QDateTime::currentSecsSinceEpoch())); - qDebug() << "sendGetRequest URL:" << modifiedUrl.toString(); - QNetworkRequest request(modifiedUrl); - prepareRequestHeaders(request, sign, request_id); - //return; - httpClient->sendGetRequest(request); -} - -// POST 请求 -void sendPostRequest(HttpClient* httpClient, const QUrl& url, const QMap& params, const QJsonObject& jsonData, const QString& secret) { - QString request_id = generateRandomRequestID(); - qDebug() << "request_id:" << request_id; - QString sign = calculateSignature(params, "POST", secret, request_id, QString::number(QDateTime::currentSecsSinceEpoch())); - qDebug() << "sendPostRequest URL:" << url.toString(); - QNetworkRequest request(url); - prepareRequestHeaders(request, sign, request_id); - QByteArray jsonDataByteArray = QJsonDocument(jsonData).toJson(); - //return; - httpClient->sendPostRequest(request, jsonDataByteArray); -} - -// GET 获取 UUID -void MainWidget::FactoryToolSendGetUuidToHttpServer() { - QUrl url("http://admin.hassecurity.cn/v1/getUuid"); - QMap params = { - {"label", "TEST_SL100_20240826"}, - {"model", "SL100"}, - {"batch", "1"}, - {"mac", "2a:61:az:a1"} - }; - - QString secret = "rCeOzwisLFLasvlt"; - sendGetRequest(httpClient, url, params, secret); -} - -// GET 查询 License -void MainWidget::FactoryToolSendGetLicenseToHttpServer(const QString& hw_info) { - QUrl url("http://admin.hassecurity.cn/v1/getAlgorithmKey"); - QMap params = { - {"id", hw_info} - }; - - QString secret = "rCeOzwisLFLasvlt"; - sendGetRequest(httpClient, url, params, secret); -} - -// POST 确认烧录 -void MainWidget::FactoryToolSendPostComfirmToHttpServer() { - QUrl url("http://admin.hassecurity.cn/v1/confirm"); - QMap params = { - {"factory_id", "TEST"}, - {"label", "SL100Label"}, - {"batch", "240830"}, - {"model", "SL100"}, - {"timestamp", QString::number(QDateTime::currentSecsSinceEpoch())}, - {"request_id", generateRandomRequestID()} - }; - - QJsonObject jsonData = { - {"mac", "value4"}, - {"uuid", "value4"} - }; - - QString secret = "rCeOzwisLFLasvlt"; - sendPostRequest(httpClient, url, params, jsonData, secret); -} - -// POST 上报测试结果 -void MainWidget::FactoryToolSendPostTestToHttpServer() { - QUrl url("http://admin.hassecurity.cn/v1/testRecords"); - QMap params = { - {"id", "123456"}, - {"location", "allMachine"} - }; - //QString itemString = "function=faceVerify,result=false,msg=timeout"; - //QString itemString = "function=faceVerify,result=false,msg=timeout"; - QString itemString = "[{\"function\":\"faceVerify\",\"msg\":\"timeout\",\"result\":false}]"; - params["items"] = itemString; - - QJsonObject jsonItem = { - {"function", "faceVerify"}, - {"result", false}, - {"msg", "timeout"} - }; - QJsonArray itemsArray; - itemsArray.append(jsonItem); - - QJsonObject jsonData = { - {"id", "123456"}, - {"location", "allMachine"}, - {"items", itemsArray} - }; - - QString secret = "rCeOzwisLFLasvlt"; - sendPostRequest(httpClient, url, params, jsonData, secret); -} - -// POST 图语 License 上报 -void MainWidget::FactoryToolSendPostLicenseToHttpServer(const QString& hardware_info, const QString& license_info) { - QUrl url("http://admin.hassecurity.cn/v1/algorithmKey"); - QString UTC_time = QString::number(QDateTime::currentSecsSinceEpoch()); - QMap params = { - {"id", hardware_info}, - {"key", license_info}, - {"time", UTC_time}, - {"type", "TUYU"} - }; - - QJsonObject jsonData = { - {"id", hardware_info}, - {"key", license_info}, - {"time", UTC_time} - }; - - QString secret = "rCeOzwisLFLasvlt"; - sendPostRequest(httpClient, url, params, jsonData, secret); -} - -void MainWidget::startClientReadTimer(int clientId) { - qDebug() << "------ startClientReadTimer clientId:" << clientId; - if (clientReadTimers.contains(clientId)) { - clientReadTimers[clientId]->start(10); - } -} - -void MainWidget::stopClientReadTimer(int clientId) { - qDebug() << "------ stopClientReadTimer clientId:" << clientId; - if (clientReadTimers.contains(clientId)) { - clientReadTimers[clientId]->stop(); - } -} - -void MainWidget::onCheckConnectionStatus() -{ - int activeThreadCount = clients_1.size(); - //qDebug() << "------Number of active threads:" << activeThreadCount; - for (auto it = clients_1.begin(); it != clients_1.end(); ++it) { - int clientId = it.key(); - ClientHandler* handler = it.value(); - QTcpSocket* socket = handler->getSocket(); - if (socket->state() != QTcpSocket::ConnectedState) { - qCritical() << "--------------Connection lost for clientId:" << clientId << ". Socket state:" << socket->state(); - emit handler->clientDisconnected(handler); - } - else { - qDebug() << "Connection for clientId:" << clientId << "is active."; - } - } -} - -void MainWidget::onCheckThreadStatus() -{ - //qDebug() << "Checking thread status..."; - int activeThreadCount = clientThreads.size(); - //qDebug() << "Number of active threads:" << activeThreadCount; - for (auto it = clientThreads.begin(); it != clientThreads.end(); ++it) { - int clientId = it.key(); - QThread* thread = it.value(); - ClientHandler* handler = nullptr; - for (ClientHandler* h : clients) { - if (h->getClientId() == clientId) { - handler = h; - break; - } - } - if (handler && handler->isData_Stuck()) { - qDebug() << "Thread for clientId:" << clientId << "is stuck."; - // 处理线程卡住的情况,比如重启线程或记录更多日志 - } - else if (thread->isRunning()) { - qDebug() << "isData_Stuck = :" << handler->isData_Stuck(); - qDebug() << "Thread for clientId:" << clientId << "is running."; - } - else { - qDebug() << "Thread for clientId:" << clientId << "is not running."; - // 处理线程意外停止的情况 - } - } -} - -// 打印线程池信息 -void MainWidget::printThreadPoolInfo() -{ - QThreadPool* threadPool = QThreadPool::globalInstance(); - //qDebug() << "Active threads:" << threadPool->activeThreadCount(); - //qDebug() << "Max threads:" << threadPool->maxThreadCount(); -} - -void MainWidget::setupTimerForThreadPoolInfo() -{ - QTimer* timer = new QTimer(this); - connect(timer, &QTimer::timeout, this, &MainWidget::printThreadPoolInfo); - timer->start(5000); // 每5秒打印一次线程池信息 -} - -void MainWidget::readJsonConfig() -{ - frontBoardOneClickTest = readJson_frontBoardOneClickTest(); - frontBoardTest = readJson_frontBoardTest(); - frontBoardFuncConfig = readJson_frontBoardFuncConfig(); - frontBoardDevInfoJson = readJson_frontDevInfo(); - frontBoardLicenseJson = readJson_frontLicense(); - - backBoardOneClickTest = readJson_backBoardOneClickTest(); - backBoardTest = readJson_backBoardTest(); - backBoardFuncConfig = readJson_backBoardFuncConfig(); - backBoardDevInfoJson = readJson_backDevInfo(); - backBoardUuidJson = readJson_backUuid(); - - testJsonConfig = readJson_testConfig(); - funcJsonConfig = readJson_funcConfig(); - - getPicJson = readJson_getPic(); - getVideoJson = readJson_getVideo(); -} - -// 设置 UI -void MainWidget::setupUI() -{ - startServerButton = new QPushButton("开始监听\n(Start Listening...)", this); - startServerButton->setFixedSize(190, 70); - - sendAllButton = new QPushButton("一键功能测试", this); - sendAllButton->setFixedSize(190, 70); - sendAllButton->setEnabled(false); - - statusListWidget = new QListWidget(this); - statusListWidget->setMinimumSize(350, 840); - statusListWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - - QHBoxLayout* buttonLayout = new QHBoxLayout; - buttonLayout->addWidget(startServerButton); - buttonLayout->addWidget(sendAllButton); - buttonLayout->addStretch(); - - QVBoxLayout* leftLayout = new QVBoxLayout; - leftLayout->addLayout(buttonLayout); - leftLayout->setStretch(0, 1); - leftLayout->addWidget(statusListWidget); - leftLayout->setStretch(1, 200); - - saveCheckBox = new QCheckBox("", this); - selectFileButton = new QPushButton("Save", this); - selectFileButton->setFixedSize(45, 28); - clearLogButton = new QPushButton("Clear", this); - clearLogButton->setFixedSize(55, 28); - filePathLineEdit = new QLineEdit(this); - filePathLineEdit->setFixedSize(250, 28); - filePathLineEdit->setReadOnly(true); - - QHBoxLayout* fileLayout = new QHBoxLayout; - fileLayout->addWidget(saveCheckBox); - fileLayout->addWidget(selectFileButton); - fileLayout->addWidget(filePathLineEdit); - fileLayout->addWidget(clearLogButton); - - leftLayout->addLayout(fileLayout); - leftLayout->setStretch(2, 1); - - // 读取 JSON 配置文件 - readJsonConfig(); - - /*QGroupBox* groupBox = createLicenseGroupBox(); - leftLayout->addWidget(groupBox); - leftLayout->setStretch(3, 1);*/ - - QWidget* leftContainer = new QWidget(this); - leftContainer->setLayout(leftLayout); - leftContainer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - - // 前板 - QGroupBox* frontDeviceInfoGroupBox = createFrontDeviceInfoGroupBox(); - QGroupBox* frontLicenseGroupBox = createLicenseGroupBox(); - - QHBoxLayout* frontGroupBoxLayout = new QHBoxLayout; - frontGroupBoxLayout->addWidget(frontDeviceInfoGroupBox, 1); - frontGroupBoxLayout->addWidget(frontLicenseGroupBox, 1); - - QTabWidget* frontTabWidget = new QTabWidget(this); - frontTabWidget->setFixedSize(900, 315); - QWidget* frontFunctionTestTab = createFunctionTestTab(frontBoardTest, "frontBoardTest"); - QWidget* frontFunctionConfigTab = createFunctionConfigTab(frontBoardFuncConfig, "frontBoardFuncConfig"); - frontTabWidget->addTab(frontFunctionTestTab, "前板测试项"); - frontTabWidget->addTab(frontFunctionConfigTab, "前板配置项"); - - QTabWidget* mainTabWidget = new QTabWidget(this); - QWidget* frontDevAreaTab = new QWidget(this); - QVBoxLayout* frontDevLayout = new QVBoxLayout(frontDevAreaTab); - frontDevLayout->addLayout(frontGroupBoxLayout); - frontDevLayout->addWidget(frontTabWidget, 2, Qt::AlignTop | Qt::AlignLeft); - mainTabWidget->addTab(frontDevAreaTab, "前 板"); - - // 后板 - QGroupBox* backDeviceInfoGroupBox1 = createBackDeviceInfoGroupBox(); - QGroupBox* BackConnectServerGroupBox = createBackConnectServerGroupBox(); - - QHBoxLayout* backGroupBoxLayout = new QHBoxLayout; - backGroupBoxLayout->addWidget(backDeviceInfoGroupBox1, 1); - backGroupBoxLayout->addWidget(BackConnectServerGroupBox, 1); - - QTabWidget* backTabWidget = new QTabWidget(this); - backTabWidget->setFixedSize(900, 315); - QWidget* backFunctionTestTab = createFunctionTestTab(backBoardTest, "backBoardTest"); - QWidget* backFunctionConfigTab = createFunctionConfigTab(backBoardFuncConfig, "backBoardFuncConfig"); - backTabWidget->addTab(backFunctionTestTab, "后板测试项"); - backTabWidget->addTab(backFunctionConfigTab, "后板配置项"); - - QWidget* backDevAreaTab = new QWidget(this); - QVBoxLayout* backDevLayout = new QVBoxLayout(backDevAreaTab); - backDevLayout->addLayout(backGroupBoxLayout); - backDevLayout->addWidget(backTabWidget, 2, Qt::AlignTop | Qt::AlignLeft); - mainTabWidget->addTab(backDevAreaTab, "后 板"); - - // 整机 - QWidget* allDevAreaTab = new QWidget(this); - QVBoxLayout* allDevLayout = new QVBoxLayout(allDevAreaTab); - mainTabWidget->addTab(allDevAreaTab, "整 机"); - - QTabWidget* tabWidget_media = new QTabWidget(this); - QWidget* imageDisplayTab = createImageDisplayTab(); - QWidget* videoDisplayTab = createVideoDisplayTab(); - tabWidget_media->addTab(imageDisplayTab, "图像显示区"); - tabWidget_media->addTab(videoDisplayTab, "视频显示区"); - - QVBoxLayout* rightVerticalLayout = new QVBoxLayout; - rightVerticalLayout->addWidget(mainTabWidget, 5); - rightVerticalLayout->addWidget(tabWidget_media, 4); - - QHBoxLayout* mainLayout = new QHBoxLayout; - mainLayout->addWidget(leftContainer, 1, Qt::AlignTop | Qt::AlignLeft); - mainLayout->addLayout(rightVerticalLayout, 3); - - setLayout(mainLayout); - setWindowTitle("SL100 工厂产测工具 - V0.0.1"); - resize(1340, 1000); - - connect(startServerButton, &QPushButton::clicked, this, &MainWidget::onStartServerClicked); - connect(sendAllButton, &QPushButton::clicked, this, &MainWidget::onSendAllClicked); - connect(statusListWidget, &QListWidget::itemChanged, this, &MainWidget::scrollToBottom); - connect(selectFileButton, &QPushButton::clicked, this, &MainWidget::onSelectFileButtonClicked); - connect(clearLogButton, &QPushButton::clicked, this, &MainWidget::onclearLogButtonClicked); - connect(saveCheckBox, &QCheckBox::stateChanged, this, &MainWidget::onSaveCheckBoxStateChanged); -} - -void MainWidget::onSelectFileButtonClicked() -{ - QString filePath = QFileDialog::getSaveFileName(this, tr("选择文件路径"), "", tr("Text Files (*.txt);;All Files (*)")); - if (!filePath.isEmpty()) { - filePathLineEdit->setText(filePath); - } -} - -void MainWidget::onclearLogButtonClicked() -{ - statusListWidget->clear(); -} - -void MainWidget::onSaveCheckBoxStateChanged(int state) -{ - if (state == Qt::Checked) { - saveStatusListToFile(filePathLineEdit->text()); - } -} - -void MainWidget::saveStatusListToFile(const QString& filePath) -{ - if (filePath.isEmpty()) { - return; - } - - QFile file(filePath); - if (!file.open(QIODevice::WriteOnly | QIODevice::Text)) { - return; - } - - QTextStream out(&file); - for (int i = 0; i < statusListWidget->count(); ++i) { - QListWidgetItem* item = statusListWidget->item(i); - out << item->text() << "\n"; - } - file.close(); -} - -void MainWidget::onStartTimeout(int clientId, int timeout) -{ - //qDebug() << "---------------> onStartTimeout :" << clientId << "timeout :" << timeout; - if (clientTimers.contains(clientId)) { - QTimer* timer = clientTimers[clientId]; - if (timeout > 0) { - timer->start(timeout); - } - else { - timer->stop(); - } - } -} - -void MainWidget::scrollToBottom() -{ - statusListWidget->scrollToBottom(); -} - -void MainWidget::onDisconnectClient(int clientId) -{ - for (ClientHandler* handler : clients) { - if (handler->getClientId() == clientId) { - // 断开与该客户端的连接 - handler->getSocket()->disconnectFromHost(); - handler->getSocket()->waitForDisconnected(); - clients.removeOne(handler); - if (clientTimers.contains(clientId)) { - QTimer* timer = clientTimers[clientId]; - timer->stop(); - delete timer; - clientTimers.remove(clientId); - } - handler->deleteLater(); - connectedClientsCount--; - updateServerButtonText(); - - break; - } - } - - // 启动 mDNS 服务广播 - startMdnsService(); -} - -// 处理客户端断开连接信号 -void MainWidget::onClientDisconnected(ClientHandler* handler) -{ - int clientId = handler->getClientId(); - if (clientTimers.contains(clientId)) { - QTimer* timer = clientTimers[clientId]; - timer->stop(); - delete timer; - clientTimers.remove(clientId); - } - - clients.removeOne(handler); - /* - 将 ClientHandler 对象的删除操作放入事件队列中,等待事件循环处理。 - 在事件循环执行时,会安全地删除 ClientHandler 对象,这包括释放其占用的资源和内存 - */ - handler->deleteLater(); // 延迟删除 ClientHandler 对象 - - // 更新连接数并更新按键文本 - connectedClientsCount--; - if (nextClientId <= 2) nextClientId--; - deviceConnected = true; - updateServerButtonText(); -} - -// 更新按键文本的函数 -void MainWidget::updateServerButtonText() -{ - if (deviceConnected) { - deviceConnected = false; - startServerButton->setText(tr("正在监听(Listening)")); - if (connectedClientsCount == 0) startMdnsService(); - } - else if (connectedClientsCount == 0) { - startServerButton->setText(tr("开始监听\n(Start Listening...)")); - } - else { - startServerButton->setText(tr("正在监听(Listening)\n%1 台设备连接").arg(connectedClientsCount)); - } -} - -QString formatLicenseKey(const QString& licenseKey) { - QString formattedKey; - qDebug() << "licenseKey.length():" << licenseKey.length(); - for (int i = 0; i < licenseKey.length(); i += 2) { - QString byteStr = licenseKey.mid(i, 2); // 每次取两个字符 - formattedKey.append(QString("0x%1, ").arg(byteStr)); - } - if (!formattedKey.isEmpty()) { - formattedKey.chop(2); - } - - return formattedKey; -} - -void MainWidget::onLicenseButtonClicked() -{ - if (connectedClientsCount) { - QPushButton* button = qobject_cast(sender()); - if (button) { - int index = button->property("licenseIndex").toInt(); - if (index >= 0 && index < frontBoardLicenseJson.size()) { - QJsonObject jsonObject = frontBoardLicenseJson[index].toObject(); - unsigned char hardware_info[PIX_HARDWARE_INFO_BYTES] = { 0 }; - unsigned char license_info[PIX_LICENCE_BYTES] = { 0 }; - QString dataStr = ""; - if (jsonObject["lable"].toString() == "get_license") { - QString hwInfoText = licenseHwInfoEdit->toPlainText(); - dataStr = hwInfoText.remove(","); // 去掉所有的逗号 - QString sendToHttpServerDataStr = dataStr.replace("0x", "").replace(" ", ""); // 去掉0x和空格 -#if 1 - qDebug() << "sendToHttpServerDataStr:" << sendToHttpServerDataStr; - FactoryToolSendGetLicenseToHttpServer(sendToHttpServerDataStr); - while (isRequestSuccessful == 0) { - QCoreApplication::processEvents(); // 防止阻塞UI线程 - } - qDebug() << "isRequestSuccessful:" << isRequestSuccessful; - if (isRequestSuccessful == 2) { - return; - } - else if(isRequestSuccessful == 1) { - if (licenseDataArray.contains("has") && licenseDataArray["has"].toBool()) { - qDebug() << "Found item with 'has' = true"; - if (licenseDataArray.contains("key")) { - QString licenseKey = licenseDataArray["key"].toString(); - licenseKey = formatLicenseKey(licenseKey); - licenseHwInfoEdit->setPlainText(licenseKey); - qDebug() << "HTTP Server License is:" << licenseKey; - return; - } - } - else if (licenseDataArray.contains("has")) { - qDebug() << "licenseDataArray[\"has\"].toBool():" << licenseDataArray["has"].toBool(); - } - } -#else - QString licenseKey = "128532C1D2A8"; - licenseKey = formatLicenseKey(licenseKey); - licenseHwInfoEdit->setPlainText(licenseKey); - qDebug() << "License Key set in licenseHwInfoEdit:" << licenseKey; - return; -#endif - QByteArray dataByteArray = QByteArray::fromHex(dataStr.toUtf8()); - memcpy(hardware_info, dataByteArray.data(), qMin(dataByteArray.size(), PIX_HARDWARE_INFO_BYTES)); - //unsigned char hardware_info[PIX_HARDWARE_INFO_BYTES] = { 0x46,0x0b,0x5d,0x11,0x58,0x17,0x4d,0x5e,0x55,0x5c,0x51,0x4a,0x5a,0x07,0x59,0x4c,0x5f,0x45,0x5b,0x5f,0x5a,0x45,0x1c,0x5a,0x45,0x43,0x44,0x47,0x51,0x5e,0x44,0x30 }; - LicenseConfirmWindow dialog("你确定要获取此授权吗?"); - if (dialog.exec() == QDialog::Accepted) { -#if 0 - licenseGenerate(hardware_info, license_info); - QString licenseInfoHex = QByteArray(reinterpret_cast(license_info), PIX_LICENCE_BYTES).toHex().toUpper(); -#else - unsigned char license_info_1[PIX_LICENCE_BYTES] = { 0x07, 0xe8, 0xf3, 0x80, 0xa8, 0x07, 0x72, 0xa1, 0x17, 0xfe, 0xda, 0x67, 0xbd, 0x4a, 0x5a, 0xb5, 0xbb, 0x8b, 0x2d, 0xb2, 0xbf, 0x89, 0x74, 0xe5, 0xb0, 0x99, 0x70, 0x74, 0x3c, 0x6f, 0xf8, 0x82, 0x79, 0xab, 0x31, 0x9c, 0xdf, 0xe8, 0x9e, 0x75, 0x8f, 0x42, 0xb3, 0xcf, 0x00, 0x60, 0xa0, 0x38, 0xa4, 0xb8, 0xbe, 0xa6, 0x5d, 0x9f, 0x8b, 0x41, 0xf3, 0x0a, 0x69, 0xf6, 0x50, 0x94, 0x3f, 0xd0, 0xa5, 0xee, 0x88, 0x20, 0x93, 0x9a, 0x1c, 0xe9, 0x64, 0xd3, 0xaf, 0x9f, 0xc7, 0x66, 0x00, 0x7d, 0x7d, 0x68, 0xf1, 0xa4, 0xe1, 0x58, 0x00, 0x1d, 0x03, 0x0d, 0x40, 0x08, 0xa4, 0xcc, 0x0b, 0xd8, 0x19, 0x70, 0x9a, 0x83, 0x81, 0xbf, 0x27, 0x35, 0xb8, 0xec, 0x59, 0xa8, 0xd0, 0x03, 0xdb, 0xf6, 0xcf, 0x83, 0xaa, 0x0e, 0xfc, 0x95, 0x29, 0x77, 0xec, 0x89, 0xc5, 0x79, 0x10, 0x40, 0xd8, 0xbb }; - QString licenseInfoHex = QByteArray(reinterpret_cast(license_info_1), PIX_LICENCE_BYTES).toHex().toUpper(); -#endif - qDebug() << "上报服务器 licenseInfoHex:" << licenseInfoHex; - // License上报服务器 - FactoryToolSendPostLicenseToHttpServer(sendToHttpServerDataStr, licenseInfoHex); - QString licenseInfoStr; - printf("U盘 Get License is\n"); - for (int j = 0; j < PIX_LICENCE_BYTES; ++j) { - //printf("0x%02x, ", license_info[j]); - //licenseInfoStr.append(QString::asprintf("0x%02x, ", license_info[j])); - printf("0x%02x, ", license_info_1[j]); - licenseInfoStr.append(QString::asprintf("0x%02x, ", license_info_1[j])); - } - printf("\n"); - licenseHwInfoEdit->setPlainText(licenseInfoStr); - } - } - else { -#if 0 - if (jsonObject["lable"].toString() == "write_license") { - QString hwInfoText = licenseHwInfoEdit->toPlainText(); - dataStr = hwInfoText.remove(","); // 去掉所有的逗号 - QByteArray dataByteArray = QByteArray::fromHex(dataStr.toUtf8()); - memcpy(hardware_info, dataByteArray.data(), qMin(dataByteArray.size(), PIX_HARDWARE_INFO_BYTES)); - qDebug() << "hardware_info:" << QByteArray(reinterpret_cast(hardware_info), PIX_HARDWARE_INFO_BYTES).toHex(); - licenseGenerate(hardware_info, license_info); - QString licenseInfoStr; - printf("License is\n"); - for (int j = 0; j < PIX_LICENCE_BYTES; ++j) { - printf("0x%02x, ", license_info[j]); - licenseInfoStr.append(QString::asprintf("0x%02x, ", license_info[j])); - } - printf("\n"); - licenseHwInfoEdit->setPlainText(licenseInfoStr); - dataStr = QByteArray(reinterpret_cast(license_info), PIX_LICENCE_BYTES).toHex(); - qDebug() << "license_info:" << dataStr; - } -#else - if (jsonObject["lable"].toString() == "write_license") { - QString licenseInfoText = licenseHwInfoEdit->toPlainText(); - qDebug() << "licenseInfoText:" << licenseInfoText; - dataStr = licenseInfoText.remove(","); // 去掉所有的逗号 - dataStr = dataStr.replace("0x", "").replace(" ", ""); // 去掉0x和空格 - QByteArray dataByteArray = QByteArray::fromHex(dataStr.toUtf8()); - memcpy(license_info, dataByteArray.data(), qMin(dataByteArray.size(), PIX_LICENCE_BYTES)); - //qDebug() << "hardware_info:" << QByteArray(reinterpret_cast(hardware_info), PIX_HARDWARE_INFO_BYTES).toHex(); - //licenseGenerate(hardware_info, license_info); - QString licenseInfoStr; - for (int j = 0; j < PIX_LICENCE_BYTES; ++j) { - licenseInfoStr.append(QString::asprintf("0x%02x, ", license_info[j])); - } - //printf("\n"); - dataStr = QByteArray(reinterpret_cast(license_info), PIX_LICENCE_BYTES).toHex(); - qDebug() << "license_info:" << dataStr; - } -#endif - for (ClientHandler* handler : clients) { - handler->sendLicenseItem(index, dataStr); - } - } - } - } - } - else { - QListWidgetItem* listItem = new QListWidgetItem(QString("No device is connected !!!"), statusListWidget); - listItem->setBackground(Qt::red); - } -} - -//void MainWidget::onLicenseButtonClicked() -//{ -// if (connectedClientsCount) { -// QPushButton* button = qobject_cast(sender()); -// if (button) { -// int index = button->property("licenseIndex").toInt(); -// if (index >= 0 && index < frontBoardLicenseJson.size()) { -// QJsonObject jsonObject = frontBoardLicenseJson[index].toObject(); -// //QString jsonString = QJsonDocument(jsonObject).toJson(QJsonDocument::Compact); -// //qDebug() << "license Button clicked, sending JSON:" << jsonString; -// unsigned char license_info[PIX_LICENCE_BYTES] = { 0 }; -// if (jsonObject["lable"].toString() == "get_license") { -// LicenseConfirmWindow dialog("你确定要获取此授权吗?"); -// if (dialog.exec() == QDialog::Accepted) -// licenseGenerate(license_info, license_info); -// } -// else { -// if (jsonObject["lable"].toString() == "write_license") { -// LicenseConfirmWindow dialog("你确定要发送此授权吗?"); -// if (dialog.exec() == QDialog::Accepted) -// licenseGenerate(license_info, license_info); -// } -// for (ClientHandler* handler : clients) { -// handler->sendLicenseItem(index); -// } -// } -// } -// } -// } -// else { -// QListWidgetItem* listItem = new QListWidgetItem(QString("No device is connected !!!"), statusListWidget); -// listItem->setBackground(Qt::red); -// } -//} - -void MainWidget::onUuidButtonClicked() -{ - if (connectedClientsCount) { - QPushButton* button = qobject_cast(sender()); - if (button) { - int index = button->property("UuidIndex").toInt(); - if (index >= 0 && index < backBoardUuidJson.size()) { - QJsonObject jsonObject = backBoardUuidJson[index].toObject(); - //QString jsonString = QJsonDocument(jsonObject).toJson(QJsonDocument::Compact); - //qDebug() << "license Button clicked, sending JSON:" << jsonString; - unsigned char license_info[PIX_LICENCE_BYTES] = { 0 }; - if (jsonObject["lable"].toString() == "get_license") { - - } - else { - if (jsonObject["lable"].toString() == "write_license") { - LicenseConfirmWindow dialog("你确定要发送此授权吗?"); - if (dialog.exec() == QDialog::Accepted) - licenseGenerate(license_info, license_info); - } - for (ClientHandler* handler : clients) { - handler->sendUuidItem(index, ""); - } - } - } - } - } - else { - QListWidgetItem* listItem = new QListWidgetItem(QString("No device is connected !!!"), statusListWidget); - listItem->setBackground(Qt::red); - } -} - -void MainWidget::startMdnsService() -{ - QDateTime currentTime = QDateTime::currentDateTime(); - QString formattedTime = currentTime.toString("yyyy-MM-dd hh:mm:ss.zzz"); - qDebug() << "[" << formattedTime << "]:" << "Start Mdns Broadcast Service"; - QString serviceName = "SL100 FactoryTool Mdns Broadcast Service"; - QString serviceType = "_SL100_FactoryTool-service._tcp"; - quint16 port = TCP_CONNECT_PORT; - mServiceProvider->startServiceBroadcast(serviceName, serviceType, port); - - if (!mdnsTimer->isActive()) { - mdnsTimer->start(1000); - } -} - -void MainWidget::stopMdnsService() -{ - if (mdnsTimer->isActive()) { - mdnsTimer->stop(); // 停止定时器 - } - mServiceProvider->stopServiceBroadcast(); -} - -#if TEST_UDP_BROADCAST -void MainWidget::sendMulticastMessage() -{ - QByteArray datagram = "--------------------------------- Test multicast message from MainWidget"; - QHostAddress groupAddress("224.0.0.251"); - quint16 port = 5353; - - qint64 sentBytes = multicastSocket->writeDatagram(datagram, groupAddress, port); - if (sentBytes == -1) { - qWarning() << "Failed to send multicast message:" << multicastSocket->errorString(); - } - else { - qDebug() << "Multicast message sentBytes:" << sentBytes; - qDebug() << "Multicast message sent:" << datagram; - } -} -#endif - -// 处理开始服务器按键点击事件 -void MainWidget::onStartServerClicked() -{ - if (!server->isListening()) { - startMdnsService(); -#if TEST_UDP_BROADCAST - sendMulticastMessage(); -#endif - // QHostAddress specifiedIpAddress("10.10.10.253"); - quint16 specifiedPort = TCP_CONNECT_PORT; - qDebug() << "" << specifiedPort; - if (server->listen(QHostAddress::Any, specifiedPort)) { - startServerButton->setText(tr("正在监听(Listening)")); - startServerButton->setStyleSheet("background-color: green;"); - sendAllButton->setEnabled(true); - } - else { - qDebug() << "Failed to start server. Error:" << server->errorString(); - } - } - else { - server->close(); - startServerButton->setText(tr("开始监听\n(Start Listening...)")); - startServerButton->setStyleSheet(""); - sendAllButton->setEnabled(false); - - stopMdnsService(); - } -} - -void MainWidget::sendDataToClient(int clientId, const QByteArray& data) -{ - if (clients_1.contains(clientId)) { - ClientHandler* handler = clients_1[clientId]; - handler->sendDataToClient(data); // 调用 ClientHandler 中的方法发送数据 - } - else { - qWarning() << "没有找到 ID 为" << clientId << "的客户端!"; - } -} - -// 处理发送获取设备信息按键点击事件 -void MainWidget::onSendGetDevInfoClicked() -{ - if (connectedClientsCount) { - QPushButton* button = qobject_cast(sender()); - int itemIndex = button->property("deviceInfoIndex").toInt(); - if (itemIndex + 1 > connectedClientsCount) { - QListWidgetItem* listItem = new QListWidgetItem(QString("No device %1 is connected !!!").arg(itemIndex + 1), statusListWidget); - listItem->setBackground(Qt::red); - } - else { - for (ClientHandler* handler : clients) { - handler->sendGetDevInfoItem(itemIndex); - } - } - } - else { - QListWidgetItem* listItem = new QListWidgetItem(QString("No device is connected !!!"), statusListWidget); - listItem->setBackground(Qt::red); - } -} - -// 处理发送取图按键点击事件 -void MainWidget::onSendGetPicClicked() -{ - if (connectedClientsCount) { - QPushButton* button = qobject_cast(sender()); - int itemIndex = button->property("getPicIndex").toInt(); - - if (itemIndex < 2) { - button->setStyleSheet("background-color: green;"); - if (lastClickedGetPicCamIndex != -1 && lastClickedGetPicCamIndex != itemIndex) { - getPicButtons[lastClickedGetPicCamIndex]->setStyleSheet(""); - } - lastClickedGetPicCamIndex = itemIndex; - } - else { - if (lastClickedGetPicCamIndex == -1) { - QListWidgetItem* listItem = new QListWidgetItem(QString("Please select IR or RGB lens to get image!!!"), statusListWidget); - listItem->setBackground(Qt::red); - } - else { - if (itemIndex - 2 >= connectedClientsCount) { - QListWidgetItem* listItem = new QListWidgetItem(QString("No device %1 is connected !!!").arg(itemIndex - 1), statusListWidget); - listItem->setBackground(Qt::red); - } - else { - button->setStyleSheet("background-color: green;"); - if (lastClickedGetPicDevIndex != -1 && lastClickedGetPicDevIndex != itemIndex) { - getPicButtons[lastClickedGetPicDevIndex]->setStyleSheet(""); - } - lastClickedGetPicDevIndex = itemIndex; - //QMutexLocker locker(&mutex); - for (ClientHandler* handler : clients) { - handler->sendGetPicItem(itemIndex - 2, lastClickedGetPicCamIndex); - } - } - } - } - } - else { - QListWidgetItem* listItem = new QListWidgetItem(QString("No device is connected !!!"), statusListWidget); - listItem->setBackground(Qt::red); - } -} - -// 处理发送拉视频流按键点击事件 -void MainWidget::onSendGetVideoClicked() -{ - if (connectedClientsCount) { - QPushButton* button = qobject_cast(sender()); - int itemIndex = button->property("getVideoIndex").toInt(); - - if (itemIndex < 2) { - button->setStyleSheet("background-color: green;"); - if (lastClickedGetVideoCamIndex != -1 && lastClickedGetVideoCamIndex != itemIndex) { - getVideoButtons[lastClickedGetVideoCamIndex]->setStyleSheet(""); - } - lastClickedGetVideoCamIndex = itemIndex; - } - else { - if (lastClickedGetVideoCamIndex == -1) { - QListWidgetItem* listItem = new QListWidgetItem(QString("Please select IR or RGB lens to get video!!!"), statusListWidget); - listItem->setBackground(Qt::red); - } - else { - if (itemIndex - 6 >= connectedClientsCount) { - QListWidgetItem* listItem = new QListWidgetItem(QString("No device %1 is connected !!!").arg(itemIndex - 4), statusListWidget); - listItem->setBackground(Qt::red); - } - else { - button->setStyleSheet("background-color: green;"); - if (lastClickedGetVideoDevIndex != -1 && lastClickedGetVideoDevIndex != itemIndex) { - getVideoButtons[lastClickedGetVideoDevIndex]->setStyleSheet(""); - } - lastClickedGetVideoDevIndex = itemIndex; - //QMutexLocker locker(&mutex); - for (ClientHandler* handler : clients) { - handler->sendGetVideoItem(itemIndex - 5, 1); - } - getVideoButtons[2]->setEnabled(true); - } - } - } - } - else { - QListWidgetItem* listItem = new QListWidgetItem(QString("No device is connected !!!"), statusListWidget); - listItem->setBackground(Qt::red); - } -} - -void MainWidget::onOpenFocusWindowClicked() -{ - QPushButton* button = qobject_cast(sender()); - if (button) { - int itemIndex = button->property("getVideoIndex").toInt(); - //qDebug() << "New Button clicked with itemIndex:" << itemIndex; - if (itemIndex == 2) { - // 创建并显示新窗口 - NewButtonDialog dialog(this); - dialog.exec(); - } - } -} - -// 处理一键发送按键点击事件 -void MainWidget::onSendAllClicked() -{ - if (connectedClientsCount) { - QMutexLocker locker(&mutex); - isSendingAll = !isSendingAll; - if (isSendingAll) { - sendAllButton->setText("一键功能测试中...\n再次点击取消"); - sendAllButton->setStyleSheet("background-color: green;"); - manualSend = true; - for (ClientHandler* handler : clients) { - // 重置索引 - handler->resetCurrentItemIndex(); - handler->sendNextItem(); - //handler->sendDevInfoItem(); - } - } - else { - sendAllButton->setText("一键功能测试"); - sendAllButton->setStyleSheet("background-color: white;"); - manualSend = false; - for (ClientHandler* handler : clients) { - handler->resetCurrentItemIndex(); - } - } - } - else { - QListWidgetItem* listItem = new QListWidgetItem(QString("No device is connected !!!"), statusListWidget); - listItem->setBackground(Qt::red); - } -} - -// 处理单独发送功能项按键点击事件 -void MainWidget::onSendFrontFuncItemClicked() -{ - if (connectedClientsCount) { - QPushButton* button = qobject_cast(sender()); - int itemIndex = button->property("frontBoardFuncConfig").toInt(); - for (ClientHandler* handler : clients) { - QString text = frontFuncConfigLineEdit->text(); - qDebug() << "Text in frontFuncConfigLineEdit:" << text; - handler->sendFrontFuncItem(itemIndex, text); - } - } - else { - QListWidgetItem* listItem = new QListWidgetItem(QString("No device is connected !!!"), statusListWidget); - listItem->setBackground(Qt::red); - } -} - -void MainWidget::onSendBackFuncItemClicked() -{ - if (connectedClientsCount) { - QPushButton* button = qobject_cast(sender()); - int itemIndex = button->property("backBoardFuncConfig").toInt(); - for (ClientHandler* handler : clients) { - QString text = backFuncConfigLineEdit->text(); - qDebug() << "Text in backFuncConfigLineEdit:" << text; - handler->sendBackFuncItem(itemIndex, text); - } - } - else { - QListWidgetItem* listItem = new QListWidgetItem(QString("No device is connected !!!"), statusListWidget); - listItem->setBackground(Qt::red); - } -} - -// 处理单独发送项按键点击事件 -void MainWidget::onSendFrontItemClicked() -{ - qDebug() << "onSendFrontItemClicked" ; - if (connectedClientsCount) { - QPushButton* button = qobject_cast(sender()); - int itemIndex = button->property("frontBoardTest").toInt(); - for (ClientHandler* handler : clients) { - handler->sendFrontItem(itemIndex); - } - } - else { - QListWidgetItem* listItem = new QListWidgetItem(QString("No device is connected !!!"), statusListWidget); - listItem->setBackground(Qt::red); - } -} - -void MainWidget::onSendBackItemClicked() -{ - qDebug() << "onSendBackItemClicked"; - if (connectedClientsCount) { - QPushButton* button = qobject_cast(sender()); - int itemIndex = button->property("backBoardTest").toInt(); - for (ClientHandler* handler : clients) { - handler->sendBackItem(itemIndex); - } - } - else { - QListWidgetItem* listItem = new QListWidgetItem(QString("No device is connected !!!"), statusListWidget); - listItem->setBackground(Qt::red); - } -} - -// 处理状态更新信号 -void MainWidget::onStatusUpdated(const QString& client, int itemIndex, int FuncItemIndex, - bool success, const QString& itemData, const QString& funcItemData) -{ - int clientId = -1; - // 遍历所有的 ClientHandler,找到匹配的 client - for (ClientHandler* handler : clients) { - if (handler->getClientAddress() == client) { - clientId = handler->getClientId(); - QString lable = handler->getCurrentItemLable(); - lable = handler->getCurrentFuncItemLable(); - break; - } - else - { - //qDebug() << "" << __FUNCTION__ << "handler->getClientAddress() != client" ; - } - } - //qDebug() << "itemIndex :" << itemIndex; - //qDebug() << "FuncItemIndex:" << FuncItemIndex; - if (itemIndex > 0) { - QListWidgetItem* listItem = new QListWidgetItem(QString("device ID: %1 - Item %2: %3 ---> %4") - .arg(clientId) - .arg(itemIndex) - .arg(itemData) // data 字段 - .arg(success ? "OK" : "NG"), statusListWidget); - - listItem->setBackground(success ? Qt::green : Qt::red); - statusListWidget->addItem(listItem); - } - else if (FuncItemIndex > 0) { - QListWidgetItem* listItem = new QListWidgetItem(QString("device ID: %1 - funcItem %2: %3 ---> %4") - .arg(clientId) - .arg(FuncItemIndex) - .arg(funcItemData) // data 字段 - .arg(success ? "OK" : "NG"), statusListWidget); - - listItem->setBackground(success ? Qt::green : Qt::red); - statusListWidget->addItem(listItem); - } - statusListWidget->scrollToBottom(); -} - -// json文件里面的配置项都测试结束 -void MainWidget::onAllItemsProcessed(const QString& client, int itemsProcessedCount) -{ - isSendingAll = false; - sendAllButton->setText("一键功能测试"); - sendAllButton->setStyleSheet("background-color: white;"); - //qDebug() << "onAllItemsProcessed called for client:" << client << "itemsProcessedCount:" << itemsProcessedCount; - int clientId = -1; - for (ClientHandler* handler : clients) { - if (handler->getClientAddress() == client) { - clientId = handler->getClientId(); - qDebug() << "Current clientId:" << clientId; - break; - } - else - { - //qDebug() << "" << __FUNCTION__ << "handler->getClientAddress() != client"; - } - } - - QListWidgetItem* listItem = new QListWidgetItem(QString("device ID:-%1 ---> All %2 items test completed !!!") - .arg(clientId) - .arg(itemsProcessedCount), statusListWidget); - statusListWidget->addItem(listItem); - statusListWidget->scrollToBottom(); -} -