// RecvDataHandler.cpp #include "RecvDataHandler.h" #include "../Network/ClientHandler.h" DataHandler::DataHandler(QLabel* leftLens_imageLabel, QLabel* rightLens_imageLabel, QLabel* videoLabel, QTextEdit* licenseHwInfoEdit, QMap* devInfoLineEdits, QJsonArray frontBoardOneClickTest, QJsonArray frontBoardTest, QJsonArray frontBoardFuncConfig, QJsonArray frontBoardDevInfoJson, QJsonArray frontBoardLicenseJson, QJsonArray backBoardOneClickTest, QJsonArray backBoardTest, QJsonArray backBoardFuncConfig, QJsonArray backBoardDevInfoJson, QJsonArray backBoardUuidJson, QJsonArray getPicJson, QJsonArray getVideoJson, QObject* parent) : QObject(parent), leftLens_m_imageLabel(leftLens_imageLabel), rightLens_m_imageLabel(rightLens_imageLabel), videoLabel(videoLabel), licenseHwInfoEdit(licenseHwInfoEdit), devInfoLineEdits(devInfoLineEdits), frontBoardOneClickTest(frontBoardOneClickTest), frontBoardTest(frontBoardTest), frontBoardFuncConfig(frontBoardFuncConfig), frontBoardDevInfoJson(frontBoardDevInfoJson), frontBoardLicenseJson(frontBoardLicenseJson), backBoardOneClickTest(backBoardOneClickTest), backBoardTest(backBoardTest), backBoardFuncConfig(backBoardFuncConfig), backBoardDevInfoJson(backBoardDevInfoJson), backBoardUuidJson(backBoardUuidJson), getPicJson(getPicJson), getVideoJson(getVideoJson), ffmpegDecoder(new FFmpegDecoder()), // 初始化FFmpeg解码器 buffer(new QByteArray()) { ffmpegDecoder->initialize(); // 初始化解码器 clearAllRecvData(); initializeMsgIdToCmdMap(); qDebug() << "DataHandler created"; } DataHandler::~DataHandler() { qDebug() << "---1--- DataHandler destroyed"; if (ffmpegDecoder) { ffmpegDecoder->stopFFmpegDecoder(); ffmpegDecoder->requestInterruption(); ffmpegDecoder->wait(); // 等待解码器线程完成 delete ffmpegDecoder; ffmpegDecoder = nullptr; } delete buffer; buffer = nullptr; qDebug() << "---2--- DataHandler 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(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); } //ffmpegDecoder->decodeFile(filePath_1, videoLabel); } void DataHandler::updateLineEdit(int msg_id, const QByteArray& actual_data) { QString dataStr = QString(actual_data.toHex(' ')); licenseHwInfoEdit->setPlainText(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(buffer->at(5)) << 8) | (static_cast(buffer->at(4))); int dataSize = (static_cast(buffer->at(9)) << 24) | (static_cast(buffer->at(8)) << 16) | (static_cast(buffer->at(7)) << 8) | (static_cast(buffer->at(6))); //qDebug() << "---Received dataSize:" << dataSize; //qDebug() << "---msg_id:" << QString::number(msg_id, 16).toUpper(); //qDebug() << "---(static_cast(buffer->at(10)):" << static_cast(buffer->at(10)); //qDebug() << "---(static_cast(buffer->at(11)):" << static_cast(buffer->at(11)); //qDebug() << "---(static_cast(buffer->at(12)):" << static_cast(buffer->at(12)); //qDebug() << "---(static_cast(buffer->at(13)):" << static_cast(buffer->at(13)); //qDebug() << "---(static_cast(buffer->at(14)):" << static_cast(buffer->at(14)); //qDebug() << "---(static_cast(buffer->at(15)):" << static_cast(buffer->at(15)); // 第11字节为返回 OK/NG bool success = (static_cast(buffer->at(10)) == 0x00); int totalSize = 10 + dataSize; // 数据头大小(10字节) + 实际数据大小 if (buffer->size() >= totalSize) { // 去掉前面 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); //qDebug() << "---Received hexString:" << hexString; buffer->remove(0, totalSize); // 移除已处理的数据 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; // 数据还不完整,等待下一次接收 } } 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 0x0019: { showPic(leftLens_m_imageLabel, rightLens_m_imageLabel, client, actual_data); } break; case 0x0011: { showVideo(client, actual_data); } break; case 0x0021: { //showVideo(client, actual_data); } break; 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: { showPic(leftLens_m_imageLabel, rightLens_m_imageLabel, client, actual_data); } 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"; //QString dataStr = QString(actual_data.toHex(' ')); 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(actual_data[i]), 2, 16, QLatin1Char('0')).toUpper().replace("0X", "0x"); } dataStr = hexList.join(", "); } else dataStr = "前板发送的HW INFO 数据大小不正确"; QString displayText = dataStr; licenseHwInfoEdit->setPlainText(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) { } }