Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix client protocol type identification from first rpc frame received #528

Merged
merged 1 commit into from
Nov 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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