Remove legacy COM codec
This commit is contained in:
@@ -1,121 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/QByteArray>
|
||||
#include <QtCore/QtGlobal>
|
||||
|
||||
struct Packet_len
|
||||
{
|
||||
static const quint8 Com_Len_UnKnow = 0;
|
||||
static const quint8 Com_Len_HelloReq = 1;
|
||||
static const quint8 Com_Len_HelloRsp = 9;
|
||||
static const quint8 Com_Len_Bitmap = 29;
|
||||
static const quint8 Com_Len_FunctionKeyEvent = 3;
|
||||
static const quint8 Com_Len_LedState = 1;
|
||||
static const quint8 Com_Len_TimeSync = 16;
|
||||
static const quint8 Com_Len_ThemeRgb = 3;
|
||||
static const quint8 Com_Len_Ack = 1;
|
||||
static const quint8 Com_Len_Error = 2;
|
||||
};
|
||||
|
||||
enum Packet_Type : quint8
|
||||
{
|
||||
Com_Type_UnKnow = 0x00,
|
||||
|
||||
Com_Type_HelloReq = 0x01,
|
||||
Com_Type_HelloRsp = 0x02,
|
||||
|
||||
Com_Type_Bitmap = 0x10,
|
||||
|
||||
Com_Type_FunctionKeyEvent = 0x20,
|
||||
Com_Type_LedState = 0x21,
|
||||
|
||||
Com_Type_TimeSync = 0x30,
|
||||
Com_Type_ThemeRgb = 0x31,
|
||||
|
||||
Com_Type_Ack = 0x7E,
|
||||
Com_Type_Error = 0x7F
|
||||
};
|
||||
|
||||
enum Key_Action : quint8
|
||||
{
|
||||
Key_Action_Release = 0x00,
|
||||
Key_Action_Press = 0x01
|
||||
};
|
||||
|
||||
enum Error_Code : quint8
|
||||
{
|
||||
Error_Code_None = 0x00,
|
||||
Error_Code_UnknownType = 0x01,
|
||||
Error_Code_InvalidLength = 0x02,
|
||||
Error_Code_InvalidParam = 0x03,
|
||||
Error_Code_NotReady = 0x04
|
||||
};
|
||||
|
||||
struct Packet
|
||||
{
|
||||
quint8 Com_Packet_Head1 = 0xAA;
|
||||
quint8 Com_Packet_Head2 = 0x55;
|
||||
|
||||
quint8 len = Packet_len::Com_Len_UnKnow;
|
||||
Packet_Type type = Com_Type_UnKnow;
|
||||
|
||||
QByteArray data;
|
||||
};
|
||||
|
||||
struct Packet_HelloReq
|
||||
{
|
||||
quint8 ProtocolVersion = 0x01;
|
||||
};
|
||||
|
||||
struct Packet_HelloRsp
|
||||
{
|
||||
quint8 ProtocolVersion = 0x01;
|
||||
quint16 VendorId = 0;
|
||||
quint16 ProductId = 0;
|
||||
quint8 FirmwareMajor = 0;
|
||||
quint8 FirmwareMinor = 0;
|
||||
quint16 CapabilityFlags = 0;
|
||||
};
|
||||
|
||||
struct Packet_Bitmap
|
||||
{
|
||||
QByteArray UsageBitmap = QByteArray(Packet_len::Com_Len_Bitmap, 0);
|
||||
};
|
||||
|
||||
struct Packet_FunctionKeyEvent
|
||||
{
|
||||
quint16 Usage = 0;
|
||||
quint8 Action = Key_Action_Release;
|
||||
};
|
||||
|
||||
struct Packet_LedState
|
||||
{
|
||||
quint8 LedMask = 0;
|
||||
};
|
||||
|
||||
struct Packet_TimeSync
|
||||
{
|
||||
quint8 Version = 1;
|
||||
quint8 Flags = 0;
|
||||
quint16 TimezoneMin = 0;
|
||||
quint64 UtcMs = 0;
|
||||
quint32 AccuracyMs = 0;
|
||||
};
|
||||
|
||||
struct Packet_ThemeRgb
|
||||
{
|
||||
quint8 Red = 0;
|
||||
quint8 Green = 0;
|
||||
quint8 Blue = 0;
|
||||
};
|
||||
|
||||
struct Packet_Ack
|
||||
{
|
||||
quint8 AckedType = 0;
|
||||
};
|
||||
|
||||
struct Packet_Error
|
||||
{
|
||||
quint8 ErrorType = 0;
|
||||
quint8 ErrorCode = Error_Code_None;
|
||||
};
|
||||
@@ -1,424 +0,0 @@
|
||||
#include "COM/Com_CdcDecode.h"
|
||||
#include "COM/Com_CdcEncode.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
constexpr quint8 COM_CDC_CONST_PACKET_HEAD1 = 0xAA;
|
||||
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)
|
||||
{
|
||||
case Com_Type_UnKnow:
|
||||
return DataLength == Packet_len::Com_Len_UnKnow;
|
||||
|
||||
case Com_Type_HelloReq:
|
||||
return DataLength == Packet_len::Com_Len_HelloReq;
|
||||
|
||||
case Com_Type_HelloRsp:
|
||||
return DataLength == Packet_len::Com_Len_HelloRsp;
|
||||
|
||||
case Com_Type_Bitmap:
|
||||
return DataLength == Packet_len::Com_Len_Bitmap;
|
||||
|
||||
case Com_Type_FunctionKeyEvent:
|
||||
return DataLength == Packet_len::Com_Len_FunctionKeyEvent;
|
||||
|
||||
case Com_Type_LedState:
|
||||
return DataLength == Packet_len::Com_Len_LedState;
|
||||
|
||||
case Com_Type_TimeSync:
|
||||
return DataLength == Packet_len::Com_Len_TimeSync;
|
||||
|
||||
case Com_Type_ThemeRgb:
|
||||
return DataLength == Packet_len::Com_Len_ThemeRgb;
|
||||
|
||||
case Com_Type_Ack:
|
||||
return DataLength == Packet_len::Com_Len_Ack;
|
||||
|
||||
case Com_Type_Error:
|
||||
return DataLength == Packet_len::Com_Len_Error;
|
||||
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
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))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (static_cast<quint8>(ByteArray.at(0)) != COM_CDC_CONST_PACKET_HEAD1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (static_cast<quint8>(ByteArray.at(1)) != COM_CDC_CONST_PACKET_HEAD2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const quint8 DataLength = static_cast<quint8>(ByteArray.at(2));
|
||||
if (DataLength > COM_CDC_CONST_MAX_PAYLOAD_LENGTH)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const Packet_Type Type =
|
||||
static_cast<Packet_Type>(static_cast<quint8>(ByteArray.at(3)));
|
||||
if (!Com_Cdc_Func_IsKnownLengthValid(Type, DataLength))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const int FrameLength = COM_CDC_CONST_FRAME_OVERHEAD + static_cast<int>(DataLength);
|
||||
if (ByteArray.size() != FrameLength)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const QByteArray Body = ByteArray.left(FrameLength - 1);
|
||||
const quint8 Checksum = Com_Cdc_Func_CalcChecksum(Body);
|
||||
const quint8 ChecksumRx = static_cast<quint8>(ByteArray.at(FrameLength - 1));
|
||||
if (Checksum != ChecksumRx)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
p_Packet->Com_Packet_Head1 = COM_CDC_CONST_PACKET_HEAD1;
|
||||
p_Packet->Com_Packet_Head2 = COM_CDC_CONST_PACKET_HEAD2;
|
||||
p_Packet->len = DataLength;
|
||||
p_Packet->type = Type;
|
||||
p_Packet->data = ByteArray.mid(4, DataLength);
|
||||
return true;
|
||||
}
|
||||
|
||||
int Com_Cdc_Func_FindHead(const QByteArray& ByteArray)
|
||||
{
|
||||
for (int Index = 0; Index + 1 < ByteArray.size(); ++Index)
|
||||
{
|
||||
if ((static_cast<quint8>(ByteArray.at(Index)) == COM_CDC_CONST_PACKET_HEAD1) &&
|
||||
(static_cast<quint8>(ByteArray.at(Index + 1)) == COM_CDC_CONST_PACKET_HEAD2))
|
||||
{
|
||||
return Index;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void Com_Cdc_Func_KeepTailForNextScan(QByteArray* p_Buffer)
|
||||
{
|
||||
if (!p_Buffer->isEmpty() &&
|
||||
(static_cast<quint8>(p_Buffer->at(p_Buffer->size() - 1)) == COM_CDC_CONST_PACKET_HEAD1))
|
||||
{
|
||||
*p_Buffer = QByteArray(1, static_cast<char>(COM_CDC_CONST_PACKET_HEAD1));
|
||||
return;
|
||||
}
|
||||
|
||||
p_Buffer->clear();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
bool Com_Cdc_Func_ParseFrame(const QByteArray& ByteArray, Packet* p_Packet)
|
||||
{
|
||||
return Com_Cdc_Func_ParseFrameAtStart(ByteArray, p_Packet);
|
||||
}
|
||||
|
||||
bool Com_Cdc_Func_TryTakeFrame(QByteArray* p_Buffer, Packet* p_Packet)
|
||||
{
|
||||
if ((p_Buffer == nullptr) || (p_Packet == nullptr))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
if (p_Buffer->size() < 2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const int HeadIndex = Com_Cdc_Func_FindHead(*p_Buffer);
|
||||
if (HeadIndex < 0)
|
||||
{
|
||||
Com_Cdc_Func_KeepTailForNextScan(p_Buffer);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (HeadIndex > 0)
|
||||
{
|
||||
p_Buffer->remove(0, HeadIndex);
|
||||
}
|
||||
|
||||
if (p_Buffer->size() < 4)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const quint8 DataLength = static_cast<quint8>(p_Buffer->at(2));
|
||||
if (DataLength > COM_CDC_CONST_MAX_PAYLOAD_LENGTH)
|
||||
{
|
||||
p_Buffer->remove(0, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
const Packet_Type Type =
|
||||
static_cast<Packet_Type>(static_cast<quint8>(p_Buffer->at(3)));
|
||||
if (!Com_Cdc_Func_IsKnownLengthValid(Type, DataLength))
|
||||
{
|
||||
p_Buffer->remove(0, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
const int FrameLength = COM_CDC_CONST_FRAME_OVERHEAD + static_cast<int>(DataLength);
|
||||
if (p_Buffer->size() < FrameLength)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const QByteArray FrameBytes = p_Buffer->left(FrameLength);
|
||||
if (!Com_Cdc_Func_ParseFrameAtStart(FrameBytes, p_Packet))
|
||||
{
|
||||
p_Buffer->remove(0, 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
p_Buffer->remove(0, FrameLength);
|
||||
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;
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/QByteArray>
|
||||
|
||||
#include "COM/Com_Cdc.h"
|
||||
|
||||
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);
|
||||
@@ -1,159 +0,0 @@
|
||||
#include "COM/Com_CdcEncode.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
Packet Com_Cdc_Func_MakePacket(Packet_Type Type, const QByteArray& Data)
|
||||
{
|
||||
Packet PacketData;
|
||||
PacketData.type = Type;
|
||||
PacketData.len = static_cast<quint8>(Data.size());
|
||||
PacketData.data = Data;
|
||||
return PacketData;
|
||||
}
|
||||
|
||||
void Com_Cdc_Func_WriteLe16(QByteArray* p_Data, int Offset, quint16 Value)
|
||||
{
|
||||
(*p_Data)[Offset] = static_cast<char>(Value & 0x00FFU);
|
||||
(*p_Data)[Offset + 1] = static_cast<char>((Value >> 8) & 0x00FFU);
|
||||
}
|
||||
|
||||
void Com_Cdc_Func_WriteLe32(QByteArray* p_Data, int Offset, quint32 Value)
|
||||
{
|
||||
for (int Index = 0; Index < 4; ++Index)
|
||||
{
|
||||
(*p_Data)[Offset + Index] = static_cast<char>((Value >> (Index * 8)) & 0xFFU);
|
||||
}
|
||||
}
|
||||
|
||||
void Com_Cdc_Func_WriteLe64(QByteArray* p_Data, int Offset, quint64 Value)
|
||||
{
|
||||
for (int Index = 0; Index < 8; ++Index)
|
||||
{
|
||||
(*p_Data)[Offset + Index] = static_cast<char>((Value >> (Index * 8)) & 0xFFULL);
|
||||
}
|
||||
}
|
||||
|
||||
QByteArray Com_Cdc_Func_FitPayload(const QByteArray& Data, int ExpectedLength)
|
||||
{
|
||||
QByteArray Payload = Data.left(ExpectedLength);
|
||||
if (Payload.size() < ExpectedLength)
|
||||
{
|
||||
Payload.append(ExpectedLength - Payload.size(), 0);
|
||||
}
|
||||
return Payload;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
quint8 Com_Cdc_Func_CalcChecksum(const QByteArray& ByteArray)
|
||||
{
|
||||
quint8 Checksum = 0;
|
||||
|
||||
for (int Index = 0; Index < ByteArray.size(); ++Index)
|
||||
{
|
||||
const quint8 ByteValue = static_cast<quint8>(ByteArray.at(Index));
|
||||
Checksum = static_cast<quint8>(Checksum ^ ByteValue);
|
||||
}
|
||||
|
||||
return Checksum;
|
||||
}
|
||||
|
||||
QByteArray Com_Cdc_Func_BuildFrame(const Packet& PacketData)
|
||||
{
|
||||
if (PacketData.data.size() > 0xFF)
|
||||
{
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
QByteArray ByteArray;
|
||||
const quint8 DataLength = static_cast<quint8>(PacketData.data.size());
|
||||
|
||||
ByteArray.append(static_cast<char>(PacketData.Com_Packet_Head1));
|
||||
ByteArray.append(static_cast<char>(PacketData.Com_Packet_Head2));
|
||||
ByteArray.append(static_cast<char>(DataLength));
|
||||
ByteArray.append(static_cast<char>(PacketData.type));
|
||||
ByteArray.append(PacketData.data);
|
||||
|
||||
const quint8 Checksum = Com_Cdc_Func_CalcChecksum(ByteArray);
|
||||
ByteArray.append(static_cast<char>(Checksum));
|
||||
return ByteArray;
|
||||
}
|
||||
|
||||
QByteArray Com_Cdc_Func_BuildHelloReq(const Packet_HelloReq& PacketData)
|
||||
{
|
||||
QByteArray Payload(Packet_len::Com_Len_HelloReq, 0);
|
||||
Payload[0] = static_cast<char>(PacketData.ProtocolVersion);
|
||||
return Com_Cdc_Func_BuildFrame(Com_Cdc_Func_MakePacket(Com_Type_HelloReq, Payload));
|
||||
}
|
||||
|
||||
QByteArray Com_Cdc_Func_BuildHelloRsp(const Packet_HelloRsp& PacketData)
|
||||
{
|
||||
QByteArray Payload(Packet_len::Com_Len_HelloRsp, 0);
|
||||
Payload[0] = static_cast<char>(PacketData.ProtocolVersion);
|
||||
Com_Cdc_Func_WriteLe16(&Payload, 1, PacketData.VendorId);
|
||||
Com_Cdc_Func_WriteLe16(&Payload, 3, PacketData.ProductId);
|
||||
Payload[5] = static_cast<char>(PacketData.FirmwareMajor);
|
||||
Payload[6] = static_cast<char>(PacketData.FirmwareMinor);
|
||||
Com_Cdc_Func_WriteLe16(&Payload, 7, PacketData.CapabilityFlags);
|
||||
return Com_Cdc_Func_BuildFrame(Com_Cdc_Func_MakePacket(Com_Type_HelloRsp, Payload));
|
||||
}
|
||||
|
||||
QByteArray Com_Cdc_Func_BuildBitmap(const Packet_Bitmap& PacketData)
|
||||
{
|
||||
return Com_Cdc_Func_BuildFrame(
|
||||
Com_Cdc_Func_MakePacket(
|
||||
Com_Type_Bitmap,
|
||||
Com_Cdc_Func_FitPayload(PacketData.UsageBitmap, Packet_len::Com_Len_Bitmap)));
|
||||
}
|
||||
|
||||
QByteArray Com_Cdc_Func_BuildFunctionKeyEvent(const Packet_FunctionKeyEvent& PacketData)
|
||||
{
|
||||
QByteArray Payload(Packet_len::Com_Len_FunctionKeyEvent, 0);
|
||||
Com_Cdc_Func_WriteLe16(&Payload, 0, PacketData.Usage);
|
||||
Payload[2] = static_cast<char>(PacketData.Action);
|
||||
return Com_Cdc_Func_BuildFrame(
|
||||
Com_Cdc_Func_MakePacket(Com_Type_FunctionKeyEvent, Payload));
|
||||
}
|
||||
|
||||
QByteArray Com_Cdc_Func_BuildLedState(const Packet_LedState& PacketData)
|
||||
{
|
||||
QByteArray Payload(Packet_len::Com_Len_LedState, 0);
|
||||
Payload[0] = static_cast<char>(PacketData.LedMask);
|
||||
return Com_Cdc_Func_BuildFrame(Com_Cdc_Func_MakePacket(Com_Type_LedState, Payload));
|
||||
}
|
||||
|
||||
QByteArray Com_Cdc_Func_BuildTimeSync(const Packet_TimeSync& PacketData)
|
||||
{
|
||||
QByteArray Payload(Packet_len::Com_Len_TimeSync, 0);
|
||||
Payload[0] = static_cast<char>(PacketData.Version);
|
||||
Payload[1] = static_cast<char>(PacketData.Flags);
|
||||
Com_Cdc_Func_WriteLe16(&Payload, 2, PacketData.TimezoneMin);
|
||||
Com_Cdc_Func_WriteLe64(&Payload, 4, PacketData.UtcMs);
|
||||
Com_Cdc_Func_WriteLe32(&Payload, 12, PacketData.AccuracyMs);
|
||||
return Com_Cdc_Func_BuildFrame(Com_Cdc_Func_MakePacket(Com_Type_TimeSync, Payload));
|
||||
}
|
||||
|
||||
QByteArray Com_Cdc_Func_BuildThemeRgb(const Packet_ThemeRgb& PacketData)
|
||||
{
|
||||
QByteArray Payload(Packet_len::Com_Len_ThemeRgb, 0);
|
||||
Payload[0] = static_cast<char>(PacketData.Red);
|
||||
Payload[1] = static_cast<char>(PacketData.Green);
|
||||
Payload[2] = static_cast<char>(PacketData.Blue);
|
||||
return Com_Cdc_Func_BuildFrame(Com_Cdc_Func_MakePacket(Com_Type_ThemeRgb, Payload));
|
||||
}
|
||||
|
||||
QByteArray Com_Cdc_Func_BuildAck(const Packet_Ack& PacketData)
|
||||
{
|
||||
QByteArray Payload(Packet_len::Com_Len_Ack, 0);
|
||||
Payload[0] = static_cast<char>(PacketData.AckedType);
|
||||
return Com_Cdc_Func_BuildFrame(Com_Cdc_Func_MakePacket(Com_Type_Ack, Payload));
|
||||
}
|
||||
|
||||
QByteArray Com_Cdc_Func_BuildError(const Packet_Error& PacketData)
|
||||
{
|
||||
QByteArray Payload(Packet_len::Com_Len_Error, 0);
|
||||
Payload[0] = static_cast<char>(PacketData.ErrorType);
|
||||
Payload[1] = static_cast<char>(PacketData.ErrorCode);
|
||||
return Com_Cdc_Func_BuildFrame(Com_Cdc_Func_MakePacket(Com_Type_Error, Payload));
|
||||
}
|
||||
@@ -1,19 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/QByteArray>
|
||||
|
||||
#include "COM/Com_Cdc.h"
|
||||
|
||||
quint8 Com_Cdc_Func_CalcChecksum(const QByteArray& ByteArray);
|
||||
|
||||
QByteArray Com_Cdc_Func_BuildFrame(const Packet& PacketData);
|
||||
|
||||
QByteArray Com_Cdc_Func_BuildHelloReq(const Packet_HelloReq& PacketData);
|
||||
QByteArray Com_Cdc_Func_BuildHelloRsp(const Packet_HelloRsp& PacketData);
|
||||
QByteArray Com_Cdc_Func_BuildBitmap(const Packet_Bitmap& PacketData);
|
||||
QByteArray Com_Cdc_Func_BuildFunctionKeyEvent(const Packet_FunctionKeyEvent& PacketData);
|
||||
QByteArray Com_Cdc_Func_BuildLedState(const Packet_LedState& PacketData);
|
||||
QByteArray Com_Cdc_Func_BuildTimeSync(const Packet_TimeSync& PacketData);
|
||||
QByteArray Com_Cdc_Func_BuildThemeRgb(const Packet_ThemeRgb& PacketData);
|
||||
QByteArray Com_Cdc_Func_BuildAck(const Packet_Ack& PacketData);
|
||||
QByteArray Com_Cdc_Func_BuildError(const Packet_Error& PacketData);
|
||||
@@ -1,10 +1,20 @@
|
||||
#include "COM/Com_PbCodec.h"
|
||||
|
||||
#include "COM/Com_CdcEncode.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
|
||||
quint32 Com_Pb_Func_CalcChecksum(const QByteArray& ByteArray)
|
||||
{
|
||||
quint32 Checksum = 0;
|
||||
|
||||
for (int Index = 0; Index < ByteArray.size(); ++Index)
|
||||
{
|
||||
Checksum ^= static_cast<quint8>(ByteArray.at(Index));
|
||||
}
|
||||
|
||||
return Checksum & 0xFFU;
|
||||
}
|
||||
|
||||
quint32 Com_Pb_Func_CalcFrameChecksum(const keyboard::cdc::CdcFrame& Frame)
|
||||
{
|
||||
QByteArray ByteArray;
|
||||
@@ -14,7 +24,7 @@ quint32 Com_Pb_Func_CalcFrameChecksum(const keyboard::cdc::CdcFrame& Frame)
|
||||
ByteArray.append(static_cast<char>(Frame.type()));
|
||||
ByteArray.append(QByteArray::fromStdString(Frame.payload()));
|
||||
|
||||
return Com_Cdc_Func_CalcChecksum(ByteArray);
|
||||
return Com_Pb_Func_CalcChecksum(ByteArray);
|
||||
}
|
||||
|
||||
keyboard::cdc::CdcFrame Com_Pb_Func_BuildFrame(
|
||||
|
||||
@@ -94,11 +94,6 @@
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="COM\Com_Cdc.h" />
|
||||
<ClCompile Include="COM\Com_CdcEncode.cpp" />
|
||||
<ClInclude Include="COM\Com_CdcEncode.h" />
|
||||
<ClCompile Include="COM\Com_CdcDecode.cpp" />
|
||||
<ClInclude Include="COM\Com_CdcDecode.h" />
|
||||
<ClCompile Include="DRI\Dri_Cdc.cpp" />
|
||||
<ClCompile Include="DRI\GATT\Dri_Gatt.cpp" />
|
||||
<ClInclude Include="DRI\GATT\Dri_Gatt.h" />
|
||||
|
||||
@@ -23,21 +23,6 @@
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="COM\Com_Cdc.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="COM\Com_CdcEncode.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="COM\Com_CdcEncode.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="COM\Com_CdcDecode.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClInclude Include="COM\Com_CdcDecode.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClCompile Include="DRI\Dri_Cdc.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
|
||||
@@ -20,69 +20,25 @@ The COM layer should not:
|
||||
|
||||
## Current file roles
|
||||
|
||||
### `Com_Cdc.h`
|
||||
### `Com_PbCodec.h/.cpp`
|
||||
|
||||
Owns the packet model:
|
||||
Owns the protobuf-side wrapper:
|
||||
|
||||
- packet types
|
||||
- fixed payload lengths
|
||||
- payload structs
|
||||
- full protobuf frame serialize / parse
|
||||
- checksum validation
|
||||
- typed helper entry points like hello request / response
|
||||
|
||||
### `Com_CdcEncode.h/.cpp`
|
||||
### `keyboard.pb.h/.cc`
|
||||
|
||||
Owns the write direction:
|
||||
Own the generated protocol model:
|
||||
|
||||
- checksum
|
||||
- full frame build
|
||||
- typed payload encode
|
||||
|
||||
### `Com_CdcDecode.h/.cpp`
|
||||
|
||||
Owns the read direction:
|
||||
|
||||
- full frame parse
|
||||
- stream extraction
|
||||
- typed payload decode
|
||||
- outer `CdcFrame`
|
||||
- business `CdcPacketBody`
|
||||
- all message definitions
|
||||
|
||||
## Completed nodes
|
||||
|
||||
### Node 1: legacy frame encode baseline
|
||||
|
||||
Already present before this step:
|
||||
|
||||
- build full frame
|
||||
- build all typed packets
|
||||
|
||||
### Node 2: typed packet decode completion
|
||||
|
||||
Files updated in this step:
|
||||
|
||||
- `KeyBorad/KeyBorad/COM/Com_CdcDecode.h`
|
||||
- `KeyBorad/KeyBorad/COM/Com_CdcDecode.cpp`
|
||||
|
||||
Design notes:
|
||||
|
||||
- keep decode logic flat and explicit
|
||||
- one helper for little-endian reads
|
||||
- one helper for type + length validation
|
||||
- one decode function per packet type
|
||||
|
||||
Implemented behavior:
|
||||
|
||||
- parse frame header and checksum
|
||||
- extract frames from a byte stream
|
||||
- decode:
|
||||
- `HelloReq`
|
||||
- `HelloRsp`
|
||||
- `Bitmap`
|
||||
- `FunctionKeyEvent`
|
||||
- `LedState`
|
||||
- `TimeSync`
|
||||
- `ThemeRgb`
|
||||
- `Ack`
|
||||
- `Error`
|
||||
|
||||
### Node 3: protobuf thin wrapper
|
||||
### Node 1: protobuf thin wrapper
|
||||
|
||||
Files added in this step:
|
||||
|
||||
@@ -102,16 +58,32 @@ Implemented behavior:
|
||||
- build `HelloReq` using generated protobuf types
|
||||
- parse `HelloRsp` using generated protobuf types
|
||||
|
||||
Current limit:
|
||||
### Node 2: remove legacy manual codec
|
||||
|
||||
- not wired into the project yet
|
||||
- protobuf runtime include and link setup is still pending
|
||||
Files removed in this step:
|
||||
|
||||
- `KeyBorad/KeyBorad/COM/Com_Cdc.h`
|
||||
- `KeyBorad/KeyBorad/COM/Com_CdcEncode.h`
|
||||
- `KeyBorad/KeyBorad/COM/Com_CdcEncode.cpp`
|
||||
- `KeyBorad/KeyBorad/COM/Com_CdcDecode.h`
|
||||
- `KeyBorad/KeyBorad/COM/Com_CdcDecode.cpp`
|
||||
|
||||
Design notes:
|
||||
|
||||
- no dual path
|
||||
- no hand-written payload encode/decode path left behind
|
||||
- protobuf is now the only packet encode/decode direction
|
||||
|
||||
Implemented behavior:
|
||||
|
||||
- checksum moved into `Com_PbCodec.cpp`
|
||||
- old manual packet structs and old codec files removed
|
||||
|
||||
## COM done criteria
|
||||
|
||||
For the current project stage, COM is considered done when:
|
||||
|
||||
1. every supported packet can be built
|
||||
2. every supported packet can be parsed
|
||||
3. stream extraction is stable
|
||||
4. higher layers no longer need to know byte offsets
|
||||
1. the protocol source is the `.proto` file
|
||||
2. generated `.pb.*` files exist
|
||||
3. `Com_PbCodec` provides thin project-facing helpers
|
||||
4. no legacy hand-written packet codec remains
|
||||
|
||||
Reference in New Issue
Block a user