From 3c47fc56972315c276f2945dd718c39ef050ae97 Mon Sep 17 00:00:00 2001 From: Fanda Vacek Date: Tue, 5 Nov 2024 15:57:45 +0100 Subject: [PATCH] Fix client protocol type identification from first rpc frame received --- .../include/shv/chainpack/rpcdriver.h | 7 ++-- .../include/shv/chainpack/socketrpcdriver.h | 1 + libshvchainpack/src/rpcdriver.cpp | 35 +++++-------------- libshvchainpack/src/socketrpcdriver.cpp | 21 +++++++++++ libshviotqt/src/rpc/socketrpcconnection.cpp | 2 +- 5 files changed, 36 insertions(+), 30 deletions(-) diff --git a/libshvchainpack/include/shv/chainpack/rpcdriver.h b/libshvchainpack/include/shv/chainpack/rpcdriver.h index a77bd42e3..960fc8148 100644 --- a/libshvchainpack/include/shv/chainpack/rpcdriver.h +++ b/libshvchainpack/include/shv/chainpack/rpcdriver.h @@ -27,18 +27,19 @@ class SHVCHAINPACK_DECL_EXPORT RpcDriver virtual bool isOpen() = 0; virtual void writeFrameData(const std::string &frame_data) = 0; - virtual void onFrameDataRead(const std::string &frame_data); + void processRpcFrame(RpcFrame &&frame); virtual void onRpcFrameReceived(RpcFrame &&frame); virtual void onParseDataException(const shv::chainpack::ParseException &e) = 0; virtual void onRpcMessageReceived(const shv::chainpack::RpcMessage &msg) = 0; void setClientProtocolType(Rpc::ProtocolType pt) { m_clientProtocolType = pt; } +protected: + /// We must remember recent message protocol type to support legacy CPON clients + Rpc::ProtocolType m_clientProtocolType = Rpc::ProtocolType::Invalid; private: // NOLINTNEXTLINE(cppcoreguidelines-avoid-non-const-global-variables) static int s_defaultRpcTimeoutMsec; - /// We must remember recent message protocol type to support legacy CPON clients - Rpc::ProtocolType m_clientProtocolType = Rpc::ProtocolType::Invalid; }; } diff --git a/libshvchainpack/include/shv/chainpack/socketrpcdriver.h b/libshvchainpack/include/shv/chainpack/socketrpcdriver.h index 44359a20e..e77f1cdfa 100644 --- a/libshvchainpack/include/shv/chainpack/socketrpcdriver.h +++ b/libshvchainpack/include/shv/chainpack/socketrpcdriver.h @@ -22,6 +22,7 @@ class SHVCHAINPACK_DECL_EXPORT SocketRpcDriver : public RpcDriver bool isOpen() override; void writeFrameData(const std::string &frame_data) override; + virtual void onFrameDataRead(const std::string &frame_data); virtual void idleTaskOnSelectTimeout(); private: bool isOpenImpl() const; diff --git a/libshvchainpack/src/rpcdriver.cpp b/libshvchainpack/src/rpcdriver.cpp index bddc6e1ea..bee3d2211 100644 --- a/libshvchainpack/src/rpcdriver.cpp +++ b/libshvchainpack/src/rpcdriver.cpp @@ -57,31 +57,6 @@ void RpcDriver::sendRpcFrame(RpcFrame &&frame) } } -void RpcDriver::onFrameDataRead(const std::string &frame_data) -{ - logRpcData().nospace() << "FRAME DATA READ " << frame_data.size() << " bytes of data read:\n" << shv::chainpack::utils::hexDump(frame_data); - try { - auto frame = RpcFrame::fromFrameData(frame_data); - - // set client protocol type according to protocol type received from it - // default protocol type is chainpack, this is needed just for legacy devices support - if (m_clientProtocolType == Rpc::ProtocolType::Invalid) { - m_clientProtocolType = frame.protocol; - } - - onRpcFrameReceived(std::move(frame)); - } - catch (const ParseException &e) { - logRpcDataW() << "ERROR - Rpc frame data corrupted:" << e.what(); - //logRpcDataW() << "The error occured in data:\n" << shv::chainpack::utils::hexDump(m_readData.data(), 1024); - onParseDataException(e); - return; - } - catch (const std::exception &e) { - nError() << "ERROR - Rpc frame process error:" << e.what(); - } -} - int RpcDriver::defaultRpcTimeoutMsec() { return s_defaultRpcTimeoutMsec; @@ -92,11 +67,19 @@ void RpcDriver::setDefaultRpcTimeoutMsec(int msec) s_defaultRpcTimeoutMsec = msec; } -void RpcDriver::onRpcFrameReceived(RpcFrame &&frame) +void RpcDriver::processRpcFrame(RpcFrame &&frame) { + // set client protocol type according to protocol type received from it + // default protocol type is chainpack, this is needed just for legacy devices support if (m_clientProtocolType == Rpc::ProtocolType::Invalid) { m_clientProtocolType = frame.protocol; } + + onRpcFrameReceived(std::move(frame)); +} + +void RpcDriver::onRpcFrameReceived(RpcFrame &&frame) +{ std::string errmsg; auto msg = frame.toRpcMessage(&errmsg); if (errmsg.empty()) { diff --git a/libshvchainpack/src/socketrpcdriver.cpp b/libshvchainpack/src/socketrpcdriver.cpp index 48ffef1d2..6fec2cd31 100644 --- a/libshvchainpack/src/socketrpcdriver.cpp +++ b/libshvchainpack/src/socketrpcdriver.cpp @@ -21,6 +21,9 @@ #include #endif +#define logRpcData() nCMessage("RpcData") +#define logRpcDataW() nCWarning("RpcData") + namespace cp = shv::chainpack; namespace shv::chainpack { @@ -65,6 +68,24 @@ void SocketRpcDriver::writeFrameData(const std::string &frame_data) } } +void SocketRpcDriver::onFrameDataRead(const std::string &frame_data) +{ + logRpcData().nospace() << "FRAME DATA READ " << frame_data.size() << " bytes of data read:\n" << shv::chainpack::utils::hexDump(frame_data); + try { + auto frame = RpcFrame::fromFrameData(frame_data); + processRpcFrame(std::move(frame)); + } + catch (const ParseException &e) { + logRpcDataW() << "ERROR - Rpc frame data corrupted:" << e.what(); + //logRpcDataW() << "The error occured in data:\n" << shv::chainpack::utils::hexDump(m_readData.data(), 1024); + onParseDataException(e); + return; + } + catch (const std::exception &e) { + nError() << "ERROR - Rpc frame process error:" << e.what(); + } +} + bool SocketRpcDriver::flush() { if(m_writeBuffer.empty()) { diff --git a/libshviotqt/src/rpc/socketrpcconnection.cpp b/libshviotqt/src/rpc/socketrpcconnection.cpp index fc06be761..a873c03dc 100644 --- a/libshviotqt/src/rpc/socketrpcconnection.cpp +++ b/libshviotqt/src/rpc/socketrpcconnection.cpp @@ -85,7 +85,7 @@ void SocketRpcConnection::onReadyRead() { auto frames = socket()->takeFrames(); for (auto begin = std::make_move_iterator(frames.begin()), end = std::make_move_iterator(frames.end()); begin != end; ++begin) { - onRpcFrameReceived(*begin); + processRpcFrame(*begin); } }