diff --git a/src/OWLS_Disconnect.cpp b/src/OWLS_Disconnect.cpp index d87824a..6e01f91 100644 --- a/src/OWLS_Disconnect.cpp +++ b/src/OWLS_Disconnect.cpp @@ -26,6 +26,12 @@ namespace OpenWifi::OWLSclientEvents { Runner->Reactor().removeEventHandler( *Client->WS_, Poco::NObserver( *Client->Runner_, &SimulationRunner::OnSocketReadable)); + Runner->Reactor().removeEventHandler( + *Client->WS_, Poco::NObserver( + *Client->Runner_, &SimulationRunner::OnSocketError)); + Runner->Reactor().removeEventHandler( + *Client->WS_, Poco::NObserver( + *Client->Runner_, &SimulationRunner::OnSocketShutdown)); (*Client->WS_).close(); } Client->Connected_ = false; diff --git a/src/OWLS_EstablishConnection.cpp b/src/OWLS_EstablishConnection.cpp index 02cdae7..41f76f2 100644 --- a/src/OWLS_EstablishConnection.cpp +++ b/src/OWLS_EstablishConnection.cpp @@ -73,6 +73,12 @@ namespace OpenWifi::OWLSclientEvents { Runner->Reactor().addEventHandler( *Client->WS_, Poco::NObserver( *Runner, &SimulationRunner::OnSocketReadable)); + Runner->Reactor().addEventHandler( + *Client->WS_, Poco::NObserver( + *Runner, &SimulationRunner::OnSocketError)); + Runner->Reactor().addEventHandler( + *Client->WS_, Poco::NObserver( + *Runner, &SimulationRunner::OnSocketShutdown)); Client->Connected_ = true; Runner->AddClientFd(Client->WS_->impl()->sockfd(), Client); Runner->Scheduler().in(std::chrono::seconds(1), Connect, Client, Runner); diff --git a/src/OWLS_HealthCheck.cpp b/src/OWLS_HealthCheck.cpp index caa0940..a23b906 100644 --- a/src/OWLS_HealthCheck.cpp +++ b/src/OWLS_HealthCheck.cpp @@ -28,7 +28,7 @@ namespace OpenWifi::OWLSclientEvents { M["params"]["sanity"] = 100; M["params"]["data"] = P; - if (Client->Send(to_string(M))) { + if (Client->SendObject(M)) { DEBUG_LINE("sent"); Runner->Scheduler().in(std::chrono::seconds(Client->HealthInterval_), OWLSclientEvents::HealthCheck, Client, Runner); diff --git a/src/OWLS_WSPing.cpp b/src/OWLS_WSPing.cpp index e0c87b7..d333ab3 100644 --- a/src/OWLS_WSPing.cpp +++ b/src/OWLS_WSPing.cpp @@ -19,11 +19,11 @@ namespace OpenWifi::OWLSclientEvents { if(Client->Valid_ && Client->Connected_) { Runner->Report().ev_wsping++; try { - if (Client->SendWSPing()) { - Runner->Scheduler().in(std::chrono::seconds(60 * 4), - OWLSclientEvents::WSPing, Client, Runner); - return; - } + Client->WS_->sendFrame( + "", 0, Poco::Net::WebSocket::FRAME_OP_PING | Poco::Net::WebSocket::FRAME_FLAG_FIN); + Runner->Scheduler().in(std::chrono::seconds(60 * 4), + OWLSclientEvents::WSPing, Client, Runner); + return; } catch (const Poco::Exception &E) { DEBUG_LINE("exception1"); Client->Logger().log(E); diff --git a/src/OWLSclient.cpp b/src/OWLSclient.cpp index 3688c49..c8bc529 100644 --- a/src/OWLSclient.cpp +++ b/src/OWLSclient.cpp @@ -652,9 +652,9 @@ namespace OpenWifi { return false; } - bool OWLSclient::SendObject(nlohmann::json &O) { + bool OWLSclient::SendObject(const nlohmann::json &O) { try { - auto M = to_string(O); + std::string M = to_string(O); uint32_t BytesSent = WS_->sendFrame(M.c_str(), M.size()); if (BytesSent == M.size()) { DEBUG_LINE("sent"); diff --git a/src/OWLSclient.h b/src/OWLSclient.h index aa67a42..239cd8f 100644 --- a/src/OWLSclient.h +++ b/src/OWLSclient.h @@ -33,10 +33,13 @@ namespace OpenWifi { public: OWLSclient(std::string SerialNumber, Poco::Logger &Logger, SimulationRunner *runner); + ~OWLSclient() { + std::cout << SerialNumber_ << ": Deleting client" << std::endl; + } bool Send(const std::string &Cmd); bool SendWSPing(); - bool SendObject(nlohmann::json &O); + bool SendObject(const nlohmann::json &O); void SetFirmware(const std::string &S = "sim-firmware-1") { Firmware_ = S; } diff --git a/src/SimulationRunner.cpp b/src/SimulationRunner.cpp index dfd1860..a7e7723 100644 --- a/src/SimulationRunner.cpp +++ b/src/SimulationRunner.cpp @@ -17,6 +17,7 @@ #include #include +#include namespace OpenWifi { void SimulationRunner::Start() { @@ -62,6 +63,62 @@ namespace OpenWifi { } } + void SimulationRunner::OnSocketError(const Poco::AutoPtr &pNf) { + std::lock_guard G(Mutex_); + + auto socket = pNf->socket().impl()->sockfd(); + std::map>::iterator client_hint; + std::shared_ptr client; + + client_hint = Clients_fd_.find(socket); + if (client_hint == end(Clients_fd_)) { + poco_warning(Logger_, fmt::format("{}: Invalid socket", socket)); + return; + } + client = client_hint->second; + Clients_fd_.erase(socket); + Reactor_.removeEventHandler( + *client->WS_, Poco::NObserver( + *this, &SimulationRunner::OnSocketReadable)); + Reactor_.removeEventHandler( + *client->WS_, Poco::NObserver( + *this, &SimulationRunner::OnSocketError)); + Reactor_.removeEventHandler( + *client->WS_, Poco::NObserver( + *this, &SimulationRunner::OnSocketShutdown)); + client->fd_ = -1; + if(Running_) + OWLSclientEvents::Reconnect(client,this); + } + + void SimulationRunner::OnSocketShutdown(const Poco::AutoPtr &pNf) { + std::lock_guard G(Mutex_); + + auto socket = pNf->socket().impl()->sockfd(); + std::map>::iterator client_hint; + std::shared_ptr client; + + client_hint = Clients_fd_.find(socket); + if (client_hint == end(Clients_fd_)) { + poco_warning(Logger_, fmt::format("{}: Invalid socket", socket)); + return; + } + client = client_hint->second; + Clients_fd_.erase(socket); + Reactor_.removeEventHandler( + *client->WS_, Poco::NObserver( + *this, &SimulationRunner::OnSocketReadable)); + Reactor_.removeEventHandler( + *client->WS_, Poco::NObserver( + *this, &SimulationRunner::OnSocketError)); + Reactor_.removeEventHandler( + *client->WS_, Poco::NObserver( + *this, &SimulationRunner::OnSocketShutdown)); + client->fd_ = -1; + if(Running_) + OWLSclientEvents::Reconnect(client,this); + } + void SimulationRunner::OnSocketReadable(const Poco::AutoPtr &pNf) { std::map>::iterator client_hint; std::shared_ptr client; diff --git a/src/SimulationRunner.h b/src/SimulationRunner.h index c1f7268..81cceeb 100644 --- a/src/SimulationRunner.h +++ b/src/SimulationRunner.h @@ -31,6 +31,8 @@ namespace OpenWifi { CensusReport & Report() { return CensusReport_; } void OnSocketReadable(const Poco::AutoPtr &pNf); + void OnSocketError(const Poco::AutoPtr &pNf); + void OnSocketShutdown(const Poco::AutoPtr &pNf); const std::string & Id() const { return Id_; }