mirror of
https://github.com/Telecominfraproject/wlan-cloud-owls.git
synced 2026-01-27 02:22:44 +00:00
151 lines
7.2 KiB
C++
151 lines
7.2 KiB
C++
//
|
|
// Created by stephane bourque on 2023-04-12.
|
|
//
|
|
|
|
#include <fmt/format.h>
|
|
#include <Poco/NObserver.h>
|
|
|
|
#include "OWLSclient.h"
|
|
#include "SimulationRunner.h"
|
|
#include "SimulationCoordinator.h"
|
|
#include "SimStats.h"
|
|
#include "OWLSclientEvents.h"
|
|
|
|
namespace OpenWifi::OWLSClientEvents {
|
|
|
|
void EstablishConnection( const std::shared_ptr<OWLSclient> &Client, SimulationRunner *Runner) {
|
|
if(!Runner->Running()) {
|
|
return;
|
|
}
|
|
|
|
Poco::URI uri(Runner->Details().gateway);
|
|
|
|
Poco::Net::Context::Params P;
|
|
|
|
Runner->Report().ev_establish_connection++;
|
|
|
|
P.verificationMode = Poco::Net::Context::VERIFY_STRICT;
|
|
P.verificationDepth = 9;
|
|
P.caLocation = SimulationCoordinator()->GetCasLocation();
|
|
P.loadDefaultCAs = false;
|
|
P.certificateFile = SimulationCoordinator()->GetCertFileName();
|
|
P.privateKeyFile = SimulationCoordinator()->GetKeyFileName();
|
|
P.cipherList = "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH";
|
|
P.dhUse2048Bits = true;
|
|
|
|
auto Context = new Poco::Net::Context(Poco::Net::Context::CLIENT_USE, P);
|
|
Poco::Crypto::X509Certificate Cert(SimulationCoordinator()->GetCertFileName());
|
|
Poco::Crypto::X509Certificate Root(SimulationCoordinator()->GetRootCAFileName());
|
|
|
|
Context->useCertificate(Cert);
|
|
Context->addChainCertificate(Root);
|
|
|
|
Context->addCertificateAuthority(Root);
|
|
|
|
if (SimulationCoordinator()->GetLevel() == Poco::Net::Context::VERIFY_STRICT) {
|
|
}
|
|
|
|
Poco::Crypto::RSAKey Key("", SimulationCoordinator()->GetKeyFileName(), "");
|
|
Context->usePrivateKey(Key);
|
|
|
|
SSL_CTX *SSLCtx = Context->sslContext();
|
|
if (!SSL_CTX_check_private_key(SSLCtx)) {
|
|
poco_error(Client->Logger_,fmt::format("Wrong Certificate: {} for {}",SimulationCoordinator()->GetCertFileName() ,
|
|
SimulationCoordinator()->GetKeyFileName()));
|
|
}
|
|
|
|
if (SimulationCoordinator()->GetLevel() == Poco::Net::Context::VERIFY_STRICT) {
|
|
}
|
|
|
|
Poco::Net::HTTPSClientSession Session(uri.getHost(), uri.getPort(), Context);
|
|
Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_GET, "/?encoding=text",
|
|
Poco::Net::HTTPMessage::HTTP_1_1);
|
|
Request.set("origin", "http://www.websocket.org");
|
|
Poco::Net::HTTPResponse Response;
|
|
|
|
std::lock_guard ClientGuard(Client->Mutex_);
|
|
|
|
Client->Logger_.information(fmt::format("connecting({}): host={} port={}", Client->SerialNumber_,
|
|
uri.getHost(), uri.getPort()));
|
|
|
|
try {
|
|
Client->WS_ = std::make_unique<Poco::Net::WebSocket>(Session, Request, Response);
|
|
(*Client->WS_).setReceiveTimeout(Poco::Timespan(1200,0));
|
|
(*Client->WS_).setSendTimeout(Poco::Timespan(1200,0));
|
|
(*Client->WS_).setKeepAlive(true);
|
|
(*Client->WS_).setNoDelay(true);
|
|
(*Client->WS_).setBlocking(false);
|
|
(*Client->WS_).setMaxPayloadSize(128000);
|
|
Runner->AddClientFd(Client->WS_->impl()->sockfd(), Client);
|
|
Client->Connected_ = true;
|
|
Client->Reactor_.addEventHandler(
|
|
*Client->WS_, Poco::NObserver<SimulationRunner, Poco::Net::ReadableNotification>(
|
|
*Runner, &SimulationRunner::OnSocketReadable));
|
|
Client->Reactor_.addEventHandler(
|
|
*Client->WS_, Poco::NObserver<SimulationRunner, Poco::Net::ErrorNotification>(
|
|
*Runner, &SimulationRunner::OnSocketError));
|
|
Client->Reactor_.addEventHandler(
|
|
*Client->WS_, Poco::NObserver<SimulationRunner, Poco::Net::ShutdownNotification>(
|
|
*Runner, &SimulationRunner::OnSocketShutdown));
|
|
Connect(ClientGuard, Client, Runner);
|
|
Client->Logger_.information(fmt::format("connecting({}): connected.", Client->SerialNumber_));
|
|
} catch (const Poco::Exception &E) {
|
|
Client->Logger_.warning(
|
|
fmt::format("connecting({}): exception. {}", Client->SerialNumber_, E.displayText()));
|
|
Runner->Scheduler().in(std::chrono::seconds(Client->Backoff()), Reconnect, Client, Runner);
|
|
} catch (const std::exception &E) {
|
|
Client->Logger_.warning(
|
|
fmt::format("connecting({}): std::exception. {}", Client->SerialNumber_, E.what()));
|
|
Runner->Scheduler().in(std::chrono::seconds(Client->Backoff()), Reconnect, Client, Runner);
|
|
} catch (...) {
|
|
Client->Logger_.warning(fmt::format("connecting({}): unknown exception. {}", Client->SerialNumber_));
|
|
Runner->Scheduler().in(std::chrono::seconds(Client->Backoff()), Reconnect, Client, Runner);
|
|
}
|
|
}
|
|
|
|
void Connect(std::lock_guard<std::mutex> & ClientGuard, const std::shared_ptr<OWLSclient> &Client, SimulationRunner *Runner) {
|
|
|
|
try {
|
|
Runner->Report().ev_connect++;
|
|
|
|
Poco::JSON::Object::Ptr ConnectMessage{new Poco::JSON::Object}, Params{new Poco::JSON::Object},
|
|
TmpCapabilities{new Poco::JSON::Object}, Capabilities{new Poco::JSON::Object}, MacAddr{new Poco::JSON::Object};
|
|
auto LabelMac = Utils::SerialNumberToInt(Client->SerialNumber_);
|
|
Params->set("serial", Client->SerialNumber_);
|
|
Params->set("uuid", Client->UUID_);
|
|
Params->set("firmware", Client->Firmware_);
|
|
MacAddr->set("wan", Client->SerialNumber_);
|
|
MacAddr->set("lan", Utils::SerialToMAC(Utils::IntToSerialNumber(LabelMac + 1)));
|
|
TmpCapabilities = SimulationCoordinator()->GetSimCapabilitiesPtr();
|
|
TmpCapabilities->set("label_macaddr", Client->SerialNumber_);
|
|
TmpCapabilities->set("macaddr", MacAddr);
|
|
Params->set("capabilities", TmpCapabilities);
|
|
|
|
OWLSutils::MakeHeader(ConnectMessage,"connect",Params);
|
|
|
|
if (Client->SendObject(__func__, ConnectMessage)) {
|
|
Client->Reset();
|
|
Runner->Scheduler().in(std::chrono::seconds(Client->StatisticsInterval_),
|
|
OWLSClientEvents::State, Client, Runner);
|
|
Runner->Scheduler().in(std::chrono::seconds(Client->HealthInterval_),
|
|
OWLSClientEvents::HealthCheck, Client, Runner);
|
|
Runner->Scheduler().in(std::chrono::seconds(MicroServiceRandom(120, 200)),
|
|
OWLSClientEvents::Log, Client, Runner, 1, "Device started");
|
|
Runner->Scheduler().in(std::chrono::seconds(60 * 4),
|
|
OWLSClientEvents::WSPing, Client, Runner);
|
|
Runner->Scheduler().in(std::chrono::seconds(30),
|
|
OWLSClientEvents::Update, Client, Runner);
|
|
Client->Logger_.information(fmt::format("connect({}): completed.", Client->SerialNumber_));
|
|
Client->Backoff_=0;
|
|
SimStats()->Connect(Runner->Id());
|
|
return;
|
|
}
|
|
} catch (const Poco::Exception &E) {
|
|
Client->Logger().log(E);
|
|
}
|
|
OWLSClientEvents::Disconnect(ClientGuard, Client, Runner, "Error occurred during connection", true);
|
|
}
|
|
|
|
|
|
}
|