mirror of
				https://github.com/Telecominfraproject/wlan-cloud-owprov.git
				synced 2025-10-30 18:18:03 +00:00 
			
		
		
		
	Compare commits
	
		
			28 Commits
		
	
	
		
			release/v3
			...
			v3.2.1
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
|   | e7b8ff7674 | ||
|   | 4e189980e5 | ||
|   | 3c139374a9 | ||
|   | 1bd1cf0af6 | ||
|   | 6ce0f2fb51 | ||
|   | 020ff8641a | ||
|   | 342c6900ef | ||
|   | 83ce648020 | ||
|   | dba50327b0 | ||
|   | b15808d1e0 | ||
|   | a549024a29 | ||
|   | 6f84eeb901 | ||
|   | 6cb71d4cdf | ||
|   | c44dabe2f3 | ||
|   | c78888372c | ||
|   | 4ae0b99f55 | ||
|   | 41e172be25 | ||
|   | d7e05eac60 | ||
|   | fd25e19095 | ||
|   | 3b8a8bafff | ||
|   | 20785d82ce | ||
|   | 1327b29d7b | ||
|   | 226cd3e9e9 | ||
|   | de512f0e2c | ||
|   | 7a845e2f8c | ||
|   | b0f925a7c0 | ||
|   | 984c8fafac | ||
|   | da23ff1192 | 
| @@ -1,5 +1,5 @@ | |||||||
| cmake_minimum_required(VERSION 3.13) | cmake_minimum_required(VERSION 3.13) | ||||||
| project(owprov VERSION 3.0.2) | project(owprov VERSION 3.2.1) | ||||||
|  |  | ||||||
| set(CMAKE_CXX_STANDARD 17) | set(CMAKE_CXX_STANDARD 17) | ||||||
|  |  | ||||||
|   | |||||||
| @@ -9,7 +9,7 @@ fullnameOverride: "" | |||||||
| images: | images: | ||||||
|   owprov: |   owprov: | ||||||
|     repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owprov |     repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owprov | ||||||
|     tag: v3.0.2-RC1 |     tag: v3.2.1 | ||||||
|     pullPolicy: Always |     pullPolicy: Always | ||||||
| #    regcred: | #    regcred: | ||||||
| #      registry: tip-tip-wlan-cloud-ucentral.jfrog.io | #      registry: tip-tip-wlan-cloud-ucentral.jfrog.io | ||||||
|   | |||||||
| @@ -5,6 +5,7 @@ | |||||||
| #include "AutoDiscovery.h" | #include "AutoDiscovery.h" | ||||||
| #include "Poco/JSON/Parser.h" | #include "Poco/JSON/Parser.h" | ||||||
| #include "StorageService.h" | #include "StorageService.h" | ||||||
|  | #include "Tasks/VenueConfigUpdater.h" | ||||||
| #include "framework/KafkaManager.h" | #include "framework/KafkaManager.h" | ||||||
| #include "framework/KafkaTopics.h" | #include "framework/KafkaTopics.h" | ||||||
| #include "framework/ow_constants.h" | #include "framework/ow_constants.h" | ||||||
| @@ -107,6 +108,11 @@ namespace OpenWifi { | |||||||
|                         if (!SerialNumber.empty() && Connected) { |                         if (!SerialNumber.empty() && Connected) { | ||||||
|                             StorageService()->InventoryDB().CreateFromConnection( |                             StorageService()->InventoryDB().CreateFromConnection( | ||||||
|                                     SerialNumber, ConnectedIP, Compatible, Locale, isConnection); |                                     SerialNumber, ConnectedIP, Compatible, Locale, isConnection); | ||||||
|  |                             // Now that the entry has been created, we can try to push a config if | ||||||
|  |                             // the connection was a capabilities message. | ||||||
|  |                             if (isConnection){ | ||||||
|  |                                 ComputeAndPushConfig(SerialNumber, Compatible, Logger()); | ||||||
|  |                             } | ||||||
|                         } |                         } | ||||||
|                     } |                     } | ||||||
| 				} catch (const Poco::Exception &E) { | 				} catch (const Poco::Exception &E) { | ||||||
|   | |||||||
| @@ -14,28 +14,13 @@ | |||||||
| #include "RESTAPI/RESTAPI_db_helpers.h" | #include "RESTAPI/RESTAPI_db_helpers.h" | ||||||
| #include "SerialNumberCache.h" | #include "SerialNumberCache.h" | ||||||
| #include "StorageService.h" | #include "StorageService.h" | ||||||
|  | #include "Tasks/VenueConfigUpdater.h" | ||||||
| #include "framework/utils.h" | #include "framework/utils.h" | ||||||
| #include "sdks/SDK_gw.h" | #include "sdks/SDK_gw.h" | ||||||
| #include "sdks/SDK_sec.h" | #include "sdks/SDK_sec.h" | ||||||
|  |  | ||||||
| namespace OpenWifi { | namespace OpenWifi { | ||||||
|  |  | ||||||
| 	void GetRejectedLines(const Poco::JSON::Object::Ptr &Response, Types::StringVec &Warnings) { |  | ||||||
| 		try { |  | ||||||
| 			if (Response->has("results")) { |  | ||||||
| 				auto Results = Response->get("results").extract<Poco::JSON::Object::Ptr>(); |  | ||||||
| 				auto Status = Results->get("status").extract<Poco::JSON::Object::Ptr>(); |  | ||||||
| 				auto Rejected = Status->getArray("rejected"); |  | ||||||
| 				std::transform( |  | ||||||
| 					Rejected->begin(), Rejected->end(), std::back_inserter(Warnings), |  | ||||||
| 					[](auto i) -> auto { return i.toString(); }); |  | ||||||
| 				//                for(const auto &i:*Rejected) |  | ||||||
| 				//                  Warnings.push_back(i.toString()); |  | ||||||
| 			} |  | ||||||
| 		} catch (...) { |  | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	void RESTAPI_inventory_handler::DoGet() { | 	void RESTAPI_inventory_handler::DoGet() { | ||||||
|  |  | ||||||
| 		ProvObjects::InventoryTag Existing; | 		ProvObjects::InventoryTag Existing; | ||||||
| @@ -314,6 +299,8 @@ namespace OpenWifi { | |||||||
| 			return NotFound(); | 			return NotFound(); | ||||||
| 		} | 		} | ||||||
|  |  | ||||||
|  | 		std::string previous_venue = Existing.venue; | ||||||
|  |  | ||||||
| 		auto RemoveSubscriber = GetParameter("removeSubscriber"); | 		auto RemoveSubscriber = GetParameter("removeSubscriber"); | ||||||
| 		if (!RemoveSubscriber.empty()) { | 		if (!RemoveSubscriber.empty()) { | ||||||
| 			if (Existing.subscriber == RemoveSubscriber) { | 			if (Existing.subscriber == RemoveSubscriber) { | ||||||
| @@ -471,6 +458,13 @@ namespace OpenWifi { | |||||||
| 			SDK::GW::Device::SetOwnerShip(this, SerialNumber, Existing.entity, Existing.venue, | 			SDK::GW::Device::SetOwnerShip(this, SerialNumber, Existing.entity, Existing.venue, | ||||||
| 										  Existing.subscriber); | 										  Existing.subscriber); | ||||||
|  |  | ||||||
|  | 			// Attempt an automatic config push when the venue is set and different than what is | ||||||
|  | 			// in DB. | ||||||
|  | 			poco_information(Logger(), fmt::format("New Venue {} Old Venue {}", NewObject.venue, previous_venue)); | ||||||
|  | 			if (!NewObject.venue.empty() && NewObject.venue != previous_venue) { | ||||||
|  | 				ComputeAndPushConfig(SerialNumber, NewObject.deviceType, Logger()); | ||||||
|  | 			} | ||||||
|  |  | ||||||
| 			ProvObjects::InventoryTag NewObjectCreated; | 			ProvObjects::InventoryTag NewObjectCreated; | ||||||
| 			DB_.GetRecord("id", Existing.info.id, NewObjectCreated); | 			DB_.GetRecord("id", Existing.info.id, NewObjectCreated); | ||||||
| 			Poco::JSON::Object Answer; | 			Poco::JSON::Object Answer; | ||||||
|   | |||||||
| @@ -28,6 +28,42 @@ namespace OpenWifi { | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | 	[[maybe_unused]] static void ComputeAndPushConfig(const std::string &SerialNumber, const std::string &DeviceType, Poco::Logger &Logger) { | ||||||
|  | 		/* | ||||||
|  | 		Generic Helper to compute a device's config and push it down to the device. | ||||||
|  | 		*/ | ||||||
|  | 		poco_information(Logger, fmt::format("Attempting to push venue config for device {}", SerialNumber)); | ||||||
|  | 		auto DeviceConfig = std::make_shared<APConfig>(SerialNumber, | ||||||
|  | 														DeviceType, Logger, false); | ||||||
|  | 		auto Configuration = Poco::makeShared<Poco::JSON::Object>(); | ||||||
|  | 		try { | ||||||
|  | 			if (DeviceConfig->Get(Configuration)) { | ||||||
|  | 				std::ostringstream OS; | ||||||
|  | 				Configuration->stringify(OS); | ||||||
|  | 				auto Response = Poco::makeShared<Poco::JSON::Object>(); | ||||||
|  | 				poco_debug(Logger, | ||||||
|  | 							fmt::format("{}: Pushing configuration.", SerialNumber)); | ||||||
|  | 				if (SDK::GW::Device::Configure(nullptr, SerialNumber, Configuration, | ||||||
|  | 												Response)) { | ||||||
|  | 					Logger.debug( | ||||||
|  | 						fmt::format("{}: Configuration pushed.", SerialNumber)); | ||||||
|  | 					poco_information(Logger, | ||||||
|  | 										fmt::format("{}: Updated.", SerialNumber)); | ||||||
|  | 				} else { | ||||||
|  | 					poco_information(Logger, | ||||||
|  | 										fmt::format("{}: Not updated.", SerialNumber)); | ||||||
|  | 				} | ||||||
|  | 			} else { | ||||||
|  | 				poco_debug(Logger, | ||||||
|  | 							fmt::format("{}: Configuration is bad.", SerialNumber)); | ||||||
|  | 			} | ||||||
|  | 		} catch (...) { | ||||||
|  | 			poco_debug(Logger, | ||||||
|  | 						fmt::format("{}: Configuration is bad (caused an exception).", | ||||||
|  | 									SerialNumber)); | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  |  | ||||||
| 	class VenueDeviceConfigUpdater : public Poco::Runnable { | 	class VenueDeviceConfigUpdater : public Poco::Runnable { | ||||||
| 	  public: | 	  public: | ||||||
| 		VenueDeviceConfigUpdater(const std::string &UUID, const std::string &venue, Poco::Logger &L) | 		VenueDeviceConfigUpdater(const std::string &UUID, const std::string &venue, Poco::Logger &L) | ||||||
|   | |||||||
| @@ -67,9 +67,9 @@ namespace OpenWifi { | |||||||
|  |  | ||||||
|         bool Get(const char *key, std::vector<std::string> &Value) { |         bool Get(const char *key, std::vector<std::string> &Value) { | ||||||
|             if(Registry_->has(key) && !Registry_->isNull(key) && Registry_->isArray(key)) { |             if(Registry_->has(key) && !Registry_->isNull(key) && Registry_->isArray(key)) { | ||||||
|                 auto Arr = Registry_->get(key); |                 auto pArr = Registry_->getArray(key); | ||||||
|                 for(const auto &v:Arr) { |                 for(const auto &v : *pArr) { | ||||||
|                     Value.emplace_back(v); |                     Value.emplace_back(v.toString()); | ||||||
|                 } |                 } | ||||||
|                 return true; |                 return true; | ||||||
|             } |             } | ||||||
|   | |||||||
| @@ -28,7 +28,6 @@ static const std::vector<std::string> GitJSONSchemaURLs = { | |||||||
| }; | }; | ||||||
|  |  | ||||||
| static std::string DefaultAPSchema = R"foo( | static std::string DefaultAPSchema = R"foo( | ||||||
|  |  | ||||||
| { | { | ||||||
|     "$id": "https://openwrt.org/ucentral.schema.json", |     "$id": "https://openwrt.org/ucentral.schema.json", | ||||||
|     "$schema": "http://json-schema.org/draft-07/schema#", |     "$schema": "http://json-schema.org/draft-07/schema#", | ||||||
| @@ -354,14 +353,6 @@ static std::string DefaultAPSchema = R"foo( | |||||||
|                         10000 |                         10000 | ||||||
|                     ] |                     ] | ||||||
|                 }, |                 }, | ||||||
|                 "duplex": { |  | ||||||
|                     "description": "The duplex mode that shall be forced.", |  | ||||||
|                     "type": "string", |  | ||||||
|                     "enum": [ |  | ||||||
|                         "half", |  | ||||||
|                         "full" |  | ||||||
|                     ] |  | ||||||
|                 }, |  | ||||||
|                 "enabled": { |                 "enabled": { | ||||||
|                     "description": "This allows forcing the port to down state by default.", |                     "description": "This allows forcing the port to down state by default.", | ||||||
|                     "type": "boolean", |                     "type": "boolean", | ||||||
| @@ -490,7 +481,59 @@ static std::string DefaultAPSchema = R"foo( | |||||||
|                 "bss-color": { |                 "bss-color": { | ||||||
|                     "description": "This enables BSS Coloring on the PHY. setting it to 0 disables the feature 1-63 sets the color and 64 will make hostapd pick a random color.", |                     "description": "This enables BSS Coloring on the PHY. setting it to 0 disables the feature 1-63 sets the color and 64 will make hostapd pick a random color.", | ||||||
|                     "type": "integer", |                     "type": "integer", | ||||||
|                     "default": 64 |                     "minimum": 0, | ||||||
|  |                     "maximum": 64, | ||||||
|  |                     "default": 0 | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         }, | ||||||
|  |         "radio.he-6ghz": { | ||||||
|  |             "type": "object", | ||||||
|  |             "properties": { | ||||||
|  |                 "power-type": { | ||||||
|  |                     "description": "This config is to set the 6 GHz Access Point type", | ||||||
|  |                     "type": "string", | ||||||
|  |                     "enum": [ | ||||||
|  |                         "indoor-power-indoor", | ||||||
|  |                         "standard-power", | ||||||
|  |                         "very-low-power" | ||||||
|  |                     ], | ||||||
|  |                     "default": "very-low-power" | ||||||
|  |                 }, | ||||||
|  |                 "controller": { | ||||||
|  |                     "description": "The URL of the AFC controller that the AP shall connect to.", | ||||||
|  |                     "type": "string" | ||||||
|  |                 }, | ||||||
|  |                 "ca-certificate": { | ||||||
|  |                     "description": "The CA of the server. This enables mTLS.", | ||||||
|  |                     "type": "string", | ||||||
|  |                     "format": "uc-base64" | ||||||
|  |                 }, | ||||||
|  |                 "serial-number": { | ||||||
|  |                     "description": "The serial number that the AP shall send to the AFC controller.", | ||||||
|  |                     "type": "string" | ||||||
|  |                 }, | ||||||
|  |                 "certificate-ids": { | ||||||
|  |                     "description": "The certificate IDs that the AP shall send to the AFC controller.", | ||||||
|  |                     "type": "string" | ||||||
|  |                 }, | ||||||
|  |                 "minimum-power": { | ||||||
|  |                     "description": "The minimum power that the AP shall request from to the AFC controller.", | ||||||
|  |                     "type": "number" | ||||||
|  |                 }, | ||||||
|  |                 "frequency-ranges": { | ||||||
|  |                     "description": "The list of frequency ranges that the AP shall request from to the AFC controller.", | ||||||
|  |                     "type": "array", | ||||||
|  |                     "items": { | ||||||
|  |                         "type": "string" | ||||||
|  |                     } | ||||||
|  |                 }, | ||||||
|  |                 "operating-classes": { | ||||||
|  |                     "description": "The list of frequency ranges that the AP shall request from to the AFC controller.", | ||||||
|  |                     "type": "array", | ||||||
|  |                     "items": { | ||||||
|  |                         "type": "number" | ||||||
|  |                     } | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         }, |         }, | ||||||
| @@ -635,6 +678,9 @@ static std::string DefaultAPSchema = R"foo( | |||||||
|                 "he-settings": { |                 "he-settings": { | ||||||
|                     "$ref": "#/$defs/radio.he" |                     "$ref": "#/$defs/radio.he" | ||||||
|                 }, |                 }, | ||||||
|  |                 "he-6ghz-settings": { | ||||||
|  |                     "$ref": "#/$defs/radio.he-6ghz" | ||||||
|  |                 }, | ||||||
|                 "hostapd-iface-raw": { |                 "hostapd-iface-raw": { | ||||||
|                     "description": "This array allows passing raw hostapd.conf lines.", |                     "description": "This array allows passing raw hostapd.conf lines.", | ||||||
|                     "type": "array", |                     "type": "array", | ||||||
| @@ -784,8 +830,19 @@ static std::string DefaultAPSchema = R"foo( | |||||||
|                 }, |                 }, | ||||||
|                 "use-dns": { |                 "use-dns": { | ||||||
|                     "description": "The DNS server sent to clients as DHCP option 6.", |                     "description": "The DNS server sent to clients as DHCP option 6.", | ||||||
|                     "type": "string", |                     "anyOf": [ | ||||||
|                     "format": "uc-ip" |                         { | ||||||
|  |                             "type": "string", | ||||||
|  |                             "format": "ipv4" | ||||||
|  |                         }, | ||||||
|  |                         { | ||||||
|  |                             "type": "array", | ||||||
|  |                             "items": { | ||||||
|  |                                 "type": "string", | ||||||
|  |                                 "format": "ipv4" | ||||||
|  |                             } | ||||||
|  |                         } | ||||||
|  |                     ] | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         }, |         }, | ||||||
| @@ -1313,8 +1370,7 @@ static std::string DefaultAPSchema = R"foo( | |||||||
|                 "domain-identifier": { |                 "domain-identifier": { | ||||||
|                     "description": "Mobility Domain identifier (dot11FTMobilityDomainID, MDID).", |                     "description": "Mobility Domain identifier (dot11FTMobilityDomainID, MDID).", | ||||||
|                     "type": "string", |                     "type": "string", | ||||||
|                     "maxLength": 4, |                     "format": "uc-mobility", | ||||||
|                     "minLength": 4, |  | ||||||
|                     "examples": [ |                     "examples": [ | ||||||
|                         "abcd" |                         "abcd" | ||||||
|                     ] |                     ] | ||||||
| @@ -3701,6 +3757,42 @@ static std::string DefaultAPSchema = R"foo( | |||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         }, |         }, | ||||||
|  |         "service.fingerprint": { | ||||||
|  |             "description": "This section can be used to configure device fingerprinting.", | ||||||
|  |             "type": "object", | ||||||
|  |             "properties": { | ||||||
|  |                 "mode": { | ||||||
|  |                     "description": "Enable this option if you would like to enable the MDNS server on the unit.", | ||||||
|  |                     "type": "string", | ||||||
|  |                     "enum": [ | ||||||
|  |                         "polled", | ||||||
|  |                         "final", | ||||||
|  |                         "raw-data" | ||||||
|  |                     ], | ||||||
|  |                     "default": "final" | ||||||
|  |                 }, | ||||||
|  |                 "minimum-age": { | ||||||
|  |                     "description": "The minimum age a fingerprint must have before it is reported.", | ||||||
|  |                     "type": "number", | ||||||
|  |                     "default": 60 | ||||||
|  |                 }, | ||||||
|  |                 "maximum-age": { | ||||||
|  |                     "description": "The age at which fingerprints get flushed from the local state.", | ||||||
|  |                     "type": "number", | ||||||
|  |                     "default": 60 | ||||||
|  |                 }, | ||||||
|  |                 "periodicity": { | ||||||
|  |                     "description": "This value defines the period at which entries get reported.", | ||||||
|  |                     "type": "number", | ||||||
|  |                     "default": 600 | ||||||
|  |                 }, | ||||||
|  |                 "allow-wan": { | ||||||
|  |                     "description": "Allow fingerprinting devices found on the WAN port.", | ||||||
|  |                     "type": "boolean", | ||||||
|  |                     "default": false | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         }, | ||||||
|         "service": { |         "service": { | ||||||
|             "description": "This section describes all of the services that may be present on the AP. Each service is then referenced via its name inside an interface, ssid, ...", |             "description": "This section describes all of the services that may be present on the AP. Each service is then referenced via its name inside an interface, ssid, ...", | ||||||
|             "type": "object", |             "type": "object", | ||||||
| @@ -3770,6 +3862,9 @@ static std::string DefaultAPSchema = R"foo( | |||||||
|                 }, |                 }, | ||||||
|                 "rrm": { |                 "rrm": { | ||||||
|                     "$ref": "#/$defs/service.rrm" |                     "$ref": "#/$defs/service.rrm" | ||||||
|  |                 }, | ||||||
|  |                 "fingerprint": { | ||||||
|  |                     "$ref": "#/$defs/service.fingerprint" | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|         }, |         }, | ||||||
|   | |||||||
| @@ -107,7 +107,16 @@ namespace OpenWifi { | |||||||
| 					NewMessage.partition(0); | 					NewMessage.partition(0); | ||||||
| 					NewMessage.payload(Msg->Payload()); | 					NewMessage.payload(Msg->Payload()); | ||||||
| 					Producer.produce(NewMessage); | 					Producer.produce(NewMessage); | ||||||
| 					Producer.flush(); | 					if (Queue_.size() < 100) { | ||||||
|  | 						// use flush when internal queue is lightly loaded, i.e. flush after each | ||||||
|  | 						// message | ||||||
|  | 						Producer.flush(); | ||||||
|  | 					} | ||||||
|  | 					else { | ||||||
|  | 						// use poll when internal queue is loaded to allow messages to be sent in | ||||||
|  | 						// batches | ||||||
|  | 						Producer.poll((std::chrono::milliseconds) 0); | ||||||
|  | 					} | ||||||
| 				} | 				} | ||||||
| 			} catch (const cppkafka::HandleException &E) { | 			} catch (const cppkafka::HandleException &E) { | ||||||
| 				poco_warning(Logger_, | 				poco_warning(Logger_, | ||||||
| @@ -117,8 +126,13 @@ namespace OpenWifi { | |||||||
| 			} catch (...) { | 			} catch (...) { | ||||||
| 				poco_error(Logger_, "std::exception"); | 				poco_error(Logger_, "std::exception"); | ||||||
| 			} | 			} | ||||||
|  | 			if (Queue_.size() == 0) { | ||||||
|  | 				// message queue is empty, flush all previously sent messages | ||||||
|  | 				Producer.flush(); | ||||||
|  | 			} | ||||||
| 			Note = Queue_.waitDequeueNotification(); | 			Note = Queue_.waitDequeueNotification(); | ||||||
| 		} | 		} | ||||||
|  | 		Producer.flush(); | ||||||
| 		poco_information(Logger_, "Stopped..."); | 		poco_information(Logger_, "Stopped..."); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user