stephb9959
2022-07-23 08:47:33 -07:00
parent b09cec0bc2
commit 2ad0ec12dd
15 changed files with 392 additions and 332 deletions

View File

@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.13)
project(owgw VERSION 2.6.0)
project(owgw VERSION 2.7.0)
set(CMAKE_CXX_STANDARD 17)
@@ -105,7 +105,7 @@ add_executable( owgw
src/storage/storage_tables.cpp
src/RESTAPI/RESTAPI_routers.cpp
src/Daemon.cpp src/Daemon.h
src/WS_Server.cpp src/WS_Server.h
src/AP_WS_Server.cpp src/AP_WS_Server.h
src/StorageService.cpp src/StorageService.h
src/DeviceRegistry.cpp src/DeviceRegistry.h
src/CommandManager.cpp src/CommandManager.h
@@ -118,7 +118,7 @@ add_executable( owgw
src/TelemetryStream.cpp src/TelemetryStream.h
src/framework/ConfigurationValidator.cpp src/framework/ConfigurationValidator.h
src/ConfigurationCache.h
src/CapabilitiesCache.h src/FindCountry.h src/rttys/RTTYS_server.cpp src/rttys/RTTYS_server.h src/rttys/RTTYS_device.cpp src/rttys/RTTYS_device.h src/rttys/RTTYS_ClientConnection.cpp src/rttys/RTTYS_ClientConnection.h src/rttys/RTTYS_WebServer.cpp src/rttys/RTTYS_WebServer.h src/RESTAPI/RESTAPI_device_helper.h src/SDKcalls.cpp src/SDKcalls.h src/StateUtils.cpp src/StateUtils.h src/WS_ReactorPool.h src/WS_Connection.h src/WS_Connection.cpp src/TelemetryClient.h src/TelemetryClient.cpp src/RESTAPI/RESTAPI_iptocountry_handler.cpp src/RESTAPI/RESTAPI_iptocountry_handler.h src/framework/ow_constants.h src/GwWebSocketClient.cpp src/GwWebSocketClient.h src/framework/WebSocketClientNotifications.h src/RADIUS_proxy_server.cpp src/RADIUS_proxy_server.h src/RESTAPI/RESTAPI_radiusProxyConfig_handler.cpp src/RESTAPI/RESTAPI_radiusProxyConfig_handler.h src/ParseWifiScan.h src/RADIUS_helpers.h src/VenueBroadcaster.h src/sdks/sdk_prov.h)
src/CapabilitiesCache.h src/FindCountry.h src/rttys/RTTYS_server.cpp src/rttys/RTTYS_server.h src/rttys/RTTYS_device.cpp src/rttys/RTTYS_device.h src/rttys/RTTYS_ClientConnection.cpp src/rttys/RTTYS_ClientConnection.h src/rttys/RTTYS_WebServer.cpp src/rttys/RTTYS_WebServer.h src/RESTAPI/RESTAPI_device_helper.h src/SDKcalls.cpp src/SDKcalls.h src/StateUtils.cpp src/StateUtils.h src/WS_ReactorPool.h src/AP_WS_Connection.h src/AP_WS_Connection.cpp src/TelemetryClient.h src/TelemetryClient.cpp src/RESTAPI/RESTAPI_iptocountry_handler.cpp src/RESTAPI/RESTAPI_iptocountry_handler.h src/framework/ow_constants.h src/GwWebSocketClient.cpp src/GwWebSocketClient.h src/framework/WebSocketClientNotifications.h src/RADIUS_proxy_server.cpp src/RADIUS_proxy_server.h src/RESTAPI/RESTAPI_radiusProxyConfig_handler.cpp src/RESTAPI/RESTAPI_radiusProxyConfig_handler.h src/ParseWifiScan.h src/RADIUS_helpers.h src/VenueBroadcaster.h src/sdks/sdk_prov.h)
if(NOT SMALL_BUILD)

2
build
View File

@@ -1 +1 @@
151
3

View File

