diff --git a/build b/build index 9a03714..9d60796 100644 --- a/build +++ b/build @@ -1 +1 @@ -10 \ No newline at end of file +11 \ No newline at end of file diff --git a/src/RESTObjects/RESTAPI_GWobjects.cpp b/src/RESTObjects/RESTAPI_GWobjects.cpp index 285517d..d6b3f1d 100644 --- a/src/RESTObjects/RESTAPI_GWobjects.cpp +++ b/src/RESTObjects/RESTAPI_GWobjects.cpp @@ -203,6 +203,10 @@ namespace OpenWifi::GWObjects { field_to_json(Obj,"kafkaClients", kafkaClients); field_to_json(Obj,"kafkaPackets", kafkaPackets); 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: @@ -218,6 +222,21 @@ namespace OpenWifi::GWObjects { } } + void DeviceConnectionStatistics::to_json(Poco::JSON::Object &Obj) const { + field_to_json(Obj,"averageConnectionTime", averageConnectionTime); + field_to_json(Obj,"connectedDevices", connectedDevices ); + } + + bool DeviceConnectionStatistics::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + field_from_json(Obj,"averageConnectionTime", averageConnectionTime); + field_from_json(Obj,"connectedDevices", connectedDevices ); + return true; + } catch (const Poco::Exception &E) { + } + return false; + } + void RttySessionDetails::to_json(Poco::JSON::Object &Obj) const { field_to_json(Obj,"serialNumber", SerialNumber); field_to_json(Obj,"server", Server); @@ -293,7 +312,6 @@ namespace OpenWifi::GWObjects { } catch (const Poco::Exception &E) { } return false; - } void RadiusProxyPoolList::to_json(Poco::JSON::Object &Obj) const { @@ -314,6 +332,8 @@ namespace OpenWifi::GWObjects { field_to_json(Obj,"description",description); field_to_json(Obj,"authConfig",authConfig); field_to_json(Obj,"acctConfig",acctConfig); + field_to_json(Obj,"coaConfig",coaConfig); + field_to_json(Obj,"useByDefault",useByDefault); } bool RadiusProxyPool::from_json(const Poco::JSON::Object::Ptr &Obj) { @@ -322,6 +342,8 @@ namespace OpenWifi::GWObjects { field_from_json(Obj,"description",description); field_from_json(Obj,"authConfig",authConfig); field_from_json(Obj,"acctConfig",acctConfig); + field_from_json(Obj,"coaConfig",coaConfig); + field_from_json(Obj,"useByDefault",useByDefault); return true; } catch (const Poco::Exception &E) { } @@ -329,7 +351,7 @@ namespace OpenWifi::GWObjects { } void RadiusProxyServerConfig::to_json(Poco::JSON::Object &Obj) const { - field_to_json(Obj,"policy",strategy); + field_to_json(Obj,"strategy",strategy); field_to_json(Obj,"monitor",monitor); field_to_json(Obj,"monitorMethod",monitorMethod); field_to_json(Obj,"methodParameters",methodParameters); @@ -338,7 +360,7 @@ namespace OpenWifi::GWObjects { bool RadiusProxyServerConfig::from_json(const Poco::JSON::Object::Ptr &Obj) { try { - field_from_json(Obj,"policy",strategy); + field_from_json(Obj,"strategy",strategy); field_from_json(Obj,"monitor",monitor); field_from_json(Obj,"monitorMethod",monitorMethod); field_from_json(Obj,"methodParameters",methodParameters); @@ -354,6 +376,16 @@ namespace OpenWifi::GWObjects { field_to_json(Obj,"ip",ip); field_to_json(Obj,"port",port); field_to_json(Obj,"weight",weight); + field_to_json(Obj,"secret",secret); + field_to_json(Obj,"certificate",certificate); + field_to_json(Obj,"radsec",radsec); + field_to_json(Obj,"radsecPort",radsecPort); + field_to_json(Obj,"radsecSecret",radsecSecret); + field_to_json(Obj,"radsecCacerts",radsecCacerts); + field_to_json(Obj,"radsecCert",radsecCert); + field_to_json(Obj,"radsecKey",radsecKey); + field_to_json(Obj,"radsecRealms",radsecRealms); + field_to_json(Obj,"ignore",ignore); } bool RadiusProxyServerEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { @@ -362,6 +394,16 @@ namespace OpenWifi::GWObjects { field_from_json(Obj,"ip",ip); field_from_json(Obj,"port",port); field_from_json(Obj,"weight",weight); + field_from_json(Obj,"secret",secret); + field_from_json(Obj,"certificate",certificate); + field_from_json(Obj,"radsec",radsec); + field_from_json(Obj,"radsecSecret",radsecSecret); + field_from_json(Obj,"radsecPort",radsecPort); + field_from_json(Obj,"radsecCacerts",radsecCacerts); + field_from_json(Obj,"radsecCert",radsecCert); + field_from_json(Obj,"radsecKey",radsecKey); + field_from_json(Obj,"radsecRealms",radsecRealms); + field_from_json(Obj,"ignore",ignore); return true; } catch (const Poco::Exception &E) { } diff --git a/src/RESTObjects/RESTAPI_GWobjects.h b/src/RESTObjects/RESTAPI_GWobjects.h index 7395545..2a2b2a9 100644 --- a/src/RESTObjects/RESTAPI_GWobjects.h +++ b/src/RESTObjects/RESTAPI_GWobjects.h @@ -38,6 +38,10 @@ namespace OpenWifi::GWObjects { uint64_t kafkaPackets=0; uint64_t websocketPackets=0; std::string locale; + uint64_t started=0; + uint64_t sessionId=0; + double connectionCompletionTime=0.0; + void to_json(Poco::JSON::Object &Obj) const; }; @@ -71,6 +75,13 @@ namespace OpenWifi::GWObjects { void Print() const; }; + struct DeviceConnectionStatistics { + std::uint64_t connectedDevices = 0; + std::uint64_t averageConnectionTime = 0; + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + struct Statistics { std::string SerialNumber; uint64_t UUID = 0 ; @@ -216,6 +227,16 @@ namespace OpenWifi::GWObjects { std::string ip; uint16_t port=0; uint64_t weight=0; + std::string secret; + std::string certificate; + bool radsec=false; + uint16_t radsecPort=2083; + std::string radsecSecret; + std::string radsecKey; + std::string radsecCert; + std::vector radsecCacerts; + std::vector radsecRealms; + bool ignore=false; void to_json(Poco::JSON::Object &Obj) const; bool from_json(const Poco::JSON::Object::Ptr &Obj); @@ -237,6 +258,8 @@ namespace OpenWifi::GWObjects { std::string description; RadiusProxyServerConfig authConfig; RadiusProxyServerConfig acctConfig; + RadiusProxyServerConfig coaConfig; + bool useByDefault=false; void to_json(Poco::JSON::Object &Obj) const; bool from_json(const Poco::JSON::Object::Ptr &Obj); diff --git a/src/framework/ConfigurationValidator.cpp b/src/framework/ConfigurationValidator.cpp index 7a4a571..5170ef6 100644 --- a/src/framework/ConfigurationValidator.cpp +++ b/src/framework/ConfigurationValidator.cpp @@ -44,7 +44,7 @@ static json DefaultUCentralSchema = R"( "switch": { "$ref": "#/$defs/switch" }, - "radios": { + "radiosgrep": { "type": "array", "items": { "$ref": "#/$defs/radio" diff --git a/src/framework/MicroService.h b/src/framework/MicroService.h index a62b46c..9c520a1 100644 --- a/src/framework/MicroService.h +++ b/src/framework/MicroService.h @@ -23,6 +23,13 @@ #include #include + +// This must be defined for poco_debug and poco_trace macros to function. + +#ifndef POCO_LOG_DEBUG +#define POCO_LOG_DEBUG true +#endif + namespace OpenWifi { inline uint64_t Now() { return std::time(nullptr); }; } @@ -1345,17 +1352,17 @@ namespace OpenWifi { inline void exception(const Poco::Exception & E) { Poco::Thread * CurrentThread = Poco::Thread::current(); App_.logger().log(E); - App_.logger().error(fmt::format("Exception occurred in {}",CurrentThread->getName())); + poco_error(App_.logger(), fmt::format("Exception occurred in {}",CurrentThread->getName())); } inline void exception(const std::exception & E) { Poco::Thread * CurrentThread = Poco::Thread::current(); - App_.logger().warning(fmt::format("std::exception in {}: {}",CurrentThread->getName(),E.what())); + poco_warning(App_.logger(), fmt::format("std::exception in {}: {}",CurrentThread->getName(),E.what())); } inline void exception() { Poco::Thread * CurrentThread = Poco::Thread::current(); - App_.logger().warning(fmt::format("exception in {}",CurrentThread->getName())); + poco_warning(App_.logger(), fmt::format("exception in {}",CurrentThread->getName())); } private: Poco::Util::Application &App_; @@ -1363,12 +1370,17 @@ namespace OpenWifi { class BusEventManager : public Poco::Runnable { public: + explicit BusEventManager(Poco::Logger &L) : Logger_(L) { + + } inline void run() final; inline void Start(); inline void Stop(); + inline Poco::Logger & Logger() { return Logger_; } private: mutable std::atomic_bool Running_ = false; Poco::Thread Thread_; + Poco::Logger &Logger_; }; class MyPrivateKeyPassphraseHandler : public Poco::Net::PrivateKeyPassphraseHandler { @@ -1382,6 +1394,7 @@ namespace OpenWifi { Logger_.information("Returning key passphrase."); privateKey = Password_; }; + inline Poco::Logger & Logger() { return Logger_; } private: std::string Password_; Poco::Logger & Logger_; @@ -1650,14 +1663,14 @@ namespace OpenWifi { class SubSystemServer : public Poco::Util::Application::Subsystem { public: - SubSystemServer(std::string Name, const std::string &LoggingPrefix, - std::string SubSystemConfigPrefix); + SubSystemServer(const std::string & Name, const std::string &LoggingPrefix, + const std::string & SubSystemConfigPrefix); inline void initialize(Poco::Util::Application &self) override; inline void uninitialize() override { } inline void reinitialize([[maybe_unused]] Poco::Util::Application &self) override { - Logger().information("Reloading of this subsystem is not supported."); + Logger_->L_.information("Reloading of this subsystem is not supported."); } inline void defineOptions([[maybe_unused]] Poco::Util::OptionSet &options) override { } @@ -1666,30 +1679,30 @@ 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_) - return Log_->L; - return Poco::Logger::get("tmp"); - }; - inline void SetLoggingLevel(Poco::Message::Priority NewPriority) { Logger().setLevel(NewPriority); } - inline int GetLoggingLevel() { return Logger().getLevel(); } + inline Poco::Logger & Logger() const { return Logger_->L_; } + inline void SetLoggingLevel(const std::string & levelName) { + Logger_->L_.setLevel(Poco::Logger::parseLevel(levelName)); + } + inline int GetLoggingLevel() { return Logger_->L_.getLevel(); } virtual int Start() = 0; virtual void Stop() = 0; - struct LoggerWrapper { - Poco::Logger &L; - explicit inline LoggerWrapper(Poco::Logger &Logger) : L(Logger) {} - }; + struct LoggerWrapper { + Poco::Logger & L_; + LoggerWrapper(Poco::Logger &L) : + L_(L) {} + }; protected: std::recursive_mutex Mutex_; std::vector ConfigServersList_; + private: - std::unique_ptr Log_; - // Poco::Logger &Logger_; - std::string Name_; - std::string LoggerPrefix_; - std::string SubSystemConfigPrefix_; + std::unique_ptr Logger_; + std::string Name_; + std::string LoggerPrefix_; + std::string SubSystemConfigPrefix_; }; class RESTAPI_GenericServer { @@ -1823,7 +1836,7 @@ namespace OpenWifi { E->Count++; Cache_.update(H,E); if(E->Count > MaxCalls) { - Logger().warning(fmt::format("RATE-LIMIT-EXCEEDED: from '{}'", R.clientAddress().toString())); + poco_warning(Logger(),fmt::format("RATE-LIMIT-EXCEEDED: from '{}'", R.clientAddress().toString())); return true; } return false; @@ -2165,12 +2178,16 @@ namespace OpenWifi { SetCommonHeaders(CloseConnection); } - inline void BadRequest(const OpenWifi::RESTAPI::Errors::msg &E) { + inline void BadRequest(const OpenWifi::RESTAPI::Errors::msg &E, const std::string & Extra="") { PrepareResponse(Poco::Net::HTTPResponse::HTTP_BAD_REQUEST); Poco::JSON::Object ErrorObject; ErrorObject.set("ErrorCode",400); ErrorObject.set("ErrorDetails",Request->getMethod()); - ErrorObject.set("ErrorDescription",fmt::format("{}: {}",E.err_num,E.err_txt)) ; + if(Extra.empty()) + ErrorObject.set("ErrorDescription",fmt::format("{}: {}",E.err_num,E.err_txt)) ; + else + ErrorObject.set("ErrorDescription",fmt::format("{}: {} ({})",E.err_num,E.err_txt, Extra)) ; + std::ostream &Answer = Response->send(); Poco::JSON::Stringifier::stringify(ErrorObject, Answer); } @@ -2214,7 +2231,7 @@ namespace OpenWifi { ErrorObject.set("ErrorDescription",fmt::format("{}: {}",E.err_num,E.err_txt)) ; std::ostream &Answer = Response->send(); Poco::JSON::Stringifier::stringify(ErrorObject, Answer); - Logger_.debug(fmt::format("RES-NOTFOUND: User='{}@{}' Method='{}' Path='{}", + poco_debug(Logger_,fmt::format("RES-NOTFOUND: User='{}@{}' Method='{}' Path='{}", UserInfo_.userinfo.email, Utils::FormatIPv6(Request->clientAddress().toString()), Request->getMethod(), @@ -2783,9 +2800,11 @@ namespace OpenWifi { inline void Stop() override { if(KafkaEnabled_) { + poco_information(Logger(),"Stopping..."); Dispatcher_.Stop(); ProducerThr_.Stop(); ConsumerThr_.Stop(); + poco_information(Logger(),"Stopped..."); return; } } @@ -2947,12 +2966,12 @@ namespace OpenWifi { { } - void handleRequest(Poco::Net::HTTPServerRequest& Request, Poco::Net::HTTPServerResponse& Response) override + void handleRequest([[maybe_unused]] Poco::Net::HTTPServerRequest& Request, Poco::Net::HTTPServerResponse& Response) override { Utils::SetThreadName("alb-request"); try { if((id_ % 100) == 0) { - Logger_.debug(fmt::format("ALB-REQUEST({}): ALB Request {}.", + poco_debug(Logger_,fmt::format("ALB-REQUEST({}): ALB Request {}.", Request.clientAddress().toString(), id_)); } Response.setChunkedTransferEncoding(true); @@ -3010,8 +3029,10 @@ namespace OpenWifi { inline int Start() override; inline void Stop() override { + poco_information(Logger(),"Stopping..."); if(Running_) - Server_->stop(); + Server_->stopAll(true); + poco_information(Logger(),"Stopped..."); } private: @@ -3040,10 +3061,11 @@ namespace OpenWifi { inline void Stop() override { Logger().information("Stopping..."); for( const auto & svr : RESTServers_ ) - svr->stop(); + svr->stopAll(true); Pool_.stopAll(); Pool_.joinAll(); RESTServers_.clear(); + Logger().information("Stopped..."); } @@ -3058,7 +3080,7 @@ namespace OpenWifi { private: std::vector> RESTServers_; - Poco::ThreadPool Pool_{"x-rest",2,32}; + Poco::ThreadPool Pool_{"x-rest",4,128}; RESTAPI_GenericServer Server_; RESTAPI_ExtServer() noexcept: @@ -3175,9 +3197,10 @@ namespace OpenWifi { inline void Stop() override { Logger().information("Stopping..."); for( const auto & svr : RESTServers_ ) - svr->stop(); + svr->stopAll(true); Pool_.stopAll(); Pool_.joinAll(); + Logger().information("Stopped..."); } inline void reinitialize(Poco::Util::Application &self) override; @@ -3187,11 +3210,10 @@ namespace OpenWifi { Utils::SetThreadName(fmt::format("i-rest:{}",Id).c_str()); return RESTAPI_IntRouter(Path, Bindings, Logger(), Server_, Id); } - const Poco::ThreadPool & Pool() { return Pool_; } private: std::vector> RESTServers_; - Poco::ThreadPool Pool_{"i-rest",2,16}; + Poco::ThreadPool Pool_{"i-rest",4,96}; RESTAPI_GenericServer Server_; RESTAPI_IntServer() noexcept: @@ -3272,7 +3294,7 @@ namespace OpenWifi { return ((RandomEngine_() % (max-min)) + min); } - inline Poco::Logger & GetLogger(const std::string &Name) { +/* inline Poco::Logger & GetLogger(const std::string &Name) { static auto initialized = false; if(!initialized) { @@ -3281,7 +3303,7 @@ namespace OpenWifi { } return Poco::Logger::get(Name); } - +*/ virtual void GetExtraConfiguration(Poco::JSON::Object & Cfg) { Cfg.set("additionalConfiguration",false); } @@ -3374,7 +3396,6 @@ namespace OpenWifi { std::string MyPublicEndPoint_; std::string UIURI_; std::string Version_{ OW_VERSION::VERSION + "("+ OW_VERSION::BUILD + ")" + " - " + OW_VERSION::HASH }; - BusEventManager BusEventManager_; std::recursive_mutex InfraMutex_; std::default_random_engine RandomEngine_; Poco::Util::PropertyFileConfiguration * PropConfigurationFile_ = nullptr; @@ -3388,7 +3409,8 @@ namespace OpenWifi { bool NoBuiltInCrypto_=false; Poco::JWT::Signer Signer_; Poco::Logger &Logger_; - Poco::ThreadPool TimerPool_{"timer:pool",2,16}; + Poco::ThreadPool TimerPool_{"timer:pool",2,16}; + std::unique_ptr BusEventManager_; }; inline void MicroService::Exit(int Reason) { @@ -3469,7 +3491,7 @@ namespace OpenWifi { } } catch (const Poco::Exception &E) { - Logger_.log(E); + logger().log(E); } } @@ -3720,8 +3742,9 @@ namespace OpenWifi { } inline void MicroService::InitializeSubSystemServers() { - for(auto i:SubSystems_) - addSubsystem(i); + for(auto i:SubSystems_) { + addSubsystem(i); + } } inline void MicroService::StartSubSystemServers() { @@ -3729,12 +3752,13 @@ namespace OpenWifi { for(auto i:SubSystems_) { i->Start(); } - BusEventManager_.Start(); + BusEventManager_ = std::make_unique(Poco::Logger::create("BusEventManager",Poco::Logger::root().getChannel(),Poco::Logger::root().getLevel())); + BusEventManager_->Start(); } inline void MicroService::StopSubSystemServers() { AddActivity("Stopping"); - BusEventManager_.Stop(); + BusEventManager_->Stop(); for(auto i=SubSystems_.rbegin(); i!=SubSystems_.rend(); ++i) { (*i)->Stop(); } @@ -3911,14 +3935,15 @@ namespace OpenWifi { } } - inline SubSystemServer::SubSystemServer(std::string Name, const std::string &LoggingPrefix, - std::string SubSystemConfigPrefix): - Name_(std::move(Name)), - LoggerPrefix_(LoggingPrefix), - SubSystemConfigPrefix_(std::move(SubSystemConfigPrefix)) { + inline SubSystemServer::SubSystemServer(const std::string &Name, const std::string &LoggingPrefix, + const std::string &SubSystemConfigPrefix): + Name_(Name), + LoggerPrefix_(LoggingPrefix), + SubSystemConfigPrefix_(SubSystemConfigPrefix) { } inline int RESTAPI_ExtServer::Start() { + Logger().information("Starting."); Server_.InitLogging(); for(const auto & Svr: ConfigServersList_) { @@ -3950,7 +3975,6 @@ namespace OpenWifi { NewServer->start(); RESTServers_.push_back(std::move(NewServer)); } - return 0; } @@ -4040,7 +4064,11 @@ namespace OpenWifi { auto i = 0; bool good = true; - Log_ = std::make_unique(Poco::Logger::get(LoggerPrefix_)); + auto NewLevel = MicroService::instance().ConfigGetString("logging.level." + Name_, ""); + if(NewLevel.empty()) + Logger_ = std::make_unique(Poco::Logger::create(LoggerPrefix_, Poco::Logger::root().getChannel(), Poco::Logger::root().getLevel())); + else + Logger_ = std::make_unique(Poco::Logger::create(LoggerPrefix_, Poco::Logger::root().getChannel(), Poco::Logger::parseLevel(NewLevel))); ConfigServersList_.clear(); while (good) { @@ -4130,9 +4158,11 @@ namespace OpenWifi { inline void BusEventManager::Stop() { if(KafkaManager()->Enabled()) { + poco_information(Logger(),"Stopping..."); Running_ = false; Thread_.wakeUp(); Thread_.join(); + poco_information(Logger(),"Stopped..."); } } @@ -4144,37 +4174,37 @@ namespace OpenWifi { inline void KafkaLoggerFun([[maybe_unused]] cppkafka::KafkaHandleBase & handle, int level, const std::string & facility, const std::string &message) { switch ((cppkafka::LogLevel) level) { case cppkafka::LogLevel::LogNotice: { - KafkaManager()->Logger().notice(fmt::format("kafka-log: facility: {} message: {}",facility, message)); + poco_notice(KafkaManager()->Logger(),fmt::format("kafka-log: facility: {} message: {}",facility, message)); } break; case cppkafka::LogLevel::LogDebug: { - KafkaManager()->Logger().debug(fmt::format("kafka-log: facility: {} message: {}",facility, message)); + poco_debug(KafkaManager()->Logger(),fmt::format("kafka-log: facility: {} message: {}",facility, message)); } break; case cppkafka::LogLevel::LogInfo: { - KafkaManager()->Logger().information(fmt::format("kafka-log: facility: {} message: {}",facility, message)); + poco_information(KafkaManager()->Logger(),fmt::format("kafka-log: facility: {} message: {}",facility, message)); } break; - case cppkafka::LogLevel::LogWarning: { - KafkaManager()->Logger().warning(fmt::format("kafka-log: facility: {} message: {}",facility, message)); + case cppkafka::LogLevel::LogWarning: { + poco_warning(KafkaManager()->Logger(), fmt::format("kafka-log: facility: {} message: {}",facility, message)); } break; case cppkafka::LogLevel::LogAlert: case cppkafka::LogLevel::LogCrit: { - KafkaManager()->Logger().critical(fmt::format("kafka-log: facility: {} message: {}",facility, message)); + poco_critical(KafkaManager()->Logger(),fmt::format("kafka-log: facility: {} message: {}",facility, message)); } break; case cppkafka::LogLevel::LogErr: case cppkafka::LogLevel::LogEmerg: default: { - KafkaManager()->Logger().error(fmt::format("kafka-log: facility: {} message: {}",facility, message)); + poco_error(KafkaManager()->Logger(),fmt::format("kafka-log: facility: {} message: {}",facility, message)); } break; } } inline void KafkaErrorFun([[maybe_unused]] cppkafka::KafkaHandleBase & handle, int error, const std::string &reason) { - KafkaManager()->Logger().error(fmt::format("kafka-error: {}, reason: {}", error, reason)); + poco_error(KafkaManager()->Logger(),fmt::format("kafka-error: {}, reason: {}", error, reason)); } inline void AddKafkaSecurity(cppkafka::Configuration & Config) { @@ -4223,11 +4253,11 @@ namespace OpenWifi { cppkafka::MessageBuilder(Msg->Topic()).key(Msg->Key()).payload(Msg->Payload())); } } catch (const cppkafka::HandleException &E) { - KafkaManager()->Logger().warning(fmt::format("Caught a Kafka exception (producer): {}", E.what())); + poco_warning(KafkaManager()->Logger(),fmt::format("Caught a Kafka exception (producer): {}", E.what())); } catch( const Poco::Exception &E) { KafkaManager()->Logger().log(E); } catch (...) { - KafkaManager()->Logger().error("std::exception"); + poco_error(KafkaManager()->Logger(),"std::exception"); } Note = Queue_.waitDequeueNotification(); } @@ -4287,7 +4317,7 @@ namespace OpenWifi { continue; if (Msg.get_error()) { if (!Msg.is_eof()) { - KafkaManager()->Logger().error(fmt::format("Error: {}", Msg.get_error().to_string())); + poco_error(KafkaManager()->Logger(),fmt::format("Error: {}", Msg.get_error().to_string())); } if(!AutoCommit) Consumer.async_commit(Msg); @@ -4298,11 +4328,11 @@ namespace OpenWifi { Consumer.async_commit(Msg); } } catch (const cppkafka::HandleException &E) { - KafkaManager()->Logger().warning(fmt::format("Caught a Kafka exception (consumer): {}", E.what())); + poco_warning(KafkaManager()->Logger(),fmt::format("Caught a Kafka exception (consumer): {}", E.what())); } catch (const Poco::Exception &E) { KafkaManager()->Logger().log(E); } catch (...) { - KafkaManager()->Logger().error("std::exception"); + poco_error(KafkaManager()->Logger(),"std::exception"); } } Consumer.unsubscribe(); @@ -4754,7 +4784,7 @@ namespace OpenWifi { Contacted = true; if(!Allowed) { if(Server_.LogBadTokens(false)) { - Logger_.debug(fmt::format("I-REQ-DENIED({}): Method={} Path={}", + poco_debug(Logger_,fmt::format("I-REQ-DENIED({}): Method={} Path={}", Utils::FormatIPv6(Request->clientAddress().toString()), Request->getMethod(), Request->getURI())); } @@ -4762,7 +4792,7 @@ namespace OpenWifi { auto Id = Request->get("X-INTERNAL-NAME", "unknown"); REST_Requester_ = Id; if(Server_.LogIt(Request->getMethod(),true)) { - Logger_.debug(fmt::format("I-REQ-ALLOWED({}): User='{}' Method={} Path={}", + poco_debug(Logger_,fmt::format("I-REQ-ALLOWED({}): User='{}' Method={} Path={}", Utils::FormatIPv6(Request->clientAddress().toString()), Id, Request->getMethod(), Request->getURI())); } @@ -4786,7 +4816,7 @@ namespace OpenWifi { #endif REST_Requester_ = UserInfo_.userinfo.email; if(Server_.LogIt(Request->getMethod(),true)) { - Logger_.debug(fmt::format("X-REQ-ALLOWED({}): User='{}@{}' Method={} Path={}", + poco_debug(Logger_,fmt::format("X-REQ-ALLOWED({}): User='{}@{}' Method={} Path={}", UserInfo_.userinfo.email, Utils::FormatIPv6(Request->clientAddress().toString()), Request->clientAddress().toString(), @@ -4796,7 +4826,7 @@ namespace OpenWifi { return true; } else { if(Server_.LogBadTokens(true)) { - Logger_.debug(fmt::format("X-REQ-DENIED({}): Method={} Path={}", + poco_debug(Logger_,fmt::format("X-REQ-DENIED({}): Method={} Path={}", Utils::FormatIPv6(Request->clientAddress().toString()), Request->getMethod(), Request->getURI())); } @@ -4867,7 +4897,7 @@ namespace OpenWifi { void run() override; // MyParallelSocketReactor &ReactorPool(); Poco::Net::SocketReactor & Reactor() { return Reactor_; } - void NewClient(Poco::Net::WebSocket &WS, const std::string &Id); + void NewClient(Poco::Net::WebSocket &WS, const std::string &Id, const std::string &UserName); bool Register(WebSocketClient *Client, const std::string &Id); void SetProcessor(WebSocketClientProcessor *F); void UnRegister(const std::string &Id); @@ -4918,18 +4948,22 @@ namespace OpenWifi { class WebSocketClient { public: - explicit WebSocketClient(Poco::Net::WebSocket &WS, const std::string &Id, Poco::Logger &L, - WebSocketClientProcessor *Processor); + explicit WebSocketClient(Poco::Net::WebSocket &WS, + const std::string &Id, + const std::string &UserName, + Poco::Logger &L, + WebSocketClientProcessor *Processor); virtual ~WebSocketClient(); [[nodiscard]] inline const std::string &Id(); [[nodiscard]] Poco::Logger &Logger(); inline bool Send(const std::string &Payload); private: std::unique_ptr WS_; - Poco::Net::SocketReactor &Reactor_; - std::string Id_; - Poco::Logger &Logger_; - bool Authenticated_ = false; + Poco::Net::SocketReactor &Reactor_; + std::string Id_; + std::string UserName_; + Poco::Logger &Logger_; + std::atomic_bool Authenticated_ = false; SecurityObjects::UserInfoAndPolicy UserInfo_; WebSocketClientProcessor *Processor_ = nullptr; void OnSocketReadable(const Poco::AutoPtr &pNf); @@ -4937,33 +4971,9 @@ namespace OpenWifi { void OnSocketError(const Poco::AutoPtr &pNf); }; -/* inline MyParallelSocketReactor::MyParallelSocketReactor(uint32_t NumReactors) : - NumReactors_(NumReactors) - { - Reactors_ = new Poco::Net::SocketReactor[NumReactors_]; - for(uint32_t i=0;iIsAuthorized(Tokens[1], UserInfo_, Expired, Contacted)) { Authenticated_ = true; + UserName_ = UserInfo_.userinfo.email; + poco_warning(Logger(),Poco::format("START(%s): %s UI Client is starting WS connection.", Id_, UserName_)); std::string S{"Welcome! Bienvenue! Bienvenidos!"}; WS_->sendFrame(S.c_str(), S.size()); WebSocketClientServer()->SetUser(Id_, UserInfo_.userinfo.email); @@ -5149,9 +5162,10 @@ namespace OpenWifi { } - inline WebSocketClient::WebSocketClient( Poco::Net::WebSocket & WS , const std::string &Id, Poco::Logger & L, WebSocketClientProcessor * Processor) : + inline WebSocketClient::WebSocketClient( Poco::Net::WebSocket & WS , const std::string &Id, const std::string &UserName, Poco::Logger & L, WebSocketClientProcessor * Processor) : Reactor_(WebSocketClientServer()->Reactor()), Id_(Id), + UserName_(UserName), Logger_(L), Processor_(Processor) { try { @@ -5165,7 +5179,10 @@ namespace OpenWifi { Reactor_.addEventHandler(*WS_, Poco::NObserver( *this, &WebSocketClient::OnSocketError)); - // WebSocketClientServer()->Register(this, Id_); + WS_->setNoDelay(true); + WS_->setKeepAlive(true); + WS_->setBlocking(false); + } catch (...) { delete this; } @@ -5231,9 +5248,8 @@ namespace OpenWifi { try { Poco::Net::WebSocket WS(*Request, *Response); - Logger().information("UI-WebSocket connection established."); auto Id = MicroService::CreateUUID(); - WebSocketClientServer()->NewClient(WS,Id); + WebSocketClientServer()->NewClient(WS,Id,UserInfo_.userinfo.email); } catch (...) { std::cout << "Cannot create websocket client..." << std::endl; diff --git a/src/framework/StorageClass.h b/src/framework/StorageClass.h index 34ecc2f..d9f3b98 100644 --- a/src/framework/StorageClass.h +++ b/src/framework/StorageClass.h @@ -33,7 +33,6 @@ namespace OpenWifi { int Start() override { std::lock_guard Guard(Mutex_); - Logger().setLevel(Poco::Message::PRIO_INFORMATION); Logger().notice("Starting."); std::string DBType = MicroService::instance().ConfigGetString("storage.type"); diff --git a/src/framework/WebSocketClientNotifications.h b/src/framework/WebSocketClientNotifications.h index a0c3a02..435732c 100644 --- a/src/framework/WebSocketClientNotifications.h +++ b/src/framework/WebSocketClientNotifications.h @@ -146,6 +146,10 @@ namespace OpenWifi { WebSocketClientServer()->SendUserNotification(User,N); } + ///// + ///// + ///// + struct WebSocketNotificationRebootList { std::string title, details, @@ -189,5 +193,58 @@ namespace OpenWifi { WebSocketClientServer()->SendUserNotification(User,N); } + ///// + ///// + ///// + + struct WebSocketNotificationUpgradeList { + std::string title, + details, + jobId; + std::vector success, + skipped, + no_firmware, + not_connected; + uint64_t timeStamp=OpenWifi::Now(); + + void to_json(Poco::JSON::Object &Obj) const; + bool from_json(const Poco::JSON::Object::Ptr &Obj); + }; + + typedef WebSocketNotification WebSocketClientNotificationVenueUpgradeList_t; + + inline void WebSocketNotificationUpgradeList::to_json(Poco::JSON::Object &Obj) const { + RESTAPI_utils::field_to_json(Obj,"title",title); + RESTAPI_utils::field_to_json(Obj,"jobId",jobId); + RESTAPI_utils::field_to_json(Obj,"success",success); + RESTAPI_utils::field_to_json(Obj,"notConnected",not_connected); + RESTAPI_utils::field_to_json(Obj,"noFirmware",no_firmware); + RESTAPI_utils::field_to_json(Obj,"skipped",skipped); + RESTAPI_utils::field_to_json(Obj,"timeStamp",timeStamp); + RESTAPI_utils::field_to_json(Obj,"details",details); + } + + inline bool WebSocketNotificationUpgradeList::from_json(const Poco::JSON::Object::Ptr &Obj) { + try { + RESTAPI_utils::field_from_json(Obj,"title",title); + RESTAPI_utils::field_from_json(Obj,"jobId",jobId); + RESTAPI_utils::field_from_json(Obj,"success",success); + RESTAPI_utils::field_from_json(Obj,"notConnected",not_connected); + RESTAPI_utils::field_from_json(Obj,"noFirmware",no_firmware); + RESTAPI_utils::field_from_json(Obj,"skipped",skipped); + RESTAPI_utils::field_from_json(Obj,"timeStamp",timeStamp); + RESTAPI_utils::field_from_json(Obj,"details",details); + return true; + } catch(...) { + + } + return false; + } + + inline void WebSocketClientNotificationVenueUpgradeCompletionToUser( const std::string & User, WebSocketClientNotificationVenueUpgradeList_t &N) { + N.type = "venue_upgrader"; + WebSocketClientServer()->SendUserNotification(User,N); + } + } // namespace OpenWifi diff --git a/src/framework/ow_constants.h b/src/framework/ow_constants.h index 443a457..5d70763 100644 --- a/src/framework/ow_constants.h +++ b/src/framework/ow_constants.h @@ -196,6 +196,8 @@ namespace OpenWifi::RESTAPI::Errors { static const struct msg InvalidRadiusServerEntry{1142,"RADIUS Server IP address invalid or port missing."}; static const struct msg InvalidRadiusServerWeigth{1143,"RADIUS Server IP weight cannot be 0."}; + static const struct msg MaximumRTTYSessionsReached{1144,"Too many RTTY sessions currently active"}; + static const struct msg DeviceIsAlreadyBusy{1145,"Device is already executing a command. Please try later."}; } @@ -428,6 +430,7 @@ namespace OpenWifi::uCentralProtocol { static const char *RADIUSDATA = "data"; static const char *RADIUSACCT = "acct"; static const char *RADIUSAUTH = "auth"; + static const char *RADIUSCOA = "coa"; static const char *RADIUSDST = "dst"; static const char *IES = "ies"; } @@ -444,6 +447,7 @@ namespace OpenWifi::uCentralProtocol::Events { static const char *RECOVERY = "recovery"; static const char *TELEMETRY = "telemetry"; static const char *DEVICEUPDATE = "deviceupdate"; + static const char *VENUE_BROADCAST = "venue_broadcast"; enum EVENT_MSG { ET_UNKNOWN, @@ -456,7 +460,8 @@ namespace OpenWifi::uCentralProtocol::Events { ET_CFGPENDING, ET_RECOVERY, ET_DEVICEUPDATE, - ET_TELEMETRY + ET_TELEMETRY, + ET_VENUEBROADCAST }; inline EVENT_MSG EventFromString(const std::string & Method) { @@ -480,6 +485,8 @@ namespace OpenWifi::uCentralProtocol::Events { return ET_RECOVERY; else if(strcmp(TELEMETRY,Method.c_str())==0) return ET_TELEMETRY; + else if(strcmp(VENUE_BROADCAST,Method.c_str())==0) + return ET_VENUEBROADCAST; return ET_UNKNOWN; }; }