mirror of
				https://github.com/Telecominfraproject/wlan-cloud-ucentralfms.git
				synced 2025-10-29 18:02:20 +00:00 
			
		
		
		
	Compare commits
	
		
			24 Commits
		
	
	
		
			gh-pages
			...
			v2.8.0-RC2
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | 7760230f02 | ||
|   | 6223ade0f6 | ||
|   | 64e6a6f70a | ||
|   | c67367ec4d | ||
|   | fe3c5d7c4a | ||
|   | da52cf5823 | ||
|   | 3c8d8697e0 | ||
|   | 7b0c61ff5e | ||
|   | e9a9416332 | ||
|   | 2255988b4c | ||
|   | 106c9353fc | ||
|   | 6c7fc8e310 | ||
|   | e151b45d51 | ||
|   | 1584ff1ebe | ||
|   | 82ccb08d6b | ||
|   | 82b184a79f | ||
|   | 71c37edde7 | ||
|   | 0c8fa44935 | ||
|   | 32714f95b6 | ||
|   | 13cbf8c603 | ||
|   | 48c95c3101 | ||
|   | 857055750f | ||
|   | 96b22ef09b | ||
|   | acff9afff2 | 
							
								
								
									
										1
									
								
								.github/workflows/openapi-pages.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.github/workflows/openapi-pages.yml
									
									
									
									
										vendored
									
									
								
							| @@ -34,6 +34,7 @@ jobs: | ||||
