Skip to content

Commit

Permalink
Fix client protocol type identification from first rpc frame received
Browse files Browse the repository at this point in the history
  • Loading branch information
Fanda Vacek authored and fvacek committed Nov 5, 2024
1 parent 24f8052 commit 6fafc4b
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 30 deletions.
7 changes: 4 additions & 3 deletions libshvchainpack/include/shv/chainpack/rpcdriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};

}
1 change: 1 addition & 0 deletions libshvchainpack/include/shv/chainpack/socketrpcdriver.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
35 changes: 9 additions & 26 deletions libshvchainpack/src/rpcdriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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()) {
Expand Down
21 changes: 21 additions & 0 deletions libshvchainpack/src/socketrpcdriver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
#include <netdb.h>
#endif

#define logRpcData() nCMessage("RpcData")
#define logRpcDataW() nCWarning("RpcData")

namespace cp = shv::chainpack;

namespace shv::chainpack {
Expand Down Expand Up @@ -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()) {
Expand Down
2 changes: 1 addition & 1 deletion libshviotqt/src/rpc/socketrpcconnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
}

Expand Down

0 comments on commit 6fafc4b

Please sign in to comment.