#pragma once #include "JDefines.h" namespace Incart::Usb { class FrameParcer { private: enum EState { FIRST, LENG0, LENG1, CODE, DATA, CRC0, CRC1, FINAL }; std::vector m_data; EState m_state; uint8_t m_code; int m_length; int m_crc; int m_index; int errors; int count; public: FrameParcer(uint32_t sz) : m_data(sz) { restart(); } void restart() { m_state = EState::FIRST; m_index = 0; errors = 0; count = 0; } int getErrors() { return errors; } int getDataLength() { return m_length - 4; } int getCount() { return count; } int getSize() { return m_index; } std::vector getData() { return m_data; } std::vector getResult() { return std::vector(m_data.begin(), m_data.begin() + m_index); } uint32_t getSign() { return *reinterpret_cast(&m_data[0]); } void clear() { m_data.clear(); } bool put(const uint8_t b) { bool isFrameEnd = false; bool hasError = false; switch (m_state) { case EState::FIRST: // ждем начало кадра m_index = 0; if (b==0x7e) { m_data[m_index++] = b; m_state = EState::LENG0; } else { hasError = true; } break; case EState::LENG0: // фиксируем длину m_length = b; m_data[m_index++] = b; m_state = EState::LENG1; break; case EState::LENG1: // проверяем на 0 m_data[m_index++] = b; m_length += (static_cast(b) << 8); m_state = EState::CODE; break; case EState::CODE: // фиксируем код команды m_code = b; m_data[m_index++] = b; m_state = (m_index != (m_length + 4) ? EState::DATA : EState::CRC0); break; case EState::DATA: // фиксируем данные m_data[m_index++] = b; if (m_index == m_length + 4) { m_state = EState::CRC0; } break; case EState::CRC0: // фиксируем CRC m_data[m_index++] = b; m_crc = b; m_state = EState::CRC1; break; case EState::CRC1: // фиксируем CRC m_data[m_index++] = b; { uint32_t crcByte = b; m_crc += (crcByte << 0x8); } m_state = EState::FINAL; break; case EState::FINAL: // фиксируем конец кадра m_data[m_index++] = b; m_state = EState::FIRST; if (b == 0xbd) { isFrameEnd = true; } else { hasError = true; } break; } // точка отладки if (hasError) errors++; if (isFrameEnd) count++; return isFrameEnd; } }; } //namespace Incart::Usb