@@ -2,7 +2,7 @@
// Created by stephane bourque on 2022-02-03.
//
#include "WS_Connection.h"
#include "AP_WS_Connection.h"
#include "Poco/Net/SecureStreamSocketImpl.h"
#include "Poco/Net/SecureServerSocketImpl.h"
@@ -17,30 +17,34 @@
#include "Poco/zlib.h"
#include "WS_Server.h"
#include "StorageService.h"
#include "AP_WS_Server.h"
#include "CentralConfig.h"
#include "CommandManager.h"
#include "StateUtils.h"
#include "ConfigurationCache.h"
#include "Daemon.h"
#include "TelemetryStream.h"
#include "CentralConfig.h"
#include "FindCountry.h"
#include "StateUtils.h"
#include "StorageService.h"
#include "TelemetryStream.h"
#include "VenueBroadcaster.h"
#include "framework/WebSocketClientNotifications.h"
#include "Poco/Net/WebSocketImpl.h"
#include "RADIUS_proxy_server.h"
namespace OpenWifi {
void WSConnection::LogException(const Poco::Exception &E) {
void AP_WS_Connection::LogException(const Poco::Exception &E) {
Logger().information(fmt::format("EXCEPTION({}): {}", CId_, E.displayText()));
}
void WSConnection::CompleteStartup() {
void AP_WS_Connection::CompleteStartup() {
std::lock_guard Guard(Mutex_);
try {
auto SS = dynamic_cast<Poco::Net::SecureStreamSocketImpl *>(Socket_.impl());
auto SockImpl = dynamic_cast<Poco::Net::WebSocketImpl *>(WS_->impl());
auto SS = dynamic_cast<Poco::Net::SecureStreamSocketImpl*>(SockImpl->streamSocketImpl());
while (true) {
auto V = SS->completeHandshake();
if (V == 1)
@@ -60,7 +64,7 @@ namespace OpenWifi {
try {
Poco::Crypto::X509Certificate PeerCert(SS->peerCertificate());
if (WebSocketServer()->ValidateCertificate(CId_, PeerCert)) {
if (AP_WS_Server()->ValidateCertificate(CId_, PeerCert)) {
CN_ = Poco::trim(Poco::toLower(PeerCert.commonName()));
CertValidation_ = GWObjects::MISMATCH_SERIAL;
poco_trace(Logger(),fmt::format("{}: Valid certificate: CN={}", CId_, CN_));
@@ -74,7 +78,7 @@ namespace OpenWifi {
poco_error(Logger(),fmt::format("{}: No certificates available..", CId_));
}
if (WebSocketServer::IsSim(CN_) && !WebSocketServer()->IsSimEnabled()) {
if (AP_WS_Server::IsSim(CN_) && !AP_WS_Server()->IsSimEnabled()) {
Logger().debug(fmt::format(
"CONNECTION({}): Sim Device {} is not allowed. Disconnecting.", CId_, CN_));
delete this;
@@ -89,32 +93,20 @@ namespace OpenWifi {
CId_, CN_));
return delete this;
}
auto Params = Poco::AutoPtr<Poco::Net::HTTPServerParams>(new Poco::Net::HTTPServerParams);
Poco::Net::HTTPServerSession Session(Socket_, Params);
Poco::Net::HTTPServerResponseImpl Response(Session);
Poco::Net::HTTPServerRequestImpl Request(Response, Session, Params);
auto now = OpenWifi::Now();
Response.setDate(now);
Response.setVersion(Request.getVersion());
Response.setKeepAlive(Params->getKeepAlive() && Request.getKeepAlive() &&
Session.canKeepAlive());
WS_ = std::make_unique<Poco::Net::WebSocket>(Request, Response);
WS_->setMaxPayloadSize(BufSize);
auto TS = Poco::Timespan(360, 0);
WS_->setReceiveTimeout(TS);
WS_->setNoDelay(true);
WS_->setKeepAlive(true);
Reactor_.addEventHandler(*WS_,
Poco::NObserver<WSConnection, Poco::Net::ReadableNotification>(
*this, &WSConnection::OnSocketReadable));
Poco::NObserver<AP_WS_Connection, Poco::Net::ReadableNotification>(
*this, &AP_WS_Connection::OnSocketReadable));
Reactor_.addEventHandler(*WS_,
Poco::NObserver<WSConnection, Poco::Net::ShutdownNotification>(
*this, &WSConnection::OnSocketShutdown));
Reactor_.addEventHandler(*WS_, Poco::NObserver<WSConnection, Poco::Net::ErrorNotification>(
*this, &WSConnection::OnSocketError));
Poco::NObserver<AP_WS_Connection, Poco::Net::ShutdownNotification>(
*this, &AP_WS_Connection::OnSocketShutdown));
Reactor_.addEventHandler(*WS_, Poco::NObserver<AP_WS_Connection, Poco::Net::ErrorNotification>(
*this, &AP_WS_Connection::OnSocketError));
Registered_ = true;
poco_debug(Logger(),fmt::format("CONNECTION({}): completed.", CId_));
return;
@@ -154,13 +146,13 @@ namespace OpenWifi {
return delete this;
}
WSConnection::WSConnection(Poco::Net::StreamSocket &socket, [[maybe_unused]] Poco::Net::SocketReactor &reactor)
: Logger_(WebSocketServer()->Logger()) ,
Socket_(socket),
Reactor_(ReactorThreadPool()->NextReactor())
{
std::thread T([=]() { CompleteStartup(); });
T.detach();
AP_WS_Connection::AP_WS_Connection(Poco::Net::HTTPServerRequest &request,
Poco::Net::HTTPServerResponse &response)
: Logger_(AP_WS_Server()->Logger()) ,
Reactor_(AP_WS_Server()->NextReactor())
{
WS_ = std::make_unique<Poco::Net::WebSocket>(request,response);
CompleteStartup();
}
static void NotifyKafkaDisconnect(const std::string & SerialNumber) {
@@ -178,7 +170,7 @@ namespace OpenWifi {
}
}
WSConnection::~WSConnection() {
AP_WS_Connection::~AP_WS_Connection() {
poco_debug(Logger(),fmt::format("{}: Removing connection for {}.", CId_, SerialNumber_));
if (ConnectionId_)
@@ -186,19 +178,17 @@ namespace OpenWifi {
if (Registered_ && WS_) {
Reactor_.removeEventHandler(*WS_,
Poco::NObserver<WSConnection, Poco::Net::ReadableNotification>(
*this, &WSConnection::OnSocketReadable));
Poco::NObserver<AP_WS_Connection, Poco::Net::ReadableNotification>(
*this, &AP_WS_Connection::OnSocketReadable));
Reactor_.removeEventHandler(*WS_,
Poco::NObserver<WSConnection, Poco::Net::ShutdownNotification>(
*this, &WSConnection::OnSocketShutdown));
Poco::NObserver<AP_WS_Connection, Poco::Net::ShutdownNotification>(
*this, &AP_WS_Connection::OnSocketShutdown));
Reactor_.removeEventHandler(*WS_,
Poco::NObserver<WSConnection, Poco::Net::ErrorNotification>(
*this, &WSConnection::OnSocketError));
Poco::NObserver<AP_WS_Connection, Poco::Net::ErrorNotification>(
*this, &AP_WS_Connection::OnSocketError));
(*WS_).close();
Socket_.shutdown();
} else if (WS_) {
(*WS_).close();
Socket_.shutdown();
}
if (KafkaManager()->Enabled() && !SerialNumber_.empty()) {
@@ -210,7 +200,7 @@ namespace OpenWifi {
WebSocketClientNotificationDeviceDisconnected(SerialNumber_);
}
bool WSConnection::LookForUpgrade(const uint64_t UUID, uint64_t & UpgradedUUID) {
bool AP_WS_Connection::LookForUpgrade(const uint64_t UUID, uint64_t & UpgradedUUID) {
// A UUID of zero means ignore updates for that connection.
if (UUID == 0)
@@ -276,11 +266,11 @@ namespace OpenWifi {
return false;
}
void WSConnection::ProcessJSONRPCResult(Poco::JSON::Object::Ptr Doc) {
void AP_WS_Connection::ProcessJSONRPCResult(Poco::JSON::Object::Ptr Doc) {
CommandManager()->PostCommandResult(SerialNumber_, *Doc);
}
void WSConnection::ProcessJSONRPCEvent(Poco::JSON::Object::Ptr &Doc) {
void AP_WS_Connection::ProcessJSONRPCEvent(Poco::JSON::Object::Ptr &Doc) {
auto Method = Doc->get(uCentralProtocol::METHOD).toString();
auto EventType = uCentralProtocol::Events::EventFromString(Method);
@@ -373,7 +363,7 @@ namespace OpenWifi {
CId_ = SerialNumber_ + "@" + CId_;
// We need to verify the certificate if we have one
if ((!CN_.empty() && Utils::SerialNumberMatch(CN_, SerialNumber_)) ||
WebSocketServer()->IsSimSerialNumber(CN_)) {
AP_WS_Server()->IsSimSerialNumber(CN_)) {
CertValidation_ = GWObjects::VERIFIED;
poco_information(Logger(), fmt::format("CONNECT({}): Fully validated and authenticated device.", CId_));
} else {
@@ -774,7 +764,7 @@ namespace OpenWifi {
}
}
bool WSConnection::StartTelemetry() {
bool AP_WS_Connection::StartTelemetry() {
// std::cout << "Start telemetry for " << SerialNumber_ << std::endl;
poco_information(Logger(), fmt::format("TELEMETRY({}): Starting.", CId_));
Poco::JSON::Object StartMessage;
@@ -797,7 +787,7 @@ namespace OpenWifi {
return true;
}
bool WSConnection::StopTelemetry() {
bool AP_WS_Connection::StopTelemetry() {
// std::cout << "Stop telemetry for " << SerialNumber_ << std::endl;
poco_information(Logger(), fmt::format("TELEMETRY({}): Stopping.", CId_));
Poco::JSON::Object StopMessage;
@@ -817,14 +807,14 @@ namespace OpenWifi {
return true;
}
void WSConnection::UpdateCounts() {
void AP_WS_Connection::UpdateCounts() {
if (Conn_) {
Conn_->Conn_.kafkaClients = TelemetryKafkaRefCount_;
Conn_->Conn_.webSocketClients = TelemetryWebSocketRefCount_;
}
}
bool WSConnection::SetWebSocketTelemetryReporting(uint64_t Interval,
bool AP_WS_Connection::SetWebSocketTelemetryReporting(uint64_t Interval,
uint64_t LifeTime) {
std::lock_guard G(Mutex_);
TelemetryWebSocketRefCount_++;
@@ -839,7 +829,7 @@ namespace OpenWifi {
return true;
}
bool WSConnection::SetKafkaTelemetryReporting(uint64_t Interval, uint64_t LifeTime) {
bool AP_WS_Connection::SetKafkaTelemetryReporting(uint64_t Interval, uint64_t LifeTime) {
std::lock_guard G(Mutex_);
TelemetryKafkaRefCount_++;
TelemetryInterval_ = TelemetryInterval_ ? std::min(Interval, TelemetryInterval_) : Interval;
@@ -853,7 +843,7 @@ namespace OpenWifi {
return true;
}
bool WSConnection::StopWebSocketTelemetry() {
bool AP_WS_Connection::StopWebSocketTelemetry() {
std::lock_guard G(Mutex_);
if (TelemetryWebSocketRefCount_)
TelemetryWebSocketRefCount_--;
@@ -865,7 +855,7 @@ namespace OpenWifi {
return true;
}
bool WSConnection::StopKafkaTelemetry() {
bool AP_WS_Connection::StopKafkaTelemetry() {
std::lock_guard G(Mutex_);
if (TelemetryKafkaRefCount_)
TelemetryKafkaRefCount_--;
@@ -877,19 +867,19 @@ namespace OpenWifi {
return true;
}
void WSConnection::OnSocketShutdown([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ShutdownNotification> &pNf) {
void AP_WS_Connection::OnSocketShutdown([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ShutdownNotification> &pNf) {
std::lock_guard Guard(Mutex_);
poco_trace(Logger(), fmt::format("SOCKET-SHUTDOWN({}): Closing.", CId_));
delete this;
}
void WSConnection::OnSocketError([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ErrorNotification> &pNf) {
void AP_WS_Connection::OnSocketError([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ErrorNotification> &pNf) {
std::lock_guard Guard(Mutex_);
poco_trace(Logger(), fmt::format("SOCKET-ERROR({}): Closing.", CId_));
delete this;
}
void WSConnection::OnSocketReadable([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf) {
void AP_WS_Connection::OnSocketReadable([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf) {
std::lock_guard Guard(Mutex_);
try {
ProcessIncomingFrame();
@@ -914,7 +904,7 @@ namespace OpenWifi {
return "";
}
void WSConnection::ProcessIncomingFrame() {
void AP_WS_Connection::ProcessIncomingFrame() {
// bool MustDisconnect=false;
Poco::Buffer<char> IncomingFrame(0);
@@ -1082,7 +1072,7 @@ namespace OpenWifi {
delete this;
}
bool WSConnection::Send(const std::string &Payload) {
bool AP_WS_Connection::Send(const std::string &Payload) {
std::lock_guard Guard(Mutex_);
size_t BytesSent = WS_->sendFrame(Payload.c_str(), (int)Payload.size());
@@ -1103,7 +1093,7 @@ namespace OpenWifi {
return ofs.str();
}
bool WSConnection::SendRadiusAuthenticationData(const unsigned char * buffer, std::size_t size) {
bool AP_WS_Connection::SendRadiusAuthenticationData(const unsigned char * buffer, std::size_t size) {
Poco::JSON::Object Answer;
Answer.set(uCentralProtocol::RADIUS,uCentralProtocol::RADIUSAUTH);
Answer.set(uCentralProtocol::RADIUSDATA, Base64Encode(buffer,size));
@@ -1113,7 +1103,7 @@ namespace OpenWifi {
return Send(Payload.str());
}
bool WSConnection::SendRadiusAccountingData(const unsigned char * buffer, std::size_t size) {
bool AP_WS_Connection::SendRadiusAccountingData(const unsigned char * buffer, std::size_t size) {
Poco::JSON::Object Answer;
Answer.set(uCentralProtocol::RADIUS,uCentralProtocol::RADIUSACCT);
Answer.set(uCentralProtocol::RADIUSDATA, Base64Encode(buffer,size));
@@ -1123,7 +1113,7 @@ namespace OpenWifi {
return Send(Payload.str());
}
bool WSConnection::SendRadiusCoAData(const unsigned char * buffer, std::size_t size) {
bool AP_WS_Connection::SendRadiusCoAData(const unsigned char * buffer, std::size_t size) {
Poco::JSON::Object Answer;
Answer.set(uCentralProtocol::RADIUS,uCentralProtocol::RADIUSCOA);
Answer.set(uCentralProtocol::RADIUSDATA, Base64Encode(buffer,size));
@@ -1133,7 +1123,7 @@ namespace OpenWifi {
return Send(Payload.str());
}
void WSConnection::ProcessIncomingRadiusData(const Poco::JSON::Object::Ptr &Doc) {
void AP_WS_Connection::ProcessIncomingRadiusData(const Poco::JSON::Object::Ptr &Doc) {
if( Doc->has(uCentralProtocol::RADIUSDATA)) {
auto Type = Doc->get(uCentralProtocol::RADIUS).toString();
if(Type==uCentralProtocol::RADIUSACCT) {

View File

@@ -17,11 +17,12 @@
namespace OpenWifi {
class WSConnection {
class AP_WS_Connection {
static constexpr int BufSize = 128000;
public:
WSConnection(Poco::Net::StreamSocket& Socket, Poco::Net::SocketReactor& Reactor);
~WSConnection();
AP_WS_Connection(Poco::Net::HTTPServerRequest &request,
Poco::Net::HTTPServerResponse &response);
~AP_WS_Connection();
void ProcessJSONRPCEvent(Poco::JSON::Object::Ptr & Doc);
void ProcessJSONRPCResult(Poco::JSON::Object::Ptr Doc);
@@ -64,7 +65,6 @@ class WSConnection {
private:
std::recursive_mutex Mutex_;
Poco::Logger &Logger_;
Poco::Net::StreamSocket Socket_;
Poco::Net::SocketReactor & Reactor_;
std::unique_ptr<Poco::Net::WebSocket> WS_;
std::string SerialNumber_;

102
src/AP_WS_Server.cpp Normal file
View File

@@ -0,0 +1,102 @@
//
// License type: BSD 3-Clause License
// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
//
// Created by Stephane Bourque on 2021-03-04.
// Arilia Wireless Inc.
//
#include "Poco/Net/HTTPHeaderStream.h"
#include "Poco/JSON/Array.h"
#include "Poco/Net/Context.h"
#include "AP_WS_Server.h"
#include "ConfigurationCache.h"
#include "TelemetryStream.h"
#include <openssl/ssl.h>
namespace OpenWifi {
void AP_WS_RequestHandler::handleRequest(Poco::Net::HTTPServerRequest &request,
Poco::Net::HTTPServerResponse &response) {
try {
new AP_WS_Connection(request,response);
} catch (...) {
Logger_.warning("Exception during WS creation");
}
};
bool AP_WS_Server::ValidateCertificate(const std::string & ConnectionId, const Poco::Crypto::X509Certificate & Certificate) {
if(IsCertOk()) {
Logger().debug(fmt::format("CERTIFICATE({}): issuer='{}' cn='{}'", ConnectionId, Certificate.issuerName(),Certificate.commonName()));
if(!Certificate.issuedBy(*IssuerCert_)) {
Logger().debug(fmt::format("CERTIFICATE({}): issuer mismatch. Local='{}' Incoming='{}'", ConnectionId, IssuerCert_->issuerName(), Certificate.issuerName()));
return false;
}
return true;
}
return false;
}
int AP_WS_Server::Start() {
for(const auto & Svr : ConfigServersList_ ) {
Logger().notice(fmt::format("Starting: {}:{} Keyfile:{} CertFile: {}", Svr.Address(),
Svr.Port(), Svr.KeyFile(), Svr.CertFile()));
Svr.LogCert(Logger());
if (!Svr.RootCA().empty())
Svr.LogCas(Logger());
auto Sock{Svr.CreateSecureSocket(Logger())};
if (!IsCertOk()) {
IssuerCert_ = std::make_unique<Poco::Crypto::X509Certificate>(Svr.IssuerCertFile());
Logger().information(
fmt::format("Certificate Issuer Name:{}", IssuerCert_->issuerName()));
}
auto WebServerHttpParams = new Poco::Net::HTTPServerParams;
WebServerHttpParams->setMaxThreads(50);
WebServerHttpParams->setMaxQueued(200);
WebServerHttpParams->setKeepAlive(true);
auto NewWebServer = std::make_unique<Poco::Net::HTTPServer>(
new AP_WS_RequestHandlerFactory(Logger()), Sock, WebServerHttpParams);
WebServers_.push_back(std::move(NewWebServer));
}
for(auto &server:WebServers_)
server->start();
ReactorThread_.start(Reactor_);
auto ProvString = MicroService::instance().ConfigGetString("autoprovisioning.process","default");
if(ProvString!="default") {
auto Tokens = Poco::StringTokenizer(ProvString, ",");
for (const auto &i : Tokens) {
if (i == "prov")
LookAtProvisioning_ = true;
else
UseDefaultConfig_ = true;
}
} else {
UseDefaultConfig_ = true;
}
SimulatorId_ = MicroService::instance().ConfigGetString("simulatorid","");
SimulatorEnabled_ = !SimulatorId_.empty();
Utils::SetThreadName(ReactorThread_,"device-reactor");
return 0;
}
void AP_WS_Server::Stop() {
Logger().notice("Stopping reactors...");
// ReactorPool_.Stop();
Reactor_.stop();
ReactorThread_.join();
}
} //namespace

107
src/AP_WS_Server.h Normal file
View File

@@ -0,0 +1,107 @@
//
// License type: BSD 3-Clause License
// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
//
// Created by Stephane Bourque on 2021-03-04.
// Arilia Wireless Inc.
//
#pragma once
#include <mutex>
#include <thread>
#include <array>
#include <ctime>
#include "framework/MicroService.h"
#include "Poco/AutoPtr.h"
#include "Poco/Net/SocketReactor.h"
#include "Poco/Net/ParallelSocketAcceptor.h"
#include "Poco/Net/SocketAcceptor.h"
#include "AP_WS_Connection.h"
#include "WS_ReactorPool.h"
namespace OpenWifi {
class AP_WS_RequestHandler : public Poco::Net::HTTPRequestHandler {
public:
explicit AP_WS_RequestHandler(Poco::Logger &L)
: Logger_(L) {
};
void handleRequest(Poco::Net::HTTPServerRequest &request,
Poco::Net::HTTPServerResponse &response) override;
private:
Poco::Logger &Logger_;
};
class AP_WS_RequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
public:
inline explicit AP_WS_RequestHandlerFactory(Poco::Logger &L)
: Logger_(L) {
}
inline Poco::Net::HTTPRequestHandler *
createRequestHandler(const Poco::Net::HTTPServerRequest &request) override {
if (request.find("Upgrade") != request.end() &&
Poco::icompare(request["Upgrade"], "websocket") == 0) {
Poco::Thread::current()->setName("AP_CONN_INIT");
return new AP_WS_RequestHandler(Logger_);
} else {
return nullptr;
}
}
private:
Poco::Logger &Logger_;
};
class AP_WS_Server : public SubSystemServer {
public:
static auto instance() {
static auto instance_ = new AP_WS_Server;
return instance_;
}
int Start() override;
void Stop() override;
bool IsCertOk() { return IssuerCert_!= nullptr; }
bool ValidateCertificate(const std::string & ConnectionId, const Poco::Crypto::X509Certificate & Certificate);
// Poco::Net::SocketReactor & GetNextReactor() { return ReactorPool_.NextReactor(); }
inline bool IsSimSerialNumber(const std::string & SerialNumber) const {
return IsSim(SerialNumber) && SerialNumber == SimulatorId_;
}
inline static bool IsSim(const std::string & SerialNumber) {
return SerialNumber.substr(0,6) == "53494d";
}
inline bool IsSimEnabled() const {
return SimulatorEnabled_;
}
inline bool UseProvisioning() const { return LookAtProvisioning_; }
inline bool UseDefaults() const { return UseDefaultConfig_; }
[[nodiscard]] inline Poco::Net::SocketReactor & NextReactor() { return Reactor_; }
private:
std::unique_ptr<Poco::Crypto::X509Certificate> IssuerCert_;
std::list<std::unique_ptr<Poco::Net::HTTPServer>> WebServers_;
Poco::Net::SocketReactor Reactor_;
Poco::Thread ReactorThread_;
std::string SimulatorId_;
bool LookAtProvisioning_ = false;
bool UseDefaultConfig_ = true;
bool SimulatorEnabled_=false;
AP_WS_Server() noexcept:
SubSystemServer("WebSocketServer", "WS-SVR", "ucentral.websocket") {
}
};
inline auto AP_WS_Server() { return AP_WS_Server::instance(); }
} //namespace

View File

@@ -10,22 +10,22 @@
#include "Poco/Util/Option.h"
#include "Poco/Environment.h"
#include "AP_WS_Server.h"
#include "CommandManager.h"
#include "Daemon.h"
#include "DeviceRegistry.h"
#include "FileUploader.h"
#include "FindCountry.h"
#include "OUIServer.h"
#include "RADIUS_proxy_server.h"
#include "SerialNumberCache.h"
#include "StorageArchiver.h"
#include "StorageService.h"
#include "TelemetryStream.h"
#include "WS_Server.h"
#include "VenueBroadcaster.h"
#include "framework/ConfigurationValidator.h"
#include "framework/MicroService.h"
#include "FindCountry.h"
#include "rttys/RTTYS_server.h"
#include "RADIUS_proxy_server.h"
#include "VenueBroadcaster.h"
namespace OpenWifi {
class Daemon *Daemon::instance() {
@@ -47,7 +47,7 @@ namespace OpenWifi {
StorageArchiver(),
TelemetryStream(),
RTTYS_server(),
WebSocketServer(),
AP_WS_Server(),
RADIUS_proxy_server(),
VenueBroadcaster()
});

View File

@@ -9,8 +9,8 @@
#include "Poco/JSON/Object.h"
#include "Poco/JSON/Parser.h"
#include "AP_WS_Server.h"
#include "DeviceRegistry.h"
#include "WS_Server.h"
#include "OUIServer.h"
namespace OpenWifi {
@@ -87,7 +87,7 @@ namespace OpenWifi {
}
}
std::shared_ptr<DeviceRegistry::ConnectionEntry> DeviceRegistry::Register(uint64_t SerialNumber, WSConnection *Ptr, uint64_t & ConnectionId )
std::shared_ptr<DeviceRegistry::ConnectionEntry> DeviceRegistry::Register(uint64_t SerialNumber, AP_WS_Connection *Ptr, uint64_t & ConnectionId )
{
std::lock_guard Guard(Mutex_);

View File

@@ -17,11 +17,11 @@
namespace OpenWifi {
class WSConnection;
class AP_WS_Connection;
class DeviceRegistry : public SubSystemServer {
public:
struct ConnectionEntry {
WSConnection * WSConn_ = nullptr;
AP_WS_Connection * WSConn_ = nullptr;
GWObjects::ConnectionState Conn_;
std::string LastStats;
GWObjects::HealthCheck LastHealthcheck;
@@ -66,7 +66,7 @@ namespace OpenWifi {
}
void SetHealthcheck(uint64_t SerialNumber, const GWObjects::HealthCheck &H);
std::shared_ptr<ConnectionEntry> Register(uint64_t SerialNumber, WSConnection *Conn, uint64_t & ConnectionId);
std::shared_ptr<ConnectionEntry> Register(uint64_t SerialNumber, AP_WS_Connection *Conn, uint64_t & ConnectionId);
inline void UnRegister(const std::string & SerialNumber, uint64_t ConnectionId) {
return UnRegister(Utils::SerialNumberToInt(SerialNumber),ConnectionId);

View File

@@ -1737,91 +1737,112 @@ namespace OpenWifi {
std::ostringstream ofs;
Obj->stringify(ofs);
nlohmann::json D = nlohmann::json::parse(ofs.str());
std::cout << "Start of parsing wifi" << std::endl;
if (D.contains("status")) {
auto Status = D["status"];
if (Status.contains("scan") && Status["scan"].is_array()) {
nlohmann::json ScanArray = Status["scan"];
nlohmann::json ParsedScan = nlohmann::json::array();
for (auto &scan_entry : ScanArray) {
if (scan_entry.contains("ies") && scan_entry["ies"].is_array()) {
auto ies = scan_entry["ies"];
nlohmann::json new_ies=nlohmann::json::array();
for (auto &ie : ies) {
try {
if (ie.contains("type") && ie.contains("data")) {
uint64_t ie_type = ie["type"];
std::string ie_data = ie["data"];
// std::cout << "TYPE:" << ie_type << " DATA:" << ie_data << std::endl;
auto data = Base64Decode2Vec(ie_data);
if (ie_type == ieee80211_eid::WLAN_EID_COUNTRY) {
new_ies.push_back(WFS_WLAN_EID_COUNTRY(data));
} else if (ie_type == ieee80211_eid::WLAN_EID_SUPP_RATES) {
new_ies.push_back(WFS_WLAN_EID_SUPP_RATES(data));
} else if (ie_type == ieee80211_eid::WLAN_EID_FH_PARAMS) {
new_ies.push_back(WFS_WLAN_EID_FH_PARAMS(data));
} else if (ie_type == ieee80211_eid::WLAN_EID_DS_PARAMS) {
new_ies.push_back(WFS_WLAN_EID_DS_PARAMS(data));
} else if (ie_type == ieee80211_eid::WLAN_EID_TIM) {
new_ies.push_back(WFS_WLAN_EID_TIM(data));
} else if (ie_type == ieee80211_eid::WLAN_EID_QBSS_LOAD) {
new_ies.push_back(WFS_WLAN_EID_QBSS_LOAD(data));
} else if (ie_type == ieee80211_eid::WLAN_EID_PWR_CONSTRAINT) {
new_ies.push_back(WFS_WLAN_EID_PWR_CONSTRAINT(data));
} else if (ie_type == ieee80211_eid::WLAN_EID_ERP_INFO) {
new_ies.push_back(WFS_WLAN_EID_ERP_INFO(data));
} else if (ie_type == ieee80211_eid::WLAN_EID_SUPPORTED_REGULATORY_CLASSES) {
new_ies.push_back(WFS_WLAN_EID_SUPPORTED_REGULATORY_CLASSES(data));
} else if (ie_type == ieee80211_eid::WLAN_EID_HT_CAPABILITY) {
new_ies.push_back(WFS_WLAN_EID_HT_CAPABILITY(data));
} else if (ie_type == ieee80211_eid::WLAN_EID_EXT_SUPP_RATES) {
new_ies.push_back(WFS_WLAN_EID_EXT_SUPP_RATES(data));
} else if (ie_type == ieee80211_eid::WLAN_EID_TX_POWER_ENVELOPE) {
new_ies.push_back(WFS_WLAN_EID_TX_POWER_ENVELOPE(data));
} else if (ie_type == ieee80211_eid::WLAN_EID_VHT_CAPABILITY) {
new_ies.push_back(WFS_WLAN_EID_VHT_CAPABILITY(data));
} else if (ie_type == ieee80211_eid::WLAN_EID_RRM_ENABLED_CAPABILITIES) {
new_ies.push_back(WFS_WLAN_EID_RRM_ENABLED_CAPABILITIES(data));
} else if (ie_type == ieee80211_eid::WLAN_EID_EXT_CAPABILITY) {
new_ies.push_back(WFS_WLAN_EID_EXT_CAPABILITY(data));
} else if (ie_type == ieee80211_eid::WLAN_EID_TPC_REPORT) {
new_ies.push_back(WFS_WLAN_EID_TPC_REPORT(data));
} else if (ie_type == ieee80211_eid::WLAN_EID_RSN) {
new_ies.push_back(WFS_WLAN_EID_RSN(data));
} else if (ie_type == ieee80211_eid::WLAN_EID_VENDOR_SPECIFIC) {
new_ies.push_back(WFS_WLAN_EID_VENDOR_SPECIFIC(data));
} else if (ie_type == ieee80211_eid::WLAN_EID_EXTENSION) {
new_ies.push_back(WFS_WLAN_EID_EXTENSION(data));
try {
nlohmann::json D = nlohmann::json::parse(ofs.str());
std::cout << "Start of parsing wifi" << std::endl;
if (D.contains("status")) {
auto Status = D["status"];
if (Status.contains("scan") && Status["scan"].is_array()) {
nlohmann::json ScanArray = Status["scan"];
nlohmann::json ParsedScan = nlohmann::json::array();
for (auto &scan_entry : ScanArray) {
if (scan_entry.contains("ies") && scan_entry["ies"].is_array()) {
auto ies = scan_entry["ies"];
nlohmann::json new_ies = nlohmann::json::array();
for (auto &ie : ies) {
try {
if (ie.contains("type") && ie.contains("data")) {
uint64_t ie_type = ie["type"];
std::string ie_data = ie["data"];
// std::cout << "TYPE:" << ie_type << " DATA:" << ie_data << std::endl;
auto data = Base64Decode2Vec(ie_data);
if (ie_type == ieee80211_eid::WLAN_EID_COUNTRY) {
new_ies.push_back(WFS_WLAN_EID_COUNTRY(data));
} else if (ie_type == ieee80211_eid::WLAN_EID_SUPP_RATES) {
new_ies.push_back(WFS_WLAN_EID_SUPP_RATES(data));
} else if (ie_type == ieee80211_eid::WLAN_EID_FH_PARAMS) {
new_ies.push_back(WFS_WLAN_EID_FH_PARAMS(data));
} else if (ie_type == ieee80211_eid::WLAN_EID_DS_PARAMS) {
new_ies.push_back(WFS_WLAN_EID_DS_PARAMS(data));
} else if (ie_type == ieee80211_eid::WLAN_EID_TIM) {
new_ies.push_back(WFS_WLAN_EID_TIM(data));
} else if (ie_type == ieee80211_eid::WLAN_EID_QBSS_LOAD) {
new_ies.push_back(WFS_WLAN_EID_QBSS_LOAD(data));
} else if (ie_type ==
ieee80211_eid::WLAN_EID_PWR_CONSTRAINT) {
new_ies.push_back(WFS_WLAN_EID_PWR_CONSTRAINT(data));
} else if (ie_type == ieee80211_eid::WLAN_EID_ERP_INFO) {
new_ies.push_back(WFS_WLAN_EID_ERP_INFO(data));
} else if (ie_type ==
ieee80211_eid::
WLAN_EID_SUPPORTED_REGULATORY_CLASSES) {
new_ies.push_back(
WFS_WLAN_EID_SUPPORTED_REGULATORY_CLASSES(data));
} else if (ie_type ==
ieee80211_eid::WLAN_EID_HT_CAPABILITY) {
new_ies.push_back(WFS_WLAN_EID_HT_CAPABILITY(data));
} else if (ie_type ==
ieee80211_eid::WLAN_EID_EXT_SUPP_RATES) {
new_ies.push_back(WFS_WLAN_EID_EXT_SUPP_RATES(data));
} else if (ie_type ==
ieee80211_eid::WLAN_EID_TX_POWER_ENVELOPE) {
new_ies.push_back(WFS_WLAN_EID_TX_POWER_ENVELOPE(data));
} else if (ie_type ==
ieee80211_eid::WLAN_EID_VHT_CAPABILITY) {
new_ies.push_back(WFS_WLAN_EID_VHT_CAPABILITY(data));
} else if (ie_type ==
ieee80211_eid::
WLAN_EID_RRM_ENABLED_CAPABILITIES) {
new_ies.push_back(
WFS_WLAN_EID_RRM_ENABLED_CAPABILITIES(data));
} else if (ie_type ==
ieee80211_eid::WLAN_EID_EXT_CAPABILITY) {
new_ies.push_back(WFS_WLAN_EID_EXT_CAPABILITY(data));
} else if (ie_type == ieee80211_eid::WLAN_EID_TPC_REPORT) {
new_ies.push_back(WFS_WLAN_EID_TPC_REPORT(data));
} else if (ie_type == ieee80211_eid::WLAN_EID_RSN) {
new_ies.push_back(WFS_WLAN_EID_RSN(data));
} else if (ie_type ==
ieee80211_eid::WLAN_EID_VENDOR_SPECIFIC) {
new_ies.push_back(WFS_WLAN_EID_VENDOR_SPECIFIC(data));
} else if (ie_type == ieee80211_eid::WLAN_EID_EXTENSION) {
new_ies.push_back(WFS_WLAN_EID_EXTENSION(data));
} else {
std::cout
<< "Skipping IE: no parsing available: " << ie_type
<< std::endl;
new_ies.push_back(ie);
}
} else {
std::cout
<< "Skipping IE: no parsing available: " << ie_type
<< std::endl;
std::cout << "Skipping IE: no data and type" << std::endl;
new_ies.push_back(ie);
}
} else {
std::cout << "Skipping IE: no data and type" << std::endl;
} catch (...) {
std::cout << "Skipping IE: exception" << std::endl;
Logger.information(fmt::format("Error parsing IEs"));
new_ies.push_back(ie);
}
} catch (...) {
std::cout << "Skipping IE: exception" << std::endl;
Logger.information(fmt::format("Error parsing IEs"));
new_ies.push_back(ie);
}
scan_entry["ies"] = new_ies;
ParsedScan.push_back(scan_entry);
} else {
std::cout << "Skipping scan" << std::endl;
ParsedScan.push_back(scan_entry);
}
scan_entry["ies"] = new_ies;
ParsedScan.push_back(scan_entry);
} else {
std::cout << "Skipping scan" << std::endl;
ParsedScan.push_back(scan_entry);
}
Status["scan"] = ParsedScan;
D["status"] = Status;
}
Status["scan"] = ParsedScan;
D["status"] = Status;
}
Result << to_string(D);
std::cout << "End of parsing wifi" << std::endl;
return true;
} catch (const Poco::Exception &E) {
Logger.log(E);
Logger.error(fmt::format("Failure to parse WifiScan."));
} catch (...) {
Logger.error(fmt::format("Failure to parse WifiScan."));
}
Result << to_string(D);
std::cout << "End of parsing wifi" << std::endl;
return false;
}

View File

@@ -11,19 +11,19 @@
#include "Poco/JSON/Parser.h"
#include "AP_WS_Server.h"
#include "CentralConfig.h"
#include "DeviceRegistry.h"
#include "FileUploader.h"
#include "RESTObjects/RESTAPI_GWobjects.h"
#include "RESTAPI_device_commandHandler.h"
#include "StorageService.h"
#include "RESTAPI_RPC.h"
#include "RESTAPI_device_commandHandler.h"
#include "RESTObjects/RESTAPI_GWobjects.h"
#include "StorageService.h"
#include "TelemetryStream.h"
#include "framework/ow_constants.h"
#include "framework/KafkaTopics.h"
#include "framework/ConfigurationValidator.h"
#include "framework/KafkaTopics.h"
#include "framework/ow_constants.h"
#include "rttys/RTTYS_server.h"
#include "WS_Server.h"
namespace OpenWifi {

View File

@@ -6,10 +6,10 @@
#include "Poco/Net/SSLException.h"
#include "AP_WS_Connection.h"
#include "DeviceRegistry.h"
#include "TelemetryClient.h"
#include "TelemetryStream.h"
#include "DeviceRegistry.h"
#include "WS_Connection.h"
namespace OpenWifi {

View File

@@ -1,84 +0,0 @@
//
// License type: BSD 3-Clause License
// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
//
// Created by Stephane Bourque on 2021-03-04.
// Arilia Wireless Inc.
//
#include "Poco/Net/HTTPHeaderStream.h"
#include "Poco/JSON/Array.h"
#include "Poco/Net/Context.h"
#include "ConfigurationCache.h"
#include "TelemetryStream.h"
#include "WS_Server.h"
#include <openssl/ssl.h>
namespace OpenWifi {
bool WebSocketServer::ValidateCertificate(const std::string & ConnectionId, const Poco::Crypto::X509Certificate & Certificate) {
if(IsCertOk()) {
Logger().debug(fmt::format("CERTIFICATE({}): issuer='{}' cn='{}'", ConnectionId, Certificate.issuerName(),Certificate.commonName()));
if(!Certificate.issuedBy(*IssuerCert_)) {
Logger().debug(fmt::format("CERTIFICATE({}): issuer mismatch. Local='{}' Incoming='{}'", ConnectionId, IssuerCert_->issuerName(), Certificate.issuerName()));
return false;
}
return true;
}
return false;
}
int WebSocketServer::Start() {
// ReactorPool_.Start("DeviceReactorPool_");
for(const auto & Svr : ConfigServersList_ ) {
Logger().notice( fmt::format("Starting: {}:{} Keyfile:{} CertFile: {}",
Svr.Address(),
Svr.Port(),
Svr.KeyFile(),Svr.CertFile()));
Svr.LogCert(Logger());
if(!Svr.RootCA().empty())
Svr.LogCas(Logger());
auto Sock{Svr.CreateSecureSocket(Logger())};
if(!IsCertOk()) {
IssuerCert_ = std::make_unique<Poco::Crypto::X509Certificate>(Svr.IssuerCertFile());
Logger().information( fmt::format("Certificate Issuer Name:{}",IssuerCert_->issuerName()));
}
auto NewSocketAcceptor = std::make_unique<ws_server_reactor_type_t>(Sock, Reactor_); // , 2 /*Poco::Environment::processorCount()*2) */ );
Acceptors_.push_back(std::move(NewSocketAcceptor));
}
auto ProvString = MicroService::instance().ConfigGetString("autoprovisioning.process","default");
if(ProvString!="default") {
auto Tokens = Poco::StringTokenizer(ProvString, ",");
for (const auto &i : Tokens) {
if (i == "prov")
LookAtProvisioning_ = true;
else
UseDefaultConfig_ = true;
}
} else {
UseDefaultConfig_ = true;
}
SimulatorId_ = MicroService::instance().ConfigGetString("simulatorid","");
SimulatorEnabled_ = !SimulatorId_.empty();
ReactorThread_.setStackSize(3000000);
ReactorThread_.start(Reactor_);
Utils::SetThreadName(ReactorThread_,"device-reactor");
return 0;
}
void WebSocketServer::Stop() {
Logger().notice("Stopping reactors...");
// ReactorPool_.Stop();
Reactor_.stop();
ReactorThread_.join();
}
} //namespace

View File

@@ -1,76 +0,0 @@
//
// License type: BSD 3-Clause License
// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
//
// Created by Stephane Bourque on 2021-03-04.
// Arilia Wireless Inc.
//
#pragma once
#include <mutex>
#include <thread>
#include <array>
#include <ctime>
#include "framework/MicroService.h"
#include "Poco/AutoPtr.h"
#include "Poco/Net/SocketReactor.h"
#include "Poco/Net/ParallelSocketAcceptor.h"
#include "Poco/Net/SocketAcceptor.h"
#include "WS_Connection.h"
#include "WS_ReactorPool.h"
namespace OpenWifi {
class WebSocketServer : public SubSystemServer {
public:
static auto instance() {
static auto instance_ = new WebSocketServer;
return instance_;
}
int Start() override;
void Stop() override;
bool IsCertOk() { return IssuerCert_!= nullptr; }
bool ValidateCertificate(const std::string & ConnectionId, const Poco::Crypto::X509Certificate & Certificate);
// Poco::Net::SocketReactor & GetNextReactor() { return ReactorPool_.NextReactor(); }
inline bool IsSimSerialNumber(const std::string & SerialNumber) const {
return IsSim(SerialNumber) && SerialNumber == SimulatorId_;
}
inline static bool IsSim(const std::string & SerialNumber) {
return SerialNumber.substr(0,6) == "53494d";
}
inline bool IsSimEnabled() const {
return SimulatorEnabled_;
}
inline bool UseProvisioning() const { return LookAtProvisioning_; }
inline bool UseDefaults() const { return UseDefaultConfig_; }
private:
std::unique_ptr<Poco::Crypto::X509Certificate> IssuerCert_;
// typedef std::unique_ptr<Poco::Net::ParallelSocketAcceptor<WSConnection, Poco::Net::SocketReactor>> ws_server_reactor_type_t;
typedef Poco::Net::SocketAcceptor<WSConnection> ws_server_reactor_type_t;
std::vector<std::unique_ptr<ws_server_reactor_type_t>> Acceptors_;
Poco::Net::SocketReactor Reactor_;
Poco::Thread ReactorThread_;
std::string SimulatorId_;
bool LookAtProvisioning_ = false;
bool UseDefaultConfig_ = true;
bool SimulatorEnabled_=false;
WebSocketServer() noexcept:
SubSystemServer("WebSocketServer", "WS-SVR", "ucentral.websocket") {
}
};
inline auto WebSocketServer() { return WebSocketServer::instance(); }
} //namespace

View File

@@ -6,21 +6,21 @@
// Arilia Wireless Inc.
//
#include "AP_WS_Server.h"
#include "CapabilitiesCache.h"
#include "CentralConfig.h"
#include "ConfigurationCache.h"
#include "Daemon.h"
#include "DeviceRegistry.h"
#include "FindCountry.h"
#include "OUIServer.h"
#include "Poco/Data/RecordSet.h"
#include "Poco/Net/IPAddress.h"
#include "SDKcalls.h"
#include "SerialNumberCache.h"
#include "StateUtils.h"
#include "StorageService.h"
#include "framework/MicroService.h"
#include "CapabilitiesCache.h"
#include "FindCountry.h"
#include "WS_Server.h"
#include "SDKcalls.h"
#include "StateUtils.h"
namespace OpenWifi {
@@ -326,7 +326,7 @@ namespace OpenWifi {
bool Found = false;
std::string FoundConfig;
if(WebSocketServer()->UseProvisioning()) {
if(AP_WS_Server()->UseProvisioning()) {
if(SDKCalls::GetProvisioningConfiguration(SerialNumber, FoundConfig)) {
if(FoundConfig != "none") {
Found = true;
@@ -337,7 +337,7 @@ namespace OpenWifi {
}
}
if (!Found && WebSocketServer()->UseDefaults() && FindDefaultConfigurationForModel(Compat, DefConfig)) {
if (!Found && AP_WS_Server()->UseDefaults() && FindDefaultConfigurationForModel(Compat, DefConfig)) {
Config::Config NewConfig(DefConfig.Configuration);
NewConfig.SetUUID(Now);
D.Configuration = NewConfig.get();