mirror of
				https://github.com/Telecominfraproject/wlan-cloud-owprov.git
				synced 2025-11-03 20:17:54 +00:00 
			
		
		
		
	Compare commits
	
		
			4 Commits
		
	
	
		
			v2.10.0
			...
			release/v2
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
						 | 
					9bc5086f24 | ||
| 
						 | 
					71eefca353 | ||
| 
						 | 
					1cccd2aa73 | ||
| 
						 | 
					198888d554 | 
@@ -1,5 +1,5 @@
 | 
				
			|||||||
cmake_minimum_required(VERSION 3.13)
 | 
					cmake_minimum_required(VERSION 3.13)
 | 
				
			||||||
project(owprov VERSION 2.10.0)
 | 
					project(owprov VERSION 2.9.0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
set(CMAKE_CXX_STANDARD 17)
 | 
					set(CMAKE_CXX_STANDARD 17)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -117,7 +117,6 @@ add_executable(owprov
 | 
				
			|||||||
        src/framework/MicroServiceExtra.h
 | 
					        src/framework/MicroServiceExtra.h
 | 
				
			||||||
        src/framework/ConfigurationValidator.cpp
 | 
					        src/framework/ConfigurationValidator.cpp
 | 
				
			||||||
        src/framework/ConfigurationValidator.h
 | 
					        src/framework/ConfigurationValidator.h
 | 
				
			||||||
        src/framework/default_device_types.h
 | 
					 | 
				
			||||||
        src/UI_Prov_WebSocketNotifications.h
 | 
					        src/UI_Prov_WebSocketNotifications.h
 | 
				
			||||||
        src/UI_Prov_WebSocketNotifications.cpp
 | 
					        src/UI_Prov_WebSocketNotifications.cpp
 | 
				
			||||||
        src/RESTObjects/RESTAPI_SecurityObjects.h src/RESTObjects/RESTAPI_SecurityObjects.cpp
 | 
					        src/RESTObjects/RESTAPI_SecurityObjects.h src/RESTObjects/RESTAPI_SecurityObjects.cpp
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -42,7 +42,6 @@ if [[ "$TEMPLATE_CONFIG" = 'true' ]]; then
 | 
				
			|||||||
  STORAGE_TYPE_MYSQL_PASSWORD=${STORAGE_TYPE_MYSQL_PASSWORD:-"owprov"} \
 | 
					  STORAGE_TYPE_MYSQL_PASSWORD=${STORAGE_TYPE_MYSQL_PASSWORD:-"owprov"} \
 | 
				
			||||||
  STORAGE_TYPE_MYSQL_DATABASE=${STORAGE_TYPE_MYSQL_DATABASE:-"owprov"} \
 | 
					  STORAGE_TYPE_MYSQL_DATABASE=${STORAGE_TYPE_MYSQL_DATABASE:-"owprov"} \
 | 
				
			||||||
  STORAGE_TYPE_MYSQL_PORT=${STORAGE_TYPE_MYSQL_PORT:-"3306"} \
 | 
					  STORAGE_TYPE_MYSQL_PORT=${STORAGE_TYPE_MYSQL_PORT:-"3306"} \
 | 
				
			||||||
  RRM_PROVIDERS=${RRM_PROVIDERS:-"owrrm"} \
 | 
					 | 
				
			||||||
  envsubst < /owprov.properties.tmpl > $OWPROV_CONFIG/owprov.properties
 | 
					  envsubst < /owprov.properties.tmpl > $OWPROV_CONFIG/owprov.properties
 | 
				
			||||||
fi
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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: v2.10.0
 | 
					    tag: v2.9.0
 | 
				
			||||||
    pullPolicy: Always
 | 
					    pullPolicy: Always
 | 
				
			||||||
#    regcred:
 | 
					#    regcred:
 | 
				
			||||||
#      registry: tip-tip-wlan-cloud-ucentral.jfrog.io
 | 
					#      registry: tip-tip-wlan-cloud-ucentral.jfrog.io
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2258,7 +2258,7 @@ paths:
 | 
				
			|||||||
    get:
 | 
					    get:
 | 
				
			||||||
      tags:
 | 
					      tags:
 | 
				
			||||||
        - Configuration Overrides
 | 
					        - Configuration Overrides
 | 
				
			||||||
      operationId: getConfigurationOverrides
 | 
					      operationId: getCponfigurationOverrides
 | 
				
			||||||
      summary: retrieve a list of configuration overrides for a given device
 | 
					      summary: retrieve a list of configuration overrides for a given device
 | 
				
			||||||
      parameters:
 | 
					      parameters:
 | 
				
			||||||
        - in: path
 | 
					        - in: path
 | 
				
			||||||
@@ -2282,7 +2282,7 @@ paths:
 | 
				
			|||||||
    delete:
 | 
					    delete:
 | 
				
			||||||
      tags:
 | 
					      tags:
 | 
				
			||||||
        - Configuration Overrides
 | 
					        - Configuration Overrides
 | 
				
			||||||
      operationId: deleteConfigurationOverrides
 | 
					      operationId: deleteCponfigurationOverrides
 | 
				
			||||||
      summary: delete all configuration overrides for a given device from a given source
 | 
					      summary: delete all configuration overrides for a given device from a given source
 | 
				
			||||||
      parameters:
 | 
					      parameters:
 | 
				
			||||||
        - in: path
 | 
					        - in: path
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -37,12 +37,10 @@ openwifi.system.data = ${SYSTEM_DATA}
 | 
				
			|||||||
openwifi.system.debug = false
 | 
					openwifi.system.debug = false
 | 
				
			||||||
openwifi.system.uri.private = ${SYSTEM_URI_PRIVATE}
 | 
					openwifi.system.uri.private = ${SYSTEM_URI_PRIVATE}
 | 
				
			||||||
openwifi.system.uri.public = ${SYSTEM_URI_PUBLIC}
 | 
					openwifi.system.uri.public = ${SYSTEM_URI_PUBLIC}
 | 
				
			||||||
openwifi.system.commandchannel = /tmp/app.owprov
 | 
					openwifi.system.commandchannel = /tmp/app.ucentralfms
 | 
				
			||||||
openwifi.system.uri.ui = ${SYSTEM_URI_UI}
 | 
					openwifi.system.uri.ui = ${SYSTEM_URI_UI}
 | 
				
			||||||
openwifi.security.restapi.disable = ${SECURITY_RESTAPI_DISABLE}
 | 
					openwifi.security.restapi.disable = ${SECURITY_RESTAPI_DISABLE}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
rrm.providers = ${RRM_PROVIDERS}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#############################
 | 
					#############################
 | 
				
			||||||
# Generic information for all micro services
 | 
					# Generic information for all micro services
 | 
				
			||||||
#############################
 | 
					#############################
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -41,7 +41,7 @@ namespace OpenWifi {
 | 
				
			|||||||
		Payload.set("ObjectType", OT);
 | 
							Payload.set("ObjectType", OT);
 | 
				
			||||||
		std::ostringstream OS;
 | 
							std::ostringstream OS;
 | 
				
			||||||
		Payload.stringify(OS);
 | 
							Payload.stringify(OS);
 | 
				
			||||||
		KafkaManager()->PostMessage(KafkaTopics::PROVISIONING_CHANGE, Ops[op], std::make_shared<std::string>(OS.str()));
 | 
							KafkaManager()->PostMessage(KafkaTopics::PROVISIONING_CHANGE, Ops[op], OS.str());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return true;
 | 
							return true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,7 +13,6 @@
 | 
				
			|||||||
#ifdef TIP_GATEWAY_SERVICE
 | 
					#ifdef TIP_GATEWAY_SERVICE
 | 
				
			||||||
#include "AP_WS_Server.h"
 | 
					#include "AP_WS_Server.h"
 | 
				
			||||||
#include "CapabilitiesCache.h"
 | 
					#include "CapabilitiesCache.h"
 | 
				
			||||||
#include "RADIUSSessionTracker.h"
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "RESTAPI_GWobjects.h"
 | 
					#include "RESTAPI_GWobjects.h"
 | 
				
			||||||
@@ -30,7 +29,6 @@ namespace OpenWifi::GWObjects {
 | 
				
			|||||||
		field_to_json(Obj, "serialNumber", SerialNumber);
 | 
							field_to_json(Obj, "serialNumber", SerialNumber);
 | 
				
			||||||
#ifdef TIP_GATEWAY_SERVICE
 | 
					#ifdef TIP_GATEWAY_SERVICE
 | 
				
			||||||
		field_to_json(Obj, "deviceType", CapabilitiesCache::instance()->GetPlatform(Compatible));
 | 
							field_to_json(Obj, "deviceType", CapabilitiesCache::instance()->GetPlatform(Compatible));
 | 
				
			||||||
		field_to_json(Obj, "hasRADIUSSessions", RADIUSSessionTracker()->HasSessions(SerialNumber));
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
		field_to_json(Obj, "macAddress", MACAddress);
 | 
							field_to_json(Obj, "macAddress", MACAddress);
 | 
				
			||||||
		field_to_json(Obj, "manufacturer", Manufacturer);
 | 
							field_to_json(Obj, "manufacturer", Manufacturer);
 | 
				
			||||||
@@ -56,9 +54,6 @@ namespace OpenWifi::GWObjects {
 | 
				
			|||||||
		field_to_json(Obj, "pendingConfiguration", pendingConfiguration);
 | 
							field_to_json(Obj, "pendingConfiguration", pendingConfiguration);
 | 
				
			||||||
		field_to_json(Obj, "pendingConfigurationCmd", pendingConfigurationCmd);
 | 
							field_to_json(Obj, "pendingConfigurationCmd", pendingConfigurationCmd);
 | 
				
			||||||
		field_to_json(Obj, "restrictionDetails", restrictionDetails);
 | 
							field_to_json(Obj, "restrictionDetails", restrictionDetails);
 | 
				
			||||||
		field_to_json(Obj, "pendingUUID", pendingUUID);
 | 
					 | 
				
			||||||
		field_to_json(Obj, "simulated", simulated);
 | 
					 | 
				
			||||||
		field_to_json(Obj, "lastRecordedContact", lastRecordedContact);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void Device::to_json_with_status(Poco::JSON::Object &Obj) const {
 | 
						void Device::to_json_with_status(Poco::JSON::Object &Obj) const {
 | 
				
			||||||
@@ -68,7 +63,7 @@ namespace OpenWifi::GWObjects {
 | 
				
			|||||||
		ConnectionState ConState;
 | 
							ConnectionState ConState;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (AP_WS_Server()->GetState(SerialNumber, ConState)) {
 | 
							if (AP_WS_Server()->GetState(SerialNumber, ConState)) {
 | 
				
			||||||
			ConState.to_json(SerialNumber,Obj);
 | 
								ConState.to_json(Obj);
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			field_to_json(Obj, "ipAddress", "");
 | 
								field_to_json(Obj, "ipAddress", "");
 | 
				
			||||||
			field_to_json(Obj, "txBytes", (uint64_t)0);
 | 
								field_to_json(Obj, "txBytes", (uint64_t)0);
 | 
				
			||||||
@@ -80,13 +75,6 @@ namespace OpenWifi::GWObjects {
 | 
				
			|||||||
			field_to_json(Obj, "associations_2G", (uint64_t)0);
 | 
								field_to_json(Obj, "associations_2G", (uint64_t)0);
 | 
				
			||||||
			field_to_json(Obj, "associations_5G", (uint64_t)0);
 | 
								field_to_json(Obj, "associations_5G", (uint64_t)0);
 | 
				
			||||||
			field_to_json(Obj, "associations_6G", (uint64_t)0);
 | 
								field_to_json(Obj, "associations_6G", (uint64_t)0);
 | 
				
			||||||
			field_to_json(Obj, "hasRADIUSSessions", false);
 | 
					 | 
				
			||||||
			field_to_json(Obj, "hasGPS", ConState.hasGPS);
 | 
					 | 
				
			||||||
			field_to_json(Obj, "sanity", ConState.sanity);
 | 
					 | 
				
			||||||
			field_to_json(Obj, "memoryUsed", ConState.memoryUsed);
 | 
					 | 
				
			||||||
			field_to_json(Obj, "sanity", ConState.sanity);
 | 
					 | 
				
			||||||
			field_to_json(Obj, "load", ConState.load);
 | 
					 | 
				
			||||||
			field_to_json(Obj, "temperature", ConState.temperature);
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -96,32 +84,20 @@ namespace OpenWifi::GWObjects {
 | 
				
			|||||||
			field_from_json(Obj, "serialNumber", SerialNumber);
 | 
								field_from_json(Obj, "serialNumber", SerialNumber);
 | 
				
			||||||
			field_from_json(Obj, "deviceType", DeviceType);
 | 
								field_from_json(Obj, "deviceType", DeviceType);
 | 
				
			||||||
			field_from_json(Obj, "macAddress", MACAddress);
 | 
								field_from_json(Obj, "macAddress", MACAddress);
 | 
				
			||||||
			field_from_json(Obj, "manufacturer", Manufacturer);
 | 
					 | 
				
			||||||
			field_from_json(Obj, "UUID", UUID);
 | 
					 | 
				
			||||||
			field_from_json(Obj, "configuration", Configuration);
 | 
								field_from_json(Obj, "configuration", Configuration);
 | 
				
			||||||
			field_from_json(Obj, "notes", Notes);
 | 
								field_from_json(Obj, "notes", Notes);
 | 
				
			||||||
			field_from_json(Obj, "createdTimestamp", CreationTimestamp);
 | 
								field_from_json(Obj, "manufacturer", Manufacturer);
 | 
				
			||||||
			field_from_json(Obj, "lastConfigurationChange", LastConfigurationChange);
 | 
					 | 
				
			||||||
			field_from_json(Obj, "lastConfigurationDownload", LastConfigurationDownload);
 | 
					 | 
				
			||||||
			field_from_json(Obj, "lastFWUpdate", LastFWUpdate);
 | 
					 | 
				
			||||||
			field_from_json(Obj, "owner", Owner);
 | 
								field_from_json(Obj, "owner", Owner);
 | 
				
			||||||
			field_from_json(Obj, "location", Location);
 | 
								field_from_json(Obj, "location", Location);
 | 
				
			||||||
			field_from_json(Obj, "venue", Venue);
 | 
								field_from_json(Obj, "venue", Venue);
 | 
				
			||||||
			field_from_json(Obj, "firmware", Firmware);
 | 
					 | 
				
			||||||
			field_from_json(Obj, "compatible", Compatible);
 | 
								field_from_json(Obj, "compatible", Compatible);
 | 
				
			||||||
			field_from_json(Obj, "fwUpdatePolicy", FWUpdatePolicy);
 | 
					 | 
				
			||||||
			field_from_json(Obj, "devicePassword", DevicePassword);
 | 
					 | 
				
			||||||
			field_from_json(Obj, "subscriber", subscriber);
 | 
								field_from_json(Obj, "subscriber", subscriber);
 | 
				
			||||||
			field_from_json(Obj, "entity", entity);
 | 
								field_from_json(Obj, "entity", entity);
 | 
				
			||||||
			field_from_json(Obj, "modified", modified);
 | 
					 | 
				
			||||||
			field_from_json(Obj, "locale", locale);
 | 
								field_from_json(Obj, "locale", locale);
 | 
				
			||||||
			field_from_json(Obj, "restrictedDevice", restrictedDevice);
 | 
								field_from_json(Obj, "restrictedDevice", restrictedDevice);
 | 
				
			||||||
			field_from_json(Obj, "pendingConfiguration", pendingConfiguration);
 | 
								field_from_json(Obj, "pendingConfiguration", pendingConfiguration);
 | 
				
			||||||
			field_from_json(Obj, "pendingConfigurationCmd", pendingConfigurationCmd);
 | 
								field_from_json(Obj, "pendingConfigurationCmd", pendingConfigurationCmd);
 | 
				
			||||||
			field_from_json(Obj, "restrictionDetails", restrictionDetails);
 | 
								field_from_json(Obj, "restrictionDetails", restrictionDetails);
 | 
				
			||||||
			field_from_json(Obj, "pendingUUID", pendingUUID);
 | 
					 | 
				
			||||||
			field_from_json(Obj, "simulated", simulated);
 | 
					 | 
				
			||||||
			field_from_json(Obj, "lastRecordedContact", lastRecordedContact);
 | 
					 | 
				
			||||||
			return true;
 | 
								return true;
 | 
				
			||||||
		} catch (const Poco::Exception &E) {
 | 
							} catch (const Poco::Exception &E) {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -189,8 +165,6 @@ namespace OpenWifi::GWObjects {
 | 
				
			|||||||
		field_to_json(Obj, "waitingForFile", WaitingForFile);
 | 
							field_to_json(Obj, "waitingForFile", WaitingForFile);
 | 
				
			||||||
		field_to_json(Obj, "attachFile", AttachDate);
 | 
							field_to_json(Obj, "attachFile", AttachDate);
 | 
				
			||||||
		field_to_json(Obj, "executionTime", executionTime);
 | 
							field_to_json(Obj, "executionTime", executionTime);
 | 
				
			||||||
		field_to_json(Obj, "lastTry", lastTry);
 | 
					 | 
				
			||||||
		field_to_json(Obj, "deferred", deferred);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool DefaultConfiguration::from_json(const Poco::JSON::Object::Ptr &Obj) {
 | 
						bool DefaultConfiguration::from_json(const Poco::JSON::Object::Ptr &Obj) {
 | 
				
			||||||
@@ -224,7 +198,7 @@ namespace OpenWifi::GWObjects {
 | 
				
			|||||||
		return false;
 | 
							return false;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void ConnectionState::to_json([[maybe_unused]] const std::string &SerialNumber, Poco::JSON::Object &Obj)  {
 | 
						void ConnectionState::to_json(Poco::JSON::Object &Obj) const {
 | 
				
			||||||
		field_to_json(Obj, "ipAddress", Address);
 | 
							field_to_json(Obj, "ipAddress", Address);
 | 
				
			||||||
		field_to_json(Obj, "txBytes", TX);
 | 
							field_to_json(Obj, "txBytes", TX);
 | 
				
			||||||
		field_to_json(Obj, "rxBytes", RX);
 | 
							field_to_json(Obj, "rxBytes", RX);
 | 
				
			||||||
@@ -246,20 +220,6 @@ namespace OpenWifi::GWObjects {
 | 
				
			|||||||
		field_to_json(Obj, "connectionCompletionTime", connectionCompletionTime);
 | 
							field_to_json(Obj, "connectionCompletionTime", connectionCompletionTime);
 | 
				
			||||||
		field_to_json(Obj, "totalConnectionTime", Utils::Now() - started);
 | 
							field_to_json(Obj, "totalConnectionTime", Utils::Now() - started);
 | 
				
			||||||
		field_to_json(Obj, "certificateExpiryDate", certificateExpiryDate);
 | 
							field_to_json(Obj, "certificateExpiryDate", certificateExpiryDate);
 | 
				
			||||||
#ifdef TIP_GATEWAY_SERVICE
 | 
					 | 
				
			||||||
		hasRADIUSSessions = RADIUSSessionTracker()->HasSessions(SerialNumber);
 | 
					 | 
				
			||||||
		AP_WS_Server()->ExtendedAttributes(SerialNumber, hasGPS, sanity,
 | 
					 | 
				
			||||||
										   memoryUsed,
 | 
					 | 
				
			||||||
										   load,
 | 
					 | 
				
			||||||
										   temperature);
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
		field_to_json(Obj, "hasRADIUSSessions", hasRADIUSSessions );
 | 
					 | 
				
			||||||
		field_to_json(Obj, "hasGPS", hasGPS);
 | 
					 | 
				
			||||||
		field_to_json(Obj, "sanity", sanity);
 | 
					 | 
				
			||||||
		field_to_json(Obj, "memoryUsed", memoryUsed);
 | 
					 | 
				
			||||||
		field_to_json(Obj, "sanity", sanity);
 | 
					 | 
				
			||||||
		field_to_json(Obj, "load", load);
 | 
					 | 
				
			||||||
		field_to_json(Obj, "temperature", temperature);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		switch (VerifiedCertificate) {
 | 
							switch (VerifiedCertificate) {
 | 
				
			||||||
		case NO_CERTIFICATE:
 | 
							case NO_CERTIFICATE:
 | 
				
			||||||
@@ -274,9 +234,6 @@ namespace OpenWifi::GWObjects {
 | 
				
			|||||||
		case VERIFIED:
 | 
							case VERIFIED:
 | 
				
			||||||
			field_to_json(Obj, "verifiedCertificate", "VERIFIED");
 | 
								field_to_json(Obj, "verifiedCertificate", "VERIFIED");
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case SIMULATED:
 | 
					 | 
				
			||||||
			field_to_json(Obj, "verifiedCertificate", "SIMULATED");
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			field_to_json(Obj, "verifiedCertificate", "NO_CERTIFICATE");
 | 
								field_to_json(Obj, "verifiedCertificate", "NO_CERTIFICATE");
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
@@ -533,29 +490,6 @@ namespace OpenWifi::GWObjects {
 | 
				
			|||||||
		return false;
 | 
							return false;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void RangeOptions::to_json(Poco::JSON::Object &Obj) const {
 | 
					 | 
				
			||||||
		field_to_json(Obj, "NO_IR", NO_IR);
 | 
					 | 
				
			||||||
		field_to_json(Obj, "AUTO_BW", AUTO_BW);
 | 
					 | 
				
			||||||
		field_to_json(Obj, "DFS", DFS);
 | 
					 | 
				
			||||||
		field_to_json(Obj, "NO_OUTDOOR", NO_OUTDOOR);
 | 
					 | 
				
			||||||
		field_to_json(Obj, "wmmrule_ETSI", wmmrule_ETSI);
 | 
					 | 
				
			||||||
		field_to_json(Obj, "NO_OFDM", NO_OFDM);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void FrequencyRange::to_json(Poco::JSON::Object &Obj) const {
 | 
					 | 
				
			||||||
		field_to_json(Obj, "from", from);
 | 
					 | 
				
			||||||
		field_to_json(Obj, "to", to);
 | 
					 | 
				
			||||||
		field_to_json(Obj, "channelWidth", channelWidth);
 | 
					 | 
				
			||||||
		field_to_json(Obj, "powerDb", powerDb);
 | 
					 | 
				
			||||||
		field_to_json(Obj, "options", options);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void RegulatoryCountryInfo::to_json(Poco::JSON::Object &Obj) const {
 | 
					 | 
				
			||||||
		field_to_json(Obj, "country", country);
 | 
					 | 
				
			||||||
		field_to_json(Obj, "domain", domain);
 | 
					 | 
				
			||||||
		field_to_json(Obj, "ranges", ranges);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void DeviceRestrictionsKeyInfo::to_json(Poco::JSON::Object &Obj) const {
 | 
						void DeviceRestrictionsKeyInfo::to_json(Poco::JSON::Object &Obj) const {
 | 
				
			||||||
		field_to_json(Obj, "vendor", vendor);
 | 
							field_to_json(Obj, "vendor", vendor);
 | 
				
			||||||
		field_to_json(Obj, "algo", algo);
 | 
							field_to_json(Obj, "algo", algo);
 | 
				
			||||||
@@ -610,42 +544,4 @@ namespace OpenWifi::GWObjects {
 | 
				
			|||||||
				(T.commands != commands) || (T.developer != developer) || (T.ssh != ssh) ||
 | 
									(T.commands != commands) || (T.developer != developer) || (T.ssh != ssh) ||
 | 
				
			||||||
				(T.key_info != key_info) || (T.country != country));
 | 
									(T.key_info != key_info) || (T.country != country));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	void RADIUSSession::to_json(Poco::JSON::Object &Obj) const {
 | 
					 | 
				
			||||||
		field_to_json(Obj, "started", started);
 | 
					 | 
				
			||||||
		field_to_json(Obj, "lastTransaction", lastTransaction);
 | 
					 | 
				
			||||||
		field_to_json(Obj, "destination", destination);
 | 
					 | 
				
			||||||
		field_to_json(Obj, "serialNumber", serialNumber);
 | 
					 | 
				
			||||||
		field_to_json(Obj, "userName", userName);
 | 
					 | 
				
			||||||
		field_to_json(Obj, "accountingSessionId", accountingSessionId);
 | 
					 | 
				
			||||||
		field_to_json(Obj, "accountingMultiSessionId", accountingMultiSessionId);
 | 
					 | 
				
			||||||
		field_to_json(Obj, "inputPackets", inputPackets);
 | 
					 | 
				
			||||||
		field_to_json(Obj, "outputPackets", outputPackets);
 | 
					 | 
				
			||||||
		field_to_json(Obj, "inputOctets", inputOctets);
 | 
					 | 
				
			||||||
		field_to_json(Obj, "outputOctets", outputOctets);
 | 
					 | 
				
			||||||
		field_to_json(Obj, "inputGigaWords", inputGigaWords);
 | 
					 | 
				
			||||||
		field_to_json(Obj, "outputGigaWords", outputGigaWords);
 | 
					 | 
				
			||||||
		field_to_json(Obj, "sessionTime", sessionTime);
 | 
					 | 
				
			||||||
		field_to_json(Obj, "callingStationId", callingStationId);
 | 
					 | 
				
			||||||
		field_to_json(Obj, "chargeableUserIdentity", chargeableUserIdentity);
 | 
					 | 
				
			||||||
		field_to_json(Obj, "interface", interface);
 | 
					 | 
				
			||||||
		field_to_json(Obj, "secret", secret);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void RADIUSSessionList::to_json(Poco::JSON::Object &Obj) const {
 | 
					 | 
				
			||||||
		field_to_json(Obj, "sessions", sessions);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	bool RadiusCoADMParameters::from_json(const Poco::JSON::Object::Ptr &Obj) {
 | 
					 | 
				
			||||||
		try {
 | 
					 | 
				
			||||||
			field_from_json(Obj, "accountingSessionId", accountingSessionId);
 | 
					 | 
				
			||||||
			field_from_json(Obj, "accountingMultiSessionId", accountingMultiSessionId);
 | 
					 | 
				
			||||||
			field_from_json(Obj, "callingStationId", callingStationId);
 | 
					 | 
				
			||||||
			field_from_json(Obj, "chargeableUserIdentity", chargeableUserIdentity);
 | 
					 | 
				
			||||||
			return true;
 | 
					 | 
				
			||||||
		} catch (const Poco::Exception &E) {
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return false;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
} // namespace OpenWifi::GWObjects
 | 
					} // namespace OpenWifi::GWObjects
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,13 +11,9 @@
 | 
				
			|||||||
#include "Poco/JSON/Object.h"
 | 
					#include "Poco/JSON/Object.h"
 | 
				
			||||||
#include "RESTAPI_SecurityObjects.h"
 | 
					#include "RESTAPI_SecurityObjects.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef TIP_GATEWAY_SERVICE
 | 
					 | 
				
			||||||
#include <RADIUS_helpers.h>
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace OpenWifi::GWObjects {
 | 
					namespace OpenWifi::GWObjects {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	enum CertificateValidation { NO_CERTIFICATE, VALID_CERTIFICATE, MISMATCH_SERIAL, VERIFIED, SIMULATED };
 | 
						enum CertificateValidation { NO_CERTIFICATE, VALID_CERTIFICATE, MISMATCH_SERIAL, VERIFIED };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct ConnectionState {
 | 
						struct ConnectionState {
 | 
				
			||||||
		uint64_t MessageCount = 0;
 | 
							uint64_t MessageCount = 0;
 | 
				
			||||||
@@ -42,14 +38,8 @@ namespace OpenWifi::GWObjects {
 | 
				
			|||||||
		uint64_t sessionId = 0;
 | 
							uint64_t sessionId = 0;
 | 
				
			||||||
		double connectionCompletionTime = 0.0;
 | 
							double connectionCompletionTime = 0.0;
 | 
				
			||||||
		std::uint64_t certificateExpiryDate = 0;
 | 
							std::uint64_t certificateExpiryDate = 0;
 | 
				
			||||||
		bool hasRADIUSSessions = false;
 | 
					 | 
				
			||||||
		bool hasGPS = false;
 | 
					 | 
				
			||||||
		std::uint64_t sanity=0;
 | 
					 | 
				
			||||||
		std::double_t memoryUsed=0.0;
 | 
					 | 
				
			||||||
		std::double_t load=0.0;
 | 
					 | 
				
			||||||
		std::double_t temperature=0.0;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		void to_json(const std::string &SerialNumber, Poco::JSON::Object &Obj) ;
 | 
							void to_json(Poco::JSON::Object &Obj) const;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct DeviceRestrictionsKeyInfo {
 | 
						struct DeviceRestrictionsKeyInfo {
 | 
				
			||||||
@@ -106,9 +96,6 @@ namespace OpenWifi::GWObjects {
 | 
				
			|||||||
		std::string pendingConfiguration;
 | 
							std::string pendingConfiguration;
 | 
				
			||||||
		std::string pendingConfigurationCmd;
 | 
							std::string pendingConfigurationCmd;
 | 
				
			||||||
		DeviceRestrictions restrictionDetails;
 | 
							DeviceRestrictions restrictionDetails;
 | 
				
			||||||
		std::uint64_t pendingUUID = 0;
 | 
					 | 
				
			||||||
		bool simulated=false;
 | 
					 | 
				
			||||||
		std::uint64_t lastRecordedContact=0;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		void to_json(Poco::JSON::Object &Obj) const;
 | 
							void to_json(Poco::JSON::Object &Obj) const;
 | 
				
			||||||
		void to_json_with_status(Poco::JSON::Object &Obj) const;
 | 
							void to_json_with_status(Poco::JSON::Object &Obj) const;
 | 
				
			||||||
@@ -201,11 +188,7 @@ namespace OpenWifi::GWObjects {
 | 
				
			|||||||
		uint64_t AttachSize = 0;
 | 
							uint64_t AttachSize = 0;
 | 
				
			||||||
		std::string AttachType;
 | 
							std::string AttachType;
 | 
				
			||||||
		double executionTime = 0.0;
 | 
							double executionTime = 0.0;
 | 
				
			||||||
		std::uint64_t lastTry = 0;
 | 
					 | 
				
			||||||
		bool deferred = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		void to_json(Poco::JSON::Object &Obj) const;
 | 
							void to_json(Poco::JSON::Object &Obj) const;
 | 
				
			||||||
		bool from_json(const Poco::JSON::Object::Ptr &Obj);
 | 
					 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct BlackListedDevice {
 | 
						struct BlackListedDevice {
 | 
				
			||||||
@@ -351,76 +334,4 @@ namespace OpenWifi::GWObjects {
 | 
				
			|||||||
		bool from_json(const Poco::JSON::Object::Ptr &Obj);
 | 
							bool from_json(const Poco::JSON::Object::Ptr &Obj);
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct RangeOptions {
 | 
					 | 
				
			||||||
		bool NO_IR=false;
 | 
					 | 
				
			||||||
		bool AUTO_BW=false;
 | 
					 | 
				
			||||||
		bool DFS=false;
 | 
					 | 
				
			||||||
		bool NO_OUTDOOR=false;
 | 
					 | 
				
			||||||
		bool wmmrule_ETSI=false;
 | 
					 | 
				
			||||||
		bool NO_OFDM=false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		void to_json(Poco::JSON::Object &Obj) const;
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct FrequencyRange {
 | 
					 | 
				
			||||||
		float from = 0.0;
 | 
					 | 
				
			||||||
		float to = 0.0;
 | 
					 | 
				
			||||||
		int channelWidth = 0;
 | 
					 | 
				
			||||||
		int powerDb = 0;
 | 
					 | 
				
			||||||
		RangeOptions    options;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		void to_json(Poco::JSON::Object &Obj) const;
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct RegulatoryCountryInfo {
 | 
					 | 
				
			||||||
		std::string country;
 | 
					 | 
				
			||||||
		std::string domain;
 | 
					 | 
				
			||||||
		std::vector<FrequencyRange>   ranges;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		void to_json(Poco::JSON::Object &Obj) const;
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	using RegulatoryInfoCountryMap = std::map<std::string,RegulatoryCountryInfo>;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct RADIUSSession {
 | 
					 | 
				
			||||||
		std::uint64_t 			started=0,
 | 
					 | 
				
			||||||
								lastTransaction=0;
 | 
					 | 
				
			||||||
		std::string 			serialNumber,
 | 
					 | 
				
			||||||
								destination,
 | 
					 | 
				
			||||||
								userName,
 | 
					 | 
				
			||||||
					 			accountingSessionId,
 | 
					 | 
				
			||||||
								accountingMultiSessionId,
 | 
					 | 
				
			||||||
					 			callingStationId,
 | 
					 | 
				
			||||||
								chargeableUserIdentity,
 | 
					 | 
				
			||||||
								secret,
 | 
					 | 
				
			||||||
								interface;
 | 
					 | 
				
			||||||
		std::uint64_t 			inputPackets = 0,
 | 
					 | 
				
			||||||
								outputPackets = 0,
 | 
					 | 
				
			||||||
								inputOctets = 0,
 | 
					 | 
				
			||||||
								outputOctets = 0,
 | 
					 | 
				
			||||||
								inputGigaWords = 0,
 | 
					 | 
				
			||||||
								outputGigaWords = 0;
 | 
					 | 
				
			||||||
		std::uint32_t 			sessionTime = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#ifdef TIP_GATEWAY_SERVICE
 | 
					 | 
				
			||||||
		RADIUS::RadiusPacket	accountingPacket;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		void to_json(Poco::JSON::Object &Obj) const;
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct RADIUSSessionList {
 | 
					 | 
				
			||||||
		std::vector<RADIUSSession>	sessions;
 | 
					 | 
				
			||||||
		void to_json(Poco::JSON::Object &Obj) const;
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	struct RadiusCoADMParameters {
 | 
					 | 
				
			||||||
		std::string 			accountingSessionId,
 | 
					 | 
				
			||||||
								accountingMultiSessionId,
 | 
					 | 
				
			||||||
								callingStationId,
 | 
					 | 
				
			||||||
								chargeableUserIdentity;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		bool from_json(const Poco::JSON::Object::Ptr &Obj);
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
} // namespace OpenWifi::GWObjects
 | 
					} // namespace OpenWifi::GWObjects
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,19 +4,17 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "ALBserver.h"
 | 
					#include "ALBserver.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "fmt/format.h"
 | 
					 | 
				
			||||||
#include "framework/MicroServiceFuncs.h"
 | 
					 | 
				
			||||||
#include "framework/utils.h"
 | 
					#include "framework/utils.h"
 | 
				
			||||||
 | 
					#include "framework/MicroServiceFuncs.h"
 | 
				
			||||||
 | 
					#include "fmt/format.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void ALBRequestHandler::handleRequest([[maybe_unused]] Poco::Net::HTTPServerRequest &Request,
 | 
						void ALBRequestHandler::handleRequest([[maybe_unused]] Poco::Net::HTTPServerRequest& Request, Poco::Net::HTTPServerResponse& Response) {
 | 
				
			||||||
										  Poco::Net::HTTPServerResponse &Response) {
 | 
					 | 
				
			||||||
		Utils::SetThreadName("alb-request");
 | 
							Utils::SetThreadName("alb-request");
 | 
				
			||||||
		try {
 | 
							try {
 | 
				
			||||||
			if((id_ % 100) == 0) {
 | 
								if((id_ % 100) == 0) {
 | 
				
			||||||
				Logger_.debug(fmt::format("ALB-REQUEST({}): ALB Request {}.",
 | 
									Logger_.debug(fmt::format("ALB-REQUEST({}): ALB Request {}.", Request.clientAddress().toString(), id_));
 | 
				
			||||||
										  Request.clientAddress().toString(), id_));
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			Response.setChunkedTransferEncoding(true);
 | 
								Response.setChunkedTransferEncoding(true);
 | 
				
			||||||
			Response.setContentType("text/html");
 | 
								Response.setContentType("text/html");
 | 
				
			||||||
@@ -28,21 +26,25 @@ namespace OpenWifi {
 | 
				
			|||||||
			std::ostream &Answer = Response.send();
 | 
								std::ostream &Answer = Response.send();
 | 
				
			||||||
			Answer << "process Alive and kicking!";
 | 
								Answer << "process Alive and kicking!";
 | 
				
			||||||
		} catch (...) {
 | 
							} catch (...) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ALBRequestHandlerFactory::ALBRequestHandlerFactory(Poco::Logger &L) : Logger_(L) {}
 | 
						ALBRequestHandlerFactory::ALBRequestHandlerFactory(Poco::Logger & L):
 | 
				
			||||||
 | 
							Logger_(L) {
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ALBRequestHandler *
 | 
						ALBRequestHandler* ALBRequestHandlerFactory::createRequestHandler(const Poco::Net::HTTPServerRequest& request) {
 | 
				
			||||||
	ALBRequestHandlerFactory::createRequestHandler(const Poco::Net::HTTPServerRequest &request) {
 | 
					 | 
				
			||||||
		if (request.getURI() == "/")
 | 
							if (request.getURI() == "/")
 | 
				
			||||||
			return new ALBRequestHandler(Logger_, req_id_++);
 | 
								return new ALBRequestHandler(Logger_, req_id_++);
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			return nullptr;
 | 
								return nullptr;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ALBHealthCheckServer::ALBHealthCheckServer()
 | 
						ALBHealthCheckServer::ALBHealthCheckServer() :
 | 
				
			||||||
		: SubSystemServer("ALBHealthCheckServer", "ALB-SVR", "alb") {}
 | 
							  SubSystemServer("ALBHealthCheckServer", "ALB-SVR", "alb")
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int ALBHealthCheckServer::Start() {
 | 
						int ALBHealthCheckServer::Start() {
 | 
				
			||||||
		if(MicroServiceConfigGetBool("alb.enable",false)) {
 | 
							if(MicroServiceConfigGetBool("alb.enable",false)) {
 | 
				
			||||||
@@ -58,8 +60,7 @@ namespace OpenWifi {
 | 
				
			|||||||
			Socket_ = std::make_unique<Poco::Net::ServerSocket>(SockAddr, Port_);
 | 
								Socket_ = std::make_unique<Poco::Net::ServerSocket>(SockAddr, Port_);
 | 
				
			||||||
			auto Params = new Poco::Net::HTTPServerParams;
 | 
								auto Params = new Poco::Net::HTTPServerParams;
 | 
				
			||||||
			Params->setName("ws:alb");
 | 
								Params->setName("ws:alb");
 | 
				
			||||||
			Server_ = std::make_unique<Poco::Net::HTTPServer>(
 | 
								Server_ = std::make_unique<Poco::Net::HTTPServer>(new ALBRequestHandlerFactory(Logger()), *Socket_, Params);
 | 
				
			||||||
				new ALBRequestHandlerFactory(Logger()), *Socket_, Params);
 | 
					 | 
				
			||||||
			Server_->start();
 | 
								Server_->start();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,30 +7,31 @@
 | 
				
			|||||||
#include "framework/SubSystemServer.h"
 | 
					#include "framework/SubSystemServer.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "Poco/Net/HTTPRequestHandler.h"
 | 
					#include "Poco/Net/HTTPRequestHandler.h"
 | 
				
			||||||
#include "Poco/Net/HTTPRequestHandlerFactory.h"
 | 
					 | 
				
			||||||
#include "Poco/Net/HTTPServer.h"
 | 
					 | 
				
			||||||
#include "Poco/Net/HTTPServerRequest.h"
 | 
					#include "Poco/Net/HTTPServerRequest.h"
 | 
				
			||||||
#include "Poco/Net/HTTPServerResponse.h"
 | 
					#include "Poco/Net/HTTPServerResponse.h"
 | 
				
			||||||
 | 
					#include "Poco/Net/HTTPRequestHandlerFactory.h"
 | 
				
			||||||
 | 
					#include "Poco/Net/HTTPServer.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	class ALBRequestHandler: public Poco::Net::HTTPRequestHandler {
 | 
						class ALBRequestHandler: public Poco::Net::HTTPRequestHandler {
 | 
				
			||||||
	  public:
 | 
						  public:
 | 
				
			||||||
		explicit ALBRequestHandler(Poco::Logger &L, uint64_t id) : Logger_(L), id_(id) {}
 | 
							explicit ALBRequestHandler(Poco::Logger & L, uint64_t id)
 | 
				
			||||||
 | 
					                : Logger_(L), id_(id) {
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		void handleRequest([[maybe_unused]] Poco::Net::HTTPServerRequest &Request,
 | 
							void handleRequest([[maybe_unused]] Poco::Net::HTTPServerRequest& Request, Poco::Net::HTTPServerResponse& Response) override;
 | 
				
			||||||
						   Poco::Net::HTTPServerResponse &Response) override;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	  private:
 | 
						  private:
 | 
				
			||||||
		Poco::Logger 	& Logger_;
 | 
							Poco::Logger 	& Logger_;
 | 
				
			||||||
		uint64_t 		id_;
 | 
							uint64_t 		id_;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	class ALBRequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
 | 
						class ALBRequestHandlerFactory: public Poco::Net::HTTPRequestHandlerFactory
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
	  public:
 | 
						  public:
 | 
				
			||||||
		explicit ALBRequestHandlerFactory(Poco::Logger & L);
 | 
							explicit ALBRequestHandlerFactory(Poco::Logger & L);
 | 
				
			||||||
		ALBRequestHandler *
 | 
							ALBRequestHandler* createRequestHandler(const Poco::Net::HTTPServerRequest& request) override;
 | 
				
			||||||
		createRequestHandler(const Poco::Net::HTTPServerRequest &request) override;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	  private:
 | 
						  private:
 | 
				
			||||||
		Poco::Logger	                            &Logger_;
 | 
							Poco::Logger	                            &Logger_;
 | 
				
			||||||
@@ -59,3 +60,4 @@ namespace OpenWifi {
 | 
				
			|||||||
	inline auto ALBHealthCheckServer() { return ALBHealthCheckServer::instance(); }
 | 
						inline auto ALBHealthCheckServer() { return ALBHealthCheckServer::instance(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace OpenWifi
 | 
					} // namespace OpenWifi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,19 +4,22 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "Poco/JSON/Parser.h"
 | 
					 | 
				
			||||||
#include "Poco/Logger.h"
 | 
					#include "Poco/Logger.h"
 | 
				
			||||||
#include "Poco/Net/HTTPSClientSession.h"
 | 
					#include "Poco/JSON/Parser.h"
 | 
				
			||||||
#include "Poco/Net/HTTPServerRequest.h"
 | 
					#include "Poco/Net/HTTPServerRequest.h"
 | 
				
			||||||
#include "Poco/Net/HTTPServerResponse.h"
 | 
					#include "Poco/Net/HTTPServerResponse.h"
 | 
				
			||||||
 | 
					#include "Poco/Net/HTTPSClientSession.h"
 | 
				
			||||||
#include "Poco/URI.h"
 | 
					#include "Poco/URI.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "framework/MicroServiceFuncs.h"
 | 
					#include "framework/MicroServiceFuncs.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
	inline void API_Proxy(Poco::Logger &Logger, Poco::Net::HTTPServerRequest *Request,
 | 
					    inline void API_Proxy( Poco::Logger &Logger,
 | 
				
			||||||
						  Poco::Net::HTTPServerResponse *Response, const char *ServiceType,
 | 
					                    Poco::Net::HTTPServerRequest *Request,
 | 
				
			||||||
						  const char *PathRewrite, uint64_t msTimeout_ = 10000) {
 | 
					                    Poco::Net::HTTPServerResponse *Response,
 | 
				
			||||||
 | 
					                    const char * ServiceType,
 | 
				
			||||||
 | 
					                    const char * PathRewrite,
 | 
				
			||||||
 | 
					                    uint64_t msTimeout_ = 10000 ) {
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            auto Services = MicroServiceGetServices(ServiceType);
 | 
					            auto Services = MicroServiceGetServices(ServiceType);
 | 
				
			||||||
            for(auto const &Svc:Services) {
 | 
					            for(auto const &Svc:Services) {
 | 
				
			||||||
@@ -28,8 +31,7 @@ namespace OpenWifi {
 | 
				
			|||||||
                // std::cout << "     Source: " << SourceURI.toString() << std::endl;
 | 
					                // std::cout << "     Source: " << SourceURI.toString() << std::endl;
 | 
				
			||||||
                // std::cout << "Destination: " << DestinationURI.toString() << std::endl;
 | 
					                // std::cout << "Destination: " << DestinationURI.toString() << std::endl;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				Poco::Net::HTTPSClientSession Session(DestinationURI.getHost(),
 | 
					                Poco::Net::HTTPSClientSession Session(DestinationURI.getHost(), DestinationURI.getPort());
 | 
				
			||||||
													  DestinationURI.getPort());
 | 
					 | 
				
			||||||
                Session.setKeepAlive(true);
 | 
					                Session.setKeepAlive(true);
 | 
				
			||||||
                Session.setTimeout(Poco::Timespan(msTimeout_/1000, msTimeout_ % 1000));
 | 
					                Session.setTimeout(Poco::Timespan(msTimeout_/1000, msTimeout_ % 1000));
 | 
				
			||||||
                Poco::Net::HTTPRequest ProxyRequest(Request->getMethod(),
 | 
					                Poco::Net::HTTPRequest ProxyRequest(Request->getMethod(),
 | 
				
			||||||
@@ -74,8 +76,7 @@ namespace OpenWifi {
 | 
				
			|||||||
                    try {
 | 
					                    try {
 | 
				
			||||||
                        std::istream &ProxyResponseStream = Session.receiveResponse(ProxyResponse);
 | 
					                        std::istream &ProxyResponseStream = Session.receiveResponse(ProxyResponse);
 | 
				
			||||||
                        Poco::JSON::Parser  P2;
 | 
					                        Poco::JSON::Parser  P2;
 | 
				
			||||||
						auto ProxyResponseBody =
 | 
					                        auto ProxyResponseBody = P2.parse(ProxyResponseStream).extract<Poco::JSON::Object::Ptr>();
 | 
				
			||||||
							P2.parse(ProxyResponseStream).extract<Poco::JSON::Object::Ptr>();
 | 
					 | 
				
			||||||
                        Poco::JSON::Stringifier::condense(ProxyResponseBody,SSR);
 | 
					                        Poco::JSON::Stringifier::condense(ProxyResponseBody,SSR);
 | 
				
			||||||
                        Response->setContentType("application/json");
 | 
					                        Response->setContentType("application/json");
 | 
				
			||||||
                        Response->setContentLength(SSR.str().size());
 | 
					                        Response->setContentLength(SSR.str().size());
 | 
				
			||||||
@@ -83,6 +84,7 @@ namespace OpenWifi {
 | 
				
			|||||||
                        Response->sendBuffer(SSR.str().c_str(),SSR.str().size());
 | 
					                        Response->sendBuffer(SSR.str().c_str(),SSR.str().size());
 | 
				
			||||||
                        return;
 | 
					                        return;
 | 
				
			||||||
                    } catch( const Poco::Exception & E) {
 | 
					                    } catch( const Poco::Exception & E) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    Response->setStatus(ProxyResponse.getStatus());
 | 
					                    Response->setStatus(ProxyResponse.getStatus());
 | 
				
			||||||
                    Response->send();
 | 
					                    Response->send();
 | 
				
			||||||
@@ -94,4 +96,4 @@ namespace OpenWifi {
 | 
				
			|||||||
            Logger.log(E);
 | 
					            Logger.log(E);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
} // namespace OpenWifi
 | 
					}
 | 
				
			||||||
@@ -4,13 +4,13 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
#include <fstream>
 | 
					#include <fstream>
 | 
				
			||||||
#include <iomanip>
 | 
					#include <iomanip>
 | 
				
			||||||
#include <iostream>
 | 
					#include <iostream>
 | 
				
			||||||
#include <string>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "Poco/File.h"
 | 
					 | 
				
			||||||
#include "Poco/StreamCopier.h"
 | 
					#include "Poco/StreamCopier.h"
 | 
				
			||||||
 | 
					#include "Poco/File.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "framework/MicroServiceFuncs.h"
 | 
					#include "framework/MicroServiceFuncs.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -18,6 +18,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	class AppServiceRegistry {
 | 
						class AppServiceRegistry {
 | 
				
			||||||
	  public:
 | 
						  public:
 | 
				
			||||||
		AppServiceRegistry() {
 | 
							AppServiceRegistry() {
 | 
				
			||||||
@@ -41,7 +42,9 @@ namespace OpenWifi {
 | 
				
			|||||||
			return *instance_;
 | 
								return *instance_;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline ~AppServiceRegistry() { Save(); }
 | 
							inline ~AppServiceRegistry() {
 | 
				
			||||||
 | 
								Save();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline void Save() {
 | 
							inline void Save() {
 | 
				
			||||||
			std::istringstream  IS( to_string(Registry_));
 | 
								std::istringstream  IS( to_string(Registry_));
 | 
				
			||||||
@@ -96,4 +99,4 @@ namespace OpenWifi {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	inline auto AppServiceRegistry() { return AppServiceRegistry::instance(); }
 | 
						inline auto AppServiceRegistry() { return AppServiceRegistry::instance(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace OpenWifi
 | 
					}
 | 
				
			||||||
@@ -4,27 +4,28 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "Poco/Net/HTTPServerResponse.h"
 | 
					#include "Poco/Net/HTTPServerResponse.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "fmt/format.h"
 | 
					 | 
				
			||||||
#include "framework/AuthClient.h"
 | 
					#include "framework/AuthClient.h"
 | 
				
			||||||
#include "framework/MicroServiceNames.h"
 | 
					#include "framework/MicroServiceNames.h"
 | 
				
			||||||
#include "framework/OpenAPIRequests.h"
 | 
					#include "framework/OpenAPIRequests.h"
 | 
				
			||||||
#include "framework/utils.h"
 | 
					#include "framework/utils.h"
 | 
				
			||||||
 | 
					#include "fmt/format.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool AuthClient::RetrieveTokenInformation(const std::string & SessionToken,
 | 
						bool AuthClient::RetrieveTokenInformation(const std::string & SessionToken,
 | 
				
			||||||
										 SecurityObjects::UserInfoAndPolicy & UInfo,
 | 
															 SecurityObjects::UserInfoAndPolicy & UInfo,
 | 
				
			||||||
											  std::uint64_t TID, bool &Expired, bool &Contacted,
 | 
															 std::uint64_t TID,
 | 
				
			||||||
											  bool Sub) {
 | 
															 bool & Expired, bool & Contacted, bool Sub) {
 | 
				
			||||||
		try {
 | 
							try {
 | 
				
			||||||
			Types::StringPairVec QueryData;
 | 
								Types::StringPairVec QueryData;
 | 
				
			||||||
			QueryData.push_back(std::make_pair("token",SessionToken));
 | 
								QueryData.push_back(std::make_pair("token",SessionToken));
 | 
				
			||||||
			std::string AlternateURIForLogging = fmt::format(
 | 
					            std::string     AlternateURIForLogging = fmt::format("{}?token={}",  Sub ? "/api/v1/validateSubToken" : "/api/v1/validateToken", Utils::SanitizeToken(SessionToken));
 | 
				
			||||||
				"{}?token={}", Sub ? "/api/v1/validateSubToken" : "/api/v1/validateToken",
 | 
					 | 
				
			||||||
				Utils::SanitizeToken(SessionToken));
 | 
					 | 
				
			||||||
			OpenAPIRequestGet	Req(    uSERVICE_SECURITY,
 | 
								OpenAPIRequestGet	Req(    uSERVICE_SECURITY,
 | 
				
			||||||
								  Sub ? "/api/v1/validateSubToken" : "/api/v1/validateToken",
 | 
													  Sub ? "/api/v1/validateSubToken" : "/api/v1/validateToken",
 | 
				
			||||||
								  QueryData, 10000, AlternateURIForLogging);
 | 
													  QueryData,
 | 
				
			||||||
 | 
													  10000,
 | 
				
			||||||
 | 
													  AlternateURIForLogging
 | 
				
			||||||
 | 
					                                  );
 | 
				
			||||||
			Poco::JSON::Object::Ptr Response;
 | 
								Poco::JSON::Object::Ptr Response;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			auto StatusCode = Req.Do(Response);
 | 
								auto StatusCode = Req.Do(Response);
 | 
				
			||||||
@@ -49,15 +50,14 @@ namespace OpenWifi {
 | 
				
			|||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		} catch (...) {
 | 
							} catch (...) {
 | 
				
			||||||
			poco_error(Logger(), fmt::format("Failed to retrieve token={} for TID={}",
 | 
								poco_error(Logger(),fmt::format("Failed to retrieve token={} for TID={}", Utils::SanitizeToken(SessionToken), TID));
 | 
				
			||||||
											 Utils::SanitizeToken(SessionToken), TID));
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		Expired = false;
 | 
							Expired = false;
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool AuthClient::IsAuthorized(const std::string &SessionToken,
 | 
						bool AuthClient::IsAuthorized(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo,
 | 
				
			||||||
								  SecurityObjects::UserInfoAndPolicy &UInfo, std::uint64_t TID,
 | 
												 std::uint64_t TID,
 | 
				
			||||||
							 bool & Expired, bool & Contacted, bool Sub) {
 | 
												 bool & Expired, bool & Contacted, bool Sub) {
 | 
				
			||||||
		auto User = Cache_.get(SessionToken);
 | 
							auto User = Cache_.get(SessionToken);
 | 
				
			||||||
		if(!User.isNull()) {
 | 
							if(!User.isNull()) {
 | 
				
			||||||
@@ -75,14 +75,16 @@ namespace OpenWifi {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    bool AuthClient::RetrieveApiKeyInformation(const std::string & SessionToken,
 | 
					    bool AuthClient::RetrieveApiKeyInformation(const std::string & SessionToken,
 | 
				
			||||||
                                              SecurityObjects::UserInfoAndPolicy & UInfo,
 | 
					                                              SecurityObjects::UserInfoAndPolicy & UInfo,
 | 
				
			||||||
											   std::uint64_t TID, bool &Expired, bool &Contacted,
 | 
					                                              std::uint64_t TID,
 | 
				
			||||||
											   [[maybe_unused]] bool &Suspended) {
 | 
					                                              bool & Expired, bool & Contacted, [[maybe_unused]] bool & Suspended) {
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            Types::StringPairVec QueryData;
 | 
					            Types::StringPairVec QueryData;
 | 
				
			||||||
            QueryData.push_back(std::make_pair("apikey",SessionToken));
 | 
					            QueryData.push_back(std::make_pair("apikey",SessionToken));
 | 
				
			||||||
			std::string AlternateURIForLogging =
 | 
					            std::string     AlternateURIForLogging = fmt::format("/api/v1/validateApiKey?apiKey={}", Utils::SanitizeToken(SessionToken));
 | 
				
			||||||
				fmt::format("/api/v1/validateApiKey?apiKey={}", Utils::SanitizeToken(SessionToken));
 | 
					            OpenAPIRequestGet	Req(    uSERVICE_SECURITY,
 | 
				
			||||||
			OpenAPIRequestGet Req(uSERVICE_SECURITY, "/api/v1/validateApiKey", QueryData, 10000,
 | 
					                                         "/api/v1/validateApiKey" ,
 | 
				
			||||||
 | 
					                                         QueryData,
 | 
				
			||||||
 | 
					                                         10000,
 | 
				
			||||||
                                         AlternateURIForLogging);
 | 
					                                         AlternateURIForLogging);
 | 
				
			||||||
            Poco::JSON::Object::Ptr Response;
 | 
					            Poco::JSON::Object::Ptr Response;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -94,29 +96,24 @@ namespace OpenWifi {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            Contacted = true;
 | 
					            Contacted = true;
 | 
				
			||||||
            if(StatusCode==Poco::Net::HTTPServerResponse::HTTP_OK) {
 | 
					            if(StatusCode==Poco::Net::HTTPServerResponse::HTTP_OK) {
 | 
				
			||||||
				if (Response->has("tokenInfo") && Response->has("userInfo") &&
 | 
					                if(Response->has("tokenInfo") && Response->has("userInfo") && Response->has("expiresOn")) {
 | 
				
			||||||
					Response->has("expiresOn")) {
 | 
					 | 
				
			||||||
                    UInfo.from_json(Response);
 | 
					                    UInfo.from_json(Response);
 | 
				
			||||||
                    Expired = false;
 | 
					                    Expired = false;
 | 
				
			||||||
					ApiKeyCache_.update(SessionToken,
 | 
					                    ApiKeyCache_.update(SessionToken, ApiKeyCacheEntry{ .UserInfo = UInfo, .ExpiresOn = Response->get("expiresOn")});
 | 
				
			||||||
										ApiKeyCacheEntry{.UserInfo = UInfo,
 | 
					 | 
				
			||||||
														 .ExpiresOn = Response->get("expiresOn")});
 | 
					 | 
				
			||||||
                    return true;
 | 
					                    return true;
 | 
				
			||||||
                } else {
 | 
					                } else {
 | 
				
			||||||
                    return false;
 | 
					                    return false;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        } catch (...) {
 | 
					        } catch (...) {
 | 
				
			||||||
			poco_error(Logger(), fmt::format("Failed to retrieve api key={} for TID={}",
 | 
					            poco_error(Logger(),fmt::format("Failed to retrieve api key={} for TID={}", Utils::SanitizeToken(SessionToken), TID));
 | 
				
			||||||
											 Utils::SanitizeToken(SessionToken), TID));
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        Expired = false;
 | 
					        Expired = false;
 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool AuthClient::IsValidApiKey(const std::string &SessionToken,
 | 
					    bool AuthClient::IsValidApiKey(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy &UInfo,
 | 
				
			||||||
								   SecurityObjects::UserInfoAndPolicy &UInfo, std::uint64_t TID,
 | 
					                                   std::uint64_t TID, bool &Expired, bool &Contacted, bool & Suspended) {
 | 
				
			||||||
								   bool &Expired, bool &Contacted, bool &Suspended) {
 | 
					 | 
				
			||||||
        auto User = ApiKeyCache_.get(SessionToken);
 | 
					        auto User = ApiKeyCache_.get(SessionToken);
 | 
				
			||||||
        if (!User.isNull()) {
 | 
					        if (!User.isNull()) {
 | 
				
			||||||
            if(User->ExpiresOn < Utils::Now()) {
 | 
					            if(User->ExpiresOn < Utils::Now()) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,9 +4,9 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "Poco/ExpireLRUCache.h"
 | 
					 | 
				
			||||||
#include "RESTObjects/RESTAPI_SecurityObjects.h"
 | 
					 | 
				
			||||||
#include "framework/SubSystemServer.h"
 | 
					#include "framework/SubSystemServer.h"
 | 
				
			||||||
 | 
					#include "RESTObjects/RESTAPI_SecurityObjects.h"
 | 
				
			||||||
 | 
					#include "Poco/ExpireLRUCache.h"
 | 
				
			||||||
#include "framework/utils.h"
 | 
					#include "framework/utils.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
@@ -14,8 +14,10 @@ namespace OpenWifi {
 | 
				
			|||||||
	class AuthClient : public SubSystemServer {
 | 
						class AuthClient : public SubSystemServer {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	  public:
 | 
						  public:
 | 
				
			||||||
		explicit AuthClient() noexcept
 | 
							explicit AuthClient() noexcept:
 | 
				
			||||||
			: SubSystemServer("Authentication", "AUTH-CLNT", "authentication") {}
 | 
								 SubSystemServer("Authentication", "AUTH-CLNT", "authentication")
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		static auto instance() {
 | 
							static auto instance() {
 | 
				
			||||||
			static auto instance_ = new AuthClient;
 | 
								static auto instance_ = new AuthClient;
 | 
				
			||||||
@@ -27,7 +29,9 @@ namespace OpenWifi {
 | 
				
			|||||||
            std::uint64_t                                   ExpiresOn;
 | 
					            std::uint64_t                                   ExpiresOn;
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline int Start() override { return 0; }
 | 
					        inline int Start() override {
 | 
				
			||||||
 | 
								return 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline void Stop() override {
 | 
							inline void Stop() override {
 | 
				
			||||||
			poco_information(Logger(),"Stopping...");
 | 
								poco_information(Logger(),"Stopping...");
 | 
				
			||||||
@@ -46,27 +50,30 @@ namespace OpenWifi {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		bool RetrieveTokenInformation(const std::string & SessionToken,
 | 
							bool RetrieveTokenInformation(const std::string & SessionToken,
 | 
				
			||||||
									  SecurityObjects::UserInfoAndPolicy &UInfo, std::uint64_t TID,
 | 
								SecurityObjects::UserInfoAndPolicy & UInfo,
 | 
				
			||||||
 | 
								std::uint64_t TID,
 | 
				
			||||||
		bool & Expired, bool & Contacted, bool Sub=false);
 | 
							bool & Expired, bool & Contacted, bool Sub=false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        bool RetrieveApiKeyInformation(const std::string & SessionToken,
 | 
					        bool RetrieveApiKeyInformation(const std::string & SessionToken,
 | 
				
			||||||
									   SecurityObjects::UserInfoAndPolicy &UInfo, std::uint64_t TID,
 | 
					                                      SecurityObjects::UserInfoAndPolicy & UInfo,
 | 
				
			||||||
 | 
					                                      std::uint64_t TID,
 | 
				
			||||||
                                      bool & Expired, bool & Contacted, bool & Suspended);
 | 
					                                      bool & Expired, bool & Contacted, bool & Suspended);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		bool IsAuthorized(const std::string &SessionToken,
 | 
							bool IsAuthorized(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo,
 | 
				
			||||||
						  SecurityObjects::UserInfoAndPolicy &UInfo, std::uint64_t TID,
 | 
													 std::uint64_t TID,
 | 
				
			||||||
								 bool & Expired, bool & Contacted, bool Sub = false);
 | 
													 bool & Expired, bool & Contacted, bool Sub = false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		bool IsValidApiKey(const std::string &SessionToken,
 | 
					        bool IsValidApiKey(const std::string &SessionToken, SecurityObjects::UserInfoAndPolicy & UInfo,
 | 
				
			||||||
						   SecurityObjects::UserInfoAndPolicy &UInfo, std::uint64_t TID,
 | 
					                          std::uint64_t TID,
 | 
				
			||||||
                          bool & Expired, bool & Contacted, bool & Suspended) ;
 | 
					                          bool & Expired, bool & Contacted, bool & Suspended) ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	  private:
 | 
						  private:
 | 
				
			||||||
		Poco::ExpireLRUCache<std::string, OpenWifi::SecurityObjects::UserInfoAndPolicy> Cache_{
 | 
					
 | 
				
			||||||
			512, 1200000};
 | 
							Poco::ExpireLRUCache<std::string,OpenWifi::SecurityObjects::UserInfoAndPolicy>      Cache_{512,1200000 };
 | 
				
			||||||
        Poco::ExpireLRUCache<std::string,ApiKeyCacheEntry>                                  ApiKeyCache_{512,1200000 };
 | 
					        Poco::ExpireLRUCache<std::string,ApiKeyCacheEntry>                                  ApiKeyCache_{512,1200000 };
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline auto AuthClient() { return AuthClient::instance(); }
 | 
						inline auto AuthClient() { return AuthClient::instance(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace OpenWifi
 | 
					} // namespace OpenWifi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -152,4 +152,4 @@ namespace OpenWifi::CIDR {
 | 
				
			|||||||
	[[nodiscard]] inline bool ValidateIpRanges(const Types::StringVec &Ranges) {
 | 
						[[nodiscard]] inline bool ValidateIpRanges(const Types::StringVec &Ranges) {
 | 
				
			||||||
		return std::all_of(cbegin(Ranges), cend(Ranges), ValidateRange);
 | 
							return std::all_of(cbegin(Ranges), cend(Ranges), ValidateRange);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
} // namespace OpenWifi::CIDR
 | 
					}
 | 
				
			||||||
@@ -2,8 +2,8 @@
 | 
				
			|||||||
// Created by stephane bourque on 2021-09-14.
 | 
					// Created by stephane bourque on 2021-09-14.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <fstream>
 | 
					 | 
				
			||||||
#include <iostream>
 | 
					#include <iostream>
 | 
				
			||||||
 | 
					#include <fstream>
 | 
				
			||||||
#include <regex>
 | 
					#include <regex>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "ConfigurationValidator.h"
 | 
					#include "ConfigurationValidator.h"
 | 
				
			||||||
@@ -17,15 +17,14 @@
 | 
				
			|||||||
#include "fmt/format.h"
 | 
					#include "fmt/format.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <valijson/adapters/poco_json_adapter.hpp>
 | 
					#include <valijson/adapters/poco_json_adapter.hpp>
 | 
				
			||||||
#include <valijson/constraints/constraint.hpp>
 | 
					#include <valijson/utils/poco_json_utils.hpp>
 | 
				
			||||||
#include <valijson/schema.hpp>
 | 
					#include <valijson/schema.hpp>
 | 
				
			||||||
#include <valijson/schema_parser.hpp>
 | 
					#include <valijson/schema_parser.hpp>
 | 
				
			||||||
#include <valijson/utils/poco_json_utils.hpp>
 | 
					 | 
				
			||||||
#include <valijson/validator.hpp>
 | 
					#include <valijson/validator.hpp>
 | 
				
			||||||
 | 
					#include <valijson/constraints/constraint.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static const std::string GitUCentralJSONSchemaFile{
 | 
					static const std::string GitUCentralJSONSchemaFile{
 | 
				
			||||||
	"https://raw.githubusercontent.com/Telecominfraproject/wlan-ucentral-schema/main/"
 | 
						"https://raw.githubusercontent.com/Telecominfraproject/wlan-ucentral-schema/main/ucentral.schema.json"};
 | 
				
			||||||
	"ucentral.schema.json"};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static std::string DefaultUCentralSchema = R"foo(
 | 
					static std::string DefaultUCentralSchema = R"foo(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -37,10 +36,6 @@ static std::string DefaultUCentralSchema = R"foo(
 | 
				
			|||||||
        "uuid": {
 | 
					        "uuid": {
 | 
				
			||||||
            "type": "integer"
 | 
					            "type": "integer"
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        "public_ip_lookup": {
 | 
					 | 
				
			||||||
            "type": "string",
 | 
					 | 
				
			||||||
            "format": "uc-fqdn"
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        "unit": {
 | 
					        "unit": {
 | 
				
			||||||
            "$ref": "#/$defs/unit"
 | 
					            "$ref": "#/$defs/unit"
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
@@ -638,6 +633,26 @@ static std::string DefaultUCentralSchema = R"foo(
 | 
				
			|||||||
                    "type": "string",
 | 
					                    "type": "string",
 | 
				
			||||||
                    "format": "uc-timeout",
 | 
					                    "format": "uc-timeout",
 | 
				
			||||||
                    "default": "6h"
 | 
					                    "default": "6h"
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                "relay-server": {
 | 
				
			||||||
 | 
					                    "type": "string",
 | 
				
			||||||
 | 
					                    "format": "ipv4",
 | 
				
			||||||
 | 
					                    "example": "192.168.2.1"
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                "circuit-id-format": {
 | 
				
			||||||
 | 
					                    "type": "string",
 | 
				
			||||||
 | 
					                    "example": [
 | 
				
			||||||
 | 
					                        "\\{Interface\\}:\\{VLAN-Id\\}:\\{SSID\\}:\\{Model\\}:\\{Name\\}:\\{AP-MAC\\}:\\{Location\\}",
 | 
				
			||||||
 | 
					                        "\\{AP-MAC\\};\\{SSID\\};\\{Crypto\\}",
 | 
				
			||||||
 | 
					                        "\\{Name\\} \\{ESSID\\}"
 | 
				
			||||||
 | 
					                    ]
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                "remote-id-format": {
 | 
				
			||||||
 | 
					                    "type": "string",
 | 
				
			||||||
 | 
					                    "example": [
 | 
				
			||||||
 | 
					                        "\\{Client-MAC-hex\\} \\{SSID\\}",
 | 
				
			||||||
 | 
					                        "\\{AP-MAC-hex\\} \\{SSID\\}"
 | 
				
			||||||
 | 
					                    ]
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
@@ -1216,32 +1231,6 @@ static std::string DefaultUCentralSchema = R"foo(
 | 
				
			|||||||
                        "secret"
 | 
					                        "secret"
 | 
				
			||||||
                    ]
 | 
					                    ]
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
                "secondary": {
 | 
					 | 
				
			||||||
                    "type": "object",
 | 
					 | 
				
			||||||
                    "properties": {
 | 
					 | 
				
			||||||
                        "host": {
 | 
					 | 
				
			||||||
                            "type": "string",
 | 
					 | 
				
			||||||
                            "format": "uc-host",
 | 
					 | 
				
			||||||
                            "examples": [
 | 
					 | 
				
			||||||
                                "192.168.1.10"
 | 
					 | 
				
			||||||
                            ]
 | 
					 | 
				
			||||||
                        },
 | 
					 | 
				
			||||||
                        "port": {
 | 
					 | 
				
			||||||
                            "type": "integer",
 | 
					 | 
				
			||||||
                            "maximum": 65535,
 | 
					 | 
				
			||||||
                            "minimum": 1024,
 | 
					 | 
				
			||||||
                            "examples": [
 | 
					 | 
				
			||||||
                                1812
 | 
					 | 
				
			||||||
                            ]
 | 
					 | 
				
			||||||
                        },
 | 
					 | 
				
			||||||
                        "secret": {
 | 
					 | 
				
			||||||
                            "type": "string",
 | 
					 | 
				
			||||||
                            "examples": [
 | 
					 | 
				
			||||||
                                "secret"
 | 
					 | 
				
			||||||
                            ]
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                "request-attribute": {
 | 
					                "request-attribute": {
 | 
				
			||||||
                    "type": "array",
 | 
					                    "type": "array",
 | 
				
			||||||
                    "items": {
 | 
					                    "items": {
 | 
				
			||||||
@@ -1319,25 +1308,6 @@ static std::string DefaultUCentralSchema = R"foo(
 | 
				
			|||||||
                                        "value": "Example Operator"
 | 
					                                        "value": "Example Operator"
 | 
				
			||||||
                                    }
 | 
					                                    }
 | 
				
			||||||
                                ]
 | 
					                                ]
 | 
				
			||||||
                            },
 | 
					 | 
				
			||||||
                            {
 | 
					 | 
				
			||||||
                                "type": "object",
 | 
					 | 
				
			||||||
                                "properties": {
 | 
					 | 
				
			||||||
                                    "id": {
 | 
					 | 
				
			||||||
                                        "type": "integer",
 | 
					 | 
				
			||||||
                                        "maximum": 255,
 | 
					 | 
				
			||||||
                                        "minimum": 1
 | 
					 | 
				
			||||||
                                    },
 | 
					 | 
				
			||||||
                                    "hex-value": {
 | 
					 | 
				
			||||||
                                        "type": "string"
 | 
					 | 
				
			||||||
                                    }
 | 
					 | 
				
			||||||
                                },
 | 
					 | 
				
			||||||
                                "examples": [
 | 
					 | 
				
			||||||
                                    {
 | 
					 | 
				
			||||||
                                        "id": 32,
 | 
					 | 
				
			||||||
                                        "value": "0a0b0c0d"
 | 
					 | 
				
			||||||
                                    }
 | 
					 | 
				
			||||||
                                ]
 | 
					 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                        ]
 | 
					                        ]
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
@@ -1687,236 +1657,6 @@ static std::string DefaultUCentralSchema = R"foo(
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        "service.captive.click": {
 | 
					 | 
				
			||||||
            "type": "object",
 | 
					 | 
				
			||||||
            "properties": {
 | 
					 | 
				
			||||||
                "auth-mode": {
 | 
					 | 
				
			||||||
                    "type": "string",
 | 
					 | 
				
			||||||
                    "const": "click-to-continue"
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        "service.captive.radius": {
 | 
					 | 
				
			||||||
            "type": "object",
 | 
					 | 
				
			||||||
            "properties": {
 | 
					 | 
				
			||||||
                "auth-mode": {
 | 
					 | 
				
			||||||
                    "type": "string",
 | 
					 | 
				
			||||||
                    "const": "radius"
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                "auth-server": {
 | 
					 | 
				
			||||||
                    "type": "string",
 | 
					 | 
				
			||||||
                    "format": "uc-host",
 | 
					 | 
				
			||||||
                    "examples": [
 | 
					 | 
				
			||||||
                        "192.168.1.10"
 | 
					 | 
				
			||||||
                    ]
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                "auth-port": {
 | 
					 | 
				
			||||||
                    "type": "integer",
 | 
					 | 
				
			||||||
                    "maximum": 65535,
 | 
					 | 
				
			||||||
                    "minimum": 1024,
 | 
					 | 
				
			||||||
                    "default": 1812
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                "auth-secret": {
 | 
					 | 
				
			||||||
                    "type": "string",
 | 
					 | 
				
			||||||
                    "examples": [
 | 
					 | 
				
			||||||
                        "secret"
 | 
					 | 
				
			||||||
                    ]
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                "acct-server": {
 | 
					 | 
				
			||||||
                    "type": "string",
 | 
					 | 
				
			||||||
                    "format": "uc-host",
 | 
					 | 
				
			||||||
                    "examples": [
 | 
					 | 
				
			||||||
                        "192.168.1.10"
 | 
					 | 
				
			||||||
                    ]
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                "acct-port": {
 | 
					 | 
				
			||||||
                    "type": "integer",
 | 
					 | 
				
			||||||
                    "maximum": 65535,
 | 
					 | 
				
			||||||
                    "minimum": 1024,
 | 
					 | 
				
			||||||
                    "default": 1812
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                "acct-secret": {
 | 
					 | 
				
			||||||
                    "type": "string",
 | 
					 | 
				
			||||||
                    "examples": [
 | 
					 | 
				
			||||||
                        "secret"
 | 
					 | 
				
			||||||
                    ]
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                "acct-interval": {
 | 
					 | 
				
			||||||
                    "type": "integer",
 | 
					 | 
				
			||||||
                    "default": 600
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        "service.captive.credentials": {
 | 
					 | 
				
			||||||
            "type": "object",
 | 
					 | 
				
			||||||
            "properties": {
 | 
					 | 
				
			||||||
                "auth-mode": {
 | 
					 | 
				
			||||||
                    "type": "string",
 | 
					 | 
				
			||||||
                    "const": "credentials"
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                "credentials": {
 | 
					 | 
				
			||||||
                    "type": "array",
 | 
					 | 
				
			||||||
                    "items": {
 | 
					 | 
				
			||||||
                        "type": "object",
 | 
					 | 
				
			||||||
                        "properties": {
 | 
					 | 
				
			||||||
                            "username": {
 | 
					 | 
				
			||||||
                                "type": "string"
 | 
					 | 
				
			||||||
                            },
 | 
					 | 
				
			||||||
                            "password": {
 | 
					 | 
				
			||||||
                                "type": "string"
 | 
					 | 
				
			||||||
                            }
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        "service.captive.uam": {
 | 
					 | 
				
			||||||
            "type": "object",
 | 
					 | 
				
			||||||
            "properties": {
 | 
					 | 
				
			||||||
                "auth-mode": {
 | 
					 | 
				
			||||||
                    "type": "string",
 | 
					 | 
				
			||||||
                    "const": "uam"
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                "uam-port": {
 | 
					 | 
				
			||||||
                    "type": "integer",
 | 
					 | 
				
			||||||
                    "maximum": 65535,
 | 
					 | 
				
			||||||
                    "minimum": 1024,
 | 
					 | 
				
			||||||
                    "default": 3990
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                "uam-secret": {
 | 
					 | 
				
			||||||
                    "type": "string"
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                "uam-server": {
 | 
					 | 
				
			||||||
                    "type": "string"
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                "nasid": {
 | 
					 | 
				
			||||||
                    "type": "string"
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                "nasmac": {
 | 
					 | 
				
			||||||
                    "type": "string"
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                "auth-server": {
 | 
					 | 
				
			||||||
                    "type": "string",
 | 
					 | 
				
			||||||
                    "format": "uc-host",
 | 
					 | 
				
			||||||
                    "examples": [
 | 
					 | 
				
			||||||
                        "192.168.1.10"
 | 
					 | 
				
			||||||
                    ]
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                "auth-port": {
 | 
					 | 
				
			||||||
                    "type": "integer",
 | 
					 | 
				
			||||||
                    "maximum": 65535,
 | 
					 | 
				
			||||||
                    "minimum": 1024,
 | 
					 | 
				
			||||||
                    "default": 1812
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                "auth-secret": {
 | 
					 | 
				
			||||||
                    "type": "string",
 | 
					 | 
				
			||||||
                    "examples": [
 | 
					 | 
				
			||||||
                        "secret"
 | 
					 | 
				
			||||||
                    ]
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                "acct-server": {
 | 
					 | 
				
			||||||
                    "type": "string",
 | 
					 | 
				
			||||||
                    "format": "uc-host",
 | 
					 | 
				
			||||||
                    "examples": [
 | 
					 | 
				
			||||||
                        "192.168.1.10"
 | 
					 | 
				
			||||||
                    ]
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                "acct-port": {
 | 
					 | 
				
			||||||
                    "type": "integer",
 | 
					 | 
				
			||||||
                    "maximum": 65535,
 | 
					 | 
				
			||||||
                    "minimum": 1024,
 | 
					 | 
				
			||||||
                    "default": 1812
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                "acct-secret": {
 | 
					 | 
				
			||||||
                    "type": "string",
 | 
					 | 
				
			||||||
                    "examples": [
 | 
					 | 
				
			||||||
                        "secret"
 | 
					 | 
				
			||||||
                    ]
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                "acct-interval": {
 | 
					 | 
				
			||||||
                    "type": "integer",
 | 
					 | 
				
			||||||
                    "default": 600
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                "ssid": {
 | 
					 | 
				
			||||||
                    "type": "string"
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                "mac-format": {
 | 
					 | 
				
			||||||
                    "type": "string",
 | 
					 | 
				
			||||||
                    "enum": [
 | 
					 | 
				
			||||||
                        "aabbccddeeff",
 | 
					 | 
				
			||||||
                        "aa-bb-cc-dd-ee-ff",
 | 
					 | 
				
			||||||
                        "aa:bb:cc:dd:ee:ff",
 | 
					 | 
				
			||||||
                        "AABBCCDDEEFF",
 | 
					 | 
				
			||||||
                        "AA:BB:CC:DD:EE:FF",
 | 
					 | 
				
			||||||
                        "AA-BB-CC-DD-EE-FF"
 | 
					 | 
				
			||||||
                    ]
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                "final-redirect-url": {
 | 
					 | 
				
			||||||
                    "type": "string",
 | 
					 | 
				
			||||||
                    "enum": [
 | 
					 | 
				
			||||||
                        "default",
 | 
					 | 
				
			||||||
                        "uam"
 | 
					 | 
				
			||||||
                    ]
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                "mac-auth": {
 | 
					 | 
				
			||||||
                    "type": "boolean",
 | 
					 | 
				
			||||||
                    "default": "default"
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                "radius-gw-proxy": {
 | 
					 | 
				
			||||||
                    "type": "boolean",
 | 
					 | 
				
			||||||
                    "default": false
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        "service.captive": {
 | 
					 | 
				
			||||||
            "allOf": [
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    "oneOf": [
 | 
					 | 
				
			||||||
                        {
 | 
					 | 
				
			||||||
                            "$ref": "#/$defs/service.captive.click"
 | 
					 | 
				
			||||||
                        },
 | 
					 | 
				
			||||||
                        {
 | 
					 | 
				
			||||||
                            "$ref": "#/$defs/service.captive.radius"
 | 
					 | 
				
			||||||
                        },
 | 
					 | 
				
			||||||
                        {
 | 
					 | 
				
			||||||
                            "$ref": "#/$defs/service.captive.credentials"
 | 
					 | 
				
			||||||
                        },
 | 
					 | 
				
			||||||
                        {
 | 
					 | 
				
			||||||
                            "$ref": "#/$defs/service.captive.uam"
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    ]
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    "type": "object",
 | 
					 | 
				
			||||||
                    "properties": {
 | 
					 | 
				
			||||||
                        "walled-garden-fqdn": {
 | 
					 | 
				
			||||||
                            "type": "array",
 | 
					 | 
				
			||||||
                            "items": {
 | 
					 | 
				
			||||||
                                "type": "string"
 | 
					 | 
				
			||||||
                            }
 | 
					 | 
				
			||||||
                        },
 | 
					 | 
				
			||||||
                        "walled-garden-ipaddr": {
 | 
					 | 
				
			||||||
                            "type": "array",
 | 
					 | 
				
			||||||
                            "items": {
 | 
					 | 
				
			||||||
                                "type": "string",
 | 
					 | 
				
			||||||
                                "format": "uc-ip"
 | 
					 | 
				
			||||||
                            }
 | 
					 | 
				
			||||||
                        },
 | 
					 | 
				
			||||||
                        "web-root": {
 | 
					 | 
				
			||||||
                            "type": "string",
 | 
					 | 
				
			||||||
                            "format": "uc-base64"
 | 
					 | 
				
			||||||
                        },
 | 
					 | 
				
			||||||
                        "idle-timeout": {
 | 
					 | 
				
			||||||
                            "type": "integer",
 | 
					 | 
				
			||||||
                            "default": 600
 | 
					 | 
				
			||||||
                        },
 | 
					 | 
				
			||||||
                        "session-timeout": {
 | 
					 | 
				
			||||||
                            "type": "integer"
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            ]
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        "interface.ssid": {
 | 
					        "interface.ssid": {
 | 
				
			||||||
            "type": "object",
 | 
					            "type": "object",
 | 
				
			||||||
            "properties": {
 | 
					            "properties": {
 | 
				
			||||||
@@ -1969,10 +1709,6 @@ static std::string DefaultUCentralSchema = R"foo(
 | 
				
			|||||||
                "isolate-clients": {
 | 
					                "isolate-clients": {
 | 
				
			||||||
                    "type": "boolean"
 | 
					                    "type": "boolean"
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
                "strict-forwarding": {
 | 
					 | 
				
			||||||
                    "type": "boolean",
 | 
					 | 
				
			||||||
                    "default": false
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                "power-save": {
 | 
					                "power-save": {
 | 
				
			||||||
                    "type": "boolean"
 | 
					                    "type": "boolean"
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
@@ -2041,15 +1777,8 @@ static std::string DefaultUCentralSchema = R"foo(
 | 
				
			|||||||
                    "$ref": "#/$defs/interface.ssid.rate-limit"
 | 
					                    "$ref": "#/$defs/interface.ssid.rate-limit"
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
                "roaming": {
 | 
					                "roaming": {
 | 
				
			||||||
                    "anyOf": [
 | 
					 | 
				
			||||||
                        {
 | 
					 | 
				
			||||||
                    "$ref": "#/$defs/interface.ssid.roaming"
 | 
					                    "$ref": "#/$defs/interface.ssid.roaming"
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
                        {
 | 
					 | 
				
			||||||
                            "type": "boolean"
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    ]
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                "radius": {
 | 
					                "radius": {
 | 
				
			||||||
                    "$ref": "#/$defs/interface.ssid.radius"
 | 
					                    "$ref": "#/$defs/interface.ssid.radius"
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
@@ -2065,9 +1794,6 @@ static std::string DefaultUCentralSchema = R"foo(
 | 
				
			|||||||
                "access-control-list": {
 | 
					                "access-control-list": {
 | 
				
			||||||
                    "$ref": "#/$defs/interface.ssid.acl"
 | 
					                    "$ref": "#/$defs/interface.ssid.acl"
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
                "captive": {
 | 
					 | 
				
			||||||
                    "$ref": "#/$defs/service.captive"
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                "hostapd-bss-raw": {
 | 
					                "hostapd-bss-raw": {
 | 
				
			||||||
                    "type": "array",
 | 
					                    "type": "array",
 | 
				
			||||||
                    "items": {
 | 
					                    "items": {
 | 
				
			||||||
@@ -2357,10 +2083,6 @@ static std::string DefaultUCentralSchema = R"foo(
 | 
				
			|||||||
                    "examples": [
 | 
					                    "examples": [
 | 
				
			||||||
                        "01234567890123456789012345678901"
 | 
					                        "01234567890123456789012345678901"
 | 
				
			||||||
                    ]
 | 
					                    ]
 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                "mutual-tls": {
 | 
					 | 
				
			||||||
                    "type": "boolean",
 | 
					 | 
				
			||||||
                    "default": true
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
@@ -2970,6 +2692,236 @@ static std::string DefaultUCentralSchema = R"foo(
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
 | 
					        "service.captive.click": {
 | 
				
			||||||
 | 
					            "type": "object",
 | 
				
			||||||
 | 
					            "properties": {
 | 
				
			||||||
 | 
					                "auth-mode": {
 | 
				
			||||||
 | 
					                    "type": "string",
 | 
				
			||||||
 | 
					                    "const": "click-to-continue"
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "service.captive.radius": {
 | 
				
			||||||
 | 
					            "type": "object",
 | 
				
			||||||
 | 
					            "properties": {
 | 
				
			||||||
 | 
					                "auth-mode": {
 | 
				
			||||||
 | 
					                    "type": "string",
 | 
				
			||||||
 | 
					                    "const": "radius"
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                "auth-server": {
 | 
				
			||||||
 | 
					                    "type": "string",
 | 
				
			||||||
 | 
					                    "format": "uc-host",
 | 
				
			||||||
 | 
					                    "examples": [
 | 
				
			||||||
 | 
					                        "192.168.1.10"
 | 
				
			||||||
 | 
					                    ]
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                "auth-port": {
 | 
				
			||||||
 | 
					                    "type": "integer",
 | 
				
			||||||
 | 
					                    "maximum": 65535,
 | 
				
			||||||
 | 
					                    "minimum": 1024,
 | 
				
			||||||
 | 
					                    "default": 1812
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                "auth-secret": {
 | 
				
			||||||
 | 
					                    "type": "string",
 | 
				
			||||||
 | 
					                    "examples": [
 | 
				
			||||||
 | 
					                        "secret"
 | 
				
			||||||
 | 
					                    ]
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                "acct-server": {
 | 
				
			||||||
 | 
					                    "type": "string",
 | 
				
			||||||
 | 
					                    "format": "uc-host",
 | 
				
			||||||
 | 
					                    "examples": [
 | 
				
			||||||
 | 
					                        "192.168.1.10"
 | 
				
			||||||
 | 
					                    ]
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                "acct-port": {
 | 
				
			||||||
 | 
					                    "type": "integer",
 | 
				
			||||||
 | 
					                    "maximum": 65535,
 | 
				
			||||||
 | 
					                    "minimum": 1024,
 | 
				
			||||||
 | 
					                    "default": 1812
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                "acct-secret": {
 | 
				
			||||||
 | 
					                    "type": "string",
 | 
				
			||||||
 | 
					                    "examples": [
 | 
				
			||||||
 | 
					                        "secret"
 | 
				
			||||||
 | 
					                    ]
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                "acct-interval": {
 | 
				
			||||||
 | 
					                    "type": "integer",
 | 
				
			||||||
 | 
					                    "default": 600
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "service.captive.credentials": {
 | 
				
			||||||
 | 
					            "type": "object",
 | 
				
			||||||
 | 
					            "properties": {
 | 
				
			||||||
 | 
					                "auth-mode": {
 | 
				
			||||||
 | 
					                    "type": "string",
 | 
				
			||||||
 | 
					                    "const": "credentials"
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                "credentials": {
 | 
				
			||||||
 | 
					                    "type": "array",
 | 
				
			||||||
 | 
					                    "items": {
 | 
				
			||||||
 | 
					                        "type": "object",
 | 
				
			||||||
 | 
					                        "properties": {
 | 
				
			||||||
 | 
					                            "username": {
 | 
				
			||||||
 | 
					                                "type": "string"
 | 
				
			||||||
 | 
					                            },
 | 
				
			||||||
 | 
					                            "password": {
 | 
				
			||||||
 | 
					                                "type": "string"
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "service.captive.uam": {
 | 
				
			||||||
 | 
					            "type": "object",
 | 
				
			||||||
 | 
					            "properties": {
 | 
				
			||||||
 | 
					                "auth-mode": {
 | 
				
			||||||
 | 
					                    "type": "string",
 | 
				
			||||||
 | 
					                    "const": "uam"
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                "uam-port": {
 | 
				
			||||||
 | 
					                    "type": "integer",
 | 
				
			||||||
 | 
					                    "maximum": 65535,
 | 
				
			||||||
 | 
					                    "minimum": 1024,
 | 
				
			||||||
 | 
					                    "default": 3990
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                "uam-secret": {
 | 
				
			||||||
 | 
					                    "type": "string"
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                "uam-server": {
 | 
				
			||||||
 | 
					                    "type": "string"
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                "nasid": {
 | 
				
			||||||
 | 
					                    "type": "string"
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                "nasmac": {
 | 
				
			||||||
 | 
					                    "type": "string"
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                "auth-server": {
 | 
				
			||||||
 | 
					                    "type": "string",
 | 
				
			||||||
 | 
					                    "format": "uc-host",
 | 
				
			||||||
 | 
					                    "examples": [
 | 
				
			||||||
 | 
					                        "192.168.1.10"
 | 
				
			||||||
 | 
					                    ]
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                "auth-port": {
 | 
				
			||||||
 | 
					                    "type": "integer",
 | 
				
			||||||
 | 
					                    "maximum": 65535,
 | 
				
			||||||
 | 
					                    "minimum": 1024,
 | 
				
			||||||
 | 
					                    "default": 1812
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                "auth-secret": {
 | 
				
			||||||
 | 
					                    "type": "string",
 | 
				
			||||||
 | 
					                    "examples": [
 | 
				
			||||||
 | 
					                        "secret"
 | 
				
			||||||
 | 
					                    ]
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                "acct-server": {
 | 
				
			||||||
 | 
					                    "type": "string",
 | 
				
			||||||
 | 
					                    "format": "uc-host",
 | 
				
			||||||
 | 
					                    "examples": [
 | 
				
			||||||
 | 
					                        "192.168.1.10"
 | 
				
			||||||
 | 
					                    ]
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                "acct-port": {
 | 
				
			||||||
 | 
					                    "type": "integer",
 | 
				
			||||||
 | 
					                    "maximum": 65535,
 | 
				
			||||||
 | 
					                    "minimum": 1024,
 | 
				
			||||||
 | 
					                    "default": 1812
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                "acct-secret": {
 | 
				
			||||||
 | 
					                    "type": "string",
 | 
				
			||||||
 | 
					                    "examples": [
 | 
				
			||||||
 | 
					                        "secret"
 | 
				
			||||||
 | 
					                    ]
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                "acct-interval": {
 | 
				
			||||||
 | 
					                    "type": "integer",
 | 
				
			||||||
 | 
					                    "default": 600
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                "ssid": {
 | 
				
			||||||
 | 
					                    "type": "string"
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                "mac-format": {
 | 
				
			||||||
 | 
					                    "type": "string",
 | 
				
			||||||
 | 
					                    "enum": [
 | 
				
			||||||
 | 
					                        "aabbccddeeff",
 | 
				
			||||||
 | 
					                        "aa-bb-cc-dd-ee-ff",
 | 
				
			||||||
 | 
					                        "aa:bb:cc:dd:ee:ff",
 | 
				
			||||||
 | 
					                        "AABBCCDDEEFF",
 | 
				
			||||||
 | 
					                        "AA:BB:CC:DD:EE:FF",
 | 
				
			||||||
 | 
					                        "AA-BB-CC-DD-EE-FF"
 | 
				
			||||||
 | 
					                    ]
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                "final-redirect-url": {
 | 
				
			||||||
 | 
					                    "type": "string",
 | 
				
			||||||
 | 
					                    "enum": [
 | 
				
			||||||
 | 
					                        "default",
 | 
				
			||||||
 | 
					                        "uam"
 | 
				
			||||||
 | 
					                    ]
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                "mac-auth": {
 | 
				
			||||||
 | 
					                    "type": "boolean",
 | 
				
			||||||
 | 
					                    "default": "default"
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                "radius-gw-proxy": {
 | 
				
			||||||
 | 
					                    "type": "boolean",
 | 
				
			||||||
 | 
					                    "default": false
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        "service.captive": {
 | 
				
			||||||
 | 
					            "allOf": [
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    "oneOf": [
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            "$ref": "#/$defs/service.captive.click"
 | 
				
			||||||
 | 
					                        },
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            "$ref": "#/$defs/service.captive.radius"
 | 
				
			||||||
 | 
					                        },
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            "$ref": "#/$defs/service.captive.credentials"
 | 
				
			||||||
 | 
					                        },
 | 
				
			||||||
 | 
					                        {
 | 
				
			||||||
 | 
					                            "$ref": "#/$defs/service.captive.uam"
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    ]
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    "type": "object",
 | 
				
			||||||
 | 
					                    "properties": {
 | 
				
			||||||
 | 
					                        "walled-garden-fqdn": {
 | 
				
			||||||
 | 
					                            "type": "array",
 | 
				
			||||||
 | 
					                            "items": {
 | 
				
			||||||
 | 
					                                "type": "string"
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        },
 | 
				
			||||||
 | 
					                        "walled-garden-ipaddr": {
 | 
				
			||||||
 | 
					                            "type": "array",
 | 
				
			||||||
 | 
					                            "items": {
 | 
				
			||||||
 | 
					                                "type": "string",
 | 
				
			||||||
 | 
					                                "format": "uc-ip"
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        },
 | 
				
			||||||
 | 
					                        "web-root": {
 | 
				
			||||||
 | 
					                            "type": "string",
 | 
				
			||||||
 | 
					                            "format": "uc-base64"
 | 
				
			||||||
 | 
					                        },
 | 
				
			||||||
 | 
					                        "idle-timeout": {
 | 
				
			||||||
 | 
					                            "type": "integer",
 | 
				
			||||||
 | 
					                            "default": 600
 | 
				
			||||||
 | 
					                        },
 | 
				
			||||||
 | 
					                        "session-timeout": {
 | 
				
			||||||
 | 
					                            "type": "integer"
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            ]
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
        "service.gps": {
 | 
					        "service.gps": {
 | 
				
			||||||
            "type": "object",
 | 
					            "type": "object",
 | 
				
			||||||
            "properties": {
 | 
					            "properties": {
 | 
				
			||||||
@@ -2988,32 +2940,6 @@ static std::string DefaultUCentralSchema = R"foo(
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        "service.dhcp-relay": {
 | 
					 | 
				
			||||||
            "type": "object",
 | 
					 | 
				
			||||||
            "properties": {
 | 
					 | 
				
			||||||
                "select-ports": {
 | 
					 | 
				
			||||||
                    "type": "array",
 | 
					 | 
				
			||||||
                    "items": {
 | 
					 | 
				
			||||||
                        "type": "string"
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                "vlans": {
 | 
					 | 
				
			||||||
                    "type": "array",
 | 
					 | 
				
			||||||
                    "items": {
 | 
					 | 
				
			||||||
                        "type": "object",
 | 
					 | 
				
			||||||
                        "properties": {
 | 
					 | 
				
			||||||
                            "vlan": {
 | 
					 | 
				
			||||||
                                "type": "number"
 | 
					 | 
				
			||||||
                            },
 | 
					 | 
				
			||||||
                            "relay-server": {
 | 
					 | 
				
			||||||
                                "type": "string",
 | 
					 | 
				
			||||||
                                "format": "uc-ip"
 | 
					 | 
				
			||||||
                            }
 | 
					 | 
				
			||||||
                        }
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        "service": {
 | 
					        "service": {
 | 
				
			||||||
            "type": "object",
 | 
					            "type": "object",
 | 
				
			||||||
            "properties": {
 | 
					            "properties": {
 | 
				
			||||||
@@ -3073,9 +2999,6 @@ static std::string DefaultUCentralSchema = R"foo(
 | 
				
			|||||||
                },
 | 
					                },
 | 
				
			||||||
                "gps": {
 | 
					                "gps": {
 | 
				
			||||||
                    "$ref": "#/$defs/service.gps"
 | 
					                    "$ref": "#/$defs/service.gps"
 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                "dhcp-relay": {
 | 
					 | 
				
			||||||
                    "$ref": "#/$defs/service.dhcp-relay"
 | 
					 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
@@ -3168,20 +3091,6 @@ static std::string DefaultUCentralSchema = R"foo(
 | 
				
			|||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        "metrics.wifi-scan": {
 | 
					 | 
				
			||||||
            "type": "object",
 | 
					 | 
				
			||||||
            "properties": {
 | 
					 | 
				
			||||||
                "interval": {
 | 
					 | 
				
			||||||
                    "type": "integer"
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                "verbose": {
 | 
					 | 
				
			||||||
                    "type": "boolean"
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                "information-elements": {
 | 
					 | 
				
			||||||
                    "type": "boolean"
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        },
 | 
					 | 
				
			||||||
        "metrics.telemetry": {
 | 
					        "metrics.telemetry": {
 | 
				
			||||||
            "type": "object",
 | 
					            "type": "object",
 | 
				
			||||||
            "properties": {
 | 
					            "properties": {
 | 
				
			||||||
@@ -3191,27 +3100,7 @@ static std::string DefaultUCentralSchema = R"foo(
 | 
				
			|||||||
                "types": {
 | 
					                "types": {
 | 
				
			||||||
                    "type": "array",
 | 
					                    "type": "array",
 | 
				
			||||||
                    "items": {
 | 
					                    "items": {
 | 
				
			||||||
                        "type": "string",
 | 
					                        "type": "string"
 | 
				
			||||||
                        "enum": [
 | 
					 | 
				
			||||||
                            "ssh",
 | 
					 | 
				
			||||||
                            "health",
 | 
					 | 
				
			||||||
                            "health.dns",
 | 
					 | 
				
			||||||
                            "health.dhcp",
 | 
					 | 
				
			||||||
                            "health.radius",
 | 
					 | 
				
			||||||
                            "health.memory",
 | 
					 | 
				
			||||||
                            "client",
 | 
					 | 
				
			||||||
                            "client.join",
 | 
					 | 
				
			||||||
                            "client.leave",
 | 
					 | 
				
			||||||
                            "client.key-mismatch",
 | 
					 | 
				
			||||||
                            "wifi",
 | 
					 | 
				
			||||||
                            "wifi.start",
 | 
					 | 
				
			||||||
                            "wifi.stop",
 | 
					 | 
				
			||||||
                            "wired",
 | 
					 | 
				
			||||||
                            "wired.carrier-up",
 | 
					 | 
				
			||||||
                            "wired.carrier-down",
 | 
					 | 
				
			||||||
                            "unit",
 | 
					 | 
				
			||||||
                            "unit.boot-up"
 | 
					 | 
				
			||||||
                        ]
 | 
					 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -3222,27 +3111,7 @@ static std::string DefaultUCentralSchema = R"foo(
 | 
				
			|||||||
                "types": {
 | 
					                "types": {
 | 
				
			||||||
                    "type": "array",
 | 
					                    "type": "array",
 | 
				
			||||||
                    "items": {
 | 
					                    "items": {
 | 
				
			||||||
                        "type": "string",
 | 
					                        "type": "string"
 | 
				
			||||||
                        "enum": [
 | 
					 | 
				
			||||||
                            "ssh",
 | 
					 | 
				
			||||||
                            "health",
 | 
					 | 
				
			||||||
                            "health.dns",
 | 
					 | 
				
			||||||
                            "health.dhcp",
 | 
					 | 
				
			||||||
                            "health.radius",
 | 
					 | 
				
			||||||
                            "health.memory",
 | 
					 | 
				
			||||||
                            "client",
 | 
					 | 
				
			||||||
                            "client.join",
 | 
					 | 
				
			||||||
                            "client.leave",
 | 
					 | 
				
			||||||
                            "client.key-mismatch",
 | 
					 | 
				
			||||||
                            "wifi",
 | 
					 | 
				
			||||||
                            "wifi.start",
 | 
					 | 
				
			||||||
                            "wifi.stop",
 | 
					 | 
				
			||||||
                            "wired",
 | 
					 | 
				
			||||||
                            "wired.carrier-up",
 | 
					 | 
				
			||||||
                            "wired.carrier-down",
 | 
					 | 
				
			||||||
                            "unit",
 | 
					 | 
				
			||||||
                            "unit.boot-up"
 | 
					 | 
				
			||||||
                        ]
 | 
					 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -3262,9 +3131,6 @@ static std::string DefaultUCentralSchema = R"foo(
 | 
				
			|||||||
                "dhcp-snooping": {
 | 
					                "dhcp-snooping": {
 | 
				
			||||||
                    "$ref": "#/$defs/metrics.dhcp-snooping"
 | 
					                    "$ref": "#/$defs/metrics.dhcp-snooping"
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
                "wifi-scan": {
 | 
					 | 
				
			||||||
                    "$ref": "#/$defs/metrics.wifi-scan"
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                "telemetry": {
 | 
					                "telemetry": {
 | 
				
			||||||
                    "$ref": "#/$defs/metrics.telemetry"
 | 
					                    "$ref": "#/$defs/metrics.telemetry"
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
@@ -3318,6 +3184,7 @@ static std::string DefaultUCentralSchema = R"foo(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
)foo";
 | 
					)foo";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline bool IsIPv4(const std::string &value) {
 | 
					static inline bool IsIPv4(const std::string &value) {
 | 
				
			||||||
	Poco::Net::IPAddress A;
 | 
						Poco::Net::IPAddress A;
 | 
				
			||||||
	return ((Poco::Net::IPAddress::tryParse(value, A) && A.family() == Poco::Net::IPAddress::IPv4));
 | 
						return ((Poco::Net::IPAddress::tryParse(value, A) && A.family() == Poco::Net::IPAddress::IPv4));
 | 
				
			||||||
@@ -3375,68 +3242,57 @@ bool ExternalValijsonFormatChecker(const std::string &format, const std::string
 | 
				
			|||||||
	if (format == "uc-cidr4") {
 | 
						if (format == "uc-cidr4") {
 | 
				
			||||||
		if (IsCIDRv4(value))
 | 
							if (IsCIDRv4(value))
 | 
				
			||||||
			return true;
 | 
								return true;
 | 
				
			||||||
		if (results)
 | 
							if(results) results->pushError(context,fmt::format("{} is not a valid CIDR IPv4 block",value));
 | 
				
			||||||
			results->pushError(context, fmt::format("{} is not a valid CIDR IPv4 block", value));
 | 
					 | 
				
			||||||
	} else if (format == "uc-cidr6") {
 | 
						} else if (format == "uc-cidr6") {
 | 
				
			||||||
		if (IsCIDRv6(value))
 | 
							if (IsCIDRv6(value))
 | 
				
			||||||
			return true;
 | 
								return true;
 | 
				
			||||||
		if (results)
 | 
							if(results) results->pushError(context,fmt::format("{} is not a valid CIDR IPv6 block",value));
 | 
				
			||||||
			results->pushError(context, fmt::format("{} is not a valid CIDR IPv6 block", value));
 | 
					 | 
				
			||||||
	} else if (format == "uc-cidr") {
 | 
						} else if (format == "uc-cidr") {
 | 
				
			||||||
		if (IsCIDR(value))
 | 
							if (IsCIDR(value))
 | 
				
			||||||
			return true;
 | 
								return true;
 | 
				
			||||||
		if (results)
 | 
							if(results) results->pushError(context,fmt::format("{} is not a valid CIDR block",value));
 | 
				
			||||||
			results->pushError(context, fmt::format("{} is not a valid CIDR block", value));
 | 
					 | 
				
			||||||
	} else if (format == "uc-mac") {
 | 
						} else if (format == "uc-mac") {
 | 
				
			||||||
		if (std::regex_match(value, mac_regex))
 | 
							if (std::regex_match(value, mac_regex))
 | 
				
			||||||
			return true;
 | 
								return true;
 | 
				
			||||||
		if (results)
 | 
							if(results) results->pushError(context,fmt::format("{} is not a valid MAC address",value));
 | 
				
			||||||
			results->pushError(context, fmt::format("{} is not a valid MAC address", value));
 | 
					 | 
				
			||||||
	} else if (format == "uc-timeout") {
 | 
						} else if (format == "uc-timeout") {
 | 
				
			||||||
		if (std::regex_match(value, uc_timeout_regex))
 | 
							if (std::regex_match(value, uc_timeout_regex))
 | 
				
			||||||
			return true;
 | 
								return true;
 | 
				
			||||||
		if (results)
 | 
							if(results) results->pushError(context,fmt::format("{} is not a valid timeout value",value));
 | 
				
			||||||
			results->pushError(context, fmt::format("{} is not a valid timeout value", value));
 | 
					 | 
				
			||||||
	} else if (format == "uc-host") {
 | 
						} else if (format == "uc-host") {
 | 
				
			||||||
		if (IsIP(value))
 | 
							if (IsIP(value))
 | 
				
			||||||
			return true;
 | 
								return true;
 | 
				
			||||||
		if (std::regex_match(value, host_regex))
 | 
							if (std::regex_match(value, host_regex))
 | 
				
			||||||
			return true;
 | 
								return true;
 | 
				
			||||||
		if (results)
 | 
							if(results) results->pushError(context,fmt::format("{} is not a valid hostname",value));
 | 
				
			||||||
			results->pushError(context, fmt::format("{} is not a valid hostname", value));
 | 
					 | 
				
			||||||
	} else if (format == "fqdn" || format == "uc-fqdn") {
 | 
						} else if (format == "fqdn" || format == "uc-fqdn") {
 | 
				
			||||||
		if (std::regex_match(value, host_regex))
 | 
							if (std::regex_match(value, host_regex))
 | 
				
			||||||
			return true;
 | 
								return true;
 | 
				
			||||||
		if (results)
 | 
							if(results) results->pushError(context,fmt::format("{} is not a valid FQDN",value));
 | 
				
			||||||
			results->pushError(context, fmt::format("{} is not a valid FQDN", value));
 | 
					 | 
				
			||||||
	} else if (format == "uc-base64") {
 | 
						} else if (format == "uc-base64") {
 | 
				
			||||||
		std::string s{value};
 | 
							std::string s{value};
 | 
				
			||||||
		Poco::trimInPlace(s);
 | 
							Poco::trimInPlace(s);
 | 
				
			||||||
		if ((s.size() % 4 == 0) && std::regex_match(s, b64_regex))
 | 
							if ((s.size() % 4 == 0) && std::regex_match(s, b64_regex))
 | 
				
			||||||
			return true;
 | 
								return true;
 | 
				
			||||||
		if (results)
 | 
							if(results) results->pushError(context,fmt::format("{} is not a valid base 64 value",value));
 | 
				
			||||||
			results->pushError(context, fmt::format("{} is not a valid base 64 value", value));
 | 
					 | 
				
			||||||
	} else if (format == "uri") {
 | 
						} else if (format == "uri") {
 | 
				
			||||||
		try {
 | 
							try {
 | 
				
			||||||
			Poco::URI uri(value);
 | 
								Poco::URI uri(value);
 | 
				
			||||||
			return true;
 | 
								return true;
 | 
				
			||||||
		} catch (...) {
 | 
							} catch (...) {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (results)
 | 
							if(results) results->pushError(context,fmt::format("{} is not a valid URL",value));
 | 
				
			||||||
			results->pushError(context, fmt::format("{} is not a valid URL", value));
 | 
					 | 
				
			||||||
	} else if (format == "uc-portrange") {
 | 
						} else if (format == "uc-portrange") {
 | 
				
			||||||
		try {
 | 
							try {
 | 
				
			||||||
			if (IsPortRangeIsValid(value))
 | 
								if (IsPortRangeIsValid(value))
 | 
				
			||||||
				return true;
 | 
									return true;
 | 
				
			||||||
		} catch (...) {
 | 
							} catch (...) {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (results)
 | 
							if(results) results->pushError(context,fmt::format("{} is not a valid post range",value));
 | 
				
			||||||
			results->pushError(context, fmt::format("{} is not a valid post range", value));
 | 
					 | 
				
			||||||
	} else if (format == "ip") {
 | 
						} else if (format == "ip") {
 | 
				
			||||||
		if (IsIP(value))
 | 
							if (IsIP(value))
 | 
				
			||||||
			return true;
 | 
								return true;
 | 
				
			||||||
		if (results)
 | 
							if(results) results->pushError(context,fmt::format("{} is not a valid IP address",value));
 | 
				
			||||||
			results->pushError(context, fmt::format("{} is not a valid IP address", value));
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return true;
 | 
						return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -3448,7 +3304,9 @@ namespace OpenWifi {
 | 
				
			|||||||
		return 0;
 | 
							return 0;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void ConfigurationValidator::Stop() {}
 | 
						void ConfigurationValidator::Stop() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool ConfigurationValidator::SetSchema(const std::string &SchemaStr) {
 | 
						bool ConfigurationValidator::SetSchema(const std::string &SchemaStr) {
 | 
				
			||||||
		try {
 | 
							try {
 | 
				
			||||||
@@ -3492,22 +3350,21 @@ namespace OpenWifi {
 | 
				
			|||||||
					schema_file << input.rdbuf();
 | 
										schema_file << input.rdbuf();
 | 
				
			||||||
					input.close();
 | 
										input.close();
 | 
				
			||||||
					if(SetSchema(schema_file.str())) {
 | 
										if(SetSchema(schema_file.str())) {
 | 
				
			||||||
					poco_information(
 | 
											poco_information(Logger(),
 | 
				
			||||||
						Logger(), "Using uCentral data model validation schema from local file.");
 | 
															 "Using uCentral data model validation schema from local file.");
 | 
				
			||||||
						return;
 | 
											return;
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
		} catch (const Poco::Exception &E) {
 | 
							} catch (const Poco::Exception &E) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		} catch (...) {
 | 
							} catch (...) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		SetSchema(DefaultUCentralSchema);
 | 
							SetSchema(DefaultUCentralSchema);
 | 
				
			||||||
		poco_information(Logger(),
 | 
							poco_information(Logger(),"Using uCentral data model validation schema from built-in default.");
 | 
				
			||||||
						 "Using uCentral data model validation schema from built-in default.");
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool ConfigurationValidator::Validate(const std::string &C, std::vector<std::string> &Errors,
 | 
					    bool ConfigurationValidator::Validate(const std::string &C, std::vector<std::string> &Errors, bool Strict) {
 | 
				
			||||||
										  bool Strict) {
 | 
					 | 
				
			||||||
        if(Working_) {
 | 
					        if(Working_) {
 | 
				
			||||||
            try {
 | 
					            try {
 | 
				
			||||||
				Poco::JSON::Parser P;
 | 
									Poco::JSON::Parser P;
 | 
				
			||||||
@@ -3525,8 +3382,7 @@ namespace OpenWifi {
 | 
				
			|||||||
			} catch(const Poco::Exception &E) {
 | 
								} catch(const Poco::Exception &E) {
 | 
				
			||||||
				Logger().log(E);
 | 
									Logger().log(E);
 | 
				
			||||||
            } catch(const std::exception &E) {
 | 
					            } catch(const std::exception &E) {
 | 
				
			||||||
				Logger().warning(
 | 
									Logger().warning(fmt::format("Error wile validating a configuration (1): {}", E.what()));
 | 
				
			||||||
					fmt::format("Error wile validating a configuration (1): {}", E.what()));
 | 
					 | 
				
			||||||
            } catch(...) {
 | 
					            } catch(...) {
 | 
				
			||||||
				Logger().warning("Error wile validating a configuration (2)");
 | 
									Logger().warning("Error wile validating a configuration (2)");
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -3542,4 +3398,4 @@ namespace OpenWifi {
 | 
				
			|||||||
        Init();
 | 
					        Init();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace OpenWifi
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,16 +7,17 @@
 | 
				
			|||||||
#include "framework/SubSystemServer.h"
 | 
					#include "framework/SubSystemServer.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <valijson/adapters/poco_json_adapter.hpp>
 | 
					#include <valijson/adapters/poco_json_adapter.hpp>
 | 
				
			||||||
#include <valijson/constraints/constraint.hpp>
 | 
					#include <valijson/utils/poco_json_utils.hpp>
 | 
				
			||||||
#include <valijson/constraints/constraint_visitor.hpp>
 | 
					 | 
				
			||||||
#include <valijson/schema.hpp>
 | 
					#include <valijson/schema.hpp>
 | 
				
			||||||
#include <valijson/schema_parser.hpp>
 | 
					#include <valijson/schema_parser.hpp>
 | 
				
			||||||
#include <valijson/utils/poco_json_utils.hpp>
 | 
					 | 
				
			||||||
#include <valijson/validator.hpp>
 | 
					#include <valijson/validator.hpp>
 | 
				
			||||||
 | 
					#include <valijson/constraints/constraint.hpp>
 | 
				
			||||||
 | 
					#include <valijson/constraints/constraint_visitor.hpp>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
    class ConfigurationValidator : public  SubSystemServer {
 | 
					    class ConfigurationValidator : public  SubSystemServer {
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        static auto instance() {
 | 
					        static auto instance() {
 | 
				
			||||||
            static auto instance_ = new ConfigurationValidator;
 | 
					            static auto instance_ = new ConfigurationValidator;
 | 
				
			||||||
            return instance_;
 | 
					            return instance_;
 | 
				
			||||||
@@ -37,13 +38,12 @@ namespace OpenWifi {
 | 
				
			|||||||
		Poco::JSON::Object::Ptr 			SchemaDocPtr_;
 | 
							Poco::JSON::Object::Ptr 			SchemaDocPtr_;
 | 
				
			||||||
		bool 								SetSchema(const std::string &SchemaStr);
 | 
							bool 								SetSchema(const std::string &SchemaStr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ConfigurationValidator()
 | 
					        ConfigurationValidator():
 | 
				
			||||||
			: SubSystemServer("ConfigValidator", "CFG-VALIDATOR", "config.validator") {}
 | 
					            SubSystemServer("ConfigValidator", "CFG-VALIDATOR", "config.validator") {
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    inline auto ConfigurationValidator() { return ConfigurationValidator::instance(); }
 | 
					    inline auto ConfigurationValidator() { return ConfigurationValidator::instance(); }
 | 
				
			||||||
	inline bool ValidateUCentralConfiguration(const std::string &C, std::vector<std::string> &Error,
 | 
					    inline bool ValidateUCentralConfiguration(const std::string &C, std::vector<std::string> &Error, bool strict) { return ConfigurationValidator::instance()->Validate(C, Error, strict); }
 | 
				
			||||||
											  bool strict) {
 | 
					 | 
				
			||||||
		return ConfigurationValidator::instance()->Validate(C, Error, strict);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
} // namespace OpenWifi
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,9 +4,9 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <vector>
 | 
				
			||||||
#include <string>
 | 
					#include <string>
 | 
				
			||||||
#include <utility>
 | 
					#include <utility>
 | 
				
			||||||
#include <vector>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
@@ -264,6 +264,8 @@ namespace OpenWifi {
 | 
				
			|||||||
        { .code= "EH", .name= "Western Sahara" },
 | 
					        { .code= "EH", .name= "Western Sahara" },
 | 
				
			||||||
        { .code= "YE", .name= "Yemen" },
 | 
					        { .code= "YE", .name= "Yemen" },
 | 
				
			||||||
        { .code= "ZM", .name= "Zambia" },
 | 
					        { .code= "ZM", .name= "Zambia" },
 | 
				
			||||||
		{.code = "ZW", .name = "Zimbabwe"}};
 | 
					        { .code= "ZW", .name= "Zimbabwe" }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace OpenWifi
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,30 +4,29 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "framework/EventBusManager.h"
 | 
					#include "framework/EventBusManager.h"
 | 
				
			||||||
#include "framework/KafkaManager.h"
 | 
					#include "framework/KafkaManager.h"
 | 
				
			||||||
#include "framework/MicroServiceFuncs.h"
 | 
					 | 
				
			||||||
#include "framework/utils.h"
 | 
					#include "framework/utils.h"
 | 
				
			||||||
 | 
					#include "framework/MicroServiceFuncs.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	EventBusManager::EventBusManager(Poco::Logger &L) : Logger_(L) {}
 | 
						EventBusManager::EventBusManager(Poco::Logger &L) :
 | 
				
			||||||
 | 
							Logger_(L) {
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void EventBusManager::run() {
 | 
						void EventBusManager::run() {
 | 
				
			||||||
		Running_ = true;
 | 
							Running_ = true;
 | 
				
			||||||
		Utils::SetThreadName("fmwk:EventMgr");
 | 
							Utils::SetThreadName("fmwk:EventMgr");
 | 
				
			||||||
		auto Msg = std::make_shared<std::string>(MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_JOIN));
 | 
							auto Msg = MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_JOIN);
 | 
				
			||||||
		KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS, MicroServicePrivateEndPoint(), Msg,
 | 
							KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS,MicroServicePrivateEndPoint(),Msg, false);
 | 
				
			||||||
									false);
 | 
					 | 
				
			||||||
		while(Running_) {
 | 
							while(Running_) {
 | 
				
			||||||
			Poco::Thread::trySleep((unsigned long)MicroServiceDaemonBusTimer());
 | 
								Poco::Thread::trySleep((unsigned long)MicroServiceDaemonBusTimer());
 | 
				
			||||||
			if(!Running_)
 | 
								if(!Running_)
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
			Msg = std::make_shared<std::string>(MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE));
 | 
								Msg = MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE);
 | 
				
			||||||
			KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS, MicroServicePrivateEndPoint(),
 | 
								KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS,MicroServicePrivateEndPoint(),Msg, false);
 | 
				
			||||||
										Msg, false);
 | 
					 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		Msg = std::make_shared<std::string>(MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_LEAVE));
 | 
							Msg = MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_LEAVE);
 | 
				
			||||||
		KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS, MicroServicePrivateEndPoint(), Msg,
 | 
							KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS,MicroServicePrivateEndPoint(),Msg, false);
 | 
				
			||||||
									false);
 | 
					 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void EventBusManager::Start() {
 | 
						void EventBusManager::Start() {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,8 +4,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "Poco/Logger.h"
 | 
					 | 
				
			||||||
#include "Poco/Runnable.h"
 | 
					#include "Poco/Runnable.h"
 | 
				
			||||||
 | 
					#include "Poco/Logger.h"
 | 
				
			||||||
#include "Poco/Thread.h"
 | 
					#include "Poco/Thread.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
@@ -25,3 +25,4 @@ namespace OpenWifi {
 | 
				
			|||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace OpenWifi
 | 
					} // namespace OpenWifi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,54 +4,50 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "KafkaManager.h"
 | 
					#include "KafkaManager.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "fmt/format.h"
 | 
					 | 
				
			||||||
#include "framework/MicroServiceFuncs.h"
 | 
					#include "framework/MicroServiceFuncs.h"
 | 
				
			||||||
 | 
					#include "fmt/format.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void KafkaLoggerFun([[maybe_unused]] cppkafka::KafkaHandleBase &handle, int level,
 | 
						void KafkaLoggerFun([[maybe_unused]] cppkafka::KafkaHandleBase & handle, int level, const std::string & facility, const std::string &message) {
 | 
				
			||||||
						const std::string &facility, const std::string &message) {
 | 
					 | 
				
			||||||
		switch ((cppkafka::LogLevel) level) {
 | 
							switch ((cppkafka::LogLevel) level) {
 | 
				
			||||||
		case cppkafka::LogLevel::LogNotice: {
 | 
							case cppkafka::LogLevel::LogNotice: {
 | 
				
			||||||
			poco_notice(KafkaManager()->Logger(),
 | 
								poco_notice(KafkaManager()->Logger(),fmt::format("kafka-log: facility: {} message: {}",facility, message));
 | 
				
			||||||
						fmt::format("kafka-log: facility: {} message: {}", facility, message));
 | 
							}
 | 
				
			||||||
		} break;
 | 
							break;
 | 
				
			||||||
		case cppkafka::LogLevel::LogDebug: {
 | 
							case cppkafka::LogLevel::LogDebug: {
 | 
				
			||||||
			poco_debug(KafkaManager()->Logger(),
 | 
								poco_debug(KafkaManager()->Logger(),fmt::format("kafka-log: facility: {} message: {}",facility, message));
 | 
				
			||||||
					   fmt::format("kafka-log: facility: {} message: {}", facility, message));
 | 
							}
 | 
				
			||||||
		} break;
 | 
							break;
 | 
				
			||||||
		case cppkafka::LogLevel::LogInfo: {
 | 
							case cppkafka::LogLevel::LogInfo: {
 | 
				
			||||||
			poco_information(KafkaManager()->Logger(),
 | 
								poco_information(KafkaManager()->Logger(),fmt::format("kafka-log: facility: {} message: {}",facility, message));
 | 
				
			||||||
							 fmt::format("kafka-log: facility: {} message: {}", facility, message));
 | 
							}
 | 
				
			||||||
		} break;
 | 
							break;
 | 
				
			||||||
		case cppkafka::LogLevel::LogWarning: {
 | 
							case cppkafka::LogLevel::LogWarning: {
 | 
				
			||||||
			poco_warning(KafkaManager()->Logger(),
 | 
								poco_warning(KafkaManager()->Logger(), fmt::format("kafka-log: facility: {} message: {}",facility, message));
 | 
				
			||||||
						 fmt::format("kafka-log: facility: {} message: {}", facility, message));
 | 
							}
 | 
				
			||||||
		} break;
 | 
							break;
 | 
				
			||||||
		case cppkafka::LogLevel::LogAlert:
 | 
							case cppkafka::LogLevel::LogAlert:
 | 
				
			||||||
		case cppkafka::LogLevel::LogCrit: {
 | 
							case cppkafka::LogLevel::LogCrit: {
 | 
				
			||||||
			poco_critical(KafkaManager()->Logger(),
 | 
								poco_critical(KafkaManager()->Logger(),fmt::format("kafka-log: facility: {} message: {}",facility, message));
 | 
				
			||||||
						  fmt::format("kafka-log: facility: {} message: {}", facility, message));
 | 
							}
 | 
				
			||||||
		} break;
 | 
							break;
 | 
				
			||||||
		case cppkafka::LogLevel::LogErr:
 | 
							case cppkafka::LogLevel::LogErr:
 | 
				
			||||||
		case cppkafka::LogLevel::LogEmerg:
 | 
							case cppkafka::LogLevel::LogEmerg:
 | 
				
			||||||
		default: {
 | 
							default: {
 | 
				
			||||||
			poco_error(KafkaManager()->Logger(),
 | 
								poco_error(KafkaManager()->Logger(),fmt::format("kafka-log: facility: {} message: {}",facility, message));
 | 
				
			||||||
					   fmt::format("kafka-log: facility: {} message: {}", facility, message));
 | 
							}
 | 
				
			||||||
		} break;
 | 
							break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline void KafkaErrorFun([[maybe_unused]] cppkafka::KafkaHandleBase &handle, int error,
 | 
						inline void KafkaErrorFun([[maybe_unused]] cppkafka::KafkaHandleBase & handle, int error, const std::string &reason) {
 | 
				
			||||||
							  const std::string &reason) {
 | 
							poco_error(KafkaManager()->Logger(),fmt::format("kafka-error: {}, reason: {}", error, reason));
 | 
				
			||||||
		poco_error(KafkaManager()->Logger(),
 | 
					 | 
				
			||||||
				   fmt::format("kafka-error: {}, reason: {}", error, reason));
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline void AddKafkaSecurity(cppkafka::Configuration & Config) {
 | 
						inline void AddKafkaSecurity(cppkafka::Configuration & Config) {
 | 
				
			||||||
		auto CA = MicroServiceConfigGetString("openwifi.kafka.ssl.ca.location","");
 | 
							auto CA = MicroServiceConfigGetString("openwifi.kafka.ssl.ca.location","");
 | 
				
			||||||
		auto Certificate =
 | 
							auto Certificate = MicroServiceConfigGetString("openwifi.kafka.ssl.certificate.location","");
 | 
				
			||||||
			MicroServiceConfigGetString("openwifi.kafka.ssl.certificate.location", "");
 | 
					 | 
				
			||||||
		auto Key = MicroServiceConfigGetString("openwifi.kafka.ssl.key.location","");
 | 
							auto Key = MicroServiceConfigGetString("openwifi.kafka.ssl.key.location","");
 | 
				
			||||||
		auto Password = MicroServiceConfigGetString("openwifi.kafka.ssl.key.password","");
 | 
							auto Password = MicroServiceConfigGetString("openwifi.kafka.ssl.key.password","");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -65,29 +61,29 @@ namespace OpenWifi {
 | 
				
			|||||||
			Config.set("ssl.key.password", Password);
 | 
								Config.set("ssl.key.password", Password);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void KafkaManager::initialize(Poco::Util::Application & self) {
 | 
						void KafkaManager::initialize(Poco::Util::Application & self) {
 | 
				
			||||||
		SubSystemServer::initialize(self);
 | 
							SubSystemServer::initialize(self);
 | 
				
			||||||
		KafkaEnabled_ = MicroServiceConfigGetBool("openwifi.kafka.enable",false);
 | 
							KafkaEnabled_ = MicroServiceConfigGetBool("openwifi.kafka.enable",false);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline void KafkaProducer::run() {
 | 
						inline void KafkaProducer::run() {
 | 
				
			||||||
		Poco::Logger &Logger_ =
 | 
					        Poco::Logger &Logger_ = Poco::Logger::create("KAFKA-PRODUCER", KafkaManager()->Logger().getChannel());
 | 
				
			||||||
			Poco::Logger::create("KAFKA-PRODUCER", KafkaManager()->Logger().getChannel());
 | 
					 | 
				
			||||||
        poco_information(Logger_,"Starting...");
 | 
					        poco_information(Logger_,"Starting...");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Utils::SetThreadName("Kafka:Prod");
 | 
							Utils::SetThreadName("Kafka:Prod");
 | 
				
			||||||
		cppkafka::Configuration Config(
 | 
							cppkafka::Configuration Config({
 | 
				
			||||||
			{{"client.id", MicroServiceConfigGetString("openwifi.kafka.client.id", "")},
 | 
								{ "client.id", MicroServiceConfigGetString("openwifi.kafka.client.id", "") },
 | 
				
			||||||
			 {"metadata.broker.list",
 | 
								{ "metadata.broker.list", MicroServiceConfigGetString("openwifi.kafka.brokerlist", "") }
 | 
				
			||||||
			  MicroServiceConfigGetString("openwifi.kafka.brokerlist", "")}});
 | 
							});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		AddKafkaSecurity(Config);
 | 
							AddKafkaSecurity(Config);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Config.set_log_callback(KafkaLoggerFun);
 | 
							Config.set_log_callback(KafkaLoggerFun);
 | 
				
			||||||
		Config.set_error_callback(KafkaErrorFun);
 | 
							Config.set_error_callback(KafkaErrorFun);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		KafkaManager()->SystemInfoWrapper_ =
 | 
							KafkaManager()->SystemInfoWrapper_ = 	R"lit({ "system" : { "id" : )lit" +
 | 
				
			||||||
			R"lit({ "system" : { "id" : )lit" + std::to_string(MicroServiceID()) +
 | 
																 std::to_string(MicroServiceID()) +
 | 
				
			||||||
											 R"lit( , "host" : ")lit" + MicroServicePrivateEndPoint() +
 | 
																 R"lit( , "host" : ")lit" + MicroServicePrivateEndPoint() +
 | 
				
			||||||
											 R"lit(" } , "payload" : )lit" ;
 | 
																 R"lit(" } , "payload" : )lit" ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -99,13 +95,11 @@ namespace OpenWifi {
 | 
				
			|||||||
			try {
 | 
								try {
 | 
				
			||||||
				auto Msg = dynamic_cast<KafkaMessage *>(Note.get());
 | 
									auto Msg = dynamic_cast<KafkaMessage *>(Note.get());
 | 
				
			||||||
				if (Msg != nullptr) {
 | 
									if (Msg != nullptr) {
 | 
				
			||||||
					Producer.produce(cppkafka::MessageBuilder(Msg->Topic())
 | 
										Producer.produce(
 | 
				
			||||||
										 .key(Msg->Key())
 | 
											cppkafka::MessageBuilder(Msg->Topic()).key(Msg->Key()).payload(Msg->Payload()));
 | 
				
			||||||
										 .payload(Msg->Payload()));
 | 
					 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			} catch (const cppkafka::HandleException &E) {
 | 
								} catch (const cppkafka::HandleException &E) {
 | 
				
			||||||
				poco_warning(Logger_,
 | 
									poco_warning(Logger_,fmt::format("Caught a Kafka exception (producer): {}", E.what()));
 | 
				
			||||||
							 fmt::format("Caught a Kafka exception (producer): {}", E.what()));
 | 
					 | 
				
			||||||
			} catch( const Poco::Exception &E) {
 | 
								} catch( const Poco::Exception &E) {
 | 
				
			||||||
				Logger_.log(E);
 | 
									Logger_.log(E);
 | 
				
			||||||
			} catch (...) {
 | 
								} catch (...) {
 | 
				
			||||||
@@ -119,25 +113,27 @@ namespace OpenWifi {
 | 
				
			|||||||
	inline void KafkaConsumer::run() {
 | 
						inline void KafkaConsumer::run() {
 | 
				
			||||||
		Utils::SetThreadName("Kafka:Cons");
 | 
							Utils::SetThreadName("Kafka:Cons");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Poco::Logger &Logger_ =
 | 
					        Poco::Logger &Logger_ = Poco::Logger::create("KAFKA-CONSUMER", KafkaManager()->Logger().getChannel());
 | 
				
			||||||
			Poco::Logger::create("KAFKA-CONSUMER", KafkaManager()->Logger().getChannel());
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        poco_information(Logger_,"Starting...");
 | 
					        poco_information(Logger_,"Starting...");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		cppkafka::Configuration Config(
 | 
							cppkafka::Configuration Config({
 | 
				
			||||||
			{{"client.id", MicroServiceConfigGetString("openwifi.kafka.client.id", "")},
 | 
								{ "client.id", MicroServiceConfigGetString("openwifi.kafka.client.id","") },
 | 
				
			||||||
			{ "metadata.broker.list", MicroServiceConfigGetString("openwifi.kafka.brokerlist","") },
 | 
								{ "metadata.broker.list", MicroServiceConfigGetString("openwifi.kafka.brokerlist","") },
 | 
				
			||||||
			{ "group.id", MicroServiceConfigGetString("openwifi.kafka.group.id","") },
 | 
								{ "group.id", MicroServiceConfigGetString("openwifi.kafka.group.id","") },
 | 
				
			||||||
			{ "enable.auto.commit", MicroServiceConfigGetBool("openwifi.kafka.auto.commit",false) },
 | 
								{ "enable.auto.commit", MicroServiceConfigGetBool("openwifi.kafka.auto.commit",false) },
 | 
				
			||||||
			{ "auto.offset.reset", "latest" } ,
 | 
								{ "auto.offset.reset", "latest" } ,
 | 
				
			||||||
			 {"enable.partition.eof", false}});
 | 
								{ "enable.partition.eof", false }
 | 
				
			||||||
 | 
							});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		AddKafkaSecurity(Config);
 | 
							AddKafkaSecurity(Config);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Config.set_log_callback(KafkaLoggerFun);
 | 
							Config.set_log_callback(KafkaLoggerFun);
 | 
				
			||||||
		Config.set_error_callback(KafkaErrorFun);
 | 
							Config.set_error_callback(KafkaErrorFun);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		cppkafka::TopicConfiguration topic_config = {{"auto.offset.reset", "smallest"}};
 | 
							cppkafka::TopicConfiguration topic_config = {
 | 
				
			||||||
 | 
								{ "auto.offset.reset", "smallest" }
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Now configure it to be the default topic config
 | 
							// Now configure it to be the default topic config
 | 
				
			||||||
		Config.set_default_topic_configuration(topic_config);
 | 
							Config.set_default_topic_configuration(topic_config);
 | 
				
			||||||
@@ -166,27 +162,24 @@ namespace OpenWifi {
 | 
				
			|||||||
		Running_ = true;
 | 
							Running_ = true;
 | 
				
			||||||
		while(Running_) {
 | 
							while(Running_) {
 | 
				
			||||||
			try {
 | 
								try {
 | 
				
			||||||
				std::vector<cppkafka::Message> MsgVec =
 | 
									std::vector<cppkafka::Message> MsgVec = Consumer.poll_batch(BatchSize, std::chrono::milliseconds(100));
 | 
				
			||||||
					Consumer.poll_batch(BatchSize, std::chrono::milliseconds(100));
 | 
					 | 
				
			||||||
				for(auto const &Msg:MsgVec) {
 | 
									for(auto const &Msg:MsgVec) {
 | 
				
			||||||
					if (!Msg)
 | 
										if (!Msg)
 | 
				
			||||||
						continue;
 | 
											continue;
 | 
				
			||||||
					if (Msg.get_error()) {
 | 
										if (Msg.get_error()) {
 | 
				
			||||||
						if (!Msg.is_eof()) {
 | 
											if (!Msg.is_eof()) {
 | 
				
			||||||
							poco_error(Logger_,
 | 
												poco_error(Logger_,fmt::format("Error: {}", Msg.get_error().to_string()));
 | 
				
			||||||
									   fmt::format("Error: {}", Msg.get_error().to_string()));
 | 
					 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
						if(!AutoCommit)
 | 
											if(!AutoCommit)
 | 
				
			||||||
							Consumer.async_commit(Msg);
 | 
												Consumer.async_commit(Msg);
 | 
				
			||||||
						continue;
 | 
											continue;
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					KafkaManager()->Dispatch(Msg.get_topic().c_str(), Msg.get_key(), std::make_shared<std::string>(Msg.get_payload()));
 | 
										KafkaManager()->Dispatch(Msg.get_topic(), Msg.get_key(),Msg.get_payload() );
 | 
				
			||||||
					if (!AutoCommit)
 | 
										if (!AutoCommit)
 | 
				
			||||||
						Consumer.async_commit(Msg);
 | 
											Consumer.async_commit(Msg);
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			} catch (const cppkafka::HandleException &E) {
 | 
								} catch (const cppkafka::HandleException &E) {
 | 
				
			||||||
				poco_warning(Logger_,
 | 
									poco_warning(Logger_,fmt::format("Caught a Kafka exception (consumer): {}", E.what()));
 | 
				
			||||||
							 fmt::format("Caught a Kafka exception (consumer): {}", E.what()));
 | 
					 | 
				
			||||||
			} catch (const Poco::Exception &E) {
 | 
								} catch (const Poco::Exception &E) {
 | 
				
			||||||
				Logger_.log(E);
 | 
									Logger_.log(E);
 | 
				
			||||||
			} catch (...) {
 | 
								} catch (...) {
 | 
				
			||||||
@@ -212,8 +205,7 @@ namespace OpenWifi {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void KafkaProducer::Produce(const char *Topic, const std::string &Key,
 | 
						void KafkaProducer::Produce(const std::string &Topic, const std::string &Key, const std::string &Payload) {
 | 
				
			||||||
								const std::shared_ptr<std::string> Payload) {
 | 
					 | 
				
			||||||
		std::lock_guard	G(Mutex_);
 | 
							std::lock_guard	G(Mutex_);
 | 
				
			||||||
		Queue_.enqueueNotification( new KafkaMessage(Topic,Key,Payload));
 | 
							Queue_.enqueueNotification( new KafkaMessage(Topic,Key,Payload));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -248,8 +240,7 @@ namespace OpenWifi {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	auto KafkaDispatcher::RegisterTopicWatcher(const std::string &Topic,
 | 
						auto KafkaDispatcher::RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction &F) {
 | 
				
			||||||
											   Types::TopicNotifyFunction &F) {
 | 
					 | 
				
			||||||
		std::lock_guard G(Mutex_);
 | 
							std::lock_guard G(Mutex_);
 | 
				
			||||||
		auto It = Notifiers_.find(Topic);
 | 
							auto It = Notifiers_.find(Topic);
 | 
				
			||||||
		if(It == Notifiers_.end()) {
 | 
							if(It == Notifiers_.end()) {
 | 
				
			||||||
@@ -275,8 +266,7 @@ namespace OpenWifi {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void KafkaDispatcher::Dispatch(const char *Topic, const std::string &Key,
 | 
						void KafkaDispatcher::Dispatch(const std::string &Topic, const std::string &Key, const std::string &Payload) {
 | 
				
			||||||
								   const std::shared_ptr<std::string> Payload) {
 | 
					 | 
				
			||||||
		std::lock_guard	G(Mutex_);
 | 
							std::lock_guard	G(Mutex_);
 | 
				
			||||||
		auto It = Notifiers_.find(Topic);
 | 
							auto It = Notifiers_.find(Topic);
 | 
				
			||||||
		if(It!=Notifiers_.end()) {
 | 
							if(It!=Notifiers_.end()) {
 | 
				
			||||||
@@ -285,8 +275,7 @@ namespace OpenWifi {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void KafkaDispatcher::run() {
 | 
						void KafkaDispatcher::run() {
 | 
				
			||||||
		Poco::Logger &Logger_ =
 | 
					        Poco::Logger &Logger_ = Poco::Logger::create("KAFKA-DISPATCHER", KafkaManager()->Logger().getChannel());
 | 
				
			||||||
			Poco::Logger::create("KAFKA-DISPATCHER", KafkaManager()->Logger().getChannel());
 | 
					 | 
				
			||||||
        poco_information(Logger_,"Starting...");
 | 
					        poco_information(Logger_,"Starting...");
 | 
				
			||||||
		Poco::AutoPtr<Poco::Notification>	Note(Queue_.waitDequeueNotification());
 | 
							Poco::AutoPtr<Poco::Notification>	Note(Queue_.waitDequeueNotification());
 | 
				
			||||||
		Utils::SetThreadName("kafka:dispatch");
 | 
							Utils::SetThreadName("kafka:dispatch");
 | 
				
			||||||
@@ -312,6 +301,7 @@ namespace OpenWifi {
 | 
				
			|||||||
			T.push_back(TopicName);
 | 
								T.push_back(TopicName);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int KafkaManager::Start() {
 | 
						int KafkaManager::Start() {
 | 
				
			||||||
		if(!KafkaEnabled_)
 | 
							if(!KafkaEnabled_)
 | 
				
			||||||
			return 0;
 | 
								return 0;
 | 
				
			||||||
@@ -332,25 +322,21 @@ namespace OpenWifi {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void KafkaManager::PostMessage(const char *topic, const std::string &key,
 | 
						void KafkaManager::PostMessage(const std::string &topic, const std::string & key, const std::string &PayLoad, bool WrapMessage ) {
 | 
				
			||||||
								   const std::shared_ptr<std::string> PayLoad, bool WrapMessage) {
 | 
					 | 
				
			||||||
		if(KafkaEnabled_) {
 | 
							if(KafkaEnabled_) {
 | 
				
			||||||
			ProducerThr_.Produce(topic,key,WrapMessage ? WrapSystemId(PayLoad) : PayLoad);
 | 
								ProducerThr_.Produce(topic,key,WrapMessage ? WrapSystemId(PayLoad) : PayLoad);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void KafkaManager::Dispatch(const char *Topic, const std::string &Key,
 | 
						void KafkaManager::Dispatch(const std::string &Topic, const std::string & Key, const std::string &Payload) {
 | 
				
			||||||
								const std::shared_ptr<std::string> Payload) {
 | 
					 | 
				
			||||||
		Dispatcher_.Dispatch(Topic, Key, Payload);
 | 
							Dispatcher_.Dispatch(Topic, Key, Payload);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	[[nodiscard]] const std::shared_ptr<std::string> KafkaManager::WrapSystemId(const std::shared_ptr<std::string> PayLoad) {
 | 
						[[nodiscard]] std::string KafkaManager::WrapSystemId(const std::string & PayLoad) {
 | 
				
			||||||
		*PayLoad = SystemInfoWrapper_ + *PayLoad + "}";
 | 
							return SystemInfoWrapper_ + PayLoad + "}";
 | 
				
			||||||
		return PayLoad;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	uint64_t KafkaManager::RegisterTopicWatcher(const std::string &Topic,
 | 
						uint64_t KafkaManager::RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction &F) {
 | 
				
			||||||
												Types::TopicNotifyFunction &F) {
 | 
					 | 
				
			||||||
		if(KafkaEnabled_) {
 | 
							if(KafkaEnabled_) {
 | 
				
			||||||
			return Dispatcher_.RegisterTopicWatcher(Topic,F);
 | 
								return Dispatcher_.RegisterTopicWatcher(Topic,F);
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
@@ -364,16 +350,16 @@ namespace OpenWifi {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void KafkaManager::Topics(std::vector<std::string> &T) { Dispatcher_.Topics(T); }
 | 
						void KafkaManager::Topics(std::vector<std::string> &T) {
 | 
				
			||||||
 | 
							Dispatcher_.Topics(T);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void KafkaManager::PartitionAssignment(const cppkafka::TopicPartitionList& partitions) {
 | 
						void KafkaManager::PartitionAssignment(const cppkafka::TopicPartitionList& partitions) {
 | 
				
			||||||
		poco_information(
 | 
							poco_information(Logger(),fmt::format("Partition assigned: {}...", partitions.front().get_partition()));
 | 
				
			||||||
			Logger(), fmt::format("Partition assigned: {}...", partitions.front().get_partition()));
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void KafkaManager::PartitionRevocation(const cppkafka::TopicPartitionList& partitions) {
 | 
						void KafkaManager::PartitionRevocation(const cppkafka::TopicPartitionList& partitions) {
 | 
				
			||||||
		poco_information(Logger(), fmt::format("Partition revocation: {}...",
 | 
							poco_information(Logger(),fmt::format("Partition revocation: {}...",partitions.front().get_partition()));
 | 
				
			||||||
											   partitions.front().get_partition()));
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace OpenWifi
 | 
					} // namespace OpenWifi
 | 
				
			||||||
@@ -7,10 +7,10 @@
 | 
				
			|||||||
#include "Poco/Notification.h"
 | 
					#include "Poco/Notification.h"
 | 
				
			||||||
#include "Poco/NotificationQueue.h"
 | 
					#include "Poco/NotificationQueue.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "framework/KafkaTopics.h"
 | 
					 | 
				
			||||||
#include "framework/OpenWifiTypes.h"
 | 
					 | 
				
			||||||
#include "framework/SubSystemServer.h"
 | 
					#include "framework/SubSystemServer.h"
 | 
				
			||||||
 | 
					#include "framework/OpenWifiTypes.h"
 | 
				
			||||||
#include "framework/utils.h"
 | 
					#include "framework/utils.h"
 | 
				
			||||||
 | 
					#include "framework/KafkaTopics.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "cppkafka/cppkafka.h"
 | 
					#include "cppkafka/cppkafka.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -18,17 +18,18 @@ namespace OpenWifi {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	class KafkaMessage: public Poco::Notification {
 | 
						class KafkaMessage: public Poco::Notification {
 | 
				
			||||||
	  public:
 | 
						  public:
 | 
				
			||||||
		KafkaMessage(const char * Topic, const std::string &Key, const std::shared_ptr<std::string> Payload)
 | 
							KafkaMessage( const std::string &Topic, const std::string &Key, const std::string & Payload) :
 | 
				
			||||||
			: Topic_(Topic), Key_(Key), Payload_(std::move(Payload)) {}
 | 
								Topic_(Topic), Key_(Key), Payload_(Payload) {
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline const char * Topic() { return Topic_; }
 | 
							inline const std::string & Topic() { return Topic_; }
 | 
				
			||||||
		inline const std::string & Key() { return Key_; }
 | 
							inline const std::string & Key() { return Key_; }
 | 
				
			||||||
		inline const std::string &Payload() { return *Payload_; }
 | 
							inline const std::string & Payload() { return Payload_; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	  private:
 | 
						  private:
 | 
				
			||||||
		const char *Topic_;
 | 
							std::string	Topic_;
 | 
				
			||||||
		std::string	Key_;
 | 
							std::string	Key_;
 | 
				
			||||||
		std::shared_ptr<std::string> Payload_;
 | 
							std::string	Payload_;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	class KafkaProducer : public Poco::Runnable {
 | 
						class KafkaProducer : public Poco::Runnable {
 | 
				
			||||||
@@ -36,7 +37,7 @@ namespace OpenWifi {
 | 
				
			|||||||
            void run () override;
 | 
					            void run () override;
 | 
				
			||||||
            void Start();
 | 
					            void Start();
 | 
				
			||||||
            void Stop();
 | 
					            void Stop();
 | 
				
			||||||
		void Produce(const char *Topic, const std::string &Key, const std::shared_ptr<std::string> Payload);
 | 
					            void Produce(const std::string &Topic, const std::string &Key, const std::string &Payload);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	  private:
 | 
						  private:
 | 
				
			||||||
            std::recursive_mutex  		Mutex_;
 | 
					            std::recursive_mutex  		Mutex_;
 | 
				
			||||||
@@ -63,7 +64,7 @@ namespace OpenWifi {
 | 
				
			|||||||
		void Stop();
 | 
							void Stop();
 | 
				
			||||||
		auto RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction &F);
 | 
							auto RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction &F);
 | 
				
			||||||
		void UnregisterTopicWatcher(const std::string &Topic, int Id);
 | 
							void UnregisterTopicWatcher(const std::string &Topic, int Id);
 | 
				
			||||||
		void Dispatch(const char *Topic, const std::string &Key, const std::shared_ptr<std::string> Payload);
 | 
							void Dispatch(const std::string &Topic, const std::string &Key, const std::string &Payload);
 | 
				
			||||||
		void run() override;
 | 
							void run() override;
 | 
				
			||||||
		void Topics(std::vector<std::string> &T);
 | 
							void Topics(std::vector<std::string> &T);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -78,6 +79,7 @@ namespace OpenWifi {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	class KafkaManager : public SubSystemServer {
 | 
						class KafkaManager : public SubSystemServer {
 | 
				
			||||||
	  public:
 | 
						  public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		friend class KafkaConsumer;
 | 
							friend class KafkaConsumer;
 | 
				
			||||||
		friend class KafkaProducer;
 | 
							friend class KafkaProducer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -91,10 +93,9 @@ namespace OpenWifi {
 | 
				
			|||||||
		int Start() override;
 | 
							int Start() override;
 | 
				
			||||||
		void Stop() override;
 | 
							void Stop() override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		void PostMessage(const char *topic, const std::string &key,
 | 
							void PostMessage(const std::string &topic, const std::string & key, const std::string &PayLoad, bool WrapMessage = true  );
 | 
				
			||||||
						 const std::shared_ptr<std::string> PayLoad, bool WrapMessage = true);
 | 
							void Dispatch(const std::string &Topic, const std::string & Key, const std::string &Payload);
 | 
				
			||||||
		void Dispatch(const char *Topic, const std::string &Key, const std::shared_ptr<std::string> Payload);
 | 
							[[nodiscard]] std::string WrapSystemId(const std::string & PayLoad);
 | 
				
			||||||
		[[nodiscard]] const std::shared_ptr<std::string> WrapSystemId(const std::shared_ptr<std::string> PayLoad);
 | 
					 | 
				
			||||||
		[[nodiscard]] inline bool Enabled() const { return KafkaEnabled_; }
 | 
							[[nodiscard]] inline bool Enabled() const { return KafkaEnabled_; }
 | 
				
			||||||
		uint64_t RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction &F);
 | 
							uint64_t RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction &F);
 | 
				
			||||||
		void UnregisterTopicWatcher(const std::string &Topic, uint64_t Id);
 | 
							void UnregisterTopicWatcher(const std::string &Topic, uint64_t Id);
 | 
				
			||||||
@@ -110,9 +111,12 @@ namespace OpenWifi {
 | 
				
			|||||||
		void PartitionAssignment(const cppkafka::TopicPartitionList& partitions);
 | 
							void PartitionAssignment(const cppkafka::TopicPartitionList& partitions);
 | 
				
			||||||
		void PartitionRevocation(const cppkafka::TopicPartitionList& partitions);
 | 
							void PartitionRevocation(const cppkafka::TopicPartitionList& partitions);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		KafkaManager() noexcept : SubSystemServer("KafkaManager", "KAFKA-SVR", "openwifi.kafka") {}
 | 
							KafkaManager() noexcept:
 | 
				
			||||||
 | 
								SubSystemServer("KafkaManager", "KAFKA-SVR", "openwifi.kafka") {
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline auto KafkaManager() { return KafkaManager::instance(); }
 | 
						inline auto KafkaManager() { return KafkaManager::instance(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace OpenWifi
 | 
					} // namespace OpenWifi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,32 +10,33 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <string>
 | 
					#include <string>
 | 
				
			||||||
namespace OpenWifi::KafkaTopics {
 | 
					namespace OpenWifi::KafkaTopics {
 | 
				
			||||||
	inline const char * HEALTHCHECK = "healthcheck";
 | 
						static const std::string HEALTHCHECK{"healthcheck"};
 | 
				
			||||||
	inline const char * STATE = "state";
 | 
						static const std::string STATE{"state"};
 | 
				
			||||||
	inline const char * CONNECTION = "connection";
 | 
						static const std::string CONNECTION{"connection"};
 | 
				
			||||||
	inline const char * WIFISCAN = "wifiscan";
 | 
						static const std::string WIFISCAN{"wifiscan"};
 | 
				
			||||||
	inline const char * ALERTS = "alerts";
 | 
						static const std::string ALERTS{"alerts"};
 | 
				
			||||||
	inline const char * COMMAND = "command";
 | 
						static const std::string COMMAND{"command"};
 | 
				
			||||||
	inline const char * SERVICE_EVENTS = "service_events";
 | 
						static const std::string SERVICE_EVENTS{"service_events"};
 | 
				
			||||||
	inline const char * DEVICE_EVENT_QUEUE = "device_event_queue";
 | 
						static const std::string DEVICE_EVENT_QUEUE{"device_event_queue"};
 | 
				
			||||||
	inline const char * DEVICE_TELEMETRY = "device_telemetry";
 | 
						static const std::string DEVICE_TELEMETRY{"device_telemetry"};
 | 
				
			||||||
	inline const char * PROVISIONING_CHANGE = "provisioning_change";
 | 
					    static const std::string PROVISIONING_CHANGE{"provisioning_change"};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	namespace ServiceEvents {
 | 
						namespace ServiceEvents {
 | 
				
			||||||
		inline const char * EVENT_JOIN = "join";
 | 
							static const std::string EVENT_JOIN{"join"};
 | 
				
			||||||
		inline const char * EVENT_LEAVE = "leave";
 | 
							static const std::string EVENT_LEAVE{"leave"};
 | 
				
			||||||
		inline const char * EVENT_KEEP_ALIVE = "keep-alive";
 | 
							static const std::string EVENT_KEEP_ALIVE{"keep-alive"};
 | 
				
			||||||
		inline const char * EVENT_REMOVE_TOKEN = "remove-token";
 | 
							static const std::string EVENT_REMOVE_TOKEN{"remove-token"};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		namespace Fields {
 | 
							namespace Fields {
 | 
				
			||||||
			inline const char * EVENT = "event";
 | 
								static const std::string EVENT{"event"};
 | 
				
			||||||
			inline const char * ID = "id";
 | 
								static const std::string ID{"id"};
 | 
				
			||||||
			inline const char * TYPE = "type";
 | 
								static const std::string TYPE{"type"};
 | 
				
			||||||
			inline const char * PUBLIC = "publicEndPoint";
 | 
								static const std::string PUBLIC{"publicEndPoint"};
 | 
				
			||||||
			inline const char * PRIVATE = "privateEndPoint";
 | 
								static const std::string PRIVATE{"privateEndPoint"};
 | 
				
			||||||
			inline const char * KEY = "key";
 | 
								static const std::string KEY{"key"};
 | 
				
			||||||
			inline const char * VRSN = "version";
 | 
								static const std::string VRSN{"version"};
 | 
				
			||||||
			inline const char * TOKEN = "token";
 | 
								static const std::string TOKEN{"token"};
 | 
				
			||||||
		} // namespace Fields
 | 
							}
 | 
				
			||||||
	}	  // namespace ServiceEvents
 | 
						}
 | 
				
			||||||
} // namespace OpenWifi::KafkaTopics
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,39 +2,40 @@
 | 
				
			|||||||
// Created by stephane bourque on 2022-10-26.
 | 
					// Created by stephane bourque on 2022-10-26.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "Poco/AsyncChannel.h"
 | 
					 | 
				
			||||||
#include "Poco/ConsoleChannel.h"
 | 
					 | 
				
			||||||
#include "Poco/FileChannel.h"
 | 
					#include "Poco/FileChannel.h"
 | 
				
			||||||
 | 
					#include "Poco/ConsoleChannel.h"
 | 
				
			||||||
 | 
					#include "Poco/PatternFormatter.h"
 | 
				
			||||||
#include "Poco/FormattingChannel.h"
 | 
					#include "Poco/FormattingChannel.h"
 | 
				
			||||||
#include "Poco/JSON/JSONException.h"
 | 
					#include "Poco/AsyncChannel.h"
 | 
				
			||||||
 | 
					#include "Poco/NullChannel.h"
 | 
				
			||||||
 | 
					#include "Poco/SplitterChannel.h"
 | 
				
			||||||
 | 
					#include "Poco/Net/HTTPStreamFactory.h"
 | 
				
			||||||
 | 
					#include "Poco/Net/HTTPSStreamFactory.h"
 | 
				
			||||||
#include "Poco/Net/FTPSStreamFactory.h"
 | 
					#include "Poco/Net/FTPSStreamFactory.h"
 | 
				
			||||||
#include "Poco/Net/FTPStreamFactory.h"
 | 
					#include "Poco/Net/FTPStreamFactory.h"
 | 
				
			||||||
#include "Poco/Net/HTTPSStreamFactory.h"
 | 
					 | 
				
			||||||
#include "Poco/Net/HTTPStreamFactory.h"
 | 
					 | 
				
			||||||
#include "Poco/Net/SSLManager.h"
 | 
					#include "Poco/Net/SSLManager.h"
 | 
				
			||||||
#include "Poco/NullChannel.h"
 | 
					#include "Poco/JSON/JSONException.h"
 | 
				
			||||||
#include "Poco/PatternFormatter.h"
 | 
					 | 
				
			||||||
#include "Poco/SplitterChannel.h"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "framework/ALBserver.h"
 | 
					 | 
				
			||||||
#include "framework/AuthClient.h"
 | 
					 | 
				
			||||||
#include "framework/KafkaManager.h"
 | 
					 | 
				
			||||||
#include "framework/MicroService.h"
 | 
					#include "framework/MicroService.h"
 | 
				
			||||||
#include "framework/MicroServiceErrorHandler.h"
 | 
					#include "framework/MicroServiceErrorHandler.h"
 | 
				
			||||||
#include "framework/MicroServiceNames.h"
 | 
					 | 
				
			||||||
#include "framework/RESTAPI_ExtServer.h"
 | 
					 | 
				
			||||||
#include "framework/RESTAPI_GenericServerAccounting.h"
 | 
					 | 
				
			||||||
#include "framework/RESTAPI_IntServer.h"
 | 
					 | 
				
			||||||
#include "framework/UI_WebSocketClientServer.h"
 | 
					#include "framework/UI_WebSocketClientServer.h"
 | 
				
			||||||
#include "framework/WebSocketLogger.h"
 | 
					#include "framework/MicroServiceNames.h"
 | 
				
			||||||
 | 
					#include "framework/AuthClient.h"
 | 
				
			||||||
 | 
					#include "framework/ALBserver.h"
 | 
				
			||||||
 | 
					#include "framework/KafkaManager.h"
 | 
				
			||||||
 | 
					#include "framework/RESTAPI_GenericServerAccounting.h"
 | 
				
			||||||
 | 
					#include "framework/RESTAPI_ExtServer.h"
 | 
				
			||||||
 | 
					#include "framework/RESTAPI_IntServer.h"
 | 
				
			||||||
#include "framework/utils.h"
 | 
					#include "framework/utils.h"
 | 
				
			||||||
 | 
					#include "framework/WebSocketLogger.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void MicroService::Exit(int Reason) { std::exit(Reason); }
 | 
						void MicroService::Exit(int Reason) {
 | 
				
			||||||
 | 
							std::exit(Reason);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void MicroService::BusMessageReceived([[maybe_unused]] const std::string &Key,
 | 
						void MicroService::BusMessageReceived([[maybe_unused]] const std::string &Key, const std::string & Payload) {
 | 
				
			||||||
										  const std::string &Payload) {
 | 
					 | 
				
			||||||
		std::lock_guard G(InfraMutex_);
 | 
							std::lock_guard G(InfraMutex_);
 | 
				
			||||||
		try {
 | 
							try {
 | 
				
			||||||
			Poco::JSON::Parser P;
 | 
								Poco::JSON::Parser P;
 | 
				
			||||||
@@ -53,45 +54,21 @@ namespace OpenWifi {
 | 
				
			|||||||
							Object->has(KafkaTopics::ServiceEvents::Fields::PRIVATE) &&
 | 
												Object->has(KafkaTopics::ServiceEvents::Fields::PRIVATE) &&
 | 
				
			||||||
							Object->has(KafkaTopics::ServiceEvents::Fields::VRSN) &&
 | 
												Object->has(KafkaTopics::ServiceEvents::Fields::VRSN) &&
 | 
				
			||||||
							Object->has(KafkaTopics::ServiceEvents::Fields::KEY)) {
 | 
												Object->has(KafkaTopics::ServiceEvents::Fields::KEY)) {
 | 
				
			||||||
							auto PrivateEndPoint =
 | 
												auto PrivateEndPoint = Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE).toString();
 | 
				
			||||||
								Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE).toString();
 | 
												if (Event == KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE && Services_.find(PrivateEndPoint) != Services_.end()) {
 | 
				
			||||||
							if (Event == KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE &&
 | 
					 | 
				
			||||||
								Services_.find(PrivateEndPoint) != Services_.end()) {
 | 
					 | 
				
			||||||
								Services_[PrivateEndPoint].LastUpdate = Utils::Now();
 | 
													Services_[PrivateEndPoint].LastUpdate = Utils::Now();
 | 
				
			||||||
							} else if (Event == KafkaTopics::ServiceEvents::EVENT_LEAVE) {
 | 
												} else if (Event == KafkaTopics::ServiceEvents::EVENT_LEAVE) {
 | 
				
			||||||
								Services_.erase(PrivateEndPoint);
 | 
													Services_.erase(PrivateEndPoint);
 | 
				
			||||||
								poco_debug(
 | 
													poco_debug(logger(),fmt::format("Service {} ID={} leaving system.",Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE).toString(),ID));
 | 
				
			||||||
									logger(),
 | 
												} else if (Event == KafkaTopics::ServiceEvents::EVENT_JOIN || Event == KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE) {
 | 
				
			||||||
									fmt::format(
 | 
													poco_debug(logger(),fmt::format("Service {} ID={} joining system.",Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE).toString(),ID));
 | 
				
			||||||
										"Service {} ID={} leaving system.",
 | 
					 | 
				
			||||||
										Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE)
 | 
					 | 
				
			||||||
											.toString(),
 | 
					 | 
				
			||||||
										ID));
 | 
					 | 
				
			||||||
							} else if (Event == KafkaTopics::ServiceEvents::EVENT_JOIN ||
 | 
					 | 
				
			||||||
									   Event == KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE) {
 | 
					 | 
				
			||||||
								poco_debug(
 | 
					 | 
				
			||||||
									logger(),
 | 
					 | 
				
			||||||
									fmt::format(
 | 
					 | 
				
			||||||
										"Service {} ID={} joining system.",
 | 
					 | 
				
			||||||
										Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE)
 | 
					 | 
				
			||||||
											.toString(),
 | 
					 | 
				
			||||||
										ID));
 | 
					 | 
				
			||||||
								Services_[PrivateEndPoint] = Types::MicroServiceMeta{
 | 
													Services_[PrivateEndPoint] = Types::MicroServiceMeta{
 | 
				
			||||||
									.Id = ID,
 | 
														.Id = ID,
 | 
				
			||||||
									.Type = Poco::toLower(
 | 
														.Type = Poco::toLower(Object->get(KafkaTopics::ServiceEvents::Fields::TYPE).toString()),
 | 
				
			||||||
										Object->get(KafkaTopics::ServiceEvents::Fields::TYPE)
 | 
														.PrivateEndPoint = Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE).toString(),
 | 
				
			||||||
											.toString()),
 | 
														.PublicEndPoint = Object->get(KafkaTopics::ServiceEvents::Fields::PUBLIC).toString(),
 | 
				
			||||||
									.PrivateEndPoint =
 | 
														.AccessKey = Object->get(KafkaTopics::ServiceEvents::Fields::KEY).toString(),
 | 
				
			||||||
										Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE)
 | 
														.Version = Object->get(KafkaTopics::ServiceEvents::Fields::VRSN).toString(),
 | 
				
			||||||
											.toString(),
 | 
					 | 
				
			||||||
									.PublicEndPoint =
 | 
					 | 
				
			||||||
										Object->get(KafkaTopics::ServiceEvents::Fields::PUBLIC)
 | 
					 | 
				
			||||||
											.toString(),
 | 
					 | 
				
			||||||
									.AccessKey =
 | 
					 | 
				
			||||||
										Object->get(KafkaTopics::ServiceEvents::Fields::KEY)
 | 
					 | 
				
			||||||
											.toString(),
 | 
					 | 
				
			||||||
									.Version = Object->get(KafkaTopics::ServiceEvents::Fields::VRSN)
 | 
					 | 
				
			||||||
												   .toString(),
 | 
					 | 
				
			||||||
									.LastUpdate = Utils::Now() };
 | 
														.LastUpdate = Utils::Now() };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
								std::string SvcList;
 | 
													std::string SvcList;
 | 
				
			||||||
@@ -101,30 +78,21 @@ namespace OpenWifi {
 | 
				
			|||||||
									else
 | 
														else
 | 
				
			||||||
										SvcList += ", " + Svc.second.Type;
 | 
															SvcList += ", " + Svc.second.Type;
 | 
				
			||||||
								}
 | 
													}
 | 
				
			||||||
								poco_information(
 | 
													poco_information(logger(),fmt::format("Current list of microservices: {}", SvcList));
 | 
				
			||||||
									logger(),
 | 
					 | 
				
			||||||
									fmt::format("Current list of microservices: {}", SvcList));
 | 
					 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
						} else {
 | 
											} else {
 | 
				
			||||||
							poco_error(
 | 
												poco_error(logger(),fmt::format("KAFKA-MSG: invalid event '{}', missing a field.",Event));
 | 
				
			||||||
								logger(),
 | 
					 | 
				
			||||||
								fmt::format("KAFKA-MSG: invalid event '{}', missing a field.",
 | 
					 | 
				
			||||||
											Event));
 | 
					 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
					} else if (Event==KafkaTopics::ServiceEvents::EVENT_REMOVE_TOKEN) {
 | 
										} else if (Event==KafkaTopics::ServiceEvents::EVENT_REMOVE_TOKEN) {
 | 
				
			||||||
						if(Object->has(KafkaTopics::ServiceEvents::Fields::TOKEN)) {
 | 
											if(Object->has(KafkaTopics::ServiceEvents::Fields::TOKEN)) {
 | 
				
			||||||
	#ifndef TIP_SECURITY_SERVICE
 | 
						#ifndef TIP_SECURITY_SERVICE
 | 
				
			||||||
							AuthClient()->RemovedCachedToken(
 | 
												AuthClient()->RemovedCachedToken(Object->get(KafkaTopics::ServiceEvents::Fields::TOKEN).toString());
 | 
				
			||||||
								Object->get(KafkaTopics::ServiceEvents::Fields::TOKEN).toString());
 | 
					 | 
				
			||||||
	#endif
 | 
						#endif
 | 
				
			||||||
						} else {
 | 
											} else {
 | 
				
			||||||
							poco_error(
 | 
												poco_error(logger(),fmt::format("KAFKA-MSG: invalid event '{}', missing token",Event));
 | 
				
			||||||
								logger(),
 | 
					 | 
				
			||||||
								fmt::format("KAFKA-MSG: invalid event '{}', missing token", Event));
 | 
					 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
					} else {
 | 
										} else {
 | 
				
			||||||
						poco_error(logger(),
 | 
											poco_error(logger(),fmt::format("Unknown Event: {} Source: {}", Event, ID));
 | 
				
			||||||
								   fmt::format("Unknown Event: {} Source: {}", Event, ID));
 | 
					 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
@@ -169,16 +137,14 @@ namespace OpenWifi {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	void MicroService::LoadConfigurationFile() {
 | 
						void MicroService::LoadConfigurationFile() {
 | 
				
			||||||
		std::string Location = Poco::Environment::get(DAEMON_CONFIG_ENV_VAR,".");
 | 
							std::string Location = Poco::Environment::get(DAEMON_CONFIG_ENV_VAR,".");
 | 
				
			||||||
		ConfigFileName_ =
 | 
							ConfigFileName_ = ConfigFileName_.empty() ? Location + "/" + DAEMON_PROPERTIES_FILENAME : ConfigFileName_;
 | 
				
			||||||
			ConfigFileName_.empty() ? Location + "/" + DAEMON_PROPERTIES_FILENAME : ConfigFileName_;
 | 
					 | 
				
			||||||
		Poco::Path ConfigFile(ConfigFileName_);
 | 
							Poco::Path ConfigFile(ConfigFileName_);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (!ConfigFile.isFile()) {
 | 
							if(!ConfigFile.isFile())
 | 
				
			||||||
			std::cerr << DAEMON_APP_NAME << ": Configuration " << ConfigFile.toString()
 | 
							{
 | 
				
			||||||
					  << " does not seem to exist. Please set " + DAEMON_CONFIG_ENV_VAR +
 | 
								std::cerr << DAEMON_APP_NAME << ": Configuration "
 | 
				
			||||||
							 " env variable the path of the " + DAEMON_PROPERTIES_FILENAME +
 | 
										  << ConfigFile.toString() << " does not seem to exist. Please set " + DAEMON_CONFIG_ENV_VAR
 | 
				
			||||||
							 " file."
 | 
																		  + " env variable the path of the " + DAEMON_PROPERTIES_FILENAME + " file." << std::endl;
 | 
				
			||||||
					  << std::endl;
 | 
					 | 
				
			||||||
			std::exit(Poco::Util::Application::EXIT_CONFIG);
 | 
								std::exit(Poco::Util::Application::EXIT_CONFIG);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -197,8 +163,7 @@ namespace OpenWifi {
 | 
				
			|||||||
		std::string KeyFile = ConfigPath("openwifi.service.key","");
 | 
							std::string KeyFile = ConfigPath("openwifi.service.key","");
 | 
				
			||||||
		if(!KeyFile.empty()) {
 | 
							if(!KeyFile.empty()) {
 | 
				
			||||||
			std::string KeyFilePassword = ConfigPath("openwifi.service.key.password", "");
 | 
								std::string KeyFilePassword = ConfigPath("openwifi.service.key.password", "");
 | 
				
			||||||
			AppKey_ = Poco::SharedPtr<Poco::Crypto::RSAKey>(
 | 
								AppKey_ = Poco::SharedPtr<Poco::Crypto::RSAKey>(new Poco::Crypto::RSAKey("", KeyFile, KeyFilePassword));
 | 
				
			||||||
				new Poco::Crypto::RSAKey("", KeyFile, KeyFilePassword));
 | 
					 | 
				
			||||||
			Cipher_ = CipherFactory_.createCipher(*AppKey_);
 | 
								Cipher_ = CipherFactory_.createCipher(*AppKey_);
 | 
				
			||||||
			Signer_.setRSAKey(AppKey_);
 | 
								Signer_.setRSAKey(AppKey_);
 | 
				
			||||||
			Signer_.addAllAlgorithms();
 | 
								Signer_.addAllAlgorithms();
 | 
				
			||||||
@@ -223,13 +188,11 @@ namespace OpenWifi {
 | 
				
			|||||||
			initialized = true;
 | 
								initialized = true;
 | 
				
			||||||
			LoadConfigurationFile();
 | 
								LoadConfigurationFile();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			auto LoggingDestination =
 | 
								auto LoggingDestination = MicroService::instance().ConfigGetString("logging.type", "file");
 | 
				
			||||||
				MicroService::instance().ConfigGetString("logging.type", "file");
 | 
								auto LoggingFormat = MicroService::instance().ConfigGetString("logging.format",
 | 
				
			||||||
			auto LoggingFormat = MicroService::instance().ConfigGetString(
 | 
																							  "%Y-%m-%d %H:%M:%S.%i %s: [%p][thr:%I] %t");
 | 
				
			||||||
				"logging.format", "%Y-%m-%d %H:%M:%S.%i %s: [%p][thr:%I] %t");
 | 
					 | 
				
			||||||
			auto UseAsyncLogs_ = MicroService::instance().ConfigGetBool("logging.asynch", true);
 | 
								auto UseAsyncLogs_ = MicroService::instance().ConfigGetBool("logging.asynch", true);
 | 
				
			||||||
			auto DisableWebSocketLogging =
 | 
								auto DisableWebSocketLogging = MicroService::instance().ConfigGetBool("logging.websocket",false);
 | 
				
			||||||
				MicroService::instance().ConfigGetBool("logging.websocket", false);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (LoggingDestination == "null") {
 | 
								if (LoggingDestination == "null") {
 | 
				
			||||||
				Poco::AutoPtr<Poco::NullChannel> DevNull(new Poco::NullChannel);
 | 
									Poco::AutoPtr<Poco::NullChannel> DevNull(new Poco::NullChannel);
 | 
				
			||||||
@@ -243,12 +206,10 @@ namespace OpenWifi {
 | 
				
			|||||||
			} else if (LoggingDestination == "syslog") {
 | 
								} else if (LoggingDestination == "syslog") {
 | 
				
			||||||
                SetSyslogLogs(UseAsyncLogs_, DisableWebSocketLogging, LoggingFormat);
 | 
					                SetSyslogLogs(UseAsyncLogs_, DisableWebSocketLogging, LoggingFormat);
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				SetFileLogs(UseAsyncLogs_, DisableWebSocketLogging, LoggingFormat,
 | 
					                SetFileLogs(UseAsyncLogs_, DisableWebSocketLogging, LoggingFormat, DAEMON_ROOT_ENV_VAR);
 | 
				
			||||||
							DAEMON_ROOT_ENV_VAR);
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			auto Level = Poco::Logger::parseLevel(
 | 
								auto Level = Poco::Logger::parseLevel(MicroService::instance().ConfigGetString("logging.level", "debug"));
 | 
				
			||||||
				MicroService::instance().ConfigGetString("logging.level", "debug"));
 | 
					 | 
				
			||||||
			Poco::Logger::root().setLevel(Level);
 | 
								Poco::Logger::root().setLevel(Level);
 | 
				
			||||||
			if(!DisableWebSocketLogging) {
 | 
								if(!DisableWebSocketLogging) {
 | 
				
			||||||
				static const UI_WebSocketClientServer::NotificationTypeIdVec Notifications = {
 | 
									static const UI_WebSocketClientServer::NotificationTypeIdVec Notifications = {
 | 
				
			||||||
@@ -258,14 +219,12 @@ namespace OpenWifi {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void MicroService::SetConsoleLogs(bool UseAsync, bool DisableWebSocketLogging,
 | 
					    void MicroService::SetConsoleLogs(bool UseAsync, bool DisableWebSocketLogging, const std::string & FormatterPattern) {
 | 
				
			||||||
									  const std::string &FormatterPattern) {
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Poco::AutoPtr<Poco::ConsoleChannel> Console(new Poco::ConsoleChannel);
 | 
					        Poco::AutoPtr<Poco::ConsoleChannel> Console(new Poco::ConsoleChannel);
 | 
				
			||||||
        Poco::AutoPtr<Poco::PatternFormatter> Formatter(new Poco::PatternFormatter);
 | 
					        Poco::AutoPtr<Poco::PatternFormatter> Formatter(new Poco::PatternFormatter);
 | 
				
			||||||
        Formatter->setProperty("pattern", FormatterPattern);
 | 
					        Formatter->setProperty("pattern", FormatterPattern);
 | 
				
			||||||
		Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel(
 | 
					        Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel(new Poco::FormattingChannel(Formatter, Console));
 | 
				
			||||||
			new Poco::FormattingChannel(Formatter, Console));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(DisableWebSocketLogging) {
 | 
					        if(DisableWebSocketLogging) {
 | 
				
			||||||
            if(UseAsync) {
 | 
					            if(UseAsync) {
 | 
				
			||||||
@@ -286,18 +245,15 @@ namespace OpenWifi {
 | 
				
			|||||||
                Poco::Logger::root().setChannel(Splitter);
 | 
					                Poco::Logger::root().setChannel(Splitter);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
		Poco::Logger::root().information(fmt::format("Enabled console logs: asynch={} websocket={}",
 | 
							Poco::Logger::root().information(fmt::format("Enabled console logs: asynch={} websocket={}",UseAsync,DisableWebSocketLogging));
 | 
				
			||||||
													 UseAsync, DisableWebSocketLogging));
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void MicroService::SetColorConsoleLogs(bool UseAsync, bool DisableWebSocketLogging,
 | 
					    void MicroService::SetColorConsoleLogs(bool UseAsync, bool DisableWebSocketLogging, const std::string & FormatterPattern) {
 | 
				
			||||||
										   const std::string &FormatterPattern) {
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Poco::AutoPtr<Poco::ColorConsoleChannel> Console(new Poco::ColorConsoleChannel);
 | 
					        Poco::AutoPtr<Poco::ColorConsoleChannel> Console(new Poco::ColorConsoleChannel);
 | 
				
			||||||
        Poco::AutoPtr<Poco::PatternFormatter> Formatter(new Poco::PatternFormatter);
 | 
					        Poco::AutoPtr<Poco::PatternFormatter> Formatter(new Poco::PatternFormatter);
 | 
				
			||||||
        Formatter->setProperty("pattern", FormatterPattern);
 | 
					        Formatter->setProperty("pattern", FormatterPattern);
 | 
				
			||||||
		Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel(
 | 
					        Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel(new Poco::FormattingChannel(Formatter, Console));
 | 
				
			||||||
			new Poco::FormattingChannel(Formatter, Console));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(DisableWebSocketLogging) {
 | 
					        if(DisableWebSocketLogging) {
 | 
				
			||||||
            if(UseAsync) {
 | 
					            if(UseAsync) {
 | 
				
			||||||
@@ -318,28 +274,20 @@ namespace OpenWifi {
 | 
				
			|||||||
                Poco::Logger::root().setChannel(Splitter);
 | 
					                Poco::Logger::root().setChannel(Splitter);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
		Poco::Logger::root().information(
 | 
							Poco::Logger::root().information(fmt::format("Enabled color console logs: asynch={} websocket={}",UseAsync,DisableWebSocketLogging));
 | 
				
			||||||
			fmt::format("Enabled color console logs: asynch={} websocket={}", UseAsync,
 | 
					 | 
				
			||||||
						DisableWebSocketLogging));
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void MicroService::SetSQLLogs([[maybe_unused]] bool UseAsync,
 | 
					    void MicroService::SetSQLLogs([[maybe_unused]] bool UseAsync,[[maybe_unused]]  bool DisableWebSocketLogging,[[maybe_unused]]  const std::string & FormatterPattern) {
 | 
				
			||||||
								  [[maybe_unused]] bool DisableWebSocketLogging,
 | 
					        //"CREATE TABLE T_POCO_LOG (Source VARCHAR, Name VARCHAR, ProcessId INTEGER, Thread VARCHAR, ThreadId INTEGER, Priority INTEGER, Text VARCHAR, DateTime DATE)"
 | 
				
			||||||
								  [[maybe_unused]] const std::string &FormatterPattern) {
 | 
					 | 
				
			||||||
		//"CREATE TABLE T_POCO_LOG (Source VARCHAR, Name VARCHAR, ProcessId INTEGER, Thread VARCHAR,
 | 
					 | 
				
			||||||
		//ThreadId INTEGER, Priority INTEGER, Text VARCHAR, DateTime DATE)"
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void MicroService::SetSyslogLogs([[maybe_unused]] bool UseAsync,
 | 
					    void MicroService::SetSyslogLogs([[maybe_unused]] bool UseAsync,[[maybe_unused]]  bool DisableWebSocketLogging,[[maybe_unused]]  const std::string & FormatterPattern) {
 | 
				
			||||||
									 [[maybe_unused]] bool DisableWebSocketLogging,
 | 
					 | 
				
			||||||
									 [[maybe_unused]] const std::string &FormatterPattern) {}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void MicroService::SetFileLogs(bool UseAsync, bool DisableWebSocketLogging,
 | 
					    }
 | 
				
			||||||
								   const std::string &FormatterPattern,
 | 
					
 | 
				
			||||||
								   const std::string &root_env_var) {
 | 
					    void MicroService::SetFileLogs(bool UseAsync, bool DisableWebSocketLogging, const std::string & FormatterPattern, const std::string & root_env_var) {
 | 
				
			||||||
        std::string DefaultLogPath = fmt::format("${}/logs",root_env_var);
 | 
					        std::string DefaultLogPath = fmt::format("${}/logs",root_env_var);
 | 
				
			||||||
		auto LoggingLocationDir =
 | 
					        auto LoggingLocationDir = MicroService::instance().ConfigPath("logging.path", DefaultLogPath);
 | 
				
			||||||
			MicroService::instance().ConfigPath("logging.path", DefaultLogPath);
 | 
					 | 
				
			||||||
        Poco::File      LD(LoggingLocationDir);
 | 
					        Poco::File      LD(LoggingLocationDir);
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            if(!LD.exists()) {
 | 
					            if(!LD.exists()) {
 | 
				
			||||||
@@ -358,8 +306,7 @@ namespace OpenWifi {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        Poco::AutoPtr<Poco::PatternFormatter> Formatter(new Poco::PatternFormatter);
 | 
					        Poco::AutoPtr<Poco::PatternFormatter> Formatter(new Poco::PatternFormatter);
 | 
				
			||||||
        Formatter->setProperty("pattern", FormatterPattern);
 | 
					        Formatter->setProperty("pattern", FormatterPattern);
 | 
				
			||||||
		Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel(
 | 
					        Poco::AutoPtr<Poco::FormattingChannel> FormattingChannel(new Poco::FormattingChannel(Formatter, FileChannel));
 | 
				
			||||||
			new Poco::FormattingChannel(Formatter, FileChannel));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(DisableWebSocketLogging) {
 | 
					        if(DisableWebSocketLogging) {
 | 
				
			||||||
            if(UseAsync) {
 | 
					            if(UseAsync) {
 | 
				
			||||||
@@ -380,8 +327,7 @@ namespace OpenWifi {
 | 
				
			|||||||
                Poco::Logger::root().setChannel(Splitter);
 | 
					                Poco::Logger::root().setChannel(Splitter);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
		Poco::Logger::root().information(fmt::format("Enabled file logs: asynch={} websocket={}",
 | 
							Poco::Logger::root().information(fmt::format("Enabled file logs: asynch={} websocket={}",UseAsync,DisableWebSocketLogging));
 | 
				
			||||||
													 UseAsync, DisableWebSocketLogging));
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void DaemonPostInitialization(Poco::Util::Application &self);
 | 
						void DaemonPostInitialization(Poco::Util::Application &self);
 | 
				
			||||||
@@ -425,9 +371,7 @@ namespace OpenWifi {
 | 
				
			|||||||
		ServerApplication::initialize(self);
 | 
							ServerApplication::initialize(self);
 | 
				
			||||||
		DaemonPostInitialization(self);
 | 
							DaemonPostInitialization(self);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Types::TopicNotifyFunction F = [this](const std::string &Key, const std::string &Payload) {
 | 
							Types::TopicNotifyFunction F = [this](const std::string &Key,const std::string &Payload) { this->BusMessageReceived(Key, Payload); };
 | 
				
			||||||
			this->BusMessageReceived(Key, Payload);
 | 
					 | 
				
			||||||
		};
 | 
					 | 
				
			||||||
		KafkaManager()->RegisterTopicWatcher(KafkaTopics::SERVICE_EVENTS, F);
 | 
							KafkaManager()->RegisterTopicWatcher(KafkaTopics::SERVICE_EVENTS, F);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -448,64 +392,58 @@ namespace OpenWifi {
 | 
				
			|||||||
			Poco::Util::Option("help", "", "display help information on command line arguments")
 | 
								Poco::Util::Option("help", "", "display help information on command line arguments")
 | 
				
			||||||
				.required(false)
 | 
									.required(false)
 | 
				
			||||||
				.repeatable(false)
 | 
									.repeatable(false)
 | 
				
			||||||
				.callback(
 | 
									.callback(Poco::Util::OptionCallback<MicroService>(this, &MicroService::handleHelp)));
 | 
				
			||||||
					Poco::Util::OptionCallback<MicroService>(this, &MicroService::handleHelp)));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		options.addOption(Poco::Util::Option("file", "", "specify the configuration file")
 | 
							options.addOption(
 | 
				
			||||||
 | 
								Poco::Util::Option("file", "", "specify the configuration file")
 | 
				
			||||||
				.required(false)
 | 
									.required(false)
 | 
				
			||||||
				.repeatable(false)
 | 
									.repeatable(false)
 | 
				
			||||||
				.argument("file")
 | 
									.argument("file")
 | 
				
			||||||
							  .callback(Poco::Util::OptionCallback<MicroService>(
 | 
									.callback(Poco::Util::OptionCallback<MicroService>(this, &MicroService::handleConfig)));
 | 
				
			||||||
								  this, &MicroService::handleConfig)));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		options.addOption(Poco::Util::Option("debug", "", "to run in debug, set to true")
 | 
							options.addOption(
 | 
				
			||||||
 | 
								Poco::Util::Option("debug", "", "to run in debug, set to true")
 | 
				
			||||||
				.required(false)
 | 
									.required(false)
 | 
				
			||||||
				.repeatable(false)
 | 
									.repeatable(false)
 | 
				
			||||||
							  .callback(Poco::Util::OptionCallback<MicroService>(
 | 
									.callback(Poco::Util::OptionCallback<MicroService>(this, &MicroService::handleDebug)));
 | 
				
			||||||
								  this, &MicroService::handleDebug)));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		options.addOption(
 | 
							options.addOption(
 | 
				
			||||||
			Poco::Util::Option("logs", "", "specify the log directory and file (i.e. dir/file.log)")
 | 
								Poco::Util::Option("logs", "", "specify the log directory and file (i.e. dir/file.log)")
 | 
				
			||||||
				.required(false)
 | 
									.required(false)
 | 
				
			||||||
				.repeatable(false)
 | 
									.repeatable(false)
 | 
				
			||||||
				.argument("dir")
 | 
									.argument("dir")
 | 
				
			||||||
				.callback(
 | 
									.callback(Poco::Util::OptionCallback<MicroService>(this, &MicroService::handleLogs)));
 | 
				
			||||||
					Poco::Util::OptionCallback<MicroService>(this, &MicroService::handleLogs)));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		options.addOption(Poco::Util::Option("version", "", "get the version and quit.")
 | 
							options.addOption(
 | 
				
			||||||
 | 
								Poco::Util::Option("version", "", "get the version and quit.")
 | 
				
			||||||
				.required(false)
 | 
									.required(false)
 | 
				
			||||||
				.repeatable(false)
 | 
									.repeatable(false)
 | 
				
			||||||
							  .callback(Poco::Util::OptionCallback<MicroService>(
 | 
									.callback(Poco::Util::OptionCallback<MicroService>(this, &MicroService::handleVersion)));
 | 
				
			||||||
								  this, &MicroService::handleVersion)));
 | 
					
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void MicroService::handleHelp([[maybe_unused]] const std::string &name,
 | 
						void MicroService::handleHelp([[maybe_unused]] const std::string &name, [[maybe_unused]] const std::string &value) {
 | 
				
			||||||
								  [[maybe_unused]] const std::string &value) {
 | 
					 | 
				
			||||||
		HelpRequested_ = true;
 | 
							HelpRequested_ = true;
 | 
				
			||||||
		displayHelp();
 | 
							displayHelp();
 | 
				
			||||||
		stopOptionsProcessing();
 | 
							stopOptionsProcessing();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void MicroService::handleVersion([[maybe_unused]] const std::string &name,
 | 
						void MicroService::handleVersion([[maybe_unused]] const std::string &name, [[maybe_unused]] const std::string &value) {
 | 
				
			||||||
									 [[maybe_unused]] const std::string &value) {
 | 
					 | 
				
			||||||
		HelpRequested_ = true;
 | 
							HelpRequested_ = true;
 | 
				
			||||||
		std::cout << Version() << std::endl;
 | 
							std::cout << Version() << std::endl;
 | 
				
			||||||
		stopOptionsProcessing();
 | 
							stopOptionsProcessing();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void MicroService::handleDebug([[maybe_unused]] const std::string &name,
 | 
						void MicroService::handleDebug([[maybe_unused]] const std::string &name, const std::string &value) {
 | 
				
			||||||
								   const std::string &value) {
 | 
					 | 
				
			||||||
		if(value == "true")
 | 
							if(value == "true")
 | 
				
			||||||
			DebugMode_ = true ;
 | 
								DebugMode_ = true ;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void MicroService::handleLogs([[maybe_unused]] const std::string &name,
 | 
						void MicroService::handleLogs([[maybe_unused]] const std::string &name, const std::string &value) {
 | 
				
			||||||
								  const std::string &value) {
 | 
					 | 
				
			||||||
		LogDir_ = value;
 | 
							LogDir_ = value;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void MicroService::handleConfig([[maybe_unused]] const std::string &name,
 | 
						void MicroService::handleConfig([[maybe_unused]] const std::string &name, const std::string &value) {
 | 
				
			||||||
									const std::string &value) {
 | 
					 | 
				
			||||||
		ConfigFileName_ = value;
 | 
							ConfigFileName_ = value;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -528,8 +466,7 @@ namespace OpenWifi {
 | 
				
			|||||||
		for(auto i:SubSystems_) {
 | 
							for(auto i:SubSystems_) {
 | 
				
			||||||
			i->Start();
 | 
								i->Start();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		EventBusManager_ = std::make_unique<EventBusManager>(Poco::Logger::create(
 | 
							EventBusManager_ = std::make_unique<EventBusManager>(Poco::Logger::create("EventBusManager",Poco::Logger::root().getChannel(),Poco::Logger::root().getLevel()));
 | 
				
			||||||
			"EventBusManager", Poco::Logger::root().getChannel(), Poco::Logger::root().getLevel()));
 | 
					 | 
				
			||||||
		EventBusManager_->Start();
 | 
							EventBusManager_->Start();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -573,8 +510,7 @@ namespace OpenWifi {
 | 
				
			|||||||
		return ss.str();
 | 
							return ss.str();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool MicroService::SetSubsystemLogLevel(const std::string &SubSystem,
 | 
						bool MicroService::SetSubsystemLogLevel(const std::string &SubSystem, const std::string &Level) {
 | 
				
			||||||
											const std::string &Level) {
 | 
					 | 
				
			||||||
		try {
 | 
							try {
 | 
				
			||||||
			auto P = Poco::Logger::parseLevel(Level);
 | 
								auto P = Poco::Logger::parseLevel(Level);
 | 
				
			||||||
			auto Sub = Poco::toLower(SubSystem);
 | 
								auto Sub = Poco::toLower(SubSystem);
 | 
				
			||||||
@@ -625,8 +561,7 @@ namespace OpenWifi {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	const Types::StringVec & MicroService::GetLogLevelNames() {
 | 
						const Types::StringVec & MicroService::GetLogLevelNames() {
 | 
				
			||||||
		static Types::StringVec LevelNames{"none",	 "fatal",		"critical", "error", "warning",
 | 
							static Types::StringVec LevelNames{"none", "fatal", "critical", "error", "warning", "notice", "information", "debug", "trace" };
 | 
				
			||||||
										   "notice", "information", "debug",	"trace"};
 | 
					 | 
				
			||||||
		return LevelNames;
 | 
							return LevelNames;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -634,13 +569,17 @@ namespace OpenWifi {
 | 
				
			|||||||
		return (uint64_t) config().getInt64(Key,Default);
 | 
							return (uint64_t) config().getInt64(Key,Default);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	uint64_t MicroService::ConfigGetInt(const std::string &Key) { return config().getInt(Key); }
 | 
						uint64_t MicroService::ConfigGetInt(const std::string &Key) {
 | 
				
			||||||
 | 
							return config().getInt(Key);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	uint64_t MicroService::ConfigGetBool(const std::string &Key,bool Default) {
 | 
						uint64_t MicroService::ConfigGetBool(const std::string &Key,bool Default) {
 | 
				
			||||||
		return config().getBool(Key,Default);
 | 
							return config().getBool(Key,Default);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	uint64_t MicroService::ConfigGetBool(const std::string &Key) { return config().getBool(Key); }
 | 
						uint64_t MicroService::ConfigGetBool(const std::string &Key) {
 | 
				
			||||||
 | 
							return config().getBool(Key);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	std::string MicroService::ConfigGetString(const std::string &Key,const std::string & Default) {
 | 
						std::string MicroService::ConfigGetString(const std::string &Key,const std::string & Default) {
 | 
				
			||||||
		return config().getString(Key, Default);
 | 
							return config().getString(Key, Default);
 | 
				
			||||||
@@ -664,16 +603,14 @@ namespace OpenWifi {
 | 
				
			|||||||
		if(NoBuiltInCrypto_) {
 | 
							if(NoBuiltInCrypto_) {
 | 
				
			||||||
			return S;
 | 
								return S;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return Cipher_->encryptString(S, Poco::Crypto::Cipher::Cipher::ENC_BASE64);
 | 
							return Cipher_->encryptString(S, Poco::Crypto::Cipher::Cipher::ENC_BASE64);;
 | 
				
			||||||
		;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	std::string MicroService::Decrypt(const std::string &S) {
 | 
						std::string MicroService::Decrypt(const std::string &S) {
 | 
				
			||||||
		if(NoBuiltInCrypto_) {
 | 
							if(NoBuiltInCrypto_) {
 | 
				
			||||||
			return S;
 | 
								return S;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return Cipher_->decryptString(S, Poco::Crypto::Cipher::Cipher::ENC_BASE64);
 | 
							return Cipher_->decryptString(S, Poco::Crypto::Cipher::Cipher::ENC_BASE64);;
 | 
				
			||||||
		;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	std::string MicroService::MakeSystemEventMessage( const std::string & Type ) const {
 | 
						std::string MicroService::MakeSystemEventMessage( const std::string & Type ) const {
 | 
				
			||||||
@@ -703,11 +640,11 @@ namespace OpenWifi {
 | 
				
			|||||||
	void MicroService::SavePID() {
 | 
						void MicroService::SavePID() {
 | 
				
			||||||
		try {
 | 
							try {
 | 
				
			||||||
			std::ofstream O;
 | 
								std::ofstream O;
 | 
				
			||||||
			O.open(MicroService::instance().DataDir() + "/pidfile",
 | 
								O.open(MicroService::instance().DataDir() + "/pidfile",std::ios::binary | std::ios::trunc);
 | 
				
			||||||
				   std::ios::binary | std::ios::trunc);
 | 
					 | 
				
			||||||
			O << Poco::Process::id();
 | 
								O << Poco::Process::id();
 | 
				
			||||||
			O.close();
 | 
								O.close();
 | 
				
			||||||
		} catch (...) {
 | 
							} catch (...)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
			std::cout << "Could not save system ID" << std::endl;
 | 
								std::cout << "Could not save system ID" << std::endl;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -750,6 +687,7 @@ namespace OpenWifi {
 | 
				
			|||||||
				std::time_t now = std::chrono::system_clock::to_time_t(t);
 | 
									std::time_t now = std::chrono::system_clock::to_time_t(t);
 | 
				
			||||||
				of << Activity << " at " << std::ctime(&now) ;
 | 
									of << Activity << " at " << std::ctime(&now) ;
 | 
				
			||||||
			} catch (...) {
 | 
								} catch (...) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -769,7 +707,8 @@ namespace OpenWifi {
 | 
				
			|||||||
			if(F.exists())
 | 
								if(F.exists())
 | 
				
			||||||
				F.remove();
 | 
									F.remove();
 | 
				
			||||||
		} catch (...) {
 | 
							} catch (...) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace OpenWifi
 | 
					}
 | 
				
			||||||
@@ -9,11 +9,12 @@
 | 
				
			|||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <array>
 | 
					#include <array>
 | 
				
			||||||
#include <ctime>
 | 
					 | 
				
			||||||
#include <fstream>
 | 
					 | 
				
			||||||
#include <iostream>
 | 
					#include <iostream>
 | 
				
			||||||
#include <random>
 | 
					 | 
				
			||||||
#include <vector>
 | 
					#include <vector>
 | 
				
			||||||
 | 
					#include <fstream>
 | 
				
			||||||
 | 
					#include <random>
 | 
				
			||||||
 | 
					#include <ctime>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// This must be defined for poco_debug and poco_trace macros to function.
 | 
					// This must be defined for poco_debug and poco_trace macros to function.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -23,37 +24,37 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
    inline uint64_t Now() { return std::time(nullptr); };
 | 
					    inline uint64_t Now() { return std::time(nullptr); };
 | 
				
			||||||
} // namespace OpenWifi
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "Poco/AutoPtr.h"
 | 
					 | 
				
			||||||
#include "Poco/Crypto/Cipher.h"
 | 
					 | 
				
			||||||
#include "Poco/Crypto/CipherFactory.h"
 | 
					 | 
				
			||||||
#include "Poco/Crypto/RSAKey.h"
 | 
					 | 
				
			||||||
#include "Poco/Environment.h"
 | 
					 | 
				
			||||||
#include "Poco/JSON/Object.h"
 | 
					 | 
				
			||||||
#include "Poco/JWT/Signer.h"
 | 
					 | 
				
			||||||
#include "Poco/Net/HTTPServerRequest.h"
 | 
					 | 
				
			||||||
#include "Poco/Process.h"
 | 
					 | 
				
			||||||
#include "Poco/Util/Application.h"
 | 
					#include "Poco/Util/Application.h"
 | 
				
			||||||
#include "Poco/Util/HelpFormatter.h"
 | 
					#include "Poco/Util/ServerApplication.h"
 | 
				
			||||||
#include "Poco/Util/Option.h"
 | 
					#include "Poco/Util/Option.h"
 | 
				
			||||||
#include "Poco/Util/OptionSet.h"
 | 
					#include "Poco/Util/OptionSet.h"
 | 
				
			||||||
 | 
					#include "Poco/Crypto/RSAKey.h"
 | 
				
			||||||
 | 
					#include "Poco/Crypto/CipherFactory.h"
 | 
				
			||||||
 | 
					#include "Poco/Crypto/Cipher.h"
 | 
				
			||||||
 | 
					#include "Poco/Net/HTTPServerRequest.h"
 | 
				
			||||||
 | 
					#include "Poco/Process.h"
 | 
				
			||||||
 | 
					#include "Poco/Util/HelpFormatter.h"
 | 
				
			||||||
 | 
					#include "Poco/JSON/Object.h"
 | 
				
			||||||
 | 
					#include "Poco/AutoPtr.h"
 | 
				
			||||||
#include "Poco/Util/PropertyFileConfiguration.h"
 | 
					#include "Poco/Util/PropertyFileConfiguration.h"
 | 
				
			||||||
#include "Poco/Util/ServerApplication.h"
 | 
					#include "Poco/JWT/Signer.h"
 | 
				
			||||||
 | 
					#include "Poco/Environment.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "framework/OpenWifiTypes.h"
 | 
					#include "framework/OpenWifiTypes.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "framework/EventBusManager.h"
 | 
					 | 
				
			||||||
#include "framework/SubSystemServer.h"
 | 
					 | 
				
			||||||
#include "framework/ow_constants.h"
 | 
					#include "framework/ow_constants.h"
 | 
				
			||||||
#include "framework/utils.h"
 | 
					#include "framework/utils.h"
 | 
				
			||||||
 | 
					#include "framework/SubSystemServer.h"
 | 
				
			||||||
 | 
					#include "framework/EventBusManager.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "RESTObjects/RESTAPI_SecurityObjects.h"
 | 
					#include "RESTObjects/RESTAPI_SecurityObjects.h"
 | 
				
			||||||
#include "cppkafka/cppkafka.h"
 | 
					#include "cppkafka/cppkafka.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "fmt/core.h"
 | 
					 | 
				
			||||||
#include "nlohmann/json.hpp"
 | 
					#include "nlohmann/json.hpp"
 | 
				
			||||||
#include "ow_version.h"
 | 
					#include "ow_version.h"
 | 
				
			||||||
 | 
					#include "fmt/core.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define _OWDEBUG_ std::cout<< __FILE__ <<":" << __LINE__ << std::endl;
 | 
					#define _OWDEBUG_ std::cout<< __FILE__ <<":" << __LINE__ << std::endl;
 | 
				
			||||||
// #define _OWDEBUG_ Logger().debug(Poco::format("%s: %lu",__FILE__,__LINE__));
 | 
					// #define _OWDEBUG_ Logger().debug(Poco::format("%s: %lu",__FILE__,__LINE__));
 | 
				
			||||||
@@ -62,12 +63,19 @@ namespace OpenWifi {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	class MicroService : public Poco::Util::ServerApplication {
 | 
						class MicroService : public Poco::Util::ServerApplication {
 | 
				
			||||||
	  public:
 | 
						  public:
 | 
				
			||||||
		explicit MicroService(std::string PropFile, std::string RootEnv, std::string ConfigVar,
 | 
							explicit MicroService( 	std::string PropFile,
 | 
				
			||||||
							  std::string AppName, uint64_t BusTimer, SubSystemVec Subsystems)
 | 
										 	std::string RootEnv,
 | 
				
			||||||
			: DAEMON_PROPERTIES_FILENAME(std::move(PropFile)),
 | 
										 	std::string ConfigVar,
 | 
				
			||||||
			  DAEMON_ROOT_ENV_VAR(std::move(RootEnv)), DAEMON_CONFIG_ENV_VAR(std::move(ConfigVar)),
 | 
										 	std::string AppName,
 | 
				
			||||||
			  DAEMON_APP_NAME(std::move(AppName)), DAEMON_BUS_TIMER(BusTimer),
 | 
										  	uint64_t BusTimer,
 | 
				
			||||||
			  SubSystems_(std::move(Subsystems)), Logger_(Poco::Logger::get("FRAMEWORK")) {
 | 
										  	SubSystemVec Subsystems) :
 | 
				
			||||||
 | 
									DAEMON_PROPERTIES_FILENAME(std::move(PropFile)),
 | 
				
			||||||
 | 
									DAEMON_ROOT_ENV_VAR(std::move(RootEnv)),
 | 
				
			||||||
 | 
									DAEMON_CONFIG_ENV_VAR(std::move(ConfigVar)),
 | 
				
			||||||
 | 
									DAEMON_APP_NAME(std::move(AppName)),
 | 
				
			||||||
 | 
									DAEMON_BUS_TIMER(BusTimer),
 | 
				
			||||||
 | 
									SubSystems_(std::move(Subsystems)),
 | 
				
			||||||
 | 
									Logger_(Poco::Logger::get("FRAMEWORK")) {
 | 
				
			||||||
		    instance_ = this;
 | 
							    instance_ = this;
 | 
				
			||||||
		    RandomEngine_.seed(std::chrono::steady_clock::now().time_since_epoch().count());
 | 
							    RandomEngine_.seed(std::chrono::steady_clock::now().time_since_epoch().count());
 | 
				
			||||||
			// Logger_ = Poco::Logger::root().get("BASE-SVC");
 | 
								// Logger_ = Poco::Logger::root().get("BASE-SVC");
 | 
				
			||||||
@@ -92,13 +100,9 @@ namespace OpenWifi {
 | 
				
			|||||||
		inline uint64_t DaemonBusTimer() const { return DAEMON_BUS_TIMER; };
 | 
							inline uint64_t DaemonBusTimer() const { return DAEMON_BUS_TIMER; };
 | 
				
			||||||
        [[nodiscard]] const std::string & AppName() { return DAEMON_APP_NAME; }
 | 
					        [[nodiscard]] const std::string & AppName() { return DAEMON_APP_NAME; }
 | 
				
			||||||
		static inline uint64_t GetPID() { return Poco::Process::id(); };
 | 
							static inline uint64_t GetPID() { return Poco::Process::id(); };
 | 
				
			||||||
		[[nodiscard]] inline const std::string GetPublicAPIEndPoint() {
 | 
							[[nodiscard]] inline const std::string GetPublicAPIEndPoint() { return MyPublicEndPoint_ + "/api/v1"; };
 | 
				
			||||||
			return MyPublicEndPoint_ + "/api/v1";
 | 
					 | 
				
			||||||
		};
 | 
					 | 
				
			||||||
		[[nodiscard]] inline const std::string & GetUIURI() const { return UIURI_;};
 | 
							[[nodiscard]] inline const std::string & GetUIURI() const { return UIURI_;};
 | 
				
			||||||
		[[nodiscard]] inline uint64_t Random(uint64_t ceiling) {
 | 
							[[nodiscard]] inline uint64_t Random(uint64_t ceiling) { return (RandomEngine_() % ceiling); }
 | 
				
			||||||
			return (RandomEngine_() % ceiling);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		[[nodiscard]] inline uint64_t Random(uint64_t min, uint64_t max) {
 | 
							[[nodiscard]] inline uint64_t Random(uint64_t min, uint64_t max) {
 | 
				
			||||||
		    return ((RandomEngine_() % (max-min)) + min);
 | 
							    return ((RandomEngine_() % (max-min)) + min);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -154,17 +158,11 @@ namespace OpenWifi {
 | 
				
			|||||||
		[[nodiscard]] std::string Sign(Poco::JWT::Token &T, const std::string &Algo);
 | 
							[[nodiscard]] std::string Sign(Poco::JWT::Token &T, const std::string &Algo);
 | 
				
			||||||
		void AddActivity(const std::string &Activity);
 | 
							void AddActivity(const std::string &Activity);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		static void SetConsoleLogs(bool UseAsync, bool AllowWebSocket,
 | 
					        static void SetConsoleLogs(bool UseAsync, bool AllowWebSocket, const std::string & FormatterPattern);
 | 
				
			||||||
								   const std::string &FormatterPattern);
 | 
					        static void SetColorConsoleLogs(bool UseAsync, bool AllowWebSocket, const std::string & FormatterPattern);
 | 
				
			||||||
		static void SetColorConsoleLogs(bool UseAsync, bool AllowWebSocket,
 | 
					        static void SetSQLLogs(bool UseAsync, bool AllowWebSocket, const std::string & FormatterPattern);
 | 
				
			||||||
										const std::string &FormatterPattern);
 | 
					        static void SetSyslogLogs(bool UseAsync, bool AllowWebSocket, const std::string & FormatterPattern);
 | 
				
			||||||
		static void SetSQLLogs(bool UseAsync, bool AllowWebSocket,
 | 
					        static void SetFileLogs(bool UseAsync, bool AllowWebSocket, const std::string & FormatterPattern, const std::string & root_env_var);
 | 
				
			||||||
							   const std::string &FormatterPattern);
 | 
					 | 
				
			||||||
		static void SetSyslogLogs(bool UseAsync, bool AllowWebSocket,
 | 
					 | 
				
			||||||
								  const std::string &FormatterPattern);
 | 
					 | 
				
			||||||
		static void SetFileLogs(bool UseAsync, bool AllowWebSocket,
 | 
					 | 
				
			||||||
								const std::string &FormatterPattern,
 | 
					 | 
				
			||||||
								const std::string &root_env_var);
 | 
					 | 
				
			||||||
        inline bool AllowExternalMicroServices() const { return AllowExternalMicroServices_; }
 | 
					        inline bool AllowExternalMicroServices() const { return AllowExternalMicroServices_; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	  private:
 | 
						  private:
 | 
				
			||||||
@@ -184,8 +182,7 @@ namespace OpenWifi {
 | 
				
			|||||||
		std::string 				MyPrivateEndPoint_;
 | 
							std::string 				MyPrivateEndPoint_;
 | 
				
			||||||
		std::string 				MyPublicEndPoint_;
 | 
							std::string 				MyPublicEndPoint_;
 | 
				
			||||||
		std::string                 UIURI_;
 | 
							std::string                 UIURI_;
 | 
				
			||||||
		std::string Version_{OW_VERSION::VERSION + "(" + OW_VERSION::BUILD + ")" + " - " +
 | 
							std::string 				Version_{ OW_VERSION::VERSION + "("+ OW_VERSION::BUILD + ")" + " - " + OW_VERSION::HASH };
 | 
				
			||||||
							 OW_VERSION::HASH};
 | 
					 | 
				
			||||||
		std::recursive_mutex		InfraMutex_;
 | 
							std::recursive_mutex		InfraMutex_;
 | 
				
			||||||
		std::default_random_engine  RandomEngine_;
 | 
							std::default_random_engine  RandomEngine_;
 | 
				
			||||||
        Poco::Util::PropertyFileConfiguration   * PropConfigurationFile_ = nullptr;
 | 
					        Poco::Util::PropertyFileConfiguration   * PropConfigurationFile_ = nullptr;
 | 
				
			||||||
@@ -206,4 +203,4 @@ namespace OpenWifi {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	inline MicroService * MicroService::instance_ = nullptr;
 | 
						inline MicroService * MicroService::instance_ = nullptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace OpenWifi
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,20 +4,21 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "fmt/format.h"
 | 
				
			||||||
 | 
					#include "Poco/Util/Application.h"
 | 
				
			||||||
#include "Poco/ErrorHandler.h"
 | 
					#include "Poco/ErrorHandler.h"
 | 
				
			||||||
#include "Poco/JSON/JSONException.h"
 | 
					 | 
				
			||||||
#include "Poco/JSON/Template.h"
 | 
					 | 
				
			||||||
#include "Poco/Net/NetException.h"
 | 
					#include "Poco/Net/NetException.h"
 | 
				
			||||||
#include "Poco/Net/SSLException.h"
 | 
					#include "Poco/Net/SSLException.h"
 | 
				
			||||||
 | 
					#include "Poco/JSON/Template.h"
 | 
				
			||||||
 | 
					#include "Poco/JSON/JSONException.h"
 | 
				
			||||||
#include "Poco/Thread.h"
 | 
					#include "Poco/Thread.h"
 | 
				
			||||||
#include "Poco/Util/Application.h"
 | 
					 | 
				
			||||||
#include "fmt/format.h"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	class MicroServiceErrorHandler : public Poco::ErrorHandler {
 | 
						class MicroServiceErrorHandler : public Poco::ErrorHandler {
 | 
				
			||||||
	  public:
 | 
						  public:
 | 
				
			||||||
		explicit MicroServiceErrorHandler(Poco::Util::Application &App) : App_(App) {}
 | 
							explicit MicroServiceErrorHandler(Poco::Util::Application &App) : App_(App) {
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline void exception(const Poco::Exception & Base) override {
 | 
							inline void exception(const Poco::Exception & Base) override {
 | 
				
			||||||
			try {
 | 
								try {
 | 
				
			||||||
@@ -33,134 +34,146 @@ namespace OpenWifi {
 | 
				
			|||||||
				Base.rethrow();
 | 
									Base.rethrow();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			} catch (const Poco::Net::InvalidCertificateException &E) {
 | 
								} catch (const Poco::Net::InvalidCertificateException &E) {
 | 
				
			||||||
				poco_error(App_.logger(),
 | 
									poco_error(App_.logger(), fmt::format("Poco::Net::InvalidCertificateException thr_name={} thr_id={} code={} text={} msg={} what={}",
 | 
				
			||||||
						   fmt::format("Poco::Net::InvalidCertificateException thr_name={} "
 | 
																		  t_name, t_id, E.code(),
 | 
				
			||||||
									   "thr_id={} code={} text={} msg={} what={}",
 | 
																		  E.displayText(),
 | 
				
			||||||
									   t_name, t_id, E.code(), E.displayText(), E.message(),
 | 
																		  E.message(),
 | 
				
			||||||
													  E.what()));
 | 
																		  E.what()));
 | 
				
			||||||
			} catch (const Poco::Net::InvalidSocketException &E) {
 | 
								} catch (const Poco::Net::InvalidSocketException &E) {
 | 
				
			||||||
				poco_error(App_.logger(),
 | 
									poco_error(App_.logger(), fmt::format("Poco::Net::InvalidSocketException thr_name={} thr_id={} code={} text={} msg={} what={}",
 | 
				
			||||||
						   fmt::format("Poco::Net::InvalidSocketException thr_name={} thr_id={} "
 | 
																		  t_name, t_id, E.code(),
 | 
				
			||||||
									   "code={} text={} msg={} what={}",
 | 
																		  E.displayText(),
 | 
				
			||||||
									   t_name, t_id, E.code(), E.displayText(), E.message(),
 | 
																		  E.message(),
 | 
				
			||||||
													  E.what()));
 | 
																		  E.what()));
 | 
				
			||||||
			} catch (const Poco::Net::WebSocketException &E) {
 | 
								} catch (const Poco::Net::WebSocketException &E) {
 | 
				
			||||||
				poco_error(App_.logger(), fmt::format("Poco::Net::WebSocketException thr_name={} "
 | 
									poco_error(App_.logger(), fmt::format("Poco::Net::WebSocketException thr_name={} thr_id={} code={} text={} msg={} what={}",
 | 
				
			||||||
													  "thr_id={} code={} text={} msg={} what={}",
 | 
																		  t_name, t_id, E.code(),
 | 
				
			||||||
													  t_name, t_id, E.code(), E.displayText(),
 | 
																		  E.displayText(),
 | 
				
			||||||
													  E.message(), E.what()));
 | 
																		  E.message(),
 | 
				
			||||||
 | 
																		  E.what()));
 | 
				
			||||||
			} catch (const Poco::Net::ConnectionResetException &E) {
 | 
								} catch (const Poco::Net::ConnectionResetException &E) {
 | 
				
			||||||
				poco_error(App_.logger(),
 | 
									poco_error(App_.logger(), fmt::format("Poco::Net::ConnectionResetException thr_name={} thr_id={} code={} text={} msg={} what={}",
 | 
				
			||||||
						   fmt::format("Poco::Net::ConnectionResetException thr_name={} thr_id={} "
 | 
																		  t_name, t_id, E.code(),
 | 
				
			||||||
									   "code={} text={} msg={} what={}",
 | 
																		  E.displayText(),
 | 
				
			||||||
									   t_name, t_id, E.code(), E.displayText(), E.message(),
 | 
																		  E.message(),
 | 
				
			||||||
													  E.what()));
 | 
																		  E.what()));
 | 
				
			||||||
			} catch (const Poco::Net::CertificateValidationException &E) {
 | 
								} catch (const Poco::Net::CertificateValidationException &E) {
 | 
				
			||||||
				poco_error(App_.logger(),
 | 
									poco_error(App_.logger(), fmt::format("Poco::Net::CertificateValidationException thr_name={} thr_id={} code={} text={} msg={} what={}",
 | 
				
			||||||
						   fmt::format("Poco::Net::CertificateValidationException thr_name={} "
 | 
																		  t_name, t_id, E.code(),
 | 
				
			||||||
									   "thr_id={} code={} text={} msg={} what={}",
 | 
																		  E.displayText(),
 | 
				
			||||||
									   t_name, t_id, E.code(), E.displayText(), E.message(),
 | 
																		  E.message(),
 | 
				
			||||||
													  E.what()));
 | 
																		  E.what()));
 | 
				
			||||||
			} catch (const Poco::Net::SSLConnectionUnexpectedlyClosedException &E) {
 | 
								} catch (const Poco::Net::SSLConnectionUnexpectedlyClosedException &E) {
 | 
				
			||||||
				poco_error(App_.logger(),
 | 
									poco_error(App_.logger(), fmt::format("Poco::Net::SSLConnectionUnexpectedlyClosedException thr_name={} thr_id={} code={} text={} msg={} what={}",
 | 
				
			||||||
						   fmt::format("Poco::Net::SSLConnectionUnexpectedlyClosedException "
 | 
																		  t_name, t_id, E.code(),
 | 
				
			||||||
									   "thr_name={} thr_id={} code={} text={} msg={} what={}",
 | 
																		  E.displayText(),
 | 
				
			||||||
									   t_name, t_id, E.code(), E.displayText(), E.message(),
 | 
																		  E.message(),
 | 
				
			||||||
													  E.what()));
 | 
																		  E.what()));
 | 
				
			||||||
			} catch (const Poco::Net::SSLContextException &E) {
 | 
								} catch (const Poco::Net::SSLContextException &E) {
 | 
				
			||||||
				poco_error(App_.logger(), fmt::format("Poco::Net::SSLContextException thr_name={} "
 | 
									poco_error(App_.logger(), fmt::format("Poco::Net::SSLContextException thr_name={} thr_id={} code={} text={} msg={} what={}",
 | 
				
			||||||
													  "thr_id={} code={} text={} msg={} what={}",
 | 
																		  t_name, t_id, E.code(),
 | 
				
			||||||
													  t_name, t_id, E.code(), E.displayText(),
 | 
																		  E.displayText(),
 | 
				
			||||||
													  E.message(), E.what()));
 | 
																		  E.message(),
 | 
				
			||||||
 | 
																		  E.what()));
 | 
				
			||||||
			} catch (const Poco::Net::SSLException &E) {
 | 
								} catch (const Poco::Net::SSLException &E) {
 | 
				
			||||||
				poco_error(App_.logger(), fmt::format("Poco::Net::SSLException thr_name={} "
 | 
									poco_error(App_.logger(), fmt::format("Poco::Net::SSLException thr_name={} thr_id={} code={} text={} msg={} what={}",
 | 
				
			||||||
													  "thr_id={} code={} text={} msg={} what={}",
 | 
																		  t_name, t_id, E.code(),
 | 
				
			||||||
													  t_name, t_id, E.code(), E.displayText(),
 | 
																		  E.displayText(),
 | 
				
			||||||
													  E.message(), E.what()));
 | 
																		  E.message(),
 | 
				
			||||||
 | 
																		  E.what()));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			} catch (const Poco::Net::InvalidAddressException &E) {
 | 
								} catch (const Poco::Net::InvalidAddressException &E) {
 | 
				
			||||||
				poco_error(App_.logger(),
 | 
									poco_error(App_.logger(), fmt::format("Poco::Net::InvalidAddressException thr_name={} thr_id={} code={} text={} msg={} what={}",
 | 
				
			||||||
						   fmt::format("Poco::Net::InvalidAddressException thr_name={} thr_id={} "
 | 
																		  t_name, t_id, E.code(),
 | 
				
			||||||
									   "code={} text={} msg={} what={}",
 | 
																		  E.displayText(),
 | 
				
			||||||
									   t_name, t_id, E.code(), E.displayText(), E.message(),
 | 
																		  E.message(),
 | 
				
			||||||
													  E.what()));
 | 
																		  E.what()));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			} catch (const Poco::Net::NetException &E) {
 | 
								} catch (const Poco::Net::NetException &E) {
 | 
				
			||||||
				poco_error(App_.logger(), fmt::format("Poco::Net::NetException thr_name={} "
 | 
									poco_error(App_.logger(), fmt::format("Poco::Net::NetException thr_name={} thr_id={} code={} text={} msg={} what={}",
 | 
				
			||||||
													  "thr_id={} code={} text={} msg={} what={}",
 | 
																		  t_name, t_id, E.code(),
 | 
				
			||||||
													  t_name, t_id, E.code(), E.displayText(),
 | 
																		  E.displayText(),
 | 
				
			||||||
													  E.message(), E.what()));
 | 
																		  E.message(),
 | 
				
			||||||
 | 
																		  E.what()));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			} catch (const Poco::IOException &E) {
 | 
								} catch (const Poco::IOException &E) {
 | 
				
			||||||
				poco_error(
 | 
									poco_error(App_.logger(), fmt::format("Poco::IOException thr_name={} thr_id={} code={} text={} msg={} what={}",
 | 
				
			||||||
					App_.logger(),
 | 
																		  t_name, t_id, E.code(),
 | 
				
			||||||
					fmt::format(
 | 
																		  E.displayText(),
 | 
				
			||||||
						"Poco::IOException thr_name={} thr_id={} code={} text={} msg={} what={}",
 | 
																		  E.message(),
 | 
				
			||||||
						t_name, t_id, E.code(), E.displayText(), E.message(), E.what()));
 | 
																		  E.what()));
 | 
				
			||||||
			} catch (const Poco::TimeoutException &E) {
 | 
								} catch (const Poco::TimeoutException &E) {
 | 
				
			||||||
				poco_error(App_.logger(), fmt::format("Poco::TimeoutException thr_name={} "
 | 
									poco_error(App_.logger(), fmt::format("Poco::TimeoutException thr_name={} thr_id={} code={} text={} msg={} what={}",
 | 
				
			||||||
													  "thr_id={} code={} text={} msg={} what={}",
 | 
																		  t_name, t_id, E.code(),
 | 
				
			||||||
													  t_name, t_id, E.code(), E.displayText(),
 | 
																		  E.displayText(),
 | 
				
			||||||
													  E.message(), E.what()));
 | 
																		  E.message(),
 | 
				
			||||||
 | 
																		  E.what()));
 | 
				
			||||||
			} catch (const Poco::NoThreadAvailableException &E) {
 | 
								} catch (const Poco::NoThreadAvailableException &E) {
 | 
				
			||||||
				poco_error(App_.logger(),
 | 
									poco_error(App_.logger(), fmt::format("Poco::NoThreadAvailableException thr_name={} thr_id={} code={} text={} msg={} what={}",
 | 
				
			||||||
						   fmt::format("Poco::NoThreadAvailableException thr_name={} thr_id={} "
 | 
																		  t_name, t_id, E.code(),
 | 
				
			||||||
									   "code={} text={} msg={} what={}",
 | 
																		  E.displayText(),
 | 
				
			||||||
									   t_name, t_id, E.code(), E.displayText(), E.message(),
 | 
																		  E.message(),
 | 
				
			||||||
													  E.what()));
 | 
																		  E.what()));
 | 
				
			||||||
			} catch (const Poco::OutOfMemoryException &E) {
 | 
								} catch (const Poco::OutOfMemoryException &E) {
 | 
				
			||||||
				poco_error(App_.logger(), fmt::format("Poco::OutOfMemoryException thr_name={} "
 | 
									poco_error(App_.logger(), fmt::format("Poco::OutOfMemoryException thr_name={} thr_id={} code={} text={} msg={} what={}",
 | 
				
			||||||
													  "thr_id={} code={} text={} msg={} what={}",
 | 
																		  t_name, t_id, E.code(),
 | 
				
			||||||
													  t_name, t_id, E.code(), E.displayText(),
 | 
																		  E.displayText(),
 | 
				
			||||||
													  E.message(), E.what()));
 | 
																		  E.message(),
 | 
				
			||||||
 | 
																		  E.what()));
 | 
				
			||||||
			} catch (const Poco::BadCastException &E) {
 | 
								} catch (const Poco::BadCastException &E) {
 | 
				
			||||||
				poco_error(App_.logger(), fmt::format("Poco::BadCastException thr_name={} "
 | 
									poco_error(App_.logger(), fmt::format("Poco::BadCastException thr_name={} thr_id={} code={} text={} msg={} what={}",
 | 
				
			||||||
													  "thr_id={} code={} text={} msg={} what={}",
 | 
																		  t_name, t_id, E.code(),
 | 
				
			||||||
													  t_name, t_id, E.code(), E.displayText(),
 | 
																		  E.displayText(),
 | 
				
			||||||
													  E.message(), E.what()));
 | 
																		  E.message(),
 | 
				
			||||||
 | 
																		  E.what()));
 | 
				
			||||||
			} catch (const Poco::DataException &E) {
 | 
								} catch (const Poco::DataException &E) {
 | 
				
			||||||
				poco_error(
 | 
									poco_error(App_.logger(), fmt::format("Poco::DataException thr_name={} thr_id={} code={} text={} msg={} what={}",
 | 
				
			||||||
					App_.logger(),
 | 
																		  t_name, t_id, E.code(),
 | 
				
			||||||
					fmt::format(
 | 
																		  E.displayText(),
 | 
				
			||||||
						"Poco::DataException thr_name={} thr_id={} code={} text={} msg={} what={}",
 | 
																		  E.message(),
 | 
				
			||||||
						t_name, t_id, E.code(), E.displayText(), E.message(), E.what()));
 | 
																		  E.what()));
 | 
				
			||||||
			} catch (const Poco::PoolOverflowException &E) {
 | 
								} catch (const Poco::PoolOverflowException &E) {
 | 
				
			||||||
				poco_error(App_.logger(), fmt::format("Poco::PoolOverflowException thr_name={} "
 | 
									poco_error(App_.logger(), fmt::format("Poco::PoolOverflowException thr_name={} thr_id={} code={} text={} msg={} what={}",
 | 
				
			||||||
													  "thr_id={} code={} text={} msg={} what={}",
 | 
																		  t_name, t_id, E.code(),
 | 
				
			||||||
													  t_name, t_id, E.code(), E.displayText(),
 | 
																		  E.displayText(),
 | 
				
			||||||
													  E.message(), E.what()));
 | 
																		  E.message(),
 | 
				
			||||||
 | 
																		  E.what()));
 | 
				
			||||||
			} catch (const Poco::SystemException &E) {
 | 
								} catch (const Poco::SystemException &E) {
 | 
				
			||||||
				poco_error(App_.logger(), fmt::format("Poco::SystemException thr_name={} thr_id={} "
 | 
									poco_error(App_.logger(), fmt::format("Poco::SystemException thr_name={} thr_id={} code={} text={} msg={} what={}",
 | 
				
			||||||
													  "code={} text={} msg={} what={}",
 | 
																		  t_name, t_id, E.code(),
 | 
				
			||||||
													  t_name, t_id, E.code(), E.displayText(),
 | 
																		  E.displayText(),
 | 
				
			||||||
													  E.message(), E.what()));
 | 
																		  E.message(),
 | 
				
			||||||
 | 
																		  E.what()));
 | 
				
			||||||
			} catch (const Poco::RuntimeException &E) {
 | 
								} catch (const Poco::RuntimeException &E) {
 | 
				
			||||||
				poco_error(App_.logger(), fmt::format("Poco::RuntimeException thr_name={} "
 | 
									poco_error(App_.logger(), fmt::format("Poco::RuntimeException thr_name={} thr_id={} code={} text={} msg={} what={}",
 | 
				
			||||||
													  "thr_id={} code={} text={} msg={} what={}",
 | 
																		  t_name, t_id, E.code(),
 | 
				
			||||||
													  t_name, t_id, E.code(), E.displayText(),
 | 
																		  E.displayText(),
 | 
				
			||||||
													  E.message(), E.what()));
 | 
																		  E.message(),
 | 
				
			||||||
 | 
																		  E.what()));
 | 
				
			||||||
			} catch (const Poco::JSON::JSONTemplateException &E) {
 | 
								} catch (const Poco::JSON::JSONTemplateException &E) {
 | 
				
			||||||
				poco_error(App_.logger(),
 | 
									poco_error(App_.logger(), fmt::format("Poco::JSON::JSONTemplateException thr_name={} thr_id={} code={} text={} msg={} what={}",
 | 
				
			||||||
						   fmt::format("Poco::JSON::JSONTemplateException thr_name={} thr_id={} "
 | 
																		  t_name, t_id, E.code(),
 | 
				
			||||||
									   "code={} text={} msg={} what={}",
 | 
																		  E.displayText(),
 | 
				
			||||||
									   t_name, t_id, E.code(), E.displayText(), E.message(),
 | 
																		  E.message(),
 | 
				
			||||||
													  E.what()));
 | 
																		  E.what()));
 | 
				
			||||||
			} catch (const Poco::JSON::JSONException &E) {
 | 
								} catch (const Poco::JSON::JSONException &E) {
 | 
				
			||||||
				poco_error(App_.logger(), fmt::format("Poco::JSON::JSONException thr_name={} "
 | 
									poco_error(App_.logger(), fmt::format("Poco::JSON::JSONException thr_name={} thr_id={} code={} text={} msg={} what={}",
 | 
				
			||||||
													  "thr_id={} code={} text={} msg={} what={}",
 | 
																		  t_name, t_id, E.code(),
 | 
				
			||||||
													  t_name, t_id, E.code(), E.displayText(),
 | 
																		  E.displayText(),
 | 
				
			||||||
													  E.message(), E.what()));
 | 
																		  E.message(),
 | 
				
			||||||
 | 
																		  E.what()));
 | 
				
			||||||
			} catch (const Poco::ApplicationException &E) {
 | 
								} catch (const Poco::ApplicationException &E) {
 | 
				
			||||||
				poco_error(App_.logger(), fmt::format("Poco::ApplicationException thr_name={} "
 | 
									poco_error(App_.logger(), fmt::format("Poco::ApplicationException thr_name={} thr_id={} code={} text={} msg={} what={}",
 | 
				
			||||||
													  "thr_id={} code={} text={} msg={} what={}",
 | 
																		  t_name, t_id, E.code(),
 | 
				
			||||||
													  t_name, t_id, E.code(), E.displayText(),
 | 
																		  E.displayText(),
 | 
				
			||||||
													  E.message(), E.what()));
 | 
																		  E.message(),
 | 
				
			||||||
 | 
																		  E.what()));
 | 
				
			||||||
			} catch (const Poco::Exception &E) {
 | 
								} catch (const Poco::Exception &E) {
 | 
				
			||||||
				poco_error(
 | 
									poco_error(App_.logger(), fmt::format("Poco::Exception thr_name={} thr_id={} code={} text={} msg={} what={}",
 | 
				
			||||||
					App_.logger(),
 | 
																		  t_name, t_id, E.code(),
 | 
				
			||||||
					fmt::format(
 | 
																		  E.displayText(),
 | 
				
			||||||
						"Poco::Exception thr_name={} thr_id={} code={} text={} msg={} what={}",
 | 
																		  E.message(),
 | 
				
			||||||
						t_name, t_id, E.code(), E.displayText(), E.message(), E.what()));
 | 
																		  E.what()));
 | 
				
			||||||
			} catch (...) {
 | 
								} catch (...) {
 | 
				
			||||||
				poco_error(App_.logger(), fmt::format("Poco:Generic thr_name={}",t_name, t_id));
 | 
									poco_error(App_.logger(), fmt::format("Poco:Generic thr_name={}",t_name, t_id));
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -174,8 +187,9 @@ namespace OpenWifi {
 | 
				
			|||||||
				t_name = "startup_code";
 | 
									t_name = "startup_code";
 | 
				
			||||||
				t_id = 0;
 | 
									t_id = 0;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			poco_warning(App_.logger(),
 | 
								poco_warning(App_.logger(), fmt::format("std::exception in {}: {} thr_id={}",
 | 
				
			||||||
						 fmt::format("std::exception in {}: {} thr_id={}", t_name, E.what(), t_id));
 | 
																		t_name,E.what(),
 | 
				
			||||||
 | 
																		t_id));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline void exception() override {
 | 
							inline void exception() override {
 | 
				
			||||||
@@ -186,14 +200,13 @@ namespace OpenWifi {
 | 
				
			|||||||
				t_name = "startup_code";
 | 
									t_name = "startup_code";
 | 
				
			||||||
				t_id = 0;
 | 
									t_id = 0;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			poco_warning(App_.logger(),
 | 
								poco_warning(App_.logger(), fmt::format("generic exception in {} thr_id={}",
 | 
				
			||||||
						 fmt::format("generic exception in {} thr_id={}", t_name, t_id));
 | 
																		t_name, t_id));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					 | 
				
			||||||
	  private:
 | 
						  private:
 | 
				
			||||||
		Poco::Util::Application	&App_;
 | 
							Poco::Util::Application	&App_;
 | 
				
			||||||
		std::string		t_name;
 | 
							std::string		t_name;
 | 
				
			||||||
		int 			t_id=0;
 | 
							int 			t_id=0;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace OpenWifi
 | 
					}
 | 
				
			||||||
@@ -4,8 +4,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <map>
 | 
					 | 
				
			||||||
#include <string>
 | 
					#include <string>
 | 
				
			||||||
 | 
					#include <map>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "Poco/BasicEvent.h"
 | 
					#include "Poco/BasicEvent.h"
 | 
				
			||||||
#include "Poco/ExpireLRUCache.h"
 | 
					#include "Poco/ExpireLRUCache.h"
 | 
				
			||||||
@@ -13,26 +13,27 @@
 | 
				
			|||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
	class ConfigurationEntry {
 | 
						class ConfigurationEntry {
 | 
				
			||||||
	  public:
 | 
						  public:
 | 
				
			||||||
		template <typename T> explicit ConfigurationEntry(T def) : Default_(def), Current_(def) {}
 | 
							template <typename T> explicit ConfigurationEntry(T def) :
 | 
				
			||||||
 | 
																 Default_(def),
 | 
				
			||||||
 | 
																 Current_(def){
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		template <typename T>
 | 
							template <typename T> explicit ConfigurationEntry(T def, T cur, const std::string  &Hint="") :
 | 
				
			||||||
		explicit ConfigurationEntry(T def, T cur, const std::string &Hint = "")
 | 
																									  Default_(def),
 | 
				
			||||||
			: Default_(def), Current_(cur), Hint_(Hint) {}
 | 
																									  Current_(cur),
 | 
				
			||||||
 | 
																									  Hint_(Hint){
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline ConfigurationEntry()=default;
 | 
							inline ConfigurationEntry()=default;
 | 
				
			||||||
		inline ~ConfigurationEntry()=default;
 | 
							inline ~ConfigurationEntry()=default;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		template <typename T> explicit operator T () const { return std::get<T>(Current_); }
 | 
							template <typename T> explicit operator T () const { return std::get<T>(Current_); }
 | 
				
			||||||
		inline ConfigurationEntry &operator=(const char *v) {
 | 
							inline ConfigurationEntry & operator=(const char *v) { Current_ = std::string(v); return *this;}
 | 
				
			||||||
			Current_ = std::string(v);
 | 
							template <typename T> ConfigurationEntry &  operator=(T v) { Current_ = (T) v; return *this;}
 | 
				
			||||||
			return *this;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		template <typename T> ConfigurationEntry &operator=(T v) {
 | 
					 | 
				
			||||||
			Current_ = (T)v;
 | 
					 | 
				
			||||||
			return *this;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		void reset() { Current_ = Default_; }
 | 
							void reset() {
 | 
				
			||||||
 | 
								Current_ = Default_;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	  private:
 | 
						  private:
 | 
				
			||||||
		std::variant<bool,uint64_t,std::string> Default_, Current_;
 | 
							std::variant<bool,uint64_t,std::string> Default_, Current_;
 | 
				
			||||||
@@ -44,9 +45,14 @@ namespace OpenWifi {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	template <typename T> class FIFO {
 | 
						template <typename T> class FIFO {
 | 
				
			||||||
	  public:
 | 
						  public:
 | 
				
			||||||
		explicit FIFO(uint32_t Size) : Size_(Size) { Buffer_ = new T[Size_]; }
 | 
							explicit FIFO(uint32_t Size) :
 | 
				
			||||||
 | 
														   Size_(Size) {
 | 
				
			||||||
 | 
								Buffer_ = new T [Size_];
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		~FIFO() { delete[] Buffer_; }
 | 
							~FIFO() {
 | 
				
			||||||
 | 
								delete [] Buffer_;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		mutable Poco::BasicEvent<bool> Writable_;
 | 
							mutable Poco::BasicEvent<bool> Writable_;
 | 
				
			||||||
		mutable Poco::BasicEvent<bool> Readable_;
 | 
							mutable Poco::BasicEvent<bool> Readable_;
 | 
				
			||||||
@@ -102,17 +108,25 @@ namespace OpenWifi {
 | 
				
			|||||||
		T	  					* Buffer_ = nullptr;
 | 
							T	  					* Buffer_ = nullptr;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	template <class Record, typename KeyType = std::string, int Size = 256, int Expiry = 60000>
 | 
						template <class Record, typename KeyType = std::string, int Size=256, int Expiry=60000> class RecordCache {
 | 
				
			||||||
	class RecordCache {
 | 
					 | 
				
			||||||
	  public:
 | 
						  public:
 | 
				
			||||||
		explicit RecordCache(KeyType Record::*Q) : MemberOffset(Q){};
 | 
							explicit RecordCache( KeyType Record::* Q) :
 | 
				
			||||||
		inline auto update(const Record &R) { return Cache_.update(R.*MemberOffset, R); }
 | 
																	   MemberOffset(Q){
 | 
				
			||||||
		inline auto get(const KeyType &K) { return Cache_.get(K); }
 | 
																	   };
 | 
				
			||||||
		inline auto remove(const KeyType &K) { return Cache_.remove(K); }
 | 
							inline auto update(const Record &R) {
 | 
				
			||||||
		inline auto remove(const Record &R) { return Cache_.remove(R.*MemberOffset); }
 | 
								return Cache_.update(R.*MemberOffset, R);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							inline auto get(const KeyType &K) {
 | 
				
			||||||
 | 
								return Cache_.get(K);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							inline auto remove(const KeyType &K) {
 | 
				
			||||||
 | 
								return Cache_.remove(K);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							inline auto remove(const Record &R) {
 | 
				
			||||||
 | 
								return Cache_.remove(R.*MemberOffset);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	  private:
 | 
						  private:
 | 
				
			||||||
		KeyType Record::* MemberOffset;
 | 
							KeyType Record::* MemberOffset;
 | 
				
			||||||
		Poco::ExpireLRUCache<KeyType,Record>  Cache_{Size,Expiry};
 | 
							Poco::ExpireLRUCache<KeyType,Record>  Cache_{Size,Expiry};
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
} // namespace OpenWifi
 | 
					}
 | 
				
			||||||
@@ -2,8 +2,8 @@
 | 
				
			|||||||
// Created by stephane bourque on 2022-10-25.
 | 
					// Created by stephane bourque on 2022-10-25.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "framework/MicroServiceFuncs.h"
 | 
					 | 
				
			||||||
#include "framework/MicroService.h"
 | 
					#include "framework/MicroService.h"
 | 
				
			||||||
 | 
					#include "framework/MicroServiceFuncs.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
    const std::string &MicroServiceDataDirectory() { return MicroService::instance().DataDir(); }
 | 
					    const std::string &MicroServiceDataDirectory() { return MicroService::instance().DataDir(); }
 | 
				
			||||||
@@ -18,8 +18,7 @@ namespace OpenWifi {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    std::string MicroServicePublicEndPoint() { return MicroService::instance().PublicEndPoint(); }
 | 
					    std::string MicroServicePublicEndPoint() { return MicroService::instance().PublicEndPoint(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	std::string MicroServiceConfigGetString(const std::string &Key,
 | 
					    std::string MicroServiceConfigGetString(const std::string &Key, const std::string &DefaultValue) {
 | 
				
			||||||
											const std::string &DefaultValue) {
 | 
					 | 
				
			||||||
        return MicroService::instance().ConfigGetString(Key, DefaultValue);
 | 
					        return MicroService::instance().ConfigGetString(Key, DefaultValue);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -47,17 +46,15 @@ namespace OpenWifi {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    void MicroServiceReload(const std::string &Type) { MicroService::instance().Reload(Type); }
 | 
					    void MicroServiceReload(const std::string &Type) { MicroService::instance().Reload(Type); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Types::StringVec MicroServiceGetLogLevelNames() {
 | 
					    const Types::StringVec MicroServiceGetLogLevelNames() {
 | 
				
			||||||
        return MicroService::instance().GetLogLevelNames();
 | 
					        return MicroService::instance().GetLogLevelNames();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Types::StringVec MicroServiceGetSubSystems() {
 | 
					    const Types::StringVec MicroServiceGetSubSystems() {
 | 
				
			||||||
        return MicroService::instance().GetSubSystems();
 | 
					        return MicroService::instance().GetSubSystems();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Types::StringPairVec MicroServiceGetLogLevels() {
 | 
					    Types::StringPairVec MicroServiceGetLogLevels() { return MicroService::instance().GetLogLevels(); }
 | 
				
			||||||
		return MicroService::instance().GetLogLevels();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bool MicroServiceSetSubsystemLogLevel(const std::string &SubSystem, const std::string &Level) {
 | 
					    bool MicroServiceSetSubsystemLogLevel(const std::string &SubSystem, const std::string &Level) {
 | 
				
			||||||
        return MicroService::instance().SetSubsystemLogLevel(SubSystem, Level);
 | 
					        return MicroService::instance().SetSubsystemLogLevel(SubSystem, Level);
 | 
				
			||||||
@@ -79,7 +76,7 @@ namespace OpenWifi {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    std::string MicroServiceGetUIURI() { return MicroService::instance().GetUIURI(); }
 | 
					    std::string MicroServiceGetUIURI() { return MicroService::instance().GetUIURI(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	SubSystemVec MicroServiceGetFullSubSystems() {
 | 
					    const SubSystemVec MicroServiceGetFullSubSystems() {
 | 
				
			||||||
        return MicroService::instance().GetFullSubSystems();
 | 
					        return MicroService::instance().GetFullSubSystems();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -87,17 +84,20 @@ namespace OpenWifi {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    std::uint64_t MicroServiceDaemonBusTimer() { return MicroService::instance().DaemonBusTimer(); }
 | 
					    std::uint64_t MicroServiceDaemonBusTimer() { return MicroService::instance().DaemonBusTimer(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	std::string MicroServiceMakeSystemEventMessage(const char *Type) {
 | 
					    std::string MicroServiceMakeSystemEventMessage(const std::string &Type) {
 | 
				
			||||||
        return MicroService::instance().MakeSystemEventMessage(Type);
 | 
					        return MicroService::instance().MakeSystemEventMessage(Type);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Poco::ThreadPool &MicroServiceTimerPool() { return MicroService::instance().TimerPool(); }
 | 
					    Poco::ThreadPool &MicroServiceTimerPool() { return MicroService::instance().TimerPool(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	std::string MicroServiceConfigPath(const std::string &Key, const std::string &DefaultValue) {
 | 
					    std::string MicroServiceConfigPath(const std::string &Key,
 | 
				
			||||||
 | 
					                                       const std::string &DefaultValue) {
 | 
				
			||||||
        return MicroService::instance().ConfigPath(Key, DefaultValue);
 | 
					        return MicroService::instance().ConfigPath(Key, DefaultValue);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	std::string MicroServiceWWWAssetsDir() { return MicroService::instance().WWWAssetsDir(); }
 | 
					    std::string MicroServiceWWWAssetsDir() {
 | 
				
			||||||
 | 
					        return MicroService::instance().WWWAssetsDir();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    std::uint64_t MicroServiceRandom(std::uint64_t Start,std::uint64_t End) {
 | 
					    std::uint64_t MicroServiceRandom(std::uint64_t Start,std::uint64_t End) {
 | 
				
			||||||
        return MicroService::instance().Random(Start, End);
 | 
					        return MicroService::instance().Random(Start, End);
 | 
				
			||||||
@@ -123,4 +123,4 @@ namespace OpenWifi {
 | 
				
			|||||||
        return MicroService::instance().AllowExternalMicroServices();
 | 
					        return MicroService::instance().AllowExternalMicroServices();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace OpenWifi
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,10 +8,11 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "framework/OpenWifiTypes.h"
 | 
					#include "framework/OpenWifiTypes.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "Poco/JSON/Object.h"
 | 
					 | 
				
			||||||
#include "Poco/JWT/Token.h"
 | 
					 | 
				
			||||||
#include "Poco/Net/HTTPServerRequest.h"
 | 
					#include "Poco/Net/HTTPServerRequest.h"
 | 
				
			||||||
 | 
					#include "Poco/JSON/Object.h"
 | 
				
			||||||
#include "Poco/ThreadPool.h"
 | 
					#include "Poco/ThreadPool.h"
 | 
				
			||||||
 | 
					#include "Poco/JWT/Token.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
	class SubSystemServer;
 | 
						class SubSystemServer;
 | 
				
			||||||
@@ -20,8 +21,7 @@ namespace OpenWifi {
 | 
				
			|||||||
	Types::MicroServiceMetaVec MicroServiceGetServices(const std::string & Type);
 | 
						Types::MicroServiceMetaVec MicroServiceGetServices(const std::string & Type);
 | 
				
			||||||
    Types::MicroServiceMetaVec MicroServiceGetServices();
 | 
					    Types::MicroServiceMetaVec MicroServiceGetServices();
 | 
				
			||||||
	std::string MicroServicePublicEndPoint();
 | 
						std::string MicroServicePublicEndPoint();
 | 
				
			||||||
	std::string MicroServiceConfigGetString(const std::string &Key,
 | 
						std::string MicroServiceConfigGetString(const std::string &Key, const std::string &DefaultValue);
 | 
				
			||||||
											const std::string &DefaultValue);
 | 
					 | 
				
			||||||
	bool MicroServiceConfigGetBool(const std::string &Key, bool DefaultValue);
 | 
						bool MicroServiceConfigGetBool(const std::string &Key, bool DefaultValue);
 | 
				
			||||||
	std::uint64_t MicroServiceConfigGetInt(const std::string &Key, std::uint64_t DefaultValue);
 | 
						std::uint64_t MicroServiceConfigGetInt(const std::string &Key, std::uint64_t DefaultValue);
 | 
				
			||||||
	std::string MicroServicePrivateEndPoint();
 | 
						std::string MicroServicePrivateEndPoint();
 | 
				
			||||||
@@ -31,8 +31,8 @@ namespace OpenWifi {
 | 
				
			|||||||
	void MicroServiceLoadConfigurationFile();
 | 
						void MicroServiceLoadConfigurationFile();
 | 
				
			||||||
	void MicroServiceReload();
 | 
						void MicroServiceReload();
 | 
				
			||||||
	void MicroServiceReload(const std::string &Type);
 | 
						void MicroServiceReload(const std::string &Type);
 | 
				
			||||||
	Types::StringVec MicroServiceGetLogLevelNames();
 | 
						const Types::StringVec MicroServiceGetLogLevelNames();
 | 
				
			||||||
	Types::StringVec MicroServiceGetSubSystems();
 | 
						const Types::StringVec MicroServiceGetSubSystems();
 | 
				
			||||||
	Types::StringPairVec MicroServiceGetLogLevels();
 | 
						Types::StringPairVec MicroServiceGetLogLevels();
 | 
				
			||||||
	bool MicroServiceSetSubsystemLogLevel(const std::string &SubSystem, const std::string &Level);
 | 
						bool MicroServiceSetSubsystemLogLevel(const std::string &SubSystem, const std::string &Level);
 | 
				
			||||||
	void MicroServiceGetExtraConfiguration(Poco::JSON::Object &Answer);
 | 
						void MicroServiceGetExtraConfiguration(Poco::JSON::Object &Answer);
 | 
				
			||||||
@@ -40,12 +40,13 @@ namespace OpenWifi {
 | 
				
			|||||||
	std::uint64_t MicroServiceUptimeTotalSeconds();
 | 
						std::uint64_t MicroServiceUptimeTotalSeconds();
 | 
				
			||||||
	std::uint64_t MicroServiceStartTimeEpochTime();
 | 
						std::uint64_t MicroServiceStartTimeEpochTime();
 | 
				
			||||||
	std::string MicroServiceGetUIURI();
 | 
						std::string MicroServiceGetUIURI();
 | 
				
			||||||
	SubSystemVec MicroServiceGetFullSubSystems();
 | 
						const SubSystemVec MicroServiceGetFullSubSystems();
 | 
				
			||||||
	std::string MicroServiceCreateUUID();
 | 
						std::string MicroServiceCreateUUID();
 | 
				
			||||||
	std::uint64_t MicroServiceDaemonBusTimer();
 | 
						std::uint64_t MicroServiceDaemonBusTimer();
 | 
				
			||||||
	std::string MicroServiceMakeSystemEventMessage(const char *Type);
 | 
						std::string MicroServiceMakeSystemEventMessage( const std::string & Type );
 | 
				
			||||||
	Poco::ThreadPool & MicroServiceTimerPool();
 | 
						Poco::ThreadPool & MicroServiceTimerPool();
 | 
				
			||||||
	std::string MicroServiceConfigPath(const std::string &Key, const std::string &DefaultValue);
 | 
						std::string MicroServiceConfigPath(const std::string &Key,
 | 
				
			||||||
 | 
														   const std::string &DefaultValue);
 | 
				
			||||||
    std::string MicroServiceWWWAssetsDir();
 | 
					    std::string MicroServiceWWWAssetsDir();
 | 
				
			||||||
    std::uint64_t MicroServiceRandom(std::uint64_t Start,std::uint64_t End);
 | 
					    std::uint64_t MicroServiceRandom(std::uint64_t Start,std::uint64_t End);
 | 
				
			||||||
    std::uint64_t MicroServiceRandom(std::uint64_t Range);
 | 
					    std::uint64_t MicroServiceRandom(std::uint64_t Range);
 | 
				
			||||||
@@ -53,4 +54,4 @@ namespace OpenWifi {
 | 
				
			|||||||
    std::string MicroServiceGetPublicAPIEndPoint();
 | 
					    std::string MicroServiceGetPublicAPIEndPoint();
 | 
				
			||||||
	void MicroServiceDeleteOverrideConfiguration();
 | 
						void MicroServiceDeleteOverrideConfiguration();
 | 
				
			||||||
    bool AllowExternalMicroServices();
 | 
					    bool AllowExternalMicroServices();
 | 
				
			||||||
} // namespace OpenWifi
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,4 +19,4 @@ namespace OpenWifi {
 | 
				
			|||||||
	static const std::string uSERVICE_ANALYTICS{ "owanalytics"};
 | 
						static const std::string uSERVICE_ANALYTICS{ "owanalytics"};
 | 
				
			||||||
	static const std::string uSERVICE_OWRRM{ "owrrm"};
 | 
						static const std::string uSERVICE_OWRRM{ "owrrm"};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace OpenWifi
 | 
					}
 | 
				
			||||||
@@ -4,19 +4,18 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "OpenAPIRequests.h"
 | 
					#include "OpenAPIRequests.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "Poco/JSON/Parser.h"
 | 
					 | 
				
			||||||
#include "Poco/Logger.h"
 | 
					#include "Poco/Logger.h"
 | 
				
			||||||
 | 
					#include "Poco/URI.h"
 | 
				
			||||||
#include "Poco/Net/HTTPRequest.h"
 | 
					#include "Poco/Net/HTTPRequest.h"
 | 
				
			||||||
#include "Poco/Net/HTTPSClientSession.h"
 | 
					#include "Poco/Net/HTTPSClientSession.h"
 | 
				
			||||||
#include "Poco/URI.h"
 | 
					#include "Poco/JSON/Parser.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "fmt/format.h"
 | 
					#include "fmt/format.h"
 | 
				
			||||||
#include "framework/MicroServiceFuncs.h"
 | 
					#include "framework/MicroServiceFuncs.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Poco::Net::HTTPServerResponse::HTTPStatus
 | 
						Poco::Net::HTTPServerResponse::HTTPStatus OpenAPIRequestGet::Do(Poco::JSON::Object::Ptr &ResponseObject, const std::string & BearerToken) {
 | 
				
			||||||
	OpenAPIRequestGet::Do(Poco::JSON::Object::Ptr &ResponseObject, const std::string &BearerToken) {
 | 
					 | 
				
			||||||
	try {
 | 
						try {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		auto Services = MicroServiceGetServices(Type_);
 | 
							auto Services = MicroServiceGetServices(Type_);
 | 
				
			||||||
@@ -30,11 +29,11 @@ namespace OpenWifi {
 | 
				
			|||||||
				URI.addQueryParameter(qp.first, qp.second);
 | 
									URI.addQueryParameter(qp.first, qp.second);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			std::string Path(URI.getPathAndQuery());
 | 
								std::string Path(URI.getPathAndQuery());
 | 
				
			||||||
				Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_GET, Path,
 | 
								Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_GET,
 | 
				
			||||||
 | 
															   Path,
 | 
				
			||||||
										   Poco::Net::HTTPMessage::HTTP_1_1);
 | 
															   Poco::Net::HTTPMessage::HTTP_1_1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				poco_debug(Poco::Logger::get("REST-CALLER-GET"),
 | 
								poco_debug(Poco::Logger::get("REST-CALLER-GET"), fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_ ) );
 | 
				
			||||||
						   fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if(BearerToken.empty()) {
 | 
								if(BearerToken.empty()) {
 | 
				
			||||||
				Request.add("X-API-KEY", Svc.AccessKey);
 | 
									Request.add("X-API-KEY", Svc.AccessKey);
 | 
				
			||||||
@@ -72,14 +71,15 @@ namespace OpenWifi {
 | 
				
			|||||||
				return Response.getStatus();
 | 
									return Response.getStatus();
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		} catch (const Poco::Exception &E) {
 | 
						}
 | 
				
			||||||
 | 
						catch (const Poco::Exception &E)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
		Poco::Logger::get("REST-CALLER-GET").log(E);
 | 
							Poco::Logger::get("REST-CALLER-GET").log(E);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT;
 | 
						return Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Poco::Net::HTTPServerResponse::HTTPStatus
 | 
						Poco::Net::HTTPServerResponse::HTTPStatus OpenAPIRequestPut::Do(Poco::JSON::Object::Ptr &ResponseObject, const std::string & BearerToken) {
 | 
				
			||||||
	OpenAPIRequestPut::Do(Poco::JSON::Object::Ptr &ResponseObject, const std::string &BearerToken) {
 | 
					 | 
				
			||||||
	try {
 | 
						try {
 | 
				
			||||||
		auto Services = MicroServiceGetServices(Type_);
 | 
							auto Services = MicroServiceGetServices(Type_);
 | 
				
			||||||
		for(auto const &Svc:Services) {
 | 
							for(auto const &Svc:Services) {
 | 
				
			||||||
@@ -91,12 +91,12 @@ namespace OpenWifi {
 | 
				
			|||||||
			for (const auto &qp : QueryData_)
 | 
								for (const auto &qp : QueryData_)
 | 
				
			||||||
				URI.addQueryParameter(qp.first, qp.second);
 | 
									URI.addQueryParameter(qp.first, qp.second);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				poco_debug(Poco::Logger::get("REST-CALLER-PUT"),
 | 
								poco_debug(Poco::Logger::get("REST-CALLER-PUT"), fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_ ) );
 | 
				
			||||||
						   fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			std::string Path(URI.getPathAndQuery());
 | 
								std::string Path(URI.getPathAndQuery());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_PUT, Path,
 | 
								Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_PUT,
 | 
				
			||||||
 | 
															   Path,
 | 
				
			||||||
										   Poco::Net::HTTPMessage::HTTP_1_1);
 | 
															   Poco::Net::HTTPMessage::HTTP_1_1);
 | 
				
			||||||
			std::ostringstream obody;
 | 
								std::ostringstream obody;
 | 
				
			||||||
			Poco::JSON::Stringifier::stringify(Body_,obody);
 | 
								Poco::JSON::Stringifier::stringify(Body_,obody);
 | 
				
			||||||
@@ -148,33 +148,34 @@ namespace OpenWifi {
 | 
				
			|||||||
				return Response.getStatus();
 | 
									return Response.getStatus();
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		} catch (const Poco::Exception &E) {
 | 
						}
 | 
				
			||||||
 | 
						catch (const Poco::Exception &E)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
		Poco::Logger::get("REST-CALLER-PUT").log(E);
 | 
							Poco::Logger::get("REST-CALLER-PUT").log(E);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT;
 | 
						return Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Poco::Net::HTTPServerResponse::HTTPStatus
 | 
						Poco::Net::HTTPServerResponse::HTTPStatus OpenAPIRequestPost::Do(Poco::JSON::Object::Ptr &ResponseObject, const std::string & BearerToken) {
 | 
				
			||||||
	OpenAPIRequestPost::Do(Poco::JSON::Object::Ptr &ResponseObject,
 | 
					 | 
				
			||||||
						   const std::string &BearerToken) {
 | 
					 | 
				
			||||||
	try {
 | 
						try {
 | 
				
			||||||
		auto Services = MicroServiceGetServices(Type_);
 | 
							auto Services = MicroServiceGetServices(Type_);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for(auto const &Svc:Services) {
 | 
							for(auto const &Svc:Services) {
 | 
				
			||||||
			Poco::URI	URI(Svc.PrivateEndPoint);
 | 
								Poco::URI	URI(Svc.PrivateEndPoint);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			auto Secure = (URI.getScheme() == "https");
 | 
								auto Secure = (URI.getScheme() == "https");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			URI.setPath(EndPoint_);
 | 
								URI.setPath(EndPoint_);
 | 
				
			||||||
			for (const auto &qp : QueryData_)
 | 
								for (const auto &qp : QueryData_)
 | 
				
			||||||
				URI.addQueryParameter(qp.first, qp.second);
 | 
									URI.addQueryParameter(qp.first, qp.second);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				poco_debug(Poco::Logger::get("REST-CALLER-POST"),
 | 
								poco_debug(Poco::Logger::get("REST-CALLER-POST"),fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_ ) );
 | 
				
			||||||
						   fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			std::string Path(URI.getPathAndQuery());
 | 
								std::string Path(URI.getPathAndQuery());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_POST, Path,
 | 
								Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_POST,
 | 
				
			||||||
 | 
															   Path,
 | 
				
			||||||
										   Poco::Net::HTTPMessage::HTTP_1_1);
 | 
															   Poco::Net::HTTPMessage::HTTP_1_1);
 | 
				
			||||||
			std::ostringstream obody;
 | 
								std::ostringstream obody;
 | 
				
			||||||
			Poco::JSON::Stringifier::stringify(Body_,obody);
 | 
								Poco::JSON::Stringifier::stringify(Body_,obody);
 | 
				
			||||||
@@ -224,14 +225,15 @@ namespace OpenWifi {
 | 
				
			|||||||
				return Response.getStatus();
 | 
									return Response.getStatus();
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		} catch (const Poco::Exception &E) {
 | 
						}
 | 
				
			||||||
 | 
						catch (const Poco::Exception &E)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
		Poco::Logger::get("REST-CALLER-POST").log(E);
 | 
							Poco::Logger::get("REST-CALLER-POST").log(E);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT;
 | 
						return Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Poco::Net::HTTPServerResponse::HTTPStatus
 | 
						Poco::Net::HTTPServerResponse::HTTPStatus OpenAPIRequestDelete::Do(const std::string & BearerToken) {
 | 
				
			||||||
	OpenAPIRequestDelete::Do(const std::string &BearerToken) {
 | 
					 | 
				
			||||||
	try {
 | 
						try {
 | 
				
			||||||
		auto Services = MicroServiceGetServices(Type_);
 | 
							auto Services = MicroServiceGetServices(Type_);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -244,12 +246,12 @@ namespace OpenWifi {
 | 
				
			|||||||
			for (const auto &qp : QueryData_)
 | 
								for (const auto &qp : QueryData_)
 | 
				
			||||||
				URI.addQueryParameter(qp.first, qp.second);
 | 
									URI.addQueryParameter(qp.first, qp.second);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				poco_debug(Poco::Logger::get("REST-CALLER-DELETE"),
 | 
								poco_debug(Poco::Logger::get("REST-CALLER-DELETE"),fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_ ) );
 | 
				
			||||||
						   fmt::format(" {}", LoggingStr_.empty() ? URI.toString() : LoggingStr_));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			std::string Path(URI.getPathAndQuery());
 | 
								std::string Path(URI.getPathAndQuery());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_DELETE, Path,
 | 
								Poco::Net::HTTPRequest Request(Poco::Net::HTTPRequest::HTTP_DELETE,
 | 
				
			||||||
 | 
															   Path,
 | 
				
			||||||
										   Poco::Net::HTTPMessage::HTTP_1_1);
 | 
															   Poco::Net::HTTPMessage::HTTP_1_1);
 | 
				
			||||||
			if(BearerToken.empty()) {
 | 
								if(BearerToken.empty()) {
 | 
				
			||||||
				Request.add("X-API-KEY", Svc.AccessKey);
 | 
									Request.add("X-API-KEY", Svc.AccessKey);
 | 
				
			||||||
@@ -275,10 +277,13 @@ namespace OpenWifi {
 | 
				
			|||||||
				return Response.getStatus();
 | 
									return Response.getStatus();
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		} catch (const Poco::Exception &E) {
 | 
						}
 | 
				
			||||||
 | 
						catch (const Poco::Exception &E)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
		Poco::Logger::get("REST-CALLER-DELETE").log(E);
 | 
							Poco::Logger::get("REST-CALLER-DELETE").log(E);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT;
 | 
						return Poco::Net::HTTPServerResponse::HTTP_GATEWAY_TIMEOUT;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace OpenWifi
 | 
					} // namespace OpenWifi
 | 
				
			||||||
@@ -15,14 +15,17 @@ namespace OpenWifi {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	class OpenAPIRequestGet {
 | 
						class OpenAPIRequestGet {
 | 
				
			||||||
	  public:
 | 
						  public:
 | 
				
			||||||
		explicit OpenAPIRequestGet(const std::string &Type, const std::string &EndPoint,
 | 
							explicit OpenAPIRequestGet( const std::string & Type,
 | 
				
			||||||
								   const Types::StringPairVec &QueryData, uint64_t msTimeout,
 | 
													   const std::string & EndPoint,
 | 
				
			||||||
								   const std::string &LoggingStr = "")
 | 
													   const Types::StringPairVec & QueryData,
 | 
				
			||||||
			: Type_(Type), EndPoint_(EndPoint), QueryData_(QueryData), msTimeout_(msTimeout),
 | 
													   uint64_t msTimeout,
 | 
				
			||||||
 | 
					                                   const std::string &LoggingStr=""):
 | 
				
			||||||
 | 
																			 Type_(Type),
 | 
				
			||||||
 | 
																			 EndPoint_(EndPoint),
 | 
				
			||||||
 | 
																			 QueryData_(QueryData),
 | 
				
			||||||
 | 
																			 msTimeout_(msTimeout),
 | 
				
			||||||
                                                         LoggingStr_(LoggingStr){};
 | 
					                                                         LoggingStr_(LoggingStr){};
 | 
				
			||||||
		Poco::Net::HTTPServerResponse::HTTPStatus Do(Poco::JSON::Object::Ptr &ResponseObject,
 | 
							Poco::Net::HTTPServerResponse::HTTPStatus Do(Poco::JSON::Object::Ptr &ResponseObject, const std::string & BearerToken = "");
 | 
				
			||||||
													 const std::string &BearerToken = "");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	  private:
 | 
						  private:
 | 
				
			||||||
		std::string 			Type_;
 | 
							std::string 			Type_;
 | 
				
			||||||
		std::string 			EndPoint_;
 | 
							std::string 			EndPoint_;
 | 
				
			||||||
@@ -33,15 +36,20 @@ namespace OpenWifi {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	class OpenAPIRequestPut {
 | 
						class OpenAPIRequestPut {
 | 
				
			||||||
	  public:
 | 
						  public:
 | 
				
			||||||
		explicit OpenAPIRequestPut(const std::string &Type, const std::string &EndPoint,
 | 
							explicit OpenAPIRequestPut( const std::string & Type,
 | 
				
			||||||
 | 
													   const std::string & EndPoint,
 | 
				
			||||||
								   const Types::StringPairVec & QueryData,
 | 
													   const Types::StringPairVec & QueryData,
 | 
				
			||||||
								   const Poco::JSON::Object &Body, uint64_t msTimeout,
 | 
													   const Poco::JSON::Object & Body,
 | 
				
			||||||
								   const std::string &LoggingStr = "")
 | 
													   uint64_t msTimeout,
 | 
				
			||||||
			: Type_(Type), EndPoint_(EndPoint), QueryData_(QueryData), msTimeout_(msTimeout),
 | 
					                                   const std::string &LoggingStr=""):
 | 
				
			||||||
			  Body_(Body), LoggingStr_(LoggingStr){};
 | 
																			 Type_(Type),
 | 
				
			||||||
 | 
																			 EndPoint_(EndPoint),
 | 
				
			||||||
 | 
																			 QueryData_(QueryData),
 | 
				
			||||||
 | 
																			 msTimeout_(msTimeout),
 | 
				
			||||||
 | 
																			 Body_(Body),
 | 
				
			||||||
 | 
					                                                         LoggingStr_(LoggingStr){};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Poco::Net::HTTPServerResponse::HTTPStatus Do(Poco::JSON::Object::Ptr &ResponseObject,
 | 
							Poco::Net::HTTPServerResponse::HTTPStatus Do(Poco::JSON::Object::Ptr &ResponseObject, const std::string & BearerToken = "");
 | 
				
			||||||
													 const std::string &BearerToken = "");
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	  private:
 | 
						  private:
 | 
				
			||||||
		std::string 			Type_;
 | 
							std::string 			Type_;
 | 
				
			||||||
@@ -54,15 +62,19 @@ namespace OpenWifi {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	class OpenAPIRequestPost {
 | 
						class OpenAPIRequestPost {
 | 
				
			||||||
	  public:
 | 
						  public:
 | 
				
			||||||
		explicit OpenAPIRequestPost(const std::string &Type, const std::string &EndPoint,
 | 
							explicit OpenAPIRequestPost( const std::string & Type,
 | 
				
			||||||
 | 
														const std::string & EndPoint,
 | 
				
			||||||
									const Types::StringPairVec & QueryData,
 | 
														const Types::StringPairVec & QueryData,
 | 
				
			||||||
									const Poco::JSON::Object &Body, uint64_t msTimeout,
 | 
														const Poco::JSON::Object & Body,
 | 
				
			||||||
									const std::string &LoggingStr = "")
 | 
														uint64_t msTimeout,
 | 
				
			||||||
			: Type_(Type), EndPoint_(EndPoint), QueryData_(QueryData), msTimeout_(msTimeout),
 | 
					                                   const std::string &LoggingStr=""):
 | 
				
			||||||
			  Body_(Body), LoggingStr_(LoggingStr){};
 | 
																			  Type_(Type),
 | 
				
			||||||
		Poco::Net::HTTPServerResponse::HTTPStatus Do(Poco::JSON::Object::Ptr &ResponseObject,
 | 
																			  EndPoint_(EndPoint),
 | 
				
			||||||
													 const std::string &BearerToken = "");
 | 
																			  QueryData_(QueryData),
 | 
				
			||||||
 | 
																			  msTimeout_(msTimeout),
 | 
				
			||||||
 | 
																			  Body_(Body),
 | 
				
			||||||
 | 
					                                                         LoggingStr_(LoggingStr){};
 | 
				
			||||||
 | 
							Poco::Net::HTTPServerResponse::HTTPStatus Do(Poco::JSON::Object::Ptr &ResponseObject, const std::string & BearerToken = "");
 | 
				
			||||||
	  private:
 | 
						  private:
 | 
				
			||||||
		std::string 			Type_;
 | 
							std::string 			Type_;
 | 
				
			||||||
		std::string 			EndPoint_;
 | 
							std::string 			EndPoint_;
 | 
				
			||||||
@@ -74,10 +86,15 @@ namespace OpenWifi {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	class OpenAPIRequestDelete {
 | 
						class OpenAPIRequestDelete {
 | 
				
			||||||
	  public:
 | 
						  public:
 | 
				
			||||||
		explicit OpenAPIRequestDelete(const std::string &Type, const std::string &EndPoint,
 | 
							explicit OpenAPIRequestDelete(  const std::string & Type,
 | 
				
			||||||
									  const Types::StringPairVec &QueryData, uint64_t msTimeout,
 | 
														    const std::string & EndPoint,
 | 
				
			||||||
									  const std::string &LoggingStr = "")
 | 
														    const Types::StringPairVec & QueryData,
 | 
				
			||||||
			: Type_(Type), EndPoint_(EndPoint), QueryData_(QueryData), msTimeout_(msTimeout),
 | 
														    uint64_t msTimeout,
 | 
				
			||||||
 | 
					                                        const std::string &LoggingStr=""):
 | 
				
			||||||
 | 
					                                            Type_(Type),
 | 
				
			||||||
 | 
					                                            EndPoint_(EndPoint),
 | 
				
			||||||
 | 
					                                            QueryData_(QueryData),
 | 
				
			||||||
 | 
					                                            msTimeout_(msTimeout),
 | 
				
			||||||
                                            LoggingStr_(LoggingStr){};
 | 
					                                            LoggingStr_(LoggingStr){};
 | 
				
			||||||
		Poco::Net::HTTPServerResponse::HTTPStatus Do(const std::string & BearerToken = "");
 | 
							Poco::Net::HTTPServerResponse::HTTPStatus Do(const std::string & BearerToken = "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,14 +4,14 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <functional>
 | 
					 | 
				
			||||||
#include <list>
 | 
					 | 
				
			||||||
#include <map>
 | 
					#include <map>
 | 
				
			||||||
#include <queue>
 | 
					 | 
				
			||||||
#include <set>
 | 
					 | 
				
			||||||
#include <string>
 | 
					 | 
				
			||||||
#include <utility>
 | 
					#include <utility>
 | 
				
			||||||
#include <vector>
 | 
					#include <vector>
 | 
				
			||||||
 | 
					#include <functional>
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
 | 
					#include <queue>
 | 
				
			||||||
 | 
					#include <list>
 | 
				
			||||||
 | 
					#include <set>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi::Types {
 | 
					namespace OpenWifi::Types {
 | 
				
			||||||
    typedef std::pair<std::string,std::string>                  StringPair;
 | 
					    typedef std::pair<std::string,std::string>                  StringPair;
 | 
				
			||||||
@@ -41,12 +41,11 @@ namespace OpenWifi::Types {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	typedef std::map<std::string, MicroServiceMeta>				MicroServiceMetaMap;
 | 
						typedef std::map<std::string, MicroServiceMeta>				MicroServiceMetaMap;
 | 
				
			||||||
	typedef std::vector<MicroServiceMeta>						MicroServiceMetaVec;
 | 
						typedef std::vector<MicroServiceMeta>						MicroServiceMetaVec;
 | 
				
			||||||
} // namespace OpenWifi::Types
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline void UpdateCountedMap(OpenWifi::Types::CountedMap &M, const std::string &S,
 | 
					    inline void UpdateCountedMap(OpenWifi::Types::CountedMap &M, const std::string &S, uint64_t Increment=1) {
 | 
				
			||||||
								 uint64_t Increment = 1) {
 | 
					 | 
				
			||||||
        auto it = M.find(S);
 | 
					        auto it = M.find(S);
 | 
				
			||||||
        if(it==M.end())
 | 
					        if(it==M.end())
 | 
				
			||||||
            M[S] = Increment;
 | 
					            M[S] = Increment;
 | 
				
			||||||
@@ -54,14 +53,14 @@ namespace OpenWifi {
 | 
				
			|||||||
            it->second += Increment;
 | 
					            it->second += Increment;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline void UpdateCountedMap(OpenWifi::Types::Counted3DMapSII &M, const std::string &S,
 | 
					    inline void UpdateCountedMap(OpenWifi::Types::Counted3DMapSII &M, const std::string &S, uint32_t Index, uint64_t Increment=1) {
 | 
				
			||||||
								 uint32_t Index, uint64_t Increment = 1) {
 | 
					 | 
				
			||||||
        auto it = M.find(S);
 | 
					        auto it = M.find(S);
 | 
				
			||||||
        if(it==M.end()) {
 | 
					        if(it==M.end()) {
 | 
				
			||||||
            std::map<uint32_t,uint64_t> E;
 | 
					            std::map<uint32_t,uint64_t> E;
 | 
				
			||||||
            E[Index] = Increment;
 | 
					            E[Index] = Increment;
 | 
				
			||||||
            M[S] = E;
 | 
					            M[S] = E;
 | 
				
			||||||
		} else {
 | 
					        }
 | 
				
			||||||
 | 
					        else {
 | 
				
			||||||
            std::map<uint32_t,uint64_t> & IndexMap = it->second;
 | 
					            std::map<uint32_t,uint64_t> & IndexMap = it->second;
 | 
				
			||||||
            auto it_index = IndexMap.find(Index);
 | 
					            auto it_index = IndexMap.find(Index);
 | 
				
			||||||
            if(it_index == IndexMap.end()) {
 | 
					            if(it_index == IndexMap.end()) {
 | 
				
			||||||
@@ -71,4 +70,4 @@ namespace OpenWifi {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
} // namespace OpenWifi
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,23 +6,22 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Poco::Net::HTTPRequestHandler *
 | 
						Poco::Net::HTTPRequestHandler *ExtRequestHandlerFactory::createRequestHandler(const Poco::Net::HTTPServerRequest &Request) {
 | 
				
			||||||
	ExtRequestHandlerFactory::createRequestHandler(const Poco::Net::HTTPServerRequest &Request) {
 | 
					 | 
				
			||||||
		try {
 | 
							try {
 | 
				
			||||||
			Poco::URI uri(Request.getURI());
 | 
								Poco::URI uri(Request.getURI());
 | 
				
			||||||
			auto TID = NextTransactionId_++;
 | 
								auto TID = NextTransactionId_++;
 | 
				
			||||||
			Utils::SetThreadName(fmt::format("x-rest:{}",TID).c_str());
 | 
								Utils::SetThreadName(fmt::format("x-rest:{}",TID).c_str());
 | 
				
			||||||
			return RESTAPI_ExtServer()->CallServer(uri.getPath(), TID);
 | 
								return RESTAPI_ExtServer()->CallServer(uri.getPath(), TID);
 | 
				
			||||||
		} catch (...) {
 | 
							} catch (...) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return nullptr;
 | 
							return nullptr;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Poco::Net::HTTPRequestHandler *RESTAPI_ExtServer::CallServer(const std::string &Path,
 | 
						Poco::Net::HTTPRequestHandler *RESTAPI_ExtServer::CallServer(const std::string &Path, uint64_t Id) {
 | 
				
			||||||
																 uint64_t Id) {
 | 
					 | 
				
			||||||
		RESTAPIHandler::BindingMap Bindings;
 | 
							RESTAPIHandler::BindingMap Bindings;
 | 
				
			||||||
		Utils::SetThreadName(fmt::format("x-rest:{}",Id).c_str());
 | 
							Utils::SetThreadName(fmt::format("x-rest:{}",Id).c_str());
 | 
				
			||||||
		return RESTAPI_ExtRouter(Path, Bindings, Logger(), Server_, Id);
 | 
							return RESTAPI_ExtRouter(Path, Bindings, Logger(), Server_, Id);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace OpenWifi
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,21 +6,18 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "Poco/Net/HTTPServer.h"
 | 
					#include "Poco/Net/HTTPServer.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "framework/RESTAPI_Handler.h"
 | 
					 | 
				
			||||||
#include "framework/SubSystemServer.h"
 | 
					#include "framework/SubSystemServer.h"
 | 
				
			||||||
 | 
					#include "framework/RESTAPI_Handler.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Poco::Net::HTTPRequestHandler *
 | 
						Poco::Net::HTTPRequestHandler * RESTAPI_ExtRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings,
 | 
				
			||||||
	RESTAPI_ExtRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings,
 | 
					 | 
				
			||||||
													 Poco::Logger & L, RESTAPI_GenericServerAccounting & S, uint64_t Id);
 | 
																		 Poco::Logger & L, RESTAPI_GenericServerAccounting & S, uint64_t Id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	class ExtRequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
 | 
						class ExtRequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
 | 
				
			||||||
	  public:
 | 
						  public:
 | 
				
			||||||
		ExtRequestHandlerFactory() = default;
 | 
							ExtRequestHandlerFactory() = default;
 | 
				
			||||||
		Poco::Net::HTTPRequestHandler *
 | 
							Poco::Net::HTTPRequestHandler *createRequestHandler(const Poco::Net::HTTPServerRequest &Request) override;
 | 
				
			||||||
		createRequestHandler(const Poco::Net::HTTPServerRequest &Request) override;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	  private:
 | 
						  private:
 | 
				
			||||||
		static inline std::atomic_uint64_t  NextTransactionId_ = 1;
 | 
							static inline std::atomic_uint64_t  NextTransactionId_ = 1;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
@@ -39,15 +36,10 @@ namespace OpenWifi {
 | 
				
			|||||||
			for(const auto & Svr: ConfigServersList_) {
 | 
								for(const auto & Svr: ConfigServersList_) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if(MicroServiceNoAPISecurity()) {
 | 
									if(MicroServiceNoAPISecurity()) {
 | 
				
			||||||
					poco_information(
 | 
										poco_information(Logger(),fmt::format("Starting: {}:{}. Security has been disabled for APIs.", Svr.Address(), Svr.Port()));
 | 
				
			||||||
						Logger(),
 | 
					 | 
				
			||||||
						fmt::format("Starting: {}:{}. Security has been disabled for APIs.",
 | 
					 | 
				
			||||||
									Svr.Address(), Svr.Port()));
 | 
					 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					poco_information(Logger(),
 | 
										poco_information(Logger(),fmt::format("Starting: {}:{} Keyfile:{} CertFile: {}", Svr.Address(), Svr.Port(),
 | 
				
			||||||
									 fmt::format("Starting: {}:{} Keyfile:{} CertFile: {}",
 | 
																		 Svr.KeyFile(),Svr.CertFile()));
 | 
				
			||||||
												 Svr.Address(), Svr.Port(), Svr.KeyFile(),
 | 
					 | 
				
			||||||
												 Svr.CertFile()));
 | 
					 | 
				
			||||||
					Svr.LogCert(Logger());
 | 
										Svr.LogCert(Logger());
 | 
				
			||||||
					if (!Svr.RootCA().empty())
 | 
										if (!Svr.RootCA().empty())
 | 
				
			||||||
						Svr.LogCas(Logger());
 | 
											Svr.LogCas(Logger());
 | 
				
			||||||
@@ -60,12 +52,10 @@ namespace OpenWifi {
 | 
				
			|||||||
				std::unique_ptr<Poco::Net::HTTPServer>  NewServer;
 | 
									std::unique_ptr<Poco::Net::HTTPServer>  NewServer;
 | 
				
			||||||
				if(MicroServiceNoAPISecurity()) {
 | 
									if(MicroServiceNoAPISecurity()) {
 | 
				
			||||||
					auto Sock{Svr.CreateSocket(Logger())};
 | 
										auto Sock{Svr.CreateSocket(Logger())};
 | 
				
			||||||
					NewServer = std::make_unique<Poco::Net::HTTPServer>(
 | 
										NewServer = std::make_unique<Poco::Net::HTTPServer>(new ExtRequestHandlerFactory, Pool_, Sock, Params);
 | 
				
			||||||
						new ExtRequestHandlerFactory, Pool_, Sock, Params);
 | 
					 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					auto Sock{Svr.CreateSecureSocket(Logger())};
 | 
										auto Sock{Svr.CreateSecureSocket(Logger())};
 | 
				
			||||||
					NewServer = std::make_unique<Poco::Net::HTTPServer>(
 | 
										NewServer = std::make_unique<Poco::Net::HTTPServer>(new ExtRequestHandlerFactory, Pool_, Sock, Params);
 | 
				
			||||||
						new ExtRequestHandlerFactory, Pool_, Sock, Params);
 | 
					 | 
				
			||||||
				};
 | 
									};
 | 
				
			||||||
				NewServer->start();
 | 
									NewServer->start();
 | 
				
			||||||
				RESTServers_.push_back(std::move(NewServer));
 | 
									RESTServers_.push_back(std::move(NewServer));
 | 
				
			||||||
@@ -98,10 +88,12 @@ namespace OpenWifi {
 | 
				
			|||||||
		Poco::ThreadPool	    Pool_{"x-rest",8,128};
 | 
							Poco::ThreadPool	    Pool_{"x-rest",8,128};
 | 
				
			||||||
		RESTAPI_GenericServerAccounting   Server_;
 | 
							RESTAPI_GenericServerAccounting   Server_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		RESTAPI_ExtServer() noexcept
 | 
							RESTAPI_ExtServer() noexcept:
 | 
				
			||||||
			: SubSystemServer("RESTAPI_ExtServer", "REST-XSRV", "openwifi.restapi") {}
 | 
														   SubSystemServer("RESTAPI_ExtServer", "REST-XSRV", "openwifi.restapi")
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline auto RESTAPI_ExtServer() { return RESTAPI_ExtServer::instance(); };
 | 
						inline auto RESTAPI_ExtServer() { return RESTAPI_ExtServer::instance(); };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace OpenWifi
 | 
					}
 | 
				
			||||||
@@ -4,19 +4,25 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <array>
 | 
					 | 
				
			||||||
#include <string>
 | 
					#include <string>
 | 
				
			||||||
 | 
					#include <array>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "Poco/Net/HTTPRequest.h"
 | 
					 | 
				
			||||||
#include "Poco/String.h"
 | 
					 | 
				
			||||||
#include "Poco/StringTokenizer.h"
 | 
					#include "Poco/StringTokenizer.h"
 | 
				
			||||||
 | 
					#include "Poco/String.h"
 | 
				
			||||||
 | 
					#include "Poco/Net/HTTPRequest.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "framework/MicroServiceFuncs.h"
 | 
					#include "framework/MicroServiceFuncs.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
	class RESTAPI_GenericServerAccounting {
 | 
						class RESTAPI_GenericServerAccounting {
 | 
				
			||||||
	  public:
 | 
						  public:
 | 
				
			||||||
		enum { LOG_GET = 0, LOG_DELETE, LOG_PUT, LOG_POST };
 | 
					
 | 
				
			||||||
 | 
							enum {
 | 
				
			||||||
 | 
								LOG_GET=0,
 | 
				
			||||||
 | 
								LOG_DELETE,
 | 
				
			||||||
 | 
								LOG_PUT,
 | 
				
			||||||
 | 
								LOG_POST
 | 
				
			||||||
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		void inline SetFlags(bool External, const std::string &Methods) {
 | 
							void inline SetFlags(bool External, const std::string &Methods) {
 | 
				
			||||||
			Poco::StringTokenizer   Tokens(Methods,",");
 | 
								Poco::StringTokenizer   Tokens(Methods,",");
 | 
				
			||||||
@@ -34,18 +40,14 @@ namespace OpenWifi {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline void InitLogging() {
 | 
							inline void InitLogging() {
 | 
				
			||||||
			std::string Public =
 | 
								std::string Public = MicroServiceConfigGetString("apilogging.public.methods","PUT,POST,DELETE");
 | 
				
			||||||
				MicroServiceConfigGetString("apilogging.public.methods", "PUT,POST,DELETE");
 | 
					 | 
				
			||||||
			SetFlags(true, Public);
 | 
								SetFlags(true, Public);
 | 
				
			||||||
			std::string Private =
 | 
								std::string Private = MicroServiceConfigGetString("apilogging.private.methods","PUT,POST,DELETE");
 | 
				
			||||||
				MicroServiceConfigGetString("apilogging.private.methods", "PUT,POST,DELETE");
 | 
					 | 
				
			||||||
			SetFlags(false, Private);
 | 
								SetFlags(false, Private);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			std::string PublicBadTokens =
 | 
								std::string PublicBadTokens = MicroServiceConfigGetString("apilogging.public.badtokens.methods","");
 | 
				
			||||||
				MicroServiceConfigGetString("apilogging.public.badtokens.methods", "");
 | 
					 | 
				
			||||||
			LogBadTokens_[0] = (Poco::icompare(PublicBadTokens,"true")==0);
 | 
								LogBadTokens_[0] = (Poco::icompare(PublicBadTokens,"true")==0);
 | 
				
			||||||
			std::string PrivateBadTokens =
 | 
								std::string PrivateBadTokens = MicroServiceConfigGetString("apilogging.private.badtokens.methods","");
 | 
				
			||||||
				MicroServiceConfigGetString("apilogging.private.badtokens.methods", "");
 | 
					 | 
				
			||||||
			LogBadTokens_[1] = (Poco::icompare(PrivateBadTokens,"true")==0);
 | 
								LogBadTokens_[1] = (Poco::icompare(PrivateBadTokens,"true")==0);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -70,4 +72,4 @@ namespace OpenWifi {
 | 
				
			|||||||
		std::array<bool,8>       LogFlags_{false};
 | 
							std::array<bool,8>       LogFlags_{false};
 | 
				
			||||||
		std::array<bool,2>       LogBadTokens_{false};
 | 
							std::array<bool,2>       LogBadTokens_{false};
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
} // namespace OpenWifi
 | 
					}
 | 
				
			||||||
@@ -4,4 +4,5 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "RESTAPI_Handler.h"
 | 
					#include "RESTAPI_Handler.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {} // namespace OpenWifi
 | 
					namespace OpenWifi {
 | 
				
			||||||
 | 
					} // namespace OpenWifi
 | 
				
			||||||
@@ -4,27 +4,27 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <map>
 | 
					 | 
				
			||||||
#include <string>
 | 
					#include <string>
 | 
				
			||||||
#include <vector>
 | 
					#include <vector>
 | 
				
			||||||
 | 
					#include <map>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "Poco/DeflatingStream.h"
 | 
					#include "Poco/Net/HTTPRequestHandler.h"
 | 
				
			||||||
 | 
					#include "Poco/Logger.h"
 | 
				
			||||||
#include "Poco/JSON/Object.h"
 | 
					#include "Poco/JSON/Object.h"
 | 
				
			||||||
#include "Poco/JSON/Parser.h"
 | 
					#include "Poco/JSON/Parser.h"
 | 
				
			||||||
#include "Poco/Logger.h"
 | 
					 | 
				
			||||||
#include "Poco/Net/HTTPRequestHandler.h"
 | 
					 | 
				
			||||||
#include "Poco/Net/HTTPResponse.h"
 | 
					#include "Poco/Net/HTTPResponse.h"
 | 
				
			||||||
#include "Poco/Net/HTTPServerResponse.h"
 | 
					#include "Poco/Net/HTTPServerResponse.h"
 | 
				
			||||||
#include "Poco/Net/OAuth20Credentials.h"
 | 
					#include "Poco/DeflatingStream.h"
 | 
				
			||||||
#include "Poco/TemporaryFile.h"
 | 
					#include "Poco/TemporaryFile.h"
 | 
				
			||||||
 | 
					#include "Poco/Net/OAuth20Credentials.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "RESTObjects/RESTAPI_SecurityObjects.h"
 | 
					#include "framework/ow_constants.h"
 | 
				
			||||||
#include "framework/AuthClient.h"
 | 
					 | 
				
			||||||
#include "framework/RESTAPI_GenericServerAccounting.h"
 | 
					#include "framework/RESTAPI_GenericServerAccounting.h"
 | 
				
			||||||
#include "framework/RESTAPI_RateLimiter.h"
 | 
					#include "framework/RESTAPI_RateLimiter.h"
 | 
				
			||||||
#include "framework/RESTAPI_utils.h"
 | 
					 | 
				
			||||||
#include "framework/ow_constants.h"
 | 
					 | 
				
			||||||
#include "framework/utils.h"
 | 
					#include "framework/utils.h"
 | 
				
			||||||
 | 
					#include "framework/RESTAPI_utils.h"
 | 
				
			||||||
 | 
					#include "framework/AuthClient.h"
 | 
				
			||||||
 | 
					#include "RESTObjects/RESTAPI_SecurityObjects.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(TIP_SECURITY_SERVICE)
 | 
					#if defined(TIP_SECURITY_SERVICE)
 | 
				
			||||||
#include "AuthService.h"
 | 
					#include "AuthService.h"
 | 
				
			||||||
@@ -40,8 +40,7 @@ namespace OpenWifi {
 | 
				
			|||||||
			uint64_t StartDate = 0 , EndDate = 0 , Offset = 0 , Limit = 0, LogType = 0 ;
 | 
								uint64_t StartDate = 0 , EndDate = 0 , Offset = 0 , Limit = 0, LogType = 0 ;
 | 
				
			||||||
			std::string SerialNumber, Filter;
 | 
								std::string SerialNumber, Filter;
 | 
				
			||||||
			std::vector<std::string>    Select;
 | 
								std::vector<std::string>    Select;
 | 
				
			||||||
			bool Lifetime = false, LastOnly = false, Newest = false, CountOnly = false,
 | 
								bool Lifetime=false, LastOnly=false, Newest=false, CountOnly=false, AdditionalInfo=false;
 | 
				
			||||||
				 AdditionalInfo = false;
 | 
					 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
		typedef std::map<std::string, std::string> BindingMap;
 | 
							typedef std::map<std::string, std::string> BindingMap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -50,19 +49,30 @@ namespace OpenWifi {
 | 
				
			|||||||
			int64_t     MaxCalls=10;
 | 
								int64_t     MaxCalls=10;
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		RESTAPIHandler(BindingMap map, Poco::Logger &l, std::vector<std::string> Methods,
 | 
							RESTAPIHandler( BindingMap map,
 | 
				
			||||||
					   RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId,
 | 
										   Poco::Logger &l,
 | 
				
			||||||
					   bool Internal, bool AlwaysAuthorize = true, bool RateLimited = false,
 | 
										   std::vector<std::string> Methods,
 | 
				
			||||||
 | 
										   RESTAPI_GenericServerAccounting & Server,
 | 
				
			||||||
 | 
										   uint64_t TransactionId,
 | 
				
			||||||
 | 
										   bool Internal,
 | 
				
			||||||
 | 
										   bool AlwaysAuthorize=true,
 | 
				
			||||||
 | 
										   bool RateLimited=false,
 | 
				
			||||||
					   const RateLimit & Profile = RateLimit{.Interval=1000,.MaxCalls=100},
 | 
										   const RateLimit & Profile = RateLimit{.Interval=1000,.MaxCalls=100},
 | 
				
			||||||
					   bool SubscriberOnly=false)
 | 
										   bool SubscriberOnly=false)
 | 
				
			||||||
			: Bindings_(std::move(map)), Logger_(l), Methods_(std::move(Methods)),
 | 
								:   Bindings_(std::move(map)),
 | 
				
			||||||
			  Internal_(Internal), RateLimited_(RateLimited), SubOnlyService_(SubscriberOnly),
 | 
								  Logger_(l),
 | 
				
			||||||
			  AlwaysAuthorize_(AlwaysAuthorize), Server_(Server), MyRates_(Profile),
 | 
								  Methods_(std::move(Methods)),
 | 
				
			||||||
			  TransactionId_(TransactionId) {}
 | 
								  Internal_(Internal),
 | 
				
			||||||
 | 
								  RateLimited_(RateLimited),
 | 
				
			||||||
 | 
								  SubOnlyService_(SubscriberOnly),
 | 
				
			||||||
 | 
								  AlwaysAuthorize_(AlwaysAuthorize),
 | 
				
			||||||
 | 
								  Server_(Server),
 | 
				
			||||||
 | 
								  MyRates_(Profile),
 | 
				
			||||||
 | 
								  TransactionId_(TransactionId)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline bool RoleIsAuthorized([[maybe_unused]] const std::string &Path,
 | 
							inline bool RoleIsAuthorized([[maybe_unused]] const std::string & Path, [[maybe_unused]] const std::string & Method, [[maybe_unused]] std::string & Reason) {
 | 
				
			||||||
									 [[maybe_unused]] const std::string &Method,
 | 
					 | 
				
			||||||
									 [[maybe_unused]] std::string &Reason) {
 | 
					 | 
				
			||||||
			return true;
 | 
								return true;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -77,13 +87,11 @@ namespace OpenWifi {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
				if(Request->getContentLength()>0) {
 | 
									if(Request->getContentLength()>0) {
 | 
				
			||||||
					if(Request->getContentType().find("application/json")!=std::string::npos) {
 | 
										if(Request->getContentType().find("application/json")!=std::string::npos) {
 | 
				
			||||||
						ParsedBody_ = IncomingParser_.parse(Request->stream())
 | 
											ParsedBody_ = IncomingParser_.parse(Request->stream()).extract<Poco::JSON::Object::Ptr>();
 | 
				
			||||||
										  .extract<Poco::JSON::Object::Ptr>();
 | 
					 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if (RateLimited_ && RESTAPI_RateLimiter()->IsRateLimited(
 | 
									if(RateLimited_ && RESTAPI_RateLimiter()->IsRateLimited(RequestIn,MyRates_.Interval, MyRates_.MaxCalls)) {
 | 
				
			||||||
										RequestIn, MyRates_.Interval, MyRates_.MaxCalls)) {
 | 
					 | 
				
			||||||
					return UnAuthorized(RESTAPI::Errors::RATE_LIMIT_EXCEEDED);
 | 
										return UnAuthorized(RESTAPI::Errors::RATE_LIMIT_EXCEEDED);
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -122,13 +130,9 @@ namespace OpenWifi {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[[nodiscard]] inline bool NeedAdditionalInfo() const { return QB_.AdditionalInfo; }
 | 
							[[nodiscard]] inline bool NeedAdditionalInfo() const { return QB_.AdditionalInfo; }
 | 
				
			||||||
		[[nodiscard]] inline const std::vector<std::string> &SelectedRecords() const {
 | 
							[[nodiscard]] inline const std::vector<std::string> & SelectedRecords() const { return QB_.Select; }
 | 
				
			||||||
			return QB_.Select;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline static bool ParseBindings(const std::string &Request,
 | 
							inline static bool ParseBindings(const std::string & Request, const std::list<std::string> & EndPoints, BindingMap &bindings) {
 | 
				
			||||||
										 const std::list<std::string> &EndPoints,
 | 
					 | 
				
			||||||
										 BindingMap &bindings) {
 | 
					 | 
				
			||||||
			bindings.clear();
 | 
								bindings.clear();
 | 
				
			||||||
			auto PathItems = Poco::StringTokenizer(Request, "/");
 | 
								auto PathItems = Poco::StringTokenizer(Request, "/");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -176,39 +180,29 @@ namespace OpenWifi {
 | 
				
			|||||||
			return false;
 | 
								return false;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[[nodiscard]] inline uint64_t GetParameter(const std::string &Name,
 | 
							[[nodiscard]] inline uint64_t GetParameter(const std::string &Name, const uint64_t Default) {
 | 
				
			||||||
												   const uint64_t Default) {
 | 
								auto Hint = std::find_if(Parameters_.begin(),Parameters_.end(),[&](const std::pair<std::string,std::string> &S){ return S.first==Name; });
 | 
				
			||||||
			auto Hint = std::find_if(
 | 
					 | 
				
			||||||
				Parameters_.begin(), Parameters_.end(),
 | 
					 | 
				
			||||||
				[&](const std::pair<std::string, std::string> &S) { return S.first == Name; });
 | 
					 | 
				
			||||||
			if(Hint==Parameters_.end() || !is_number(Hint->second))
 | 
								if(Hint==Parameters_.end() || !is_number(Hint->second))
 | 
				
			||||||
				return Default;
 | 
									return Default;
 | 
				
			||||||
			return std::stoull(Hint->second);
 | 
								return std::stoull(Hint->second);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[[nodiscard]] inline bool GetBoolParameter(const std::string &Name, bool Default=false) {
 | 
							[[nodiscard]] inline bool GetBoolParameter(const std::string &Name, bool Default=false) {
 | 
				
			||||||
			auto Hint = std::find_if(
 | 
								auto Hint = std::find_if(begin(Parameters_),end(Parameters_),[&](const std::pair<std::string,std::string> &S){ return S.first==Name; });
 | 
				
			||||||
				begin(Parameters_), end(Parameters_),
 | 
					 | 
				
			||||||
				[&](const std::pair<std::string, std::string> &S) { return S.first == Name; });
 | 
					 | 
				
			||||||
			if(Hint==end(Parameters_) || !is_bool(Hint->second))
 | 
								if(Hint==end(Parameters_) || !is_bool(Hint->second))
 | 
				
			||||||
				return Default;
 | 
									return Default;
 | 
				
			||||||
			return Hint->second=="true";
 | 
								return Hint->second=="true";
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[[nodiscard]] inline std::string GetParameter(const std::string &Name,
 | 
							[[nodiscard]] inline std::string GetParameter(const std::string &Name, const std::string &Default="") {
 | 
				
			||||||
													  const std::string &Default = "") {
 | 
								auto Hint = std::find_if(begin(Parameters_),end(Parameters_),[&](const std::pair<std::string,std::string> &S){ return S.first==Name; });
 | 
				
			||||||
			auto Hint = std::find_if(
 | 
					 | 
				
			||||||
				begin(Parameters_), end(Parameters_),
 | 
					 | 
				
			||||||
				[&](const std::pair<std::string, std::string> &S) { return S.first == Name; });
 | 
					 | 
				
			||||||
			if(Hint==end(Parameters_))
 | 
								if(Hint==end(Parameters_))
 | 
				
			||||||
				return Default;
 | 
									return Default;
 | 
				
			||||||
			return Hint->second;
 | 
								return Hint->second;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[[nodiscard]] inline bool HasParameter(const std::string &Name, std::string &Value) {
 | 
							[[nodiscard]] inline bool HasParameter(const std::string &Name, std::string &Value) {
 | 
				
			||||||
			auto Hint = std::find_if(
 | 
								auto Hint = std::find_if(begin(Parameters_),end(Parameters_),[&](const std::pair<std::string,std::string> &S){ return S.first==Name; });
 | 
				
			||||||
				begin(Parameters_), end(Parameters_),
 | 
					 | 
				
			||||||
				[&](const std::pair<std::string, std::string> &S) { return S.first == Name; });
 | 
					 | 
				
			||||||
			if(Hint==end(Parameters_))
 | 
								if(Hint==end(Parameters_))
 | 
				
			||||||
				return false;
 | 
									return false;
 | 
				
			||||||
			Value = Hint->second;
 | 
								Value = Hint->second;
 | 
				
			||||||
@@ -216,17 +210,14 @@ namespace OpenWifi {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[[nodiscard]] inline bool HasParameter(const std::string &Name, uint64_t & Value) {
 | 
							[[nodiscard]] inline bool HasParameter(const std::string &Name, uint64_t & Value) {
 | 
				
			||||||
			auto Hint = std::find_if(
 | 
								auto Hint = std::find_if(begin(Parameters_),end(Parameters_),[&](const std::pair<std::string,std::string> &S){ return S.first==Name; });
 | 
				
			||||||
				begin(Parameters_), end(Parameters_),
 | 
					 | 
				
			||||||
				[&](const std::pair<std::string, std::string> &S) { return S.first == Name; });
 | 
					 | 
				
			||||||
			if(Hint==end(Parameters_))
 | 
								if(Hint==end(Parameters_))
 | 
				
			||||||
				return false;
 | 
									return false;
 | 
				
			||||||
			Value = std::stoull(Hint->second);
 | 
								Value = std::stoull(Hint->second);
 | 
				
			||||||
			return true;
 | 
								return true;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[[nodiscard]] inline const std::string &GetBinding(const std::string &Name,
 | 
							[[nodiscard]] inline const std::string & GetBinding(const std::string &Name, const std::string &Default="") {
 | 
				
			||||||
														   const std::string &Default = "") {
 | 
					 | 
				
			||||||
			auto E = Bindings_.find(Poco::toLower(Name));
 | 
								auto E = Bindings_.find(Poco::toLower(Name));
 | 
				
			||||||
			if (E == Bindings_.end())
 | 
								if (E == Bindings_.end())
 | 
				
			||||||
				return Default;
 | 
									return Default;
 | 
				
			||||||
@@ -245,8 +236,7 @@ namespace OpenWifi {
 | 
				
			|||||||
			return Return;
 | 
								return Return;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O,
 | 
							static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O, const std::string &Field, Types::UUIDvec_t & Value) {
 | 
				
			||||||
										   const std::string &Field, Types::UUIDvec_t &Value) {
 | 
					 | 
				
			||||||
			if(O->has(Field) && O->isArray(Field)) {
 | 
								if(O->has(Field) && O->isArray(Field)) {
 | 
				
			||||||
				auto Arr = O->getArray(Field);
 | 
									auto Arr = O->getArray(Field);
 | 
				
			||||||
				for(const auto &i:*Arr)
 | 
									for(const auto &i:*Arr)
 | 
				
			||||||
@@ -256,8 +246,7 @@ namespace OpenWifi {
 | 
				
			|||||||
			return false;
 | 
								return false;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O,
 | 
							static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O, const std::string &Field, std::string &Value) {
 | 
				
			||||||
										   const std::string &Field, std::string &Value) {
 | 
					 | 
				
			||||||
			if(O->has(Field)) {
 | 
								if(O->has(Field)) {
 | 
				
			||||||
				Value = O->get(Field).toString();
 | 
									Value = O->get(Field).toString();
 | 
				
			||||||
				return true;
 | 
									return true;
 | 
				
			||||||
@@ -265,8 +254,7 @@ namespace OpenWifi {
 | 
				
			|||||||
			return false;
 | 
								return false;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O,
 | 
							static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O, const std::string &Field, uint64_t &Value) {
 | 
				
			||||||
										   const std::string &Field, uint64_t &Value) {
 | 
					 | 
				
			||||||
			if(O->has(Field)) {
 | 
								if(O->has(Field)) {
 | 
				
			||||||
				Value = O->get(Field);
 | 
									Value = O->get(Field);
 | 
				
			||||||
				return true;
 | 
									return true;
 | 
				
			||||||
@@ -274,8 +262,7 @@ namespace OpenWifi {
 | 
				
			|||||||
			return false;
 | 
								return false;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O,
 | 
							static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O, const std::string &Field, bool &Value) {
 | 
				
			||||||
										   const std::string &Field, bool &Value) {
 | 
					 | 
				
			||||||
			if(O->has(Field)) {
 | 
								if(O->has(Field)) {
 | 
				
			||||||
				Value = O->get(Field).toString()=="true";
 | 
									Value = O->get(Field).toString()=="true";
 | 
				
			||||||
				return true;
 | 
									return true;
 | 
				
			||||||
@@ -283,8 +270,7 @@ namespace OpenWifi {
 | 
				
			|||||||
			return false;
 | 
								return false;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O,
 | 
							static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O, const std::string &Field, double &Value) {
 | 
				
			||||||
										   const std::string &Field, double &Value) {
 | 
					 | 
				
			||||||
			if(O->has(Field)) {
 | 
								if(O->has(Field)) {
 | 
				
			||||||
				Value = (double) O->get(Field);
 | 
									Value = (double) O->get(Field);
 | 
				
			||||||
				return true;
 | 
									return true;
 | 
				
			||||||
@@ -292,8 +278,7 @@ namespace OpenWifi {
 | 
				
			|||||||
			return false;
 | 
								return false;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O,
 | 
							static inline bool AssignIfPresent(const Poco::JSON::Object::Ptr &O, const std::string &Field, Poco::Data::BLOB &Value) {
 | 
				
			||||||
										   const std::string &Field, Poco::Data::BLOB &Value) {
 | 
					 | 
				
			||||||
			if(O->has(Field)) {
 | 
								if(O->has(Field)) {
 | 
				
			||||||
				std::string Content = O->get(Field).toString();
 | 
									std::string Content = O->get(Field).toString();
 | 
				
			||||||
				auto DecodedBlob = Utils::base64decode(Content);
 | 
									auto DecodedBlob = Utils::base64decode(Content);
 | 
				
			||||||
@@ -303,9 +288,8 @@ namespace OpenWifi {
 | 
				
			|||||||
			return false;
 | 
								return false;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		template <typename T>
 | 
					
 | 
				
			||||||
		bool AssignIfPresent(const Poco::JSON::Object::Ptr &O, const std::string &Field,
 | 
							template <typename T> bool AssignIfPresent(const Poco::JSON::Object::Ptr &O, const std::string &Field, const T &value, T & assignee) {
 | 
				
			||||||
							 const T &value, T &assignee) {
 | 
					 | 
				
			||||||
			if(O->has(Field)) {
 | 
								if(O->has(Field)) {
 | 
				
			||||||
				assignee = value;
 | 
									assignee = value;
 | 
				
			||||||
				return true;
 | 
									return true;
 | 
				
			||||||
@@ -358,15 +342,13 @@ namespace OpenWifi {
 | 
				
			|||||||
			Response->send();
 | 
								Response->send();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline void PrepareResponse(
 | 
							inline void PrepareResponse(Poco::Net::HTTPResponse::HTTPStatus Status = Poco::Net::HTTPResponse::HTTP_OK,
 | 
				
			||||||
			Poco::Net::HTTPResponse::HTTPStatus Status = Poco::Net::HTTPResponse::HTTP_OK,
 | 
					 | 
				
			||||||
									bool CloseConnection = false) {
 | 
														bool CloseConnection = false) {
 | 
				
			||||||
			Response->setStatus(Status);
 | 
								Response->setStatus(Status);
 | 
				
			||||||
			SetCommonHeaders(CloseConnection);
 | 
								SetCommonHeaders(CloseConnection);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline void BadRequest(const OpenWifi::RESTAPI::Errors::msg &E,
 | 
							inline void BadRequest(const OpenWifi::RESTAPI::Errors::msg &E, const std::string & Extra="") {
 | 
				
			||||||
							   const std::string &Extra = "") {
 | 
					 | 
				
			||||||
			PrepareResponse(Poco::Net::HTTPResponse::HTTP_BAD_REQUEST);
 | 
								PrepareResponse(Poco::Net::HTTPResponse::HTTP_BAD_REQUEST);
 | 
				
			||||||
			Poco::JSON::Object	ErrorObject;
 | 
								Poco::JSON::Object	ErrorObject;
 | 
				
			||||||
			ErrorObject.set("ErrorCode",400);
 | 
								ErrorObject.set("ErrorCode",400);
 | 
				
			||||||
@@ -374,8 +356,7 @@ namespace OpenWifi {
 | 
				
			|||||||
			if(Extra.empty())
 | 
								if(Extra.empty())
 | 
				
			||||||
				ErrorObject.set("ErrorDescription",fmt::format("{}: {}",E.err_num,E.err_txt)) ;
 | 
									ErrorObject.set("ErrorDescription",fmt::format("{}: {}",E.err_num,E.err_txt)) ;
 | 
				
			||||||
			else
 | 
								else
 | 
				
			||||||
				ErrorObject.set("ErrorDescription",
 | 
									ErrorObject.set("ErrorDescription",fmt::format("{}: {} ({})",E.err_num,E.err_txt, Extra)) ;
 | 
				
			||||||
								fmt::format("{}: {} ({})", E.err_num, E.err_txt, Extra));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			std::ostream &Answer = Response->send();
 | 
								std::ostream &Answer = Response->send();
 | 
				
			||||||
			Poco::JSON::Stringifier::stringify(ErrorObject, Answer);
 | 
								Poco::JSON::Stringifier::stringify(ErrorObject, Answer);
 | 
				
			||||||
@@ -410,10 +391,11 @@ namespace OpenWifi {
 | 
				
			|||||||
			ErrorObject.set("ErrorDescription",fmt::format("{}: {}",E.err_num,E.err_txt)) ;
 | 
								ErrorObject.set("ErrorDescription",fmt::format("{}: {}",E.err_num,E.err_txt)) ;
 | 
				
			||||||
			std::ostream &Answer = Response->send();
 | 
								std::ostream &Answer = Response->send();
 | 
				
			||||||
			Poco::JSON::Stringifier::stringify(ErrorObject, Answer);
 | 
								Poco::JSON::Stringifier::stringify(ErrorObject, Answer);
 | 
				
			||||||
			poco_debug(Logger_,
 | 
								poco_debug(Logger_,fmt::format("RES-NOTFOUND: User='{}@{}' Method='{}' Path='{}",
 | 
				
			||||||
					   fmt::format("RES-NOTFOUND: User='{}@{}' Method='{}' Path='{}", Requester(),
 | 
					                                            Requester(),
 | 
				
			||||||
											Utils::FormatIPv6(Request->clientAddress().toString()),
 | 
																Utils::FormatIPv6(Request->clientAddress().toString()),
 | 
				
			||||||
								   Request->getMethod(), Request->getURI()));
 | 
																Request->getMethod(),
 | 
				
			||||||
 | 
																Request->getURI()));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline void OK() {
 | 
							inline void OK() {
 | 
				
			||||||
@@ -474,8 +456,7 @@ namespace OpenWifi {
 | 
				
			|||||||
			Response->sendFile(File.path(),MT.ContentType);
 | 
								Response->sendFile(File.path(),MT.ContentType);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline void SendFile(Poco::TemporaryFile &TempAvatar,
 | 
							inline void SendFile(Poco::TemporaryFile &TempAvatar, [[maybe_unused]] const std::string &Type, const std::string & Name) {
 | 
				
			||||||
							 [[maybe_unused]] const std::string &Type, const std::string &Name) {
 | 
					 | 
				
			||||||
			Response->setStatus(Poco::Net::HTTPResponse::HTTPStatus::HTTP_OK);
 | 
								Response->setStatus(Poco::Net::HTTPResponse::HTTPStatus::HTTP_OK);
 | 
				
			||||||
			SetCommonHeaders();
 | 
								SetCommonHeaders();
 | 
				
			||||||
			auto MT = Utils::FindMediaType(Name);
 | 
								auto MT = Utils::FindMediaType(Name);
 | 
				
			||||||
@@ -483,7 +464,6 @@ namespace OpenWifi {
 | 
				
			|||||||
				Response->set("Content-Transfer-Encoding","binary");
 | 
									Response->set("Content-Transfer-Encoding","binary");
 | 
				
			||||||
				Response->set("Accept-Ranges", "bytes");
 | 
									Response->set("Accept-Ranges", "bytes");
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			Response->set("Access-Control-Expose-Headers", "Content-Disposition");
 | 
					 | 
				
			||||||
			Response->set("Content-Disposition", "attachment; filename=" + Name );
 | 
								Response->set("Content-Disposition", "attachment; filename=" + Name );
 | 
				
			||||||
			Response->set("Accept-Ranges", "bytes");
 | 
								Response->set("Accept-Ranges", "bytes");
 | 
				
			||||||
			Response->set("Cache-Control", "no-store");
 | 
								Response->set("Cache-Control", "no-store");
 | 
				
			||||||
@@ -492,8 +472,7 @@ namespace OpenWifi {
 | 
				
			|||||||
			Response->sendFile(TempAvatar.path(),MT.ContentType);
 | 
								Response->sendFile(TempAvatar.path(),MT.ContentType);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline void SendFileContent(const std::string &Content, [[maybe_unused]] const std::string &Type,
 | 
							inline void SendFileContent(const std::string &Content, const std::string &Type, const std::string & Name) {
 | 
				
			||||||
									const std::string &Name) {
 | 
					 | 
				
			||||||
			Response->setStatus(Poco::Net::HTTPResponse::HTTPStatus::HTTP_OK);
 | 
								Response->setStatus(Poco::Net::HTTPResponse::HTTPStatus::HTTP_OK);
 | 
				
			||||||
			SetCommonHeaders();
 | 
								SetCommonHeaders();
 | 
				
			||||||
			auto MT = Utils::FindMediaType(Name);
 | 
								auto MT = Utils::FindMediaType(Name);
 | 
				
			||||||
@@ -501,18 +480,18 @@ namespace OpenWifi {
 | 
				
			|||||||
				Response->set("Content-Transfer-Encoding","binary");
 | 
									Response->set("Content-Transfer-Encoding","binary");
 | 
				
			||||||
				Response->set("Accept-Ranges", "bytes");
 | 
									Response->set("Accept-Ranges", "bytes");
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			Response->set("Access-Control-Expose-Headers", "Content-Disposition");
 | 
					 | 
				
			||||||
			Response->set("Content-Disposition", "attachment; filename=" + Name );
 | 
								Response->set("Content-Disposition", "attachment; filename=" + Name );
 | 
				
			||||||
			Response->set("Accept-Ranges", "bytes");
 | 
								Response->set("Accept-Ranges", "bytes");
 | 
				
			||||||
			Response->set("Cache-Control", "no-store");
 | 
								Response->set("Cache-Control", "no-store");
 | 
				
			||||||
			Response->set("Expires", "Mon, 26 Jul 2027 05:00:00 GMT");
 | 
								Response->set("Expires", "Mon, 26 Jul 2027 05:00:00 GMT");
 | 
				
			||||||
			Response->setContentLength(Content.size());
 | 
								Response->setContentLength(Content.size());
 | 
				
			||||||
			Response->setContentType(MT.ContentType);
 | 
								Response->setContentType(Type );
 | 
				
			||||||
			auto & OutputStream = Response->send();
 | 
								auto & OutputStream = Response->send();
 | 
				
			||||||
			OutputStream << Content ;
 | 
								OutputStream << Content ;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline void SendHTMLFileBack(Poco::File &File, const Types::StringPairVec &FormVars) {
 | 
							inline void SendHTMLFileBack(Poco::File & File,
 | 
				
			||||||
 | 
														 const Types::StringPairVec & FormVars) {
 | 
				
			||||||
			Response->setStatus(Poco::Net::HTTPResponse::HTTPStatus::HTTP_OK);
 | 
								Response->setStatus(Poco::Net::HTTPResponse::HTTPStatus::HTTP_OK);
 | 
				
			||||||
			SetCommonHeaders();
 | 
								SetCommonHeaders();
 | 
				
			||||||
			Response->set("Pragma", "private");
 | 
								Response->set("Pragma", "private");
 | 
				
			||||||
@@ -526,8 +505,7 @@ namespace OpenWifi {
 | 
				
			|||||||
			ostr << FormContent;
 | 
								ostr << FormContent;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline void ReturnStatus(Poco::Net::HTTPResponse::HTTPStatus Status,
 | 
							inline void ReturnStatus(Poco::Net::HTTPResponse::HTTPStatus Status, bool CloseConnection=false) {
 | 
				
			||||||
								 bool CloseConnection = false) {
 | 
					 | 
				
			||||||
			PrepareResponse(Status, CloseConnection);
 | 
								PrepareResponse(Status, CloseConnection);
 | 
				
			||||||
			if(Status == Poco::Net::HTTPResponse::HTTP_NO_CONTENT) {
 | 
								if(Status == Poco::Net::HTTPResponse::HTTP_NO_CONTENT) {
 | 
				
			||||||
				Response->setContentLength(0);
 | 
									Response->setContentLength(0);
 | 
				
			||||||
@@ -541,8 +519,7 @@ namespace OpenWifi {
 | 
				
			|||||||
			if (Request->getMethod() == Poco::Net::HTTPRequest::HTTP_OPTIONS) {
 | 
								if (Request->getMethod() == Poco::Net::HTTPRequest::HTTP_OPTIONS) {
 | 
				
			||||||
				ProcessOptions();
 | 
									ProcessOptions();
 | 
				
			||||||
				return false;
 | 
									return false;
 | 
				
			||||||
			} else if (std::find(Methods_.begin(), Methods_.end(), Request->getMethod()) ==
 | 
								} else if (std::find(Methods_.begin(), Methods_.end(), Request->getMethod()) == Methods_.end()) {
 | 
				
			||||||
					   Methods_.end()) {
 | 
					 | 
				
			||||||
				BadRequest(RESTAPI::Errors::UnsupportedHTTPMethod);
 | 
									BadRequest(RESTAPI::Errors::UnsupportedHTTPMethod);
 | 
				
			||||||
				return false;
 | 
									return false;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -562,8 +539,7 @@ namespace OpenWifi {
 | 
				
			|||||||
						AcceptedEncoding->second.find("compress")!=std::string::npos) {
 | 
											AcceptedEncoding->second.find("compress")!=std::string::npos) {
 | 
				
			||||||
						Response->set("Content-Encoding", "gzip");
 | 
											Response->set("Content-Encoding", "gzip");
 | 
				
			||||||
						std::ostream &Answer = Response->send();
 | 
											std::ostream &Answer = Response->send();
 | 
				
			||||||
						Poco::DeflatingOutputStream deflater(Answer,
 | 
											Poco::DeflatingOutputStream deflater(Answer, Poco::DeflatingStreamBuf::STREAM_GZIP);
 | 
				
			||||||
															 Poco::DeflatingStreamBuf::STREAM_GZIP);
 | 
					 | 
				
			||||||
						Poco::JSON::Stringifier::stringify(Object, deflater);
 | 
											Poco::JSON::Stringifier::stringify(Object, deflater);
 | 
				
			||||||
						deflater.close();
 | 
											deflater.close();
 | 
				
			||||||
						return;
 | 
											return;
 | 
				
			||||||
@@ -584,8 +560,7 @@ namespace OpenWifi {
 | 
				
			|||||||
						AcceptedEncoding->second.find("compress")!=std::string::npos) {
 | 
											AcceptedEncoding->second.find("compress")!=std::string::npos) {
 | 
				
			||||||
						Response->set("Content-Encoding", "gzip");
 | 
											Response->set("Content-Encoding", "gzip");
 | 
				
			||||||
						std::ostream &Answer = Response->send();
 | 
											std::ostream &Answer = Response->send();
 | 
				
			||||||
						Poco::DeflatingOutputStream deflater(Answer,
 | 
											Poco::DeflatingOutputStream deflater(Answer, Poco::DeflatingStreamBuf::STREAM_GZIP);
 | 
				
			||||||
															 Poco::DeflatingStreamBuf::STREAM_GZIP);
 | 
					 | 
				
			||||||
                        deflater << json_doc;
 | 
					                        deflater << json_doc;
 | 
				
			||||||
						deflater.close();
 | 
											deflater.close();
 | 
				
			||||||
						return;
 | 
											return;
 | 
				
			||||||
@@ -630,23 +605,19 @@ namespace OpenWifi {
 | 
				
			|||||||
			return true;
 | 
								return true;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[[nodiscard]] inline uint64_t Get(const char *Parameter, const Poco::JSON::Object::Ptr &Obj,
 | 
							[[nodiscard]] inline uint64_t Get(const char *Parameter,const Poco::JSON::Object::Ptr &Obj, uint64_t Default=0){
 | 
				
			||||||
										  uint64_t Default = 0) {
 | 
					 | 
				
			||||||
			if(Obj->has(Parameter))
 | 
								if(Obj->has(Parameter))
 | 
				
			||||||
				return Obj->get(Parameter);
 | 
									return Obj->get(Parameter);
 | 
				
			||||||
			return Default;
 | 
								return Default;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[[nodiscard]] inline std::string GetS(const char *Parameter,
 | 
							[[nodiscard]] inline std::string GetS(const char *Parameter,const Poco::JSON::Object::Ptr &Obj, const std::string & Default=""){
 | 
				
			||||||
											  const Poco::JSON::Object::Ptr &Obj,
 | 
					 | 
				
			||||||
											  const std::string &Default = "") {
 | 
					 | 
				
			||||||
			if(Obj->has(Parameter))
 | 
								if(Obj->has(Parameter))
 | 
				
			||||||
				return Obj->get(Parameter).toString();
 | 
									return Obj->get(Parameter).toString();
 | 
				
			||||||
			return Default;
 | 
								return Default;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[[nodiscard]] inline bool GetB(const char *Parameter, const Poco::JSON::Object::Ptr &Obj,
 | 
							[[nodiscard]] inline bool GetB(const char *Parameter,const Poco::JSON::Object::Ptr &Obj, bool Default=false){
 | 
				
			||||||
									   bool Default = false) {
 | 
					 | 
				
			||||||
			if(Obj->has(Parameter))
 | 
								if(Obj->has(Parameter))
 | 
				
			||||||
				return Obj->get(Parameter).toString()=="true";
 | 
									return Obj->get(Parameter).toString()=="true";
 | 
				
			||||||
			return Default;
 | 
								return Default;
 | 
				
			||||||
@@ -686,7 +657,6 @@ namespace OpenWifi {
 | 
				
			|||||||
		SecurityObjects::UserInfoAndPolicy 	UserInfo_;
 | 
							SecurityObjects::UserInfoAndPolicy 	UserInfo_;
 | 
				
			||||||
		QueryBlock					QB_;
 | 
							QueryBlock					QB_;
 | 
				
			||||||
		const std::string & Requester() const { return REST_Requester_; }
 | 
							const std::string & Requester() const { return REST_Requester_; }
 | 
				
			||||||
 | 
					 | 
				
			||||||
	  protected:
 | 
						  protected:
 | 
				
			||||||
		BindingMap 					Bindings_;
 | 
							BindingMap 					Bindings_;
 | 
				
			||||||
		Poco::URI::QueryParameters 	Parameters_;
 | 
							Poco::URI::QueryParameters 	Parameters_;
 | 
				
			||||||
@@ -707,33 +677,29 @@ namespace OpenWifi {
 | 
				
			|||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef    TIP_SECURITY_SERVICE
 | 
					#ifdef    TIP_SECURITY_SERVICE
 | 
				
			||||||
	[[nodiscard]] bool AuthServiceIsAuthorized(Poco::Net::HTTPServerRequest &Request,
 | 
						[[nodiscard]] bool AuthServiceIsAuthorized(Poco::Net::HTTPServerRequest & Request,std::string &SessionToken,
 | 
				
			||||||
											   std::string &SessionToken,
 | 
					                                               SecurityObjects::UserInfoAndPolicy & UInfo, std::uint64_t TID, bool & Expired , bool Sub );
 | 
				
			||||||
											   SecurityObjects::UserInfoAndPolicy &UInfo,
 | 
					 | 
				
			||||||
											   std::uint64_t TID, bool &Expired, bool Sub);
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
	inline bool RESTAPIHandler::IsAuthorized(bool &Expired, [[maybe_unused]] bool &Contacted,
 | 
						inline bool RESTAPIHandler::IsAuthorized( bool & Expired , [[maybe_unused]] bool & Contacted , bool Sub ) {
 | 
				
			||||||
											 bool Sub) {
 | 
					 | 
				
			||||||
		if(Internal_ && Request->has("X-INTERNAL-NAME")) {
 | 
							if(Internal_ && Request->has("X-INTERNAL-NAME")) {
 | 
				
			||||||
			auto Allowed = MicroServiceIsValidAPIKEY(*Request);
 | 
								auto Allowed = MicroServiceIsValidAPIKEY(*Request);
 | 
				
			||||||
			Contacted = true;
 | 
								Contacted = true;
 | 
				
			||||||
			if(!Allowed) {
 | 
								if(!Allowed) {
 | 
				
			||||||
				if(Server_.LogBadTokens(false)) {
 | 
									if(Server_.LogBadTokens(false)) {
 | 
				
			||||||
					poco_debug(Logger_,
 | 
										poco_debug(Logger_,fmt::format("I-REQ-DENIED({}): TID={} Method={} Path={}",
 | 
				
			||||||
							   fmt::format("I-REQ-DENIED({}): TID={} Method={} Path={}",
 | 
					 | 
				
			||||||
													Utils::FormatIPv6(Request->clientAddress().toString()),
 | 
																		Utils::FormatIPv6(Request->clientAddress().toString()),
 | 
				
			||||||
										   TransactionId_, Request->getMethod(),
 | 
																		TransactionId_,
 | 
				
			||||||
										   Request->getURI()));
 | 
																		Request->getMethod(), Request->getURI()));
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				auto Id = Request->get("X-INTERNAL-NAME", "unknown");
 | 
									auto Id = Request->get("X-INTERNAL-NAME", "unknown");
 | 
				
			||||||
				REST_Requester_ = Id;
 | 
									REST_Requester_ = Id;
 | 
				
			||||||
				if(Server_.LogIt(Request->getMethod(),true)) {
 | 
									if(Server_.LogIt(Request->getMethod(),true)) {
 | 
				
			||||||
					poco_debug(Logger_,
 | 
										poco_debug(Logger_,fmt::format("I-REQ-ALLOWED({}): TID={} User='{}' Method={} Path={}",
 | 
				
			||||||
							   fmt::format("I-REQ-ALLOWED({}): TID={} User='{}' Method={} Path={}",
 | 
					 | 
				
			||||||
													Utils::FormatIPv6(Request->clientAddress().toString()),
 | 
																		Utils::FormatIPv6(Request->clientAddress().toString()),
 | 
				
			||||||
										   TransactionId_, Id, Request->getMethod(),
 | 
																		TransactionId_,
 | 
				
			||||||
										   Request->getURI()));
 | 
																		Id,
 | 
				
			||||||
 | 
																		Request->getMethod(), Request->getURI()));
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			return Allowed;
 | 
								return Allowed;
 | 
				
			||||||
@@ -742,29 +708,27 @@ namespace OpenWifi {
 | 
				
			|||||||
            bool suspended=false;
 | 
					            bool suspended=false;
 | 
				
			||||||
#ifdef    TIP_SECURITY_SERVICE
 | 
					#ifdef    TIP_SECURITY_SERVICE
 | 
				
			||||||
            std::uint64_t expiresOn;
 | 
					            std::uint64_t expiresOn;
 | 
				
			||||||
			if (AuthService()->IsValidApiKey(SessionToken_, UserInfo_.webtoken, UserInfo_.userinfo,
 | 
					            if (AuthService()->IsValidApiKey(SessionToken_, UserInfo_.webtoken, UserInfo_.userinfo, Expired, expiresOn, suspended)) {
 | 
				
			||||||
											 Expired, expiresOn, suspended)) {
 | 
					 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
			if (AuthClient()->IsValidApiKey(SessionToken_, UserInfo_, TransactionId_, Expired,
 | 
					            if (AuthClient()->IsValidApiKey( SessionToken_, UserInfo_, TransactionId_, Expired, Contacted, suspended)) {
 | 
				
			||||||
											Contacted, suspended)) {
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
                REST_Requester_ = UserInfo_.userinfo.email;
 | 
					                REST_Requester_ = UserInfo_.userinfo.email;
 | 
				
			||||||
                if(Server_.LogIt(Request->getMethod(),true)) {
 | 
					                if(Server_.LogIt(Request->getMethod(),true)) {
 | 
				
			||||||
					poco_debug(Logger_,
 | 
					                    poco_debug(Logger_,fmt::format("X-REQ-ALLOWED({}): APIKEY-ACCESS TID={} User='{}@{}' Method={} Path={}",
 | 
				
			||||||
							   fmt::format("X-REQ-ALLOWED({}): APIKEY-ACCESS TID={} User='{}@{}' "
 | 
					                                                   UserInfo_.userinfo.email,
 | 
				
			||||||
										   "Method={} Path={}",
 | 
					                                                   TransactionId_,
 | 
				
			||||||
										   UserInfo_.userinfo.email, TransactionId_,
 | 
					 | 
				
			||||||
                                                   Utils::FormatIPv6(Request->clientAddress().toString()),
 | 
					                                                   Utils::FormatIPv6(Request->clientAddress().toString()),
 | 
				
			||||||
                                                   Request->clientAddress().toString(),
 | 
					                                                   Request->clientAddress().toString(),
 | 
				
			||||||
										   Request->getMethod(), Request->getURI()));
 | 
					                                                   Request->getMethod(),
 | 
				
			||||||
 | 
					                                                   Request->getURI()));
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                return true;
 | 
					                return true;
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                if(Server_.LogBadTokens(true)) {
 | 
					                if(Server_.LogBadTokens(true)) {
 | 
				
			||||||
					poco_debug(Logger_,
 | 
					                    poco_debug(Logger_,fmt::format("X-REQ-DENIED({}): TID={} Method={} Path={}",
 | 
				
			||||||
							   fmt::format("X-REQ-DENIED({}): TID={} Method={} Path={}",
 | 
					 | 
				
			||||||
                                                   Utils::FormatIPv6(Request->clientAddress().toString()),
 | 
					                                                   Utils::FormatIPv6(Request->clientAddress().toString()),
 | 
				
			||||||
										   TransactionId_, Request->getMethod(),
 | 
					                                                   TransactionId_,
 | 
				
			||||||
 | 
					                                                   Request->getMethod(),
 | 
				
			||||||
                                                   Request->getURI()));
 | 
					                                                   Request->getURI()));
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -781,29 +745,27 @@ namespace OpenWifi {
 | 
				
			|||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
#ifdef    TIP_SECURITY_SERVICE
 | 
					#ifdef    TIP_SECURITY_SERVICE
 | 
				
			||||||
			if (AuthServiceIsAuthorized(*Request, SessionToken_, UserInfo_, TransactionId_, Expired,
 | 
								if (AuthServiceIsAuthorized(*Request, SessionToken_, UserInfo_, TransactionId_, Expired, Sub)) {
 | 
				
			||||||
										Sub)) {
 | 
					 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
			if (AuthClient()->IsAuthorized(SessionToken_, UserInfo_, TransactionId_, Expired,
 | 
								if (AuthClient()->IsAuthorized( SessionToken_, UserInfo_, TransactionId_, Expired, Contacted, Sub)) {
 | 
				
			||||||
										   Contacted, Sub)) {
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
				REST_Requester_ = UserInfo_.userinfo.email;
 | 
									REST_Requester_ = UserInfo_.userinfo.email;
 | 
				
			||||||
				if(Server_.LogIt(Request->getMethod(),true)) {
 | 
									if(Server_.LogIt(Request->getMethod(),true)) {
 | 
				
			||||||
					poco_debug(
 | 
										poco_debug(Logger_,fmt::format("X-REQ-ALLOWED({}): TID={} User='{}@{}' Method={} Path={}",
 | 
				
			||||||
						Logger_,
 | 
																		UserInfo_.userinfo.email,
 | 
				
			||||||
						fmt::format("X-REQ-ALLOWED({}): TID={} User='{}@{}' Method={} Path={}",
 | 
																		TransactionId_,
 | 
				
			||||||
									UserInfo_.userinfo.email, TransactionId_,
 | 
					 | 
				
			||||||
													Utils::FormatIPv6(Request->clientAddress().toString()),
 | 
																		Utils::FormatIPv6(Request->clientAddress().toString()),
 | 
				
			||||||
									Request->clientAddress().toString(), Request->getMethod(),
 | 
																		Request->clientAddress().toString(),
 | 
				
			||||||
 | 
																		Request->getMethod(),
 | 
				
			||||||
													Request->getURI()));
 | 
																		Request->getURI()));
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				return true;
 | 
									return true;
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				if(Server_.LogBadTokens(true)) {
 | 
									if(Server_.LogBadTokens(true)) {
 | 
				
			||||||
					poco_debug(Logger_,
 | 
										poco_debug(Logger_,fmt::format("X-REQ-DENIED({}): TID={} Method={} Path={}",
 | 
				
			||||||
							   fmt::format("X-REQ-DENIED({}): TID={} Method={} Path={}",
 | 
					 | 
				
			||||||
													Utils::FormatIPv6(Request->clientAddress().toString()),
 | 
																		Utils::FormatIPv6(Request->clientAddress().toString()),
 | 
				
			||||||
										   TransactionId_, Request->getMethod(),
 | 
																		TransactionId_,
 | 
				
			||||||
 | 
																		Request->getMethod(),
 | 
				
			||||||
													Request->getURI()));
 | 
																		Request->getURI()));
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -813,11 +775,8 @@ namespace OpenWifi {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	class RESTAPI_UnknownRequestHandler : public RESTAPIHandler {
 | 
						class RESTAPI_UnknownRequestHandler : public RESTAPIHandler {
 | 
				
			||||||
	  public:
 | 
						  public:
 | 
				
			||||||
		RESTAPI_UnknownRequestHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L,
 | 
							RESTAPI_UnknownRequestHandler(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
 | 
				
			||||||
									  RESTAPI_GenericServerAccounting &Server,
 | 
								: RESTAPIHandler(bindings, L, std::vector<std::string>{}, Server, TransactionId, Internal) {}
 | 
				
			||||||
									  uint64_t TransactionId, bool Internal)
 | 
					 | 
				
			||||||
			: RESTAPIHandler(bindings, L, std::vector<std::string>{}, Server, TransactionId,
 | 
					 | 
				
			||||||
							 Internal) {}
 | 
					 | 
				
			||||||
		inline void DoGet() override {};
 | 
							inline void DoGet() override {};
 | 
				
			||||||
		inline void DoPost() override {};
 | 
							inline void DoPost() override {};
 | 
				
			||||||
		inline void DoPut() override {};
 | 
							inline void DoPut() override {};
 | 
				
			||||||
@@ -825,37 +784,35 @@ namespace OpenWifi {
 | 
				
			|||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	template<class T>
 | 
						template<class T>
 | 
				
			||||||
	constexpr auto test_has_PathName_method(T *) -> decltype(T::PathName(), std::true_type{}) {
 | 
							constexpr auto test_has_PathName_method(T*)
 | 
				
			||||||
 | 
								-> decltype(  T::PathName() , std::true_type{} )
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
			return std::true_type{};
 | 
								return std::true_type{};
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	constexpr auto test_has_PathName_method(...) -> std::false_type { return std::false_type{}; }
 | 
							constexpr auto test_has_PathName_method(...) -> std::false_type
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								return std::false_type{};
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	template<typename T, typename... Args>
 | 
						template<typename T, typename... Args>
 | 
				
			||||||
	RESTAPIHandler *RESTAPI_Router(const std::string &RequestedPath,
 | 
							RESTAPIHandler * RESTAPI_Router(const std::string & RequestedPath, RESTAPIHandler::BindingMap &Bindings,
 | 
				
			||||||
								   RESTAPIHandler::BindingMap &Bindings, Poco::Logger &Logger,
 | 
														   Poco::Logger & Logger, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId) {
 | 
				
			||||||
								   RESTAPI_GenericServerAccounting &Server,
 | 
								static_assert(test_has_PathName_method((T*)nullptr), "Class must have a static PathName() method.");
 | 
				
			||||||
								   uint64_t TransactionId) {
 | 
					 | 
				
			||||||
		static_assert(test_has_PathName_method((T *)nullptr),
 | 
					 | 
				
			||||||
					  "Class must have a static PathName() method.");
 | 
					 | 
				
			||||||
			if(RESTAPIHandler::ParseBindings(RequestedPath,T::PathName(),Bindings)) {
 | 
								if(RESTAPIHandler::ParseBindings(RequestedPath,T::PathName(),Bindings)) {
 | 
				
			||||||
				return new T(Bindings, Logger, Server, TransactionId, false);
 | 
									return new T(Bindings, Logger, Server, TransactionId, false);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if constexpr (sizeof...(Args) == 0) {
 | 
								if constexpr (sizeof...(Args) == 0) {
 | 
				
			||||||
			return new RESTAPI_UnknownRequestHandler(Bindings, Logger, Server, TransactionId,
 | 
									return new RESTAPI_UnknownRequestHandler(Bindings,Logger, Server, TransactionId, false);
 | 
				
			||||||
													 false);
 | 
					 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				return RESTAPI_Router<Args...>(RequestedPath, Bindings, Logger, Server, TransactionId);
 | 
									return RESTAPI_Router<Args...>(RequestedPath, Bindings, Logger, Server, TransactionId);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	template<typename T, typename... Args>
 | 
						template<typename T, typename... Args>
 | 
				
			||||||
	RESTAPIHandler *RESTAPI_Router_I(const std::string &RequestedPath,
 | 
							RESTAPIHandler * RESTAPI_Router_I(const std::string & RequestedPath, RESTAPIHandler::BindingMap &Bindings,
 | 
				
			||||||
									 RESTAPIHandler::BindingMap &Bindings, Poco::Logger &Logger,
 | 
															 Poco::Logger & Logger, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId) {
 | 
				
			||||||
									 RESTAPI_GenericServerAccounting &Server,
 | 
								static_assert(test_has_PathName_method((T*)nullptr), "Class must have a static PathName() method.");
 | 
				
			||||||
									 uint64_t TransactionId) {
 | 
					 | 
				
			||||||
		static_assert(test_has_PathName_method((T *)nullptr),
 | 
					 | 
				
			||||||
					  "Class must have a static PathName() method.");
 | 
					 | 
				
			||||||
			if(RESTAPIHandler::ParseBindings(RequestedPath,T::PathName(),Bindings)) {
 | 
								if(RESTAPIHandler::ParseBindings(RequestedPath,T::PathName(),Bindings)) {
 | 
				
			||||||
				return new T(Bindings, Logger, Server, TransactionId, true );
 | 
									return new T(Bindings, Logger, Server, TransactionId, true );
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -863,8 +820,7 @@ namespace OpenWifi {
 | 
				
			|||||||
			if constexpr (sizeof...(Args) == 0) {
 | 
								if constexpr (sizeof...(Args) == 0) {
 | 
				
			||||||
				return new RESTAPI_UnknownRequestHandler(Bindings,Logger, Server, TransactionId, true);
 | 
									return new RESTAPI_UnknownRequestHandler(Bindings,Logger, Server, TransactionId, true);
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
			return RESTAPI_Router_I<Args...>(RequestedPath, Bindings, Logger, Server,
 | 
									return RESTAPI_Router_I<Args...>(RequestedPath, Bindings, Logger, Server, TransactionId);
 | 
				
			||||||
											 TransactionId);
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,21 +6,18 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "Poco/Net/HTTPServer.h"
 | 
					#include "Poco/Net/HTTPServer.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "framework/RESTAPI_Handler.h"
 | 
					 | 
				
			||||||
#include "framework/SubSystemServer.h"
 | 
					#include "framework/SubSystemServer.h"
 | 
				
			||||||
 | 
					#include "framework/RESTAPI_Handler.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Poco::Net::HTTPRequestHandler *
 | 
						Poco::Net::HTTPRequestHandler * RESTAPI_IntRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings,
 | 
				
			||||||
	RESTAPI_IntRouter(const std::string &Path, RESTAPIHandler::BindingMap &Bindings,
 | 
					 | 
				
			||||||
													 Poco::Logger & L, RESTAPI_GenericServerAccounting & S, uint64_t Id);
 | 
																		 Poco::Logger & L, RESTAPI_GenericServerAccounting & S, uint64_t Id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	class IntRequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
 | 
						class IntRequestHandlerFactory : public Poco::Net::HTTPRequestHandlerFactory {
 | 
				
			||||||
	  public:
 | 
						  public:
 | 
				
			||||||
		inline IntRequestHandlerFactory() = default;
 | 
							inline IntRequestHandlerFactory() = default;
 | 
				
			||||||
		Poco::Net::HTTPRequestHandler *
 | 
							Poco::Net::HTTPRequestHandler *createRequestHandler(const Poco::Net::HTTPServerRequest &Request) override;
 | 
				
			||||||
		createRequestHandler(const Poco::Net::HTTPServerRequest &Request) override;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	  private:
 | 
						  private:
 | 
				
			||||||
		static inline std::atomic_uint64_t  NextTransactionId_ = 1;
 | 
							static inline std::atomic_uint64_t  NextTransactionId_ = 1;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
@@ -39,15 +36,10 @@ namespace OpenWifi {
 | 
				
			|||||||
			for(const auto & Svr: ConfigServersList_) {
 | 
								for(const auto & Svr: ConfigServersList_) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				if(MicroServiceNoAPISecurity()) {
 | 
									if(MicroServiceNoAPISecurity()) {
 | 
				
			||||||
					poco_information(
 | 
										poco_information(Logger(),fmt::format("Starting: {}:{}. Security has been disabled for APIs.", Svr.Address(), Svr.Port()));
 | 
				
			||||||
						Logger(),
 | 
					 | 
				
			||||||
						fmt::format("Starting: {}:{}. Security has been disabled for APIs.",
 | 
					 | 
				
			||||||
									Svr.Address(), Svr.Port()));
 | 
					 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					poco_information(Logger(),
 | 
										poco_information(Logger(),fmt::format("Starting: {}:{}. Keyfile:{} CertFile: {}", Svr.Address(), Svr.Port(),
 | 
				
			||||||
									 fmt::format("Starting: {}:{}. Keyfile:{} CertFile: {}",
 | 
																		 Svr.KeyFile(),Svr.CertFile()));
 | 
				
			||||||
												 Svr.Address(), Svr.Port(), Svr.KeyFile(),
 | 
					 | 
				
			||||||
												 Svr.CertFile()));
 | 
					 | 
				
			||||||
					Svr.LogCert(Logger());
 | 
										Svr.LogCert(Logger());
 | 
				
			||||||
					if (!Svr.RootCA().empty())
 | 
										if (!Svr.RootCA().empty())
 | 
				
			||||||
						Svr.LogCas(Logger());
 | 
											Svr.LogCas(Logger());
 | 
				
			||||||
@@ -60,12 +52,10 @@ namespace OpenWifi {
 | 
				
			|||||||
				std::unique_ptr<Poco::Net::HTTPServer>  NewServer;
 | 
									std::unique_ptr<Poco::Net::HTTPServer>  NewServer;
 | 
				
			||||||
				if(MicroServiceNoAPISecurity()) {
 | 
									if(MicroServiceNoAPISecurity()) {
 | 
				
			||||||
					auto Sock{Svr.CreateSocket(Logger())};
 | 
										auto Sock{Svr.CreateSocket(Logger())};
 | 
				
			||||||
					NewServer = std::make_unique<Poco::Net::HTTPServer>(
 | 
										NewServer = std::make_unique<Poco::Net::HTTPServer>(new IntRequestHandlerFactory, Pool_, Sock, Params);
 | 
				
			||||||
						new IntRequestHandlerFactory, Pool_, Sock, Params);
 | 
					 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					auto Sock{Svr.CreateSecureSocket(Logger())};
 | 
										auto Sock{Svr.CreateSecureSocket(Logger())};
 | 
				
			||||||
					NewServer = std::make_unique<Poco::Net::HTTPServer>(
 | 
										NewServer = std::make_unique<Poco::Net::HTTPServer>(new IntRequestHandlerFactory, Pool_, Sock, Params);
 | 
				
			||||||
						new IntRequestHandlerFactory, Pool_, Sock, Params);
 | 
					 | 
				
			||||||
				};
 | 
									};
 | 
				
			||||||
				NewServer->start();
 | 
									NewServer->start();
 | 
				
			||||||
				RESTServers_.push_back(std::move(NewServer));
 | 
									RESTServers_.push_back(std::move(NewServer));
 | 
				
			||||||
@@ -96,16 +86,19 @@ namespace OpenWifi {
 | 
				
			|||||||
			return RESTAPI_IntRouter(Path, Bindings, Logger(), Server_, Id);
 | 
								return RESTAPI_IntRouter(Path, Bindings, Logger(), Server_, Id);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		const Poco::ThreadPool & Pool() { return Pool_; }
 | 
							const Poco::ThreadPool & Pool() { return Pool_; }
 | 
				
			||||||
 | 
					 | 
				
			||||||
	  private:
 | 
						  private:
 | 
				
			||||||
		std::vector<std::unique_ptr<Poco::Net::HTTPServer>>   RESTServers_;
 | 
							std::vector<std::unique_ptr<Poco::Net::HTTPServer>>   RESTServers_;
 | 
				
			||||||
		Poco::ThreadPool	    Pool_{"i-rest",4,64};
 | 
							Poco::ThreadPool	    Pool_{"i-rest",4,64};
 | 
				
			||||||
		RESTAPI_GenericServerAccounting   Server_;
 | 
							RESTAPI_GenericServerAccounting   Server_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		RESTAPI_IntServer() noexcept
 | 
							RESTAPI_IntServer() noexcept:
 | 
				
			||||||
			: SubSystemServer("RESTAPI_IntServer", "REST-ISRV", "openwifi.internal.restapi") {}
 | 
														   SubSystemServer("RESTAPI_IntServer", "REST-ISRV", "openwifi.internal.restapi")
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline auto RESTAPI_IntServer() { return RESTAPI_IntServer::instance(); };
 | 
						inline auto RESTAPI_IntServer() { return RESTAPI_IntServer::instance(); };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace OpenWifi
 | 
					} // namespace OpenWifi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,26 +4,29 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "Poco/CountingStream.h"
 | 
					#include <string>
 | 
				
			||||||
#include "Poco/Net/MessageHeader.h"
 | 
					 | 
				
			||||||
#include "Poco/Net/PartHandler.h"
 | 
					#include "Poco/Net/PartHandler.h"
 | 
				
			||||||
 | 
					#include "Poco/Net/MessageHeader.h"
 | 
				
			||||||
 | 
					#include "Poco/CountingStream.h"
 | 
				
			||||||
#include "Poco/NullStream.h"
 | 
					#include "Poco/NullStream.h"
 | 
				
			||||||
#include "Poco/StreamCopier.h"
 | 
					#include "Poco/StreamCopier.h"
 | 
				
			||||||
#include <string>
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
	class RESTAPI_PartHandler: public Poco::Net::PartHandler {
 | 
						class RESTAPI_PartHandler: public Poco::Net::PartHandler {
 | 
				
			||||||
	  public:
 | 
						  public:
 | 
				
			||||||
		RESTAPI_PartHandler() : _length(0) {}
 | 
							RESTAPI_PartHandler():
 | 
				
			||||||
 | 
													_length(0)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline void handlePart(const Poco::Net::MessageHeader &header,
 | 
							inline void handlePart(const Poco::Net::MessageHeader& header, std::istream& stream) override
 | 
				
			||||||
							   std::istream &stream) override {
 | 
							{
 | 
				
			||||||
			_type = header.get("Content-Type", "(unspecified)");
 | 
								_type = header.get("Content-Type", "(unspecified)");
 | 
				
			||||||
			if (header.has("Content-Disposition")) {
 | 
								if (header.has("Content-Disposition"))
 | 
				
			||||||
 | 
								{
 | 
				
			||||||
				std::string disp;
 | 
									std::string disp;
 | 
				
			||||||
				Poco::Net::NameValueCollection params;
 | 
									Poco::Net::NameValueCollection params;
 | 
				
			||||||
				Poco::Net::MessageHeader::splitParameters(header["Content-Disposition"], disp,
 | 
									Poco::Net::MessageHeader::splitParameters(header["Content-Disposition"], disp, params);
 | 
				
			||||||
														  params);
 | 
					 | 
				
			||||||
				_name = params.get("name", "(unnamed)");
 | 
									_name = params.get("name", "(unnamed)");
 | 
				
			||||||
				_fileName = params.get("filename", "(unnamed)");
 | 
									_fileName = params.get("filename", "(unnamed)");
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
@@ -34,13 +37,25 @@ namespace OpenWifi {
 | 
				
			|||||||
			_length = (int)istr.chars();
 | 
								_length = (int)istr.chars();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[[nodiscard]] inline int length() const { return _length; }
 | 
							[[nodiscard]] inline int length() const
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								return _length;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[[nodiscard]] inline const std::string &name() const { return _name; }
 | 
							[[nodiscard]] inline const std::string& name() const
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								return _name;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[[nodiscard]] inline const std::string &fileName() const { return _fileName; }
 | 
							[[nodiscard]] inline const std::string& fileName() const
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								return _fileName;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[[nodiscard]] inline const std::string &contentType() const { return _type; }
 | 
							[[nodiscard]] inline const std::string& contentType() const
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								return _type;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	  private:
 | 
						  private:
 | 
				
			||||||
		int _length;
 | 
							int _length;
 | 
				
			||||||
@@ -48,4 +63,4 @@ namespace OpenWifi {
 | 
				
			|||||||
		std::string _name;
 | 
							std::string _name;
 | 
				
			||||||
		std::string _fileName;
 | 
							std::string _fileName;
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
} // namespace OpenWifi
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,9 +6,9 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "framework/SubSystemServer.h"
 | 
					#include "framework/SubSystemServer.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "Poco/ExpireLRUCache.h"
 | 
					 | 
				
			||||||
#include "Poco/Net/HTTPServerRequest.h"
 | 
					 | 
				
			||||||
#include "Poco/URI.h"
 | 
					#include "Poco/URI.h"
 | 
				
			||||||
 | 
					#include "Poco/Net/HTTPServerRequest.h"
 | 
				
			||||||
 | 
					#include "Poco/ExpireLRUCache.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "fmt/format.h"
 | 
					#include "fmt/format.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -16,6 +16,7 @@ namespace OpenWifi {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	class RESTAPI_RateLimiter : public SubSystemServer {
 | 
						class RESTAPI_RateLimiter : public SubSystemServer {
 | 
				
			||||||
	  public:
 | 
						  public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		struct ClientCacheEntry {
 | 
							struct ClientCacheEntry {
 | 
				
			||||||
			int64_t  Start=0;
 | 
								int64_t  Start=0;
 | 
				
			||||||
			int      Count=0;
 | 
								int      Count=0;
 | 
				
			||||||
@@ -29,14 +30,11 @@ namespace OpenWifi {
 | 
				
			|||||||
		inline int Start() final { return 0;};
 | 
							inline int Start() final { return 0;};
 | 
				
			||||||
		inline void Stop() final { };
 | 
							inline void Stop() final { };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline bool IsRateLimited(const Poco::Net::HTTPServerRequest &R, int64_t Period,
 | 
							inline bool IsRateLimited(const Poco::Net::HTTPServerRequest &R, int64_t Period, int64_t MaxCalls) {
 | 
				
			||||||
								  int64_t MaxCalls) {
 | 
					 | 
				
			||||||
			Poco::URI   uri(R.getURI());
 | 
								Poco::URI   uri(R.getURI());
 | 
				
			||||||
			auto H = str_hash(uri.getPath() + R.clientAddress().host().toString());
 | 
								auto H = str_hash(uri.getPath() + R.clientAddress().host().toString());
 | 
				
			||||||
			auto E = Cache_.get(H);
 | 
								auto E = Cache_.get(H);
 | 
				
			||||||
			auto Now = std::chrono::duration_cast<std::chrono::milliseconds>(
 | 
								auto Now = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
 | 
				
			||||||
						   std::chrono::system_clock::now().time_since_epoch())
 | 
					 | 
				
			||||||
						   .count();
 | 
					 | 
				
			||||||
			if(E.isNull()) {
 | 
								if(E.isNull()) {
 | 
				
			||||||
				Cache_.add(H,ClientCacheEntry{.Start=Now, .Count=1});
 | 
									Cache_.add(H,ClientCacheEntry{.Start=Now, .Count=1});
 | 
				
			||||||
				return false;
 | 
									return false;
 | 
				
			||||||
@@ -45,8 +43,7 @@ namespace OpenWifi {
 | 
				
			|||||||
				E->Count++;
 | 
									E->Count++;
 | 
				
			||||||
				Cache_.update(H,E);
 | 
									Cache_.update(H,E);
 | 
				
			||||||
				if(E->Count > MaxCalls) {
 | 
									if(E->Count > MaxCalls) {
 | 
				
			||||||
					poco_warning(Logger(), fmt::format("RATE-LIMIT-EXCEEDED: from '{}'",
 | 
										poco_warning(Logger(),fmt::format("RATE-LIMIT-EXCEEDED: from '{}'", R.clientAddress().toString()));
 | 
				
			||||||
													   R.clientAddress().toString()));
 | 
					 | 
				
			||||||
					return true;
 | 
										return true;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				return false;
 | 
									return false;
 | 
				
			||||||
@@ -57,16 +54,22 @@ namespace OpenWifi {
 | 
				
			|||||||
			return false;
 | 
								return false;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline void Clear() { Cache_.clear(); }
 | 
							inline void Clear() {
 | 
				
			||||||
 | 
								Cache_.clear();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	  private:
 | 
						  private:
 | 
				
			||||||
		Poco::ExpireLRUCache<uint64_t,ClientCacheEntry>      Cache_{2048};
 | 
							Poco::ExpireLRUCache<uint64_t,ClientCacheEntry>      Cache_{2048};
 | 
				
			||||||
		std::hash<std::string>          str_hash;
 | 
							std::hash<std::string>          str_hash;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		RESTAPI_RateLimiter() noexcept
 | 
							RESTAPI_RateLimiter() noexcept:
 | 
				
			||||||
			: SubSystemServer("RateLimiter", "RATE-LIMITER", "rate.limiter") {}
 | 
															 SubSystemServer("RateLimiter", "RATE-LIMITER", "rate.limiter")
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline auto RESTAPI_RateLimiter() { return RESTAPI_RateLimiter::instance(); }
 | 
						inline auto RESTAPI_RateLimiter() { return RESTAPI_RateLimiter::instance(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace OpenWifi
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -14,14 +14,14 @@ namespace OpenWifi {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	class RESTAPI_system_command : public RESTAPIHandler {
 | 
						class RESTAPI_system_command : public RESTAPIHandler {
 | 
				
			||||||
	  public:
 | 
						  public:
 | 
				
			||||||
		RESTAPI_system_command(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L,
 | 
							RESTAPI_system_command(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting & Server, uint64_t TransactionId, bool Internal)
 | 
				
			||||||
							   RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId,
 | 
					 | 
				
			||||||
							   bool Internal)
 | 
					 | 
				
			||||||
			: RESTAPIHandler(bindings, L,
 | 
								: RESTAPIHandler(bindings, L,
 | 
				
			||||||
							 std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_POST,
 | 
												 std::vector<std::string>{Poco::Net::HTTPRequest::HTTP_POST,
 | 
				
			||||||
													  Poco::Net::HTTPRequest::HTTP_GET,
 | 
																		  Poco::Net::HTTPRequest::HTTP_GET,
 | 
				
			||||||
													  Poco::Net::HTTPRequest::HTTP_OPTIONS},
 | 
																		  Poco::Net::HTTPRequest::HTTP_OPTIONS},
 | 
				
			||||||
							 Server, TransactionId, Internal) {}
 | 
												 Server,
 | 
				
			||||||
 | 
												 TransactionId,
 | 
				
			||||||
 | 
												 Internal) {}
 | 
				
			||||||
		static auto PathName() { return std::list<std::string>{"/api/v1/system"};}
 | 
							static auto PathName() { return std::list<std::string>{"/api/v1/system"};}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline void DoGet() {
 | 
							inline void DoGet() {
 | 
				
			||||||
@@ -88,8 +88,7 @@ namespace OpenWifi {
 | 
				
			|||||||
								auto Name = GetS(RESTAPI::Protocol::TAG, InnerObj);
 | 
													auto Name = GetS(RESTAPI::Protocol::TAG, InnerObj);
 | 
				
			||||||
								auto Value = GetS(RESTAPI::Protocol::VALUE, InnerObj);
 | 
													auto Value = GetS(RESTAPI::Protocol::VALUE, InnerObj);
 | 
				
			||||||
								MicroServiceSetSubsystemLogLevel(Name, Value);
 | 
													MicroServiceSetSubsystemLogLevel(Name, Value);
 | 
				
			||||||
								poco_information(
 | 
													poco_information(Logger_,
 | 
				
			||||||
									Logger_,
 | 
					 | 
				
			||||||
									fmt::format("Setting log level for {} at {}", Name, Value));
 | 
														fmt::format("Setting log level for {} at {}", Name, Value));
 | 
				
			||||||
							}
 | 
												}
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
@@ -155,4 +154,4 @@ namespace OpenWifi {
 | 
				
			|||||||
		void DoDelete() final {};
 | 
							void DoDelete() final {};
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace OpenWifi
 | 
					}
 | 
				
			||||||
@@ -4,33 +4,32 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "Poco/Net/WebSocket.h"
 | 
					 | 
				
			||||||
#include "framework/RESTAPI_Handler.h"
 | 
					#include "framework/RESTAPI_Handler.h"
 | 
				
			||||||
 | 
					#include "Poco/Net/WebSocket.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "framework/MicroServiceFuncs.h"
 | 
					 | 
				
			||||||
#include "framework/UI_WebSocketClientServer.h"
 | 
					#include "framework/UI_WebSocketClientServer.h"
 | 
				
			||||||
 | 
					#include "framework/MicroServiceFuncs.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
	class RESTAPI_webSocketServer : public RESTAPIHandler {
 | 
						class RESTAPI_webSocketServer : public RESTAPIHandler {
 | 
				
			||||||
	  public:
 | 
						  public:
 | 
				
			||||||
		inline RESTAPI_webSocketServer(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L,
 | 
							inline RESTAPI_webSocketServer(const RESTAPIHandler::BindingMap &bindings, Poco::Logger &L, RESTAPI_GenericServerAccounting &Server, uint64_t TransactionId, bool Internal)
 | 
				
			||||||
									   RESTAPI_GenericServerAccounting &Server,
 | 
					 | 
				
			||||||
									   uint64_t TransactionId, bool Internal)
 | 
					 | 
				
			||||||
			: RESTAPIHandler(bindings, L,
 | 
								: RESTAPIHandler(bindings, L,
 | 
				
			||||||
							 std::vector<std::string>{	Poco::Net::HTTPRequest::HTTP_GET,
 | 
												 std::vector<std::string>{	Poco::Net::HTTPRequest::HTTP_GET,
 | 
				
			||||||
													  	Poco::Net::HTTPRequest::HTTP_OPTIONS},
 | 
																		  	Poco::Net::HTTPRequest::HTTP_OPTIONS},
 | 
				
			||||||
							 Server, TransactionId, Internal,false) {}
 | 
												 Server, TransactionId, Internal,false) {}
 | 
				
			||||||
		static auto PathName() { return std::list<std::string>{"/api/v1/ws"};}
 | 
							static auto PathName() { return std::list<std::string>{"/api/v1/ws"};}
 | 
				
			||||||
		void DoGet() final {
 | 
							void DoGet() final {
 | 
				
			||||||
			try {
 | 
									try
 | 
				
			||||||
				if (Request->find("Upgrade") != Request->end() &&
 | 
									{
 | 
				
			||||||
					Poco::icompare((*Request)["Upgrade"], "websocket") == 0) {
 | 
										if(Request->find("Upgrade") != Request->end() && Poco::icompare((*Request)["Upgrade"], "websocket") == 0) {
 | 
				
			||||||
					try {
 | 
											try
 | 
				
			||||||
 | 
											{
 | 
				
			||||||
							Poco::Net::WebSocket WS(*Request, *Response);
 | 
												Poco::Net::WebSocket WS(*Request, *Response);
 | 
				
			||||||
							auto Id = MicroServiceCreateUUID();
 | 
												auto Id = MicroServiceCreateUUID();
 | 
				
			||||||
						UI_WebSocketClientServer()->NewClient(WS, Id, UserInfo_.userinfo.email,
 | 
												UI_WebSocketClientServer()->NewClient(WS,Id,UserInfo_.userinfo.email, TransactionId_);
 | 
				
			||||||
															  TransactionId_);
 | 
											}
 | 
				
			||||||
					} catch (...) {
 | 
											catch (...) {
 | 
				
			||||||
							std::cout << "Cannot create websocket client..." << std::endl;
 | 
												std::cout << "Cannot create websocket client..." << std::endl;
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
@@ -41,7 +40,6 @@ namespace OpenWifi {
 | 
				
			|||||||
		void DoDelete() final {};
 | 
							void DoDelete() final {};
 | 
				
			||||||
		void DoPost() final {};
 | 
							void DoPost() final {};
 | 
				
			||||||
		void DoPut() final {};
 | 
							void DoPut() final {};
 | 
				
			||||||
 | 
					 | 
				
			||||||
	  private:
 | 
						  private:
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
} // namespace OpenWifi
 | 
					}
 | 
				
			||||||
@@ -6,25 +6,17 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <string>
 | 
					#include <string>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "Poco/Data/LOB.h"
 | 
					 | 
				
			||||||
#include "Poco/JSON/Object.h"
 | 
					#include "Poco/JSON/Object.h"
 | 
				
			||||||
#include "Poco/JSON/Parser.h"
 | 
					#include "Poco/JSON/Parser.h"
 | 
				
			||||||
 | 
					#include "Poco/Data/LOB.h"
 | 
				
			||||||
#include "Poco/Net/HTTPServerRequest.h"
 | 
					#include "Poco/Net/HTTPServerRequest.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "framework/OpenWifiTypes.h"
 | 
					#include "framework/OpenWifiTypes.h"
 | 
				
			||||||
#include "framework/utils.h"
 | 
					#include "framework/utils.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <RESTObjects/RESTAPI_SecurityObjects.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace OpenWifi::RESTAPI_utils {
 | 
					namespace OpenWifi::RESTAPI_utils {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline bool IsRootOrAdmin(const SecurityObjects::UserInfo &UI) {
 | 
						inline void EmbedDocument(const std::string & ObjName, Poco::JSON::Object & Obj, const std::string &ObjStr) {
 | 
				
			||||||
		return 	UI.userRole==SecurityObjects::ROOT ||
 | 
					 | 
				
			||||||
				UI.userRole==SecurityObjects::ADMIN;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	inline void EmbedDocument(const std::string &ObjName, Poco::JSON::Object &Obj,
 | 
					 | 
				
			||||||
							  const std::string &ObjStr) {
 | 
					 | 
				
			||||||
		std::string D = ObjStr.empty() ? "{}" : ObjStr;
 | 
							std::string D = ObjStr.empty() ? "{}" : ObjStr;
 | 
				
			||||||
		Poco::JSON::Parser P;
 | 
							Poco::JSON::Parser P;
 | 
				
			||||||
		Poco::Dynamic::Var result = P.parse(D);
 | 
							Poco::Dynamic::Var result = P.parse(D);
 | 
				
			||||||
@@ -76,14 +68,12 @@ namespace OpenWifi::RESTAPI_utils {
 | 
				
			|||||||
		Obj.set(Field,Value);
 | 
							Obj.set(Field,Value);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline void field_to_json(Poco::JSON::Object &Obj, const char *Field,
 | 
						inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const Poco::Data::BLOB &Value) {
 | 
				
			||||||
							  const Poco::Data::BLOB &Value) {
 | 
					 | 
				
			||||||
		auto Result = Utils::base64encode((const unsigned char *)Value.rawContent(),Value.size());
 | 
							auto Result = Utils::base64encode((const unsigned char *)Value.rawContent(),Value.size());
 | 
				
			||||||
		Obj.set(Field,Result);
 | 
							Obj.set(Field,Result);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline void field_to_json(Poco::JSON::Object &Obj, const char *Field,
 | 
						inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const Types::StringPairVec & S) {
 | 
				
			||||||
							  const Types::StringPairVec &S) {
 | 
					 | 
				
			||||||
		Poco::JSON::Array   Array;
 | 
							Poco::JSON::Array   Array;
 | 
				
			||||||
		for(const auto &i:S) {
 | 
							for(const auto &i:S) {
 | 
				
			||||||
			Poco::JSON::Object  O;
 | 
								Poco::JSON::Object  O;
 | 
				
			||||||
@@ -94,8 +84,7 @@ namespace OpenWifi::RESTAPI_utils {
 | 
				
			|||||||
		Obj.set(Field,Array);
 | 
							Obj.set(Field,Array);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline void field_to_json(Poco::JSON::Object &Obj, const char *Field,
 | 
						inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const Types::StringVec &V) {
 | 
				
			||||||
							  const Types::StringVec &V) {
 | 
					 | 
				
			||||||
		Poco::JSON::Array	A;
 | 
							Poco::JSON::Array	A;
 | 
				
			||||||
		for(const auto &i:V)
 | 
							for(const auto &i:V)
 | 
				
			||||||
			A.add(i);
 | 
								A.add(i);
 | 
				
			||||||
@@ -109,8 +98,7 @@ namespace OpenWifi::RESTAPI_utils {
 | 
				
			|||||||
		Obj.set(Field,A);
 | 
							Obj.set(Field,A);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline void field_to_json(Poco::JSON::Object &Obj, const char *Field,
 | 
						inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const Types::CountedMap &M) {
 | 
				
			||||||
							  const Types::CountedMap &M) {
 | 
					 | 
				
			||||||
		Poco::JSON::Array	A;
 | 
							Poco::JSON::Array	A;
 | 
				
			||||||
		for(const auto &[Key,Value]:M) {
 | 
							for(const auto &[Key,Value]:M) {
 | 
				
			||||||
			Poco::JSON::Object  O;
 | 
								Poco::JSON::Object  O;
 | 
				
			||||||
@@ -121,8 +109,7 @@ namespace OpenWifi::RESTAPI_utils {
 | 
				
			|||||||
		Obj.set(Field,A);
 | 
							Obj.set(Field,A);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline void field_to_json(Poco::JSON::Object &Obj, const char *Field,
 | 
						inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const Types::Counted3DMapSII &M) {
 | 
				
			||||||
							  const Types::Counted3DMapSII &M) {
 | 
					 | 
				
			||||||
		Poco::JSON::Array	A;
 | 
							Poco::JSON::Array	A;
 | 
				
			||||||
		for(const auto &[OrgName,MonthlyNumberMap]:M) {
 | 
							for(const auto &[OrgName,MonthlyNumberMap]:M) {
 | 
				
			||||||
			Poco::JSON::Object  OrgObject;
 | 
								Poco::JSON::Object  OrgObject;
 | 
				
			||||||
@@ -140,14 +127,14 @@ namespace OpenWifi::RESTAPI_utils {
 | 
				
			|||||||
		Obj.set(Field, A);
 | 
							Obj.set(Field, A);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	template <typename T>
 | 
						template<typename T> void field_to_json(Poco::JSON::Object &Obj,
 | 
				
			||||||
	void field_to_json(Poco::JSON::Object &Obj, const char *Field, const T &V,
 | 
										   const char *Field,
 | 
				
			||||||
 | 
										   const T &V,
 | 
				
			||||||
					   std::function<std::string(const T &)> F) {
 | 
										   std::function<std::string(const T &)> F) {
 | 
				
			||||||
		Obj.set(Field, F(V));
 | 
							Obj.set(Field, F(V));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	template <class T>
 | 
						template<class T> void field_to_json(Poco::JSON::Object &Obj, const char *Field, const std::vector<T> &Value) {
 | 
				
			||||||
	void field_to_json(Poco::JSON::Object &Obj, const char *Field, const std::vector<T> &Value) {
 | 
					 | 
				
			||||||
		Poco::JSON::Array Arr;
 | 
							Poco::JSON::Array Arr;
 | 
				
			||||||
		for(const auto &i:Value) {
 | 
							for(const auto &i:Value) {
 | 
				
			||||||
			Poco::JSON::Object	AO;
 | 
								Poco::JSON::Object	AO;
 | 
				
			||||||
@@ -157,8 +144,7 @@ namespace OpenWifi::RESTAPI_utils {
 | 
				
			|||||||
		Obj.set(Field, Arr);
 | 
							Obj.set(Field, Arr);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	template <class T>
 | 
						template<class T> void field_to_json(Poco::JSON::Object &Obj, const char *Field, const T &Value) {
 | 
				
			||||||
	void field_to_json(Poco::JSON::Object &Obj, const char *Field, const T &Value) {
 | 
					 | 
				
			||||||
		Poco::JSON::Object  Answer;
 | 
							Poco::JSON::Object  Answer;
 | 
				
			||||||
		Value.to_json(Answer);
 | 
							Value.to_json(Answer);
 | 
				
			||||||
		Obj.set(Field, Answer);
 | 
							Obj.set(Field, Answer);
 | 
				
			||||||
@@ -169,84 +155,71 @@ namespace OpenWifi::RESTAPI_utils {
 | 
				
			|||||||
	///////////////////////////
 | 
						///////////////////////////
 | 
				
			||||||
	///////////////////////////
 | 
						///////////////////////////
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	template <typename T>
 | 
						template<typename T> bool field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, T & V,
 | 
				
			||||||
	bool field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, T &V,
 | 
					 | 
				
			||||||
						 std::function<T(const std::string &)> F) {
 | 
											 std::function<T(const std::string &)> F) {
 | 
				
			||||||
		if(Obj->has(Field) && !Obj->isNull(Field))
 | 
							if(Obj->has(Field) && !Obj->isNull(Field))
 | 
				
			||||||
			V = F(Obj->get(Field).toString());
 | 
								V = F(Obj->get(Field).toString());
 | 
				
			||||||
		return true;
 | 
							return true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
 | 
						inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, std::string &S) {
 | 
				
			||||||
								std::string &S) {
 | 
					 | 
				
			||||||
		if(Obj->has(Field) && !Obj->isNull(Field))
 | 
							if(Obj->has(Field) && !Obj->isNull(Field))
 | 
				
			||||||
			S = Obj->get(Field).toString();
 | 
								S = Obj->get(Field).toString();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
 | 
						inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, double & Value) {
 | 
				
			||||||
								double &Value) {
 | 
					 | 
				
			||||||
		if(Obj->has(Field) && !Obj->isNull(Field))
 | 
							if(Obj->has(Field) && !Obj->isNull(Field))
 | 
				
			||||||
			Value = (double)Obj->get(Field);
 | 
								Value = (double)Obj->get(Field);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
 | 
						inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, float & Value) {
 | 
				
			||||||
								float &Value) {
 | 
					 | 
				
			||||||
		if(Obj->has(Field) && !Obj->isNull(Field))
 | 
							if(Obj->has(Field) && !Obj->isNull(Field))
 | 
				
			||||||
			Value = (float)Obj->get(Field);
 | 
								Value = (float)Obj->get(Field);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
 | 
						inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, bool &Value) {
 | 
				
			||||||
								bool &Value) {
 | 
					 | 
				
			||||||
		if(Obj->has(Field) && !Obj->isNull(Field))
 | 
							if(Obj->has(Field) && !Obj->isNull(Field))
 | 
				
			||||||
			Value = (Obj->get(Field).toString() == "true");
 | 
								Value = (Obj->get(Field).toString() == "true");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
 | 
						inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, int16_t &Value) {
 | 
				
			||||||
								int16_t &Value) {
 | 
					 | 
				
			||||||
		if(Obj->has(Field) && !Obj->isNull(Field))
 | 
							if(Obj->has(Field) && !Obj->isNull(Field))
 | 
				
			||||||
			Value = (int16_t)Obj->get(Field);
 | 
								Value = (int16_t)Obj->get(Field);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
 | 
						inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, int32_t &Value) {
 | 
				
			||||||
								int32_t &Value) {
 | 
					 | 
				
			||||||
		if(Obj->has(Field) && !Obj->isNull(Field))
 | 
							if(Obj->has(Field) && !Obj->isNull(Field))
 | 
				
			||||||
			Value = (int32_t) Obj->get(Field);
 | 
								Value = (int32_t) Obj->get(Field);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
 | 
						inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, int64_t &Value) {
 | 
				
			||||||
								int64_t &Value) {
 | 
					 | 
				
			||||||
		if(Obj->has(Field) && !Obj->isNull(Field))
 | 
							if(Obj->has(Field) && !Obj->isNull(Field))
 | 
				
			||||||
			Value = (int64_t)Obj->get(Field);
 | 
								Value = (int64_t)Obj->get(Field);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
 | 
						inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, uint16_t &Value) {
 | 
				
			||||||
								uint16_t &Value) {
 | 
					 | 
				
			||||||
		if(Obj->has(Field) && !Obj->isNull(Field))
 | 
							if(Obj->has(Field) && !Obj->isNull(Field))
 | 
				
			||||||
			Value = (uint16_t)Obj->get(Field);
 | 
								Value = (uint16_t)Obj->get(Field);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
 | 
						inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, uint32_t &Value) {
 | 
				
			||||||
								uint32_t &Value) {
 | 
					 | 
				
			||||||
		if(Obj->has(Field) && !Obj->isNull(Field))
 | 
							if(Obj->has(Field) && !Obj->isNull(Field))
 | 
				
			||||||
			Value = (uint32_t)Obj->get(Field);
 | 
								Value = (uint32_t)Obj->get(Field);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
 | 
						inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, uint64_t &Value) {
 | 
				
			||||||
								uint64_t &Value) {
 | 
					 | 
				
			||||||
		if(Obj->has(Field) && !Obj->isNull(Field))
 | 
							if(Obj->has(Field) && !Obj->isNull(Field))
 | 
				
			||||||
			Value = (uint64_t)Obj->get(Field);
 | 
								Value = (uint64_t)Obj->get(Field);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
 | 
						inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, Poco::Data::BLOB &Value) {
 | 
				
			||||||
								Poco::Data::BLOB &Value) {
 | 
					 | 
				
			||||||
		if(Obj->has(Field) && !Obj->isNull(Field)) {
 | 
							if(Obj->has(Field) && !Obj->isNull(Field)) {
 | 
				
			||||||
			auto Result = Utils::base64decode(Obj->get(Field).toString());
 | 
								auto Result = Utils::base64decode(Obj->get(Field).toString());
 | 
				
			||||||
			Value.assignRaw((const unsigned char *)&Result[0],Result.size());
 | 
								Value.assignRaw((const unsigned char *)&Result[0],Result.size());
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
 | 
						inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, Types::StringPairVec &Vec) {
 | 
				
			||||||
								Types::StringPairVec &Vec) {
 | 
					 | 
				
			||||||
		if(Obj->isArray(Field) && !Obj->isNull(Field)) {
 | 
							if(Obj->isArray(Field) && !Obj->isNull(Field)) {
 | 
				
			||||||
			auto O = Obj->getArray(Field);
 | 
								auto O = Obj->getArray(Field);
 | 
				
			||||||
			for(const auto &i:*O) {
 | 
								for(const auto &i:*O) {
 | 
				
			||||||
@@ -262,8 +235,7 @@ namespace OpenWifi::RESTAPI_utils {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
 | 
						inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, Types::StringVec &Value) {
 | 
				
			||||||
								Types::StringVec &Value) {
 | 
					 | 
				
			||||||
		if(Obj->isArray(Field) && !Obj->isNull(Field)) {
 | 
							if(Obj->isArray(Field) && !Obj->isNull(Field)) {
 | 
				
			||||||
			Value.clear();
 | 
								Value.clear();
 | 
				
			||||||
			Poco::JSON::Array::Ptr A = Obj->getArray(Field);
 | 
								Poco::JSON::Array::Ptr A = Obj->getArray(Field);
 | 
				
			||||||
@@ -273,8 +245,7 @@ namespace OpenWifi::RESTAPI_utils {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
 | 
						inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, Types::TagList &Value) {
 | 
				
			||||||
								Types::TagList &Value) {
 | 
					 | 
				
			||||||
		if(Obj->isArray(Field) && !Obj->isNull(Field)) {
 | 
							if(Obj->isArray(Field) && !Obj->isNull(Field)) {
 | 
				
			||||||
			Value.clear();
 | 
								Value.clear();
 | 
				
			||||||
			Poco::JSON::Array::Ptr A = Obj->getArray(Field);
 | 
								Poco::JSON::Array::Ptr A = Obj->getArray(Field);
 | 
				
			||||||
@@ -284,9 +255,7 @@ namespace OpenWifi::RESTAPI_utils {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	template <class T>
 | 
						template<class T> void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, std::vector<T> &Value) {
 | 
				
			||||||
	void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
 | 
					 | 
				
			||||||
						 std::vector<T> &Value) {
 | 
					 | 
				
			||||||
		if(Obj->isArray(Field) && !Obj->isNull(Field)) {
 | 
							if(Obj->isArray(Field) && !Obj->isNull(Field)) {
 | 
				
			||||||
			Poco::JSON::Array::Ptr	Arr = Obj->getArray(Field);
 | 
								Poco::JSON::Array::Ptr	Arr = Obj->getArray(Field);
 | 
				
			||||||
			for(auto &i:*Arr) {
 | 
								for(auto &i:*Arr) {
 | 
				
			||||||
@@ -298,8 +267,7 @@ namespace OpenWifi::RESTAPI_utils {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	template <class T>
 | 
						template<class T> void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, T &Value) {
 | 
				
			||||||
	void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field, T &Value) {
 | 
					 | 
				
			||||||
		if(Obj->isObject(Field) && !Obj->isNull(Field)) {
 | 
							if(Obj->isObject(Field) && !Obj->isNull(Field)) {
 | 
				
			||||||
			Poco::JSON::Object::Ptr	A = Obj->getObject(Field);
 | 
								Poco::JSON::Object::Ptr	A = Obj->getObject(Field);
 | 
				
			||||||
			Value.from_json(A);
 | 
								Value.from_json(A);
 | 
				
			||||||
@@ -368,8 +336,7 @@ namespace OpenWifi::RESTAPI_utils {
 | 
				
			|||||||
			for(auto const &j:i) {
 | 
								for(auto const &j:i) {
 | 
				
			||||||
				if constexpr(std::is_integral<T>::value) {
 | 
									if constexpr(std::is_integral<T>::value) {
 | 
				
			||||||
					InnerArr.add(j);
 | 
										InnerArr.add(j);
 | 
				
			||||||
				}
 | 
									} if constexpr(std::is_same_v<T,std::string>) {
 | 
				
			||||||
				if constexpr (std::is_same_v<T, std::string>) {
 | 
					 | 
				
			||||||
					InnerArr.add(j);
 | 
										InnerArr.add(j);
 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					InnerArr.add(j);
 | 
										InnerArr.add(j);
 | 
				
			||||||
@@ -406,6 +373,7 @@ namespace OpenWifi::RESTAPI_utils {
 | 
				
			|||||||
				Result.push_back(i.toString());
 | 
									Result.push_back(i.toString());
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		} catch (...) {
 | 
							} catch (...) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return Result;
 | 
							return Result;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -422,6 +390,7 @@ namespace OpenWifi::RESTAPI_utils {
 | 
				
			|||||||
				Result.push_back(i);
 | 
									Result.push_back(i);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		} catch (...) {
 | 
							} catch (...) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return Result;
 | 
							return Result;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -442,6 +411,7 @@ namespace OpenWifi::RESTAPI_utils {
 | 
				
			|||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		} catch (...) {
 | 
							} catch (...) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		return R;
 | 
							return R;
 | 
				
			||||||
@@ -462,12 +432,12 @@ namespace OpenWifi::RESTAPI_utils {
 | 
				
			|||||||
				Result.push_back(Obj);
 | 
									Result.push_back(Obj);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		} catch (...) {
 | 
							} catch (...) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return Result;
 | 
							return Result;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	template <class T>
 | 
						template<class T> std::vector<std::vector<T>> to_array_of_array_of_object(const std::string & ObjectString) {
 | 
				
			||||||
	std::vector<std::vector<T>> to_array_of_array_of_object(const std::string &ObjectString) {
 | 
					 | 
				
			||||||
		std::vector<std::vector<T>>	Result;
 | 
							std::vector<std::vector<T>>	Result;
 | 
				
			||||||
		if(ObjectString.empty())
 | 
							if(ObjectString.empty())
 | 
				
			||||||
			return Result;
 | 
								return Result;
 | 
				
			||||||
@@ -487,6 +457,7 @@ namespace OpenWifi::RESTAPI_utils {
 | 
				
			|||||||
				Result.push_back(InnerVector);
 | 
									Result.push_back(InnerVector);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		} catch (...) {
 | 
							} catch (...) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return Result;
 | 
							return Result;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -510,4 +481,4 @@ namespace OpenWifi::RESTAPI_utils {
 | 
				
			|||||||
		Obj.from_json(RawObject);
 | 
							Obj.from_json(RawObject);
 | 
				
			||||||
		return true;
 | 
							return true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
} // namespace OpenWifi::RESTAPI_utils
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,25 +4,32 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "Poco/Data/SQLite/Connector.h"
 | 
					 | 
				
			||||||
#include "Poco/Data/Session.h"
 | 
					#include "Poco/Data/Session.h"
 | 
				
			||||||
#include "Poco/Data/SessionPool.h"
 | 
					#include "Poco/Data/SessionPool.h"
 | 
				
			||||||
 | 
					#include "Poco/Data/SQLite/Connector.h"
 | 
				
			||||||
#include "Poco/JSON/Object.h"
 | 
					#include "Poco/JSON/Object.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifndef SMALL_BUILD
 | 
					#ifndef SMALL_BUILD
 | 
				
			||||||
#include "Poco/Data/MySQL/Connector.h"
 | 
					 | 
				
			||||||
#include "Poco/Data/PostgreSQL/Connector.h"
 | 
					#include "Poco/Data/PostgreSQL/Connector.h"
 | 
				
			||||||
 | 
					#include "Poco/Data/MySQL/Connector.h"
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "framework/MicroServiceFuncs.h"
 | 
					 | 
				
			||||||
#include "framework/SubSystemServer.h"
 | 
					#include "framework/SubSystemServer.h"
 | 
				
			||||||
 | 
					#include "framework/MicroServiceFuncs.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
	enum DBType { sqlite, pgsql, mysql };
 | 
					    enum DBType {
 | 
				
			||||||
 | 
					        sqlite,
 | 
				
			||||||
 | 
					        pgsql,
 | 
				
			||||||
 | 
					        mysql
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    class StorageClass : public SubSystemServer {
 | 
					    class StorageClass : public SubSystemServer {
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
		StorageClass() noexcept : SubSystemServer("StorageClass", "STORAGE-SVR", "storage") {}
 | 
					        StorageClass() noexcept:
 | 
				
			||||||
 | 
					            SubSystemServer("StorageClass", "STORAGE-SVR", "storage")
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        int Start() override {
 | 
					        int Start() override {
 | 
				
			||||||
            std::lock_guard		Guard(Mutex_);
 | 
					            std::lock_guard		Guard(Mutex_);
 | 
				
			||||||
@@ -40,10 +47,11 @@ namespace OpenWifi {
 | 
				
			|||||||
            return 0;
 | 
					            return 0;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		void Stop() override { Pool_->shutdown(); }
 | 
					        void Stop() override {
 | 
				
			||||||
 | 
					            Pool_->shutdown();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        DBType Type() const { return dbType_; };
 | 
					        DBType Type() const { return dbType_; };
 | 
				
			||||||
 | 
					 | 
				
			||||||
    private:
 | 
					    private:
 | 
				
			||||||
        inline int Setup_SQLite();
 | 
					        inline int Setup_SQLite();
 | 
				
			||||||
        inline int Setup_MySQL();
 | 
					        inline int Setup_MySQL();
 | 
				
			||||||
@@ -58,29 +66,20 @@ namespace OpenWifi {
 | 
				
			|||||||
    };
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef	SMALL_BUILD
 | 
					#ifdef	SMALL_BUILD
 | 
				
			||||||
	int Service::Setup_MySQL() {
 | 
					    int Service::Setup_MySQL() { Daemon()->exit(Poco::Util::Application::EXIT_CONFIG); return 0; }
 | 
				
			||||||
		Daemon()->exit(Poco::Util::Application::EXIT_CONFIG);
 | 
					    int Service::Setup_PostgreSQL() { Daemon()->exit(Poco::Util::Application::EXIT_CONFIG); return 0; }
 | 
				
			||||||
		return 0;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	int Service::Setup_PostgreSQL() {
 | 
					 | 
				
			||||||
		Daemon()->exit(Poco::Util::Application::EXIT_CONFIG);
 | 
					 | 
				
			||||||
		return 0;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    inline int StorageClass::Setup_SQLite() {
 | 
					    inline int StorageClass::Setup_SQLite() {
 | 
				
			||||||
        Logger().notice("SQLite StorageClass enabled.");
 | 
					        Logger().notice("SQLite StorageClass enabled.");
 | 
				
			||||||
        dbType_ = sqlite;
 | 
					        dbType_ = sqlite;
 | 
				
			||||||
		auto DBName = MicroServiceDataDirectory() + "/" +
 | 
					        auto DBName = MicroServiceDataDirectory() + "/" + MicroServiceConfigGetString("storage.type.sqlite.db","");
 | 
				
			||||||
					  MicroServiceConfigGetString("storage.type.sqlite.db", "");
 | 
					 | 
				
			||||||
        int NumSessions = (int) MicroServiceConfigGetInt("storage.type.sqlite.maxsessions", 64);
 | 
					        int NumSessions = (int) MicroServiceConfigGetInt("storage.type.sqlite.maxsessions", 64);
 | 
				
			||||||
        int IdleTime = (int) MicroServiceConfigGetInt("storage.type.sqlite.idletime", 60);
 | 
					        int IdleTime = (int) MicroServiceConfigGetInt("storage.type.sqlite.idletime", 60);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Poco::Data::SQLite::Connector::registerConnector();
 | 
					        Poco::Data::SQLite::Connector::registerConnector();
 | 
				
			||||||
		//        Pool_ = std::make_unique<Poco::Data::SessionPool>(new
 | 
					//        Pool_ = std::make_unique<Poco::Data::SessionPool>(new Poco::Data::SessionPool(SQLiteConn_.name(), DBName, 8,
 | 
				
			||||||
		//        Poco::Data::SessionPool(SQLiteConn_.name(), DBName, 8,
 | 
					//                                                                                     (int)NumSessions, (int)IdleTime));
 | 
				
			||||||
		//                                                                                     (int)NumSessions,
 | 
					 | 
				
			||||||
		//                                                                                     (int)IdleTime));
 | 
					 | 
				
			||||||
        Pool_ = std::make_unique<Poco::Data::SessionPool>(SQLiteConn_.name(), DBName, 8,
 | 
					        Pool_ = std::make_unique<Poco::Data::SessionPool>(SQLiteConn_.name(), DBName, 8,
 | 
				
			||||||
                                                                                     (int)NumSessions, (int)IdleTime);
 | 
					                                                                                     (int)NumSessions, (int)IdleTime);
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
@@ -97,13 +96,16 @@ namespace OpenWifi {
 | 
				
			|||||||
        auto Database = MicroServiceConfigGetString("storage.type.mysql.database","");
 | 
					        auto Database = MicroServiceConfigGetString("storage.type.mysql.database","");
 | 
				
			||||||
        auto Port = MicroServiceConfigGetString("storage.type.mysql.port","");
 | 
					        auto Port = MicroServiceConfigGetString("storage.type.mysql.port","");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		std::string ConnectionStr = "host=" + Host + ";user=" + Username + ";password=" + Password +
 | 
					        std::string ConnectionStr =
 | 
				
			||||||
									";db=" + Database + ";port=" + Port +
 | 
					                "host=" + Host +
 | 
				
			||||||
 | 
					                ";user=" + Username +
 | 
				
			||||||
 | 
					                ";password=" + Password +
 | 
				
			||||||
 | 
					                ";db=" + Database +
 | 
				
			||||||
 | 
					                ";port=" + Port +
 | 
				
			||||||
                ";compress=true;auto-reconnect=true";
 | 
					                ";compress=true;auto-reconnect=true";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Poco::Data::MySQL::Connector::registerConnector();
 | 
					        Poco::Data::MySQL::Connector::registerConnector();
 | 
				
			||||||
		Pool_ = std::make_unique<Poco::Data::SessionPool>(MySQLConn_.name(), ConnectionStr, 8,
 | 
					        Pool_ = std::make_unique<Poco::Data::SessionPool>(MySQLConn_.name(), ConnectionStr, 8, NumSessions, IdleTime);
 | 
				
			||||||
														  NumSessions, IdleTime);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -118,19 +120,21 @@ namespace OpenWifi {
 | 
				
			|||||||
        auto Password = MicroServiceConfigGetString("storage.type.postgresql.password", "");
 | 
					        auto Password = MicroServiceConfigGetString("storage.type.postgresql.password", "");
 | 
				
			||||||
        auto Database = MicroServiceConfigGetString("storage.type.postgresql.database", "");
 | 
					        auto Database = MicroServiceConfigGetString("storage.type.postgresql.database", "");
 | 
				
			||||||
        auto Port = MicroServiceConfigGetString("storage.type.postgresql.port", "");
 | 
					        auto Port = MicroServiceConfigGetString("storage.type.postgresql.port", "");
 | 
				
			||||||
		auto ConnectionTimeout =
 | 
					        auto ConnectionTimeout = MicroServiceConfigGetString("storage.type.postgresql.connectiontimeout", "");
 | 
				
			||||||
			MicroServiceConfigGetString("storage.type.postgresql.connectiontimeout", "");
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		std::string ConnectionStr = "host=" + Host + " user=" + Username + " password=" + Password +
 | 
					        std::string ConnectionStr =
 | 
				
			||||||
									" dbname=" + Database + " port=" + Port +
 | 
					                "host=" + Host +
 | 
				
			||||||
 | 
					                " user=" + Username +
 | 
				
			||||||
 | 
					                " password=" + Password +
 | 
				
			||||||
 | 
					                " dbname=" + Database +
 | 
				
			||||||
 | 
					                " port=" + Port +
 | 
				
			||||||
                " connect_timeout=" + ConnectionTimeout;
 | 
					                " connect_timeout=" + ConnectionTimeout;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Poco::Data::PostgreSQL::Connector::registerConnector();
 | 
					        Poco::Data::PostgreSQL::Connector::registerConnector();
 | 
				
			||||||
		Pool_ = std::make_unique<Poco::Data::SessionPool>(PostgresConn_.name(), ConnectionStr, 8,
 | 
					        Pool_ = std::make_unique<Poco::Data::SessionPool>(PostgresConn_.name(), ConnectionStr, 8, NumSessions, IdleTime);
 | 
				
			||||||
														  NumSessions, IdleTime);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return 0;
 | 
					        return 0;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace OpenWifi
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,29 +6,36 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "framework/SubSystemServer.h"
 | 
					#include "framework/SubSystemServer.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "Poco/DateTimeFormat.h"
 | 
					 | 
				
			||||||
#include "Poco/DateTimeFormatter.h"
 | 
					 | 
				
			||||||
#include "Poco/Net/SSLManager.h"
 | 
					#include "Poco/Net/SSLManager.h"
 | 
				
			||||||
 | 
					#include "Poco/DateTimeFormatter.h"
 | 
				
			||||||
 | 
					#include "Poco/DateTimeFormat.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "framework/MicroServiceFuncs.h"
 | 
					#include "framework/MicroServiceFuncs.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	PropertiesFileServerEntry::PropertiesFileServerEntry(
 | 
						PropertiesFileServerEntry::PropertiesFileServerEntry(std::string Address, uint32_t port, std::string Key_file,
 | 
				
			||||||
		std::string Address, uint32_t port, std::string Key_file, std::string Cert_file,
 | 
												  std::string Cert_file, std::string RootCa, std::string Issuer,
 | 
				
			||||||
		std::string RootCa, std::string Issuer, std::string ClientCas, std::string Cas,
 | 
												  std::string ClientCas, std::string Cas,
 | 
				
			||||||
		std::string Key_file_password, std::string Name, Poco::Net::Context::VerificationMode M,
 | 
												  std::string Key_file_password, std::string Name,
 | 
				
			||||||
 | 
												  Poco::Net::Context::VerificationMode M,
 | 
				
			||||||
							  int backlog)
 | 
												  int backlog)
 | 
				
			||||||
		: address_(std::move(Address)), port_(port), cert_file_(std::move(Cert_file)),
 | 
							: address_(std::move(Address)),
 | 
				
			||||||
		  key_file_(std::move(Key_file)), root_ca_(std::move(RootCa)),
 | 
							  port_(port),
 | 
				
			||||||
		  key_file_password_(std::move(Key_file_password)), issuer_cert_file_(std::move(Issuer)),
 | 
							  cert_file_(std::move(Cert_file)),
 | 
				
			||||||
		  client_cas_(std::move(ClientCas)), cas_(std::move(Cas)), name_(std::move(Name)),
 | 
							  key_file_(std::move(Key_file)),
 | 
				
			||||||
		  backlog_(backlog), level_(M){
 | 
							  root_ca_(std::move(RootCa)),
 | 
				
			||||||
 | 
							  key_file_password_(std::move(Key_file_password)),
 | 
				
			||||||
 | 
							  issuer_cert_file_(std::move(Issuer)),
 | 
				
			||||||
 | 
							  client_cas_(std::move(ClientCas)),
 | 
				
			||||||
 | 
							  cas_(std::move(Cas)),
 | 
				
			||||||
 | 
							  name_(std::move(Name)),
 | 
				
			||||||
 | 
							  backlog_(backlog),
 | 
				
			||||||
 | 
							  level_(M) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	  };
 | 
						  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	[[nodiscard]] Poco::Net::SecureServerSocket
 | 
						[[nodiscard]] Poco::Net::SecureServerSocket PropertiesFileServerEntry::CreateSecureSocket(Poco::Logger &L) const {
 | 
				
			||||||
	PropertiesFileServerEntry::CreateSecureSocket(Poco::Logger &L) const {
 | 
					 | 
				
			||||||
		Poco::Net::Context::Params P;
 | 
							Poco::Net::Context::Params P;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		P.verificationMode = level_;
 | 
							P.verificationMode = level_;
 | 
				
			||||||
@@ -38,12 +45,10 @@ namespace OpenWifi {
 | 
				
			|||||||
		P.dhUse2048Bits = true;
 | 
							P.dhUse2048Bits = true;
 | 
				
			||||||
		P.caLocation = cas_;
 | 
							P.caLocation = cas_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		auto Context = Poco::AutoPtr<Poco::Net::Context>(
 | 
							auto Context = Poco::AutoPtr<Poco::Net::Context>(new Poco::Net::Context(Poco::Net::Context::TLS_SERVER_USE, P));
 | 
				
			||||||
			new Poco::Net::Context(Poco::Net::Context::TLS_SERVER_USE, P));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if(!key_file_password_.empty()) {
 | 
							if(!key_file_password_.empty()) {
 | 
				
			||||||
			auto PassphraseHandler = Poco::SharedPtr<MyPrivateKeyPassphraseHandler>(
 | 
								auto PassphraseHandler = Poco::SharedPtr<MyPrivateKeyPassphraseHandler>( new MyPrivateKeyPassphraseHandler(key_file_password_,L));
 | 
				
			||||||
				new MyPrivateKeyPassphraseHandler(key_file_password_, L));
 | 
					 | 
				
			||||||
			Poco::Net::SSLManager::instance().initializeServer(PassphraseHandler, nullptr,Context);
 | 
								Poco::Net::SSLManager::instance().initializeServer(PassphraseHandler, nullptr,Context);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -106,8 +111,7 @@ namespace OpenWifi {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	[[nodiscard]] Poco::Net::ServerSocket
 | 
						[[nodiscard]] Poco::Net::ServerSocket PropertiesFileServerEntry::CreateSocket([[maybe_unused]] Poco::Logger &L) const {
 | 
				
			||||||
	PropertiesFileServerEntry::CreateSocket([[maybe_unused]] Poco::Logger &L) const {
 | 
					 | 
				
			||||||
		Poco::Net::Context::Params P;
 | 
							Poco::Net::Context::Params P;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (address_ == "*") {
 | 
							if (address_ == "*") {
 | 
				
			||||||
@@ -123,24 +127,19 @@ namespace OpenWifi {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void PropertiesFileServerEntry::LogCertInfo(Poco::Logger &L,
 | 
						void PropertiesFileServerEntry::LogCertInfo(Poco::Logger &L, const Poco::Crypto::X509Certificate &C) const {
 | 
				
			||||||
												const Poco::Crypto::X509Certificate &C) const {
 | 
							L.information("=============================================================================================");
 | 
				
			||||||
		L.information("============================================================================"
 | 
					 | 
				
			||||||
					  "=================");
 | 
					 | 
				
			||||||
		L.information(fmt::format(">          Issuer: {}", C.issuerName()));
 | 
							L.information(fmt::format(">          Issuer: {}", C.issuerName()));
 | 
				
			||||||
		L.information("----------------------------------------------------------------------------"
 | 
							L.information("---------------------------------------------------------------------------------------------");
 | 
				
			||||||
					  "-----------------");
 | 
					 | 
				
			||||||
		L.information(fmt::format(">     Common Name: {}",
 | 
							L.information(fmt::format(">     Common Name: {}",
 | 
				
			||||||
								  C.issuerName(Poco::Crypto::X509Certificate::NID_COMMON_NAME)));
 | 
													  C.issuerName(Poco::Crypto::X509Certificate::NID_COMMON_NAME)));
 | 
				
			||||||
		L.information(fmt::format(">         Country: {}",
 | 
							L.information(fmt::format(">         Country: {}",
 | 
				
			||||||
								  C.issuerName(Poco::Crypto::X509Certificate::NID_COUNTRY)));
 | 
													  C.issuerName(Poco::Crypto::X509Certificate::NID_COUNTRY)));
 | 
				
			||||||
		L.information(fmt::format(">        Locality: {}",
 | 
							L.information(fmt::format(">        Locality: {}",
 | 
				
			||||||
								  C.issuerName(Poco::Crypto::X509Certificate::NID_LOCALITY_NAME)));
 | 
													  C.issuerName(Poco::Crypto::X509Certificate::NID_LOCALITY_NAME)));
 | 
				
			||||||
		L.information(
 | 
							L.information(fmt::format(">      State/Prov: {}",
 | 
				
			||||||
			fmt::format(">      State/Prov: {}",
 | 
					 | 
				
			||||||
								  C.issuerName(Poco::Crypto::X509Certificate::NID_STATE_OR_PROVINCE)));
 | 
													  C.issuerName(Poco::Crypto::X509Certificate::NID_STATE_OR_PROVINCE)));
 | 
				
			||||||
		L.information(
 | 
							L.information(fmt::format(">        Org name: {}",
 | 
				
			||||||
			fmt::format(">        Org name: {}",
 | 
					 | 
				
			||||||
								  C.issuerName(Poco::Crypto::X509Certificate::NID_ORGANIZATION_NAME)));
 | 
													  C.issuerName(Poco::Crypto::X509Certificate::NID_ORGANIZATION_NAME)));
 | 
				
			||||||
		L.information(
 | 
							L.information(
 | 
				
			||||||
			fmt::format(">        Org unit: {}",
 | 
								fmt::format(">        Org unit: {}",
 | 
				
			||||||
@@ -150,11 +149,9 @@ namespace OpenWifi {
 | 
				
			|||||||
						C.issuerName(Poco::Crypto::X509Certificate::NID_PKCS9_EMAIL_ADDRESS)));
 | 
											C.issuerName(Poco::Crypto::X509Certificate::NID_PKCS9_EMAIL_ADDRESS)));
 | 
				
			||||||
		L.information(fmt::format(">         Serial#: {}",
 | 
							L.information(fmt::format(">         Serial#: {}",
 | 
				
			||||||
								  C.issuerName(Poco::Crypto::X509Certificate::NID_SERIAL_NUMBER)));
 | 
													  C.issuerName(Poco::Crypto::X509Certificate::NID_SERIAL_NUMBER)));
 | 
				
			||||||
		L.information("----------------------------------------------------------------------------"
 | 
							L.information("---------------------------------------------------------------------------------------------");
 | 
				
			||||||
					  "-----------------");
 | 
					 | 
				
			||||||
		L.information(fmt::format(">         Subject: {}", C.subjectName()));
 | 
							L.information(fmt::format(">         Subject: {}", C.subjectName()));
 | 
				
			||||||
		L.information("----------------------------------------------------------------------------"
 | 
							L.information("---------------------------------------------------------------------------------------------");
 | 
				
			||||||
					  "-----------------");
 | 
					 | 
				
			||||||
		L.information(fmt::format(">     Common Name: {}",
 | 
							L.information(fmt::format(">     Common Name: {}",
 | 
				
			||||||
								  C.subjectName(Poco::Crypto::X509Certificate::NID_COMMON_NAME)));
 | 
													  C.subjectName(Poco::Crypto::X509Certificate::NID_COMMON_NAME)));
 | 
				
			||||||
		L.information(fmt::format(">         Country: {}",
 | 
							L.information(fmt::format(">         Country: {}",
 | 
				
			||||||
@@ -175,66 +172,52 @@ namespace OpenWifi {
 | 
				
			|||||||
						C.subjectName(Poco::Crypto::X509Certificate::NID_PKCS9_EMAIL_ADDRESS)));
 | 
											C.subjectName(Poco::Crypto::X509Certificate::NID_PKCS9_EMAIL_ADDRESS)));
 | 
				
			||||||
		L.information(fmt::format(">         Serial#: {}",
 | 
							L.information(fmt::format(">         Serial#: {}",
 | 
				
			||||||
								  C.subjectName(Poco::Crypto::X509Certificate::NID_SERIAL_NUMBER)));
 | 
													  C.subjectName(Poco::Crypto::X509Certificate::NID_SERIAL_NUMBER)));
 | 
				
			||||||
		L.information("----------------------------------------------------------------------------"
 | 
							L.information("---------------------------------------------------------------------------------------------");
 | 
				
			||||||
					  "-----------------");
 | 
					 | 
				
			||||||
		L.information(fmt::format(">  Signature Algo: {}", C.signatureAlgorithm()));
 | 
							L.information(fmt::format(">  Signature Algo: {}", C.signatureAlgorithm()));
 | 
				
			||||||
		auto From =
 | 
							auto From = Poco::DateTimeFormatter::format(C.validFrom(), Poco::DateTimeFormat::HTTP_FORMAT);
 | 
				
			||||||
			Poco::DateTimeFormatter::format(C.validFrom(), Poco::DateTimeFormat::HTTP_FORMAT);
 | 
					 | 
				
			||||||
		L.information(fmt::format(">      Valid from: {}", From));
 | 
							L.information(fmt::format(">      Valid from: {}", From));
 | 
				
			||||||
		auto Expires =
 | 
							auto Expires =
 | 
				
			||||||
			Poco::DateTimeFormatter::format(C.expiresOn(), Poco::DateTimeFormat::HTTP_FORMAT);
 | 
								Poco::DateTimeFormatter::format(C.expiresOn(), Poco::DateTimeFormat::HTTP_FORMAT);
 | 
				
			||||||
		L.information(fmt::format(">      Expires on: {}", Expires));
 | 
							L.information(fmt::format(">      Expires on: {}", Expires));
 | 
				
			||||||
		L.information(fmt::format(">         Version: {}", (int)C.version()));
 | 
							L.information(fmt::format(">         Version: {}", (int)C.version()));
 | 
				
			||||||
		L.information(fmt::format(">        Serial #: {}", C.serialNumber()));
 | 
							L.information(fmt::format(">        Serial #: {}", C.serialNumber()));
 | 
				
			||||||
		L.information("============================================================================"
 | 
							L.information("=============================================================================================");
 | 
				
			||||||
					  "=================");
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void PropertiesFileServerEntry::LogCert(Poco::Logger &L) const {
 | 
						void PropertiesFileServerEntry::LogCert(Poco::Logger &L) const {
 | 
				
			||||||
		try {
 | 
							try {
 | 
				
			||||||
			Poco::Crypto::X509Certificate C(cert_file_);
 | 
								Poco::Crypto::X509Certificate C(cert_file_);
 | 
				
			||||||
			L.information("========================================================================"
 | 
								L.information("=============================================================================================");
 | 
				
			||||||
						  "=====================");
 | 
								L.information("=============================================================================================");
 | 
				
			||||||
			L.information("========================================================================"
 | 
					 | 
				
			||||||
						  "=====================");
 | 
					 | 
				
			||||||
			L.information(fmt::format("Certificate Filename: {}", cert_file_));
 | 
								L.information(fmt::format("Certificate Filename: {}", cert_file_));
 | 
				
			||||||
			LogCertInfo(L, C);
 | 
								LogCertInfo(L, C);
 | 
				
			||||||
			L.information("========================================================================"
 | 
								L.information("=============================================================================================");
 | 
				
			||||||
						  "=====================");
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (!issuer_cert_file_.empty()) {
 | 
								if (!issuer_cert_file_.empty()) {
 | 
				
			||||||
				Poco::Crypto::X509Certificate C1(issuer_cert_file_);
 | 
									Poco::Crypto::X509Certificate C1(issuer_cert_file_);
 | 
				
			||||||
				L.information("===================================================================="
 | 
									L.information("=============================================================================================");
 | 
				
			||||||
							  "=========================");
 | 
									L.information("=============================================================================================");
 | 
				
			||||||
				L.information("===================================================================="
 | 
					 | 
				
			||||||
							  "=========================");
 | 
					 | 
				
			||||||
				L.information(fmt::format("Issues Certificate Filename: {}", issuer_cert_file_));
 | 
									L.information(fmt::format("Issues Certificate Filename: {}", issuer_cert_file_));
 | 
				
			||||||
				LogCertInfo(L, C1);
 | 
									LogCertInfo(L, C1);
 | 
				
			||||||
				L.information("===================================================================="
 | 
									L.information("=============================================================================================");
 | 
				
			||||||
							  "=========================");
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (!client_cas_.empty()) {
 | 
								if (!client_cas_.empty()) {
 | 
				
			||||||
				std::vector<Poco::Crypto::X509Certificate> Certs =
 | 
									std::vector<Poco::Crypto::X509Certificate> Certs =
 | 
				
			||||||
					Poco::Net::X509Certificate::readPEM(client_cas_);
 | 
										Poco::Net::X509Certificate::readPEM(client_cas_);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				L.information("===================================================================="
 | 
									L.information("=============================================================================================");
 | 
				
			||||||
							  "=========================");
 | 
									L.information("=============================================================================================");
 | 
				
			||||||
				L.information("===================================================================="
 | 
					 | 
				
			||||||
							  "=========================");
 | 
					 | 
				
			||||||
				L.information(fmt::format("Client CAs Filename: {}", client_cas_));
 | 
									L.information(fmt::format("Client CAs Filename: {}", client_cas_));
 | 
				
			||||||
				L.information("===================================================================="
 | 
									L.information("=============================================================================================");
 | 
				
			||||||
							  "=========================");
 | 
					 | 
				
			||||||
				auto i = 1;
 | 
									auto i = 1;
 | 
				
			||||||
				for (const auto &C3 : Certs) {
 | 
									for (const auto &C3 : Certs) {
 | 
				
			||||||
					L.information(fmt::format(" Index: {}", i));
 | 
										L.information(fmt::format(" Index: {}", i));
 | 
				
			||||||
					L.information("================================================================"
 | 
										L.information("=============================================================================================");
 | 
				
			||||||
								  "=============================");
 | 
					 | 
				
			||||||
					LogCertInfo(L, C3);
 | 
										LogCertInfo(L, C3);
 | 
				
			||||||
					i++;
 | 
										i++;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				L.information("===================================================================="
 | 
									L.information("=============================================================================================");
 | 
				
			||||||
							  "=========================");
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		} catch (const Poco::Exception &E) {
 | 
							} catch (const Poco::Exception &E) {
 | 
				
			||||||
@@ -247,31 +230,28 @@ namespace OpenWifi {
 | 
				
			|||||||
			std::vector<Poco::Crypto::X509Certificate> Certs =
 | 
								std::vector<Poco::Crypto::X509Certificate> Certs =
 | 
				
			||||||
				Poco::Net::X509Certificate::readPEM(root_ca_);
 | 
									Poco::Net::X509Certificate::readPEM(root_ca_);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			L.information("========================================================================"
 | 
								L.information("=============================================================================================");
 | 
				
			||||||
						  "=====================");
 | 
								L.information("=============================================================================================");
 | 
				
			||||||
			L.information("========================================================================"
 | 
					 | 
				
			||||||
						  "=====================");
 | 
					 | 
				
			||||||
			L.information(fmt::format("CA Filename: {}", root_ca_));
 | 
								L.information(fmt::format("CA Filename: {}", root_ca_));
 | 
				
			||||||
			L.information("========================================================================"
 | 
								L.information("=============================================================================================");
 | 
				
			||||||
						  "=====================");
 | 
					 | 
				
			||||||
			auto i = 1;
 | 
								auto i = 1;
 | 
				
			||||||
			for (const auto &C : Certs) {
 | 
								for (const auto &C : Certs) {
 | 
				
			||||||
				L.information(fmt::format(" Index: {}", i));
 | 
									L.information(fmt::format(" Index: {}", i));
 | 
				
			||||||
				L.information("===================================================================="
 | 
									L.information("=============================================================================================");
 | 
				
			||||||
							  "=========================");
 | 
					 | 
				
			||||||
				LogCertInfo(L, C);
 | 
									LogCertInfo(L, C);
 | 
				
			||||||
				i++;
 | 
									i++;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			L.information("========================================================================"
 | 
								L.information("=============================================================================================");
 | 
				
			||||||
						  "=====================");
 | 
					 | 
				
			||||||
		} catch (const Poco::Exception &E) {
 | 
							} catch (const Poco::Exception &E) {
 | 
				
			||||||
			L.log(E);
 | 
								L.log(E);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	SubSystemServer::SubSystemServer(const std::string &Name, const std::string &LoggingPrefix,
 | 
						SubSystemServer::SubSystemServer(const std::string &Name, const std::string &LoggingPrefix,
 | 
				
			||||||
									 const std::string &SubSystemConfigPrefix)
 | 
																const std::string &SubSystemConfigPrefix):
 | 
				
			||||||
		: Name_(Name), LoggerPrefix_(LoggingPrefix), SubSystemConfigPrefix_(SubSystemConfigPrefix) {
 | 
							Name_(Name),
 | 
				
			||||||
 | 
							LoggerPrefix_(LoggingPrefix),
 | 
				
			||||||
 | 
							SubSystemConfigPrefix_(SubSystemConfigPrefix) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void SubSystemServer::initialize([[maybe_unused]] Poco::Util::Application &self) {
 | 
						void SubSystemServer::initialize([[maybe_unused]] Poco::Util::Application &self) {
 | 
				
			||||||
@@ -280,12 +260,9 @@ namespace OpenWifi {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		auto NewLevel = MicroServiceConfigGetString("logging.level." + Name_, "");
 | 
							auto NewLevel = MicroServiceConfigGetString("logging.level." + Name_, "");
 | 
				
			||||||
		if(NewLevel.empty())
 | 
							if(NewLevel.empty())
 | 
				
			||||||
			Logger_ = std::make_unique<LoggerWrapper>(Poco::Logger::create(
 | 
								Logger_ = std::make_unique<LoggerWrapper>(Poco::Logger::create(LoggerPrefix_, Poco::Logger::root().getChannel(), Poco::Logger::root().getLevel()));
 | 
				
			||||||
				LoggerPrefix_, Poco::Logger::root().getChannel(), Poco::Logger::root().getLevel()));
 | 
					 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			Logger_ = std::make_unique<LoggerWrapper>(
 | 
								Logger_ = std::make_unique<LoggerWrapper>(Poco::Logger::create(LoggerPrefix_, Poco::Logger::root().getChannel(), Poco::Logger::parseLevel(NewLevel)));
 | 
				
			||||||
				Poco::Logger::create(LoggerPrefix_, Poco::Logger::root().getChannel(),
 | 
					 | 
				
			||||||
									 Poco::Logger::parseLevel(NewLevel)));
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ConfigServersList_.clear();
 | 
							ConfigServersList_.clear();
 | 
				
			||||||
		while (good) {
 | 
							while (good) {
 | 
				
			||||||
@@ -320,11 +297,14 @@ namespace OpenWifi {
 | 
				
			|||||||
				} else if (L == "once")
 | 
									} else if (L == "once")
 | 
				
			||||||
					M = Poco::Net::Context::VERIFY_ONCE;
 | 
										M = Poco::Net::Context::VERIFY_ONCE;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				PropertiesFileServerEntry entry(
 | 
									PropertiesFileServerEntry entry(MicroServiceConfigGetString(address, ""),
 | 
				
			||||||
					MicroServiceConfigGetString(address, ""), MicroServiceConfigGetInt(port, 0),
 | 
																	MicroServiceConfigGetInt(port, 0),
 | 
				
			||||||
					MicroServiceConfigPath(key, ""), MicroServiceConfigPath(cert, ""),
 | 
																	MicroServiceConfigPath(key, ""),
 | 
				
			||||||
					MicroServiceConfigPath(rootca, ""), MicroServiceConfigPath(issuer, ""),
 | 
																	MicroServiceConfigPath(cert, ""),
 | 
				
			||||||
					MicroServiceConfigPath(clientcas, ""), MicroServiceConfigPath(cas, ""),
 | 
																	MicroServiceConfigPath(rootca, ""),
 | 
				
			||||||
 | 
																	MicroServiceConfigPath(issuer, ""),
 | 
				
			||||||
 | 
																	MicroServiceConfigPath(clientcas, ""),
 | 
				
			||||||
 | 
																	MicroServiceConfigPath(cas, ""),
 | 
				
			||||||
												MicroServiceConfigGetString(key_password, ""),
 | 
																	MicroServiceConfigGetString(key_password, ""),
 | 
				
			||||||
												MicroServiceConfigGetString(name, ""), M,
 | 
																	MicroServiceConfigGetString(name, ""), M,
 | 
				
			||||||
												(int)MicroServiceConfigGetInt(backlog, 64));
 | 
																	(int)MicroServiceConfigGetInt(backlog, 64));
 | 
				
			||||||
@@ -334,4 +314,7 @@ namespace OpenWifi {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace OpenWifi
 | 
					} // namespace OpenWifi
 | 
				
			||||||
@@ -4,27 +4,29 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <mutex>
 | 
					 | 
				
			||||||
#include <string>
 | 
					#include <string>
 | 
				
			||||||
 | 
					#include <mutex>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "Poco/Net/Context.h"
 | 
					 | 
				
			||||||
#include "Poco/Net/PrivateKeyPassphraseHandler.h"
 | 
					 | 
				
			||||||
#include "Poco/Net/SecureServerSocket.h"
 | 
					 | 
				
			||||||
#include "Poco/Util/Application.h"
 | 
					#include "Poco/Util/Application.h"
 | 
				
			||||||
 | 
					#include "Poco/Net/Context.h"
 | 
				
			||||||
 | 
					#include "Poco/Net/SecureServerSocket.h"
 | 
				
			||||||
 | 
					#include "Poco/Net/PrivateKeyPassphraseHandler.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	class MyPrivateKeyPassphraseHandler : public Poco::Net::PrivateKeyPassphraseHandler {
 | 
						class MyPrivateKeyPassphraseHandler : public Poco::Net::PrivateKeyPassphraseHandler {
 | 
				
			||||||
	  public:
 | 
						  public:
 | 
				
			||||||
		explicit MyPrivateKeyPassphraseHandler(const std::string &Password, Poco::Logger &Logger)
 | 
							explicit MyPrivateKeyPassphraseHandler(const std::string &Password, Poco::Logger & Logger):
 | 
				
			||||||
			: PrivateKeyPassphraseHandler(true), Password_(Password), Logger_(Logger) {}
 | 
								PrivateKeyPassphraseHandler(true),
 | 
				
			||||||
 | 
								Password_(Password),
 | 
				
			||||||
 | 
								Logger_(Logger) {
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		void onPrivateKeyRequested([[maybe_unused]] const void * pSender,std::string & privateKey) {
 | 
							void onPrivateKeyRequested([[maybe_unused]] const void * pSender,std::string & privateKey) {
 | 
				
			||||||
			poco_information(Logger_,"Returning key passphrase.");
 | 
								poco_information(Logger_,"Returning key passphrase.");
 | 
				
			||||||
			privateKey = Password_;
 | 
								privateKey = Password_;
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
		inline Poco::Logger & Logger() { return Logger_; }
 | 
							inline Poco::Logger & Logger() { return Logger_; }
 | 
				
			||||||
 | 
					 | 
				
			||||||
	  private:
 | 
						  private:
 | 
				
			||||||
		std::string Password_;
 | 
							std::string Password_;
 | 
				
			||||||
		Poco::Logger & Logger_;
 | 
							Poco::Logger & Logger_;
 | 
				
			||||||
@@ -78,17 +80,17 @@ namespace OpenWifi {
 | 
				
			|||||||
						const std::string & SubSystemConfigPrefix);
 | 
											const std::string & SubSystemConfigPrefix);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		void initialize(Poco::Util::Application &self) override;
 | 
							void initialize(Poco::Util::Application &self) override;
 | 
				
			||||||
		inline void uninitialize() override {}
 | 
							inline void uninitialize() override {
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		inline void reinitialize([[maybe_unused]] Poco::Util::Application &self) override {
 | 
							inline void reinitialize([[maybe_unused]] Poco::Util::Application &self) override {
 | 
				
			||||||
			poco_information(Logger_->L_,"Reloading of this subsystem is not supported.");
 | 
								poco_information(Logger_->L_,"Reloading of this subsystem is not supported.");
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		inline void defineOptions([[maybe_unused]] Poco::Util::OptionSet &options) override {}
 | 
							inline void defineOptions([[maybe_unused]] Poco::Util::OptionSet &options) override {
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		inline const std::string & Name() const { return Name_; };
 | 
							inline const std::string & Name() const { return Name_; };
 | 
				
			||||||
		inline const char * name() const override { return Name_.c_str(); }
 | 
							inline const char * name() const override { return Name_.c_str(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline const PropertiesFileServerEntry &Host(uint64_t index) {
 | 
							inline const PropertiesFileServerEntry & Host(uint64_t index) { return ConfigServersList_[index]; };
 | 
				
			||||||
			return ConfigServersList_[index];
 | 
					 | 
				
			||||||
		};
 | 
					 | 
				
			||||||
		inline uint64_t HostSize() const { return ConfigServersList_.size(); }
 | 
							inline uint64_t HostSize() const { return ConfigServersList_.size(); }
 | 
				
			||||||
		inline Poco::Logger & Logger() const { return Logger_->L_; }
 | 
							inline Poco::Logger & Logger() const { return Logger_->L_; }
 | 
				
			||||||
		inline void SetLoggingLevel(const std::string & levelName) {
 | 
							inline void SetLoggingLevel(const std::string & levelName) {
 | 
				
			||||||
@@ -101,7 +103,9 @@ namespace OpenWifi {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		struct LoggerWrapper {
 | 
							struct LoggerWrapper {
 | 
				
			||||||
			Poco::Logger & L_;
 | 
								Poco::Logger & L_;
 | 
				
			||||||
			LoggerWrapper(Poco::Logger &L) : L_(L) {}
 | 
								LoggerWrapper(Poco::Logger &L) :
 | 
				
			||||||
 | 
					 				L_(L) {
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	  protected:
 | 
						  protected:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,4 +5,7 @@
 | 
				
			|||||||
#include "framework/UI_WebSocketClientNotifications.h"
 | 
					#include "framework/UI_WebSocketClientNotifications.h"
 | 
				
			||||||
#include "framework/UI_WebSocketClientServer.h"
 | 
					#include "framework/UI_WebSocketClientServer.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {}
 | 
					namespace OpenWifi {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -37,7 +37,9 @@ namespace OpenWifi {
 | 
				
			|||||||
			RESTAPI_utils::field_from_json(Obj, "content", content);
 | 
								RESTAPI_utils::field_from_json(Obj, "content", content);
 | 
				
			||||||
            return true;
 | 
					            return true;
 | 
				
			||||||
        } catch (...) {
 | 
					        } catch (...) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        return false;
 | 
					        return false;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
} // namespace OpenWifi
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,14 +4,14 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include <mutex>
 | 
					#include <mutex>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "Poco/NObserver.h"
 | 
				
			||||||
#include "Poco/JSON/JSONException.h"
 | 
					#include "Poco/JSON/JSONException.h"
 | 
				
			||||||
#include "Poco/JSON/Parser.h"
 | 
					#include "Poco/JSON/Parser.h"
 | 
				
			||||||
#include "Poco/Logger.h"
 | 
					#include "Poco/Logger.h"
 | 
				
			||||||
#include "Poco/NObserver.h"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "framework/UI_WebSocketClientServer.h"
 | 
				
			||||||
#include "framework/AuthClient.h"
 | 
					#include "framework/AuthClient.h"
 | 
				
			||||||
#include "framework/MicroServiceFuncs.h"
 | 
					#include "framework/MicroServiceFuncs.h"
 | 
				
			||||||
#include "framework/UI_WebSocketClientServer.h"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "fmt/format.h"
 | 
					#include "fmt/format.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -19,13 +19,11 @@
 | 
				
			|||||||
#include "AuthService.h"
 | 
					#include "AuthService.h"
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define DBG                                                                                        \
 | 
					#define DBG { std::cout << __LINE__ << std::endl; }
 | 
				
			||||||
	{ std::cout << __LINE__ << std::endl; }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void UI_WebSocketClientServer::NewClient(Poco::Net::WebSocket &WS, const std::string &Id,
 | 
						void UI_WebSocketClientServer::NewClient(Poco::Net::WebSocket & WS, const std::string &Id, const std::string &UserName, std::uint64_t TID ) {
 | 
				
			||||||
											 const std::string &UserName, std::uint64_t TID) {
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        std::lock_guard G(LocalMutex_);
 | 
					        std::lock_guard G(LocalMutex_);
 | 
				
			||||||
        auto Client = std::make_unique<UI_WebSocketClientInfo>(WS,Id, UserName);
 | 
					        auto Client = std::make_unique<UI_WebSocketClientInfo>(WS,Id, UserName);
 | 
				
			||||||
@@ -34,26 +32,28 @@ namespace OpenWifi {
 | 
				
			|||||||
        Client->WS_->setNoDelay(true);
 | 
					        Client->WS_->setNoDelay(true);
 | 
				
			||||||
        Client->WS_->setKeepAlive(true);
 | 
					        Client->WS_->setKeepAlive(true);
 | 
				
			||||||
        Client->WS_->setBlocking(false);
 | 
					        Client->WS_->setBlocking(false);
 | 
				
			||||||
		Reactor_.addEventHandler(
 | 
					        Reactor_.addEventHandler(*Client->WS_,
 | 
				
			||||||
			*Client->WS_,
 | 
					 | 
				
			||||||
                                 Poco::NObserver<UI_WebSocketClientServer, Poco::Net::ReadableNotification>(
 | 
					                                 Poco::NObserver<UI_WebSocketClientServer, Poco::Net::ReadableNotification>(
 | 
				
			||||||
                                         *this, &UI_WebSocketClientServer::OnSocketReadable));
 | 
					                                         *this, &UI_WebSocketClientServer::OnSocketReadable));
 | 
				
			||||||
		Reactor_.addEventHandler(
 | 
					        Reactor_.addEventHandler(*Client->WS_,
 | 
				
			||||||
			*Client->WS_,
 | 
					 | 
				
			||||||
                                 Poco::NObserver<UI_WebSocketClientServer, Poco::Net::ShutdownNotification>(
 | 
					                                 Poco::NObserver<UI_WebSocketClientServer, Poco::Net::ShutdownNotification>(
 | 
				
			||||||
                                         *this, &UI_WebSocketClientServer::OnSocketShutdown));
 | 
					                                         *this, &UI_WebSocketClientServer::OnSocketShutdown));
 | 
				
			||||||
		Reactor_.addEventHandler(
 | 
					        Reactor_.addEventHandler(*Client->WS_,
 | 
				
			||||||
			*Client->WS_, Poco::NObserver<UI_WebSocketClientServer, Poco::Net::ErrorNotification>(
 | 
					                                 Poco::NObserver<UI_WebSocketClientServer, Poco::Net::ErrorNotification>(
 | 
				
			||||||
                                         *this, &UI_WebSocketClientServer::OnSocketError));
 | 
					                                         *this, &UI_WebSocketClientServer::OnSocketError));
 | 
				
			||||||
        Client->SocketRegistered_ = true;
 | 
					        Client->SocketRegistered_ = true;
 | 
				
			||||||
        Clients_[ClientSocket] = std::move(Client);
 | 
					        Clients_[ClientSocket] = std::move(Client);
 | 
				
			||||||
		UsersConnected_ = Clients_.size();
 | 
							UsersConnected_ = Clients_.size();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void UI_WebSocketClientServer::SetProcessor(UI_WebSocketClientProcessor *F) { Processor_ = F; }
 | 
						void UI_WebSocketClientServer::SetProcessor( UI_WebSocketClientProcessor * F) {
 | 
				
			||||||
 | 
							Processor_ = F;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	UI_WebSocketClientServer::UI_WebSocketClientServer() noexcept
 | 
						UI_WebSocketClientServer::UI_WebSocketClientServer() noexcept:
 | 
				
			||||||
		: SubSystemServer("WebSocketClientServer", "UI-WSCLNT-SVR", "websocketclients") {}
 | 
							 SubSystemServer("WebSocketClientServer", "UI-WSCLNT-SVR", "websocketclients")
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void UI_WebSocketClientServer::run() {
 | 
						void UI_WebSocketClientServer::run() {
 | 
				
			||||||
		Running_ = true;
 | 
							Running_ = true;
 | 
				
			||||||
@@ -71,23 +71,21 @@ namespace OpenWifi {
 | 
				
			|||||||
            ToBeRemoved_.clear();
 | 
					            ToBeRemoved_.clear();
 | 
				
			||||||
			UsersConnected_ = Clients_.size();
 | 
								UsersConnected_ = Clients_.size();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void UI_WebSocketClientServer::EndConnection(ClientList::iterator Client) {
 | 
					    void UI_WebSocketClientServer::EndConnection(ClientList::iterator Client) {
 | 
				
			||||||
        if(Client->second->SocketRegistered_) {
 | 
					        if(Client->second->SocketRegistered_) {
 | 
				
			||||||
            Client->second->SocketRegistered_ = false;
 | 
					            Client->second->SocketRegistered_ = false;
 | 
				
			||||||
			Reactor_.removeEventHandler(
 | 
					            Reactor_.removeEventHandler(*Client->second->WS_,
 | 
				
			||||||
				*Client->second->WS_,
 | 
					                                        Poco::NObserver<UI_WebSocketClientServer,
 | 
				
			||||||
				Poco::NObserver<UI_WebSocketClientServer, Poco::Net::ReadableNotification>(
 | 
					                                                Poco::Net::ReadableNotification>(*this,&UI_WebSocketClientServer::OnSocketReadable));
 | 
				
			||||||
					*this, &UI_WebSocketClientServer::OnSocketReadable));
 | 
					            Reactor_.removeEventHandler(*Client->second->WS_,
 | 
				
			||||||
			Reactor_.removeEventHandler(
 | 
					                                        Poco::NObserver<UI_WebSocketClientServer,
 | 
				
			||||||
				*Client->second->WS_,
 | 
					                                                Poco::Net::ShutdownNotification>(*this,&UI_WebSocketClientServer::OnSocketShutdown));
 | 
				
			||||||
				Poco::NObserver<UI_WebSocketClientServer, Poco::Net::ShutdownNotification>(
 | 
					            Reactor_.removeEventHandler(*Client->second->WS_,
 | 
				
			||||||
					*this, &UI_WebSocketClientServer::OnSocketShutdown));
 | 
					                                        Poco::NObserver<UI_WebSocketClientServer,
 | 
				
			||||||
			Reactor_.removeEventHandler(
 | 
					                                                Poco::Net::ErrorNotification>(*this,&UI_WebSocketClientServer::OnSocketError));
 | 
				
			||||||
				*Client->second->WS_,
 | 
					 | 
				
			||||||
				Poco::NObserver<UI_WebSocketClientServer, Poco::Net::ErrorNotification>(
 | 
					 | 
				
			||||||
					*this, &UI_WebSocketClientServer::OnSocketError));
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
		ToBeRemoved_.push_back(Client);
 | 
							ToBeRemoved_.push_back(Client);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -116,13 +114,11 @@ namespace OpenWifi {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool UI_WebSocketClientServer::IsFiltered(std::uint64_t id,
 | 
						bool UI_WebSocketClientServer::IsFiltered(std::uint64_t id, const OpenWifi::UI_WebSocketClientInfo &Client) {
 | 
				
			||||||
											  const OpenWifi::UI_WebSocketClientInfo &Client) {
 | 
					 | 
				
			||||||
		return std::find(Client.Filter_.begin(), Client.Filter_.end(),id)!=end(Client.Filter_);
 | 
							return std::find(Client.Filter_.begin(), Client.Filter_.end(),id)!=end(Client.Filter_);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool UI_WebSocketClientServer::SendToUser(const std::string &UserName, std::uint64_t id,
 | 
						bool UI_WebSocketClientServer::SendToUser(const std::string &UserName, std::uint64_t id, const std::string &Payload) {
 | 
				
			||||||
											  const std::string &Payload) {
 | 
					 | 
				
			||||||
		std::lock_guard G(LocalMutex_);
 | 
							std::lock_guard G(LocalMutex_);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for(const auto &Client:Clients_) {
 | 
							for(const auto &Client:Clients_) {
 | 
				
			||||||
@@ -150,20 +146,19 @@ namespace OpenWifi {
 | 
				
			|||||||
				if(!IsFiltered(id,*Client.second) && Client.second->Authenticated_)
 | 
									if(!IsFiltered(id,*Client.second) && Client.second->Authenticated_)
 | 
				
			||||||
					Client.second->WS_->sendFrame(Payload.c_str(),(int)Payload.size());
 | 
										Client.second->WS_->sendFrame(Payload.c_str(),(int)Payload.size());
 | 
				
			||||||
			} catch (...) {
 | 
								} catch (...) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	UI_WebSocketClientServer::ClientList::iterator UI_WebSocketClientServer::FindWSClient(
 | 
					    UI_WebSocketClientServer::ClientList::iterator UI_WebSocketClientServer::FindWSClient( [[maybe_unused]]  std::lock_guard<std::recursive_mutex> &G, int ClientSocket) {
 | 
				
			||||||
		[[maybe_unused]] std::lock_guard<std::recursive_mutex> &G, int ClientSocket) {
 | 
					 | 
				
			||||||
        return Clients_.find(ClientSocket);
 | 
					        return Clients_.find(ClientSocket);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void UI_WebSocketClientServer::SortNotifications() {
 | 
						void UI_WebSocketClientServer::SortNotifications() {
 | 
				
			||||||
		struct {
 | 
							struct {
 | 
				
			||||||
			bool operator()(const NotificationEntry &A, const NotificationEntry & B) const {
 | 
								bool operator()(const NotificationEntry &A, const NotificationEntry & B) const {
 | 
				
			||||||
				return A.id < B.id;
 | 
									return A.id < B.id; };
 | 
				
			||||||
			};
 | 
					 | 
				
			||||||
		} CompareNotifications;
 | 
							} CompareNotifications;
 | 
				
			||||||
		std::sort(NotificationTypes_.begin(), NotificationTypes_.end(), CompareNotifications);
 | 
							std::sort(NotificationTypes_.begin(), NotificationTypes_.end(), CompareNotifications);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -178,15 +173,12 @@ namespace OpenWifi {
 | 
				
			|||||||
		NotificationTypesJSON_.set("notificationTypes", AllNotifications);
 | 
							NotificationTypesJSON_.set("notificationTypes", AllNotifications);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void UI_WebSocketClientServer::RegisterNotifications(
 | 
						void UI_WebSocketClientServer::RegisterNotifications(const OpenWifi::UI_WebSocketClientServer::NotificationTypeIdVec &Notifications) {
 | 
				
			||||||
		const OpenWifi::UI_WebSocketClientServer::NotificationTypeIdVec &Notifications) {
 | 
							std::copy(Notifications.begin(), Notifications.end(), std::back_inserter(NotificationTypes_));
 | 
				
			||||||
		std::copy(Notifications.begin(), Notifications.end(),
 | 
					 | 
				
			||||||
				  std::back_inserter(NotificationTypes_));
 | 
					 | 
				
			||||||
		SortNotifications();
 | 
							SortNotifications();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void UI_WebSocketClientServer::OnSocketError(
 | 
					    void UI_WebSocketClientServer::OnSocketError([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ErrorNotification> &pNf) {
 | 
				
			||||||
		[[maybe_unused]] const Poco::AutoPtr<Poco::Net::ErrorNotification> &pNf) {
 | 
					 | 
				
			||||||
        std::lock_guard     G(LocalMutex_);
 | 
					        std::lock_guard     G(LocalMutex_);
 | 
				
			||||||
        auto Client = Clients_.find(pNf->socket().impl()->sockfd());
 | 
					        auto Client = Clients_.find(pNf->socket().impl()->sockfd());
 | 
				
			||||||
        if(Client==end(Clients_))
 | 
					        if(Client==end(Clients_))
 | 
				
			||||||
@@ -194,8 +186,7 @@ namespace OpenWifi {
 | 
				
			|||||||
        EndConnection(Client);
 | 
					        EndConnection(Client);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void UI_WebSocketClientServer::OnSocketReadable(
 | 
						void UI_WebSocketClientServer::OnSocketReadable([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf) {
 | 
				
			||||||
		[[maybe_unused]] const Poco::AutoPtr<Poco::Net::ReadableNotification> &pNf) {
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        UI_WebSocketClientServer::ClientList::iterator Client;
 | 
					        UI_WebSocketClientServer::ClientList::iterator Client;
 | 
				
			||||||
        std::lock_guard     G(LocalMutex_);
 | 
					        std::lock_guard     G(LocalMutex_);
 | 
				
			||||||
@@ -213,9 +204,7 @@ namespace OpenWifi {
 | 
				
			|||||||
			auto Op = flags & Poco::Net::WebSocket::FRAME_OP_BITMASK;
 | 
								auto Op = flags & Poco::Net::WebSocket::FRAME_OP_BITMASK;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			if (n == 0) {
 | 
								if (n == 0) {
 | 
				
			||||||
				poco_debug(Logger(),
 | 
									poco_debug(Logger(),fmt::format("CLOSE({}): {} UI Client is closing WS connection.", Client->second->Id_, Client->second->UserName_));
 | 
				
			||||||
						   fmt::format("CLOSE({}): {} UI Client is closing WS connection.",
 | 
					 | 
				
			||||||
									   Client->second->Id_, Client->second->UserName_));
 | 
					 | 
				
			||||||
				return EndConnection(Client);
 | 
									return EndConnection(Client);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -228,9 +217,7 @@ namespace OpenWifi {
 | 
				
			|||||||
			case Poco::Net::WebSocket::FRAME_OP_PONG: {
 | 
								case Poco::Net::WebSocket::FRAME_OP_PONG: {
 | 
				
			||||||
			} break;
 | 
								} break;
 | 
				
			||||||
			case Poco::Net::WebSocket::FRAME_OP_CLOSE: {
 | 
								case Poco::Net::WebSocket::FRAME_OP_CLOSE: {
 | 
				
			||||||
				poco_debug(Logger(),
 | 
									poco_debug(Logger(),fmt::format("CLOSE({}): {} UI Client is closing WS connection.", Client->second->Id_, Client->second->UserName_));
 | 
				
			||||||
						   fmt::format("CLOSE({}): {} UI Client is closing WS connection.",
 | 
					 | 
				
			||||||
									   Client->second->Id_, Client->second->UserName_));
 | 
					 | 
				
			||||||
                return EndConnection(Client);
 | 
					                return EndConnection(Client);
 | 
				
			||||||
			} break;
 | 
								} break;
 | 
				
			||||||
			case Poco::Net::WebSocket::FRAME_OP_TEXT: {
 | 
								case Poco::Net::WebSocket::FRAME_OP_TEXT: {
 | 
				
			||||||
@@ -245,17 +232,13 @@ namespace OpenWifi {
 | 
				
			|||||||
#endif
 | 
					#endif
 | 
				
			||||||
					if (Tokens.size() == 2 &&
 | 
										if (Tokens.size() == 2 &&
 | 
				
			||||||
#if defined(TIP_SECURITY_SERVICE)
 | 
					#if defined(TIP_SECURITY_SERVICE)
 | 
				
			||||||
						AuthService()->IsAuthorized(Tokens[1], Client->second->UserInfo_, TID_,
 | 
					        			    AuthService()->IsAuthorized(Tokens[1], Client->second->UserInfo_, TID_, Expired)) {
 | 
				
			||||||
													Expired)) {
 | 
					 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
						AuthClient()->IsAuthorized(Tokens[1], Client->second->UserInfo_, TID_,
 | 
					                        AuthClient()->IsAuthorized(Tokens[1], Client->second->UserInfo_, TID_, Expired, Contacted)) {
 | 
				
			||||||
												   Expired, Contacted)) {
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
                        Client->second->Authenticated_ = true;
 | 
					                        Client->second->Authenticated_ = true;
 | 
				
			||||||
                        Client->second->UserName_ = Client->second->UserInfo_.userinfo.email;
 | 
					                        Client->second->UserName_ = Client->second->UserInfo_.userinfo.email;
 | 
				
			||||||
						poco_debug(Logger(),
 | 
											poco_debug(Logger(),fmt::format("START({}): {} UI Client is starting WS connection.", Client->second->Id_, Client->second->UserName_));
 | 
				
			||||||
								   fmt::format("START({}): {} UI Client is starting WS connection.",
 | 
					 | 
				
			||||||
											   Client->second->Id_, Client->second->UserName_));
 | 
					 | 
				
			||||||
						auto WelcomeMessage = NotificationTypesJSON_;
 | 
											auto WelcomeMessage = NotificationTypesJSON_;
 | 
				
			||||||
						WelcomeMessage.set("success", "Welcome! Bienvenue! Bienvenidos!");
 | 
											WelcomeMessage.set("success", "Welcome! Bienvenue! Bienvenidos!");
 | 
				
			||||||
						std::ostringstream OS;
 | 
											std::ostringstream OS;
 | 
				
			||||||
@@ -272,7 +255,8 @@ namespace OpenWifi {
 | 
				
			|||||||
					}
 | 
										}
 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
                    Poco::JSON::Parser P;
 | 
					                    Poco::JSON::Parser P;
 | 
				
			||||||
					auto Obj = P.parse(IncomingFrame.begin()).extract<Poco::JSON::Object::Ptr>();
 | 
					                    auto Obj =
 | 
				
			||||||
 | 
					                        P.parse(IncomingFrame.begin()).extract<Poco::JSON::Object::Ptr>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					if(Obj->has(DropMessagesCommand) && Obj->isArray(DropMessagesCommand)) {
 | 
										if(Obj->has(DropMessagesCommand) && Obj->isArray(DropMessagesCommand)) {
 | 
				
			||||||
						auto Filters = Obj->getArray(DropMessagesCommand);
 | 
											auto Filters = Obj->getArray(DropMessagesCommand);
 | 
				
			||||||
@@ -287,8 +271,7 @@ namespace OpenWifi {
 | 
				
			|||||||
                    std::string Answer;
 | 
					                    std::string Answer;
 | 
				
			||||||
                    bool CloseConnection=false;
 | 
					                    bool CloseConnection=false;
 | 
				
			||||||
                    if (Processor_ != nullptr) {
 | 
					                    if (Processor_ != nullptr) {
 | 
				
			||||||
						Processor_->Processor(Obj, Answer, CloseConnection,
 | 
					                        Processor_->Processor(Obj, Answer, CloseConnection,Client->second->UserInfo_.userinfo);
 | 
				
			||||||
											  Client->second->UserInfo_.userinfo);
 | 
					 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
                    if (!Answer.empty())
 | 
					                    if (!Answer.empty())
 | 
				
			||||||
                        Client->second->WS_->sendFrame(Answer.c_str(), (int)Answer.size());
 | 
					                        Client->second->WS_->sendFrame(Answer.c_str(), (int)Answer.size());
 | 
				
			||||||
@@ -309,8 +292,7 @@ namespace OpenWifi {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void UI_WebSocketClientServer::OnSocketShutdown(
 | 
						void UI_WebSocketClientServer::OnSocketShutdown([[maybe_unused]] const Poco::AutoPtr<Poco::Net::ShutdownNotification> &pNf) {
 | 
				
			||||||
		[[maybe_unused]] const Poco::AutoPtr<Poco::Net::ShutdownNotification> &pNf) {
 | 
					 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
			std::lock_guard     G(LocalMutex_);
 | 
								std::lock_guard     G(LocalMutex_);
 | 
				
			||||||
			auto Client = Clients_.find(pNf->socket().impl()->sockfd());
 | 
								auto Client = Clients_.find(pNf->socket().impl()->sockfd());
 | 
				
			||||||
@@ -318,6 +300,7 @@ namespace OpenWifi {
 | 
				
			|||||||
                return;
 | 
					                return;
 | 
				
			||||||
            EndConnection(Client);
 | 
					            EndConnection(Client);
 | 
				
			||||||
        } catch (...) {
 | 
					        } catch (...) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,11 +7,11 @@
 | 
				
			|||||||
#include <map>
 | 
					#include <map>
 | 
				
			||||||
#include <string>
 | 
					#include <string>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "Poco/JSON/Object.h"
 | 
					#include "Poco/Runnable.h"
 | 
				
			||||||
#include "Poco/Net/SocketNotification.h"
 | 
					 | 
				
			||||||
#include "Poco/Net/SocketReactor.h"
 | 
					#include "Poco/Net/SocketReactor.h"
 | 
				
			||||||
#include "Poco/Net/WebSocket.h"
 | 
					#include "Poco/Net/WebSocket.h"
 | 
				
			||||||
#include "Poco/Runnable.h"
 | 
					#include "Poco/JSON/Object.h"
 | 
				
			||||||
 | 
					#include "Poco/Net/SocketNotification.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "RESTObjects/RESTAPI_SecurityObjects.h"
 | 
					#include "RESTObjects/RESTAPI_SecurityObjects.h"
 | 
				
			||||||
#include "framework/SubSystemServer.h"
 | 
					#include "framework/SubSystemServer.h"
 | 
				
			||||||
@@ -21,9 +21,7 @@ namespace OpenWifi {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	class UI_WebSocketClientProcessor {
 | 
						class UI_WebSocketClientProcessor {
 | 
				
			||||||
	  public:
 | 
						  public:
 | 
				
			||||||
		virtual void Processor(const Poco::JSON::Object::Ptr &O, std::string &Answer, bool &Done,
 | 
							virtual void Processor(const Poco::JSON::Object::Ptr &O, std::string &Answer, bool &Done , const SecurityObjects::UserInfo & UserInfo) = 0;
 | 
				
			||||||
							   const SecurityObjects::UserInfo &UserInfo) = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	  private:
 | 
						  private:
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -36,8 +34,7 @@ namespace OpenWifi {
 | 
				
			|||||||
		std::vector<std::uint64_t>				Filter_;
 | 
							std::vector<std::uint64_t>				Filter_;
 | 
				
			||||||
        SecurityObjects::UserInfoAndPolicy      UserInfo_;
 | 
					        SecurityObjects::UserInfoAndPolicy      UserInfo_;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		UI_WebSocketClientInfo(Poco::Net::WebSocket &WS, const std::string &Id,
 | 
					        UI_WebSocketClientInfo(Poco::Net::WebSocket &WS, const std::string &Id, const std::string &username) {
 | 
				
			||||||
							   const std::string &username) {
 | 
					 | 
				
			||||||
            WS_ =  std::make_unique<Poco::Net::WebSocket>(WS);
 | 
					            WS_ =  std::make_unique<Poco::Net::WebSocket>(WS);
 | 
				
			||||||
            Id_ = Id;
 | 
					            Id_ = Id;
 | 
				
			||||||
            UserName_ = username;
 | 
					            UserName_ = username;
 | 
				
			||||||
@@ -52,21 +49,21 @@ namespace OpenWifi {
 | 
				
			|||||||
			return instance_;
 | 
								return instance_;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		bool IsAnyoneConnected() { return UsersConnected_; }
 | 
							bool IsAnyoneConnected() {
 | 
				
			||||||
 | 
								return UsersConnected_;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		int Start() override;
 | 
							int Start() override;
 | 
				
			||||||
		void Stop() override;
 | 
							void Stop() override;
 | 
				
			||||||
		void run() override;
 | 
							void run() override;
 | 
				
			||||||
		Poco::Net::SocketReactor & Reactor() { return Reactor_; }
 | 
							Poco::Net::SocketReactor & Reactor() { return Reactor_; }
 | 
				
			||||||
		void NewClient(Poco::Net::WebSocket &WS, const std::string &Id, const std::string &UserName,
 | 
							void NewClient(Poco::Net::WebSocket &WS, const std::string &Id, const std::string &UserName, std::uint64_t TID);
 | 
				
			||||||
					   std::uint64_t TID);
 | 
					 | 
				
			||||||
		void SetProcessor(UI_WebSocketClientProcessor *F);
 | 
							void SetProcessor(UI_WebSocketClientProcessor *F);
 | 
				
			||||||
		[[nodiscard]] inline bool GeoCodeEnabled() const { return GeoCodeEnabled_; }
 | 
							[[nodiscard]] inline bool GeoCodeEnabled() const { return GeoCodeEnabled_; }
 | 
				
			||||||
		[[nodiscard]] inline std::string GoogleApiKey() const { return GoogleApiKey_; }
 | 
							[[nodiscard]] inline std::string GoogleApiKey() const { return GoogleApiKey_; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		template <typename T>
 | 
							template <typename T> bool
 | 
				
			||||||
		bool SendUserNotification(const std::string &userName,
 | 
							SendUserNotification(const std::string &userName, const WebSocketNotification<T> &Notification) {
 | 
				
			||||||
								  const WebSocketNotification<T> &Notification) {
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
			Poco::JSON::Object  Payload;
 | 
								Poco::JSON::Object  Payload;
 | 
				
			||||||
			Notification.to_json(Payload);
 | 
								Notification.to_json(Payload);
 | 
				
			||||||
@@ -88,8 +85,7 @@ namespace OpenWifi {
 | 
				
			|||||||
			SendToAll(Notification.type_id, OO.str());
 | 
								SendToAll(Notification.type_id, OO.str());
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		[[nodiscard]] bool SendToUser(const std::string &userName, std::uint64_t id,
 | 
							[[nodiscard]] bool SendToUser(const std::string &userName, std::uint64_t id, const std::string &Payload);
 | 
				
			||||||
									  const std::string &Payload);
 | 
					 | 
				
			||||||
		void SendToAll(std::uint64_t id, const std::string &Payload);
 | 
							void SendToAll(std::uint64_t id, const std::string &Payload);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		struct NotificationEntry {
 | 
							struct NotificationEntry {
 | 
				
			||||||
@@ -126,12 +122,12 @@ namespace OpenWifi {
 | 
				
			|||||||
        void OnSocketShutdown(const Poco::AutoPtr<Poco::Net::ShutdownNotification> &pNf);
 | 
					        void OnSocketShutdown(const Poco::AutoPtr<Poco::Net::ShutdownNotification> &pNf);
 | 
				
			||||||
        void OnSocketError(const Poco::AutoPtr<Poco::Net::ErrorNotification> &pNf);
 | 
					        void OnSocketError(const Poco::AutoPtr<Poco::Net::ErrorNotification> &pNf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		ClientList::iterator FindWSClient(std::lock_guard<std::recursive_mutex> &G,
 | 
					        ClientList::iterator FindWSClient( std::lock_guard<std::recursive_mutex> &G, int ClientSocket);
 | 
				
			||||||
										  int ClientSocket);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		void SortNotifications();
 | 
							void SortNotifications();
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline auto UI_WebSocketClientServer() { return UI_WebSocketClientServer::instance(); }
 | 
						inline auto UI_WebSocketClientServer() { return UI_WebSocketClientServer::instance(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}; // namespace OpenWifi
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,46 +5,43 @@
 | 
				
			|||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "framework/SubSystemServer.h"
 | 
					#include "framework/SubSystemServer.h"
 | 
				
			||||||
#include "framework/UI_WebSocketClientNotifications.h"
 | 
					 | 
				
			||||||
#include "framework/UI_WebSocketClientServer.h"
 | 
					#include "framework/UI_WebSocketClientServer.h"
 | 
				
			||||||
 | 
					#include "framework/UI_WebSocketClientNotifications.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi {
 | 
					namespace OpenWifi {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	class WebSocketLogger : public Poco::Channel {
 | 
						class WebSocketLogger : public Poco::Channel {
 | 
				
			||||||
	  public:
 | 
						  public:
 | 
				
			||||||
		WebSocketLogger() {}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		~WebSocketLogger() {}
 | 
							WebSocketLogger() {
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							~WebSocketLogger() {
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		std::string getProperty( [[maybe_unused]] const std::string &p ) const {
 | 
							std::string getProperty( [[maybe_unused]] const std::string &p ) const {
 | 
				
			||||||
			std::cout << "WS getProperty" << std::endl;
 | 
								std::cout << "WS getProperty" << std::endl;
 | 
				
			||||||
			return "";
 | 
								return "";
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		void close() final {}
 | 
							void close() final {
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		void open() final {}
 | 
							void open() final {
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		static std::string to_string(Poco::Message::Priority p) {
 | 
							static std::string to_string(Poco::Message::Priority p) {
 | 
				
			||||||
			switch(p) {
 | 
								switch(p) {
 | 
				
			||||||
			case Poco::Message::PRIO_INFORMATION:
 | 
								case Poco::Message::PRIO_INFORMATION: return "information";
 | 
				
			||||||
				return "information";
 | 
								case Poco::Message::PRIO_CRITICAL: return "critical";
 | 
				
			||||||
			case Poco::Message::PRIO_CRITICAL:
 | 
								case Poco::Message::PRIO_DEBUG: return "debug";
 | 
				
			||||||
				return "critical";
 | 
								case Poco::Message::PRIO_ERROR: return "error";
 | 
				
			||||||
			case Poco::Message::PRIO_DEBUG:
 | 
								case Poco::Message::PRIO_FATAL: return "fatal";
 | 
				
			||||||
				return "debug";
 | 
								case Poco::Message::PRIO_NOTICE: return "notice";
 | 
				
			||||||
			case Poco::Message::PRIO_ERROR:
 | 
								case Poco::Message::PRIO_TRACE: return "trace";
 | 
				
			||||||
				return "error";
 | 
								case Poco::Message::PRIO_WARNING: return "warning";
 | 
				
			||||||
			case Poco::Message::PRIO_FATAL:
 | 
								default: return "none";
 | 
				
			||||||
				return "fatal";
 | 
					 | 
				
			||||||
			case Poco::Message::PRIO_NOTICE:
 | 
					 | 
				
			||||||
				return "notice";
 | 
					 | 
				
			||||||
			case Poco::Message::PRIO_TRACE:
 | 
					 | 
				
			||||||
				return "trace";
 | 
					 | 
				
			||||||
			case Poco::Message::PRIO_WARNING:
 | 
					 | 
				
			||||||
				return "warning";
 | 
					 | 
				
			||||||
			default:
 | 
					 | 
				
			||||||
				return "none";
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -75,13 +72,13 @@ namespace OpenWifi {
 | 
				
			|||||||
					RESTAPI_utils::field_from_json(Obj, "thread_id", thread_id);
 | 
										RESTAPI_utils::field_from_json(Obj, "thread_id", thread_id);
 | 
				
			||||||
					return true;
 | 
										return true;
 | 
				
			||||||
				} catch(...) {
 | 
									} catch(...) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				return false;
 | 
									return false;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		typedef WebSocketNotification<NotificationLogMessage>
 | 
							typedef WebSocketNotification<NotificationLogMessage> WebSocketClientNotificationLogMessage_t;
 | 
				
			||||||
			WebSocketClientNotificationLogMessage_t;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		void log(const Poco::Message &m) final {
 | 
							void log(const Poco::Message &m) final {
 | 
				
			||||||
			if(UI_WebSocketClientServer()->IsAnyoneConnected()) {
 | 
								if(UI_WebSocketClientServer()->IsAnyoneConnected()) {
 | 
				
			||||||
@@ -97,8 +94,7 @@ namespace OpenWifi {
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		void setProperty([[maybe_unused]] const std::string &name,
 | 
							void setProperty([[maybe_unused]] const std::string &name, [[maybe_unused]] const std::string &value) {
 | 
				
			||||||
						 [[maybe_unused]] const std::string &value) {
 | 
					 | 
				
			||||||
			std::cout << "WS setProperty" << std::endl;
 | 
								std::cout << "WS setProperty" << std::endl;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -108,4 +104,4 @@ namespace OpenWifi {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
//	inline auto WebSocketLogger() { return WebSocketLogger::instance(); }
 | 
					//	inline auto WebSocketLogger() { return WebSocketLogger::instance(); }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace OpenWifi
 | 
					}
 | 
				
			||||||
@@ -1,63 +0,0 @@
 | 
				
			|||||||
//
 | 
					 | 
				
			||||||
// Created by stephane bourque on 2023-04-19.
 | 
					 | 
				
			||||||
//
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#pragma once
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include <vector>
 | 
					 | 
				
			||||||
#include <string>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace OpenWifi {
 | 
					 | 
				
			||||||
	inline  const std::vector<std::pair<std::string, std::string>> DefaultDeviceTypeList{
 | 
					 | 
				
			||||||
		{"actiontec_web7200", "AP"},
 | 
					 | 
				
			||||||
		{"cig_wf186w", "AP"},
 | 
					 | 
				
			||||||
		{"cig_wf188n", "AP"},
 | 
					 | 
				
			||||||
		{"cig_wf194c4", "AP"},
 | 
					 | 
				
			||||||
		{"cig_wf196", "AP"},
 | 
					 | 
				
			||||||
		{"cig_wf196-ca", "AP"},
 | 
					 | 
				
			||||||
		{"cig_wf196-ca-ath12", "AP"},
 | 
					 | 
				
			||||||
		{"cig_wf196-us", "AP"},
 | 
					 | 
				
			||||||
		{"cig_wf610d", "AP"},
 | 
					 | 
				
			||||||
		{"cig_wf660a", "AP"},
 | 
					 | 
				
			||||||
		{"cig_wf808", "AP"},
 | 
					 | 
				
			||||||
		{"cybertan_eww622-a1", "AP"},
 | 
					 | 
				
			||||||
		{"edgecore_eap101", "AP"},
 | 
					 | 
				
			||||||
		{"edgecore_eap101-ath12", "AP"},
 | 
					 | 
				
			||||||
		{"edgecore_eap102", "AP"},
 | 
					 | 
				
			||||||
		{"edgecore_eap104", "AP"},
 | 
					 | 
				
			||||||
		{"edgecore_eap104-ath12", "AP"},
 | 
					 | 
				
			||||||
		{"edgecore_ecs4100-12ph", "AP"},
 | 
					 | 
				
			||||||
		{"edgecore_ecw5211", "AP"},
 | 
					 | 
				
			||||||
		{"edgecore_ecw5410", "AP"},
 | 
					 | 
				
			||||||
		{"edgecore_oap100", "AP"},
 | 
					 | 
				
			||||||
		{"edgecore_spw2ac1200", "SWITCH"},
 | 
					 | 
				
			||||||
		{"edgecore_spw2ac1200-lan-poe", "SWITCH"},
 | 
					 | 
				
			||||||
		{"edgecore_ssw2ac2600", "SWITCH"},
 | 
					 | 
				
			||||||
		{"hfcl_ion4", "AP"},
 | 
					 | 
				
			||||||
		{"hfcl_ion4x", "AP"},
 | 
					 | 
				
			||||||
		{"hfcl_ion4x_2", "AP"},
 | 
					 | 
				
			||||||
		{"hfcl_ion4xe", "AP"},
 | 
					 | 
				
			||||||
		{"hfcl_ion4xi", "AP"},
 | 
					 | 
				
			||||||
		{"indio_um-305ac", "AP"},
 | 
					 | 
				
			||||||
		{"indio_um-305ax", "AP"},
 | 
					 | 
				
			||||||
		{"indio_um-310ax-v1", "AP"},
 | 
					 | 
				
			||||||
		{"indio_um-325ac", "AP"},
 | 
					 | 
				
			||||||
		{"indio_um-510ac-v3", "AP"},
 | 
					 | 
				
			||||||
		{"indio_um-510axm-v1", "AP"},
 | 
					 | 
				
			||||||
		{"indio_um-510axp-v1", "AP"},
 | 
					 | 
				
			||||||
		{"indio_um-550ac", "AP"},
 | 
					 | 
				
			||||||
		{"linksys_e8450-ubi", "AP"},
 | 
					 | 
				
			||||||
		{"linksys_ea6350-v4", "AP"},
 | 
					 | 
				
			||||||
		{"linksys_ea8300", "AP"},
 | 
					 | 
				
			||||||
		{"liteon_wpx8324", "AP"},
 | 
					 | 
				
			||||||
		{"meshpp_s618_cp01", "AP"},
 | 
					 | 
				
			||||||
		{"meshpp_s618_cp03", "AP"},
 | 
					 | 
				
			||||||
		{"udaya_a5-id2", "AP"},
 | 
					 | 
				
			||||||
		{"wallys_dr40x9", "AP"},
 | 
					 | 
				
			||||||
		{"wallys_dr6018", "AP"},
 | 
					 | 
				
			||||||
		{"wallys_dr6018_v4", "AP"},
 | 
					 | 
				
			||||||
		{"x64_vm", "AP"},
 | 
					 | 
				
			||||||
		{"yuncore_ax840", "AP"},
 | 
					 | 
				
			||||||
		{"yuncore_fap640", "AP"},
 | 
					 | 
				
			||||||
		{"yuncore_fap650", "AP"}};
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -8,30 +8,41 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <array>
 | 
					 | 
				
			||||||
#include <fstream>
 | 
					 | 
				
			||||||
#include <iostream>
 | 
					 | 
				
			||||||
#include <map>
 | 
					 | 
				
			||||||
#include <memory>
 | 
					 | 
				
			||||||
#include <string>
 | 
					#include <string>
 | 
				
			||||||
 | 
					#include <memory>
 | 
				
			||||||
 | 
					#include <iostream>
 | 
				
			||||||
 | 
					#include <fstream>
 | 
				
			||||||
 | 
					#include <map>
 | 
				
			||||||
#include <vector>
 | 
					#include <vector>
 | 
				
			||||||
 | 
					#include <array>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "Poco/Data/RecordSet.h"
 | 
					#include "Poco/Tuple.h"
 | 
				
			||||||
#include "Poco/Data/SQLite/Connector.h"
 | 
					 | 
				
			||||||
#include "Poco/Data/SessionPool.h"
 | 
					#include "Poco/Data/SessionPool.h"
 | 
				
			||||||
#include "Poco/Data/Statement.h"
 | 
					#include "Poco/Data/Statement.h"
 | 
				
			||||||
 | 
					#include "Poco/Data/RecordSet.h"
 | 
				
			||||||
 | 
					#include "Poco/Data/SQLite/Connector.h"
 | 
				
			||||||
#include "Poco/Logger.h"
 | 
					#include "Poco/Logger.h"
 | 
				
			||||||
#include "Poco/StringTokenizer.h"
 | 
					#include "Poco/StringTokenizer.h"
 | 
				
			||||||
#include "Poco/Tuple.h"
 | 
					 | 
				
			||||||
#include "StorageClass.h"
 | 
					#include "StorageClass.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "fmt/format.h"
 | 
					#include "fmt/format.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace ORM {
 | 
					namespace ORM {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	enum FieldType { FT_INT, FT_BIGINT, FT_TEXT, FT_VARCHAR, FT_BLOB, FT_BOOLEAN, FT_REAL };
 | 
					    enum FieldType {
 | 
				
			||||||
 | 
					        FT_INT,
 | 
				
			||||||
 | 
					        FT_BIGINT,
 | 
				
			||||||
 | 
					        FT_TEXT,
 | 
				
			||||||
 | 
					        FT_VARCHAR,
 | 
				
			||||||
 | 
					        FT_BLOB,
 | 
				
			||||||
 | 
					        FT_BOOLEAN,
 | 
				
			||||||
 | 
					        FT_REAL
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	enum Indextype { ASC, DESC };
 | 
					    enum Indextype {
 | 
				
			||||||
 | 
					        ASC,
 | 
				
			||||||
 | 
					        DESC
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    struct Field {
 | 
					    struct Field {
 | 
				
			||||||
        std::string Name;
 | 
					        std::string Name;
 | 
				
			||||||
@@ -39,19 +50,31 @@ namespace ORM {
 | 
				
			|||||||
        int         Size=0;
 | 
					        int         Size=0;
 | 
				
			||||||
        bool        Index=false;
 | 
					        bool        Index=false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Field(std::string N, FieldType T, int S = 0, bool Index = false)
 | 
					 | 
				
			||||||
			: Name(std::move(N)), Type(T), Size(S), Index(Index) {}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
		explicit Field(std::string N) : Name(std::move(N)) { Type = FT_TEXT; }
 | 
					        Field(std::string N, FieldType T, int S=0, bool Index=false) :
 | 
				
			||||||
 | 
					            Name(std::move(N)),
 | 
				
			||||||
 | 
					            Type(T),
 | 
				
			||||||
 | 
					            Size(S),
 | 
				
			||||||
 | 
					            Index(Index) {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Field(std::string N, int S) : Name(std::move(N)), Size(S) {
 | 
					        explicit Field(std::string N) :
 | 
				
			||||||
 | 
					            Name(std::move(N))
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Type = FT_TEXT;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Field(std::string N, int S) :
 | 
				
			||||||
 | 
					            Name(std::move(N)), Size(S)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
            if(Size>0 && Size<255)
 | 
					            if(Size>0 && Size<255)
 | 
				
			||||||
                Type = FT_VARCHAR;
 | 
					                Type = FT_VARCHAR;
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
                Type = FT_TEXT;
 | 
					                Type = FT_TEXT;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Field(std::string N, int S, bool I) : Name(std::move(N)), Size(S), Index(I) {
 | 
					        Field(std::string N, int S, bool I):
 | 
				
			||||||
 | 
					            Name(std::move(N)), Size(S), Index(I)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
            if(Size>0 && Size<255)
 | 
					            if(Size>0 && Size<255)
 | 
				
			||||||
                Type = FT_VARCHAR;
 | 
					                Type = FT_VARCHAR;
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
@@ -74,14 +97,10 @@ namespace ORM {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    inline std::string FieldTypeToChar(OpenWifi::DBType Type, FieldType T, int Size=0) {
 | 
					    inline std::string FieldTypeToChar(OpenWifi::DBType Type, FieldType T, int Size=0) {
 | 
				
			||||||
        switch(T) {
 | 
					        switch(T) {
 | 
				
			||||||
		case FT_INT:
 | 
					            case FT_INT:    return "INT";
 | 
				
			||||||
			return "INT";
 | 
					            case FT_BIGINT: return "BIGINT";
 | 
				
			||||||
		case FT_BIGINT:
 | 
					            case FT_TEXT:   return "TEXT";
 | 
				
			||||||
			return "BIGINT";
 | 
					            case FT_BOOLEAN:   return "BOOLEAN";
 | 
				
			||||||
		case FT_TEXT:
 | 
					 | 
				
			||||||
			return "TEXT";
 | 
					 | 
				
			||||||
		case FT_BOOLEAN:
 | 
					 | 
				
			||||||
			return "BOOLEAN";
 | 
					 | 
				
			||||||
            case FT_VARCHAR:
 | 
					            case FT_VARCHAR:
 | 
				
			||||||
                if(Size)
 | 
					                if(Size)
 | 
				
			||||||
                    return std::string("VARCHAR(") + std::to_string(Size) + std::string(")");
 | 
					                    return std::string("VARCHAR(") + std::to_string(Size) + std::string(")");
 | 
				
			||||||
@@ -98,6 +117,7 @@ namespace ORM {
 | 
				
			|||||||
                return "REAL";
 | 
					                return "REAL";
 | 
				
			||||||
            default:
 | 
					            default:
 | 
				
			||||||
                assert(false);
 | 
					                assert(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        assert(false);
 | 
					        assert(false);
 | 
				
			||||||
        return "";
 | 
					        return "";
 | 
				
			||||||
@@ -115,12 +135,13 @@ namespace ORM {
 | 
				
			|||||||
        return R;
 | 
					        return R;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline std::string WHERE_AND_(std::string Result) { return Result; }
 | 
					    inline std::string WHERE_AND_(std::string Result) {
 | 
				
			||||||
 | 
					        return Result;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	template <typename T, typename... Args>
 | 
					    template <typename T, typename... Args> std::string WHERE_AND_(std::string Result, const char *fieldName, const T & Value, Args... args) {
 | 
				
			||||||
	std::string WHERE_AND_(std::string Result, const char *fieldName, const T &Value,
 | 
					        if constexpr(std::is_same_v<T,std::string>)
 | 
				
			||||||
						   Args... args) {
 | 
					        {
 | 
				
			||||||
		if constexpr (std::is_same_v<T, std::string>) {
 | 
					 | 
				
			||||||
            if(!Value.empty()) {
 | 
					            if(!Value.empty()) {
 | 
				
			||||||
                if(!Result.empty())
 | 
					                if(!Result.empty())
 | 
				
			||||||
                    Result += " and ";
 | 
					                    Result += " and ";
 | 
				
			||||||
@@ -173,13 +194,21 @@ namespace ORM {
 | 
				
			|||||||
    static const std::vector<std::string> BOPS{" and ", " or "};
 | 
					    static const std::vector<std::string> BOPS{" and ", " or "};
 | 
				
			||||||
    static const std::vector<std::string> SQLCOMPS{"=","!=","<","<=",">",">="};
 | 
					    static const std::vector<std::string> SQLCOMPS{"=","!=","<","<=",">",">="};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline std::string to_string(uint64_t V) { return std::to_string(V); }
 | 
					    inline std::string to_string(uint64_t V) {
 | 
				
			||||||
 | 
					        return std::to_string(V);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline std::string to_string(int V) { return std::to_string(V); }
 | 
					    inline std::string to_string(int V) {
 | 
				
			||||||
 | 
					        return std::to_string(V);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline std::string to_string(bool V) { return std::to_string(V); }
 | 
					    inline std::string to_string(bool V) {
 | 
				
			||||||
 | 
					        return std::to_string(V);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline std::string to_string(const std::string &S) { return S; }
 | 
					    inline std::string to_string(const std::string &S) {
 | 
				
			||||||
 | 
					        return S;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    inline std::string to_string(const Poco::Data::BLOB &blob) {
 | 
					    inline std::string to_string(const Poco::Data::BLOB &blob) {
 | 
				
			||||||
        std::string result;
 | 
					        std::string result;
 | 
				
			||||||
@@ -187,17 +216,22 @@ namespace ORM {
 | 
				
			|||||||
        return result;
 | 
					        return result;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline std::string to_string(const char *S) { return S; }
 | 
					    inline std::string to_string(const char * S) {
 | 
				
			||||||
 | 
					        return S;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    template <typename RecordType> class DBCache {
 | 
					    template <typename RecordType> class DBCache {
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
		DBCache(unsigned Size, unsigned Timeout) : Size_(Size), Timeout_(Timeout) {}
 | 
					        DBCache(unsigned Size, unsigned Timeout) :
 | 
				
			||||||
 | 
					            Size_(Size),
 | 
				
			||||||
 | 
					            Timeout_(Timeout)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        virtual void Create(const RecordType &R)=0;
 | 
					        virtual void Create(const RecordType &R)=0;
 | 
				
			||||||
		virtual bool GetFromCache(const std::string &FieldName, const std::string &Value,
 | 
					        virtual bool GetFromCache(const std::string &FieldName, const std::string &Value, RecordType &R)=0;
 | 
				
			||||||
								  RecordType &R) = 0;
 | 
					 | 
				
			||||||
        virtual void UpdateCache(const RecordType &R)=0;
 | 
					        virtual void UpdateCache(const RecordType &R)=0;
 | 
				
			||||||
        virtual void Delete(const std::string &FieldName, const std::string &Value)=0;
 | 
					        virtual void Delete(const std::string &FieldName, const std::string &Value)=0;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    private:
 | 
					    private:
 | 
				
			||||||
        size_t          Size_=0;
 | 
					        size_t          Size_=0;
 | 
				
			||||||
        uint64_t        Timeout_=0;
 | 
					        uint64_t        Timeout_=0;
 | 
				
			||||||
@@ -205,13 +239,24 @@ namespace ORM {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    template <typename RecordTuple, typename RecordType> class DB {
 | 
					    template <typename RecordTuple, typename RecordType> class DB {
 | 
				
			||||||
    public:
 | 
					    public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        typedef const char * field_name_t;
 | 
					        typedef const char * field_name_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		DB(OpenWifi::DBType dbtype, const char *TableName, const FieldVec &Fields,
 | 
					        DB( OpenWifi::DBType dbtype,
 | 
				
			||||||
		   const IndexVec &Indexes, Poco::Data::SessionPool &Pool, Poco::Logger &L,
 | 
					            const char *TableName,
 | 
				
			||||||
		   const char *Prefix, DBCache<RecordType> *Cache = nullptr)
 | 
					            const FieldVec & Fields,
 | 
				
			||||||
			: TableName_(TableName), Type_(dbtype), Pool_(Pool), Logger_(L), Prefix_(Prefix),
 | 
					            const IndexVec & Indexes,
 | 
				
			||||||
			  Cache_(Cache) {
 | 
					            Poco::Data::SessionPool & Pool,
 | 
				
			||||||
 | 
					            Poco::Logger &L,
 | 
				
			||||||
 | 
					            const char *Prefix,
 | 
				
			||||||
 | 
					            DBCache<RecordType> * Cache=nullptr):
 | 
				
			||||||
 | 
					                TableName_(TableName),
 | 
				
			||||||
 | 
					                Type_(dbtype),
 | 
				
			||||||
 | 
					                Pool_(Pool),
 | 
				
			||||||
 | 
					                Logger_(L),
 | 
				
			||||||
 | 
					                Prefix_(Prefix),
 | 
				
			||||||
 | 
					                Cache_(Cache)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
            assert(RecordTuple::length == Fields.size());
 | 
					            assert(RecordTuple::length == Fields.size());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            bool first = true;
 | 
					            bool first = true;
 | 
				
			||||||
@@ -229,8 +274,7 @@ namespace ORM {
 | 
				
			|||||||
                    SelectList_ += "(";
 | 
					                    SelectList_ += "(";
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				CreateFields_ += FieldName + " " + FieldTypeToChar(Type_, i.Type, i.Size) +
 | 
					                CreateFields_ += FieldName + " " + FieldTypeToChar(Type_, i.Type,i.Size) + (i.Index ? " unique primary key" : "");
 | 
				
			||||||
								 (i.Index ? " unique primary key" : "");
 | 
					 | 
				
			||||||
                SelectFields_ += FieldName ;
 | 
					                SelectFields_ += FieldName ;
 | 
				
			||||||
                UpdateFields_ += FieldName + "=?";
 | 
					                UpdateFields_ += FieldName + "=?";
 | 
				
			||||||
                SelectList_ += "?";
 | 
					                SelectList_ += "?";
 | 
				
			||||||
@@ -244,8 +288,7 @@ namespace ORM {
 | 
				
			|||||||
                    for(const auto &j:Indexes) {
 | 
					                    for(const auto &j:Indexes) {
 | 
				
			||||||
                        std::string IndexLine;
 | 
					                        std::string IndexLine;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
						IndexLine = std::string("CREATE INDEX IF NOT EXISTS ") + j.Name +
 | 
					                        IndexLine = std::string("CREATE INDEX IF NOT EXISTS ") + j.Name + std::string(" ON ") + TableName_+ " (";
 | 
				
			||||||
									std::string(" ON ") + TableName_ + " (";
 | 
					 | 
				
			||||||
                        bool first_entry=true;
 | 
					                        bool first_entry=true;
 | 
				
			||||||
                        for(const auto &k:j.Entries) {
 | 
					                        for(const auto &k:j.Entries) {
 | 
				
			||||||
                            auto IndexFieldName = Poco::toLower(k.FieldName);
 | 
					                            auto IndexFieldName = Poco::toLower(k.FieldName);
 | 
				
			||||||
@@ -254,8 +297,7 @@ namespace ORM {
 | 
				
			|||||||
                                IndexLine += " , ";
 | 
					                                IndexLine += " , ";
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                            first_entry = false;
 | 
					                            first_entry = false;
 | 
				
			||||||
							IndexLine += IndexFieldName + std::string(" ") +
 | 
					                            IndexLine += IndexFieldName + std::string(" ") + std::string(k.Type == Indextype::ASC ? "ASC" : "DESC") ;
 | 
				
			||||||
										 std::string(k.Type == Indextype::ASC ? "ASC" : "DESC");
 | 
					 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        IndexLine += " )";
 | 
					                        IndexLine += " )";
 | 
				
			||||||
                        IndexCreation_.template emplace_back(IndexLine);
 | 
					                        IndexCreation_.template emplace_back(IndexLine);
 | 
				
			||||||
@@ -276,8 +318,7 @@ namespace ORM {
 | 
				
			|||||||
                                IndexLine += " ,";
 | 
					                                IndexLine += " ,";
 | 
				
			||||||
                            }
 | 
					                            }
 | 
				
			||||||
                            first_entry = false;
 | 
					                            first_entry = false;
 | 
				
			||||||
							IndexLine += IndexFieldName +
 | 
					                            IndexLine += IndexFieldName + std::string(k.Type == Indextype::ASC ? " ASC" : " DESC");
 | 
				
			||||||
										 std::string(k.Type == Indextype::ASC ? " ASC" : " DESC");
 | 
					 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                        IndexLine += " ) ";
 | 
					                        IndexLine += " ) ";
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
@@ -320,20 +361,15 @@ namespace ORM {
 | 
				
			|||||||
            return std::string("(")+P1 + BOPS[BOP] + P2 +")";
 | 
					            return std::string("(")+P1 + BOPS[BOP] + P2 +")";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		std::string OP([[maybe_unused]] bool Paran, const std::string &P1, SqlBinaryOp BOP,
 | 
					        std::string OP( [[maybe_unused]] bool  Paran, const std::string &P1, SqlBinaryOp BOP , const std::string &P2) {
 | 
				
			||||||
					   const std::string &P2) {
 | 
					 | 
				
			||||||
            return P1 + BOPS[BOP] + P2 +")";
 | 
					            return P1 + BOPS[BOP] + P2 +")";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		template <typename... Others>
 | 
					        template <typename... Others> std::string OP( bool ParanOpen, const std::string &P1, SqlBinaryOp BOP , const std::string &P2, Others... More) {
 | 
				
			||||||
		std::string OP(bool ParanOpen, const std::string &P1, SqlBinaryOp BOP,
 | 
					 | 
				
			||||||
					   const std::string &P2, Others... More) {
 | 
					 | 
				
			||||||
            return P1 + BOPS[BOP] + OP(ParanOpen, P2, More...) + ")";
 | 
					            return P1 + BOPS[BOP] + OP(ParanOpen, P2, More...) + ")";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		template <typename... Others>
 | 
					        template <typename... Others> std::string OP( const std::string &P1, SqlBinaryOp BOP , const std::string &P2, Others... More) {
 | 
				
			||||||
		std::string OP(const std::string &P1, SqlBinaryOp BOP, const std::string &P2,
 | 
					 | 
				
			||||||
					   Others... More) {
 | 
					 | 
				
			||||||
            return std::string{"("} + P1 + BOPS[BOP] + OP(true, P2, More...);
 | 
					            return std::string{"("} + P1 + BOPS[BOP] + OP(true, P2, More...);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -347,24 +383,20 @@ namespace ORM {
 | 
				
			|||||||
                case OpenWifi::DBType::mysql: {
 | 
					                case OpenWifi::DBType::mysql: {
 | 
				
			||||||
                    try {
 | 
					                    try {
 | 
				
			||||||
                        Poco::Data::Session     Session = Pool_.get();
 | 
					                        Poco::Data::Session     Session = Pool_.get();
 | 
				
			||||||
					std::string Statement = IndexCreation_.empty()
 | 
					                        std::string Statement = IndexCreation_.empty() ?    "create table if not exists " + TableName_ +" ( " + CreateFields_ + " )" :
 | 
				
			||||||
												? "create table if not exists " + TableName_ +
 | 
					                                                                            "create table if not exists " + TableName_ +" ( " + CreateFields_ + " ), " + IndexCreation_[0] + " )";
 | 
				
			||||||
													  " ( " + CreateFields_ + " )"
 | 
					 | 
				
			||||||
												: "create table if not exists " + TableName_ +
 | 
					 | 
				
			||||||
													  " ( " + CreateFields_ + " ), " +
 | 
					 | 
				
			||||||
													  IndexCreation_[0] + " )";
 | 
					 | 
				
			||||||
                        Session << Statement , Poco::Data::Keywords::now;
 | 
					                        Session << Statement , Poco::Data::Keywords::now;
 | 
				
			||||||
                    } catch (const Poco::Exception &E) {
 | 
					                    } catch (const Poco::Exception &E) {
 | 
				
			||||||
                        Logger_.error("Failure to create MySQL DB resources.");
 | 
					                        Logger_.error("Failure to create MySQL DB resources.");
 | 
				
			||||||
                        Logger_.log(E);
 | 
					                        Logger_.log(E);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
			} break;
 | 
					                }
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                case OpenWifi::DBType::sqlite: {
 | 
					                case OpenWifi::DBType::sqlite: {
 | 
				
			||||||
                    try {
 | 
					                    try {
 | 
				
			||||||
                        Poco::Data::Session     Session = Pool_.get();
 | 
					                        Poco::Data::Session     Session = Pool_.get();
 | 
				
			||||||
					std::string Statement =
 | 
					                        std::string Statement = "create table if not exists " + TableName_ + " ( " + CreateFields_ + " )";
 | 
				
			||||||
						"create table if not exists " + TableName_ + " ( " + CreateFields_ + " )";
 | 
					 | 
				
			||||||
                        Session << Statement , Poco::Data::Keywords::now;
 | 
					                        Session << Statement , Poco::Data::Keywords::now;
 | 
				
			||||||
                        for(const auto &i:IndexCreation_) {
 | 
					                        for(const auto &i:IndexCreation_) {
 | 
				
			||||||
                            Session << i , Poco::Data::Keywords::now;
 | 
					                            Session << i , Poco::Data::Keywords::now;
 | 
				
			||||||
@@ -373,13 +405,13 @@ namespace ORM {
 | 
				
			|||||||
                        Logger_.error("Failure to create SQLITE DB resources.");
 | 
					                        Logger_.error("Failure to create SQLITE DB resources.");
 | 
				
			||||||
                        Logger_.log(E);
 | 
					                        Logger_.log(E);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
			} break;
 | 
					                }
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                case OpenWifi::DBType::pgsql: {
 | 
					                case OpenWifi::DBType::pgsql: {
 | 
				
			||||||
                    try {
 | 
					                    try {
 | 
				
			||||||
                        Poco::Data::Session     Session = Pool_.get();
 | 
					                        Poco::Data::Session     Session = Pool_.get();
 | 
				
			||||||
					std::string Statement =
 | 
					                        std::string Statement = "create table if not exists " + TableName_ + " ( " + CreateFields_ + " )";
 | 
				
			||||||
						"create table if not exists " + TableName_ + " ( " + CreateFields_ + " )";
 | 
					 | 
				
			||||||
                        Session << Statement , Poco::Data::Keywords::now;
 | 
					                        Session << Statement , Poco::Data::Keywords::now;
 | 
				
			||||||
                        for(const auto &i:IndexCreation_) {
 | 
					                        for(const auto &i:IndexCreation_) {
 | 
				
			||||||
                            Session << i , Poco::Data::Keywords::now;
 | 
					                            Session << i , Poco::Data::Keywords::now;
 | 
				
			||||||
@@ -388,7 +420,8 @@ namespace ORM {
 | 
				
			|||||||
                        Logger_.error("Failure to create POSTGRESQL DB resources.");
 | 
					                        Logger_.error("Failure to create POSTGRESQL DB resources.");
 | 
				
			||||||
                        Logger_.log(E);
 | 
					                        Logger_.log(E);
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
			} break;
 | 
					                }
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            return Upgrade();
 | 
					            return Upgrade();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -400,7 +433,8 @@ namespace ORM {
 | 
				
			|||||||
            std::string R;
 | 
					            std::string R;
 | 
				
			||||||
            R.reserve(S.size()*2+1);
 | 
					            R.reserve(S.size()*2+1);
 | 
				
			||||||
            auto Idx=1;
 | 
					            auto Idx=1;
 | 
				
			||||||
			for (auto const &i : S) {
 | 
					            for(auto const & i:S)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
                if(i=='?') {
 | 
					                if(i=='?') {
 | 
				
			||||||
                    R += '$';
 | 
					                    R += '$';
 | 
				
			||||||
                    R.append(std::to_string(Idx++));
 | 
					                    R.append(std::to_string(Idx++));
 | 
				
			||||||
@@ -424,9 +458,9 @@ namespace ORM {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                RecordTuple RT;
 | 
					                RecordTuple RT;
 | 
				
			||||||
                Convert(R, RT);
 | 
					                Convert(R, RT);
 | 
				
			||||||
				std::string St = "insert into  " + TableName_ + " ( " + SelectFields_ +
 | 
					                std::string St = "insert into  " + TableName_ + " ( " + SelectFields_ + " ) values " + SelectList_;
 | 
				
			||||||
								 " ) values " + SelectList_;
 | 
					                Insert  << ConvertParams(St) ,
 | 
				
			||||||
				Insert << ConvertParams(St), Poco::Data::Keywords::use(RT);
 | 
					                    Poco::Data::Keywords::use(RT);
 | 
				
			||||||
                Insert.execute();
 | 
					                Insert.execute();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if(Cache_)
 | 
					                if(Cache_)
 | 
				
			||||||
@@ -439,8 +473,7 @@ namespace ORM {
 | 
				
			|||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		template <typename T>
 | 
					        template<typename T> bool GetRecord(field_name_t FieldName, const T & Value,  RecordType & R) {
 | 
				
			||||||
		bool GetRecord(field_name_t FieldName, const T &Value, RecordType &R) {
 | 
					 | 
				
			||||||
            try {
 | 
					            try {
 | 
				
			||||||
                assert(ValidFieldName(FieldName));
 | 
					                assert(ValidFieldName(FieldName));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -453,12 +486,12 @@ namespace ORM {
 | 
				
			|||||||
                Poco::Data::Statement   Select(Session);
 | 
					                Poco::Data::Statement   Select(Session);
 | 
				
			||||||
                RecordTuple             RT;
 | 
					                RecordTuple             RT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				std::string St = "select " + SelectFields_ + " from " + TableName_ + " where " +
 | 
					                std::string St = "select " + SelectFields_ + " from " + TableName_ + " where " + FieldName + "=?" + " limit 1";
 | 
				
			||||||
								 FieldName + "=?" + " limit 1";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                auto tValue{Value};
 | 
					                auto tValue{Value};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				Select << ConvertParams(St), Poco::Data::Keywords::into(RT),
 | 
					                Select  << ConvertParams(St) ,
 | 
				
			||||||
 | 
					                    Poco::Data::Keywords::into(RT),
 | 
				
			||||||
                    Poco::Data::Keywords::use(tValue);
 | 
					                    Poco::Data::Keywords::use(tValue);
 | 
				
			||||||
                Select.execute();
 | 
					                Select.execute();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -480,10 +513,10 @@ namespace ORM {
 | 
				
			|||||||
                Poco::Data::Statement   Select(Session);
 | 
					                Poco::Data::Statement   Select(Session);
 | 
				
			||||||
                RecordTuple             RT;
 | 
					                RecordTuple             RT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				std::string St = "select " + SelectFields_ + " from " + TableName_ + " where " +
 | 
					                std::string St = "select " + SelectFields_ + " from " + TableName_ + " where " + WhereClause + " limit 1";
 | 
				
			||||||
								 WhereClause + " limit 1";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
				Select << ConvertParams(St), Poco::Data::Keywords::into(RT);
 | 
					                Select  << ConvertParams(St) ,
 | 
				
			||||||
 | 
					                        Poco::Data::Keywords::into(RT);
 | 
				
			||||||
                Select.execute();
 | 
					                Select.execute();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if(Select.execute()==1) {
 | 
					                if(Select.execute()==1) {
 | 
				
			||||||
@@ -500,8 +533,8 @@ namespace ORM {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        typedef std::vector<std::string> StringVec;
 | 
					        typedef std::vector<std::string> StringVec;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		template <typename T, typename T0, typename T1>
 | 
					        template <  typename T,
 | 
				
			||||||
		bool GR(field_name_t FieldName, T &R, T0 &V0, T1 &V1) {
 | 
					                typename T0, typename T1> bool GR(field_name_t FieldName, T & R,T0 &V0, T1 &V1) {
 | 
				
			||||||
            try {
 | 
					            try {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                assert( ValidFieldName(FieldName) );
 | 
					                assert( ValidFieldName(FieldName) );
 | 
				
			||||||
@@ -510,10 +543,12 @@ namespace ORM {
 | 
				
			|||||||
                Poco::Data::Statement   Select(Session);
 | 
					                Poco::Data::Statement   Select(Session);
 | 
				
			||||||
                RecordTuple RT;
 | 
					                RecordTuple RT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				std::string St = "select " + SelectFields_ + " from " + TableName_ + " where " +
 | 
					                std::string St = "select " + SelectFields_ + " from " + TableName_
 | 
				
			||||||
								 FieldName[0] + "=? and " + FieldName[1] + "=?";
 | 
					                                + " where " + FieldName[0] + "=? and " + FieldName[1] + "=?"  ;
 | 
				
			||||||
				Select << ConvertParams(St), Poco::Data::Keywords::into(RT),
 | 
					                Select  << ConvertParams(St) ,
 | 
				
			||||||
					Poco::Data::Keywords::use(V0), Poco::Data::Keywords::use(V1);
 | 
					                    Poco::Data::Keywords::into(RT),
 | 
				
			||||||
 | 
					                    Poco::Data::Keywords::use(V0),
 | 
				
			||||||
 | 
					                    Poco::Data::Keywords::use(V1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if(Select.execute()==1) {
 | 
					                if(Select.execute()==1) {
 | 
				
			||||||
                    Convert(RT,R);
 | 
					                    Convert(RT,R);
 | 
				
			||||||
@@ -531,7 +566,8 @@ namespace ORM {
 | 
				
			|||||||
                Poco::Data::Session     Session = Pool_.get();
 | 
					                Poco::Data::Session     Session = Pool_.get();
 | 
				
			||||||
                Poco::Data::Statement   Select(Session);
 | 
					                Poco::Data::Statement   Select(Session);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				Select << statement, Poco::Data::Keywords::into(records);
 | 
					                Select  << statement ,
 | 
				
			||||||
 | 
					                        Poco::Data::Keywords::into(records);
 | 
				
			||||||
                Select.execute();
 | 
					                Select.execute();
 | 
				
			||||||
                return true;
 | 
					                return true;
 | 
				
			||||||
            } catch (const Poco::Exception &E) {
 | 
					            } catch (const Poco::Exception &E) {
 | 
				
			||||||
@@ -544,8 +580,7 @@ namespace ORM {
 | 
				
			|||||||
        typedef std::vector<RecordType>     RecordVec;
 | 
					        typedef std::vector<RecordType>     RecordVec;
 | 
				
			||||||
        typedef RecordType                  RecordName;
 | 
					        typedef RecordType                  RecordName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		bool GetRecords(uint64_t Offset, uint64_t HowMany, RecordVec &Records,
 | 
					        bool GetRecords( uint64_t Offset, uint64_t HowMany, RecordVec & Records, const std::string & Where = "", const std::string & OrderBy = "") {
 | 
				
			||||||
						const std::string &Where = "", const std::string &OrderBy = "") {
 | 
					 | 
				
			||||||
            try {
 | 
					            try {
 | 
				
			||||||
                Poco::Data::Session     Session = Pool_.get();
 | 
					                Poco::Data::Session     Session = Pool_.get();
 | 
				
			||||||
                Poco::Data::Statement   Select(Session);
 | 
					                Poco::Data::Statement   Select(Session);
 | 
				
			||||||
@@ -554,7 +589,8 @@ namespace ORM {
 | 
				
			|||||||
                        (Where.empty() ? "" : " where " + Where) + OrderBy +
 | 
					                        (Where.empty() ? "" : " where " + Where) + OrderBy +
 | 
				
			||||||
                        ComputeRange(Offset, HowMany) ;
 | 
					                        ComputeRange(Offset, HowMany) ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				Select << St, Poco::Data::Keywords::into(RL);
 | 
					                Select  << St ,
 | 
				
			||||||
 | 
					                    Poco::Data::Keywords::into(RL);
 | 
				
			||||||
                Select.execute();
 | 
					                Select.execute();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if(Select.rowsExtracted()>0) {
 | 
					                if(Select.rowsExtracted()>0) {
 | 
				
			||||||
@@ -572,8 +608,7 @@ namespace ORM {
 | 
				
			|||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		template <typename T>
 | 
					        template <typename T> bool UpdateRecord(field_name_t FieldName, const T & Value,  const RecordType & R) {
 | 
				
			||||||
		bool UpdateRecord(field_name_t FieldName, const T &Value, const RecordType &R) {
 | 
					 | 
				
			||||||
            try {
 | 
					            try {
 | 
				
			||||||
                assert( ValidFieldName(FieldName) );
 | 
					                assert( ValidFieldName(FieldName) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -586,9 +621,9 @@ namespace ORM {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                auto tValue(Value);
 | 
					                auto tValue(Value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				std::string St =
 | 
					                std::string St = "update " + TableName_ + " set " + UpdateFields_ + " where " + FieldName + "=?" ;
 | 
				
			||||||
					"update " + TableName_ + " set " + UpdateFields_ + " where " + FieldName + "=?";
 | 
					                Update  << ConvertParams(St) ,
 | 
				
			||||||
				Update << ConvertParams(St), Poco::Data::Keywords::use(RT),
 | 
					                    Poco::Data::Keywords::use(RT),
 | 
				
			||||||
                    Poco::Data::Keywords::use(tValue);
 | 
					                    Poco::Data::Keywords::use(tValue);
 | 
				
			||||||
                Update.execute();
 | 
					                Update.execute();
 | 
				
			||||||
                if(Cache_)
 | 
					                if(Cache_)
 | 
				
			||||||
@@ -615,8 +650,7 @@ namespace ORM {
 | 
				
			|||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		template <typename T>
 | 
					        template <typename T> bool ReplaceRecord(field_name_t FieldName, const T & Value,  RecordType & R) {
 | 
				
			||||||
		bool ReplaceRecord(field_name_t FieldName, const T &Value, RecordType &R) {
 | 
					 | 
				
			||||||
            try {
 | 
					            try {
 | 
				
			||||||
                if(Exists(FieldName, Value)) {
 | 
					                if(Exists(FieldName, Value)) {
 | 
				
			||||||
                    return UpdateRecord(FieldName,Value,R);
 | 
					                    return UpdateRecord(FieldName,Value,R);
 | 
				
			||||||
@@ -628,20 +662,18 @@ namespace ORM {
 | 
				
			|||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		template <typename T>
 | 
					        template <typename T> bool GetNameAndDescription(field_name_t FieldName, const T & Value, std::string & Name, std::string & Description ) {
 | 
				
			||||||
		bool GetNameAndDescription(field_name_t FieldName, const T &Value, std::string &Name,
 | 
					 | 
				
			||||||
								   std::string &Description) {
 | 
					 | 
				
			||||||
            try {
 | 
					            try {
 | 
				
			||||||
                assert( ValidFieldName(FieldName) );
 | 
					                assert( ValidFieldName(FieldName) );
 | 
				
			||||||
                Poco::Data::Session     Session = Pool_.get();
 | 
					                Poco::Data::Session     Session = Pool_.get();
 | 
				
			||||||
                Poco::Data::Statement   Select(Session);
 | 
					                Poco::Data::Statement   Select(Session);
 | 
				
			||||||
                RecordTuple             RT;
 | 
					                RecordTuple             RT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				std::string St = "select " + SelectFields_ + " from " + TableName_ + " where " +
 | 
					                std::string St = "select " + SelectFields_ + " from " + TableName_ + " where " + FieldName + "=?" ;
 | 
				
			||||||
								 FieldName + "=?";
 | 
					 | 
				
			||||||
                RecordType R;
 | 
					                RecordType R;
 | 
				
			||||||
                auto tValue{Value};
 | 
					                auto tValue{Value};
 | 
				
			||||||
				Select << ConvertParams(St), Poco::Data::Keywords::into(RT),
 | 
					                Select  << ConvertParams(St) ,
 | 
				
			||||||
 | 
					                    Poco::Data::Keywords::into(RT),
 | 
				
			||||||
                    Poco::Data::Keywords::use(tValue);
 | 
					                    Poco::Data::Keywords::use(tValue);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if(Select.execute()==1) {
 | 
					                if(Select.execute()==1) {
 | 
				
			||||||
@@ -667,7 +699,8 @@ namespace ORM {
 | 
				
			|||||||
                std::string St = "delete from " + TableName_ + " where " + FieldName + "=?" ;
 | 
					                std::string St = "delete from " + TableName_ + " where " + FieldName + "=?" ;
 | 
				
			||||||
                auto tValue{Value};
 | 
					                auto tValue{Value};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				Delete << ConvertParams(St), Poco::Data::Keywords::use(tValue);
 | 
					                Delete  << ConvertParams(St) ,
 | 
				
			||||||
 | 
					                    Poco::Data::Keywords::use(tValue);
 | 
				
			||||||
                Delete.execute();
 | 
					                Delete.execute();
 | 
				
			||||||
                if(Cache_)
 | 
					                if(Cache_)
 | 
				
			||||||
                    Cache_->Delete(FieldName, Value);
 | 
					                    Cache_->Delete(FieldName, Value);
 | 
				
			||||||
@@ -708,8 +741,7 @@ namespace ORM {
 | 
				
			|||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		bool Iterate(std::function<bool(const RecordType &R)> F,
 | 
					        bool Iterate( std::function<bool(const RecordType &R)> F, const std::string & WhereClause = "" ) {
 | 
				
			||||||
					 const std::string &WhereClause = "") {
 | 
					 | 
				
			||||||
            try {
 | 
					            try {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                uint64_t    Offset=0;
 | 
					                uint64_t    Offset=0;
 | 
				
			||||||
@@ -770,10 +802,10 @@ namespace ORM {
 | 
				
			|||||||
                Poco::Data::Session     Session = Pool_.get();
 | 
					                Poco::Data::Session     Session = Pool_.get();
 | 
				
			||||||
                Poco::Data::Statement   Select(Session);
 | 
					                Poco::Data::Statement   Select(Session);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				std::string st{"SELECT COUNT(*) FROM " + TableName_ + " " +
 | 
					                std::string st{"SELECT COUNT(*) FROM " + TableName_ + " " + (Where.empty() ? "" : (" where " + Where)) };
 | 
				
			||||||
							   (Where.empty() ? "" : (" where " + Where))};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
				Select << st, Poco::Data::Keywords::into(Cnt);
 | 
					                Select << st ,
 | 
				
			||||||
 | 
					                    Poco::Data::Keywords::into(Cnt);
 | 
				
			||||||
                Select.execute();
 | 
					                Select.execute();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                return Cnt;
 | 
					                return Cnt;
 | 
				
			||||||
@@ -784,9 +816,7 @@ namespace ORM {
 | 
				
			|||||||
            return 0;
 | 
					            return 0;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		template <typename X>
 | 
					        template <typename X> bool ManipulateVectorMember( X T, field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID, bool Add) {
 | 
				
			||||||
		bool ManipulateVectorMember(X T, field_name_t FieldName, const std::string &ParentUUID,
 | 
					 | 
				
			||||||
									const std::string &ChildUUID, bool Add) {
 | 
					 | 
				
			||||||
            try {
 | 
					            try {
 | 
				
			||||||
                assert( ValidFieldName(FieldName) );
 | 
					                assert( ValidFieldName(FieldName) );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -823,9 +853,7 @@ namespace ORM {
 | 
				
			|||||||
                        Command << i, Poco::Data::Keywords::now;
 | 
					                        Command << i, Poco::Data::Keywords::now;
 | 
				
			||||||
                    } catch (const Poco::Exception &E) {
 | 
					                    } catch (const Poco::Exception &E) {
 | 
				
			||||||
                        // Logger_.log(E);
 | 
					                        // Logger_.log(E);
 | 
				
			||||||
						// Logger_.error(Poco::format("The following statement '%s' generated an
 | 
					                        // Logger_.error(Poco::format("The following statement '%s' generated an exception during a table upgrade. This may or may not be a problem.", i));
 | 
				
			||||||
						// exception during a table upgrade. This may or may not be a problem.",
 | 
					 | 
				
			||||||
						// i));
 | 
					 | 
				
			||||||
                        if(!IgnoreExceptions) {
 | 
					                        if(!IgnoreExceptions) {
 | 
				
			||||||
                            return false;
 | 
					                            return false;
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
@@ -839,137 +867,98 @@ namespace ORM {
 | 
				
			|||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		virtual uint32_t Version() { return 0; }
 | 
					        virtual uint32_t Version() {
 | 
				
			||||||
 | 
					            return 0;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        virtual bool Upgrade(uint32_t from, uint32_t &to) {
 | 
					        virtual bool Upgrade(uint32_t from, uint32_t &to) {
 | 
				
			||||||
            to = from;
 | 
					            to = from;
 | 
				
			||||||
            return true;
 | 
					            return true;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
		inline bool AddChild(field_name_t FieldName, const std::string &ParentUUID,
 | 
					        inline bool AddChild(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
 | 
				
			||||||
							 const std::string &ChildUUID) {
 | 
					            return ManipulateVectorMember(&RecordType::children, FieldName, ParentUUID, ChildUUID, true);
 | 
				
			||||||
			return ManipulateVectorMember(&RecordType::children, FieldName, ParentUUID, ChildUUID,
 | 
					 | 
				
			||||||
										  true);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline bool DeleteChild(field_name_t FieldName, const std::string &ParentUUID,
 | 
					        inline bool DeleteChild(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
 | 
				
			||||||
								const std::string &ChildUUID) {
 | 
					            return ManipulateVectorMember(&RecordType::children, FieldName, ParentUUID, ChildUUID, false);
 | 
				
			||||||
			return ManipulateVectorMember(&RecordType::children, FieldName, ParentUUID, ChildUUID,
 | 
					 | 
				
			||||||
										  false);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline bool AddLocation(field_name_t FieldName, const std::string &ParentUUID,
 | 
					        inline bool AddLocation(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
 | 
				
			||||||
								const std::string &ChildUUID) {
 | 
					            return ManipulateVectorMember(&RecordType::locations, FieldName, ParentUUID, ChildUUID, true);
 | 
				
			||||||
			return ManipulateVectorMember(&RecordType::locations, FieldName, ParentUUID, ChildUUID,
 | 
					 | 
				
			||||||
										  true);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline bool DeleteLocation(field_name_t FieldName, const std::string &ParentUUID,
 | 
					        inline bool DeleteLocation(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
 | 
				
			||||||
								   const std::string &ChildUUID) {
 | 
					            return ManipulateVectorMember(&RecordType::locations, FieldName, ParentUUID, ChildUUID, false);
 | 
				
			||||||
			return ManipulateVectorMember(&RecordType::locations, FieldName, ParentUUID, ChildUUID,
 | 
					 | 
				
			||||||
										  false);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline bool AddContact(field_name_t FieldName, const std::string &ParentUUID,
 | 
					        inline bool AddContact(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
 | 
				
			||||||
							   const std::string &ChildUUID) {
 | 
					            return ManipulateVectorMember(&RecordType::contacts, FieldName, ParentUUID, ChildUUID, true);
 | 
				
			||||||
			return ManipulateVectorMember(&RecordType::contacts, FieldName, ParentUUID, ChildUUID,
 | 
					 | 
				
			||||||
										  true);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline bool DeleteContact(field_name_t FieldName, const std::string &ParentUUID,
 | 
					        inline bool DeleteContact(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
 | 
				
			||||||
								  const std::string &ChildUUID) {
 | 
					            return ManipulateVectorMember(&RecordType::contacts, FieldName, ParentUUID, ChildUUID, false);
 | 
				
			||||||
			return ManipulateVectorMember(&RecordType::contacts, FieldName, ParentUUID, ChildUUID,
 | 
					 | 
				
			||||||
										  false);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline bool AddVenue(field_name_t FieldName, const std::string &ParentUUID,
 | 
					        inline bool AddVenue(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
 | 
				
			||||||
							 const std::string &ChildUUID) {
 | 
					            return ManipulateVectorMember(&RecordType::venues, FieldName, ParentUUID, ChildUUID, true);
 | 
				
			||||||
			return ManipulateVectorMember(&RecordType::venues, FieldName, ParentUUID, ChildUUID,
 | 
					 | 
				
			||||||
										  true);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline bool DeleteVenue(field_name_t FieldName, const std::string &ParentUUID,
 | 
					        inline bool DeleteVenue(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
 | 
				
			||||||
								const std::string &ChildUUID) {
 | 
					            return ManipulateVectorMember(&RecordType::venues, FieldName, ParentUUID, ChildUUID, false);
 | 
				
			||||||
			return ManipulateVectorMember(&RecordType::venues, FieldName, ParentUUID, ChildUUID,
 | 
					 | 
				
			||||||
										  false);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline bool AddDevice(field_name_t FieldName, const std::string &ParentUUID,
 | 
					        inline bool AddDevice(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
 | 
				
			||||||
							  const std::string &ChildUUID) {
 | 
					            return ManipulateVectorMember(&RecordType::devices, FieldName, ParentUUID, ChildUUID, true);
 | 
				
			||||||
			return ManipulateVectorMember(&RecordType::devices, FieldName, ParentUUID, ChildUUID,
 | 
					 | 
				
			||||||
										  true);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline bool DeleteDevice(field_name_t FieldName, const std::string &ParentUUID,
 | 
					        inline bool DeleteDevice(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
 | 
				
			||||||
								 const std::string &ChildUUID) {
 | 
					            return ManipulateVectorMember(&RecordType::devices, FieldName, ParentUUID, ChildUUID, false);
 | 
				
			||||||
			return ManipulateVectorMember(&RecordType::devices, FieldName, ParentUUID, ChildUUID,
 | 
					 | 
				
			||||||
										  false);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline bool AddEntity(field_name_t FieldName, const std::string &ParentUUID,
 | 
					        inline bool AddEntity(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
 | 
				
			||||||
							  const std::string &ChildUUID) {
 | 
					            return ManipulateVectorMember(&RecordType::entities, FieldName, ParentUUID, ChildUUID, true);
 | 
				
			||||||
			return ManipulateVectorMember(&RecordType::entities, FieldName, ParentUUID, ChildUUID,
 | 
					 | 
				
			||||||
										  true);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline bool DeleteEntity(field_name_t FieldName, const std::string &ParentUUID,
 | 
					        inline bool DeleteEntity(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
 | 
				
			||||||
								 const std::string &ChildUUID) {
 | 
					            return ManipulateVectorMember(&RecordType::entities, FieldName, ParentUUID, ChildUUID, false);
 | 
				
			||||||
			return ManipulateVectorMember(&RecordType::entities, FieldName, ParentUUID, ChildUUID,
 | 
					 | 
				
			||||||
										  false);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline bool AddUser(field_name_t FieldName, const std::string &ParentUUID,
 | 
					        inline bool AddUser(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
 | 
				
			||||||
							const std::string &ChildUUID) {
 | 
					            return ManipulateVectorMember(&RecordType::users, FieldName, ParentUUID, ChildUUID, true);
 | 
				
			||||||
			return ManipulateVectorMember(&RecordType::users, FieldName, ParentUUID, ChildUUID,
 | 
					 | 
				
			||||||
										  true);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline bool DelUser(field_name_t FieldName, const std::string &ParentUUID,
 | 
					        inline bool DelUser(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
 | 
				
			||||||
							const std::string &ChildUUID) {
 | 
					            return ManipulateVectorMember(&RecordType::users, FieldName, ParentUUID, ChildUUID, false);
 | 
				
			||||||
			return ManipulateVectorMember(&RecordType::users, FieldName, ParentUUID, ChildUUID,
 | 
					 | 
				
			||||||
										  false);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline bool AddConfiguration(field_name_t FieldName, const std::string &ParentUUID,
 | 
					        inline bool AddConfiguration(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
 | 
				
			||||||
									 const std::string &ChildUUID) {
 | 
					            return ManipulateVectorMember(&RecordType::deviceConfiguration, FieldName, ParentUUID, ChildUUID, true);
 | 
				
			||||||
			return ManipulateVectorMember(&RecordType::deviceConfiguration, FieldName, ParentUUID,
 | 
					 | 
				
			||||||
										  ChildUUID, true);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline bool DelConfiguration(field_name_t FieldName, const std::string &ParentUUID,
 | 
					        inline bool DelConfiguration(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
 | 
				
			||||||
									 const std::string &ChildUUID) {
 | 
					            return ManipulateVectorMember(&RecordType::deviceConfiguration, FieldName, ParentUUID, ChildUUID, false);
 | 
				
			||||||
			return ManipulateVectorMember(&RecordType::deviceConfiguration, FieldName, ParentUUID,
 | 
					 | 
				
			||||||
										  ChildUUID, false);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline bool AddVariable(field_name_t FieldName, const std::string &ParentUUID,
 | 
					        inline bool AddVariable(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
 | 
				
			||||||
								const std::string &ChildUUID) {
 | 
					            return ManipulateVectorMember(&RecordType::variables, FieldName, ParentUUID, ChildUUID, true);
 | 
				
			||||||
			return ManipulateVectorMember(&RecordType::variables, FieldName, ParentUUID, ChildUUID,
 | 
					 | 
				
			||||||
										  true);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline bool DelVariable(field_name_t FieldName, const std::string &ParentUUID,
 | 
					        inline bool DelVariable(field_name_t FieldName, const std::string & ParentUUID, const std::string & ChildUUID) {
 | 
				
			||||||
								const std::string &ChildUUID) {
 | 
					            return ManipulateVectorMember(&RecordType::variables, FieldName, ParentUUID, ChildUUID, false);
 | 
				
			||||||
			return ManipulateVectorMember(&RecordType::variables, FieldName, ParentUUID, ChildUUID,
 | 
					 | 
				
			||||||
										  false);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline bool AddInUse(field_name_t FieldName, const std::string &ParentUUID,
 | 
					        inline bool AddInUse(field_name_t FieldName, const std::string & ParentUUID, const std::string & Prefix, const std::string & ChildUUID) {
 | 
				
			||||||
							 const std::string &Prefix, const std::string &ChildUUID) {
 | 
					 | 
				
			||||||
            std::string FakeUUID{ Prefix + ":" + ChildUUID};
 | 
					            std::string FakeUUID{ Prefix + ":" + ChildUUID};
 | 
				
			||||||
			return ManipulateVectorMember(&RecordType::inUse, FieldName, ParentUUID, FakeUUID,
 | 
					            return ManipulateVectorMember(&RecordType::inUse,FieldName, ParentUUID, FakeUUID, true);
 | 
				
			||||||
										  true);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline bool DeleteInUse(field_name_t FieldName, const std::string &ParentUUID,
 | 
					        inline bool DeleteInUse(field_name_t FieldName, const std::string & ParentUUID, const std::string & Prefix, const std::string & ChildUUID) {
 | 
				
			||||||
								const std::string &Prefix, const std::string &ChildUUID) {
 | 
					 | 
				
			||||||
            std::string FakeUUID{ Prefix + ":" + ChildUUID};
 | 
					            std::string FakeUUID{ Prefix + ":" + ChildUUID};
 | 
				
			||||||
			return ManipulateVectorMember(&RecordType::inUse, FieldName, ParentUUID, FakeUUID,
 | 
					            return ManipulateVectorMember(&RecordType::inUse,FieldName, ParentUUID, FakeUUID, false);
 | 
				
			||||||
										  false);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		inline bool GetInUse(field_name_t FieldName, const std::string &UUID,
 | 
					        inline bool GetInUse(field_name_t FieldName, const std::string & UUID, std::vector<std::string> & UUIDs ) {
 | 
				
			||||||
							 std::vector<std::string> &UUIDs) {
 | 
					 | 
				
			||||||
            RecordType  R;
 | 
					            RecordType  R;
 | 
				
			||||||
            if(GetRecord(FieldName,UUID,R)) {
 | 
					            if(GetRecord(FieldName,UUID,R)) {
 | 
				
			||||||
                UUIDs = R.inUse;
 | 
					                UUIDs = R.inUse;
 | 
				
			||||||
@@ -988,20 +977,16 @@ namespace ORM {
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        [[nodiscard]] inline std::string ComputeRange(uint64_t From, uint64_t HowMany) {
 | 
					        [[nodiscard]] inline std::string ComputeRange(uint64_t From, uint64_t HowMany) {
 | 
				
			||||||
			if (From < 1)
 | 
					            if(From<1) From=0;
 | 
				
			||||||
				From = 0;
 | 
					 | 
				
			||||||
            switch(Type_) {
 | 
					            switch(Type_) {
 | 
				
			||||||
                case OpenWifi::DBType::sqlite:
 | 
					                case OpenWifi::DBType::sqlite:
 | 
				
			||||||
                    return " LIMIT " + std::to_string(From) + ", " + std::to_string(HowMany) +  " ";
 | 
					                    return " LIMIT " + std::to_string(From) + ", " + std::to_string(HowMany) +  " ";
 | 
				
			||||||
                case OpenWifi::DBType::pgsql:
 | 
					                case OpenWifi::DBType::pgsql:
 | 
				
			||||||
				return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From) +
 | 
					                    return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From) + " ";
 | 
				
			||||||
					   " ";
 | 
					 | 
				
			||||||
                case OpenWifi::DBType::mysql:
 | 
					                case OpenWifi::DBType::mysql:
 | 
				
			||||||
				return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From) +
 | 
					                    return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From) + " ";
 | 
				
			||||||
					   " ";
 | 
					 | 
				
			||||||
                default:
 | 
					                default:
 | 
				
			||||||
				return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From) +
 | 
					                    return " LIMIT " + std::to_string(HowMany) + " OFFSET " + std::to_string(From) + " ";
 | 
				
			||||||
					   " ";
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1025,7 +1010,6 @@ namespace ORM {
 | 
				
			|||||||
        Poco::Logger                &Logger_;
 | 
					        Poco::Logger                &Logger_;
 | 
				
			||||||
        std::string                 Prefix_;
 | 
					        std::string                 Prefix_;
 | 
				
			||||||
        DBCache<RecordType>         *Cache_= nullptr;
 | 
					        DBCache<RecordType>         *Cache_= nullptr;
 | 
				
			||||||
 | 
					 | 
				
			||||||
    private:
 | 
					    private:
 | 
				
			||||||
        std::string                 CreateFields_;
 | 
					        std::string                 CreateFields_;
 | 
				
			||||||
        std::string                 SelectFields_;
 | 
					        std::string                 SelectFields_;
 | 
				
			||||||
@@ -1034,4 +1018,5 @@ namespace ORM {
 | 
				
			|||||||
        std::vector<std::string>    IndexCreation_;
 | 
					        std::vector<std::string>    IndexCreation_;
 | 
				
			||||||
        std::map<std::string,int>   FieldNames_;
 | 
					        std::map<std::string,int>   FieldNames_;
 | 
				
			||||||
    };
 | 
					    };
 | 
				
			||||||
} // namespace ORM
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,8 +4,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <cstring>
 | 
					 | 
				
			||||||
#include <string>
 | 
					#include <string>
 | 
				
			||||||
 | 
					#include <cstring>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "Poco/String.h"
 | 
					#include "Poco/String.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -41,10 +41,7 @@ namespace OpenWifi {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi::RESTAPI::Errors {
 | 
					namespace OpenWifi::RESTAPI::Errors {
 | 
				
			||||||
	struct msg {
 | 
					    struct msg { uint64_t err_num; std::string err_txt; };
 | 
				
			||||||
		uint64_t err_num;
 | 
					 | 
				
			||||||
		std::string err_txt;
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
    static const struct msg Error404{404,"Resource does not exist."};
 | 
					    static const struct msg Error404{404,"Resource does not exist."};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    static const struct msg SUCCESS{0,"No error."};
 | 
					    static const struct msg SUCCESS{0,"No error."};
 | 
				
			||||||
@@ -60,9 +57,7 @@ namespace OpenWifi::RESTAPI::Errors {
 | 
				
			|||||||
    static const struct msg RATE_LIMIT_EXCEEDED{10,"Rate limit exceeded."};
 | 
					    static const struct msg RATE_LIMIT_EXCEEDED{10,"Rate limit exceeded."};
 | 
				
			||||||
    static const struct msg BAD_MFA_TRANSACTION{11,"Bad MFA transaction."};
 | 
					    static const struct msg BAD_MFA_TRANSACTION{11,"Bad MFA transaction."};
 | 
				
			||||||
    static const struct msg MFA_FAILURE{12,"MFA failure."};
 | 
					    static const struct msg MFA_FAILURE{12,"MFA failure."};
 | 
				
			||||||
	static const struct msg SECURITY_SERVICE_UNREACHABLE {
 | 
					    static const struct msg SECURITY_SERVICE_UNREACHABLE{13,"Security service is unreachable, try again later."};
 | 
				
			||||||
		13, "Security service is unreachable, try again later."
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
    static const struct msg CANNOT_REFRESH_TOKEN{14,"Cannot refresh token."};
 | 
					    static const struct msg CANNOT_REFRESH_TOKEN{14,"Cannot refresh token."};
 | 
				
			||||||
    static const struct msg ACCOUNT_SUSPENDED{15,"Account has been suspended."};
 | 
					    static const struct msg ACCOUNT_SUSPENDED{15,"Account has been suspended."};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -80,9 +75,7 @@ namespace OpenWifi::RESTAPI::Errors {
 | 
				
			|||||||
    static const struct msg RecordNotCreated{1011,"Record could not be created."};
 | 
					    static const struct msg RecordNotCreated{1011,"Record could not be created."};
 | 
				
			||||||
    static const struct msg RecordNotUpdated{1012,"Record could not be updated."};
 | 
					    static const struct msg RecordNotUpdated{1012,"Record could not be updated."};
 | 
				
			||||||
    static const struct msg UnknownManagementPolicyUUID{1013,"Unknown management policy UUID."};
 | 
					    static const struct msg UnknownManagementPolicyUUID{1013,"Unknown management policy UUID."};
 | 
				
			||||||
	static const struct msg CannotDeleteRoot {
 | 
					    static const struct msg CannotDeleteRoot{1014,"Root Entity cannot be removed, only modified."};
 | 
				
			||||||
		1014, "Root Entity cannot be removed, only modified."
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
    static const struct msg MustCreateRootFirst{1015,"Root entity must be created first."};
 | 
					    static const struct msg MustCreateRootFirst{1015,"Root entity must be created first."};
 | 
				
			||||||
    static const struct msg ParentUUIDMustExist{1016,"Parent UUID must exist."};
 | 
					    static const struct msg ParentUUIDMustExist{1016,"Parent UUID must exist."};
 | 
				
			||||||
    static const struct msg ConfigurationMustExist{1017,"Configuration must exist."};
 | 
					    static const struct msg ConfigurationMustExist{1017,"Configuration must exist."};
 | 
				
			||||||
@@ -102,76 +95,41 @@ namespace OpenWifi::RESTAPI::Errors {
 | 
				
			|||||||
    static const struct msg InvalidCommand{1031,"Invalid command."};
 | 
					    static const struct msg InvalidCommand{1031,"Invalid command."};
 | 
				
			||||||
    static const struct msg NoRecordsDeleted{1032,"No records deleted."};
 | 
					    static const struct msg NoRecordsDeleted{1032,"No records deleted."};
 | 
				
			||||||
    static const struct msg DeviceNotConnected{1033,"Device is not currently connected."};
 | 
					    static const struct msg DeviceNotConnected{1033,"Device is not currently connected."};
 | 
				
			||||||
	static const struct msg CannotCreateWS {
 | 
					    static const struct msg CannotCreateWS{1034,"Telemetry system could not create WS endpoint. Please try again."};
 | 
				
			||||||
		1034, "Telemetry system could not create WS endpoint. Please try again."
 | 
					    static const struct msg BothDeviceTypeRevision{1035,"Both deviceType and revision must be set."};
 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
	static const struct msg BothDeviceTypeRevision {
 | 
					 | 
				
			||||||
		1035, "Both deviceType and revision must be set."
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
    static const struct msg IdOrSerialEmpty{1036,"SerialNumber and Id must not be empty."};
 | 
					    static const struct msg IdOrSerialEmpty{1036,"SerialNumber and Id must not be empty."};
 | 
				
			||||||
    static const struct msg MissingUserID{1037,"Missing user ID."};
 | 
					    static const struct msg MissingUserID{1037,"Missing user ID."};
 | 
				
			||||||
    static const struct msg IdMustBe0{1038,"To create a user, you must set the ID to 0"};
 | 
					    static const struct msg IdMustBe0{1038,"To create a user, you must set the ID to 0"};
 | 
				
			||||||
    static const struct msg InvalidUserRole{1039,"Invalid userRole."};
 | 
					    static const struct msg InvalidUserRole{1039,"Invalid userRole."};
 | 
				
			||||||
    static const struct msg InvalidEmailAddress{1040,"Invalid email address."};
 | 
					    static const struct msg InvalidEmailAddress{1040,"Invalid email address."};
 | 
				
			||||||
	static const struct msg PasswordRejected {
 | 
					    static const struct msg PasswordRejected{1041,"Password was rejected. This maybe an old password."};
 | 
				
			||||||
		1041, "Password was rejected. This maybe an old password."
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
    static const struct msg InvalidIPRanges{1042,"Invalid IP range specifications."};
 | 
					    static const struct msg InvalidIPRanges{1042,"Invalid IP range specifications."};
 | 
				
			||||||
    static const struct msg InvalidLOrderBy{1043,"Invalid orderBy specification."};
 | 
					    static const struct msg InvalidLOrderBy{1043,"Invalid orderBy specification."};
 | 
				
			||||||
	static const struct msg NeedMobileNumber {
 | 
					    static const struct msg NeedMobileNumber{1044,"You must provide at least one validated phone number."};
 | 
				
			||||||
		1044, "You must provide at least one validated phone number."
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
    static const struct msg BadMFAMethod{1045,"MFA only supports sms or email."};
 | 
					    static const struct msg BadMFAMethod{1045,"MFA only supports sms or email."};
 | 
				
			||||||
    static const struct msg InvalidCredentials{1046,"Invalid credentials (username/password)."};
 | 
					    static const struct msg InvalidCredentials{1046,"Invalid credentials (username/password)."};
 | 
				
			||||||
	static const struct msg InvalidPassword {
 | 
					    static const struct msg InvalidPassword{1047,"Password does not conform to basic password rules."};
 | 
				
			||||||
		1047, "Password does not conform to basic password rules."
 | 
					    static const struct msg UserPendingVerification{1048,"User access denied pending email verification."};
 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
	static const struct msg UserPendingVerification {
 | 
					 | 
				
			||||||
		1048, "User access denied pending email verification."
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
    static const struct msg PasswordMustBeChanged{1049,"Password must be changed."};
 | 
					    static const struct msg PasswordMustBeChanged{1049,"Password must be changed."};
 | 
				
			||||||
	static const struct msg UnrecognizedRequest {
 | 
					    static const struct msg UnrecognizedRequest{1050,"Ill-formed request. Please consult documentation."};
 | 
				
			||||||
		1050, "Ill-formed request. Please consult documentation."
 | 
					    static const struct msg MissingAuthenticationInformation{1051,"Missing authentication information."};
 | 
				
			||||||
	};
 | 
					    static const struct msg InsufficientAccessRights{1052,"Insufficient access rights to complete the operation."};
 | 
				
			||||||
	static const struct msg MissingAuthenticationInformation {
 | 
					 | 
				
			||||||
		1051, "Missing authentication information."
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
	static const struct msg InsufficientAccessRights {
 | 
					 | 
				
			||||||
		1052, "Insufficient access rights to complete the operation."
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
    static const struct msg ExpiredToken{1053,"Token has expired, user must login."};
 | 
					    static const struct msg ExpiredToken{1053,"Token has expired, user must login."};
 | 
				
			||||||
    static const struct msg SubscriberMustExist{1054,"Subscriber must exist."};
 | 
					    static const struct msg SubscriberMustExist{1054,"Subscriber must exist."};
 | 
				
			||||||
	static const struct msg AuthenticatorVerificationIncomplete {
 | 
					    static const struct msg AuthenticatorVerificationIncomplete{1055,"Authenticator validation is not complete."};
 | 
				
			||||||
		1055, "Authenticator validation is not complete."
 | 
					    static const struct msg SMSCouldNotBeSentRetry{1056,"SMS could not be sent to validate device, try later or change the phone number."};
 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
	static const struct msg SMSCouldNotBeSentRetry {
 | 
					 | 
				
			||||||
		1056, "SMS could not be sent to validate device, try later or change the phone number."
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
    static const struct msg SMSCouldNotValidate{1057,"Code and number could not be validated"};
 | 
					    static const struct msg SMSCouldNotValidate{1057,"Code and number could not be validated"};
 | 
				
			||||||
	static const struct msg InvalidDeviceClass {
 | 
					    static const struct msg InvalidDeviceClass{1058,"Invalid device class. Must be: any, venue, entity, or subscriber"};
 | 
				
			||||||
		1058, "Invalid device class. Must be: any, venue, entity, or subscriber"
 | 
					    static const struct msg SerialNumberAlreadyProvisioned{1059,"This device has already been provisioned to a subscriber."};
 | 
				
			||||||
	};
 | 
					    static const struct msg SerialNumberNotTheProperClass{1060,"Device is not available to subscribers. It ahs been assigned to another class of devices."};
 | 
				
			||||||
	static const struct msg SerialNumberAlreadyProvisioned {
 | 
					 | 
				
			||||||
		1059, "This device has already been provisioned to a subscriber."
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
	static const struct msg SerialNumberNotTheProperClass {
 | 
					 | 
				
			||||||
		1060, "Device is not available to subscribers. It ahs been assigned to another class of "
 | 
					 | 
				
			||||||
			  "devices."
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
    static const struct msg UserAlreadyExists{1061,"Username already exists."};
 | 
					    static const struct msg UserAlreadyExists{1061,"Username already exists."};
 | 
				
			||||||
    static const struct msg NotImplemented{1062,"Function not implemented."};
 | 
					    static const struct msg NotImplemented{1062,"Function not implemented."};
 | 
				
			||||||
    static const struct msg VariableMustExist{1063,"Specified variable does not exist."};
 | 
					    static const struct msg VariableMustExist{1063,"Specified variable does not exist."};
 | 
				
			||||||
    static const struct msg InvalidEntityType{1064,"Invalid entity type."};
 | 
					    static const struct msg InvalidEntityType{1064,"Invalid entity type."};
 | 
				
			||||||
	static const struct msg CannotDeleteSubEntity {
 | 
					    static const struct msg CannotDeleteSubEntity{1065,"Cannot delete the default subscriber entity."};
 | 
				
			||||||
		1065, "Cannot delete the default subscriber entity."
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
    static const struct msg OperatorIdMustExist{1066,"Missing or bad Operator ID"};
 | 
					    static const struct msg OperatorIdMustExist{1066,"Missing or bad Operator ID"};
 | 
				
			||||||
	static const struct msg CannotDeleteDefaultOperator {
 | 
					    static const struct msg CannotDeleteDefaultOperator{1067,"Cannot delete the default operator."};
 | 
				
			||||||
		1067, "Cannot delete the default operator."
 | 
					    static const struct msg CannotCreateDefaultOperator{1068,"Cannot create the default operator."};
 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
	static const struct msg CannotCreateDefaultOperator {
 | 
					 | 
				
			||||||
		1068, "Cannot create the default operator."
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
    static const struct msg InvalidRRM{1069,"Invalid RRM value."};
 | 
					    static const struct msg InvalidRRM{1069,"Invalid RRM value."};
 | 
				
			||||||
    static const struct msg InvalidIPAddresses{1070,"Invalid IP addresses."};
 | 
					    static const struct msg InvalidIPAddresses{1070,"Invalid IP addresses."};
 | 
				
			||||||
    static const struct msg InvalidBillingCode{1071,"Empty of invalid billing code."};
 | 
					    static const struct msg InvalidBillingCode{1071,"Empty of invalid billing code."};
 | 
				
			||||||
@@ -184,19 +142,11 @@ namespace OpenWifi::RESTAPI::Errors {
 | 
				
			|||||||
    static const struct msg InvalidOperatorId{1078,"Invalid operator ID."};
 | 
					    static const struct msg InvalidOperatorId{1078,"Invalid operator ID."};
 | 
				
			||||||
    static const struct msg InvalidServiceClassId{1079,"Invalid service class ID."};
 | 
					    static const struct msg InvalidServiceClassId{1079,"Invalid service class ID."};
 | 
				
			||||||
    static const struct msg InvalidSubscriberDeviceId{1080,"Invalid subscriber device ID."};
 | 
					    static const struct msg InvalidSubscriberDeviceId{1080,"Invalid subscriber device ID."};
 | 
				
			||||||
	static const struct msg InvalidRegistrationOperatorId {
 | 
					    static const struct msg InvalidRegistrationOperatorId{1081,"Invalid registration operator ID."};
 | 
				
			||||||
		1081, "Invalid registration operator ID."
 | 
					    static const struct msg InvalidRegistrationOperatorName{1082,"Invalid registration operator name."};
 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
	static const struct msg InvalidRegistrationOperatorName {
 | 
					 | 
				
			||||||
		1082, "Invalid registration operator name."
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
    static const struct msg RegistrationNameDuplicate{1083,"Registration name must be unique."};
 | 
					    static const struct msg RegistrationNameDuplicate{1083,"Registration name must be unique."};
 | 
				
			||||||
	static const struct msg SMSMFANotEnabled {
 | 
					    static const struct msg SMSMFANotEnabled{1084,"SMS is not enabled in the security service."};
 | 
				
			||||||
		1084, "SMS is not enabled in the security service."
 | 
					    static const struct msg EMailMFANotEnabled{1085,"email is not enabled in the security service."};
 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
	static const struct msg EMailMFANotEnabled {
 | 
					 | 
				
			||||||
		1085, "email is not enabled in the security service."
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    static const struct msg TOTInvalidCode{1086,"Invalid code."};
 | 
					    static const struct msg TOTInvalidCode{1086,"Invalid code."};
 | 
				
			||||||
    static const struct msg TOTInvalidIndex{1087,"Invalid index."};
 | 
					    static const struct msg TOTInvalidIndex{1087,"Invalid index."};
 | 
				
			||||||
@@ -209,9 +159,7 @@ namespace OpenWifi::RESTAPI::Errors {
 | 
				
			|||||||
    static const struct msg SignupWaitingForDevice{1093,"Waiting for device."};
 | 
					    static const struct msg SignupWaitingForDevice{1093,"Waiting for device."};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    static const struct msg SMSMissingPhoneNumber{1094,"Missing phone number"};
 | 
					    static const struct msg SMSMissingPhoneNumber{1094,"Missing phone number"};
 | 
				
			||||||
	static const struct msg SMSTryLater {
 | 
					    static const struct msg SMSTryLater{1095,"SMS could not be sent. Verify the number or try again later."};
 | 
				
			||||||
		1095, "SMS could not be sent. Verify the number or try again later."
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
    static const struct msg SMSMissingChallenge{1096,"Missing 'challengeCode'"};
 | 
					    static const struct msg SMSMissingChallenge{1096,"Missing 'challengeCode'"};
 | 
				
			||||||
	static const struct msg MustHaveConfigElement{1097,"Must have 'configuration' element."};
 | 
						static const struct msg MustHaveConfigElement{1097,"Must have 'configuration' element."};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -221,122 +169,60 @@ namespace OpenWifi::RESTAPI::Errors {
 | 
				
			|||||||
    static const struct msg SubNoDeviceActivated{1100,"No devices activated yet."};
 | 
					    static const struct msg SubNoDeviceActivated{1100,"No devices activated yet."};
 | 
				
			||||||
    static const struct msg SubConfigNotRefreshed{1101,"Configuration could not be refreshed."};
 | 
					    static const struct msg SubConfigNotRefreshed{1101,"Configuration could not be refreshed."};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static const struct msg ProvServiceNotAvailable {
 | 
					    static const struct msg ProvServiceNotAvailable{1102,"Provisioning service not available yet."};
 | 
				
			||||||
		1102, "Provisioning service not available yet."
 | 
					    static const struct msg SSIDInvalidPassword{1103,"Invalid password length. Must be 8 characters or greater, and a maximum of 32 characters."};
 | 
				
			||||||
	};
 | 
					    static const struct msg InvalidStartingIPAddress{1104,"Invalid starting/ending IP address."};
 | 
				
			||||||
	static const struct msg SSIDInvalidPassword {
 | 
					    static const struct msg SubnetFormatError{1105,"Subnet must be in format like 192.168.1.1/24."};
 | 
				
			||||||
		1103, "Invalid password length. Must be 8 characters or greater, and a maximum of 32 "
 | 
					    static const struct msg DeviceModeError{1106,"Device mode subnet must be of the form 192.168.1.1/24."};
 | 
				
			||||||
			  "characters."
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
	static const struct msg InvalidStartingIPAddress {
 | 
					 | 
				
			||||||
		1104, "Invalid starting/ending IP address."
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
	static const struct msg SubnetFormatError {
 | 
					 | 
				
			||||||
		1105, "Subnet must be in format like 192.168.1.1/24."
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
	static const struct msg DeviceModeError {
 | 
					 | 
				
			||||||
		1106, "Device mode subnet must be of the form 192.168.1.1/24."
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    static const struct msg BadDeviceMode{1107,"Mode must be bridge, nat, or manual."};
 | 
					    static const struct msg BadDeviceMode{1107,"Mode must be bridge, nat, or manual."};
 | 
				
			||||||
	static const struct msg DefaultGatewayFormat {
 | 
					    static const struct msg DefaultGatewayFormat{1108,"Default gateway must be in format like 192.168.1.1."};
 | 
				
			||||||
		1108, "Default gateway must be in format like 192.168.1.1."
 | 
					    static const struct msg PrimaryDNSFormat{1109,"Primary DNS must be an IP address i.e. 192.168.1.1."};
 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
	static const struct msg PrimaryDNSFormat {
 | 
					 | 
				
			||||||
		1109, "Primary DNS must be an IP address i.e. 192.168.1.1."
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static const struct msg SecondaryDNSFormat {
 | 
					    static const struct msg SecondaryDNSFormat{1110,"Secondary DNS must be an IP address i.e. 192.168.1.1."};
 | 
				
			||||||
		1110, "Secondary DNS must be an IP address i.e. 192.168.1.1."
 | 
					    static const struct msg BadConnectionType{1111,"Internet Connection must be automatic, bridge, pppoe, or manual."};
 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
	static const struct msg BadConnectionType {
 | 
					 | 
				
			||||||
		1111, "Internet Connection must be automatic, bridge, pppoe, or manual."
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
    static const struct msg InvalidDeviceID{1112,"Invalid deviceID."};
 | 
					    static const struct msg InvalidDeviceID{1112,"Invalid deviceID."};
 | 
				
			||||||
    static const struct msg InvalidVisibilityAttribute{1113,"Invalid visibility attribute."};
 | 
					    static const struct msg InvalidVisibilityAttribute{1113,"Invalid visibility attribute."};
 | 
				
			||||||
    static const struct msg UnknownConfigurationSection{1114,"Unknown section."};
 | 
					    static const struct msg UnknownConfigurationSection{1114,"Unknown section."};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static const struct msg CannotValidatePhoneNumber {
 | 
					    static const struct msg CannotValidatePhoneNumber{1115,"Phone number could not be validated."};
 | 
				
			||||||
		1115, "Phone number could not be validated."
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
    static const struct msg RootUsersNoOwners{1116,"ROOT users may not have owners."};
 | 
					    static const struct msg RootUsersNoOwners{1116,"ROOT users may not have owners."};
 | 
				
			||||||
	static const struct msg PartnerMustHaveEntity {
 | 
					    static const struct msg PartnerMustHaveEntity{1118,"Partner user must belong to an entity."};
 | 
				
			||||||
		1118, "Partner user must belong to an entity."
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
    static const struct msg RootCannotModifyUsers{1119,"ROOT may not modify user roles."};
 | 
					    static const struct msg RootCannotModifyUsers{1119,"ROOT may not modify user roles."};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    static const struct msg CertificateNotIssued{1120,"Certificate was not issued."};
 | 
					    static const struct msg CertificateNotIssued{1120,"Certificate was not issued."};
 | 
				
			||||||
	static const struct msg IncompleteCertificate {
 | 
					    static const struct msg IncompleteCertificate{1121,"Incomplete certificate information. Cannot be downloaded. You must delete and recreate."};
 | 
				
			||||||
		1121, "Incomplete certificate information. Cannot be downloaded. You must delete and "
 | 
					 | 
				
			||||||
			  "recreate."
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
    static const struct msg InvalidCertificateType{1122,"Invalid certificate type."};
 | 
					    static const struct msg InvalidCertificateType{1122,"Invalid certificate type."};
 | 
				
			||||||
    static const struct msg InvalidDeviceName{1123,"Invalid device name."};
 | 
					    static const struct msg InvalidDeviceName{1123,"Invalid device name."};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    static const struct msg InvalidRedirectorName{1124,"Invalid redirector name"};
 | 
					    static const struct msg InvalidRedirectorName{1124,"Invalid redirector name"};
 | 
				
			||||||
	static const struct msg CommonNameAlreadyExists {
 | 
					    static const struct msg CommonNameAlreadyExists{1125,"A device/server of this name already exists"};
 | 
				
			||||||
		1125, "A device/server of this name already exists"
 | 
					    static const struct msg CertificateAlreadyExists{1126,"A certificate for this device already exists."};
 | 
				
			||||||
	};
 | 
					    static const struct msg CannotCreateCertTryAgain{1127,"Device certificate could not be created. Please try later."};
 | 
				
			||||||
	static const struct msg CertificateAlreadyExists {
 | 
					 | 
				
			||||||
		1126, "A certificate for this device already exists."
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
	static const struct msg CannotCreateCertTryAgain {
 | 
					 | 
				
			||||||
		1127, "Device certificate could not be created. Please try later."
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
    static const struct msg CouldNotRevoke{1128,"Certificate could not be revoked."};
 | 
					    static const struct msg CouldNotRevoke{1128,"Certificate could not be revoked."};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static const struct msg CouldNotModifyCert {
 | 
					    static const struct msg CouldNotModifyCert{1129,"Certificate could not me modified. Please verify the information you supplied."};
 | 
				
			||||||
		1129, "Certificate could not me modified. Please verify the information you supplied."
 | 
					    static const struct msg BatchCertNoCreated{1130,"Certificates have not been created for this batch."};
 | 
				
			||||||
	};
 | 
					    static const struct msg BatchTooBig{1131,"Illegal number of MAC Addresses: must be between 1 and 1000."};
 | 
				
			||||||
	static const struct msg BatchCertNoCreated {
 | 
					 | 
				
			||||||
		1130, "Certificates have not been created for this batch."
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
	static const struct msg BatchTooBig {
 | 
					 | 
				
			||||||
		1131, "Illegal number of MAC Addresses: must be between 1 and 1000."
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static const struct msg OutstandingJobs {
 | 
					    static const struct msg OutstandingJobs{1132,"Batch has running outstanding jobs. Please wait until job is finished."};
 | 
				
			||||||
		1132, "Batch has running outstanding jobs. Please wait until job is finished."
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
    static const struct msg InvalidSMSNotificationList{1133,"Invalid SMS Notification list."};
 | 
					    static const struct msg InvalidSMSNotificationList{1133,"Invalid SMS Notification list."};
 | 
				
			||||||
	static const struct msg InvalidEMailNotificationList {
 | 
					    static const struct msg InvalidEMailNotificationList{1134,"Invalid email Notification list."};
 | 
				
			||||||
		1134, "Invalid email Notification list."
 | 
					    static const struct msg CannotChangeCommanNames{1135,"You cannot provide new/modified common names after jobs have been run for a batch."};
 | 
				
			||||||
	};
 | 
					    static const struct msg FailedToVerifyDigicert{1136,"Failed to verify the DigiCert information provided."};
 | 
				
			||||||
	static const struct msg CannotChangeCommanNames {
 | 
					 | 
				
			||||||
		1135, "You cannot provide new/modified common names after jobs have been run for a batch."
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
	static const struct msg FailedToVerifyDigicert {
 | 
					 | 
				
			||||||
		1136, "Failed to verify the DigiCert information provided."
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
    static const struct msg CouldNotPerformCommand{1137,"Could not perform command."};
 | 
					    static const struct msg CouldNotPerformCommand{1137,"Could not perform command."};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static const struct msg PoolNameInvalid{1138,"Pool name is invalid."};
 | 
						static const struct msg PoolNameInvalid{1138,"Pool name is invalid."};
 | 
				
			||||||
	static const struct msg InvalidRadiusProxyStrategy {
 | 
						static const struct msg InvalidRadiusProxyStrategy{1139,"Strategy name must be: random, round_robin, weighted."};
 | 
				
			||||||
		1139, "Strategy name must be: random, round_robin, weighted."
 | 
						static const struct msg InvalidRadiusProxyMonitorMethod{1140,"monitorMethod must be: none, https, radius."};
 | 
				
			||||||
	};
 | 
						static const struct msg MustHaveAtLeastOneRadiusServer{1141,"Must have at least one RADIUS server."};
 | 
				
			||||||
	static const struct msg InvalidRadiusProxyMonitorMethod {
 | 
						static const struct msg InvalidRadiusServerEntry{1142,"RADIUS Server IP address invalid or port missing."};
 | 
				
			||||||
		1140, "monitorMethod must be: none, https, radius."
 | 
						static const struct msg InvalidRadiusServerWeigth{1143,"RADIUS Server IP weight cannot be 0."};
 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
	static const struct msg MustHaveAtLeastOneRadiusServer {
 | 
					 | 
				
			||||||
		1141, "Must have at least one RADIUS server."
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
	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 {
 | 
						static const struct msg MaximumRTTYSessionsReached{1144,"Too many RTTY sessions currently active"};
 | 
				
			||||||
		1144, "Too many RTTY sessions currently active"
 | 
						static const struct msg DeviceIsAlreadyBusy{1145,"Device is already executing a command. Please try later."};
 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
	static const struct msg DeviceIsAlreadyBusy {
 | 
					 | 
				
			||||||
		1145, "Device is already executing a command. Please try later."
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static const struct msg DeviceRequiresSignature {
 | 
						static const struct msg DeviceRequiresSignature{1146,"Device requires device signature to be provided."};
 | 
				
			||||||
		1146, "Device requires device signature to be provided."
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    static const struct msg ApiKeyNameAlreadyExists{1147,"API Key name must be unique."};
 | 
					    static const struct msg ApiKeyNameAlreadyExists{1147,"API Key name must be unique."};
 | 
				
			||||||
    static const struct msg TooManyApiKeys{1148,"Too many API Keys have already been created."};
 | 
					    static const struct msg TooManyApiKeys{1148,"Too many API Keys have already been created."};
 | 
				
			||||||
@@ -344,73 +230,32 @@ namespace OpenWifi::RESTAPI::Errors {
 | 
				
			|||||||
    static const struct msg ApiKeyNameDoesNotExist{1150,"API Key name does not exist."};
 | 
					    static const struct msg ApiKeyNameDoesNotExist{1150,"API Key name does not exist."};
 | 
				
			||||||
    static const struct msg ApiKeyDoesNotExist{1150,"API Key does not exist."};
 | 
					    static const struct msg ApiKeyDoesNotExist{1150,"API Key does not exist."};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static const struct msg DeviceIsRestricted {
 | 
						static const struct msg DeviceIsRestricted{1151,"Device is protected by regulation. This function is not allowed."};
 | 
				
			||||||
		1151, "Device is protected by regulation. This function is not allowed."
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
	static const struct msg InvalidURI{1152,"Invalid URI."};
 | 
						static const struct msg InvalidURI{1152,"Invalid URI."};
 | 
				
			||||||
	static const struct msg InvalidScriptSelection {
 | 
						static const struct msg InvalidScriptSelection{1153,"Only script or scriptId must be specified. Not both."};
 | 
				
			||||||
		1153, "Only script or scriptId must be specified. Not both."
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static const struct msg NoDeviceStatisticsYet{1154,"Device statistics not available yet."};
 | 
						static const struct msg NoDeviceStatisticsYet{1154,"Device statistics not available yet."};
 | 
				
			||||||
	static const struct msg AccountSuspended {
 | 
					    static const struct msg AccountSuspended{1155,"You account was suspended. You can only use this site in read-only mode for now."};
 | 
				
			||||||
		1155, "You account was suspended. You can only use this site in read-only mode for now."
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
    static const struct msg BatchNameAlreadyExists{1156,"Batch name must be unique."};
 | 
					    static const struct msg BatchNameAlreadyExists{1156,"Batch name must be unique."};
 | 
				
			||||||
    static const struct msg RedirectorNameIsInvalid{1157,"Redirector name is invalid."};
 | 
					    static const struct msg RedirectorNameIsInvalid{1157,"Redirector name is invalid."};
 | 
				
			||||||
	static const struct msg CertificateAlreadyBelongsToYou {
 | 
					    static const struct msg CertificateAlreadyBelongsToYou{1158,"The serial number already belongs to you. Please use the certificate modification API to change the redirector."};
 | 
				
			||||||
		1158, "The serial number already belongs to you. Please use the certificate modification "
 | 
					    static const struct msg RelocationDisabledForThisDevice{1159,"Relocation disabled for this device."};
 | 
				
			||||||
			  "API to change the redirector."
 | 
					    static const struct msg CannotModifyServerCertificates{1160,"Server certificates cannot be modified."};
 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
	static const struct msg RelocationDisabledForThisDevice {
 | 
					 | 
				
			||||||
		1159, "Relocation disabled for this device."
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
	static const struct msg CannotModifyServerCertificates {
 | 
					 | 
				
			||||||
		1160, "Server certificates cannot be modified."
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static const struct msg TransferNotInDispute {
 | 
					    static const struct msg TransferNotInDispute{1161,"The specified transfer is not being disputed."};
 | 
				
			||||||
		1161, "The specified transfer is not being disputed."
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
    static const struct msg MissingComment{1162,"Missing comment."};
 | 
					    static const struct msg MissingComment{1162,"Missing comment."};
 | 
				
			||||||
	static const struct msg EntityNotAllowedToTransfer {
 | 
					    static const struct msg EntityNotAllowedToTransfer{1163,"Entity is not allowed to transfer devices."};
 | 
				
			||||||
		1163, "Entity is not allowed to transfer devices."
 | 
					    static const struct msg DailyTransferQuotaExceeded{1164,"Entity has exceeded its daily quota."};
 | 
				
			||||||
	};
 | 
					    static const struct msg CertificateWasNotRevoked{1165,"Certificate was not revoked, so it may not be re-created."};
 | 
				
			||||||
	static const struct msg DailyTransferQuotaExceeded {
 | 
					    static const struct msg CertificateTransferNoLongerExists{1166,"The device certificate associated with this transfer no longer seem to exist."};
 | 
				
			||||||
		1164, "Entity has exceeded its daily quota."
 | 
					    static const struct msg CertificateTransferEntityNoLongerExists{1167,"The entity tied to this transfer no longer seems to exist."};
 | 
				
			||||||
	};
 | 
					    static const struct msg CannotRollBackDueToDigiCert{1168,"The change could not be rolled back at this time. Please try later."};
 | 
				
			||||||
	static const struct msg CertificateWasNotRevoked {
 | 
					    static const struct msg CertificateTransferAlreadyRolledBack{1169,"The certificate has already been rolled back."};
 | 
				
			||||||
		1165, "Certificate was not revoked, so it may not be re-created."
 | 
					    static const struct msg FirmwareBDInProgress{1170,"Firmware DB update already in progress."};
 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
	static const struct msg CertificateTransferNoLongerExists {
 | 
					 | 
				
			||||||
		1166, "The device certificate associated with this transfer no longer seem to exist."
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
	static const struct msg CertificateTransferEntityNoLongerExists {
 | 
					 | 
				
			||||||
		1167, "The entity tied to this transfer no longer seems to exist."
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
	static const struct msg CannotRollBackDueToDigiCert {
 | 
					 | 
				
			||||||
		1168, "The change could not be rolled back at this time. Please try later."
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
	static const struct msg CertificateTransferAlreadyRolledBack {
 | 
					 | 
				
			||||||
		1169, "The certificate has already been rolled back."
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
	static const struct msg FirmwareBDInProgress {
 | 
					 | 
				
			||||||
		1170, "Firmware DB update already in progress."
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
	static const struct msg SimulatedDeviceNotSupported {
 | 
					 | 
				
			||||||
		1171, "Command not supported on simulated device."
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    static const struct msg SimulationDoesNotExist {
 | 
						}
 | 
				
			||||||
        7000, "Simulation Instance ID does not exist."
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    static const struct msg SimulationIsAlreadyRunning {
 | 
					 | 
				
			||||||
        7001, "There is an instance of this simulation already running.."
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace OpenWifi::RESTAPI::Errors
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi::RESTAPI::Protocol {
 | 
					namespace OpenWifi::RESTAPI::Protocol {
 | 
				
			||||||
	static const char * CAPABILITIES = "capabilities";
 | 
						static const char * CAPABILITIES = "capabilities";
 | 
				
			||||||
@@ -543,7 +388,7 @@ namespace OpenWifi::RESTAPI::Protocol {
 | 
				
			|||||||
	static const char * INTERVAL = "interval";
 | 
						static const char * INTERVAL = "interval";
 | 
				
			||||||
	static const char * UI = "UI";
 | 
						static const char * UI = "UI";
 | 
				
			||||||
	static const char * BANDWIDTH = "bandwidth";
 | 
						static const char * BANDWIDTH = "bandwidth";
 | 
				
			||||||
} // namespace OpenWifi::RESTAPI::Protocol
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi::uCentralProtocol {
 | 
					namespace OpenWifi::uCentralProtocol {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -566,7 +411,6 @@ namespace OpenWifi::uCentralProtocol {
 | 
				
			|||||||
    static const char *HEALTHCHECK = "healthcheck";
 | 
					    static const char *HEALTHCHECK = "healthcheck";
 | 
				
			||||||
    static const char *LOG = "log";
 | 
					    static const char *LOG = "log";
 | 
				
			||||||
    static const char *CRASHLOG = "crashlog";
 | 
					    static const char *CRASHLOG = "crashlog";
 | 
				
			||||||
	static const char *REBOOTLOG = "rebootLog";
 | 
					 | 
				
			||||||
    static const char *PING = "ping";
 | 
					    static const char *PING = "ping";
 | 
				
			||||||
    static const char *CFGPENDING = "cfgpending";
 | 
					    static const char *CFGPENDING = "cfgpending";
 | 
				
			||||||
    static const char *RECOVERY = "recovery";
 | 
					    static const char *RECOVERY = "recovery";
 | 
				
			||||||
@@ -625,8 +469,6 @@ namespace OpenWifi::uCentralProtocol {
 | 
				
			|||||||
    static const char *DEVICEUPDATE = "deviceupdate";
 | 
					    static const char *DEVICEUPDATE = "deviceupdate";
 | 
				
			||||||
	static const char *FWSIGNATURE = "FWsignature";
 | 
						static const char *FWSIGNATURE = "FWsignature";
 | 
				
			||||||
	static const char *SIGNATURE = "signature";
 | 
						static const char *SIGNATURE = "signature";
 | 
				
			||||||
	static const char *INFO = "info";
 | 
					 | 
				
			||||||
	static const char *DATE = "date";
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    static const char *SERIALNUMBER = "serialNumber";
 | 
					    static const char *SERIALNUMBER = "serialNumber";
 | 
				
			||||||
    static const char *COMPATIBLE = "compatible";
 | 
					    static const char *COMPATIBLE = "compatible";
 | 
				
			||||||
@@ -648,7 +490,7 @@ namespace OpenWifi::uCentralProtocol {
 | 
				
			|||||||
	static const char *RADIUSCOA = "coa";
 | 
						static const char *RADIUSCOA = "coa";
 | 
				
			||||||
	static const char *RADIUSDST = "dst";
 | 
						static const char *RADIUSDST = "dst";
 | 
				
			||||||
	static const char *IES = "ies";
 | 
						static const char *IES = "ies";
 | 
				
			||||||
} // namespace OpenWifi::uCentralProtocol
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi::uCentralProtocol::Events {
 | 
					namespace OpenWifi::uCentralProtocol::Events {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -657,7 +499,6 @@ namespace OpenWifi::uCentralProtocol::Events {
 | 
				
			|||||||
    static const char *HEALTHCHECK = "healthcheck";
 | 
					    static const char *HEALTHCHECK = "healthcheck";
 | 
				
			||||||
    static const char *LOG = "log";
 | 
					    static const char *LOG = "log";
 | 
				
			||||||
    static const char *CRASHLOG = "crashlog";
 | 
					    static const char *CRASHLOG = "crashlog";
 | 
				
			||||||
	static const char *REBOOTLOG = "rebootLog";
 | 
					 | 
				
			||||||
    static const char *PING = "ping";
 | 
					    static const char *PING = "ping";
 | 
				
			||||||
    static const char *CFGPENDING = "cfgpending";
 | 
					    static const char *CFGPENDING = "cfgpending";
 | 
				
			||||||
    static const char *RECOVERY = "recovery";
 | 
					    static const char *RECOVERY = "recovery";
 | 
				
			||||||
@@ -681,8 +522,7 @@ namespace OpenWifi::uCentralProtocol::Events {
 | 
				
			|||||||
		ET_VENUEBROADCAST,
 | 
							ET_VENUEBROADCAST,
 | 
				
			||||||
		ET_EVENT,
 | 
							ET_EVENT,
 | 
				
			||||||
		ET_WIFISCAN,
 | 
							ET_WIFISCAN,
 | 
				
			||||||
		ET_ALARM,
 | 
							ET_ALARM
 | 
				
			||||||
		ET_REBOOTLOG
 | 
					 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline EVENT_MSG EventFromString(const std::string & Method) {
 | 
						inline EVENT_MSG EventFromString(const std::string & Method) {
 | 
				
			||||||
@@ -713,12 +553,10 @@ namespace OpenWifi::uCentralProtocol::Events {
 | 
				
			|||||||
		else if(strcmp(WIFISCAN,Method.c_str())==0)
 | 
							else if(strcmp(WIFISCAN,Method.c_str())==0)
 | 
				
			||||||
			return ET_WIFISCAN;
 | 
								return ET_WIFISCAN;
 | 
				
			||||||
		else if(strcmp(ALARM,Method.c_str())==0)
 | 
							else if(strcmp(ALARM,Method.c_str())==0)
 | 
				
			||||||
 | 
								return ET_WIFISCAN;
 | 
				
			||||||
		return ET_ALARM;
 | 
							return ET_ALARM;
 | 
				
			||||||
		else if (strcmp(REBOOTLOG, Method.c_str()) == 0)
 | 
					 | 
				
			||||||
			return ET_REBOOTLOG;
 | 
					 | 
				
			||||||
		return ET_UNKNOWN;
 | 
					 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
} // namespace OpenWifi::uCentralProtocol::Events
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi::APCommands {
 | 
					namespace OpenWifi::APCommands {
 | 
				
			||||||
	enum class Commands:uint8_t {
 | 
						enum class Commands:uint8_t {
 | 
				
			||||||
@@ -744,17 +582,28 @@ namespace OpenWifi::APCommands {
 | 
				
			|||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline static const std::vector<const char *> uCentralAPCommands {
 | 
						inline static const std::vector<const char *> uCentralAPCommands {
 | 
				
			||||||
		RESTAPI::Protocol::CAPABILITIES, RESTAPI::Protocol::LOGS,
 | 
							RESTAPI::Protocol::CAPABILITIES,
 | 
				
			||||||
		RESTAPI::Protocol::HEALTHCHECKS, RESTAPI::Protocol::STATISTICS,
 | 
							RESTAPI::Protocol::LOGS,
 | 
				
			||||||
		RESTAPI::Protocol::STATUS,		 RESTAPI::Protocol::RTTY,
 | 
							RESTAPI::Protocol::HEALTHCHECKS,
 | 
				
			||||||
		RESTAPI::Protocol::CONFIGURE,	 RESTAPI::Protocol::UPGRADE,
 | 
							RESTAPI::Protocol::STATISTICS,
 | 
				
			||||||
		RESTAPI::Protocol::REBOOT,		 RESTAPI::Protocol::FACTORY,
 | 
							RESTAPI::Protocol::STATUS,
 | 
				
			||||||
		RESTAPI::Protocol::LEDS,		 RESTAPI::Protocol::TRACE,
 | 
							RESTAPI::Protocol::RTTY,
 | 
				
			||||||
		RESTAPI::Protocol::REQUEST,		 RESTAPI::Protocol::WIFISCAN,
 | 
							RESTAPI::Protocol::CONFIGURE,
 | 
				
			||||||
		RESTAPI::Protocol::EVENTQUEUE,	 RESTAPI::Protocol::TELEMETRY,
 | 
							RESTAPI::Protocol::UPGRADE,
 | 
				
			||||||
		RESTAPI::Protocol::PING,		 RESTAPI::Protocol::SCRIPT};
 | 
							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 const char * to_string(Commands Cmd) {
 | 
				
			||||||
 | 
							return uCentralAPCommands[(uint8_t)Cmd];
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline Commands to_apcommand(const char *cmd) {
 | 
						inline Commands to_apcommand(const char *cmd) {
 | 
				
			||||||
		for(auto i=(uint8_t)Commands::capabilities;i!=(uint8_t)Commands::unknown;++i) {
 | 
							for(auto i=(uint8_t)Commands::capabilities;i!=(uint8_t)Commands::unknown;++i) {
 | 
				
			||||||
@@ -764,7 +613,7 @@ namespace OpenWifi::APCommands {
 | 
				
			|||||||
		return Commands::unknown;
 | 
							return Commands::unknown;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace OpenWifi::APCommands
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi::Provisioning::DeviceClass {
 | 
					namespace OpenWifi::Provisioning::DeviceClass {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -778,7 +627,7 @@ namespace OpenWifi::Provisioning::DeviceClass {
 | 
				
			|||||||
        return std::find(cbegin(Values), cend(Values), s) != cend(Values);
 | 
					        return std::find(cbegin(Values), cend(Values), s) != cend(Values);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace OpenWifi::Provisioning::DeviceClass
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(__GNUC__ )
 | 
					#if defined(__GNUC__ )
 | 
				
			||||||
#pragma GCC diagnostic pop
 | 
					#pragma GCC diagnostic pop
 | 
				
			||||||
@@ -787,3 +636,5 @@ namespace OpenWifi::Provisioning::DeviceClass {
 | 
				
			|||||||
#if defined(__clang__)
 | 
					#if defined(__clang__)
 | 
				
			||||||
#pragma clang diagnostic pop
 | 
					#pragma clang diagnostic pop
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,8 +4,8 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "Poco/Path.h"
 | 
					#include "Poco/Path.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "framework/AppServiceRegistry.h"
 | 
					 | 
				
			||||||
#include "framework/utils.h"
 | 
					#include "framework/utils.h"
 | 
				
			||||||
 | 
					#include "framework/AppServiceRegistry.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi::Utils {
 | 
					namespace OpenWifi::Utils {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -27,21 +27,11 @@ namespace OpenWifi::Utils {
 | 
				
			|||||||
			std::all_of(Serial.begin(),Serial.end(),[](auto i){return std::isxdigit(i);}));
 | 
								std::all_of(Serial.begin(),Serial.end(),[](auto i){return std::isxdigit(i);}));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	[[nodiscard]] bool ValidSerialNumbers(const std::vector<std::string> &numbers) {
 | 
					 | 
				
			||||||
		return std::all_of(numbers.begin(),numbers.end(),[](auto &number) {return ValidSerialNumber(number);});
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
[[nodiscard]] bool ValidUUID(const std::string &UUID) {
 | 
					[[nodiscard]] bool ValidUUID(const std::string &UUID) {
 | 
				
			||||||
	if(UUID.size()>36)
 | 
						if(UUID.size()>36)
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
	uint dashes=0;
 | 
						uint dashes=0;
 | 
				
			||||||
		return (std::all_of(UUID.begin(), UUID.end(),
 | 
						return (std::all_of(UUID.begin(),UUID.end(),[&](auto i){ if(i=='-') dashes++; return i=='-' || std::isxdigit(i);})) && (dashes>0);
 | 
				
			||||||
							[&](auto i) {
 | 
					 | 
				
			||||||
								if (i == '-')
 | 
					 | 
				
			||||||
									dashes++;
 | 
					 | 
				
			||||||
								return i == '-' || std::isxdigit(i);
 | 
					 | 
				
			||||||
							})) &&
 | 
					 | 
				
			||||||
			   (dashes > 0);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[nodiscard]] std::vector<std::string> Split(const std::string &List, char Delimiter ) {
 | 
					[[nodiscard]] std::vector<std::string> Split(const std::string &List, char Delimiter ) {
 | 
				
			||||||
@@ -49,20 +39,25 @@ namespace OpenWifi::Utils {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	unsigned long P=0;
 | 
						unsigned long P=0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		while (P < List.size()) {
 | 
						while(P<List.size())
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
		unsigned long P2 = List.find_first_of(Delimiter, P);
 | 
							unsigned long P2 = List.find_first_of(Delimiter, P);
 | 
				
			||||||
		if(P2==std::string::npos) {
 | 
							if(P2==std::string::npos) {
 | 
				
			||||||
			ReturnList.push_back(List.substr(P));
 | 
								ReturnList.push_back(List.substr(P));
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
			} else
 | 
							}
 | 
				
			||||||
 | 
							else
 | 
				
			||||||
			ReturnList.push_back(List.substr(P,P2-P));
 | 
								ReturnList.push_back(List.substr(P,P2-P));
 | 
				
			||||||
		P=P2+1;
 | 
							P=P2+1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return ReturnList;
 | 
						return ReturnList;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	[[nodiscard]] std::string FormatIPv6(const std::string &I) {
 | 
					
 | 
				
			||||||
		if (I.substr(0, 8) == "[::ffff:") {
 | 
					[[nodiscard]] std::string FormatIPv6(const std::string & I )
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if(I.substr(0,8) == "[::ffff:")
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
		unsigned long PClosingBracket = I.find_first_of(']');
 | 
							unsigned long PClosingBracket = I.find_first_of(']');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		std::string ip = I.substr(8, PClosingBracket-8);
 | 
							std::string ip = I.substr(8, PClosingBracket-8);
 | 
				
			||||||
@@ -87,24 +82,12 @@ namespace OpenWifi::Utils {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	char buf[18];
 | 
						char buf[18];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		buf[0] = R[0];
 | 
						buf[0] = R[0]; buf[1] = R[1] ; buf[2] = ':' ;
 | 
				
			||||||
		buf[1] = R[1];
 | 
						buf[3] = R[2] ; buf[4] = R[3]; buf[5] = ':' ;
 | 
				
			||||||
		buf[2] = ':';
 | 
						buf[6] = R[4]; buf[7] = R[5] ; buf[8] = ':' ;
 | 
				
			||||||
		buf[3] = R[2];
 | 
						buf[9] = R[6] ; buf[10]= R[7]; buf[11] = ':';
 | 
				
			||||||
		buf[4] = R[3];
 | 
						buf[12] = R[8] ; buf[13]= R[9]; buf[14] = ':';
 | 
				
			||||||
		buf[5] = ':';
 | 
						buf[15] = R[10] ; buf[16]= R[11];buf[17] = 0;
 | 
				
			||||||
		buf[6] = R[4];
 | 
					 | 
				
			||||||
		buf[7] = R[5];
 | 
					 | 
				
			||||||
		buf[8] = ':';
 | 
					 | 
				
			||||||
		buf[9] = R[6];
 | 
					 | 
				
			||||||
		buf[10] = R[7];
 | 
					 | 
				
			||||||
		buf[11] = ':';
 | 
					 | 
				
			||||||
		buf[12] = R[8];
 | 
					 | 
				
			||||||
		buf[13] = R[9];
 | 
					 | 
				
			||||||
		buf[14] = ':';
 | 
					 | 
				
			||||||
		buf[15] = R[10];
 | 
					 | 
				
			||||||
		buf[16] = R[11];
 | 
					 | 
				
			||||||
		buf[17] = 0;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return buf;
 | 
						return buf;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -127,8 +110,7 @@ namespace OpenWifi::Utils {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[nodiscard]] bool ValidHostname(const std::string &Hostname) {
 | 
					[[nodiscard]] bool ValidHostname(const std::string &Hostname) {
 | 
				
			||||||
		static std::regex HostNameRegex(
 | 
					    static std::regex HostNameRegex("^(?!-)[A-Za-z0-9-]+([\\-\\.]{1}[a-z0-9]+)*\\.[A-Za-z]{2,6}$");
 | 
				
			||||||
			"^(?!-)[A-Za-z0-9-]+([\\-\\.]{1}[a-z0-9]+)*\\.[A-Za-z]{2,6}$");
 | 
					 | 
				
			||||||
    return std::regex_match(Hostname,HostNameRegex);
 | 
					    return std::regex_match(Hostname,HostNameRegex);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -138,7 +120,8 @@ namespace OpenWifi::Utils {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	static const char hex[] = "0123456789abcdef";
 | 
						static const char hex[] = "0123456789abcdef";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for (const auto &i : B) {
 | 
						for(const auto &i:B)
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
		R += (hex[ (i & 0xf0) >> 4]);
 | 
							R += (hex[ (i & 0xf0) >> 4]);
 | 
				
			||||||
		R += (hex[ (i & 0x0f) ]);
 | 
							R += (hex[ (i & 0x0f) ]);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -146,8 +129,7 @@ namespace OpenWifi::Utils {
 | 
				
			|||||||
	return R;
 | 
						return R;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	inline static const char kEncodeLookup[] =
 | 
					inline static const char kEncodeLookup[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 | 
				
			||||||
		"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 | 
					 | 
				
			||||||
inline static const char kPadCharacter = '=';
 | 
					inline static const char kPadCharacter = '=';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using byte = std::uint8_t;
 | 
					using byte = std::uint8_t;
 | 
				
			||||||
@@ -189,17 +171,17 @@ namespace OpenWifi::Utils {
 | 
				
			|||||||
	return encoded;
 | 
						return encoded;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	[[nodiscard]] std::vector<byte> base64decode(const std::string &input) {
 | 
					[[nodiscard]] std::vector<byte> base64decode(const std::string& input)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
	if(input.length() % 4)
 | 
						if(input.length() % 4)
 | 
				
			||||||
		throw std::runtime_error("Invalid base64 length!");
 | 
							throw std::runtime_error("Invalid base64 length!");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	std::size_t padding=0;
 | 
						std::size_t padding=0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (input.length()) {
 | 
						if(input.length())
 | 
				
			||||||
			if (input[input.length() - 1] == kPadCharacter)
 | 
						{
 | 
				
			||||||
				padding++;
 | 
							if(input[input.length() - 1] == kPadCharacter) padding++;
 | 
				
			||||||
			if (input[input.length() - 2] == kPadCharacter)
 | 
							if(input[input.length() - 2] == kPadCharacter) padding++;
 | 
				
			||||||
				padding++;
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	std::vector<byte> decoded;
 | 
						std::vector<byte> decoded;
 | 
				
			||||||
@@ -208,21 +190,20 @@ namespace OpenWifi::Utils {
 | 
				
			|||||||
	std::uint32_t temp=0;
 | 
						std::uint32_t temp=0;
 | 
				
			||||||
	auto it = input.begin();
 | 
						auto it = input.begin();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		while (it < input.end()) {
 | 
						while(it < input.end())
 | 
				
			||||||
			for (std::size_t i = 0; i < 4; ++i) {
 | 
						{
 | 
				
			||||||
 | 
							for(std::size_t i = 0; i < 4; ++i)
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
			temp <<= 6;
 | 
								temp <<= 6;
 | 
				
			||||||
				if (*it >= 0x41 && *it <= 0x5A)
 | 
								if     (*it >= 0x41 && *it <= 0x5A) temp |= *it - 0x41;
 | 
				
			||||||
					temp |= *it - 0x41;
 | 
								else if(*it >= 0x61 && *it <= 0x7A) temp |= *it - 0x47;
 | 
				
			||||||
				else if (*it >= 0x61 && *it <= 0x7A)
 | 
								else if(*it >= 0x30 && *it <= 0x39) temp |= *it + 0x04;
 | 
				
			||||||
					temp |= *it - 0x47;
 | 
								else if(*it == 0x2B)                temp |= 0x3E;
 | 
				
			||||||
				else if (*it >= 0x30 && *it <= 0x39)
 | 
								else if(*it == 0x2F)                temp |= 0x3F;
 | 
				
			||||||
					temp |= *it + 0x04;
 | 
								else if(*it == kPadCharacter)
 | 
				
			||||||
				else if (*it == 0x2B)
 | 
								{
 | 
				
			||||||
					temp |= 0x3E;
 | 
									switch(input.end() - it)
 | 
				
			||||||
				else if (*it == 0x2F)
 | 
									{
 | 
				
			||||||
					temp |= 0x3F;
 | 
					 | 
				
			||||||
				else if (*it == kPadCharacter) {
 | 
					 | 
				
			||||||
					switch (input.end() - it) {
 | 
					 | 
				
			||||||
				case 1:
 | 
									case 1:
 | 
				
			||||||
					decoded.push_back((temp >> 16) & 0x000000FF);
 | 
										decoded.push_back((temp >> 16) & 0x000000FF);
 | 
				
			||||||
					decoded.push_back((temp >> 8 ) & 0x000000FF);
 | 
										decoded.push_back((temp >> 8 ) & 0x000000FF);
 | 
				
			||||||
@@ -233,8 +214,8 @@ namespace OpenWifi::Utils {
 | 
				
			|||||||
				default:
 | 
									default:
 | 
				
			||||||
					throw std::runtime_error("Invalid padding in base64!");
 | 
										throw std::runtime_error("Invalid padding in base64!");
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				} else
 | 
								}
 | 
				
			||||||
					throw std::runtime_error("Invalid character in base64!");
 | 
								else throw std::runtime_error("Invalid character in base64!");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			++it;
 | 
								++it;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@@ -265,6 +246,7 @@ namespace OpenWifi::Utils {
 | 
				
			|||||||
	return true;
 | 
						return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool ParseDate(const std::string &Time, int & Year, int & Month, int & Day) {
 | 
					bool ParseDate(const std::string &Time, int & Year, int & Month, int & Day) {
 | 
				
			||||||
	Poco::StringTokenizer	DateTokens(Time,"-",Poco::StringTokenizer::TOK_TRIM);
 | 
						Poco::StringTokenizer	DateTokens(Time,"-",Poco::StringTokenizer::TOK_TRIM);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -294,24 +276,15 @@ namespace OpenWifi::Utils {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[nodiscard]] std::string LogLevelToString(int Level) {
 | 
					[[nodiscard]] std::string LogLevelToString(int Level) {
 | 
				
			||||||
	switch(Level) {
 | 
						switch(Level) {
 | 
				
			||||||
		case Poco::Message::PRIO_DEBUG:
 | 
						case Poco::Message::PRIO_DEBUG: return "debug";
 | 
				
			||||||
			return "debug";
 | 
						case Poco::Message::PRIO_INFORMATION: return "information";
 | 
				
			||||||
		case Poco::Message::PRIO_INFORMATION:
 | 
						case Poco::Message::PRIO_FATAL: return "fatal";
 | 
				
			||||||
			return "information";
 | 
						case Poco::Message::PRIO_WARNING: return "warning";
 | 
				
			||||||
		case Poco::Message::PRIO_FATAL:
 | 
						case Poco::Message::PRIO_NOTICE: return "notice";
 | 
				
			||||||
			return "fatal";
 | 
						case Poco::Message::PRIO_CRITICAL: return "critical";
 | 
				
			||||||
		case Poco::Message::PRIO_WARNING:
 | 
						case Poco::Message::PRIO_ERROR: return "error";
 | 
				
			||||||
			return "warning";
 | 
						case Poco::Message::PRIO_TRACE: return "trace";
 | 
				
			||||||
		case Poco::Message::PRIO_NOTICE:
 | 
						default: return "none";
 | 
				
			||||||
			return "notice";
 | 
					 | 
				
			||||||
		case Poco::Message::PRIO_CRITICAL:
 | 
					 | 
				
			||||||
			return "critical";
 | 
					 | 
				
			||||||
		case Poco::Message::PRIO_ERROR:
 | 
					 | 
				
			||||||
			return "error";
 | 
					 | 
				
			||||||
		case Poco::Message::PRIO_TRACE:
 | 
					 | 
				
			||||||
			return "trace";
 | 
					 | 
				
			||||||
		default:
 | 
					 | 
				
			||||||
			return "none";
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -333,6 +306,7 @@ namespace OpenWifi::Utils {
 | 
				
			|||||||
	return b;
 | 
						return b;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[nodiscard]] bool SerialNumberMatch(const std::string &S1, const std::string &S2, int Bits) {
 | 
					[[nodiscard]] bool SerialNumberMatch(const std::string &S1, const std::string &S2, int Bits) {
 | 
				
			||||||
	auto S1_i = SerialNumberToInt(S1);
 | 
						auto S1_i = SerialNumberToInt(S1);
 | 
				
			||||||
	auto S2_i = SerialNumberToInt(S2);
 | 
						auto S2_i = SerialNumberToInt(S2);
 | 
				
			||||||
@@ -401,8 +375,8 @@ namespace OpenWifi::Utils {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
[[nodiscard]] bool ValidEMailAddress(const std::string &email) {
 | 
					[[nodiscard]] bool ValidEMailAddress(const std::string &email) {
 | 
				
			||||||
	// define a regular expression
 | 
						// define a regular expression
 | 
				
			||||||
		static const std::regex pattern(
 | 
						static const std::regex pattern
 | 
				
			||||||
			"[_a-z0-9-]+(\\.[_a-z0-9-]+)*(\\+[a-z0-9-]+)?@[a-z0-9-]+(\\.[a-z0-9-]+)*");
 | 
							("[_a-z0-9-]+(\\.[_a-z0-9-]+)*(\\+[a-z0-9-]+)?@[a-z0-9-]+(\\.[a-z0-9-]+)*");
 | 
				
			||||||
	// try to match the string with the regular expression
 | 
						// try to match the string with the regular expression
 | 
				
			||||||
	return std::regex_match(email, pattern);
 | 
						return std::regex_match(email, pattern);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -415,6 +389,7 @@ namespace OpenWifi::Utils {
 | 
				
			|||||||
		Poco::StreamCopier::copyStream(IF, OS);
 | 
							Poco::StreamCopier::copyStream(IF, OS);
 | 
				
			||||||
		Result = OS.str();
 | 
							Result = OS.str();
 | 
				
			||||||
	} catch (...) {
 | 
						} catch (...) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return Result;
 | 
						return Result;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -428,29 +403,28 @@ namespace OpenWifi::Utils {
 | 
				
			|||||||
[[nodiscard]] MediaTypeEncoding FindMediaType(const Poco::File &F) {
 | 
					[[nodiscard]] MediaTypeEncoding FindMediaType(const Poco::File &F) {
 | 
				
			||||||
	const auto E = Poco::Path(F.path()).getExtension();
 | 
						const auto E = Poco::Path(F.path()).getExtension();
 | 
				
			||||||
	if(E=="png")
 | 
						if(E=="png")
 | 
				
			||||||
			return MediaTypeEncoding{.Encoding = BINARY, .ContentType = "image/png"};
 | 
							return MediaTypeEncoding{   .Encoding = BINARY,
 | 
				
			||||||
 | 
													 .ContentType = "image/png" };
 | 
				
			||||||
	if(E=="gif")
 | 
						if(E=="gif")
 | 
				
			||||||
			return MediaTypeEncoding{.Encoding = BINARY, .ContentType = "image/gif"};
 | 
							return MediaTypeEncoding{   .Encoding = BINARY,
 | 
				
			||||||
 | 
													 .ContentType = "image/gif" };
 | 
				
			||||||
	if(E=="jpeg" || E=="jpg")
 | 
						if(E=="jpeg" || E=="jpg")
 | 
				
			||||||
			return MediaTypeEncoding{.Encoding = BINARY, .ContentType = "image/jpeg"};
 | 
							return MediaTypeEncoding{   .Encoding = BINARY,
 | 
				
			||||||
 | 
													 .ContentType = "image/jpeg" };
 | 
				
			||||||
	if(E=="svg" || E=="svgz")
 | 
						if(E=="svg" || E=="svgz")
 | 
				
			||||||
			return MediaTypeEncoding{.Encoding = PLAIN, .ContentType = "image/svg+xml"};
 | 
							return MediaTypeEncoding{   .Encoding = PLAIN,
 | 
				
			||||||
 | 
													 .ContentType = "image/svg+xml" };
 | 
				
			||||||
	if(E=="html")
 | 
						if(E=="html")
 | 
				
			||||||
			return MediaTypeEncoding{.Encoding = PLAIN, .ContentType = "text/html"};
 | 
							return MediaTypeEncoding{   .Encoding = PLAIN,
 | 
				
			||||||
 | 
													 .ContentType = "text/html" };
 | 
				
			||||||
	if(E=="css")
 | 
						if(E=="css")
 | 
				
			||||||
			return MediaTypeEncoding{.Encoding = PLAIN, .ContentType = "text/css"};
 | 
							return MediaTypeEncoding{   .Encoding = PLAIN,
 | 
				
			||||||
 | 
													 .ContentType = "text/css" };
 | 
				
			||||||
	if(E=="js")
 | 
						if(E=="js")
 | 
				
			||||||
			return MediaTypeEncoding{.Encoding = PLAIN, .ContentType = "application/javascript"};
 | 
							return MediaTypeEncoding{   .Encoding = PLAIN,
 | 
				
			||||||
		if (E == "pcap")
 | 
													 .ContentType = "application/javascript" };
 | 
				
			||||||
			return MediaTypeEncoding{.Encoding = BINARY, .ContentType = "application/vnd.tcpdump.pcap"};
 | 
						return MediaTypeEncoding{       .Encoding = BINARY,
 | 
				
			||||||
		if (E == "txt")
 | 
												 .ContentType = "application/octet-stream" };
 | 
				
			||||||
			return MediaTypeEncoding{.Encoding = PLAIN, .ContentType = "text/plain"};
 | 
					 | 
				
			||||||
		if (E == "tgz")
 | 
					 | 
				
			||||||
			return MediaTypeEncoding{.Encoding = BINARY, .ContentType = "application/tar+gzip"};
 | 
					 | 
				
			||||||
		if (E == "gz" || E=="gzip")
 | 
					 | 
				
			||||||
			return MediaTypeEncoding{.Encoding = BINARY, .ContentType = "application/gzip"};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		return MediaTypeEncoding{.Encoding = BINARY, .ContentType = "application/octet-stream"};
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
[[nodiscard]] std::string BinaryFileToHexString(const Poco::File &F) {
 | 
					[[nodiscard]] std::string BinaryFileToHexString(const Poco::File &F) {
 | 
				
			||||||
@@ -472,6 +446,7 @@ namespace OpenWifi::Utils {
 | 
				
			|||||||
			Result += (char) (hex[(C & 0x0f)]);
 | 
								Result += (char) (hex[(C & 0x0f)]);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} catch(...) {
 | 
						} catch(...) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return Result;
 | 
						return Result;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -484,8 +459,7 @@ namespace OpenWifi::Utils {
 | 
				
			|||||||
	Seconds -= Hours * (60*60);
 | 
						Seconds -= Hours * (60*60);
 | 
				
			||||||
	int Minutes = Seconds / 60;
 | 
						int Minutes = Seconds / 60;
 | 
				
			||||||
	Seconds -= Minutes * 60;
 | 
						Seconds -= Minutes * 60;
 | 
				
			||||||
		Result = std::to_string(Days) + " days, " + std::to_string(Hours) + ":" +
 | 
						Result = std::to_string(Days) +" days, " + std::to_string(Hours) + ":" + std::to_string(Minutes) + ":" + std::to_string(Seconds);
 | 
				
			||||||
				 std::to_string(Minutes) + ":" + std::to_string(Seconds);
 | 
					 | 
				
			||||||
	return Result;
 | 
						return Result;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -501,8 +475,7 @@ namespace OpenWifi::Utils {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// send request
 | 
							// send request
 | 
				
			||||||
			Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_GET, path,
 | 
							Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_GET, path, Poco::Net::HTTPMessage::HTTP_1_1);
 | 
				
			||||||
									   Poco::Net::HTTPMessage::HTTP_1_1);
 | 
					 | 
				
			||||||
		session.sendRequest(req);
 | 
							session.sendRequest(req);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Poco::Net::HTTPResponse res;
 | 
							Poco::Net::HTTPResponse res;
 | 
				
			||||||
@@ -514,6 +487,7 @@ namespace OpenWifi::Utils {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		return true;
 | 
							return true;
 | 
				
			||||||
	} catch (...) {
 | 
						} catch (...) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return false;
 | 
						return false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -523,17 +497,16 @@ namespace OpenWifi::Utils {
 | 
				
			|||||||
		Poco::Net::HTTPSClientSession session(uri.getHost(), uri.getPort());
 | 
							Poco::Net::HTTPSClientSession session(uri.getHost(), uri.getPort());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// send request
 | 
							// send request
 | 
				
			||||||
			Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_GET, uri.getPath(),
 | 
							Poco::Net::HTTPRequest req(Poco::Net::HTTPRequest::HTTP_GET, uri.getPath(), Poco::Net::HTTPMessage::HTTP_1_1);
 | 
				
			||||||
									   Poco::Net::HTTPMessage::HTTP_1_1);
 | 
					 | 
				
			||||||
		session.sendRequest(req);
 | 
							session.sendRequest(req);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Poco::Net::HTTPResponse res;
 | 
							Poco::Net::HTTPResponse res;
 | 
				
			||||||
		std::istream &is = session.receiveResponse(res);
 | 
							std::istream &is = session.receiveResponse(res);
 | 
				
			||||||
			std::fstream os(FileName,
 | 
							std::fstream os(FileName,std::ios_base::trunc | std::ios_base::binary | std::ios_base::out);
 | 
				
			||||||
							std::ios_base::trunc | std::ios_base::binary | std::ios_base::out);
 | 
					 | 
				
			||||||
		Poco::StreamCopier::copyStream(is,os);
 | 
							Poco::StreamCopier::copyStream(is,os);
 | 
				
			||||||
		return true;
 | 
							return true;
 | 
				
			||||||
	} catch (...) {
 | 
						} catch (...) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return false;
 | 
						return false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -546,8 +519,7 @@ namespace OpenWifi::Utils {
 | 
				
			|||||||
	Poco::StreamCopier::copyStream(b64in, ofs);
 | 
						Poco::StreamCopier::copyStream(b64in, ofs);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int factor = 20;
 | 
						int factor = 20;
 | 
				
			||||||
		unsigned long MaxSize = compress_sz ? (unsigned long)(compress_sz + 5000)
 | 
						unsigned long MaxSize = compress_sz ? (unsigned long) (compress_sz + 5000) : (unsigned long) (ofs.str().size() * factor);
 | 
				
			||||||
											: (unsigned long)(ofs.str().size() * factor);
 | 
					 | 
				
			||||||
	while(true) {
 | 
						while(true) {
 | 
				
			||||||
		std::vector<uint8_t> UncompressedBuffer(MaxSize);
 | 
							std::vector<uint8_t> UncompressedBuffer(MaxSize);
 | 
				
			||||||
		unsigned long FinalSize = MaxSize;
 | 
							unsigned long FinalSize = MaxSize;
 | 
				
			||||||
@@ -588,6 +560,7 @@ namespace OpenWifi::Utils {
 | 
				
			|||||||
			Poco::URI	u(uri);
 | 
								Poco::URI	u(uri);
 | 
				
			||||||
			return true;
 | 
								return true;
 | 
				
			||||||
		} catch (...) {
 | 
							} catch (...) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -599,4 +572,4 @@ namespace OpenWifi::Utils {
 | 
				
			|||||||
        return DT.timestamp().epochTime();
 | 
					        return DT.timestamp().epochTime();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace OpenWifi::Utils
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,34 +4,34 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <string>
 | 
				
			||||||
#include <fstream>
 | 
					#include <fstream>
 | 
				
			||||||
#include <iomanip>
 | 
					 | 
				
			||||||
#include <iostream>
 | 
					#include <iostream>
 | 
				
			||||||
 | 
					#include <iomanip>
 | 
				
			||||||
#include <random>
 | 
					#include <random>
 | 
				
			||||||
#include <regex>
 | 
					#include <regex>
 | 
				
			||||||
#include <shared_mutex>
 | 
					 | 
				
			||||||
#include <string>
 | 
					 | 
				
			||||||
#include <thread>
 | 
					#include <thread>
 | 
				
			||||||
 | 
					#include <shared_mutex>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "Poco/Thread.h"
 | 
				
			||||||
 | 
					#include "Poco/StringTokenizer.h"
 | 
				
			||||||
 | 
					#include "Poco/String.h"
 | 
				
			||||||
 | 
					#include "Poco/SHA2Engine.h"
 | 
				
			||||||
 | 
					#include "Poco/Message.h"
 | 
				
			||||||
 | 
					#include "Poco/StreamCopier.h"
 | 
				
			||||||
 | 
					#include "Poco/File.h"
 | 
				
			||||||
 | 
					#include "Poco/Net/NetworkInterface.h"
 | 
				
			||||||
 | 
					#include "Poco/URI.h"
 | 
				
			||||||
 | 
					#include "Poco/Net/HTTPRequest.h"
 | 
				
			||||||
 | 
					#include "Poco/Net/HTTPClientSession.h"
 | 
				
			||||||
 | 
					#include "Poco/Net/HTTPSClientSession.h"
 | 
				
			||||||
 | 
					#include "Poco/Net/HTTPResponse.h"
 | 
				
			||||||
#include "Poco/Base64Decoder.h"
 | 
					#include "Poco/Base64Decoder.h"
 | 
				
			||||||
#include "Poco/Base64Encoder.h"
 | 
					#include "Poco/Base64Encoder.h"
 | 
				
			||||||
#include "Poco/File.h"
 | 
					 | 
				
			||||||
#include "Poco/Message.h"
 | 
					 | 
				
			||||||
#include "Poco/Net/HTTPClientSession.h"
 | 
					 | 
				
			||||||
#include "Poco/Net/HTTPRequest.h"
 | 
					 | 
				
			||||||
#include "Poco/Net/HTTPResponse.h"
 | 
					 | 
				
			||||||
#include "Poco/Net/HTTPSClientSession.h"
 | 
					 | 
				
			||||||
#include "Poco/Net/NetworkInterface.h"
 | 
					 | 
				
			||||||
#include "Poco/SHA2Engine.h"
 | 
					 | 
				
			||||||
#include "Poco/StreamCopier.h"
 | 
					 | 
				
			||||||
#include "Poco/String.h"
 | 
					 | 
				
			||||||
#include "Poco/StringTokenizer.h"
 | 
					 | 
				
			||||||
#include "Poco/Thread.h"
 | 
					 | 
				
			||||||
#include "Poco/URI.h"
 | 
					 | 
				
			||||||
#include "Poco/zlib.h"
 | 
					#include "Poco/zlib.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "framework/OpenWifiTypes.h"
 | 
					 | 
				
			||||||
#include "framework/ow_constants.h"
 | 
					#include "framework/ow_constants.h"
 | 
				
			||||||
 | 
					#include "framework/OpenWifiTypes.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace OpenWifi::Utils {
 | 
					namespace OpenWifi::Utils {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -60,7 +60,11 @@ namespace OpenWifi::Utils {
 | 
				
			|||||||
	#endif
 | 
						#endif
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	enum MediaTypeEncodings { PLAIN, BINARY, BASE64 };
 | 
						enum MediaTypeEncodings {
 | 
				
			||||||
 | 
							PLAIN,
 | 
				
			||||||
 | 
							BINARY,
 | 
				
			||||||
 | 
							BASE64
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct MediaTypeEncoding {
 | 
						struct MediaTypeEncoding {
 | 
				
			||||||
		MediaTypeEncodings  Encoding=PLAIN;
 | 
							MediaTypeEncodings  Encoding=PLAIN;
 | 
				
			||||||
@@ -68,7 +72,6 @@ namespace OpenWifi::Utils {
 | 
				
			|||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	[[nodiscard]] bool ValidSerialNumber(const std::string &Serial);
 | 
						[[nodiscard]] bool ValidSerialNumber(const std::string &Serial);
 | 
				
			||||||
	[[nodiscard]] bool ValidSerialNumbers(const std::vector<std::string> &Serial);
 | 
					 | 
				
			||||||
	[[nodiscard]] bool ValidUUID(const std::string &UUID);
 | 
						[[nodiscard]] bool ValidUUID(const std::string &UUID);
 | 
				
			||||||
    [[nodiscard]] bool ValidHostname(const std::string &hostname);
 | 
					    [[nodiscard]] bool ValidHostname(const std::string &hostname);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -95,16 +98,14 @@ namespace OpenWifi::Utils {
 | 
				
			|||||||
	using byte = std::uint8_t;
 | 
						using byte = std::uint8_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	[[nodiscard]] std::string base64encode(const byte *input, uint32_t size);
 | 
						[[nodiscard]] std::string base64encode(const byte *input, uint32_t size);
 | 
				
			||||||
	[[nodiscard]] std::vector<byte> base64decode(const std::string &input);
 | 
						[[nodiscard]] std::vector<byte> base64decode(const std::string& input);;
 | 
				
			||||||
	;
 | 
					 | 
				
			||||||
	bool ParseTime(const std::string &Time, int & Hours, int & Minutes, int & Seconds);
 | 
						bool ParseTime(const std::string &Time, int & Hours, int & Minutes, int & Seconds);
 | 
				
			||||||
	bool ParseDate(const std::string &Time, int & Year, int & Month, int & Day);
 | 
						bool ParseDate(const std::string &Time, int & Year, int & Month, int & Day);
 | 
				
			||||||
	bool CompareTime( int H1, int H2, int M1, int M2, int S1, int S2);
 | 
						bool CompareTime( int H1, int H2, int M1, int M2, int S1, int S2);
 | 
				
			||||||
	[[nodiscard]] std::string LogLevelToString(int Level);
 | 
						[[nodiscard]] std::string LogLevelToString(int Level);
 | 
				
			||||||
	[[nodiscard]] uint64_t SerialNumberToInt(const std::string & S);
 | 
						[[nodiscard]] uint64_t SerialNumberToInt(const std::string & S);
 | 
				
			||||||
	[[nodiscard]] std::string IntToSerialNumber(uint64_t S);
 | 
						[[nodiscard]] std::string IntToSerialNumber(uint64_t S);
 | 
				
			||||||
	[[nodiscard]] bool SerialNumberMatch(const std::string &S1, const std::string &S2,
 | 
						[[nodiscard]] bool SerialNumberMatch(const std::string &S1, const std::string &S2, int Bits=2);
 | 
				
			||||||
										 int Bits = 2);
 | 
					 | 
				
			||||||
	[[nodiscard]] uint64_t SerialNumberToOUI(const std::string & S);
 | 
						[[nodiscard]] uint64_t SerialNumberToOUI(const std::string & S);
 | 
				
			||||||
	[[nodiscard]] uint64_t GetDefaultMacAsInt64();
 | 
						[[nodiscard]] uint64_t GetDefaultMacAsInt64();
 | 
				
			||||||
	[[nodiscard]] uint64_t InitializeSystemId();
 | 
						[[nodiscard]] uint64_t InitializeSystemId();
 | 
				
			||||||
@@ -123,9 +124,12 @@ namespace OpenWifi::Utils {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    [[nodiscard]] std::uint64_t ConvertDate(const std::string &d);
 | 
					    [[nodiscard]] std::uint64_t ConvertDate(const std::string &d);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	template <typename T> std::string int_to_hex(T i) {
 | 
						template< typename T >
 | 
				
			||||||
 | 
						std::string int_to_hex( T i )
 | 
				
			||||||
 | 
						{
 | 
				
			||||||
		std::stringstream stream;
 | 
							std::stringstream stream;
 | 
				
			||||||
		stream << std::setfill('0') << std::setw(12) << std::hex << i;
 | 
							stream << std::setfill ('0') << std::setw(12)
 | 
				
			||||||
 | 
								   << std::hex << i;
 | 
				
			||||||
		return stream.str();
 | 
							return stream.str();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -147,38 +151,4 @@ namespace OpenWifi::Utils {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	bool ExtractBase64CompressedData(const std::string &CompressedData,
 | 
						bool ExtractBase64CompressedData(const std::string &CompressedData,
 | 
				
			||||||
											std::string &UnCompressedData, uint64_t compress_sz );
 | 
																std::string &UnCompressedData, uint64_t compress_sz );
 | 
				
			||||||
 | 
					 | 
				
			||||||
	inline bool match(const char* first, const char* second)
 | 
					 | 
				
			||||||
	{
 | 
					 | 
				
			||||||
		// If we reach at the end of both strings, we are done
 | 
					 | 
				
			||||||
		if (*first == '\0' && *second == '\0')
 | 
					 | 
				
			||||||
			return true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// Make sure to eliminate consecutive '*'
 | 
					 | 
				
			||||||
		if (*first == '*') {
 | 
					 | 
				
			||||||
			while (*(first + 1) == '*')
 | 
					 | 
				
			||||||
				first++;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
		// Make sure that the characters after '*' are present
 | 
					 | 
				
			||||||
		// in second string. This function assumes that the
 | 
					 | 
				
			||||||
		// first string will not contain two consecutive '*'
 | 
					 | 
				
			||||||
		if (*first == '*' && *(first + 1) != '\0'
 | 
					 | 
				
			||||||
			&& *second == '\0')
 | 
					 | 
				
			||||||
			return false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// If the first string contains '?', or current
 | 
					 | 
				
			||||||
		// characters of both strings match
 | 
					 | 
				
			||||||
		if (*first == '?' || *first == *second)
 | 
					 | 
				
			||||||
			return match(first + 1, second + 1);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		// If there is *, then there are two possibilities
 | 
					 | 
				
			||||||
		// a) We consider current character of second string
 | 
					 | 
				
			||||||
		// b) We ignore current character of second string.
 | 
					 | 
				
			||||||
		if (*first == '*')
 | 
					 | 
				
			||||||
			return match(first + 1, second)
 | 
					 | 
				
			||||||
				   || match(first, second + 1);
 | 
					 | 
				
			||||||
		return false;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
} // namespace OpenWifi::Utils
 | 
					 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user