|           git config --global user.name "TIP Automation User" | ||||
|           git pull | ||||
|           git checkout gh-pages || git checkout -b gh-pages | ||||
|           rm -rf docs | ||||
|           mv tmp-docs docs | ||||
|           git add docs | ||||
|           git commit -m'Update OpenAPI docs for GitHub pages' | ||||
|   | ||||
| @@ -5,6 +5,11 @@ The uCentralFMS is a micro-service part of the OpenWiFi ecosystem. uCentralFMS i | ||||
| to facilitate the task of upgrade and maintaining the proper firmware for all the devices  | ||||
| used in your OpenWiFi solution. You may either [build it](#building) or use the [Docker version](#docker). | ||||
|  | ||||
| ## OpenAPI | ||||
| You may get static page with OpenAPI docs generated from the definition on [GitHub Page](https://telecominfraproject.github.io/wlan-cloud-ucentralfms/). | ||||
|  | ||||
| Also you may use [Swagger UI](https://petstore.swagger.io/#/) with OpenAPI definition file raw link (i.e. [latest version file](https://raw.githubusercontent.com/Telecominfraproject/wlan-cloud-ucentralfms/main/openapi/owfms.yaml)) to get interactive docs page. | ||||
|  | ||||
| ## Building | ||||
| In order to build the uCentralFMS, you will need to install its dependencies, which includes the following: | ||||
| - cmake | ||||
| @@ -216,4 +221,4 @@ s3.key =  ******************************************* | ||||
| s3.retry = 60 | ||||
| s3.bucket.uri = ucentral-ap-firmware.s3.amazonaws.com | ||||
|  | ||||
| ``` | ||||
| ``` | ||||
|   | ||||
| @@ -23,6 +23,8 @@ if [[ "$TEMPLATE_CONFIG" = 'true' ]]; then | ||||
|   SYSTEM_URI_PUBLIC=${SYSTEM_URI_PUBLIC:-"https://localhost:16004"} \ | ||||
|   SYSTEM_URI_UI=${SYSTEM_URI_UI:-"http://localhost"} \ | ||||
|   SECURITY_RESTAPI_DISABLE=${SECURITY_RESTAPI_DISABLE:-"false"} \ | ||||
|   FIRMWAREDB_REFRESH=${FIRMWAREDB_REFRESH:-"86400"} \ | ||||
|   FIRMWAREDB_MAXAGE=${FIRMWAREDB_MAXAGE:-"90"} \ | ||||
|   S3_BUCKETNAME=${S3_BUCKETNAME:-"ucentral-ap-firmware"} \ | ||||
|   S3_REGION=${S3_REGION:-"us-east-1"} \ | ||||
|   S3_SECRET=${S3_SECRET:-"*******************************************"} \ | ||||
|   | ||||
| @@ -9,7 +9,7 @@ fullnameOverride: "" | ||||
| images: | ||||
|   owfms: | ||||
|     repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owfms | ||||
|     tag: main | ||||
|     tag: v2.8.0-RC2 | ||||
|     pullPolicy: Always | ||||
| #    regcred: | ||||
| #      registry: tip-tip-wlan-cloud-ucentral.jfrog.io | ||||
| @@ -147,7 +147,7 @@ configProperties: | ||||
|   s3.region: us-east-1 | ||||
|   s3.retry: 60 | ||||
|   s3.bucket.uri: ucentral-ap-firmware.s3.amazonaws.com | ||||
|   firmwaredb.refresh: 1800 | ||||
|   firmwaredb.refresh: 86400 | ||||
|   # ALB | ||||
|   alb.enable: "true" | ||||
|   alb.port: 16104 | ||||
|   | ||||
| @@ -38,8 +38,8 @@ openwifi.system.commandchannel = /tmp/app.ucentralfms | ||||
| openwifi.system.uri.ui = ${SYSTEM_URI_UI} | ||||
| openwifi.security.restapi.disable = ${SECURITY_RESTAPI_DISABLE} | ||||
|  | ||||
| firmwaredb.refresh = 1800 | ||||
| firmwaredb.maxage = 90 | ||||
| firmwaredb.refresh = ${FIRMWAREDB_REFRESH} | ||||
| firmwaredb.maxage = ${FIRMWAREDB_MAXAGE} | ||||
|  | ||||
| # | ||||
| # Firmware Microservice Specific Section | ||||
|   | ||||
| @@ -32,9 +32,7 @@ namespace OpenWifi { | ||||
|  | ||||
|         void PostInitialization(Poco::Util::Application &self); | ||||
|         static Daemon *instance(); | ||||
|         inline void ResetDashboard() { DB_.Reset(); } | ||||
|         inline void CreateDashboard() { DB_.Create(); } | ||||
|         inline const FMSObjects::DeviceReport & GetDashboard() { return DB_.Report(); } | ||||
|         inline DeviceDashboard & GetDashboard() { return DB_; } | ||||
|  | ||||
|     private: | ||||
|         static Daemon 				*instance_; | ||||
|   | ||||
| @@ -7,13 +7,45 @@ | ||||
| #include "framework/utils.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
| 	void DeviceDashboard::Create() { | ||||
| 		uint64_t Now = Utils::Now(); | ||||
|  | ||||
| 		if(LastRun_==0 || (Now-LastRun_)>120) { | ||||
| 			DB_.reset(); | ||||
| 			StorageService()->DevicesDB().GenerateDeviceReport(DB_); | ||||
| 			LastRun_ = Now; | ||||
| 		} | ||||
| 	} | ||||
|     bool DeviceDashboard::Get(FMSObjects::DeviceReport &D, Poco::Logger & Logger) { | ||||
|         uint64_t Now = Utils::Now(); | ||||
|         if(!ValidDashboard_ || LastRun_==0 || (Now-LastRun_)>120) { | ||||
|             Generate(D, Logger); | ||||
|         } else { | ||||
|             std::lock_guard	G(DataMutex_); | ||||
|             D = DB_; | ||||
|         } | ||||
|         return ValidDashboard_; | ||||
|     }; | ||||
|  | ||||
|     void DeviceDashboard::Generate(FMSObjects::DeviceReport &D, Poco::Logger & Logger ) { | ||||
|         if (GeneratingDashboard_.load()) { | ||||
|             // std::cout << "Trying to generate dashboard but already being generated" << std::endl; | ||||
|             while(GeneratingDashboard_.load()) { | ||||
|                 Poco::Thread::trySleep(100); | ||||
|             } | ||||
|             std::lock_guard	G(DataMutex_); | ||||
|             D = DB_; | ||||
|         } else { | ||||
|             GeneratingDashboard_ = true; | ||||
|             ValidDashboard_ = false; | ||||
|             try { | ||||
|                 // std::cout << "Generating dashboard." << std::endl; | ||||
|                 poco_information(Logger, "DASHBOARD: Generating a new dashboard."); | ||||
|                 FMSObjects::DeviceReport	NewData; | ||||
|                 StorageService()->DevicesDB().GenerateDeviceReport(NewData); | ||||
|                 LastRun_ = Utils::Now(); | ||||
|                 NewData.snapshot = LastRun_; | ||||
|                 D = NewData; | ||||
|                 std::lock_guard	G(DataMutex_); | ||||
|                 DB_ = NewData; | ||||
|                 ValidDashboard_=true; | ||||
|             } catch(...) { | ||||
|  | ||||
|             } | ||||
|             GeneratingDashboard_ = false; | ||||
|         } | ||||
|     } | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -2,22 +2,26 @@ | ||||
| // Created by stephane bourque on 2021-07-21. | ||||
| // | ||||
|  | ||||
| #ifndef UCENTRALGW_DASHBOARD_H | ||||
| #define UCENTRALGW_DASHBOARD_H | ||||
| #pragma once | ||||
|  | ||||
| #include <mutex> | ||||
|  | ||||
| #include "framework/OpenWifiTypes.h" | ||||
| #include "RESTObjects/RESTAPI_FMSObjects.h" | ||||
| #include "Poco/Logger.h" | ||||
|  | ||||
| namespace OpenWifi { | ||||
| 	class DeviceDashboard { | ||||
| 	  public: | ||||
| 			void Create(); | ||||
| 			const FMSObjects::DeviceReport & Report() const { return DB_;} | ||||
| 			inline void Reset() { LastRun_=0; DB_.reset(); } | ||||
| 	  private: | ||||
|             FMSObjects::DeviceReport  	DB_; | ||||
| 			uint64_t 				LastRun_=0; | ||||
| 	}; | ||||
| } | ||||
|     class DeviceDashboard { | ||||
|     public: | ||||
|         bool Get(FMSObjects::DeviceReport &D, Poco::Logger &Logger); | ||||
|  | ||||
| #endif // UCENTRALGW_DASHBOARD_H | ||||
|     private: | ||||
|         std::mutex DataMutex_; | ||||
|         volatile std::atomic_bool GeneratingDashboard_ = false; | ||||
|         volatile bool ValidDashboard_ = false; | ||||
|         FMSObjects::DeviceReport DB_; | ||||
|         uint64_t LastRun_ = 0; | ||||
|  | ||||
|         void Generate(FMSObjects::DeviceReport &D, Poco::Logger &Logger); | ||||
|     }; | ||||
| } | ||||
|   | ||||
| @@ -43,7 +43,7 @@ namespace OpenWifi { | ||||
|             auto Tokens = Poco::StringTokenizer(Revision,"/", Poco::StringTokenizer::TOK_TRIM); | ||||
|             if(Tokens.count()!=2) | ||||
|                 return false; | ||||
|             return (Tokens[1].substr(0,5) == "IP-v"); | ||||
|             return (Tokens[1].substr(0,5) == "TIP-v"); | ||||
|         } | ||||
|  | ||||
|         void DumpCache(); | ||||
|   | ||||
| @@ -9,9 +9,13 @@ | ||||
|  | ||||
| namespace OpenWifi { | ||||
|     void RESTAPI_deviceReportHandler::DoGet() { | ||||
|         Daemon()->CreateDashboard(); | ||||
|         Poco::JSON::Object  O; | ||||
|         Daemon()->GetDashboard().to_json(O); | ||||
|         ReturnObject(O); | ||||
|         poco_information(Logger(),fmt::format("GET-DASHBOARD: {}", Requester())); | ||||
|         FMSObjects::DeviceReport	Data; | ||||
|         if(Daemon()->GetDashboard().Get(Data, Logger())) { | ||||
|             Poco::JSON::Object Answer; | ||||
|             Data.to_json(Answer); | ||||
|             return ReturnObject(Answer); | ||||
|         } | ||||
|         return BadRequest(RESTAPI::Errors::InternalError); | ||||
|     } | ||||
| } | ||||
| @@ -51,7 +51,9 @@ namespace OpenWifi::GWObjects { | ||||
| 		field_to_json(Obj,"modified", modified); | ||||
| 		field_to_json(Obj,"locale", locale); | ||||
| 		field_to_json(Obj,"restrictedDevice", restrictedDevice); | ||||
|  | ||||
| 		field_to_json(Obj,"pendingConfiguration", pendingConfiguration); | ||||
| 		field_to_json(Obj,"pendingConfigurationCmd", pendingConfigurationCmd); | ||||
| 		field_to_json(Obj,"restrictionDetails", restrictionDetails); | ||||
| 	} | ||||
|  | ||||
| 	void Device::to_json_with_status(Poco::JSON::Object &Obj) const { | ||||
| @@ -93,6 +95,9 @@ namespace OpenWifi::GWObjects { | ||||
| 			field_from_json(Obj,"entity", entity); | ||||
| 			field_from_json(Obj,"locale", locale); | ||||
| 			field_from_json(Obj,"restrictedDevice", restrictedDevice); | ||||
| 			field_from_json(Obj,"pendingConfiguration", pendingConfiguration); | ||||
| 			field_from_json(Obj,"pendingConfigurationCmd", pendingConfigurationCmd); | ||||
| 			field_from_json(Obj,"restrictionDetails", restrictionDetails); | ||||
| 			return true; | ||||
| 		} catch (const Poco::Exception &E) { | ||||
| 		} | ||||
| @@ -394,6 +399,7 @@ namespace OpenWifi::GWObjects { | ||||
| 		field_to_json(Obj,"secret",secret); | ||||
| 		field_to_json(Obj,"certificate",certificate); | ||||
| 		field_to_json(Obj,"radsec",radsec); | ||||
| 		field_to_json(Obj,"allowSelfSigned",allowSelfSigned); | ||||
| 		field_to_json(Obj,"radsecPort",radsecPort); | ||||
| 		field_to_json(Obj,"radsecSecret",radsecSecret); | ||||
| 		field_to_json(Obj,"radsecCacerts",radsecCacerts); | ||||
| @@ -412,6 +418,7 @@ namespace OpenWifi::GWObjects { | ||||
| 			field_from_json(Obj,"secret",secret); | ||||
| 			field_from_json(Obj,"certificate",certificate); | ||||
| 			field_from_json(Obj,"radsec",radsec); | ||||
| 			field_from_json(Obj,"allowSelfSigned",allowSelfSigned); | ||||
| 			field_from_json(Obj,"radsecSecret",radsecSecret); | ||||
| 			field_from_json(Obj,"radsecPort",radsecPort); | ||||
| 			field_from_json(Obj,"radsecCacerts",radsecCacerts); | ||||
| @@ -439,6 +446,7 @@ namespace OpenWifi::GWObjects { | ||||
| 		field_to_json(Obj,"restricted", restricted); | ||||
| 		field_to_json(Obj,"deferred", deferred); | ||||
| 		field_to_json(Obj,"timeout", timeout); | ||||
| 		field_to_json(Obj,"defaultUploadURI", defaultUploadURI); | ||||
| 	} | ||||
|  | ||||
| 	bool ScriptEntry::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
| @@ -456,6 +464,7 @@ namespace OpenWifi::GWObjects { | ||||
| 			field_from_json(Obj,"restricted", restricted); | ||||
| 			field_from_json(Obj,"deferred", deferred); | ||||
| 			field_from_json(Obj,"timeout", timeout); | ||||
| 			field_from_json(Obj,"defaultUploadURI", defaultUploadURI); | ||||
| 			return true; | ||||
| 		} catch (const Poco::Exception &E) { | ||||
| 		} | ||||
| @@ -475,5 +484,64 @@ namespace OpenWifi::GWObjects { | ||||
| 		return false; | ||||
| 	} | ||||
|  | ||||
| 	void DeviceRestrictionsKeyInfo::to_json(Poco::JSON::Object &Obj) const { | ||||
| 		field_to_json(Obj,"vendor", vendor); | ||||
| 		field_to_json(Obj,"algo", algo); | ||||
| 	} | ||||
|  | ||||
| 	bool DeviceRestrictionsKeyInfo::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
| 		try { | ||||
| 			field_from_json(Obj,"vendor", vendor); | ||||
| 			field_from_json(Obj,"algo", algo); | ||||
| 			return true; | ||||
| 		} catch (const Poco::Exception &E) { | ||||
| 		} | ||||
| 		return false; | ||||
|  | ||||
| 	} | ||||
|  | ||||
| 	void DeviceRestrictions::to_json(Poco::JSON::Object &Obj) const { | ||||
| 		field_to_json(Obj,"dfs", dfs); | ||||
| 		field_to_json(Obj,"ssh", ssh); | ||||
| 		field_to_json(Obj,"rtty", rtty); | ||||
| 		field_to_json(Obj,"tty", tty); | ||||
| 		field_to_json(Obj,"developer", developer); | ||||
| 		field_to_json(Obj,"upgrade", upgrade); | ||||
| 		field_to_json(Obj,"commands", commands); | ||||
| 		field_to_json(Obj,"country", country); | ||||
| 		field_to_json(Obj,"key_info", key_info); | ||||
| 	} | ||||
|  | ||||
| 	bool DeviceRestrictions::from_json(const Poco::JSON::Object::Ptr &Obj) { | ||||
| 		try { | ||||
| 			field_from_json(Obj,"dfs", dfs); | ||||
| 			field_from_json(Obj,"ssh", ssh); | ||||
| 			field_from_json(Obj,"rtty", rtty); | ||||
| 			field_from_json(Obj,"tty", tty); | ||||
| 			field_from_json(Obj,"developer", developer); | ||||
| 			field_from_json(Obj,"upgrade", upgrade); | ||||
| 			field_from_json(Obj,"commands", commands); | ||||
| 			field_from_json(Obj,"country", country); | ||||
| 			field_from_json(Obj,"key_info", key_info); | ||||
| 			return true; | ||||
| 		} catch (const Poco::Exception &E) { | ||||
| 		} | ||||
| 		return false; | ||||
| 	} | ||||
|  | ||||
| 	bool DeviceRestrictionsKeyInfo::operator!=(const OpenWifi::GWObjects::DeviceRestrictionsKeyInfo &T) const { | ||||
| 		return (T.algo!=algo) || (T.vendor!=vendor); | ||||
| 	} | ||||
|  | ||||
| 	bool DeviceRestrictions::operator!=(const OpenWifi::GWObjects::DeviceRestrictions &T) const { | ||||
| 		return (	(T.dfs!=dfs)					|| | ||||
| 					(T.rtty!=rtty)					|| | ||||
| 					(T.upgrade!=upgrade)		|| | ||||
| 					(T.commands != commands)		|| | ||||
| 					(T.developer != developer)		|| | ||||
| 					(T.ssh !=ssh) 					|| | ||||
| 					(T.key_info != key_info)		|| | ||||
| 					(T.country != country) ); | ||||
| 	} | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -47,6 +47,33 @@ namespace OpenWifi::GWObjects { | ||||
| 		void to_json(Poco::JSON::Object &Obj) const; | ||||
| 	}; | ||||
|  | ||||
| 	struct DeviceRestrictionsKeyInfo { | ||||
| 		std::string 	vendor; | ||||
| 		std::string 	algo; | ||||
|  | ||||
| 		bool operator !=(const DeviceRestrictionsKeyInfo &b) const; | ||||
|  | ||||
| 		void to_json(Poco::JSON::Object &Obj) const; | ||||
| 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
| 	}; | ||||
|  | ||||
| 	struct DeviceRestrictions { | ||||
| 		bool    					dfs = false; | ||||
| 		bool    					ssh = false; | ||||
| 		bool    					rtty = false; | ||||
| 		bool    					tty = false; | ||||
| 		bool    					developer = false; | ||||
| 		bool    					upgrade = false; | ||||
| 		bool    					commands = false; | ||||
| 		std::vector<std::string>   	country; | ||||
| 		DeviceRestrictionsKeyInfo	key_info; | ||||
|  | ||||
| 		bool operator !=(const DeviceRestrictions &D) const; | ||||
|  | ||||
| 		void to_json(Poco::JSON::Object &Obj) const; | ||||
| 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
| 	}; | ||||
|  | ||||
| 	struct Device { | ||||
| 		std::string SerialNumber; | ||||
| 		std::string DeviceType; | ||||
| @@ -71,6 +98,9 @@ namespace OpenWifi::GWObjects { | ||||
| 		uint64_t 	modified=0; | ||||
| 		std::string locale; | ||||
| 		bool 		restrictedDevice=false; | ||||
| 		std::string pendingConfiguration; | ||||
| 		std::string pendingConfigurationCmd; | ||||
| 		DeviceRestrictions	restrictionDetails; | ||||
|  | ||||
| 		void to_json(Poco::JSON::Object &Obj) const; | ||||
| 		void to_json_with_status(Poco::JSON::Object &Obj) const; | ||||
| @@ -230,6 +260,7 @@ namespace OpenWifi::GWObjects { | ||||
| 		Types::StringVec 	restricted; | ||||
| 		bool				deferred=false; | ||||
| 		std::uint64_t 		timeout=30; | ||||
| 		std::string 		defaultUploadURI; | ||||
|  | ||||
| 		void to_json(Poco::JSON::Object &Obj) const; | ||||
| 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
| @@ -265,6 +296,7 @@ namespace OpenWifi::GWObjects { | ||||
| 		std::string secret; | ||||
| 		std::string certificate; | ||||
| 		bool 		radsec=false; | ||||
| 		bool 		allowSelfSigned=false; | ||||
| 		uint16_t 	radsecPort=2083; | ||||
| 		std::string radsecSecret; | ||||
| 		std::string radsecKey; | ||||
| @@ -306,4 +338,5 @@ namespace OpenWifi::GWObjects { | ||||
| 		void to_json(Poco::JSON::Object &Obj) const; | ||||
| 		bool from_json(const Poco::JSON::Object::Ptr &Obj); | ||||
| 	}; | ||||
|  | ||||
| } | ||||
|   | ||||
| @@ -51,7 +51,13 @@ namespace OpenWifi { | ||||
|             poco_information(Logger(),"Starting..."); | ||||
| 			Running_=true; | ||||
| 			Port_ = (int)MicroServiceConfigGetInt("alb.port",15015); | ||||
| 			Socket_ = std::make_unique<Poco::Net::ServerSocket>(Port_); | ||||
| 			Poco::Net::IPAddress Addr(Poco::Net::IPAddress::wildcard( | ||||
| 				Poco::Net::Socket::supportsIPv6() ? Poco::Net::AddressFamily::IPv6 | ||||
| 												  : Poco::Net::AddressFamily::IPv4)); | ||||
| 			Poco::Net::SocketAddress SockAddr(Addr, Port_); | ||||
| 			Poco::Net::ServerSocket ClientSocket(SockAddr, 64); | ||||
|  | ||||
| 			Socket_ = std::make_unique<Poco::Net::ServerSocket>(SockAddr, Port_); | ||||
| 			auto Params = new Poco::Net::HTTPServerParams; | ||||
| 			Params->setName("ws:alb"); | ||||
| 			Server_ = std::make_unique<Poco::Net::HTTPServer>(new ALBRequestHandlerFactory(Logger()), *Socket_, Params); | ||||
|   | ||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @@ -102,6 +102,48 @@ namespace OpenWifi { | ||||
| 													  E.displayText(), | ||||
| 													  E.message(), | ||||
| 													  E.what())); | ||||
| 			} catch (const Poco::TimeoutException &E) { | ||||
| 				poco_error(App_.logger(), fmt::format("Poco::TimeoutException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||
| 													  t_name, t_id, E.code(), | ||||
| 													  E.displayText(), | ||||
| 													  E.message(), | ||||
| 													  E.what())); | ||||
| 			} catch (const Poco::NoThreadAvailableException &E) { | ||||
| 				poco_error(App_.logger(), fmt::format("Poco::NoThreadAvailableException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||
| 													  t_name, t_id, E.code(), | ||||
| 													  E.displayText(), | ||||
| 													  E.message(), | ||||
| 													  E.what())); | ||||
| 			} catch (const Poco::OutOfMemoryException &E) { | ||||
| 				poco_error(App_.logger(), fmt::format("Poco::OutOfMemoryException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||
| 													  t_name, t_id, E.code(), | ||||
| 													  E.displayText(), | ||||
| 													  E.message(), | ||||
| 													  E.what())); | ||||
| 			} catch (const Poco::BadCastException &E) { | ||||
| 				poco_error(App_.logger(), fmt::format("Poco::BadCastException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||
| 													  t_name, t_id, E.code(), | ||||
| 													  E.displayText(), | ||||
| 													  E.message(), | ||||
| 													  E.what())); | ||||
| 			} catch (const Poco::DataException &E) { | ||||
| 				poco_error(App_.logger(), fmt::format("Poco::DataException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||
| 													  t_name, t_id, E.code(), | ||||
| 													  E.displayText(), | ||||
| 													  E.message(), | ||||
| 													  E.what())); | ||||
| 			} catch (const Poco::PoolOverflowException &E) { | ||||
| 				poco_error(App_.logger(), fmt::format("Poco::PoolOverflowException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||
| 													  t_name, t_id, E.code(), | ||||
| 													  E.displayText(), | ||||
| 													  E.message(), | ||||
| 													  E.what())); | ||||
| 			} catch (const Poco::SystemException &E) { | ||||
| 				poco_error(App_.logger(), fmt::format("Poco::SystemException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||
| 													  t_name, t_id, E.code(), | ||||
| 													  E.displayText(), | ||||
| 													  E.message(), | ||||
| 													  E.what())); | ||||
| 			} catch (const Poco::RuntimeException &E) { | ||||
| 				poco_error(App_.logger(), fmt::format("Poco::RuntimeException thr_name={} thr_id={} code={} text={} msg={} what={}", | ||||
| 													  t_name, t_id, E.code(), | ||||
|   | ||||
| @@ -633,6 +633,18 @@ namespace OpenWifi { | ||||
| 			ReturnObject(Answer); | ||||
| 		} | ||||
|  | ||||
| 		template<typename T> void Object(const char *Name, const std::vector<T> & Objects) { | ||||
| 			Poco::JSON::Object  Answer; | ||||
| 			RESTAPI_utils::field_to_json(Answer,Name,Objects); | ||||
| 			ReturnObject(Answer); | ||||
| 		} | ||||
|  | ||||
| 		template <typename T> void Object(const T &O) { | ||||
| 			Poco::JSON::Object  Answer; | ||||
| 			O.to_json(Answer); | ||||
| 			ReturnObject(Answer); | ||||
| 		} | ||||
|  | ||||
| 		Poco::Logger & Logger() { return Logger_; } | ||||
|  | ||||
| 		virtual void DoGet() = 0 ; | ||||
|   | ||||
| @@ -119,7 +119,7 @@ namespace OpenWifi { | ||||
| 	} | ||||
|  | ||||
| 	bool UI_WebSocketClientServer::SendToUser(const std::string &UserName, std::uint64_t id, const std::string &Payload) { | ||||
| 		std::lock_guard G(Mutex_); | ||||
| 		std::lock_guard G(LocalMutex_); | ||||
|  | ||||
| 		for(const auto &Client:Clients_) { | ||||
| 			if(Client.second->UserName_ == UserName) { | ||||
| @@ -139,7 +139,7 @@ namespace OpenWifi { | ||||
| 	} | ||||
|  | ||||
| 	void UI_WebSocketClientServer::SendToAll(std::uint64_t id, const std::string &Payload) { | ||||
| 		std::lock_guard G(Mutex_); | ||||
| 		std::lock_guard G(LocalMutex_); | ||||
|  | ||||
| 		for(const auto &Client:Clients_) { | ||||
| 			try { | ||||
| @@ -189,7 +189,6 @@ namespace OpenWifi { | ||||
| 	void UI_WebSocketClientServer::OnSocketReadable([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf) { | ||||
|  | ||||
|         UI_WebSocketClientServer::ClientList::iterator Client; | ||||
|  | ||||
|         std::lock_guard     G(LocalMutex_); | ||||
|  | ||||
| 		try { | ||||
| @@ -295,6 +294,7 @@ namespace OpenWifi { | ||||
|  | ||||
| 	void UI_WebSocketClientServer::OnSocketShutdown([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ShutdownNotification> &pNf) { | ||||
|         try { | ||||
| 			std::lock_guard     G(LocalMutex_); | ||||
| 			auto Client = Clients_.find(pNf->socket().impl()->sockfd()); | ||||
|             if (Client == end(Clients_)) | ||||
|                 return; | ||||
|   | ||||
| @@ -231,7 +231,9 @@ namespace OpenWifi::RESTAPI::Errors { | ||||
| 	static const struct msg DeviceIsRestricted{1151,"Device is protected by regulation. This function is not allowed."}; | ||||
| 	static const struct msg InvalidURI{1152,"Invalid URI."}; | ||||
| 	static const struct msg InvalidScriptSelection{1153,"Only script or scriptId must be specified. Not both."}; | ||||
| } | ||||
|  | ||||
| 	static const struct msg NoDeviceStatisticsYet{1154,"Device statistics not available yet."}; | ||||
| 	} | ||||
|  | ||||
|  | ||||
|  | ||||
| @@ -526,6 +528,63 @@ namespace OpenWifi::uCentralProtocol::Events { | ||||
| 	}; | ||||
| } | ||||
|  | ||||
| namespace OpenWifi::APCommands { | ||||
| 	enum class Commands:uint8_t { | ||||
| 		capabilities, | ||||
| 		logs, | ||||
| 		healthchecks, | ||||
| 		statistics, | ||||
| 		status, | ||||
| 		rtty, | ||||
| 		configure, | ||||
| 		upgrade, | ||||
| 		reboot, | ||||
| 		factory, | ||||
| 		leds, | ||||
| 		trace, | ||||
| 		request, | ||||
| 		wifiscan, | ||||
| 		eventqueue, | ||||
| 		telemetry, | ||||
| 		ping, | ||||
| 		script, | ||||
| 		unknown | ||||
| 	}; | ||||
|  | ||||
| 	inline static const std::vector<const char *> uCentralAPCommands { | ||||
| 		RESTAPI::Protocol::CAPABILITIES, | ||||
| 		RESTAPI::Protocol::LOGS, | ||||
| 		RESTAPI::Protocol::HEALTHCHECKS, | ||||
| 		RESTAPI::Protocol::STATISTICS, | ||||
| 		RESTAPI::Protocol::STATUS, | ||||
| 		RESTAPI::Protocol::RTTY, | ||||
| 		RESTAPI::Protocol::CONFIGURE, | ||||
| 		RESTAPI::Protocol::UPGRADE, | ||||
| 		RESTAPI::Protocol::REBOOT, | ||||
| 		RESTAPI::Protocol::FACTORY, | ||||
| 		RESTAPI::Protocol::LEDS, | ||||
| 		RESTAPI::Protocol::TRACE, | ||||
| 		RESTAPI::Protocol::REQUEST, | ||||
| 		RESTAPI::Protocol::WIFISCAN, | ||||
| 		RESTAPI::Protocol::EVENTQUEUE, | ||||
| 		RESTAPI::Protocol::TELEMETRY, | ||||
| 		RESTAPI::Protocol::PING, | ||||
| 		RESTAPI::Protocol::SCRIPT}; | ||||
|  | ||||
| 	inline const char * to_string(Commands Cmd) { | ||||
| 		return uCentralAPCommands[(uint8_t)Cmd]; | ||||
| 	} | ||||
|  | ||||
| 	inline Commands to_apcommand(const char *cmd) { | ||||
| 		for(auto i=(uint8_t)Commands::capabilities;i!=(uint8_t)Commands::unknown;++i) { | ||||
| 			if(strcmp(uCentralAPCommands[i],cmd)==0) | ||||
| 				return (Commands)i; | ||||
| 		} | ||||
| 		return Commands::unknown; | ||||
| 	} | ||||
|  | ||||
| } | ||||
|  | ||||
| namespace OpenWifi::Provisioning::DeviceClass { | ||||
|  | ||||
|     static const char * ANY = "any"; | ||||
|   | ||||
| @@ -127,6 +127,14 @@ latestfirmware() { | ||||
|     jq < ${result_file} | ||||
| } | ||||
|  | ||||
| latestfirmwarerc() { | ||||
|     curl  ${FLAGS} -X GET "https://${OWFMS}/api/v1/firmwares?latestOnly=true&deviceType=$1&rcOnly=true" \ | ||||
|         -H "Content-Type: application/json" \ | ||||
|         -H "Authorization: Bearer ${token}" \ | ||||
|         -H "Accept: application/json" > ${result_file} | ||||
|     jq < ${result_file} | ||||
| } | ||||
|  | ||||
| revisions() { | ||||
|     curl  ${FLAGS} -X GET "https://${OWFMS}/api/v1/firmwares?revisionSet=true" \ | ||||
|         -H "Content-Type: application/json" \ | ||||
| @@ -350,6 +358,7 @@ case "$1" in | ||||
|     "login") login; help  ; logout ;; | ||||
|     "getfirmwares") login; getfirmwares "$2"; logout ;; | ||||
|     "latestfirmware") login; latestfirmware "$2"; logout ;; | ||||
|     "latestfirmwarerc") login; latestfirmwarerc "$2"; logout ;; | ||||
|     "revisions") login; revisions; logout ;; | ||||
|     "devicetypes") login; devicetypes; logout ;; | ||||
|     "firmwareage") login; firmwareage "$2" "$3"; logout ;; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user