Merge pull request #202 from Telecominfraproject/WIFI-10846

https://telecominfraproject.atlassian.net/browse/WIFI-10846
This commit is contained in:
Stephane Bourque
2022-09-17 08:58:18 -07:00
committed by GitHub
10 changed files with 77 additions and 54 deletions

2
build
View File

@@ -1 +1 @@
74 75

View File

@@ -196,7 +196,12 @@ components:
sessionId: sessionId:
type: integer type: integer
format: int64 format: int64
connectionCompletionTime:
type: number
format: double
totalConnectionTime:
type: integer
format: int64
DeviceList: DeviceList:
type: object type: object

View File

@@ -18,7 +18,7 @@
namespace OpenWifi { namespace OpenWifi {
class AP_WS_Connection { class AP_WS_Connection {
static constexpr int BufSize = 128000; static constexpr int BufSize = 256000;
public: public:
explicit AP_WS_Connection(Poco::Net::HTTPServerRequest &request, explicit AP_WS_Connection(Poco::Net::HTTPServerRequest &request,
Poco::Net::HTTPServerResponse &response, std::uint64_t connection_id); Poco::Net::HTTPServerResponse &response, std::uint64_t connection_id);
@@ -101,6 +101,8 @@ namespace OpenWifi {
GWObjects::ConnectionState State_; GWObjects::ConnectionState State_;
std::string LastStats_; std::string LastStats_;
GWObjects::HealthCheck LastHealthcheck_; GWObjects::HealthCheck LastHealthcheck_;
std::chrono::time_point<std::chrono::high_resolution_clock> ConnectionStart_ = std::chrono::high_resolution_clock::now();
std::chrono::duration<double, std::milli> ConnectionCompletionTime_;
void CompleteStartup(); void CompleteStartup();
bool StartTelemetry(); bool StartTelemetry();

View File

@@ -28,18 +28,6 @@ void AP_WS_Connection::Process_connect(Poco::JSON::Object::Ptr ParamsObj, const
State_.PendingUUID = 0; State_.PendingUUID = 0;
State_.Address = Utils::FormatIPv6(WS_->peerAddress().toString()); State_.Address = Utils::FormatIPv6(WS_->peerAddress().toString());
CId_ = SerialNumber_ + "@" + CId_; CId_ = SerialNumber_ + "@" + CId_;
// We need to verify the certificate if we have one
if(State_.VerifiedCertificate == GWObjects::VALID_CERTIFICATE) {
if (( Utils::SerialNumberMatch(CN_, SerialNumber_)) ||
AP_WS_Server()->IsSimSerialNumber(CN_)) {
State_.VerifiedCertificate = GWObjects::VERIFIED;
poco_information(Logger(), fmt::format("CONNECT({}): Fully validated and authenticated device.", CId_));
} else {
State_.VerifiedCertificate = GWObjects::MISMATCH_SERIAL;
poco_information(Logger(),
fmt::format("CONNECT({}): Serial number mismatch. CN={} Serial={}", CId_, CN_, SerialNumber_));
}
}
auto IP = PeerAddress_.toString(); auto IP = PeerAddress_.toString();
if(IP.substr(0,7)=="::ffff:") { if(IP.substr(0,7)=="::ffff:") {
@@ -79,8 +67,31 @@ void AP_WS_Connection::Process_connect(Poco::JSON::Object::Ptr ParamsObj, const
LookForUpgrade(UUID,UpgradedUUID); LookForUpgrade(UUID,UpgradedUUID);
State_.UUID = UpgradedUUID; State_.UUID = UpgradedUUID;
} }
State_.Compatible = Compatible_; State_.Compatible = Compatible_;
State_.Connected = true; State_.Connected = true;
ConnectionCompletionTime_ = std::chrono::high_resolution_clock::now() - ConnectionStart_;
State_.connectionCompletionTime = ConnectionCompletionTime_.count();
if(State_.VerifiedCertificate == GWObjects::VALID_CERTIFICATE) {
if (( Utils::SerialNumberMatch(CN_, SerialNumber_)) ||
AP_WS_Server()->IsSimSerialNumber(CN_)) {
State_.VerifiedCertificate = GWObjects::VERIFIED;
poco_information(Logger(), fmt::format("CONNECT({}): Fully validated and authenticated device. Session={} ConnectionCompletion Time={}",
CId_,
State_.sessionId,
State_.connectionCompletionTime ));
} else {
State_.VerifiedCertificate = GWObjects::MISMATCH_SERIAL;
poco_information(Logger(),
fmt::format("CONNECT({}): Serial number mismatch. CN={} Serial={} Session={} ConnectionCompletion Time={}",
CId_,
CN_,
SerialNumber_,
State_.sessionId,
State_.connectionCompletionTime ));
}
}
WebSocketClientNotificationDeviceConnected(SerialNumber_); WebSocketClientNotificationDeviceConnected(SerialNumber_);

View File

@@ -37,7 +37,7 @@ namespace OpenWifi {
using session_tuple=std::tuple<std::uint64_t,AP_WS_Connection *,std::uint64_t>; using session_tuple=std::tuple<std::uint64_t,AP_WS_Connection *,std::uint64_t>;
std::vector<session_tuple> connections; std::vector<session_tuple> connections;
{ {
std::shared_lock Guard(M_); std::shared_lock Guard(LocalMutex_);
NumberOfConnectedDevices_ = 0; NumberOfConnectedDevices_ = 0;
AverageDeviceConnectionTime_ = 0; AverageDeviceConnectionTime_ = 0;
@@ -68,8 +68,8 @@ namespace OpenWifi {
} }
} }
bool DeviceRegistry::GetStatistics(uint64_t SerialNumber, std::string & Statistics) { bool DeviceRegistry::GetStatistics(uint64_t SerialNumber, std::string & Statistics) const {
std::shared_lock Guard(M_); std::shared_lock Guard(LocalMutex_);
auto Device = SerialNumbers_.find(SerialNumber); auto Device = SerialNumbers_.find(SerialNumber);
if(Device == SerialNumbers_.end()) if(Device == SerialNumbers_.end())
return false; return false;
@@ -77,18 +77,17 @@ namespace OpenWifi {
return true; return true;
} }
bool DeviceRegistry::GetState(uint64_t SerialNumber, GWObjects::ConnectionState & State) { bool DeviceRegistry::GetState(uint64_t SerialNumber, GWObjects::ConnectionState & State) const {
std::shared_lock Guard(M_); std::shared_lock Guard(LocalMutex_);
auto Device = SerialNumbers_.find(SerialNumber); auto Device = SerialNumbers_.find(SerialNumber);
if(Device == SerialNumbers_.end()) if(Device == SerialNumbers_.end())
return false; return false;
State = Device->second.second->State_; State = Device->second.second->State_;
return true; return true;
} }
bool DeviceRegistry::EndSession(std::uint64_t connection_id, [[maybe_unused]] AP_WS_Connection * connection, std::uint64_t serial_number) { bool DeviceRegistry::EndSession(std::uint64_t connection_id, [[maybe_unused]] AP_WS_Connection * connection, std::uint64_t serial_number) {
std::unique_lock G(M_); std::unique_lock G(LocalMutex_);
auto Session = Sessions_.find(connection_id); auto Session = Sessions_.find(connection_id);
if(Session==end(Sessions_)) { if(Session==end(Sessions_)) {
@@ -111,8 +110,8 @@ namespace OpenWifi {
return SessionDeleted; return SessionDeleted;
} }
bool DeviceRegistry::GetHealthcheck(uint64_t SerialNumber, GWObjects::HealthCheck & CheckData) { bool DeviceRegistry::GetHealthcheck(uint64_t SerialNumber, GWObjects::HealthCheck & CheckData) const {
std::shared_lock Guard(M_); std::shared_lock Guard(LocalMutex_);
auto Device = SerialNumbers_.find(SerialNumber); auto Device = SerialNumbers_.find(SerialNumber);
if(Device == SerialNumbers_.end()) if(Device == SerialNumbers_.end())
@@ -122,13 +121,13 @@ namespace OpenWifi {
return true; return true;
} }
bool DeviceRegistry::Connected(uint64_t SerialNumber) { bool DeviceRegistry::Connected(uint64_t SerialNumber) const {
std::shared_lock Guard(M_); std::shared_lock Guard(LocalMutex_);
return SerialNumbers_.find(SerialNumber) != SerialNumbers_.end(); return SerialNumbers_.find(SerialNumber) != SerialNumbers_.end();
} }
bool DeviceRegistry::SendFrame(uint64_t SerialNumber, const std::string & Payload) { bool DeviceRegistry::SendFrame(uint64_t SerialNumber, const std::string & Payload) const {
std::shared_lock Guard(M_); std::shared_lock Guard(LocalMutex_);
auto Device = SerialNumbers_.find(SerialNumber); auto Device = SerialNumbers_.find(SerialNumber);
if(Device==SerialNumbers_.end()) if(Device==SerialNumbers_.end())
return false; return false;
@@ -143,7 +142,7 @@ namespace OpenWifi {
} }
void DeviceRegistry::StopWebSocketTelemetry(uint64_t SerialNumber) { void DeviceRegistry::StopWebSocketTelemetry(uint64_t SerialNumber) {
std::shared_lock Guard(M_); std::shared_lock Guard(LocalMutex_);
auto Device = SerialNumbers_.find(SerialNumber); auto Device = SerialNumbers_.find(SerialNumber);
if(Device==end(SerialNumbers_)) if(Device==end(SerialNumbers_))
@@ -152,7 +151,7 @@ namespace OpenWifi {
} }
void DeviceRegistry::SetWebSocketTelemetryReporting(uint64_t SerialNumber, uint64_t Interval, uint64_t Lifetime) { void DeviceRegistry::SetWebSocketTelemetryReporting(uint64_t SerialNumber, uint64_t Interval, uint64_t Lifetime) {
std::shared_lock Guard(M_); std::shared_lock Guard(LocalMutex_);
auto Device = SerialNumbers_.find(SerialNumber); auto Device = SerialNumbers_.find(SerialNumber);
if(Device==end(SerialNumbers_)) if(Device==end(SerialNumbers_))
@@ -161,7 +160,7 @@ namespace OpenWifi {
} }
void DeviceRegistry::SetKafkaTelemetryReporting(uint64_t SerialNumber, uint64_t Interval, uint64_t Lifetime) { void DeviceRegistry::SetKafkaTelemetryReporting(uint64_t SerialNumber, uint64_t Interval, uint64_t Lifetime) {
std::shared_lock Guard(M_); std::shared_lock Guard(LocalMutex_);
auto Device = SerialNumbers_.find(SerialNumber); auto Device = SerialNumbers_.find(SerialNumber);
if(Device==end(SerialNumbers_)) if(Device==end(SerialNumbers_))
@@ -170,7 +169,7 @@ namespace OpenWifi {
} }
void DeviceRegistry::StopKafkaTelemetry(uint64_t SerialNumber) { void DeviceRegistry::StopKafkaTelemetry(uint64_t SerialNumber) {
std::shared_lock Guard(M_); std::shared_lock Guard(LocalMutex_);
auto Device = SerialNumbers_.find(SerialNumber); auto Device = SerialNumbers_.find(SerialNumber);
if(Device==end(SerialNumbers_)) if(Device==end(SerialNumbers_))
@@ -186,7 +185,7 @@ namespace OpenWifi {
uint64_t & TelemetryKafkaCount, uint64_t & TelemetryKafkaCount,
uint64_t & TelemetryWebSocketPackets, uint64_t & TelemetryWebSocketPackets,
uint64_t & TelemetryKafkaPackets) { uint64_t & TelemetryKafkaPackets) {
std::shared_lock Guard(M_); std::shared_lock Guard(LocalMutex_);
auto Device = SerialNumbers_.find(SerialNumber); auto Device = SerialNumbers_.find(SerialNumber);
if(Device==end(SerialNumbers_)) if(Device==end(SerialNumbers_))
@@ -202,7 +201,7 @@ namespace OpenWifi {
} }
bool DeviceRegistry::SendRadiusAccountingData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size) { bool DeviceRegistry::SendRadiusAccountingData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size) {
std::shared_lock Guard(M_); std::shared_lock Guard(LocalMutex_);
auto Device = SerialNumbers_.find(Utils::SerialNumberToInt(SerialNumber)); auto Device = SerialNumbers_.find(Utils::SerialNumberToInt(SerialNumber));
if(Device==SerialNumbers_.end()) if(Device==SerialNumbers_.end())
return false; return false;
@@ -216,7 +215,7 @@ namespace OpenWifi {
} }
bool DeviceRegistry::SendRadiusAuthenticationData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size) { bool DeviceRegistry::SendRadiusAuthenticationData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size) {
std::shared_lock Guard(M_); std::shared_lock Guard(LocalMutex_);
auto Device = SerialNumbers_.find(Utils::SerialNumberToInt(SerialNumber)); auto Device = SerialNumbers_.find(Utils::SerialNumberToInt(SerialNumber));
if(Device==SerialNumbers_.end()) if(Device==SerialNumbers_.end())
return false; return false;
@@ -230,7 +229,7 @@ namespace OpenWifi {
} }
bool DeviceRegistry::SendRadiusCoAData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size) { bool DeviceRegistry::SendRadiusCoAData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size) {
std::shared_lock Guard(M_); std::shared_lock Guard(LocalMutex_);
auto Device = SerialNumbers_.find(Utils::SerialNumberToInt(SerialNumber)); auto Device = SerialNumbers_.find(Utils::SerialNumberToInt(SerialNumber));
if(Device==SerialNumbers_.end()) if(Device==SerialNumbers_.end())
return false; return false;
@@ -243,13 +242,14 @@ namespace OpenWifi {
return false; return false;
} }
void DeviceRegistry::SetPendingUUID(uint64_t SerialNumber, uint64_t PendingUUID) { /* void DeviceRegistry::SetPendingUUID(uint64_t SerialNumber, uint64_t PendingUUID) {
std::unique_lock Guard(M_); std::unique_lock Guard(LocalMutex_);
auto Device = SerialNumbers_.find(SerialNumber); auto Device = SerialNumbers_.find(SerialNumber);
if(Device==SerialNumbers_.end()) if(Device==SerialNumbers_.end())
return; return;
Device->second.second->State_.PendingUUID = PendingUUID; Device->second.second->State_.PendingUUID = PendingUUID;
} }
*/
} // namespace } // namespace

View File

@@ -33,45 +33,46 @@ namespace OpenWifi {
int Start() override; int Start() override;
void Stop() override; void Stop() override;
inline bool GetStatistics(const std::string &SerialNumber, std::string & Statistics) { inline bool GetStatistics(const std::string &SerialNumber, std::string & Statistics) const {
return GetStatistics(Utils::SerialNumberToInt(SerialNumber),Statistics); return GetStatistics(Utils::SerialNumberToInt(SerialNumber),Statistics);
} }
bool GetStatistics(std::uint64_t SerialNumber, std::string & Statistics); bool GetStatistics(std::uint64_t SerialNumber, std::string & Statistics) const;
inline bool GetState(const std::string & SerialNumber, GWObjects::ConnectionState & State) { inline bool GetState(const std::string & SerialNumber, GWObjects::ConnectionState & State) const {
return GetState(Utils::SerialNumberToInt(SerialNumber), State); return GetState(Utils::SerialNumberToInt(SerialNumber), State);
} }
bool GetState(std::uint64_t SerialNumber, GWObjects::ConnectionState & State); bool GetState(std::uint64_t SerialNumber, GWObjects::ConnectionState & State) const;
inline bool GetHealthcheck(const std::string &SerialNumber, GWObjects::HealthCheck & CheckData) { inline bool GetHealthcheck(const std::string &SerialNumber, GWObjects::HealthCheck & CheckData) const {
return GetHealthcheck(Utils::SerialNumberToInt(SerialNumber), CheckData); return GetHealthcheck(Utils::SerialNumberToInt(SerialNumber), CheckData);
} }
bool GetHealthcheck(std::uint64_t SerialNumber, GWObjects::HealthCheck & CheckData); bool GetHealthcheck(std::uint64_t SerialNumber, GWObjects::HealthCheck & CheckData) const ;
bool Connected(uint64_t SerialNumber); bool Connected(uint64_t SerialNumber) const ;
inline bool SendFrame(const std::string & SerialNumber, const std::string & Payload) { inline bool SendFrame(const std::string & SerialNumber, const std::string & Payload) const {
return SendFrame(Utils::SerialNumberToInt(SerialNumber), Payload); return SendFrame(Utils::SerialNumberToInt(SerialNumber), Payload);
} }
bool SendFrame(std::uint64_t SerialNumber, const std::string & Payload); bool SendFrame(std::uint64_t SerialNumber, const std::string & Payload) const ;
inline void SetPendingUUID(const std::string & SerialNumber, uint64_t PendingUUID) { /* inline void SetPendingUUID(const std::string & SerialNumber, uint64_t PendingUUID) {
return SetPendingUUID(Utils::SerialNumberToInt(SerialNumber), PendingUUID); return SetPendingUUID(Utils::SerialNumberToInt(SerialNumber), PendingUUID);
} }
void SetPendingUUID(std::uint64_t SerialNumber, std::uint64_t PendingUUID); void SetPendingUUID(std::uint64_t SerialNumber, std::uint64_t PendingUUID);
*/
bool SendRadiusAuthenticationData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size); bool SendRadiusAuthenticationData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size);
bool SendRadiusAccountingData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size); bool SendRadiusAccountingData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size);
bool SendRadiusCoAData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size); bool SendRadiusCoAData(const std::string & SerialNumber, const unsigned char * buffer, std::size_t size);
inline void StartSession(uint64_t ConnectionId, AP_WS_Connection * connection) { inline void StartSession(uint64_t ConnectionId, AP_WS_Connection * connection) {
std::unique_lock G(M_); std::unique_lock G(LocalMutex_);
Sessions_[ConnectionId] = connection; Sessions_[ConnectionId] = connection;
} }
inline void SetSessionDetails(std::uint64_t connection_id, AP_WS_Connection * connection, uint64_t SerialNumber) { inline void SetSessionDetails(std::uint64_t connection_id, AP_WS_Connection * connection, uint64_t SerialNumber) {
std::unique_lock G(M_); std::unique_lock G(LocalMutex_);
auto Hint = Sessions_.find(connection_id); auto Hint = Sessions_.find(connection_id);
if(Hint!=Sessions_.end() && Hint->second==connection) { if(Hint!=Sessions_.end() && Hint->second==connection) {
Logger().information(fmt::format("Starting session {}, serial {}.", connection_id, Utils::IntToSerialNumber(SerialNumber))); Logger().information(fmt::format("Starting session {}, serial {}.", connection_id, Utils::IntToSerialNumber(SerialNumber)));
@@ -102,7 +103,7 @@ namespace OpenWifi {
} }
private: private:
std::shared_mutex M_; mutable std::shared_mutex LocalMutex_;
std::map<std::uint64_t, AP_WS_Connection *> Sessions_; std::map<std::uint64_t, AP_WS_Connection *> Sessions_;
std::map<std::uint64_t, std::pair<std::uint64_t, AP_WS_Connection *>> SerialNumbers_; std::map<std::uint64_t, std::pair<std::uint64_t, AP_WS_Connection *>> SerialNumbers_;

View File

@@ -387,7 +387,7 @@ namespace OpenWifi {
Params.stringify(ParamStream); Params.stringify(ParamStream);
Cmd.Details = ParamStream.str(); Cmd.Details = ParamStream.str();
DeviceRegistry()->SetPendingUUID(SerialNumber_, NewUUID); // DeviceRegistry()->SetPendingUUID(SerialNumber_, NewUUID);
return RESTAPI_RPC::WaitForCommand(CMD_RPC,true,Cmd, Params, *Request, *Response, 60000ms, nullptr, this, Logger_); return RESTAPI_RPC::WaitForCommand(CMD_RPC,true,Cmd, Params, *Request, *Response, 60000ms, nullptr, this, Logger_);
} }
return BadRequest(RESTAPI::Errors::RecordNotUpdated); return BadRequest(RESTAPI::Errors::RecordNotUpdated);

View File

@@ -205,6 +205,8 @@ namespace OpenWifi::GWObjects {
field_to_json(Obj,"locale", locale); field_to_json(Obj,"locale", locale);
field_to_json(Obj,"started", started); field_to_json(Obj,"started", started);
field_to_json(Obj,"sessionId", sessionId); field_to_json(Obj,"sessionId", sessionId);
field_to_json(Obj,"connectionCompletionTime", connectionCompletionTime);
field_to_json(Obj,"totalConnectionTime", OpenWifi::Now() - started);
switch(VerifiedCertificate) { switch(VerifiedCertificate) {
case NO_CERTIFICATE: case NO_CERTIFICATE:

View File

@@ -40,6 +40,8 @@ namespace OpenWifi::GWObjects {
std::string locale; std::string locale;
uint64_t started=0; uint64_t started=0;
uint64_t sessionId=0; uint64_t sessionId=0;
double connectionCompletionTime=0.0;
void to_json(Poco::JSON::Object &Obj) const; void to_json(Poco::JSON::Object &Obj) const;
}; };

View File

@@ -1666,7 +1666,7 @@ namespace OpenWifi {
inline const PropertiesFileServerEntry & Host(uint64_t index) { return ConfigServersList_[index]; }; inline const PropertiesFileServerEntry & Host(uint64_t index) { return ConfigServersList_[index]; };
inline uint64_t HostSize() const { return ConfigServersList_.size(); } inline uint64_t HostSize() const { return ConfigServersList_.size(); }
inline Poco::Logger &Logger() { if(Log_) inline Poco::Logger &Logger() const { if(Log_)
return Log_->L; return Log_->L;
return Poco::Logger::get("tmp"); return Poco::Logger::get("tmp");
}; };
@@ -1685,7 +1685,7 @@ namespace OpenWifi {
std::recursive_mutex Mutex_; std::recursive_mutex Mutex_;
std::vector<PropertiesFileServerEntry> ConfigServersList_; std::vector<PropertiesFileServerEntry> ConfigServersList_;
private: private:
std::unique_ptr<LoggerWrapper> Log_; mutable std::unique_ptr<LoggerWrapper> Log_;
// Poco::Logger &Logger_; // Poco::Logger &Logger_;
std::string Name_; std::string Name_;
std::string LoggerPrefix_; std::string LoggerPrefix_;