Complete typed COM decoding

This commit is contained in:
2026-04-11 10:10:43 +08:00
parent 47a2afa3a0
commit 4317deda4b
3 changed files with 346 additions and 0 deletions

View File

@@ -9,6 +9,39 @@ constexpr quint8 COM_CDC_CONST_PACKET_HEAD2 = 0x55;
constexpr int COM_CDC_CONST_FRAME_OVERHEAD = 5;
constexpr int COM_CDC_CONST_MAX_PAYLOAD_LENGTH = 64;
quint16 Com_Cdc_Func_ReadLe16(const QByteArray& ByteArray, int Offset)
{
return static_cast<quint16>(
static_cast<quint8>(ByteArray.at(Offset)) |
(static_cast<quint16>(static_cast<quint8>(ByteArray.at(Offset + 1))) << 8));
}
quint32 Com_Cdc_Func_ReadLe32(const QByteArray& ByteArray, int Offset)
{
quint32 Value = 0;
for (int Index = 0; Index < 4; ++Index)
{
Value |= static_cast<quint32>(static_cast<quint8>(ByteArray.at(Offset + Index))) <<
(Index * 8);
}
return Value;
}
quint64 Com_Cdc_Func_ReadLe64(const QByteArray& ByteArray, int Offset)
{
quint64 Value = 0;
for (int Index = 0; Index < 8; ++Index)
{
Value |= static_cast<quint64>(static_cast<quint8>(ByteArray.at(Offset + Index))) <<
(Index * 8);
}
return Value;
}
bool Com_Cdc_Func_IsKnownLengthValid(Packet_Type Type, quint8 DataLength)
{
switch (Type)
@@ -48,6 +81,15 @@ bool Com_Cdc_Func_IsKnownLengthValid(Packet_Type Type, quint8 DataLength)
}
}
bool Com_Cdc_Func_IsExpectedPacket(
const Packet& PacketData,
Packet_Type Type,
quint8 ExpectedLength)
{
return (PacketData.type == Type) &&
(PacketData.data.size() == ExpectedLength);
}
bool Com_Cdc_Func_ParseFrameAtStart(const QByteArray& ByteArray, Packet* p_Packet)
{
if ((p_Packet == nullptr) || (ByteArray.size() < COM_CDC_CONST_FRAME_OVERHEAD))
@@ -196,3 +238,187 @@ bool Com_Cdc_Func_TryTakeFrame(QByteArray* p_Buffer, Packet* p_Packet)
return true;
}
}
bool Com_Cdc_Func_ParseHelloReq(
const Packet& PacketData,
Packet_HelloReq* p_HelloReq)
{
if ((p_HelloReq == nullptr) ||
!Com_Cdc_Func_IsExpectedPacket(
PacketData,
Com_Type_HelloReq,
Packet_len::Com_Len_HelloReq))
{
return false;
}
Packet_HelloReq HelloReq;
HelloReq.ProtocolVersion = static_cast<quint8>(PacketData.data.at(0));
*p_HelloReq = HelloReq;
return true;
}
bool Com_Cdc_Func_ParseHelloRsp(
const Packet& PacketData,
Packet_HelloRsp* p_HelloRsp)
{
if ((p_HelloRsp == nullptr) ||
!Com_Cdc_Func_IsExpectedPacket(
PacketData,
Com_Type_HelloRsp,
Packet_len::Com_Len_HelloRsp))
{
return false;
}
Packet_HelloRsp HelloRsp;
HelloRsp.ProtocolVersion = static_cast<quint8>(PacketData.data.at(0));
HelloRsp.VendorId = Com_Cdc_Func_ReadLe16(PacketData.data, 1);
HelloRsp.ProductId = Com_Cdc_Func_ReadLe16(PacketData.data, 3);
HelloRsp.FirmwareMajor = static_cast<quint8>(PacketData.data.at(5));
HelloRsp.FirmwareMinor = static_cast<quint8>(PacketData.data.at(6));
HelloRsp.CapabilityFlags = Com_Cdc_Func_ReadLe16(PacketData.data, 7);
*p_HelloRsp = HelloRsp;
return true;
}
bool Com_Cdc_Func_ParseBitmap(
const Packet& PacketData,
Packet_Bitmap* p_Bitmap)
{
if ((p_Bitmap == nullptr) ||
!Com_Cdc_Func_IsExpectedPacket(
PacketData,
Com_Type_Bitmap,
Packet_len::Com_Len_Bitmap))
{
return false;
}
Packet_Bitmap Bitmap;
Bitmap.UsageBitmap = PacketData.data;
*p_Bitmap = Bitmap;
return true;
}
bool Com_Cdc_Func_ParseFunctionKeyEvent(
const Packet& PacketData,
Packet_FunctionKeyEvent* p_Event)
{
if ((p_Event == nullptr) ||
!Com_Cdc_Func_IsExpectedPacket(
PacketData,
Com_Type_FunctionKeyEvent,
Packet_len::Com_Len_FunctionKeyEvent))
{
return false;
}
Packet_FunctionKeyEvent EventData;
EventData.Usage = Com_Cdc_Func_ReadLe16(PacketData.data, 0);
EventData.Action = static_cast<quint8>(PacketData.data.at(2));
*p_Event = EventData;
return true;
}
bool Com_Cdc_Func_ParseLedState(
const Packet& PacketData,
Packet_LedState* p_LedState)
{
if ((p_LedState == nullptr) ||
!Com_Cdc_Func_IsExpectedPacket(
PacketData,
Com_Type_LedState,
Packet_len::Com_Len_LedState))
{
return false;
}
Packet_LedState LedState;
LedState.LedMask = static_cast<quint8>(PacketData.data.at(0));
*p_LedState = LedState;
return true;
}
bool Com_Cdc_Func_ParseTimeSync(
const Packet& PacketData,
Packet_TimeSync* p_TimeSync)
{
if ((p_TimeSync == nullptr) ||
!Com_Cdc_Func_IsExpectedPacket(
PacketData,
Com_Type_TimeSync,
Packet_len::Com_Len_TimeSync))
{
return false;
}
Packet_TimeSync TimeSync;
TimeSync.Version = static_cast<quint8>(PacketData.data.at(0));
TimeSync.Flags = static_cast<quint8>(PacketData.data.at(1));
TimeSync.TimezoneMin = Com_Cdc_Func_ReadLe16(PacketData.data, 2);
TimeSync.UtcMs = Com_Cdc_Func_ReadLe64(PacketData.data, 4);
TimeSync.AccuracyMs = Com_Cdc_Func_ReadLe32(PacketData.data, 12);
*p_TimeSync = TimeSync;
return true;
}
bool Com_Cdc_Func_ParseThemeRgb(
const Packet& PacketData,
Packet_ThemeRgb* p_ThemeRgb)
{
if ((p_ThemeRgb == nullptr) ||
!Com_Cdc_Func_IsExpectedPacket(
PacketData,
Com_Type_ThemeRgb,
Packet_len::Com_Len_ThemeRgb))
{
return false;
}
Packet_ThemeRgb ThemeRgb;
ThemeRgb.Red = static_cast<quint8>(PacketData.data.at(0));
ThemeRgb.Green = static_cast<quint8>(PacketData.data.at(1));
ThemeRgb.Blue = static_cast<quint8>(PacketData.data.at(2));
*p_ThemeRgb = ThemeRgb;
return true;
}
bool Com_Cdc_Func_ParseAck(
const Packet& PacketData,
Packet_Ack* p_Ack)
{
if ((p_Ack == nullptr) ||
!Com_Cdc_Func_IsExpectedPacket(
PacketData,
Com_Type_Ack,
Packet_len::Com_Len_Ack))
{
return false;
}
Packet_Ack Ack;
Ack.AckedType = static_cast<quint8>(PacketData.data.at(0));
*p_Ack = Ack;
return true;
}
bool Com_Cdc_Func_ParseError(
const Packet& PacketData,
Packet_Error* p_Error)
{
if ((p_Error == nullptr) ||
!Com_Cdc_Func_IsExpectedPacket(
PacketData,
Com_Type_Error,
Packet_len::Com_Len_Error))
{
return false;
}
Packet_Error Error;
Error.ErrorType = static_cast<quint8>(PacketData.data.at(0));
Error.ErrorCode = static_cast<quint8>(PacketData.data.at(1));
*p_Error = Error;
return true;
}

