Simplify CDC driver layer

This commit is contained in:
2026-04-11 09:31:49 +08:00
parent c71c26bf8f
commit 14bfeff8a7
3 changed files with 115 additions and 161 deletions

View File

@@ -1,75 +1,15 @@
#include "DRI/Dri_Cdc.h"
#include "COM/Com_Cdc.h"
#include "COM/Com_CdcDecode.h"
#include "COM/Com_CdcEncode.h"
#include <QtCore/QElapsedTimer>
#include <QtCore/QtGlobal>
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
namespace
{
bool Dri_Cdc_Func_TryReadFrame(
QSerialPort* p_Serial,
QByteArray* p_ReadBuffer,
int TimeoutMs,
Packet* p_Packet)
{
if ((p_Serial == nullptr) || (p_ReadBuffer == nullptr) || (p_Packet == nullptr))
{
return false;
}
if (Com_Cdc_Func_TryTakeFrame(p_ReadBuffer, p_Packet))
{
return true;
}
QElapsedTimer Timer;
Timer.start();
while (Timer.elapsed() < TimeoutMs)
{
const int RemainingMs = TimeoutMs - static_cast<int>(Timer.elapsed());
const int WaitMs = qMin(20, RemainingMs);
if (WaitMs <= 0)
{
break;
}
if (!p_Serial->waitForReadyRead(WaitMs))
{
continue;
}
const QByteArray ReadBytes = p_Serial->readAll();
if (!ReadBytes.isEmpty())
{
p_ReadBuffer->append(ReadBytes);
}
if (Com_Cdc_Func_TryTakeFrame(p_ReadBuffer, p_Packet))
{
return true;
}
}
return false;
}
} // namespace
QVector<Dri_Cdc_Struct_PortInfo> Dri_Cdc_Enum()
{
QVector<Dri_Cdc_Struct_PortInfo> PortList;
const QList<QSerialPortInfo> InfoList = QSerialPortInfo::availablePorts();
for (int Index = 0; Index < InfoList.size(); ++Index)
for (const QSerialPortInfo& Info : InfoList)
{
const QSerialPortInfo& Info = InfoList.at(Index);
Dri_Cdc_Struct_PortInfo PortInfo;
PortInfo.PortName = Info.portName();
PortInfo.Description = Info.description();
@@ -80,41 +20,40 @@ QVector<Dri_Cdc_Struct_PortInfo> Dri_Cdc_Enum()
return PortList;
}
void Dri_Cdc_Deinit(Dri_Cdc_Struct_Port* p_Port)
void Dri_Cdc_Close(Dri_Cdc_Struct_Port* p_Port)
{
if (p_Port == nullptr)
{
return;
}
if (p_Port->p_Port != nullptr)
{
if (p_Port->p_Port->isOpen())
{
p_Port->p_Port->close();
}
delete p_Port->p_Port;
}
*p_Port = Dri_Cdc_Struct_Port();
}
bool Dri_Cdc_Init(
bool Dri_Cdc_Open(
Dri_Cdc_Struct_Port* p_Port,
const Dri_Cdc_Struct_InitConfig& Config)
const QString& PortName,
const Dri_Cdc_Struct_OpenConfig& Config)
{
Dri_Cdc_Deinit(p_Port);
const QVector<Dri_Cdc_Struct_PortInfo> PortList = Dri_Cdc_Enum();
if (PortList.isEmpty())
if ((p_Port == nullptr) || PortName.trimmed().isEmpty())
{
return false;
}
Packet_HelloReq HelloReq;
const QByteArray HelloReqFrame = Com_Cdc_Func_BuildHelloReq(HelloReq);
Dri_Cdc_Close(p_Port);
for (int Index = 0; Index < PortList.size(); ++Index)
{
const Dri_Cdc_Struct_PortInfo& PortInfo = PortList.at(Index);
QSerialPort* p_Serial = new QSerialPort();
p_Serial->setPortName(PortInfo.PortName);
QSerialPort* const p_Serial = new QSerialPort();
p_Serial->setPortName(PortName);
p_Serial->setBaudRate(Config.BaudRate);
p_Serial->setDataBits(QSerialPort::Data8);
p_Serial->setParity(QSerialPort::NoParity);
@@ -124,86 +63,46 @@ bool Dri_Cdc_Init(
if (!p_Serial->open(QIODevice::ReadWrite))
{
delete p_Serial;
continue;
return false;
}
p_Serial->readAll();
if (p_Serial->write(HelloReqFrame) != HelloReqFrame.size())
{
p_Serial->close();
delete p_Serial;
continue;
}
if (!p_Serial->waitForBytesWritten(Config.HandshakeTimeoutMs))
{
p_Serial->close();
delete p_Serial;
continue;
}
QByteArray HandshakeBuffer;
QElapsedTimer Timer;
Timer.start();
while (Timer.elapsed() < Config.HandshakeTimeoutMs)
{
Packet PacketData;
const int RemainingMs =
Config.HandshakeTimeoutMs - static_cast<int>(Timer.elapsed());
if (!Dri_Cdc_Func_TryReadFrame(
p_Serial,
&HandshakeBuffer,
qMin(20, RemainingMs),
&PacketData))
{
continue;
}
if (PacketData.type == Com_Type_HelloRsp)
{
p_Port->p_Port = p_Serial;
p_Port->IsOpened = true;
p_Port->PortName = PortInfo.PortName;
p_Port->ReadBuffer = HandshakeBuffer;
p_Port->PortName = PortName;
return true;
}
}
p_Serial->close();
delete p_Serial;
}
return false;
}
bool Dri_Cdc_Read(
bool Dri_Cdc_ReadBytes(
Dri_Cdc_Struct_Port* p_Port,
QByteArray& ByteArray)
QByteArray* p_ByteArray,
int TimeoutMs)
{
ByteArray.clear();
if (p_ByteArray != nullptr)
{
p_ByteArray->clear();
}
if (!p_Port->IsOpened || (p_Port->p_Port == nullptr))
if ((p_Port == nullptr) || (p_ByteArray == nullptr) ||
!p_Port->IsOpened || (p_Port->p_Port == nullptr))
{
return false;
}
Packet PacketData;
if (Com_Cdc_Func_TryTakeFrame(&p_Port->ReadBuffer, &PacketData) ||
Dri_Cdc_Func_TryReadFrame(p_Port->p_Port, &p_Port->ReadBuffer, 50, &PacketData))
if (TimeoutMs > 0)
{
ByteArray = Com_Cdc_Func_BuildFrame(PacketData);
return !ByteArray.isEmpty();
p_Port->p_Port->waitForReadyRead(TimeoutMs);
}
return false;
*p_ByteArray = p_Port->p_Port->readAll();
return !p_ByteArray->isEmpty();
}
bool Dri_Cdc_Write(
bool Dri_Cdc_WriteBytes(
Dri_Cdc_Struct_Port* p_Port,
const QByteArray& ByteArray)
const QByteArray& ByteArray,
int TimeoutMs)
{
if (!p_Port->IsOpened || (p_Port->p_Port == nullptr))
if ((p_Port == nullptr) || !p_Port->IsOpened || (p_Port->p_Port == nullptr))
{
return false;
}
@@ -218,10 +117,5 @@ bool Dri_Cdc_Write(
return false;
}
if (!p_Port->p_Port->waitForBytesWritten(200))
{
return false;
}
return true;
return p_Port->p_Port->waitForBytesWritten(TimeoutMs);
}

View File

@@ -13,10 +13,9 @@ struct Dri_Cdc_Struct_PortInfo
QString Manufacturer;
};
struct Dri_Cdc_Struct_InitConfig
struct Dri_Cdc_Struct_OpenConfig
{
qint32 BaudRate = 115200;
int HandshakeTimeoutMs = 200;
};
struct Dri_Cdc_Struct_Port
@@ -24,17 +23,19 @@ struct Dri_Cdc_Struct_Port
QSerialPort* p_Port = nullptr;
bool IsOpened = false;
QString PortName;
QByteArray ReadBuffer;
};
QVector<Dri_Cdc_Struct_PortInfo> Dri_Cdc_Enum();
void Dri_Cdc_Deinit(Dri_Cdc_Struct_Port* p_Port);
bool Dri_Cdc_Init(
void Dri_Cdc_Close(Dri_Cdc_Struct_Port* p_Port);
bool Dri_Cdc_Open(
Dri_Cdc_Struct_Port* p_Port,
const Dri_Cdc_Struct_InitConfig& Config);
bool Dri_Cdc_Read(
const QString& PortName,
const Dri_Cdc_Struct_OpenConfig& Config);
bool Dri_Cdc_ReadBytes(
Dri_Cdc_Struct_Port* p_Port,
QByteArray& ByteArray);
bool Dri_Cdc_Write(
QByteArray* p_ByteArray,
int TimeoutMs);
bool Dri_Cdc_WriteBytes(
Dri_Cdc_Struct_Port* p_Port,
const QByteArray& ByteArray);
const QByteArray& ByteArray,
int TimeoutMs);

