From 14bfeff8a7d3902e7dbe12b5cd8bfe1fdd9f5582 Mon Sep 17 00:00:00 2001 From: stli Date: Sat, 11 Apr 2026 09:31:49 +0800 Subject: [PATCH] Simplify CDC driver layer --- KeyBorad/KeyBorad/DRI/Dri_Cdc.cpp | 196 +++++++----------------------- KeyBorad/KeyBorad/DRI/Dri_Cdc.h | 21 ++-- docs/host_dri_rebuild.md | 59 +++++++++ 3 files changed, 115 insertions(+), 161 deletions(-) create mode 100644 docs/host_dri_rebuild.md diff --git a/KeyBorad/KeyBorad/DRI/Dri_Cdc.cpp b/KeyBorad/KeyBorad/DRI/Dri_Cdc.cpp index 72b1cbb..5e644ca 100644 --- a/KeyBorad/KeyBorad/DRI/Dri_Cdc.cpp +++ b/KeyBorad/KeyBorad/DRI/Dri_Cdc.cpp @@ -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 -#include #include #include -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(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_Enum() { QVector PortList; const QList 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,130 +20,89 @@ QVector 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 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) + 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); + p_Serial->setStopBits(QSerialPort::OneStop); + p_Serial->setFlowControl(QSerialPort::NoFlowControl); + + if (!p_Serial->open(QIODevice::ReadWrite)) { - const Dri_Cdc_Struct_PortInfo& PortInfo = PortList.at(Index); - - QSerialPort* p_Serial = new QSerialPort(); - p_Serial->setPortName(PortInfo.PortName); - p_Serial->setBaudRate(Config.BaudRate); - p_Serial->setDataBits(QSerialPort::Data8); - p_Serial->setParity(QSerialPort::NoParity); - p_Serial->setStopBits(QSerialPort::OneStop); - p_Serial->setFlowControl(QSerialPort::NoFlowControl); - - if (!p_Serial->open(QIODevice::ReadWrite)) - { - delete p_Serial; - continue; - } - - 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(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; - return true; - } - } - - p_Serial->close(); delete p_Serial; + return false; } - return false; + p_Port->p_Port = p_Serial; + p_Port->IsOpened = true; + p_Port->PortName = PortName; + return true; } -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); } diff --git a/KeyBorad/KeyBorad/DRI/Dri_Cdc.h b/KeyBorad/KeyBorad/DRI/Dri_Cdc.h index c3e8dc5..46af124 100644 --- a/KeyBorad/KeyBorad/DRI/Dri_Cdc.h +++ b/KeyBorad/KeyBorad/DRI/Dri_Cdc.h @@ -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_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); diff --git a/docs/host_dri_rebuild.md b/docs/host_dri_rebuild.md new file mode 100644 index 0000000..b32130c --- /dev/null +++ b/docs/host_dri_rebuild.md @@ -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