View File

@@ -6,3 +6,31 @@
bool Com_Cdc_Func_ParseFrame(const QByteArray& ByteArray, Packet* p_Packet);
bool Com_Cdc_Func_TryTakeFrame(QByteArray* p_Buffer, Packet* p_Packet);
bool Com_Cdc_Func_ParseHelloReq(
const Packet& PacketData,
Packet_HelloReq* p_HelloReq);
bool Com_Cdc_Func_ParseHelloRsp(
const Packet& PacketData,
Packet_HelloRsp* p_HelloRsp);
bool Com_Cdc_Func_ParseBitmap(
const Packet& PacketData,
Packet_Bitmap* p_Bitmap);
bool Com_Cdc_Func_ParseFunctionKeyEvent(
const Packet& PacketData,
Packet_FunctionKeyEvent* p_Event);
bool Com_Cdc_Func_ParseLedState(
const Packet& PacketData,
Packet_LedState* p_LedState);
bool Com_Cdc_Func_ParseTimeSync(
const Packet& PacketData,
Packet_TimeSync* p_TimeSync);
bool Com_Cdc_Func_ParseThemeRgb(
const Packet& PacketData,
Packet_ThemeRgb* p_ThemeRgb);
bool Com_Cdc_Func_ParseAck(
const Packet& PacketData,
Packet_Ack* p_Ack);
bool Com_Cdc_Func_ParseError(
const Packet& PacketData,
Packet_Error* p_Error);