59
docs/host_dri_rebuild.md Normal file
View File

@@ -0,0 +1,59 @@
# Host DRI Rebuild
## Goal
Keep the device runtime layer small and transport-only.
The DRI layer should:
- enumerate endpoints
- open and close connections
- read raw bytes
- write raw bytes
The DRI layer should not:
- parse frames
- manage protocol state
- decide handshake success
## Completed Nodes
### Node 1: GATT placeholder
Files:
- `KeyBorad/KeyBorad/DRI/GATT/Dri_Gatt.h`
- `KeyBorad/KeyBorad/DRI/GATT/Dri_Gatt.cpp`
Design notes:
- reserves the BLE transport position early
- keeps the implementation small for now
- avoids mixing GATT transport with logic concerns
### Node 2: CDC transport cleanup
Files updated in this step:
- `KeyBorad/KeyBorad/DRI/Dri_Cdc.h`
- `KeyBorad/KeyBorad/DRI/Dri_Cdc.cpp`
Design notes:
- remove frame parsing from the driver
- remove handshake ownership from the driver
- keep only enumerate/open/close/read-bytes/write-bytes
Implemented behavior:
- list ports with `Dri_Cdc_Enum()`
- open one port with `Dri_Cdc_Open()`
- close one port with `Dri_Cdc_Close()`
- read raw bytes with timeout
- write raw bytes with timeout
## Next DRI nodes
- implement real GATT discovery and notify/write path
- provide one simple connection summary for logic layer