SL100_FactoryTestTool/FactoryTestTool/SourceCode/Network/ClientHandler.cpp

921 lines
35 KiB
C++
Raw Normal View History

2024-08-01 01:17:17 +00:00
// ClientHandler.cpp
#include "ClientHandler.h"
2024-08-19 01:39:32 +00:00
#include "../LicenseGenerate/LicenseConfirmWindow.h"
#include "ImageEnrollWindow.h"
#include "PasswordEnrollWindow.h"
2024-08-06 12:32:02 +00:00
ClientHandler::ClientHandler(QJsonArray frontBoardOneClickTest, QJsonArray frontBoardTest, QJsonArray frontBoardFuncConfig,
QJsonArray frontBoardDevInfoJson, QJsonArray frontBoardLicenseJson,
QJsonArray backBoardOneClickTest, QJsonArray backBoardTest, QJsonArray backBoardFuncConfig,
QJsonArray backBoardDevInfoJson, QJsonArray backBoardUuidJson,
QJsonArray getPicJson, QJsonArray getVideoJson, int clientId, int isBackBoardOrAllBoard, QObject* parent)
: QObject(parent),
2024-08-06 12:32:02 +00:00
frontBoardOneClickTest(frontBoardOneClickTest), frontBoardTest(frontBoardTest),
frontBoardFuncConfig(frontBoardFuncConfig), frontBoardDevInfoJson(frontBoardDevInfoJson),
frontBoardLicenseJson(frontBoardLicenseJson),
backBoardOneClickTest(backBoardOneClickTest), backBoardTest(backBoardTest),
backBoardFuncConfig(backBoardFuncConfig), backBoardDevInfoJson(backBoardDevInfoJson),
backBoardUuidJson(backBoardUuidJson), getPicJson(getPicJson), getVideoJson(getVideoJson),
currentItemIndex(0), clientId(clientId), isBackBoardOrAllBoard(isBackBoardOrAllBoard),
2024-08-06 12:32:02 +00:00
isManualSend(false), isSingleSend(false), isClickedSend(false), size(0),
isFirstDataReceived(true), processDataFunction(nullptr),
isDataStuck(false), dataProcessingActive(false), isRecvVideoData(true),
currentFrontBoardIndex(0), currentLicenseIndex(0), currentUuidIndex(0),
2024-08-06 12:32:02 +00:00
currentBackBoardIndex(0)
2024-08-01 01:17:17 +00:00
{
}
2024-08-01 01:17:17 +00:00
void ClientHandler::initialize(QTcpSocket* socket)
{
this->socket = socket;
connect(socket, &QTcpSocket::readyRead, this, &ClientHandler::onDataReceived);
connect(socket, &QTcpSocket::disconnected, this, &ClientHandler::onDisconnected);
// 其他的 socket 操作都将在这个线程中进行
2024-08-01 01:17:17 +00:00
}
ClientHandler::~ClientHandler()
{
socket->deleteLater();
2024-08-01 01:17:17 +00:00
qDebug() << "ClientHandler destroyed for clientId:" << clientId;
}
// 实现 QRunnable 的 run 函数,在线程池中执行
void ClientHandler::run()
{
start();
}
// 重置索引
void ClientHandler::resetCurrentItemIndex()
{
currentItemIndex = 0;
currentFuncItemIndex = 0;
itemsProcessedCount = 0;
emit startTimeout(0);
}
// 开始处理客户端
void ClientHandler::start()
{
resetCurrentItemIndex(); // 初始化计数器和索引
//sendNextItem();
}
// 处理客户端断开连接
void ClientHandler::onDisconnected() {
qDebug() << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>";
qDebug() << "> A device is disconnected. ID:" << clientId;
qDebug() << ">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>";
emit clientDisconnected(this);
}
void ClientHandler::startReadVideoDataTimer(int client_Id)
2024-08-01 01:17:17 +00:00
{
//emit startReadTimer(clientId);
emit startReadTimer(client_Id);
qDebug() << "------ startClientReadTimer clientId:" << clientId;
2024-08-01 01:17:17 +00:00
}
void ClientHandler::stopReadVideoDataTimer(int client_Id)
2024-08-01 01:17:17 +00:00
{
//emit stopReadTimer(clientId);
emit stopReadTimer(client_Id);
2024-08-01 01:17:17 +00:00
}
qint64 getFreeMemory() {
QStorageInfo storage = QStorageInfo::root();
return storage.bytesAvailable();
}
void ClientHandler::checkConnectionStatus()
{
if (socket->state() != QTcpSocket::ConnectedState) {
qCritical() << "Connection lost for clientId:" << clientId << ". Socket state:" << socket->state();
emit clientDisconnected(this);
}
}
QString ClientHandler::getCurrentItemData() const
{
QString data = currentItem.value("data").toString();
qDebug() << "Getting current item data:" << data;
return data; // 返回当前项的 "data" 字段
}
QString ClientHandler::getCurrentFuncItemData() const
{
QString data = currentFuncItem.value("val").toString();
qDebug() << "Getting current funcItem val:" << data;
2025-02-14 03:06:28 +00:00
return data; // 返回当前项的 "val" 字段
2024-08-01 01:17:17 +00:00
}
QString ClientHandler::getCurrentItemLable() const
{
QString lable = currentItem.value("lable").toString();
qDebug() << "Getting current item lable:" << lable;
2025-02-14 03:06:28 +00:00
return lable; // 返回当前项的 "lable" 字段
2024-08-01 01:17:17 +00:00
}
QString ClientHandler::getCurrentFuncItemLable() const
{
QString lable = currentFuncItem.value("lable").toString();
2024-08-19 01:39:32 +00:00
//qDebug() << "Getting current funcItem lable:" << lable;
2024-08-01 01:17:17 +00:00
return lable; // 返回当前项的 "data" 字段
}
QString ClientHandler::getClientAddress() const
{
return socket->peerAddress().toString() + ":" + QString::number(socket->peerPort());
}
#if !TEST_TCP_MOVE_TO_MAIN
void ClientHandler::onSendData(const QByteArray& data, int isBoardType)
{
qDebug() << "Sending data isBoardType:" << isBoardType;
QByteArray prefix;
QDataStream stream(&prefix, QIODevice::WriteOnly);
stream.setByteOrder(QDataStream::LittleEndian);
stream << quint32(0x55AA55AA);
if (isBoardType != 0) {
stream << quint16(0x0421);
}
else {
stream << quint16(0x0420);
}
stream << quint32(data.size());
prefix.append(data);
qDebug() << "Sending data:" << prefix.toHex();
socket->write(prefix);
socket->flush();
}
#endif
void ClientHandler::sendDataToClient(const QByteArray& data)
{
emit sendData(data, isBackBoardOrAllBoard);
}
void ClientHandler::onCommandError() {
isCommandError = true;
}
void ClientHandler::sendJsonItem(const QJsonArray& jsonArray, int itemIndex, const QString text, const QString backBoardSn, const QString& itemType)
2024-08-01 01:17:17 +00:00
{
startReadVideoDataTimer(preVideoClientId);
currentJson = jsonArray;
currentJsonItem = itemIndex;
QMutexLocker locker(&mutex);
if (itemType == "License") {
}
2024-08-01 01:17:17 +00:00
isSingleSend = true;
isClickedSend = true;
isRecvImgData = false;
if (jsonArray == backBoardTest) {
QJsonObject tempItem = jsonArray[itemIndex].toObject();
if (tempItem["cmd"] == "VIDEO_TEST") {
if (tempItem["val"] == 0) {
isSingleSend = false;
isClickedSend = false;
isRecvVideoData = true;
isStartVideo = true;
startReadVideoDataTimer(isBackBoardOrAllBoard);
}
else if (tempItem["val"] == 1) {
isRecvVideoData = false;
isStartVideo = false;
stopReadVideoDataTimer(isBackBoardOrAllBoard);
}
}
}
2024-08-19 01:39:32 +00:00
if (itemType == "handleVideo") {
if (itemIndex == 0) {
isSingleSend = false;
isClickedSend = false;
}
else {
stopReadVideoDataTimer(preVideoClientId);
}
}
if (itemType == "getPic") {
isSingleSend = false;
isClickedSend = false;
isRecvImgData = true;
2024-08-01 01:17:17 +00:00
}
if (itemType == "Uuid") {
}
qDebug() << "itemIndex" << itemIndex;
qDebug() << "jsonArray.size()" << jsonArray.size();
2024-08-01 01:17:17 +00:00
if (itemIndex >= 0 && itemIndex < jsonArray.size()) {
currentItemIndex = (itemType == "test") ? itemIndex : 0;
currentFuncItemIndex = (itemType == "func") ? itemIndex : 0;
currentItem = jsonArray[itemIndex].toObject();
2024-08-01 01:17:17 +00:00
if (!text.isEmpty() && currentItem.contains("val")) {
QJsonValue originalValue = currentItem["val"];
qDebug() << "text:" << text;
2024-08-01 01:17:17 +00:00
if (originalValue.isDouble()) {
bool ok;
double doubleValue = text.toDouble(&ok);
if (ok) {
currentItem["val"] = doubleValue;
}
else {
qWarning() << "Text conversion to double failed, original value is kept.";
}
}
else if (originalValue.isString()) {
currentItem["val"] = text;
}
}
2025-03-25 08:05:45 +00:00
else if (currentItem.contains("cmd") && currentItem["cmd"].toString() == "CHANGE_THEME") {
QString downloadUrl;
QEventLoop loop;
emit startImageSharing(CHANGE_THEME_W, CHANGE_THEME_H, "theme", [&downloadUrl, &loop](QString responseUrl) {
//qDebug() << "Received response from slot:" << responseUrl;
downloadUrl = responseUrl; // 更新局部变量
loop.quit(); // 退出事件循环
});
//loop.exec(); // 等待回调执行完成
if (!downloadUrl.isEmpty()) {
qDebug() << "Image available at:" << downloadUrl;
}
else {
return;
}
currentItem["val"] = downloadUrl;
}
else if (currentItem.contains("cmd") && currentItem["cmd"].toString() == "UPDATE_LOGO") {
QString downloadUrl;
QEventLoop loop;
emit startLOGOImageSharing(CHANGE_THEME_W, CHANGE_THEME_H, "theme", [&downloadUrl, &loop](QString responseUrl) {
//qDebug() << "Received response from slot:" << responseUrl;
downloadUrl = responseUrl; // 更新局部变量
loop.quit(); // 退出事件循环
});
//loop.exec(); // 等待回调执行完成
if (!downloadUrl.isEmpty()) {
qDebug() << "Image available at:" << downloadUrl;
}
else {
return;
}
currentItem["val"] = downloadUrl;
}
else if (!text.isEmpty() && currentItem.contains("UUID") && currentItem.contains("SN")) {
QJsonValue originalUUID = currentItem["UUID"];
QJsonValue originalSN = currentItem["SN"];
qDebug() << "UUID:" << text;
qDebug() << "SN:" << backBoardSn;
if (originalUUID.isDouble()) {
bool ok;
double doubleValue = text.toDouble(&ok);
if (ok) {
currentItem["UUID"] = doubleValue;
}
else {
qWarning() << "Text conversion to double failed, original value is kept.";
}
}
else if (originalUUID.isString()) {
currentItem["UUID"] = text;
}
if (originalSN.isDouble()) {
bool ok;
double doubleValue = backBoardSn.toDouble(&ok);
if (ok) {
currentItem["SN"] = doubleValue;
}
else {
qWarning() << "backBoardSn conversion to double failed, original value is kept.";
}
}
else if (originalSN.isString()) {
currentItem["SN"] = backBoardSn;
}
}
2024-08-01 01:17:17 +00:00
QString itemData = QJsonDocument(currentItem).toJson();
emit currentSendItem(currentItem["cmd"].toString());
if (isBackBoardOrAllBoard) {
emit sendDataToSomeClient(isBackBoardOrAllBoard, itemData.toUtf8());
}
else {
emit sendDataToSomeClient(controlClientId, itemData.toUtf8());
}
2024-08-01 01:17:17 +00:00
if (currentItem.contains("timeout")) {
qDebug() << "sendJsonItem currentItem.contains(\"timeout\")";
2024-08-01 01:17:17 +00:00
int timeout = currentItem.value("timeout").toInt();
if (timeout > 0) {
emit startTimeout(timeout);
}
}
}
}
void ClientHandler::sendBackFuncItem(int itemIndex, const QString text)
{
if (isBackBoardOrAllBoard == 0) {
emit HandleInvalidOperate("当前连接的是前板,请勿操作后板或整机页面的按键!!!");
return;
}
else {
//qDebug() << "sendFuncItem Text:" << text;
sendJsonItem(backBoardFuncConfig, itemIndex, text, "", "func");
}
}
void ClientHandler::sendFrontItem(int itemIndex)
2024-08-01 01:17:17 +00:00
{
if (isBackBoardOrAllBoard != 0) {
emit HandleInvalidOperate("当前连接的是后板或整机,请勿操作前板页面的按键!!!");
return;
2024-08-19 01:39:32 +00:00
}
else {
2025-03-25 08:05:45 +00:00
QString text = "";
QJsonObject currentItem = frontBoardTest[itemIndex].toObject();
if (currentItem.contains("cmd") && currentItem["cmd"].toString() == "IMG_ENROLL") {
QString downloadUrl;
QEventLoop loop;
emit startImageSharing(IMG_ENROLL_W, IMG_ENROLL_H, "enroll", [&downloadUrl, &loop](QString responseUrl) {
//qDebug() << "Received response from slot:" << responseUrl;
downloadUrl = responseUrl; // 更新局部变量
loop.quit(); // 退出事件循环
});
//loop.exec(); // 等待回调执行完成
if (!downloadUrl.isEmpty()) {
qDebug() << "Image available at:" << downloadUrl;
2024-08-19 01:39:32 +00:00
}
text = downloadUrl;
2024-08-19 01:39:32 +00:00
}
else if (currentItem.contains("cmd") && currentItem["cmd"].toString() == "DEL_USER") {
DelUserWindow dialog;
if (dialog.exec() == QDialog::Accepted) {
QString userInput = dialog.getUserInput();
if (!userInput.isEmpty() && currentItem.contains("val")) {
text = userInput;
}
}
else {
return;
}
2024-08-19 01:39:32 +00:00
}
else if (currentItem.contains("cmd") && currentItem["cmd"].toString() == "PASSWD_ENROLL") {
PasswordEnrollWindow dialog;
if (dialog.exec() == QDialog::Accepted) {
text = dialog.getPassword();
}
else {
return;
}
2024-08-19 01:39:32 +00:00
}
sendJsonItem(frontBoardTest, itemIndex, text, "", "test");
2024-08-19 01:39:32 +00:00
}
2024-08-01 01:17:17 +00:00
}
void ClientHandler::sendBackItem(int itemIndex)
{
if (isBackBoardOrAllBoard == 0) {
emit HandleInvalidOperate("当前连接的是前板,请勿操作后板或整机页面的按键!!!");
return;
}
else {
QString text = "";
QJsonObject currentItem = backBoardTest[itemIndex].toObject();
2025-03-25 08:05:45 +00:00
if (currentItem.contains("cmd") && currentItem["cmd"].toString() == "DEL_USER") {
DelUserWindow dialog;
if (dialog.exec() == QDialog::Accepted) {
QString userInput = dialog.getUserInput();
if (!userInput.isEmpty() && currentItem.contains("val")) {
text = userInput;
}
}
else {
return;
}
}
else if (currentItem.contains("cmd") && currentItem["cmd"].toString() == "PASSWD_ENROLL") {
PasswordEnrollWindow dialog;
if (dialog.exec() == QDialog::Accepted) {
text = dialog.getPassword();
}
else {
return;
}
}
isRecvVideoData = false;
sendJsonItem(backBoardTest, itemIndex, text, "", "test");
}
}
2025-03-25 08:05:45 +00:00
// 发送获取设备信息按键
void ClientHandler::sendGetDevInfoItem(int itemIndex)
{
sendJsonItem(getDevInfoJson, itemIndex, "", "", "devInfo");
}
// 发送取图按键
void ClientHandler::sendGetPicItem(int itemIndex, int GetPicCamIndex)
{
sendJsonItem(getPicJson, itemIndex, QString::number(GetPicCamIndex), "", "getPic");
}
// 发送拉视频按键
void ClientHandler::sendGetVideoItem(int itemIndex, int GetVideoCamIndex)
{
qDebug() << "sendGetVideoItem itemIndex:" << itemIndex;
if(isBackBoardOrAllBoard) {
sendJsonItem(getVideoJson, itemIndex, QString::number(GetVideoCamIndex), "", "handleVideo");
}
else {
sendJsonItem(getVideoJson, itemIndex, QString::number(GetVideoCamIndex), "", "handleVideo");
}
}
// 发送License处理按键
void ClientHandler::sendLicenseItem(int itemIndex, const QString text)
{
if (isBackBoardOrAllBoard != 0) {
emit HandleInvalidOperate("当前连接的是后板或整机,请勿操作前板页面的按键!!!");
return;
}
else {
if (itemIndex < 0 || itemIndex >= frontBoardLicenseJson.size()) {
qDebug() << "Invalid itemIndex";
return;
}
sendJsonItem(frontBoardLicenseJson, itemIndex, text, "", "License");
}
}
void ClientHandler::sendUuidItem(int itemIndex, const QString backBoardUuid, const QString backBoardSn)
{
qDebug() << "ClientHandler::sendUuidItem itemIndex:" << itemIndex;
if (isBackBoardOrAllBoard == 0) {
emit HandleInvalidOperate("当前连接的是前板,请勿操作后板或整机页面的按键!!!");
return;
}
else {
if (itemIndex < 0 || itemIndex >= backBoardUuidJson.size()) {
qDebug() << "Invalid itemIndex";
return;
}
sendJsonItem(backBoardUuidJson, itemIndex, backBoardUuid, backBoardSn, "Uuid");
}
}
void ClientHandler::sendFrontFuncItem(int itemIndex, const QString text)
{
if (isBackBoardOrAllBoard != 0) {
emit HandleInvalidOperate("当前连接的是后板或整机,请勿操作前板页面的按键!!!");
return;
}
else {
//qDebug() << "sendFuncItem Text:" << text;
sendJsonItem(frontBoardFuncConfig, itemIndex, text, "", "func");
}
}
2024-08-06 12:32:02 +00:00
void ClientHandler::sendDevInfoJsonItem(const QJsonObject& jsonItem, int itemIndex)
{
QMutexLocker locker(&mutex);
isPowerOnSend = true;
qDebug() << "itemIndex" << itemIndex;
qDebug() << "jsonItem.size()" << jsonItem.size();
currentItem = jsonItem;
2024-08-06 12:32:02 +00:00
QString itemData = QJsonDocument(jsonItem).toJson();
//emit sendData(itemData.toUtf8());
if (isBackBoardOrAllBoard) {
emit sendDataToSomeClient(isBackBoardOrAllBoard, itemData.toUtf8());
}
else {
emit sendDataToSomeClient(controlClientId, itemData.toUtf8());
}
2024-08-06 12:32:02 +00:00
if (jsonItem.contains("timeout")) {
int timeout = jsonItem.value("timeout").toInt();
if (timeout > 0) {
emit startTimeout(timeout);
}
}
else {
// 如果没有 timeout 字段,则不设置超时处理,一直等待数据接收
}
}
void ClientHandler::sendDevInfoItem()
{
if (isBackBoardOrAllBoard) {
currentJson = backBoardDevInfoJson;
currentJsonItem = currentBackBoardIndex;
if (currentBackBoardIndex < backBoardDevInfoJson.size()) {
isRecvVideoData = false;
sendDevInfoJsonItem(backBoardDevInfoJson[currentBackBoardIndex ++].toObject(), 1);
2024-08-06 12:32:02 +00:00
}
else {
isRecvVideoData = true;
isPowerOnSend = false;
}
2024-08-06 12:32:02 +00:00
}
else {
currentJson = frontBoardDevInfoJson;
currentJsonItem = currentFrontBoardIndex;
if (currentFrontBoardIndex < frontBoardDevInfoJson.size()) {
sendDevInfoJsonItem(frontBoardDevInfoJson[currentFrontBoardIndex ++].toObject(), 1);
2024-08-06 12:32:02 +00:00
}
else
isPowerOnSend = false;
}
}
void ClientHandler::sendNextItem(QJsonArray& currentOneClickedItem)
2024-08-01 01:17:17 +00:00
{
QMutexLocker locker(&mutex);
2024-08-01 01:17:17 +00:00
isClickedSend = true;
//qDebug() << "------> locker(&mutex) :" << itemsProcessedCount;
//qDebug() << "------> currentItemIndex :" << currentItemIndex;
//qDebug() << "------> currentOneClickedItem.size() :" << currentOneClickedItem.size();
if (currentItemIndex < currentOneClickedItem.size()) {
currentJson = currentOneClickedItem;
currentJsonItem = currentItemIndex;
currentItem = currentOneClickedItem[currentItemIndex].toObject();
2024-08-01 01:17:17 +00:00
QString itemData = QJsonDocument(currentItem).toJson();
//qDebug() << "Sending item index:" << currentItemIndex << "data:" << itemData;
if (currentItem.contains("cmd") && currentItem["cmd"].toString() == "DEL_USER") {
2024-08-01 01:17:17 +00:00
DelUserWindow dialog;
if (dialog.exec() == QDialog::Accepted) {
QString userInput = dialog.getUserInput();
if (!userInput.isEmpty() && currentItem.contains("val")) {
currentItem["val"] = userInput;
itemData = QJsonDocument(currentItem).toJson();
}
}
2024-08-01 01:17:17 +00:00
}
if (isBackBoardOrAllBoard) {
emit sendDataToSomeClient(isBackBoardOrAllBoard, itemData.toUtf8());
}
else {
emit sendDataToSomeClient(controlClientId, itemData.toUtf8());
}
2024-08-01 01:17:17 +00:00
if (currentItem.contains("timeout")) {
int timeout = currentItem.value("timeout").toInt();
if (timeout > 0) {
emit startTimeout(timeout);
}
}
else {
// 如果没有 timeout 字段,则不设置超时处理,一直等待数据接收
}
}
else if (isManualSend) {
2025-02-14 03:06:28 +00:00
emit allItemsProcessed(isBackBoardOrAllBoard, getClientAddress(), itemsProcessedCount);
2024-08-01 01:17:17 +00:00
// 处理完毕后重置标记
isManualSend = false;
2024-08-01 01:17:17 +00:00
isClickedSend = false;
// 重置索引
2024-08-01 01:17:17 +00:00
resetCurrentItemIndex();
}
}
void ClientHandler::RNDISClient1Data(QByteArray& data) {
//qDebug() << " RNDISClient1Data size:" << data.size();
isRecvVideoData = false;
isStartVideo = false;
2024-08-01 01:17:17 +00:00
}
void ClientHandler::RNDISClient2Data(QByteArray& data) {
//qDebug() << " RNDISClient2Data size:" << data.size();
isRecvVideoData = true;
isStartVideo = true;
//qDebug() << " isRecvVideoData:" << isRecvVideoData;
2024-08-01 01:17:17 +00:00
}
void ClientHandler::RNDISClient3Data(QByteArray& data) {
//qDebug() << " RNDISClient3Data size:" << data.size();
isRecvVideoData = false;
isStartVideo = false;
2024-08-01 01:17:17 +00:00
}
void ClientHandler::RNDISClient4Data(QByteArray& data) {
//qDebug() << " RNDISClient4Data size:" << data.size();
isRecvVideoData = false;
isStartVideo = false;
2024-08-01 01:17:17 +00:00
}
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;
2024-08-01 01:17:17 +00:00
QByteArray tmpdata = data.left(11);
//qDebug() << " clientType :" << clientType << " tmpdata :" << tmpdata.toHex().data();
2024-08-01 01:17:17 +00:00
switch (clientType) {
case 0x01:
processDataFunction = &ClientHandler::RNDISClient1Data;
setThreadPriority(QThread::LowestPriority);
socket->setReadBufferSize(20 * 1024);
break;
case 0x02:
qDebug() << " clientId :" << clientId;
2024-08-01 01:17:17 +00:00
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);
2024-08-01 01:17:17 +00:00
break;
case 0x03:
processDataFunction = &ClientHandler::RNDISClient3Data;
setThreadPriority(QThread::LowPriority);
socket->setReadBufferSize(20 * 1024);
break;
case 0x04:
processDataFunction = &ClientHandler::RNDISClient4Data;
setThreadPriority(QThread::LowPriority);
2024-08-01 01:17:17 +00:00
socket->setReadBufferSize(20 * 1024);
controlClientId = clientId;
// 前板有设备连接自动发送获取设备信息
sendDevInfoItem();
2024-08-01 01:17:17 +00:00
break;
default:
qWarning() << "Unhandled client type:" << clientType;
ret = false;
break;
}
return ret;
}
void ClientHandler::onTimeoutRead()
{
onDataReceived();
}
void ClientHandler::checkThreadStatus()
{
if (!QThread::currentThread()->isRunning()) {
qCritical() << "Thread for clientId:" << clientId << "is not running!";
}
else {
qDebug() << "Thread for clientId:" << clientId << "is running normally.";
}
}
// 检查数据是否卡住
bool ClientHandler::isData_Stuck() const
{
return isDataStuck;
}
void ClientHandler::setThreadPriority(QThread::Priority priority) {
QThread* thread = QThread::currentThread();
if (thread) {
thread->setPriority(priority);
//qDebug() << "Thread priority set to" << priority << "for clientId:" << clientId;
2024-08-01 01:17:17 +00:00
}
else {
qWarning() << "Failed to set thread priority. Current thread is null.";
}
}
void ClientHandler::onPicRecvFinished()
{
if (currentJson != getPicJson && currentJson != frontBoardTest) {
currentItemIndex ++;
itemsProcessedCount ++;
qDebug() << "------> onPicRecvFinished " << __FUNCTION__;
sendNextItem(currentJson);
}
}
2024-08-01 01:17:17 +00:00
void ClientHandler::onDataReceived()
{
//qDebug() << "isRecvVideoData:" << isRecvVideoData;
2025-02-14 03:06:28 +00:00
//qDebug() << "isPowerOnSend: " << isPowerOnSend;
//qDebug() << "isClickedSend: " << isClickedSend;
//qDebug() << "isSingleSend: " << isSingleSend;
//qDebug() << "isRecvImgData: " << isRecvImgData;
2024-08-01 01:17:17 +00:00
if (!isRecvVideoData &&
(isRecvImgData || isPowerOnSend || isClickedSend || (isSingleSend && (currentItemIndex < currentJson.size())))) {
2024-08-01 01:17:17 +00:00
QByteArray allData;
while (socket->bytesAvailable() > 0) {
qint64 bytesAvailableBefore = socket->bytesAvailable();
2024-08-06 12:32:02 +00:00
//qDebug() << "Bytes available before read:" << bytesAvailableBefore << "clientId:" << clientId;
2024-08-01 01:17:17 +00:00
QByteArray buffer;
buffer.resize(qMin(bytesAvailableBefore, qint64(5 * 1024))); // 每次读取最多 5KB
qint64 bytesRead = socket->read(buffer.data(), buffer.size());
if (bytesRead > 0) {
buffer.resize(bytesRead);
allData.append(buffer);
qint64 bytesAvailableAfter = socket->bytesAvailable();
}
}
getCurrentItemLable();
//qDebug() << "------- currentItem.value(timeout):" << currentItem.value("timeout").toInt();
2024-08-01 01:17:17 +00:00
if ((currentItem.contains("timeout")) || (currentFuncItem.contains("timeout"))) {
//qDebug() << "currentItem.contains(timeout):" << currentItem.contains("timeout");
2024-08-01 01:17:17 +00:00
emit startTimeout(0);
}
QJsonObject currentTempItem = currentJson[currentItemIndex].toObject();
//qDebug() << "---Received allData size:" << allData.size();
2024-08-01 01:17:17 +00:00
if (!allData.isEmpty()) {
emit dataReceived(getClientAddress(), allData, 0xFF, currentItemIndex, currentFuncItemIndex, getCurrentItemLable(), "", currentJson, currentJsonItem);
if (!isSingleSend && !isPowerOnSend && (currentTempItem["cmd"] != "GET_IMG")) {
2024-08-01 01:17:17 +00:00
currentItemIndex ++;
itemsProcessedCount ++;
}
}
2024-08-01 01:17:17 +00:00
if (isSingleSend) {
if (currentTempItem["cmd"] != "GET_IMG") {
isSingleSend = false;
}
2024-08-01 01:17:17 +00:00
isClickedSend = false;
}
else if (isPowerOnSend) {
if (isBackBoardOrAllBoard) {
if (currentBackBoardIndex < backBoardDevInfoJson.size()) {
sendDevInfoItem();
}
else {
qDebug() << "All items processed in onDataReceived.";
2025-02-14 03:06:28 +00:00
emit allItemsProcessed(isBackBoardOrAllBoard, getClientAddress(), currentBackBoardIndex);
isPowerOnSend = false;
}
}
else {
if (currentFrontBoardIndex < frontBoardDevInfoJson.size()) {
sendDevInfoItem();
}
else {
qDebug() << "All items processed in onDataReceived.";
2025-02-14 03:06:28 +00:00
emit allItemsProcessed(isBackBoardOrAllBoard, getClientAddress(), currentFrontBoardIndex);
isPowerOnSend = false;
}
}
}
else if (isClickedSend && (currentItemIndex < currentJson.size())) {
// 判断是否是取图或者其他会接收很多数据的指令
if (currentTempItem["cmd"] != "GET_IMG") {
sendNextItem(currentJson);
}
2024-08-01 01:17:17 +00:00
}
2024-08-06 12:32:02 +00:00
else if(isClickedSend) {
2025-02-14 03:06:28 +00:00
emit allItemsProcessed(isBackBoardOrAllBoard, getClientAddress(), itemsProcessedCount);
2024-08-01 01:17:17 +00:00
isClickedSend = false;
//resetCurrentItemIndex();
}
}
2024-08-19 01:39:32 +00:00
else if (isRecvVideoData && (!dataProcessingActive)) {
2024-08-01 01:17:17 +00:00
dataProcessingActive = true;
if ((isBackBoardOrAllBoard == 0) && !isStartVideo) {
isRecvVideoData = false;
}
2024-08-01 01:17:17 +00:00
QTimer::singleShot(0, this, &ClientHandler::processPendingData);
}
else if(!isRecvVideoData && !isRecvImgData){
if (preVideoClientId == clientId) {
qDebug() << "-----------------" << preVideoClientId << "isRecvVideoData:" << isRecvVideoData;
}
QByteArray AllData = socket->readAll();
if (isCommandError) {
isCommandError = false;
emit dataReceived(getClientAddress(), AllData, 0xFF, currentItemIndex, currentFuncItemIndex, "", "", currentJson, currentJsonItem);
}
//qDebug() << "--------- AllData.size():" << AllData.size();
2024-08-19 01:39:32 +00:00
}
2024-08-01 01:17:17 +00:00
}
void ClientHandler::processPendingData()
{
if (dataProcessingActive) {
try {
int maxIterations = 10; // 每次处理的最大次数
QByteArray allData;
while (socket->bytesAvailable() > 0 && maxIterations-- > 0) {
qint64 bytesAvailableBefore = socket->bytesAvailable();
2024-08-06 12:32:02 +00:00
//qDebug() << "Bytes available before read:" << bytesAvailableBefore << "clientId:" << clientId;
2024-08-01 01:17:17 +00:00
RETRY:
// 分块读取数据,避免一次性读取过多数据
QByteArray buffer;
buffer.resize(qMin(bytesAvailableBefore, qint64(5 * 1024))); // 每次读取最多 5KB
qint64 bytesRead = socket->read(buffer.data(), buffer.size());
if (bytesRead > 0) {
buffer.resize(bytesRead);
//qDebug() << "buffer.data():" << buffer.data();
2024-08-01 01:17:17 +00:00
allData.append(buffer);
qint64 bytesAvailableAfter = socket->bytesAvailable();
2024-08-06 12:32:02 +00:00
/*qDebug() << "--1--Received data size:" << buffer.size() << "clientId:" << clientId
2024-08-01 01:17:17 +00:00
<< "at" << QDateTime::currentDateTime().toString(Qt::ISODate)
2024-08-06 12:32:02 +00:00
<< "bytesAvailable after read:" << bytesAvailableAfter; */
if ((isBackBoardOrAllBoard == 0) && isFirstDataReceived) {
2024-08-01 01:17:17 +00:00
RNDISFirstData(buffer);
isFirstDataReceived = false;
}
if (bytesAvailableAfter > 9 * 1024) {
goto RETRY;
}
// 检查是否bytesAvailable没有变化避免无限循环
if (bytesAvailableBefore == bytesAvailableAfter) {
qCritical() << "Bytes available did not change after read, possible infinite loop for clientId:" << clientId;
break;
}
}
else {
qCritical() << "Failed to read data for clientId:" << clientId << ", bytesRead:" << bytesRead
<< ", socket error:" << socket->errorString();
break;
}
// 检查socket状态
if (socket->state() != QTcpSocket::ConnectedState) {
qCritical() << "Socket disconnected for clientId:" << clientId;
break;
}
}
if (!allData.isEmpty()) {
emit dataReceived(getClientAddress(), allData, 0xFF, currentItemIndex, currentFuncItemIndex, "", "", currentJson, currentJsonItem);
2024-08-01 01:17:17 +00:00
}
// 如果还有数据需要处理,继续调度处理任务
if (socket->bytesAvailable() > 0) {
QTimer::singleShot(0, this, &ClientHandler::processPendingData);
}
else {
dataProcessingActive = false;
}
//qDebug() << "Exiting processPendingData for clientId:" << clientId;
}
catch (const std::exception& e) {
qCritical() << "Exception caught in processPendingData for clientId:" << clientId << " - " << e.what();
dataProcessingActive = false;
}
catch (...) {
qCritical() << "Unknown exception caught in processPendingData for clientId:" << clientId;
dataProcessingActive = false;
}
}
}
void ClientHandler::onTimeout()
{
{
QMutexLocker locker(&mutex);
2025-02-14 03:06:28 +00:00
emit statusUpdated(isBackBoardOrAllBoard, getClientAddress(), false, currentJson, currentJsonItem);
//qDebug() << "isSingleSend:" << isSingleSend << "isPowerOnSend:" << isPowerOnSend;
2024-08-06 12:32:02 +00:00
if (!isSingleSend && !isPowerOnSend) {
2024-08-01 01:17:17 +00:00
currentItemIndex ++;
itemsProcessedCount ++;
}
}
if (isSingleSend) {
2024-08-06 12:32:02 +00:00
isSingleSend = false;
}
else if (isClickedSend) {
if (isBackBoardOrAllBoard) {
if (currentItemIndex < backBoardOneClickTest.size()) {
sendNextItem(currentJson);
}
else if (currentItemIndex >= backBoardOneClickTest.size()) {
2025-02-14 03:06:28 +00:00
emit allItemsProcessed(isBackBoardOrAllBoard, getClientAddress(), itemsProcessedCount);
}
}
else {
if (currentItemIndex < frontBoardOneClickTest.size()) {
sendNextItem(currentJson);
}
else if (currentItemIndex >= frontBoardOneClickTest.size()) {
2025-02-14 03:06:28 +00:00
emit allItemsProcessed(isBackBoardOrAllBoard, getClientAddress(), itemsProcessedCount);
}
}
2024-08-01 01:17:17 +00:00
}
2024-08-06 12:32:02 +00:00
else if (isPowerOnSend) {
if (isBackBoardOrAllBoard) {
if (currentBackBoardIndex < backBoardDevInfoJson.size()) {
sendDevInfoItem();
}
else {
2025-02-14 03:06:28 +00:00
emit allItemsProcessed(isBackBoardOrAllBoard, getClientAddress(), currentBackBoardIndex);
currentFrontBoardIndex = 0;
currentBackBoardIndex = 0;
isPowerOnSend = false;
}
}
else {
if (currentFrontBoardIndex < frontBoardDevInfoJson.size()) {
sendDevInfoItem();
}
else {
2025-02-14 03:06:28 +00:00
emit allItemsProcessed(isBackBoardOrAllBoard, getClientAddress(), currentFrontBoardIndex);
currentFrontBoardIndex = 0;
currentBackBoardIndex = 0;
isPowerOnSend = false;
}
}
2024-08-06 12:32:02 +00:00
}
2024-08-01 01:17:17 +00:00
qDebug() << "" << __FUNCTION__ << "------> itemsProcessedCount " << itemsProcessedCount;
}