// // ****************************************************************** // // /\ /| @File Usb_packet.cc // // \ V/ @Brief // // | "") @Author lijinwen, ghz005@uni-trend.com.cn // // / | @Creation 2024-05-17 // // / \\ @Modified 2024-06-24 // // *(__\_\ // // ****************************************************************** #include "Usb_packet.h" #include "../BaseHelper/common_helper.h" #include "../BaseHelper/Loger.h" namespace Protocol { UsbPacket::UsbPacket() : PacketTitle(), pid_(0), last_nrbz_data_bit_(false), polarity_(false), end_point_(0), crc_sign_num_(0), crc16_(0), is_valid_(false), is_crc_checked_(false), to_extracted_next_data_start_index_(-1), to_nrzi_decode_next_data_start_index_(-1), max_possible_data_length_(-1) { } UsbPacket::UsbPacket(TwoLevelEdgePulse* pid_node, int32_t& left_over_size, const Sync& sync , const bool polarity, const int32_t max_data_length) { this->polarity_ = polarity; packet_sync_ = sync; if (max_data_length >= 0) { max_possible_data_length_ = max_data_length; } //this->pidType = nullptr; TwoLevelEdgePulse* tmp_pid_node = pid_node; /*if (tmp_pid_node->startIndex < sync.endIndex && tmp_pid_node->startIndex < sync.nodePtr->startIndex + sync.Length()) { while (tmp_pid_node->startIndex < sync.endIndex && tmp_pid_node->startIndex < sync.nodePtr->startIndex + sync.Length()) { tmp_pid_node += 1; } tmp_pid_node -= 2; }*/ if (!GetPID(tmp_pid_node)) { return; } is_valid_ = true; if (this->packet_type_ == UsbEnums::UsbPacketType::NO_DEFINE) { return; } //解码域内容 DecodeFields(tmp_pid_node); } bool UsbPacket::CheckNibblesInverse(const uint8_t value) { const uint8_t high_nibble = static_cast(value >> 4); const uint8_t low_nibble = static_cast(value & 0x0F); return high_nibble == (~low_nibble & 0x0F); } bool UsbPacket::GetPID(TwoLevelEdgePulse*& pid_node) { if (!CheckNodeValid(static_cast(*pid_node))) { WriteLog(LogLevel::Level2, "node check fail"); return false; } if (packet_sync_.single_bit_timing_length <= 0) { return false; } //last_nrbz_data_bit_ = !polarity_; last_nrbz_data_bit_ = true; uint8_t data; int32_t pid_start_index = packet_sync_.end_index + 2; if (!DecodeNextByte(pid_node, pid_start_index, data)) { return false; } pid_ = data; auto handshake_type = UsbEnums::HandshakePackageType::NAK; if (IsTokenPackageType()) { packet_type_ = UsbEnums::UsbPacketType::TOKEN; } else if (IsDataPackageType()) { packet_type_ = UsbEnums::UsbPacketType::DATA; } else if (IsHandshakePackageType(handshake_type)) { packet_type_ = UsbEnums::UsbPacketType::HAND_SHAKE; switch (handshake_type) { case UsbEnums::HandshakePackageType::ACK: PacketTitle = UsbEnums::EventInfoTitles::ACK; break; case UsbEnums::HandshakePackageType::NAK: PacketTitle = UsbEnums::EventInfoTitles::NAK; break; case UsbEnums::HandshakePackageType::STALL: PacketTitle = UsbEnums::EventInfoTitles::STALL; break; case UsbEnums::HandshakePackageType::NYET: PacketTitle = UsbEnums::EventInfoTitles::NYET; break; default: // NOLINT(clang-diagnostic-covered-switch-default) return false; } } else if (IsSpecialPacketType()) { packet_type_ = UsbEnums::UsbPacketType::SPECIAL; } else { return false; } return true; } bool UsbPacket::GetNRZIData(TwoLevelEdgePulse*& node, const int32_t need_bit_count, int32_t start_index, std::vector& out_data) { if (!CheckNodeValid(node)) { WriteLog(LogLevel::Level2, "node check fail"); return false; } const int32_t get_data_start_index = start_index; //const int32_t get_data_start_index = node->StartIndex; // const bool high_polarity_edge = polarity_ ? // packet_sync_.nodePtr->edge == Edge::Rise // : packet_sync_.nodePtr->edge == Edge::Falling; auto actual_level_edge = polarity_ ? Edge::RISE : Edge::FALL; const double single_bit_timing_length_threshold = packet_sync_.single_bit_timing_length * USB_SYNC_BIT_TOL; out_data = {}; //nrzi 补位个数 const int32_t pre_complement_number = need_bit_count / USB_NRZI_COMPLEMENT_PER_NUM; const int32_t pre_complement_need_bit_count = need_bit_count + pre_complement_number; std::vector nrzi_data(pre_complement_need_bit_count, false); int32_t getbit_count = 0; bool get_last_nrzi_bit_polarity = false; while (getbit_count < pre_complement_need_bit_count) { if (!CheckNodeValid(node)) { WriteLog(LogLevel::Level2, "GetNRZIData node check fail"); return false; } if (node->end_index < start_index) { node++; continue; } ////fix if (node->end_index - start_index < packet_sync_.single_bit_timing_length / 2) { node++; if (!CheckNodeValid(node)) { WriteLog(LogLevel::Level2, "GetNRZIData node check fail"); return false; } } if (!get_last_nrzi_bit_polarity && CheckNodeValid(node - 1)) { if (start_index - node->start_index > single_bit_timing_length_threshold) { last_nrbz_data_bit_ = node->current_level == TwoLevelEdgePulseStatusType::Low; if (polarity_) { last_nrbz_data_bit_ = !last_nrbz_data_bit_; } } else { //不用改 //last_NRBZ_data_bit = (node - 1)->CurrentLevel == TwoLevelEdgePulseStatusType::High; } get_last_nrzi_bit_polarity = true; } if (node->end_index - start_index >= single_bit_timing_length_threshold) { const int bits_count = static_cast((node->end_index - start_index) / single_bit_timing_length_threshold); const int last_gotbit_count = getbit_count; for (int i = 0; i < bits_count; i++) { if (last_gotbit_count + i >= pre_complement_need_bit_count) { break; } if ((last_gotbit_count + i) >= static_cast(nrzi_data.size())) { WriteLog(LogLevel::Level2, "GetNRZIData error: last_gotbit_count + i > nrzi_data.size()"); break; } /*nrzi_data[last_gotbit_count + i] = high_polarity_edge == (node->edge == actual_level_edge);*/ nrzi_data[last_gotbit_count + i] = node->edge == actual_level_edge; getbit_count++; start_index += packet_sync_.single_bit_timing_length; } } else { nrzi_data[getbit_count] = node->edge == actual_level_edge; getbit_count++; } if (getbit_count == pre_complement_need_bit_count) { break; } node++; if (start_index < node->start_index) { start_index = node->start_index; } } //待提取下个位标_位移数 int32_t move_bit_count = 0; //lastNRBZDataBit = node->Edge == Edge::Rise; //处理连续 输出结果 int32_t continuous_count = 0; bool last_value = false; for (bool data : nrzi_data) { move_bit_count++; //6个连续下一个翻转,必然是插入的bit if (continuous_count == USB_NRZI_COMPLEMENT_PER_NUM && data != last_value) { continuous_count = 0; continue; } if (last_value == data) { continuous_count++; } else { last_value = data; continuous_count = 0; } out_data.push_back(data); if (static_cast(out_data.size()) == need_bit_count) { // if (get_data_start_index == packetSYNC.NodePtr->StartIndex) // { // to_extracted_next_data_start_index = packetSYNC.EndIndex; // } // else // { to_extracted_next_data_start_index_ = get_data_start_index + (move_bit_count * packet_sync_. single_bit_timing_length); //} //while (pre_complement_number > 0 && to_extracted_next_data_start_index > 0 && to_extracted_next_data_start_index // < node->StartIndex) //{ // //退回多抽的点位标 // pre_complement_number--; // node--; //} while (to_extracted_next_data_start_index_ > 0 && to_extracted_next_data_start_index_ < node->start_index) { //退回多抽的点位标 node--; } return true; } } WriteLog(LogLevel::LevelDebug, "GetNRZIData return fail"); return false; } //NRZI解码下个字节 bool UsbPacket::DecodeNextByteByDataField(TwoLevelEdgePulse*& node, uint8_t& out_data) { return DecodeNextByte(node, to_extracted_next_data_start_index_, out_data); } void UsbPacket::NRBZToNormalData(const TwoLevelEdgePulse* node, const int32_t need_bit_count, std::vector nrzi_data, uint8_t& out_data) { //lastNRBZDataBit = node->Edge == Edge::Rise; for (int i = 0; i < need_bit_count; i++) { //信号不变,就是数据1 if (last_nrbz_data_bit_ == nrzi_data[i]) { out_data |= (1 << i); } else { //信号变了就是数据0 } last_nrbz_data_bit_ = nrzi_data[i]; } //out_data = CommonHelper::ReverseOrderBits(out_data); } //NRZI解码下个字节 bool UsbPacket::DecodeNextByte(TwoLevelEdgePulse*& node, const int32_t start_index, uint8_t& out_data) { out_data = 0; constexpr int32_t need_bit_count = 8; std::vector nrzi_data = {}; if (!GetNRZIData(node, need_bit_count, start_index, nrzi_data)) { WriteLog(LogLevel::Level2, "DecodeNextByte GetNRZIData fail"); return false; } NRBZToNormalData(node, need_bit_count, nrzi_data, out_data); return true; } bool UsbPacket::DecodeTokenBytes(TwoLevelEdgePulse*& node, const UsbEnums::TokenPackageType type) { bool is_sof_type = type == UsbEnums::TokenPackageType::SOF; bool result; if (!is_sof_type) { //7addr-4enp-5crc bit //////////////////////////// addr //////////////////////////// std::vector addr_data = {}; uint8_t addr = 0; result = GetNRZIData(node, USB_ADDR_BIT_COUNT, to_extracted_next_data_start_index_, addr_data); if (!result) { return false; } NRBZToNormalData(node, USB_ADDR_BIT_COUNT, addr_data , addr); address_.push_back(addr); //////////////////////////// endpoint //////////////////////////// std::vector endpoint_data = {}; result = GetNRZIData(node, USB_ENDPOINT_BIT_COUNT, to_extracted_next_data_start_index_, endpoint_data); if (!result) { return false; } NRBZToNormalData(node, USB_ENDPOINT_BIT_COUNT, endpoint_data , end_point_); } else { //11frame-5bitcrc //////////////////////////// frame //////////////////////////// std::vector frame_data = {}; uint8_t frame_id_tmp = 0; datas_ = {}; result = GetNRZIData(node, USB_FRAMEID_BIT_COUNT, to_extracted_next_data_start_index_, frame_data); if (!result) { return false; } NRBZToNormalData(node, USB_FRAMEID_BIT_COUNT, frame_data , frame_id_tmp); datas_.push_back(frame_id_tmp); frame_id_tmp = 0; for (int i = 8; i < USB_FRAMEID_BIT_COUNT - 8; i++) { if (last_nrbz_data_bit_ != frame_data[i]) { last_nrbz_data_bit_ = frame_data[i]; } else { frame_id_tmp |= (1 << i); } } datas_.push_back(frame_id_tmp); } //////////////////////////// CRC5 //////////////////////////// std::vector crc_data = {}; uint8_t crc = 0; result = GetNRZIData(node, USB_CRC5_BIT_COUNT, to_extracted_next_data_start_index_, crc_data); if (!result) { return false; } NRBZToNormalData(node, USB_CRC5_BIT_COUNT, crc_data , crc); crc_sign_num_ = USB_CRC5_BIT_COUNT; crc16_ = crc; WriteLog(LogLevel::LevelDebug, "DecodeTokenBytes = true,crc_sign_num=%d,crc=0x%x" , crc_sign_num_, crc16_); return true; } void UsbPacket::DecodeFields(TwoLevelEdgePulse*& node) { switch (packet_type_) // NOLINT(clang-diagnostic-switch-enum) { case UsbEnums::UsbPacketType::TOKEN: DecodeFieldsByToken(node); break; case UsbEnums::UsbPacketType::DATA: DecodeFieldsByData(node); break; case UsbEnums::UsbPacketType::HAND_SHAKE: break; case UsbEnums::UsbPacketType::SPECIAL: DecodeFieldsBySpecial(node); break; default: break; } } void UsbPacket::DecodeFieldsByToken(TwoLevelEdgePulse*& node) { if (packet_type_ == UsbEnums::UsbPacketType::NO_DEFINE) { WriteLog(LogLevel::Level2, "DecodeFieldsByToken error:packetType is NO_DEFINE"); return; } switch (static_cast< UsbEnums::TokenPackageType>(RealPID())) { case UsbEnums::TokenPackageType::SOF: PacketTitle = UsbEnums::EventInfoTitles::SOF; DecodeTokenBytes(node, UsbEnums::TokenPackageType::SOF); break; case UsbEnums::TokenPackageType::SETUP: PacketTitle = UsbEnums::EventInfoTitles::SETUP; DecodeTokenBytes(node, UsbEnums::TokenPackageType::SETUP); break; case UsbEnums::TokenPackageType::IN_TYPE: PacketTitle = UsbEnums::EventInfoTitles::TIN; DecodeTokenBytes(node, UsbEnums::TokenPackageType::IN_TYPE); break; case UsbEnums::TokenPackageType::OUT_TYPE: PacketTitle = UsbEnums::EventInfoTitles::TOUT; DecodeTokenBytes(node, UsbEnums::TokenPackageType::OUT_TYPE); break; // default: // return; } } void UsbPacket::DecodeFieldsByData(TwoLevelEdgePulse*& node) { if (packet_type_ == UsbEnums::UsbPacketType::NO_DEFINE) { WriteLog(LogLevel::Level2, "DecodeFieldsByToken error:packetType is NO_DEFINE"); return; } int32_t end_index = packet_sync_.node_ptr->end_index; std::vector get_data_tmp = {}; switch (auto package_type = static_cast(RealPID())) { case UsbEnums::DataPackageType::DATA0: case UsbEnums::DataPackageType::DATA1: PacketTitle = package_type == UsbEnums::DataPackageType::DATA0 ? UsbEnums::EventInfoTitles::DATA0 : UsbEnums::EventInfoTitles::DATA1; datas_.clear(); if (max_possible_data_length_ >= 0 && max_possible_data_length_ > packet_sync_.Length()) { end_index = max_possible_data_length_ + packet_sync_.node_ptr->start_index - packet_sync_.single_bit_timing_length / 2; } while (CheckNodeValid(node) && node->start_index < end_index) { uint8_t data; bool result = DecodeNextByteByDataField(node, data); if (!result) { WriteLog(LogLevel::Level2, "DecodeFieldsByData DecodeNextByte fail:StartIndex:%d", node->start_index); break; } get_data_tmp.push_back(data); } if (get_data_tmp.size() > 3) { //data for (uint64_t i = 0; i < get_data_tmp.size() - 3; i++) { datas_.push_back(get_data_tmp[i]); } //crc16 /* for (uint64_t i = (get_data_tmp.size() - 2); i < get_data_tmp.size(); i++) { }*/ const uint8_t crc16_h = CommonHelper::ReverseOrderBits(get_data_tmp[get_data_tmp.size() - 3]); const uint8_t crc16_l = CommonHelper::ReverseOrderBits(get_data_tmp[get_data_tmp.size() - 2]); crc16_ = (static_cast(crc16_h) << 8) + static_cast(crc16_l); crc_sign_num_ = 16; } else { WriteLog(LogLevel::Level2, "Waring:DecodeFieldsByData Decode DataSize < 2 (%d)", get_data_tmp.size()); datas_ = std::move(get_data_tmp); } get_data_tmp.clear(); break; case UsbEnums::DataPackageType::DATA2: PacketTitle = UsbEnums::EventInfoTitles::DATA2; break; case UsbEnums::DataPackageType::M_DATA: PacketTitle = UsbEnums::EventInfoTitles::MDATA; break; // default: // break; } } void UsbPacket::DecodeFieldsBySpecial(TwoLevelEdgePulse*& node) const { //todo if (packet_type_ != UsbEnums::UsbPacketType::SPECIAL) { } } bool UsbPacket::IsTokenPackageType() const { int32_t real_pid = RealPID(); if (static_cast(UsbEnums::TokenPackageType::IN_TYPE) == real_pid || static_cast(UsbEnums::TokenPackageType::OUT_TYPE) == real_pid || static_cast(UsbEnums::TokenPackageType::SETUP) == real_pid || static_cast(UsbEnums::TokenPackageType::SOF) == real_pid ) { return true; } return false; } bool UsbPacket::IsSpecialPacketType() const { int32_t real_pid = RealPID(); if (static_cast(UsbEnums::SpecialPacketType::ERR) == real_pid || static_cast(UsbEnums::SpecialPacketType::PING) == real_pid || static_cast(UsbEnums::SpecialPacketType::REMAIN) == real_pid || static_cast(UsbEnums::SpecialPacketType::SPLIT) == real_pid ) { return true; } return false; } bool UsbPacket::IsHandshakePackageType(UsbEnums::HandshakePackageType& type) const { int32_t real_pid = RealPID(); if (static_cast(UsbEnums::HandshakePackageType::NYET) == real_pid || static_cast(UsbEnums::HandshakePackageType::STALL) == real_pid || static_cast(UsbEnums::HandshakePackageType::ACK) == real_pid || static_cast(UsbEnums::HandshakePackageType::NAK) == real_pid ) { type = static_cast(real_pid); return true; } return false; } bool UsbPacket::IsDataPackageType() { int32_t real_pid = RealPID(); if (static_cast(UsbEnums::DataPackageType::DATA0) == real_pid || static_cast(UsbEnums::DataPackageType::DATA1) == real_pid || static_cast(UsbEnums::DataPackageType::DATA2) == real_pid || static_cast(UsbEnums::DataPackageType::M_DATA) == real_pid ) { to_nrzi_decode_next_data_start_index_ = packet_sync_.end_index + (packet_sync_.one_byte_timing_length); return true; } return false; } }