diff --git a/build b/build index 0aeb5485..a76c74dc 100644 --- a/build +++ b/build @@ -1 +1 @@ -74 \ No newline at end of file +75 \ No newline at end of file diff --git a/openapi/owgw.yaml b/openapi/owgw.yaml index 9dc7e3d7..a448131f 100644 --- a/openapi/owgw.yaml +++ b/openapi/owgw.yaml @@ -196,7 +196,12 @@ components: sessionId: type: integer format: int64 - + connectionCompletionTime: + type: number + format: double + totalConnectionTime: + type: integer + format: int64 DeviceList: type: object diff --git a/src/AP_WS_Connection.h b/src/AP_WS_Connection.h index b294623f..540ebfa3 100644 --- a/src/AP_WS_Connection.h +++ b/src/AP_WS_Connection.h @@ -18,7 +18,7 @@ namespace OpenWifi { class AP_WS_Connection { - static constexpr int BufSize = 128000; + static constexpr int BufSize = 256000; public: explicit AP_WS_Connection(Poco::Net::HTTPServerRequest &request, Poco::Net::HTTPServerResponse &response, std::uint64_t connection_id); @@ -101,6 +101,8 @@ namespace OpenWifi { GWObjects::ConnectionState State_; std::string LastStats_; GWObjects::HealthCheck LastHealthcheck_; + std::chrono::time_point ConnectionStart_ = std::chrono::high_resolution_clock::now(); + std::chrono::duration ConnectionCompletionTime_; void CompleteStartup(); bool StartTelemetry(); diff --git a/src/AP_WS_Process_connect.cpp b/src/AP_WS_Process_connect.cpp index 454a034e..7b0c6335 100644 --- a/src/AP_WS_Process_connect.cpp +++ b/src/AP_WS_Process_connect.cpp @@ -28,18 +28,6 @@ void AP_WS_Connection::Process_connect(Poco::JSON::Object::Ptr ParamsObj, const State_.PendingUUID = 0; State_.Address = Utils::FormatIPv6(WS_->peerAddress().toString()); 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(); 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); State_.UUID = UpgradedUUID; } + State_.Compatible = Compatible_; 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_); diff --git a/src/DeviceRegistry.cpp b/src/DeviceRegistry.cpp index d1fabcdb..25bac81b 100644 --- a/src/DeviceRegistry.cpp +++ b/src/DeviceRegistry.cpp @@ -37,7 +37,7 @@ namespace OpenWifi { using session_tuple=std::tuple; std::vector connections; { - std::shared_lock Guard(M_); + std::shared_lock Guard(LocalMutex_); NumberOfConnectedDevices_ = 0; AverageDeviceConnectionTime_ = 0; @@ -68,8 +68,8 @@ namespace OpenWifi { } } - bool DeviceRegistry::GetStatistics(uint64_t SerialNumber, std::string & Statistics) { - std::shared_lock Guard(M_); + bool DeviceRegistry::GetStatistics(uint64_t SerialNumber, std::string & Statistics) const { + std::shared_lock Guard(LocalMutex_); auto Device = SerialNumbers_.find(SerialNumber); if(Device == SerialNumbers_.end()) return false; @@ -77,18 +77,17 @@ namespace OpenWifi { return true; } - bool DeviceRegistry::GetState(uint64_t SerialNumber, GWObjects::ConnectionState & State) { - std::shared_lock Guard(M_); + bool DeviceRegistry::GetState(uint64_t SerialNumber, GWObjects::ConnectionState & State) const { + std::shared_lock Guard(LocalMutex_); auto Device = SerialNumbers_.find(SerialNumber); if(Device == SerialNumbers_.end()) return false; - State = Device->second.second->State_; return true; } 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); if(Session==end(Sessions_)) { @@ -111,8 +110,8 @@ namespace OpenWifi { return SessionDeleted; } - bool DeviceRegistry::GetHealthcheck(uint64_t SerialNumber, GWObjects::HealthCheck & CheckData) { - std::shared_lock Guard(M_); + bool DeviceRegistry::GetHealthcheck(uint64_t SerialNumber, GWObjects::HealthCheck & CheckData) const { + std::shared_lock Guard(LocalMutex_); auto Device = SerialNumbers_.find(SerialNumber); if(Device == SerialNumbers_.end()) @@ -122,13 +121,13 @@ namespace OpenWifi { return true; } - bool DeviceRegistry::Connected(uint64_t SerialNumber) { - std::shared_lock Guard(M_); + bool DeviceRegistry::Connected(uint64_t SerialNumber) const { + std::shared_lock Guard(LocalMutex_); return SerialNumbers_.find(SerialNumber) != SerialNumbers_.end(); } - bool DeviceRegistry::SendFrame(uint64_t SerialNumber, const std::string & Payload) { - std::shared_lock Guard(M_); + bool DeviceRegistry::SendFrame(uint64_t SerialNumber, const std::string & Payload) const { + std::shared_lock Guard(LocalMutex_); auto Device = SerialNumbers_.find(SerialNumber); if(Device==SerialNumbers_.end()) return false; @@ -143,7 +142,7 @@ namespace OpenWifi { } void DeviceRegistry::StopWebSocketTelemetry(uint64_t SerialNumber) { - std::shared_lock Guard(M_); + std::shared_lock Guard(LocalMutex_); auto Device = SerialNumbers_.find(SerialNumber); if(Device==end(SerialNumbers_)) @@ -152,7 +151,7 @@ namespace OpenWifi { } 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); if(Device==end(SerialNumbers_)) @@ -161,7 +160,7 @@ namespace OpenWifi { } 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); if(Device==end(SerialNumbers_)) @@ -170,7 +169,7 @@ namespace OpenWifi { } void DeviceRegistry::StopKafkaTelemetry(uint64_t SerialNumber) { - std::shared_lock Guard(M_); + std::shared_lock Guard(LocalMutex_); auto Device = SerialNumbers_.find(SerialNumber); if(Device==end(SerialNumbers_)) @@ -186,7 +185,7 @@ namespace OpenWifi { uint64_t & TelemetryKafkaCount, uint64_t & TelemetryWebSocketPackets, uint64_t & TelemetryKafkaPackets) { - std::shared_lock Guard(M_); + std::shared_lock Guard(LocalMutex_); auto Device = SerialNumbers_.find(SerialNumber); 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) { - std::shared_lock Guard(M_); + std::shared_lock Guard(LocalMutex_); auto Device = SerialNumbers_.find(Utils::SerialNumberToInt(SerialNumber)); if(Device==SerialNumbers_.end()) return false; @@ -216,7 +215,7 @@ namespace OpenWifi { } 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)); if(Device==SerialNumbers_.end()) return false; @@ -230,7 +229,7 @@ namespace OpenWifi { } 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)); if(Device==SerialNumbers_.end()) return false; @@ -243,13 +242,14 @@ namespace OpenWifi { return false; } - void DeviceRegistry::SetPendingUUID(uint64_t SerialNumber, uint64_t PendingUUID) { - std::unique_lock Guard(M_); +/* void DeviceRegistry::SetPendingUUID(uint64_t SerialNumber, uint64_t PendingUUID) { + std::unique_lock Guard(LocalMutex_); auto Device = SerialNumbers_.find(SerialNumber); if(Device==SerialNumbers_.end()) return; Device->second.second->State_.PendingUUID = PendingUUID; } +*/ } // namespace \ No newline at end of file diff --git a/src/DeviceRegistry.h b/src/DeviceRegistry.h index c9acc2e7..e85fa55a 100644 --- a/src/DeviceRegistry.h +++ b/src/DeviceRegistry.h @@ -33,45 +33,46 @@ namespace OpenWifi { int Start() 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); } - 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); } - 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); } - 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); } - 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); } 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 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); inline void StartSession(uint64_t ConnectionId, AP_WS_Connection * connection) { - std::unique_lock G(M_); + std::unique_lock G(LocalMutex_); Sessions_[ConnectionId] = connection; } 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); if(Hint!=Sessions_.end() && Hint->second==connection) { Logger().information(fmt::format("Starting session {}, serial {}.", connection_id, Utils::IntToSerialNumber(SerialNumber))); @@ -102,7 +103,7 @@ namespace OpenWifi { } private: - std::shared_mutex M_; + mutable std::shared_mutex LocalMutex_; std::map Sessions_; std::map> SerialNumbers_; diff --git a/src/RESTAPI/RESTAPI_device_commandHandler.cpp b/src/RESTAPI/RESTAPI_device_commandHandler.cpp index c898a01a..bd6c4575 100644 --- a/src/RESTAPI/RESTAPI_device_commandHandler.cpp +++ b/src/RESTAPI/RESTAPI_device_commandHandler.cpp @@ -387,7 +387,7 @@ namespace OpenWifi { Params.stringify(ParamStream); 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 BadRequest(RESTAPI::Errors::RecordNotUpdated); diff --git a/src/RESTObjects/RESTAPI_GWobjects.cpp b/src/RESTObjects/RESTAPI_GWobjects.cpp index 33496540..d6b3f1d7 100644 --- a/src/RESTObjects/RESTAPI_GWobjects.cpp +++ b/src/RESTObjects/RESTAPI_GWobjects.cpp @@ -205,6 +205,8 @@ namespace OpenWifi::GWObjects { field_to_json(Obj,"locale", locale); field_to_json(Obj,"started", started); field_to_json(Obj,"sessionId", sessionId); + field_to_json(Obj,"connectionCompletionTime", connectionCompletionTime); + field_to_json(Obj,"totalConnectionTime", OpenWifi::Now() - started); switch(VerifiedCertificate) { case NO_CERTIFICATE: diff --git a/src/RESTObjects/RESTAPI_GWobjects.h b/src/RESTObjects/RESTAPI_GWobjects.h index 63b25e4d..2a2b2a93 100644 --- a/src/RESTObjects/RESTAPI_GWobjects.h +++ b/src/RESTObjects/RESTAPI_GWobjects.h @@ -40,6 +40,8 @@ namespace OpenWifi::GWObjects { std::string locale; uint64_t started=0; uint64_t sessionId=0; + double connectionCompletionTime=0.0; + void to_json(Poco::JSON::Object &Obj) const; }; diff --git a/src/framework/MicroService.h b/src/framework/MicroService.h index d48e7a13..b2a0dfea 100644 --- a/src/framework/MicroService.h +++ b/src/framework/MicroService.h @@ -1666,7 +1666,7 @@ namespace OpenWifi { inline const PropertiesFileServerEntry & Host(uint64_t index) { return ConfigServersList_[index]; }; 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 Poco::Logger::get("tmp"); }; @@ -1685,7 +1685,7 @@ namespace OpenWifi { std::recursive_mutex Mutex_; std::vector ConfigServersList_; private: - std::unique_ptr Log_; + mutable std::unique_ptr Log_; // Poco::Logger &Logger_; std::string Name_; std::string LoggerPrefix_;