SL100_FactoryTestTool/FactoryTestTool/SourceCode/RecvDataHandler/RecvDataHandler.cpp

536 lines
15 KiB
C++

// RecvDataHandler.cpp
#include "RecvDataHandler.h"
#include "../Network/ClientHandler.h"
DataHandler::DataHandler(QLabel* videoLabel, QLineEdit* VideoResolutionEdit, QSize labelSize, 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),
videoLabel(videoLabel),
VideoResolutionEdit(VideoResolutionEdit),
labelSize(labelSize),
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),
buffer(new QByteArray()), picBuffer(new QByteArray()),
ffmpegDecoder(new FFmpegDecoder()) // 初始化FFmpeg解码器
{
ffmpegDecoder->initialize(); // 初始化解码器
clearAllRecvData();
initializeMsgIdToCmdMap();
qDebug() << "DataHandler thread created";
}
DataHandler::~DataHandler()
{
if (ffmpegDecoder) {
ffmpegDecoder->stopFFmpegDecoder();
ffmpegDecoder->requestInterruption();
ffmpegDecoder->wait(); // 等待解码器线程完成
delete ffmpegDecoder;
ffmpegDecoder = nullptr;
}
delete buffer;
buffer = nullptr;
qDebug() << "DataHandler thread destroyed";
}
void DataHandler::handleOpenFocusWindow(int itemIndex)
{
if (ffmpegDecoder) {
ffmpegDecoder->processVideo(itemIndex); // 调用 FFmpegDecoder 的处理函数
}
}
QByteArray DataHandler::hexStringToByteArray(const QString& hexString)
{
QByteArray byteArray;
for (int i = 0; i < hexString.length(); i += 2) {
byteArray.append(static_cast<char>(hexString.mid(i, 2).toUShort(nullptr, 16)));
}
return byteArray;
}
const QString filePath_1 = "/add1.h264";
// 显示视频的函数
void DataHandler::showVideo(const QString& client, const QByteArray& valData)
{
QString h264filePath = QDir::currentPath() + filePath_1;
static QFile file(h264filePath);
if (!file.isOpen()) {
if (QFile::exists(h264filePath)) {
QFile::remove(h264filePath);
}
if (!file.open(QIODevice::Append | QIODevice::WriteOnly)) {
qWarning() << "无法打开H264文件:" << file.errorString();
return;
}
}
if (!valData.isEmpty()) {
file.write(valData);
file.flush(); // 刷新文件缓冲区
}
if (!start_run) {
start_run = 1;
ffmpegDecoder->decodeFile(h264filePath, videoLabel, VideoResolutionEdit);
}
//ffmpegDecoder->decodeFile(filePath_1, videoLabel);
}
void DataHandler::updateLineEdit(int msg_id, const QByteArray& actual_data) {
QString dataStr = QString(actual_data.toHex(' '));
//licenseHwInfoEdit->setPlainText(dataStr);
emit updateLicenseHwInfoEdit(dataStr);
if (msgIdToCmdMap.contains(msg_id)) {
QString cmd = msgIdToCmdMap[msg_id];
if (devInfoLineEdits->contains(cmd)) {
QLineEdit* lineEdit = devInfoLineEdits->value(cmd);
lineEdit->setText(dataStr);
}
}
}
void DataHandler::clearAllRecvData() {
allRecvData = QByteArray();
remain = 0;
dataLen = 0;
}
// 处理接收到的数据
void DataHandler::handleData(const QString& client, const QByteArray& recvData, int msg_id,
int currentRecvItemIndex, int currentRecvFuncItemIndex, const QString& itemData,
const QString& funcItemData, const QJsonArray& jsonArray, int itemJsonIndex)
{
//qDebug() << "Data received from" << client << ":" << recvData;
#if 0
从文件中读取YUV数据
QFile file("output_2.txt");
if (!file.open(QIODevice::ReadOnly)) {
qWarning() << "Failed to open file:";
file.close();
return;
}
QByteArray recvdata = file.readAll(); // 读取文件中的数据
file.close();
qDebug() << "read file data size:" << recvdata.size();
#endif
//qDebug() << "---Received data size:" << recvData.size();
// 将接收到的数据追加到buffer
buffer->append(recvData);
while (buffer->size() >= 11) { // 至少需要11个字节来解析数据头
if (buffer->mid(0, 4) == QByteArray::fromHex("aa55aa55")) {
msg_id = (static_cast<unsigned char>(buffer->at(5)) << 8) |
(static_cast<unsigned char>(buffer->at(4)));
int dataSize = (static_cast<unsigned char>(buffer->at(9)) << 24) |
(static_cast<unsigned char>(buffer->at(8)) << 16) |
(static_cast<unsigned char>(buffer->at(7)) << 8) |
(static_cast<unsigned char>(buffer->at(6)));
//qDebug() << "---Received dataSize:" << dataSize;
//qDebug() << "---msg_id:" << QString::number(msg_id, 16).toUpper();
// 第11字节为返回 OK/NG
bool success = (static_cast<unsigned char>(buffer->at(10)) == 0x00);
int totalSize = 10 + dataSize; // 数据头大小(10字节) + 实际数据大小
if (buffer->size() >= totalSize) {
// 调试查看收到的前19个字节
/*for (int i = 0; i < 19; i++) {
qDebug() << "buffer->at(" << i << "):" << QString::number(static_cast<unsigned char>(buffer->at(i)), 16).toUpper();
}*/
// 去掉前面 11 字节
QByteArray data = buffer->mid(11, dataSize);
//QByteArray data = buffer->mid(10, dataSize);
QString hexString = QString::fromUtf8(data.toHex().data());
QByteArray actual_data = hexStringToByteArray(hexString);
buffer->remove(0, totalSize); // 移除已处理的数据
if(msg_id != 0x0040 && msg_id != START_VIDEO && msg_id != GET_IMG) {
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;
}
handleCmd(msg_id, client, actual_data);
}
else {
break; // 数据还不完整,等待下一次接收
}
}
else {
buffer->remove(0, 1); // 移除无效数据头
}
}
}
void DataHandler::initializeMsgIdToCmdMap() {
msgIdToCmdMap[GET_FRONT_V851_VERSION] = "GET_FRONT_V851_VERSION";
msgIdToCmdMap[GET_FRONT_MCU_VERSION] = "GET_FRONT_MCU_VERSION";
msgIdToCmdMap[GET_FRONT_HW_VERSION] = "GET_FRONT_HW_VERSION";
msgIdToCmdMap[GET_FRONT_ALGO_VERSION] = "GET_FRONT_ALGO_VERSION";
msgIdToCmdMap[GET_FRONT_SN] = "GET_FRONT_SN";
msgIdToCmdMap[GET_BACK_V851_VERSION] = "GET_BACK_V851_VERSION";
msgIdToCmdMap[GET_BACK_806_VERSION] = "GET_BACK_806_VERSION";
msgIdToCmdMap[GET_BACK_HW_VERSION] = "GET_BACK_HW_VERSION";
msgIdToCmdMap[GET_BACK_SN] = "GET_BACK_SN";
msgIdToCmdMap[GET_BACK_UID] = "GET_BACK_UID";
}
void DataHandler::handleCmd(int msg_id, const QString& client, QByteArray actual_data)
{
if (msg_id < 0x0400) {
handleFrontCmd(msg_id, client, actual_data);
}
else if (msg_id < 0x0500) {
handleDevInfo(msg_id, client, actual_data);
}
else if (msg_id < 0x0800) {
handleBackCmd(msg_id, client, actual_data);
}
}
void DataHandler::handleFrontCmd(int msg_id, const QString& client, QByteArray actual_data)
{
switch (msg_id) {
case FACE_ENROLL_SINGLE:
{
}
break;
case FACE_ENROLL:
{
}
break;
case HAND_ENROLL:
{
}
break;
case FACE_VERIFY:
{
}
break;
case HAND_VERIFY:
{
}
break;
case DEL_USER:
{
}
break;
case DEL_ALLUSER:
{
}
break;
case GET_USER:
{
}
break;
case GET_ALLUSER:
{
}
break;
case PASSWD_ENROLL:
{
}
break;
case IMG_ENROLL:
{
}
break;
case GET_IMG:
{
int lens_n = static_cast<unsigned char>(actual_data[1]);
int width = (static_cast<unsigned char>(actual_data[3]) << 8) | static_cast<unsigned char>(actual_data[2]);
int height = (static_cast<unsigned char>(actual_data[5]) << 8) | static_cast<unsigned char>(actual_data[4]);
int format = static_cast<unsigned char>(actual_data[6]);
qint32 picSize = width * height * 1.5;
QByteArray yuvData = actual_data.mid(7);
qDebug() << "showPic width * height * 1.5:" << picSize;
qDebug() << "showPic picBuffer.size():" << picBuffer->size();
if (yuvData.size() + picBuffer->size() == picSize) {
picBuffer->append(yuvData);
showPic(labelSize, lens_n, width, height, format, picBuffer);
picBuffer->remove(0, picSize);
}
else if (yuvData.size() + picBuffer->size() > picSize) {
picBuffer->append(yuvData);
qDebug() << "width is " << width << " height is " << height << "PIC size is" << picSize;
qDebug() << "But recv PIC size is " << picBuffer->size();
picBuffer->remove(0, picBuffer->size());
}
else {
picBuffer->append(yuvData);
}
}
break;
case START_VIDEO:
{
showVideo(client, actual_data);
}
break;
case STOP_VIDEO:
{
}
break;
case TOUCH_TEST:
{
}
break;
case MIC_TEST:
{
}
break;
case SPK_TEST:
{
}
break;
case RADAR_TEST:
{
}
break;
case NFC_TEST:
{
}
break;
case PR_SWITCH:
{
}
break;
case PS_TEST:
{
}
break;
case BACKLIGHT:
{
}
break;
case IR_LED:
{
}
break;
case UART_TEST:
{
}
break;
case PIR_TEST:
{
}
break;
case FACE_VERIFY_THRES:
{
}
break;
case FACE_THRES_LEVEL:
{
}
break;
case FACE_LIVE_THRES:
{
}
break;
case FACE_ACC_THRES:
{
}
break;
case FACE_ACC_LEVEL:
{
}
break;
case FACE_DIS_RANGE:
{
}
break;
case FACE_ANGLE_RANGE:
{
}
break;
case HAND_VERIFY_THRES:
{
}
break;
case HANS_THRES_LEVEL:
{
}
break;
case HAND_LIVE_THRES:
{
}
break;
case USER_MAX_NUM:
{
}
break;
case ADMI_USER_MAX_NUM:
{
}
break;
case FACE_REPEAT:
{
}
break;
case HAND_REPEAT:
{
}
break;
case SET_IP:
{
}
break;
case SET_PORT:
{
}
break;
case SET_VOLUME:
{
}
break;
case SET_BACKLIGHT:
{
}
break;
case SET_RADAR_DIS:
{
}
break;
case SET_UART_BARTRATE:
{
}
break;
case SET_LOG_LEVEL:
{
}
break;
default:
{}
break;
}
}
void DataHandler::handleDevInfo(int msg_id, const QString& client, QByteArray actual_data)
{
switch (msg_id) {
case GET_FRONT_V851_VERSION:
case GET_FRONT_MCU_VERSION:
case GET_FRONT_HW_VERSION:
case GET_FRONT_ALGO_VERSION:
case GET_FRONT_SN:
case GET_BACK_V851_VERSION:
case GET_BACK_806_VERSION:
case GET_BACK_HW_VERSION:
case GET_BACK_SN:
case GET_BACK_UID:
{
// aa55aa5503041d00000048464d3231305f4b3431343234395f423230323031305f41302e302e38
qDebug() << "GET_DEV_INFO";
QString dataStr = QString::fromUtf8(actual_data);
if (msgIdToCmdMap.contains(msg_id)) {
QString cmd = msgIdToCmdMap[msg_id];
if (devInfoLineEdits->contains(cmd)) {
QLineEdit* lineEdit = devInfoLineEdits->value(cmd);
lineEdit->setText(dataStr);
}
}
//qDebug() << "GET_DEV_INFO msg_id:" << QString::number(msg_id, 16).toUpper();
}
break;
case GET_FRONT_HW_INFO:
{
qDebug() << "GET_FRONT_HW_INFO";
QStringList hexList;
QString dataStr;
qDebug() << "actual_data.size(): " << actual_data.size();
qDebug() << "actual_data: " << QString::fromUtf8(actual_data.toHex().data());
if (actual_data.size() == PIX_HARDWARE_INFO_BYTES) {
for (int i = 0; i < actual_data.size(); ++i) {
hexList << QString("0x%1").arg(static_cast<unsigned char>(actual_data[i]), 2, 16, QLatin1Char('0')).toUpper().replace("0X", "0x");
}
dataStr = hexList.join(", ");
}
else
dataStr = "前板发送的HW INFO 数据大小不正确";
QString displayText = dataStr;
//licenseHwInfoEdit->setPlainText(displayText);
emit updateLicenseHwInfoEdit(displayText);
}
break;
case WRITE_FRONT_LICENSE:
{
qDebug() << "WRITE_FRONT_LICENSE";
}
break;
default:
break;
}
}
void DataHandler::handleBackCmd(int msg_id, const QString& client, QByteArray actual_data)
{
switch (msg_id) {
}
}