diff --git a/KeyBorad/KeyBorad/LOGIC/Lgc_Session.cpp b/KeyBorad/KeyBorad/LOGIC/Lgc_Session.cpp index d7509fd..7af39cf 100644 --- a/KeyBorad/KeyBorad/LOGIC/Lgc_Session.cpp +++ b/KeyBorad/KeyBorad/LOGIC/Lgc_Session.cpp @@ -1,5 +1,50 @@ #include "LOGIC/Lgc_Session.h" +#include "COM/Com_ProtoCodec.h" + +#include + +namespace +{ + +bool Lgc_Func_TryHandshakeCdcPort( + Dri_Cdc_Struct_Port* p_Port, + QByteArray* p_ReadBuffer, + Packet_HelloRsp* p_HelloRsp) +{ + const QByteArray HelloReqFrame = Com_ProtoCodec_BuildHelloReq(); + if (!Dri_Cdc_WriteBytes(p_Port, HelloReqFrame, 200)) + { + return false; + } + + QElapsedTimer Timer; + Timer.start(); + while (Timer.elapsed() < 200) + { + QByteArray ReadBytes; + if (Dri_Cdc_ReadBytes(p_Port, &ReadBytes, 20) && !ReadBytes.isEmpty()) + { + p_ReadBuffer->append(ReadBytes); + } + + Packet PacketData; + while (Com_ProtoCodec_TryTakeFrame(p_ReadBuffer, &PacketData)) + { + if (!Com_ProtoCodec_ParseHelloRsp(PacketData, p_HelloRsp)) + { + continue; + } + + return true; + } + } + + return false; +} + +} // namespace + void Lgc_Session_Init(Lgc_Session* p_Session) { if (p_Session == nullptr) @@ -17,24 +62,48 @@ void Lgc_Session_Close(Lgc_Session* p_Session) return; } - Dri_Cdc_Deinit(&p_Session->CdcPort); + Dri_Cdc_Close(&p_Session->CdcPort); Dri_Gatt_Deinit(&p_Session->GattPort); + p_Session->CdcReadBuffer.clear(); p_Session->IsStarted = false; + p_Session->IsHandshakeDone = false; + p_Session->ActiveTransport = Lgc_TransportType::None; } bool Lgc_Session_TryStartCdc( Lgc_Session* p_Session, - const Dri_Cdc_Struct_InitConfig& Config) + const Dri_Cdc_Struct_OpenConfig& Config, + Packet_HelloRsp* p_HelloRsp) { - if (p_Session == nullptr) + if ((p_Session == nullptr) || (p_HelloRsp == nullptr)) { return false; } - if (Dri_Cdc_Init(&p_Session->CdcPort, Config)) + const QVector PortList = Dri_Cdc_Enum(); + for (const Dri_Cdc_Struct_PortInfo& PortInfo : PortList) { - p_Session->IsStarted = true; - return true; + Dri_Cdc_Struct_Port Port; + if (!Dri_Cdc_Open(&Port, PortInfo.PortName, Config)) + { + continue; + } + + QByteArray ReadBuffer; + Packet_HelloRsp HelloRsp; + if (Lgc_Func_TryHandshakeCdcPort(&Port, &ReadBuffer, &HelloRsp)) + { + Dri_Cdc_Close(&p_Session->CdcPort); + p_Session->CdcPort = Port; + p_Session->CdcReadBuffer = ReadBuffer; + p_Session->IsStarted = true; + p_Session->IsHandshakeDone = true; + p_Session->ActiveTransport = Lgc_TransportType::Cdc; + *p_HelloRsp = HelloRsp; + return true; + } + + Dri_Cdc_Close(&Port); } return false; @@ -50,8 +119,34 @@ bool Lgc_Session_TryStartGatt(Lgc_Session* p_Session) if (Dri_Gatt_Init(&p_Session->GattPort)) { p_Session->IsStarted = true; + p_Session->ActiveTransport = Lgc_TransportType::Gatt; return true; } return false; } + +bool Lgc_Session_ReadNextPacket( + Lgc_Session* p_Session, + Packet* p_Packet) +{ + if ((p_Session == nullptr) || (p_Packet == nullptr)) + { + return false; + } + + *p_Packet = Packet(); + + if (p_Session->ActiveTransport == Lgc_TransportType::Cdc) + { + QByteArray ReadBytes; + if (Dri_Cdc_ReadBytes(&p_Session->CdcPort, &ReadBytes, 0) && !ReadBytes.isEmpty()) + { + p_Session->CdcReadBuffer.append(ReadBytes); + } + + return Com_ProtoCodec_TryTakeFrame(&p_Session->CdcReadBuffer, p_Packet); + } + + return false; +} diff --git a/KeyBorad/KeyBorad/LOGIC/Lgc_Session.h b/KeyBorad/KeyBorad/LOGIC/Lgc_Session.h index 95b1eee..04c7d1f 100644 --- a/KeyBorad/KeyBorad/LOGIC/Lgc_Session.h +++ b/KeyBorad/KeyBorad/LOGIC/Lgc_Session.h @@ -1,18 +1,27 @@ #pragma once +#include "COM/Com_Cdc.h" #include "DRI/Dri_Cdc.h" #include "DRI/GATT/Dri_Gatt.h" +#include "LOGIC/Lgc_State.h" struct Lgc_Session { Dri_Cdc_Struct_Port CdcPort; Dri_Gatt_Struct_Port GattPort; + QByteArray CdcReadBuffer; bool IsStarted = false; + bool IsHandshakeDone = false; + Lgc_TransportType ActiveTransport = Lgc_TransportType::None; }; void Lgc_Session_Init(Lgc_Session* p_Session); void Lgc_Session_Close(Lgc_Session* p_Session); bool Lgc_Session_TryStartCdc( Lgc_Session* p_Session, - const Dri_Cdc_Struct_InitConfig& Config); + const Dri_Cdc_Struct_OpenConfig& Config, + Packet_HelloRsp* p_HelloRsp); bool Lgc_Session_TryStartGatt(Lgc_Session* p_Session); +bool Lgc_Session_ReadNextPacket( + Lgc_Session* p_Session, + Packet* p_Packet); diff --git a/docs/host_logic_rebuild.md b/docs/host_logic_rebuild.md index c1e01b0..50bd357 100644 --- a/docs/host_logic_rebuild.md +++ b/docs/host_logic_rebuild.md @@ -47,16 +47,19 @@ Design notes: ### Node 3: session handshake path -Files planned next: +Files completed in this step: - `KeyBorad/KeyBorad/LOGIC/Lgc_Session.h` - `KeyBorad/KeyBorad/LOGIC/Lgc_Session.cpp` -Target behavior: +Implemented behavior: - try CDC handshake +- send `HelloReq` +- wait for `HelloRsp` - store the active transport -- read next parsed packet +- keep a stream buffer for CDC bytes +- return the next parsed packet to upper layers ### Node 4: core facade