123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604 |
- // // ******************************************************************
- // // /\ /| @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<uint8_t>(value >> 4);
- const uint8_t low_nibble = static_cast<uint8_t>(value & 0x0F);
- return high_nibble == (~low_nibble & 0x0F);
- }
- bool UsbPacket::GetPID(TwoLevelEdgePulse*& pid_node)
- {
- if (!CheckNodeValid(static_cast<EdgePulse>(*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<bool>& 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<bool> 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<int>((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<int32_t>(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<int32_t>(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<bool> 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<bool> 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<bool> 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<bool> 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<bool> 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<bool> 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<uint8_t> get_data_tmp = {};
- switch (auto package_type = static_cast<UsbEnums::DataPackageType>(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<uint16_t>(crc16_h) << 8) + static_cast<uint16_t>(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<int32_t>(UsbEnums::TokenPackageType::IN_TYPE) == real_pid
- || static_cast<int32_t>(UsbEnums::TokenPackageType::OUT_TYPE) == real_pid
- || static_cast<int32_t>(UsbEnums::TokenPackageType::SETUP) == real_pid
- || static_cast<int32_t>(UsbEnums::TokenPackageType::SOF) == real_pid
- )
- {
- return true;
- }
- return false;
- }
- bool UsbPacket::IsSpecialPacketType() const
- {
- int32_t real_pid = RealPID();
- if (static_cast<int32_t>(UsbEnums::SpecialPacketType::ERR) == real_pid
- || static_cast<int32_t>(UsbEnums::SpecialPacketType::PING) == real_pid
- || static_cast<int32_t>(UsbEnums::SpecialPacketType::REMAIN) == real_pid
- || static_cast<int32_t>(UsbEnums::SpecialPacketType::SPLIT) == real_pid
- )
- {
- return true;
- }
- return false;
- }
- bool UsbPacket::IsHandshakePackageType(UsbEnums::HandshakePackageType& type) const
- {
- int32_t real_pid = RealPID();
- if (static_cast<int32_t>(UsbEnums::HandshakePackageType::NYET) == real_pid
- || static_cast<int32_t>(UsbEnums::HandshakePackageType::STALL) == real_pid
- || static_cast<int32_t>(UsbEnums::HandshakePackageType::ACK) == real_pid
- || static_cast<int32_t>(UsbEnums::HandshakePackageType::NAK) == real_pid
- )
- {
- type = static_cast<UsbEnums::HandshakePackageType>(real_pid);
- return true;
- }
- return false;
- }
- bool UsbPacket::IsDataPackageType()
- {
- int32_t real_pid = RealPID();
- if (static_cast<int32_t>(UsbEnums::DataPackageType::DATA0) == real_pid
- || static_cast<int32_t>(UsbEnums::DataPackageType::DATA1) == real_pid
- || static_cast<int32_t>(UsbEnums::DataPackageType::DATA2) == real_pid
- || static_cast<int32_t>(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;
- }
- }
|