mirror of
https://github.com/Telecominfraproject/wlan-cloud-ucentralgw.git
synced 2025-10-30 02:12:29 +00:00
171 lines
4.9 KiB
C++
171 lines
4.9 KiB
C++
//
|
|
// Created by stephane bourque on 2021-11-23.
|
|
//
|
|
|
|
#include "RTTYS_ClientConnection.h"
|
|
#include "rttys/RTTYS_device.h"
|
|
#include "rttys/RTTYS_server.h"
|
|
|
|
namespace OpenWifi {
|
|
|
|
RTTYS_ClientConnection::RTTYS_ClientConnection(
|
|
Poco::Net::HTTPServerRequest &request,
|
|
Poco::Net::HTTPServerResponse &response,
|
|
Poco::Net::SocketReactor &reactor,
|
|
const std::string &Id)
|
|
:
|
|
Reactor_(reactor),
|
|
Id_(Id),
|
|
Logger_(Poco::Logger::get(fmt::format("RTTY-client({})",Id_)))
|
|
{
|
|
Valid_ = true;
|
|
WS_ = std::make_unique<Poco::Net::WebSocket>(request,response);
|
|
WS_->setBlocking(false);
|
|
WS_->setNoDelay(true);
|
|
WS_->setKeepAlive(true);
|
|
Registered_ = true;
|
|
Reactor_.addEventHandler(
|
|
*WS_, Poco::NObserver<RTTYS_ClientConnection, Poco::Net::ReadableNotification>(
|
|
*this, &RTTYS_ClientConnection::onSocketReadable));
|
|
Reactor_.addEventHandler(
|
|
*WS_, Poco::NObserver<RTTYS_ClientConnection, Poco::Net::ShutdownNotification>(
|
|
*this, &RTTYS_ClientConnection::onSocketShutdown));
|
|
Logger_.information("Starting connection");
|
|
}
|
|
|
|
RTTYS_ClientConnection::~RTTYS_ClientConnection() {
|
|
poco_information(Logger_,
|
|
fmt::format("Client {} session ending", Id_)
|
|
);
|
|
DeRegister();
|
|
}
|
|
|
|
void RTTYS_ClientConnection::DeRegister() {
|
|
Valid_ = false;
|
|
if(Registered_) {
|
|
Registered_ = false;
|
|
Reactor_.removeEventHandler(
|
|
*WS_, Poco::NObserver<RTTYS_ClientConnection, Poco::Net::ReadableNotification>(
|
|
*this, &RTTYS_ClientConnection::onSocketReadable));
|
|
Reactor_.removeEventHandler(
|
|
*WS_, Poco::NObserver<RTTYS_ClientConnection, Poco::Net::ShutdownNotification>(
|
|
*this, &RTTYS_ClientConnection::onSocketShutdown));
|
|
}
|
|
}
|
|
|
|
void RTTYS_ClientConnection::EndConnection() {
|
|
DeRegister();
|
|
RTTYS_server()->NotifyClientDisconnect(Id_, this);
|
|
}
|
|
|
|
void RTTYS_ClientConnection::onSocketReadable([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf) {
|
|
bool MustDisconnect = false;
|
|
|
|
{
|
|
if(!Valid_ || !Registered_)
|
|
return;
|
|
std::shared_lock G(Mutex_);
|
|
try {
|
|
int flags;
|
|
Poco::Buffer<char> IncomingFrame(0);
|
|
auto n = WS_->receiveFrame(IncomingFrame, flags);
|
|
auto Op = flags & Poco::Net::WebSocket::FRAME_OP_BITMASK;
|
|
switch (Op) {
|
|
case Poco::Net::WebSocket::FRAME_OP_PING: {
|
|
WS_->sendFrame("", 0,
|
|
(int)Poco::Net::WebSocket::FRAME_OP_PONG |
|
|
(int)Poco::Net::WebSocket::FRAME_FLAG_FIN);
|
|
} break;
|
|
case Poco::Net::WebSocket::FRAME_OP_PONG: {
|
|
} break;
|
|
case Poco::Net::WebSocket::FRAME_OP_TEXT: {
|
|
if (n == 0) {
|
|
Logger_.information("Socket readable shutdown.");
|
|
MustDisconnect = true;
|
|
} else {
|
|
std::string s((char *)IncomingFrame.begin(), IncomingFrame.size());
|
|
try {
|
|
auto Doc = nlohmann::json::parse(s);
|
|
if (Doc.contains("type")) {
|
|
auto Type = Doc["type"];
|
|
if (Type == "winsize") {
|
|
auto cols = Doc["cols"];
|
|
auto rows = Doc["rows"];
|
|
if (!RTTYS_server()->WindowSize(Id_, cols, rows)) {
|
|
Logger_.information("Winsize shutdown.");
|
|
MustDisconnect = true;
|
|
}
|
|
}
|
|
}
|
|
} catch (...) {
|
|
// just ignore parse errors
|
|
Logger_.information("Frame text exception shutdown.");
|
|
MustDisconnect = true;
|
|
}
|
|
}
|
|
} break;
|
|
case Poco::Net::WebSocket::FRAME_OP_BINARY: {
|
|
if (n == 0) {
|
|
Logger_.information("Frame binary size shutdown.");
|
|
MustDisconnect = true;
|
|
} else {
|
|
poco_trace(Logger_, fmt::format("Sending {} key strokes to device.", n));
|
|
if (!RTTYS_server()->SendKeyStrokes(
|
|
Id_, (const unsigned char *)IncomingFrame.begin(),
|
|
IncomingFrame.size())) {
|
|
Logger_.information("Sendkeystrokes shutdown.");
|
|
MustDisconnect = true;
|
|
}
|
|
}
|
|
} break;
|
|
case Poco::Net::WebSocket::FRAME_OP_CLOSE: {
|
|
Logger_.information("Frame frame close shutdown.");
|
|
MustDisconnect = true;
|
|
} break;
|
|
|
|
default: {
|
|
}
|
|
}
|
|
} catch (...) {
|
|
Logger_.information("Frame readable shutdown.");
|
|
MustDisconnect = true;
|
|
}
|
|
}
|
|
|
|
if(MustDisconnect) {
|
|
EndConnection();
|
|
}
|
|
}
|
|
|
|
void RTTYS_ClientConnection::SendData( const u_char *Buf, size_t len ) {
|
|
if(!Valid_ || !Registered_)
|
|
return;
|
|
try {
|
|
WS_->sendFrame(Buf, len,
|
|
Poco::Net::WebSocket::FRAME_FLAG_FIN |
|
|
Poco::Net::WebSocket::FRAME_OP_BINARY);
|
|
return;
|
|
} catch (...) {
|
|
Logger_.information("SendData shutdown.");
|
|
}
|
|
EndConnection();
|
|
}
|
|
|
|
void RTTYS_ClientConnection::SendData( const std::string &s) {
|
|
if(!Valid_ || !Registered_)
|
|
return;
|
|
try {
|
|
WS_->sendFrame(s.c_str(), s.length());
|
|
return;
|
|
} catch (...) {
|
|
Logger_.information("SendData shutdown.");
|
|
}
|
|
EndConnection();
|
|
}
|
|
|
|
void RTTYS_ClientConnection::onSocketShutdown([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ShutdownNotification> &pNf) {
|
|
Logger_.information("Socket shutdown.");
|
|
EndConnection();
|
|
}
|
|
|
|
} |