// RecvDataHandler.cpp #include "RecvDataHandler.h" #include "../Network/ClientHandler.h" DataHandler::DataHandler(QLabel* leftLens_imageLabel, QLabel* rightLens_imageLabel, QLabel* videoLabel, QTextEdit* licenseHwInfoEdit, QMap* devInfoLineEdits, QObject* parent) : QObject(parent), leftLens_m_imageLabel(leftLens_imageLabel), rightLens_m_imageLabel(rightLens_imageLabel), videoLabel(videoLabel), licenseHwInfoEdit(licenseHwInfoEdit), devInfoLineEdits(devInfoLineEdits), ffmpegDecoder(new FFmpegDecoder()), // 初始化FFmpeg解码器 buffer(new QByteArray()) { ffmpegDecoder->initialize(); // 初始化解码器 clearAllRecvData(); initializeMsgIdToCmdMap(); } DataHandler::~DataHandler() { if (ffmpegDecoder) { ffmpegDecoder->requestInterruption(); ffmpegDecoder->wait(); // 等待解码器线程完成 delete ffmpegDecoder; ffmpegDecoder = nullptr; } delete buffer; buffer = nullptr; } 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) { static QFile file(filePath_1); if (!file.isOpen()) { if (QFile::exists(filePath_1)) { QFile::remove(filePath_1); } 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(filePath_1, 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) { //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))); // 第11字节为返回 OK/NG bool success = (static_cast(buffer->at(10)) == 0x00); //int totalSize = 10 + dataSize + 1; // 数据头大小(10字节) + success + 实际数据 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); 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); } 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: { } break; case START_VIDEO: { } 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(' ')); QString displayText = "get_hw_info:\n" + 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) { } }