1.调通所有与服务器HTTP连接的接口 2.更新图语License从服务器查询和U盘获取后上报,前板可直接使用产测工具写入License 3.优化接收到前板的H264解码后出现视频卡的问题 4.更新从前板取图后旋转 5.增加ffmpeg解码的视频分辨率获取

This commit is contained in:
钟富强 2024-08-29 11:49:55 +08:00
parent 07ab6b9608
commit e0c1e37191
21 changed files with 456 additions and 1882 deletions

View File

@ -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
}
]

View File

@ -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
}
]

View File

@ -124,5 +124,11 @@
"val": 1,
"lable": "设置log等级",
"timeout": 2000
},
{
"cmd": "SET_ALL_DATA_RESET",
"val": "0",
"lable": "前板恢复出厂",
"timeout": 2000
}
]

View File

@ -1,8 +1,8 @@
[
{
"cmd": "get_YUV",
"val": 1,
"lable": "雷达测试",
"timeout": 2000
"cmd": "GET_IMG",
"val": "0",
"lable": "取图",
"timeout": 0
}
]

View File

@ -1,13 +1,13 @@
[
{
"cmd": "START_VIDEO",
"val": 1,
"val": "1",
"lable": "启动视频",
"timeout": 0
},
{
"cmd": "STOP_VIDEO",
"val": 1,
"val": "0",
"lable": "停止视频",
"timeout": 0
}

View File

@ -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<unsigned char>(valData[3]);
int width = (static_cast<unsigned char>(valData[5]) << 8) | static_cast<unsigned char>(valData[4]);
int height = (static_cast<unsigned char>(valData[7]) << 8) | static_cast<unsigned char>(valData[6]);
int format = static_cast<unsigned char>(valData[8]);
int lens_n = static_cast<unsigned char>(valData[0]);
int width = (static_cast<unsigned char>(valData[2]) << 8) | static_cast<unsigned char>(valData[1]);
int height = (static_cast<unsigned char>(valData[4]) << 8) | static_cast<unsigned char>(valData[3]);
int format = static_cast<unsigned char>(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!";
}
}

View File

@ -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;

View File

@ -12,6 +12,9 @@
#include <QMutex>
#include <QFile>
#include <QWaitCondition>
#include <cstdint>
#include <vector>
#include "RingBuffer.h"
extern "C" {

View File

@ -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<unsigned char>(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 ++;

View File

@ -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; // 超时定时器

View File

@ -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);
}

View File

@ -3,13 +3,24 @@
#include "../Network/ClientHandler.h"
DataHandler::DataHandler(QLabel* leftLens_imageLabel, QLabel* rightLens_imageLabel, QLabel* videoLabel,
QTextEdit* licenseHwInfoEdit, QMap<QString, QLineEdit*>* devInfoLineEdits, QObject* parent)
QTextEdit* licenseHwInfoEdit, QMap<QString, QLineEdit*>* 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<unsigned char>(buffer->at(8)) << 16) |
(static_cast<unsigned char>(buffer->at(7)) << 8) |
(static_cast<unsigned char>(buffer->at(6)));
//qDebug() << "---Received dataSize:" << dataSize;
//qDebug() << "---msg_id:" << QString::number(msg_id, 16).toUpper();
//qDebug() << "---(static_cast<unsigned char>(buffer->at(10)):" << static_cast<unsigned char>(buffer->at(10));
//qDebug() << "---(static_cast<unsigned char>(buffer->at(11)):" << static_cast<unsigned char>(buffer->at(11));
//qDebug() << "---(static_cast<unsigned char>(buffer->at(12)):" << static_cast<unsigned char>(buffer->at(12));
//qDebug() << "---(static_cast<unsigned char>(buffer->at(13)):" << static_cast<unsigned char>(buffer->at(13));
//qDebug() << "---(static_cast<unsigned char>(buffer->at(14)):" << static_cast<unsigned char>(buffer->at(14));
//qDebug() << "---(static_cast<unsigned char>(buffer->at(15)):" << static_cast<unsigned char>(buffer->at(15));
// 第11字节为返回 OK/NG
bool success = (static_cast<unsigned char>(buffer->at(10)) == 0x00);
//int totalSize = 10 + dataSize + 1; // 数据头大小(10字节) + success + 实际数据
int totalSize = 10 + dataSize; // 数据头大小(10字节) + 实际数据大小
bool success = (static_cast<unsigned char>(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:

View File

@ -34,18 +34,38 @@ class DataHandler : public QObject
public:
explicit DataHandler(QLabel* leftLens_imageLabel, QLabel* rightLens_imageLabel, QLabel* videoLabel,
QTextEdit* licenseHwInfoEdit, QMap<QString, QLineEdit*>* devInfoLineEdits, QObject* parent = nullptr);
QTextEdit* licenseHwInfoEdit, QMap<QString, QLineEdit*>* 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;

View File

@ -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<QString, QString>& 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<QString,
// POST 请求
void sendPostRequest(HttpClient* httpClient, const QUrl& url, const QMap<QString, QString>& 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<QString, QString> 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<char*>(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<char*>(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<char*>(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<char*>(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<QPushButton*>(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<QPushButton*>(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<QPushButton*>(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<QPushButton*>(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<QPushButton*>(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();
}

View File

@ -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 字段对象

View File

@ -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);

View File

@ -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 !!!

View File

@ -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 !!!

Binary file not shown.

View File

@ -1,231 +0,0 @@
// MainWidget.h
#pragma once
#ifndef MAINWIDGET_H
#define MAINWIDGET_H
#include <QWidget>
#include <QTcpServer>
#include <QJsonArray>
#include <QListWidget>
#include <QCheckBox>
#include <QPushButton>
#include <QVBoxLayout>
#include <QThreadPool>
#include <QMutex>
#include <QFileDialog>
#include <QLineEdit>
#include <QTextEdit>
#include <QTabWidget>
#include <QTimer>
#include <QGroupBox>
#include <QFormLayout>
#include <QLabel>
#include <QStackedLayout>
#include <QJsonDocument>
#include <QFile>
#include <QDebug>
#include <QHBoxLayout>
#include <QTcpSocket>
#include <QUdpSocket>
#include <QNetworkInterface>
#include <QTextStream>
#include <QScrollArea>
#include <QDateTime>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>
#include <QUrl>
#include <QMap>
#include <QList>
#include <QPair>
#include <QTextCodec>
#include <QCryptographicHash>
#include <QRandomGenerator>
#include <QMessageAuthenticationCode>
#include <QCoreApplication>
#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<QPushButton*> itemButtons; // 项目按键集合
QVector<QPushButton*> funcItemButtons; // 功能配置项目按键集合
QVector<QPushButton*> getPicButtons; // 保存两个取图的摄像头的按键的指针
QVector<QPushButton*> getVideoButtons; // 保存拉视频设备的按键的指针
QList<ClientHandler*> clients; // 客户端处理器集合
QMap<int, QTimer*> clientTimers; // 每个客户端的定时器
QMap<QString, QLineEdit*> 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<int, QThread*> clientThreads;
QMap<int, QTimer*> clientReadTimers;
QMap<int, ClientHandler*> clients_1;
ServiceProvider* mServiceProvider;
QTimer* mdnsTimer;
void startMdnsService();
void stopMdnsService();
#if TEST_UDP_BROADCAST
QUdpSocket* multicastSocket;
QTimer* multicastTimer;
#endif
};
#endif // MAINWIDGET_H

File diff suppressed because it is too large Load Diff