// // ****************************************************************** // // /\ /| @File RS232Decode.cpp // // \ V/ @Brief // // | "") @Author lijinwen, ghz005@uni-trend.com.cn // // / | @Creation 2024-5-7 // // / \\ @Modified 2024-5-13 // // *(__\_\ // // ****************************************************************** #include "RS232Decode.h" #include "../BaseEnums/DataCheckEnums.h" #include "../BaseHelper/DataCheckHelper.h" #include "../BaseHelper/Logger.h" namespace Protocol::ProtocolRS232 { int32_t RS232Decode::GetStartIndex(const RS232DecodeParams& options, TwoLevelEdgePulse*& node, double count, double& realCount, const int32_t startIndex, TwoLevelEdgePulseStatusType& startStatus) { startStatus = options.Polarity == Polarity::Pos ? TwoLevelEdgePulseStatusType::High : TwoLevelEdgePulseStatusType::Low; while (node != nullptr) { if (node->CurrentLevel != startStatus && node->StartIndex >= startIndex) { //计算该脉宽中,最大包括几个bit信息宽度 const double bitCount = std::round(node->GetLength() / count); if (bitCount > 0 && bitCount < static_cast(options.DataBitWidth) + 4) { realCount = node->GetLength() / bitCount; } if (bitCount > 0) break; } node++; } return node == nullptr ? -1 : node->StartIndex; } bool RS232Decode::ParseData(const RS232DecodeParams& options) { WriteLog(LogLevel::LevelDebug," SignalType:%d, DataBitWidth:%d" , static_cast(options.SignalType), static_cast(options.DataBitWidth)); if (canceled_) { WriteLog(LogLevel::Level2," ParsingData canceled.\n"); //gMutex.unlock(); // 执行完操作后手动释放锁 return false; } //栈上 初始化内存 RS232Packets_ = {}; DecodeEvents_ = {}; DecodeResultUnits_ = {}; DecodeResultBase_ = {}; RS232DecodeResult_ = {}; RS232DecodeResult* rs232DecodeResultPtr = &RS232DecodeResult_; DecodeResultBase_.ProtocolType = SerialProtocolType::RS232; DecodeResultBase_.ResultDataPtr = rs232DecodeResultPtr; DecodeResultBase_.ResultValid = false; auto decodeResultUnitsPtr = &DecodeResultUnits_; auto decodeEventsPtr = &DecodeEvents_; WriteLog(LogLevel::LevelDebug," decodeResultUnitsPtr:0x%X\n", static_cast(decodeResultUnitsPtr)); WriteLog(LogLevel::LevelDebug," decodeEventsPtr:0x%X\n", static_cast(decodeEventsPtr)); canceled_ = false; if (canceled_) { WriteLog(LogLevel::Level2," ParsingData canceled.\n"); return false; } if (options.EdgePulseData == nullptr) { WriteLog(LogLevel::Level2," EdgePulseDataPtr is nullptr\n"); return false; } //if (edgePulseData.edgePulses.empty()) if (options.EdgePulseData->WaveformDataCount == 0) { std::cout << " DataCount is 0 or sampleRate error\n"; WriteLog(LogLevel::Level2," DataCount is 0 or sampleRate error\n"); return false; } TwoLevelEdgePulse* edgePulses = options.EdgePulseData->GetDataAddrPtr(); int32_t dataBitCount = 0; switch (options.DataBitWidth) { case Enums::DataBitWidth::DataBitWidth_5Bit: dataBitCount = 5; break; case Enums::DataBitWidth::DataBitWidth_6Bit: dataBitCount = 6; break; case Enums::DataBitWidth::DataBitWidth_7Bit: dataBitCount = 7; break; case Enums::DataBitWidth::DataBitWidth_8Bit: dataBitCount = 8; break; } uint64_t edgePulseIndex = 0; //每bit理论长度 const double count = 1.0 / options.BaudRate * options.EdgePulseData->SampleRate; WriteLog(LogLevel::LevelDebug," bit count:%f", count); //const double count = static_cast(dataCount); //每bit实际长度 double realCount = count; const int32_t stopBitCount = options.StopBit == Enums::StopBit::StopBit_1bit ? 1 : options.StopBit == Enums::StopBit::StopBit_2bit ? 2 : 1; WriteLog(LogLevel::LevelDebug," realCount:%f", realCount); WriteLog(LogLevel::LevelDebug," edgePulsePointer:0x%x", reinterpret_cast(edgePulses)); //WriteLog(" edgePulsePointer:0x%x", edgePulses); WriteLog(LogLevel::LevelDebug," edgePulse StartIndex:%d", edgePulses->StartIndex); WriteLog(LogLevel::LevelDebug," edgePulse EndIndex:%d", edgePulses->EndIndex); WriteLog(LogLevel::LevelDebug," edgePulseCount:%d", options.EdgePulseData->EdgePulsesCount); try { int32_t startIndex = 0; while (edgePulses != nullptr && edgePulseIndex < options.EdgePulseData->EdgePulsesCount) { if (count <= 2) break; TwoLevelEdgePulseStatusType levelState; //找到帧头 根据帧头得到实际bit宽度realCount 帧头起始位置startIndex 电平状态levelState int32_t packetStartIndex = GetStartIndex(options, edgePulses, count, realCount, startIndex, levelState); //WriteLog(" GetStartIndex PacketStartIndex:%d\n", packetStartIndex); if (canceled_) { WriteLog(LogLevel::Level2," ParsingData canceled.\n"); return false; } if (packetStartIndex == -1) break; //std::cout << " packetStartIndex:" << packetStartIndex << " ,realCount:" << realCount << "\n"; //构造帧 RS232Packet packet = {}; packetStartIndex += static_cast(std::round(realCount / 2)); if (edgePulses->StartIndex >= edgePulses->EndIndex || !CommonHelper::EnumIsDefined< TwoLevelEdgePulseStatusType>(static_cast(edgePulses->CurrentLevel))) { std::ostringstream msg; msg << " =>178 loop break Index:" << packetStartIndex << " ,dataCount:" << options. EdgePulseData->WaveformDataCount << "\n"; WriteLog(LogLevel::LevelDebug,msg.str().c_str()); break; } if (packetStartIndex >= static_cast(options.EdgePulseData->WaveformDataCount)) { std::ostringstream msg; msg << " =>186 loop break Index:" << packetStartIndex << " ,dataCount:" << options. EdgePulseData->WaveformDataCount << "\n"; WriteLog(LogLevel::LevelDebug,msg.str().c_str()); break; } if (startIndex == static_cast(options.EdgePulseData->WaveformDataCount)) break; packet.StartBit = levelState == TwoLevelEdgePulseStatusType::High; packet.StartIndex = packetStartIndex - static_cast(std::round(realCount / 2)); packet.DataIndex = packetStartIndex + static_cast(std::round(realCount / 2)); packet.PerBitLenght = realCount; WriteLog(LogLevel::LevelDebug,"=> Tst StartIndex:%d,dataBitCount:%d", packet.StartIndex, dataBitCount); for (int32_t dataBitIndex = 0; dataBitIndex < dataBitCount; dataBitIndex++) { if (canceled_) { WriteLog(LogLevel::Level2," ParsingData canceled.\n"); return false; } packetStartIndex += static_cast(std::round(realCount)); //std::cout << " P150 Test" << "\n"; if (packetStartIndex >= static_cast(options.EdgePulseData->WaveformDataCount)) { startIndex = static_cast(options.EdgePulseData->WaveformDataCount); WriteLog(LogLevel::LevelDebug," =>%d break \n", __LINE__); break; } //std::cout << " P157 Test" << "\n"; TwoLevelEdgePulseStatusType bitStatus; if (!GetRS232Bit(edgePulses, packetStartIndex, bitStatus)) { //gMutex.unlock(); // 执行完操作后手动释放锁 return false; } //按位构造数据 if (options.MSBOrLSB == MSBOrLSB::MSB) { packet.Data = static_cast(packet.Data << 1); packet.Data |= bitStatus == TwoLevelEdgePulseStatusType::High ? 1 : 0; } else { packet.Data |= static_cast((bitStatus == TwoLevelEdgePulseStatusType::High ? 1 : 0) << dataBitIndex); } WriteLog(LogLevel::LevelDebug,"Tst CurrentLevel:%d, bitStatus:%d", edgePulses->CurrentLevel, bitStatus); } //std::cout << " P177 Test" << "\n"; if (startIndex == static_cast(options.EdgePulseData->WaveformDataCount)) break; //校验位 if (options.OddEvenCheckType != OddEvenCheck::None) { packetStartIndex += static_cast(std::round(realCount)); if (packetStartIndex >= static_cast(options.EdgePulseData->WaveformDataCount)) { //startIndex = static_cast(bufferLength); RS232Packets_.push_back(packet); WriteLog(LogLevel::LevelDebug," =>%d break \n", __LINE__); break; } TwoLevelEdgePulseStatusType bitStatus; if (!GetRS232Bit(edgePulses, packetStartIndex, bitStatus)) { //gMutex.unlock(); // 执行完操作后手动释放锁 return false; } packet.ParityFind = true; packet.ParityBit = bitStatus == TwoLevelEdgePulseStatusType::High; packet.ParityResult = DataCheckHelper::CheckDataByOddEven( packet.Data, dataBitCount, options.OddEvenCheckType); packet.ParityIndex = packet.DataIndex + static_cast( std::round(realCount * dataBitCount)); } //std::cout << " P203 Test" << "\n"; RS232Packets_.push_back(packet); packetStartIndex += static_cast(realCount * stopBitCount); startIndex = packetStartIndex; edgePulseIndex++; } } catch (const char* ex) { WriteLog(LogLevel::LevelDebug," ParsingData L%d catch :%s", __LINE__, ex); return false; } { std::ostringstream msg; msg << " edgePulseIndex:" << edgePulseIndex << ","; msg << " rs232Packets count:" << RS232Packets_.size() << ","; msg << " get events && results"; WriteLog(LogLevel::Level2,msg.str().c_str()); } //get events && results //std::cout << " P218 Test rs232Packets Count:" << rs232Packets.size() << "\n"; if (!RS232Packets_.empty()) { DecodeEventUnitsStorage_ = {}; //for (int64_t i = 0; i < static_cast(rs232Packets.size()); i++) for (auto packet : RS232Packets_) { if (canceled_) { WriteLog(LogLevel::Level2," ParsingData canceled.\n"); //gMutex.unlock(); // 执行完操作后手动释放锁 return false; } RS232DecodeResultUnit resultUnit; RS232DecodeEvent decodeEvent = {}; auto eventPtr = &decodeEvent; RS232DecodeEventUnit eventStart; RS232DecodeEventUnit eventData; int64_t eventStartIndex = packet.StartIndex; int64_t oneBitLength = static_cast(packet.PerBitLenght); eventPtr->StartIndex = packet.StartIndex; eventStart.StartIndex = packet.StartIndex; eventStart.Length = oneBitLength; eventStartIndex += 1; eventStart.EventType = Enums::RS232DecodeEventType::Start; eventData.StartIndex = eventStart.StartIndex; eventData.Length = oneBitLength * dataBitCount; eventData.Data = packet.Data; eventData.EventType = Enums::RS232DecodeEventType::Data; eventStartIndex += 8; //std::cout << " P249 Test I:" << i << "\n"; if (packet.ParityFind) { RS232DecodeEventUnit eventUints[3]; eventUints[0] = eventStart; eventUints[1] = eventData; RS232DecodeEventUnit eventParity; //std::cout << " P253 Test I:" << i << "\n"; eventParity.Data = packet.ParityResult ? 1 : 0; eventParity.StartIndex = eventStartIndex; eventParity.Length = oneBitLength; eventParity.EventType = Enums::RS232DecodeEventType::Parity; eventPtr->ParityResult = packet.ParityResult ? 1 : 0; eventUints[2] = eventParity; //eventPtr->EventData = eventUints; eventStartIndex += 8; eventPtr->EventDataCount = 3; eventPtr->EndIndex = packet.StartIndex + oneBitLength * (dataBitCount + 1); // 将eventUints复制到decodeEventUnitsStorage中 DecodeEventUnitsStorage_.insert(DecodeEventUnitsStorage_.end(), std::begin(eventUints), std::end(eventUints)); //最后来赋值 //decodeEvent.EventData = decodeEventUnitsStorage.data() + decodeEventUnitsStorage.size() - 3; } else { RS232DecodeEventUnit eventUints[2]; eventUints[0] = eventStart; eventUints[1] = eventData; eventPtr->EventDataCount = 2; //eventPtr->EventData = eventUints; //std::cout << " P263 Test I:" << i << "\n"; eventPtr->ParityResult = 0; eventPtr->EndIndex = packet.StartIndex + oneBitLength * (dataBitCount); // 将eventUints复制到decodeEventUnitsStorage中 DecodeEventUnitsStorage_.insert(DecodeEventUnitsStorage_.end(), std::begin(eventUints), std::end(eventUints)); //最后来赋值 //decodeEvent.EventData = decodeEventUnitsStorage.data() + decodeEventUnitsStorage.size() - 2; } //std::cout << " P266 Test I:" << i << "\n"; resultUnit.StartIndex = packet.StartIndex; //最后来赋值 //resultUnit.Data = &packet.Data; WriteLog(LogLevel::LevelDebug," Tst Data Ptr:0x%x , Data:%d", static_cast(resultUnit.Data), packet.Data); resultUnit.DataCount = 1; resultUnit.Length = eventStartIndex - packet.StartIndex; eventPtr->EventIndex = static_cast(decodeEventsPtr->size()); DecodeEvents_.push_back(decodeEvent); DecodeResultUnits_.push_back(resultUnit); rs232DecodeResultPtr->DecodeEventNeedUpdate = true; rs232DecodeResultPtr->DecodeResultNeedUpdate = true; } } /////////////////////////// 指针赋值 ///////////////////////////////// int64_t eventDataIndex = 0; for (int i = 0; i < DecodeEvents_.size(); i++) // NOLINT(modernize-loop-convert, clang-diagnostic-sign-compare) { DecodeEvents_[i].EventData = DecodeEventUnitsStorage_.data() + eventDataIndex; eventDataIndex += DecodeEvents_[i].EventDataCount; } for (int i = 0; i < DecodeResultUnits_.size(); i++) // NOLINT(clang-diagnostic-sign-compare) { int64_t startIndex = DecodeResultUnits_[i].StartIndex; for (int x = 0; i < RS232Packets_.size(); x++) // NOLINT(clang-diagnostic-sign-compare) { if (RS232Packets_[x].StartIndex == startIndex) { DecodeResultUnits_[i].Data = &(RS232Packets_[x].Data); break; } } } rs232DecodeResultPtr->DecodeEventsPtr = decodeEventsPtr->data(); rs232DecodeResultPtr->DecodeResultUnitsPtr = decodeResultUnitsPtr->data(); rs232DecodeResultPtr->DecodeEventCount = decodeEventsPtr->size(); rs232DecodeResultPtr->DecodeResultCount = decodeResultUnitsPtr->size(); DecodeResultBase_.ResultValid = true; DecodeResultBase_.ResultDataPtr = rs232DecodeResultPtr; WriteLog(LogLevel::Level1," Cpp ParsingData Done,return True \n\n"); return true; } void RS232Decode::Decode(const DecodeParams* decodeParams) { status_ = ProtocolStatus::DecodeInProgress; WriteLog(LogLevel::Level2," RS232 Decode Start\n"); WriteLog(LogLevel::Level2," Type: %d", decodeParams->ProtocolType); WriteLog(LogLevel::Level2," AutoClock: %d", decodeParams->AutomaticClockRecovery); try { if (decodeParams == nullptr || decodeParams->ProtocolParamsPtr == nullptr) { WriteLog(LogLevel::LevelDebug," DecodeParams or pointer is null\n"); status_ = ProtocolStatus::DecodeFailure; return; } //WriteLog(" Decode ProtocolParamsPtr:0x%x", reinterpret_cast(decodeParams->ProtocolParamsPtr)); WriteLog(LogLevel::LevelDebug," Decode ProtocolParamsPtr:0x%x", decodeParams->ProtocolParamsPtr); if (static_cast(decodeParams->ProtocolParamsPtr) == nullptr) { WriteLog(LogLevel::LevelDebug," DecodeParams is null\n"); status_ = ProtocolStatus::DecodeFailure; return; } // 安全的向下转型 const RS232DecodeParams options = static_cast(decodeParams->ProtocolParamsPtr)[0]; WriteLog(LogLevel::LevelDebug," Decode Get RS232DecodeParams BaudRate:%d", options.BaudRate); //test 测试成功 const uint64_t edgePulsesCount = options.EdgePulseData->EdgePulsesCount; const TwoLevelEdgePulse* edgePulsesPtr = options.EdgePulseData->GetDataAddrPtr(); if (edgePulsesCount > 0 && edgePulsesPtr != nullptr) { for (uint64_t i = 0; i < edgePulsesCount; i++) { const TwoLevelEdgePulse edgePulses = edgePulsesPtr[i]; WriteLog(LogLevel::LevelDebug,"Index: %d, Level:%d", edgePulses.StartIndex, edgePulses.CurrentLevel); } } const bool result = ParseData(options); WriteLog(LogLevel::Level2," Decode ParseData Result:%d", result); if (!result) { status_ = ProtocolStatus::DecodeFailure; WriteLog(LogLevel::Level1," RS232 Decode Failure\n"); return; } } catch (const std::runtime_error& e) { WriteLog(LogLevel::LevelDebug,"Caught exception: %s", e.what()); status_ = ProtocolStatus::DecodeFailure; return; } catch (const std::exception& e) { // 捕获所有标准库异常 WriteLog(LogLevel::LevelDebug,"Caught exception: %s", e.what()); status_ = ProtocolStatus::DecodeFailure; return; } catch (...) { // 捕获所有非标准库异常 WriteLog(LogLevel::LevelDebug,"Caught unknown exception"); status_ = ProtocolStatus::DecodeFailure; return; } WriteLog(LogLevel::Level1," RS232 Decode Succeed\n"); status_ = ProtocolStatus::Success; } void RS232Decode::QuantizeDecode(const QuantizeParams& decodeParams) { //todo 整形 } DecodeResult* RS232Decode::GetResult() { return &DecodeResultBase_; } RS232Decode::~RS232Decode() = default; std::vector RS232Decode::GetEventInfoTitles() { return EventInfoTitles_; } bool RS232Decode::GetRS232Bit(TwoLevelEdgePulse*& edgePulse, int32_t targetIndex, TwoLevelEdgePulseStatusType& status) { status = TwoLevelEdgePulseStatusType::None; if (edgePulse == nullptr) { return false; } if (targetIndex <= 0 || edgePulse->StartIndex > targetIndex) { return false; } while (edgePulse != nullptr) { if (edgePulse->StartIndex <= targetIndex && edgePulse->EndIndex > targetIndex) { status = edgePulse->CurrentLevel; //test WriteLog(LogLevel::Level2,"StartIndex:%d , status:%d", edgePulse->StartIndex, status); return true; } edgePulse++; } return false; } }