mirror of
https://github.com/Telecominfraproject/wlan-cloud-analytics.git
synced 2026-03-20 03:39:59 +00:00
Compare commits
51 Commits
release/v2
...
v3.2.0-RC2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
25d629ae10 | ||
|
|
1d85880156 | ||
|
|
5dd71c1fd7 | ||
|
|
9fc047d866 | ||
|
|
6249cb914b | ||
|
|
574ea606c2 | ||
|
|
a88014dab8 | ||
|
|
280ae24182 | ||
|
|
79e9a98725 | ||
|
|
5ddcf9a2bb | ||
|
|
971a6d54d8 | ||
|
|
70469e1feb | ||
|
|
85fc28974c | ||
|
|
1d96831446 | ||
|
|
a77476e394 | ||
|
|
7731a36847 | ||
|
|
e095c3e97d | ||
|
|
e43bd4f723 | ||
|
|
3c68b1a9d7 | ||
|
|
1232f3ac58 | ||
|
|
555ad0fc81 | ||
|
|
bd06caa928 | ||
|
|
5a7a38c2a4 | ||
|
|
9a40ef5a5c | ||
|
|
3bcfb6e3a3 | ||
|
|
81f07d9c83 | ||
|
|
d441d44643 | ||
|
|
a6fc1a6216 | ||
|
|
dc21f68368 | ||
|
|
b2056bce77 | ||
|
|
58a8c59914 | ||
|
|
8f593be261 | ||
|
|
29932f31da | ||
|
|
6d03e7e9f4 | ||
|
|
5ee9c9ed65 | ||
|
|
ca3c43d125 | ||
|
|
58949f50f4 | ||
|
|
70f8128504 | ||
|
|
935515bb89 | ||
|
|
5e630c8b99 | ||
|
|
55658f79c6 | ||
|
|
d728948ece | ||
|
|
a5ea86f0db | ||
|
|
b3bca3003a | ||
|
|
fe4256c290 | ||
|
|
dfb96fc998 | ||
|
|
3181a72740 | ||
|
|
d162327d3a | ||
|
|
bc261e8655 | ||
|
|
9e4185289a | ||
|
|
dc2a190dcc |
30
BUILDING.md
30
BUILDING.md
@@ -12,19 +12,19 @@ In order to build the OWANALYTICS, you will need to install its dependencies, wh
|
||||
|
||||
The build is done in 2 parts. The first part is to build a local copy of the framework tailored to your environment. This
|
||||
framework is called [Poco](https://github.com/pocoproject/poco). The version used in this project has a couple of fixes
|
||||
from the master copy needed for cmake. Please use the version of this [Poco fix](https://github.com/AriliaWireless/poco). Building
|
||||
from the master copy needed for cmake. Please use the version of this [Poco fix](https://github.com/Telecominfraproject/wlan-cloud-lib-poco). Building
|
||||
Poco may take several minutes depending on the platform you are building on.
|
||||
|
||||
## Ubuntu
|
||||
These instructions have proven to work on Ubuntu 20.4.
|
||||
These instructions have proven to work on Ubuntu 23.04.
|
||||
```bash
|
||||
sudo apt install git cmake g++ libssl-dev libmariadb-dev
|
||||
sudo apt install git cmake g++ libssl-dev libmariadb-dev libmariadbclient-dev-compat
|
||||
sudo apt install libpq-dev libaprutil1-dev apache2-dev libboost-all-dev
|
||||
sudo apt install librdkafka-dev default-libmysqlclient-dev
|
||||
sudo apt install nlohmann-json-dev
|
||||
sudo apt install librdkafka-dev
|
||||
sudo apt install zlib1g-dev nlohmann-json3-dev ca-certificates libcurl4-openssl-dev
|
||||
|
||||
cd ~
|
||||
git clone https://github.com/AriliaWireless/poco --branch poco-tip-v1
|
||||
git clone https://github.com/Telecominfraproject/wlan-cloud-lib-poco --branch poco-tip-v1 poco
|
||||
cd poco
|
||||
mkdir cmake-build
|
||||
cd cmake-build
|
||||
@@ -33,7 +33,7 @@ cmake --build . --config Release
|
||||
sudo cmake --build . --target install
|
||||
|
||||
cd ~
|
||||
git clone https://github.com/AriliaWireless/cppkafka --branch tip-v1
|
||||
git clone https://github.com/Telecominfraproject/wlan-cloud-lib-cppkafka --branch tip-v1 cppkafka
|
||||
cd cppkafka
|
||||
mkdir cmake-build
|
||||
cd cmake-build
|
||||
@@ -42,7 +42,7 @@ cmake --build . --config Release
|
||||
sudo cmake --build . --target install
|
||||
|
||||
cd ~
|
||||
git clone https://github.com/AriliaWireless/valijson --branch tip-v1
|
||||
git clone https://github.com/Telecominfraproject/wlan-cloud-lib-valijson --branch tip-v1 valijson
|
||||
cd valijson
|
||||
mkdir cmake-build
|
||||
cd cmake-build
|
||||
@@ -71,11 +71,11 @@ make -j 8
|
||||
The following instructions have proven to work on Fedora 33
|
||||
```bash
|
||||
sudo yum install cmake g++ openssl-devel mysql-devel mysql apr-util-devel boost boost-devel
|
||||
sudo yum install yaml-cpp-devel lua-devel
|
||||
sudo yum install yaml-cpp-devel lua-devel
|
||||
sudo dnf install postgresql.x86_64 librdkafka-devel
|
||||
sudo dnf install postgresql-devel json-devel
|
||||
|
||||
git clone https://github.com/AriliaWireless/poco --branch poco-tip-v1
|
||||
git clone https://github.com/Telecominfraproject/wlan-cloud-lib-poco --branch poco-tip-v1
|
||||
cd poco
|
||||
mkdir cmake-build
|
||||
cd cmake-build
|
||||
@@ -83,7 +83,7 @@ cmake ..
|
||||
cmake --build . --config Release
|
||||
sudo cmake --build . --target install
|
||||
|
||||
git clone https://github.com/AriliaWireless/cppkafka --branch tip-v1
|
||||
git clone https://github.com/Telecominfraproject/wlan-cloud-lib-cppkafka --branch tip-v1
|
||||
cd cppkafka
|
||||
mkdir cmake-build
|
||||
cd cmake-build
|
||||
@@ -92,7 +92,7 @@ cmake --build . --config Release
|
||||
sudo cmake --build . --target install
|
||||
|
||||
cd ~
|
||||
git clone https://github.com/AriliaWireless/valijson --branch tip-v1
|
||||
git clone https://github.com/Telecominfraproject/wlan-cloud-lib-valijson --branch tip-v1
|
||||
cd valijson
|
||||
mkdir cmake-build
|
||||
cd cmake-build
|
||||
@@ -125,7 +125,7 @@ brew install openssl \
|
||||
nlohmann-json \
|
||||
fmt
|
||||
|
||||
git clone https://github.com/AriliaWireless/poco --branch poco-tip-v1
|
||||
git clone https://github.com/Telecominfraproject/wlan-cloud-lib-poco --branch poco-tip-v1
|
||||
pushd poco
|
||||
mkdir cmake-build
|
||||
push cmake-build
|
||||
@@ -135,7 +135,7 @@ sudo cmake --build . --target install
|
||||
popd
|
||||
popd
|
||||
|
||||
git clone https://github.com/AriliaWireless/cppkafka --branch tip-v1
|
||||
git clone https://github.com/Telecominfraproject/wlan-cloud-lib-cppkafka --branch tip-v1
|
||||
pushd cppkafka
|
||||
mkdir cmake-build
|
||||
pushd cmake-build
|
||||
@@ -145,7 +145,7 @@ sudo cmake --build . --target install
|
||||
popd
|
||||
popd
|
||||
|
||||
git clone https://github.com/AriliaWireless/valijson --branch tip-v1
|
||||
git clone https://github.com/Telecominfraproject/wlan-cloud-lib-valijson --branch tip-v1
|
||||
cd valijson
|
||||
mkdir cmake-build
|
||||
cd cmake-build
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
cmake_minimum_required(VERSION 3.13)
|
||||
project(owanalytics VERSION 2.9.0)
|
||||
project(owanalytics VERSION 3.2.0)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_GENERATOR "Unix Makefiles")
|
||||
@@ -63,7 +63,7 @@ include_directories(/usr/local/include /usr/local/opt/openssl/include src inclu
|
||||
|
||||
configure_file(src/ow_version.h.in ${PROJECT_SOURCE_DIR}/src/ow_version.h @ONLY)
|
||||
|
||||
add_definitions(-DPOCO_LOG_DEBUG="1")
|
||||
add_definitions(-DPOCO_LOG_DEBUG="1" -DBOOST_NO_CXX98_FUNCTION_BASE=1)
|
||||
|
||||
add_executable(owanalytics
|
||||
build
|
||||
@@ -116,6 +116,7 @@ add_executable(owanalytics
|
||||
src/framework/MicroServiceExtra.h
|
||||
src/framework/ConfigurationValidator.cpp
|
||||
src/framework/ConfigurationValidator.h
|
||||
src/framework/default_device_types.h
|
||||
src/RESTObjects/RESTAPI_SecurityObjects.h src/RESTObjects/RESTAPI_SecurityObjects.cpp
|
||||
src/RESTObjects/RESTAPI_GWobjects.h src/RESTObjects/RESTAPI_GWobjects.cpp
|
||||
src/RESTObjects/RESTAPI_FMSObjects.h src/RESTObjects/RESTAPI_FMSObjects.cpp
|
||||
@@ -154,5 +155,7 @@ target_link_libraries(owanalytics PUBLIC
|
||||
${MySQL_LIBRARIES}
|
||||
${ZLIB_LIBRARIES}
|
||||
fmt::fmt
|
||||
CppKafka::cppkafka)
|
||||
resolv
|
||||
CppKafka::cppkafka
|
||||
)
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ fullnameOverride: ""
|
||||
images:
|
||||
owanalytics:
|
||||
repository: tip-tip-wlan-cloud-ucentral.jfrog.io/owanalytics
|
||||
tag: main
|
||||
tag: v3.2.0-RC2
|
||||
pullPolicy: Always
|
||||
# regcred:
|
||||
# registry: tip-tip-wlan-cloud-ucentral.jfrog.io
|
||||
|
||||
@@ -691,12 +691,6 @@ components:
|
||||
- $ref: '#/components/schemas/StringList'
|
||||
- $ref: '#/components/schemas/TagValuePairList'
|
||||
|
||||
SystemCommandResults:
|
||||
type: object
|
||||
oneOf:
|
||||
- $ref: '#/components/schemas/StringList'
|
||||
- $ref: '#/components/schemas/TagValuePairList'
|
||||
|
||||
NoteInfo:
|
||||
type: object
|
||||
properties:
|
||||
@@ -736,6 +730,33 @@ components:
|
||||
type: integer
|
||||
format: int64
|
||||
|
||||
SystemResources:
|
||||
type: object
|
||||
properties:
|
||||
numberOfFileDescriptors:
|
||||
type: integer
|
||||
format: int64
|
||||
currRealMem:
|
||||
type: integer
|
||||
format: int64
|
||||
peakRealMem:
|
||||
type: integer
|
||||
format: int64
|
||||
currVirtMem:
|
||||
type: integer
|
||||
format: int64
|
||||
peakVirtMem:
|
||||
type: integer
|
||||
format: int64
|
||||
|
||||
SystemCommandResults:
|
||||
type: object
|
||||
oneOf:
|
||||
- $ref: '#/components/schemas/SystemResources'
|
||||
- $ref: '#/components/schemas/SystemInfoResults'
|
||||
- $ref: '#/components/schemas/StringList'
|
||||
- $ref: '#/components/schemas/TagValuePairList'
|
||||
|
||||
Dashboard:
|
||||
type: object
|
||||
properties:
|
||||
@@ -1307,18 +1328,12 @@ paths:
|
||||
type: string
|
||||
enum:
|
||||
- info
|
||||
- extraConfiguration
|
||||
- resources
|
||||
required: true
|
||||
|
||||
responses:
|
||||
200:
|
||||
description: Successful command execution
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
oneOf:
|
||||
- $ref: '#/components/schemas/SystemInfoResults'
|
||||
400:
|
||||
$ref: '#/components/responses/BadRequest'
|
||||
$ref: '#/components/schemas/SystemCommandResults'
|
||||
403:
|
||||
$ref: '#/components/responses/Unauthorized'
|
||||
404:
|
||||
|
||||
@@ -112,7 +112,7 @@ namespace OpenWifi {
|
||||
DI_.connected = true;
|
||||
|
||||
AnalyticsObjects::DeviceTimePoint DTP;
|
||||
poco_information(Logger(), fmt::format("{}: stats message.", DI_.serialNumber));
|
||||
poco_trace(Logger(), fmt::format("{}: stats message.", DI_.serialNumber));
|
||||
|
||||
// find radios first to get associations.
|
||||
try {
|
||||
@@ -573,7 +573,7 @@ namespace OpenWifi {
|
||||
try {
|
||||
if (Connection->contains("ping")) {
|
||||
got_connection = true;
|
||||
poco_debug(Logger(), fmt::format("{}: ping message.", DI_.serialNumber));
|
||||
poco_trace(Logger(), fmt::format("{}: ping message.", DI_.serialNumber));
|
||||
DI_.connected = true;
|
||||
DI_.lastPing = Utils::Now();
|
||||
auto ping = (*Connection)["ping"];
|
||||
@@ -589,13 +589,13 @@ namespace OpenWifi {
|
||||
}
|
||||
}
|
||||
} else if (Connection->contains("disconnection")) {
|
||||
poco_debug(Logger(), fmt::format("{}: disconnection message.", DI_.serialNumber));
|
||||
poco_trace(Logger(), fmt::format("{}: disconnection message.", DI_.serialNumber));
|
||||
auto Disconnection = (*Connection)["disconnection"];
|
||||
GetJSON("timestamp", Disconnection, DI_.lastDisconnection, (uint64_t)0);
|
||||
got_base = got_health = got_connection = false;
|
||||
DI_.connected = false;
|
||||
} else if (Connection->contains("capabilities")) {
|
||||
poco_debug(Logger(), fmt::format("{}: connection message.", DI_.serialNumber));
|
||||
poco_trace(Logger(), fmt::format("{}: connection message.", DI_.serialNumber));
|
||||
got_connection = true;
|
||||
DI_.connected = true;
|
||||
DI_.lastConnection = Utils::Now();
|
||||
@@ -621,7 +621,7 @@ namespace OpenWifi {
|
||||
got_health = true;
|
||||
GetJSON("timestamp", *Health, DI_.lastHealth, (uint64_t)0);
|
||||
GetJSON("sanity", *Health, DI_.health, (uint64_t)0);
|
||||
poco_debug(Logger(), fmt::format("{}: health message.", DI_.serialNumber));
|
||||
poco_trace(Logger(), fmt::format("{}: health message.", DI_.serialNumber));
|
||||
} catch (...) {
|
||||
poco_information(Logger(),
|
||||
fmt::format("{}: error parsing health message.", DI_.serialNumber));
|
||||
|
||||
15
src/CMakeFiles/3.21.3/CMakeSystem.cmake
Normal file
15
src/CMakeFiles/3.21.3/CMakeSystem.cmake
Normal file
@@ -0,0 +1,15 @@
|
||||
set(CMAKE_HOST_SYSTEM "Darwin-23.0.0")
|
||||
set(CMAKE_HOST_SYSTEM_NAME "Darwin")
|
||||
set(CMAKE_HOST_SYSTEM_VERSION "23.0.0")
|
||||
set(CMAKE_HOST_SYSTEM_PROCESSOR "x86_64")
|
||||
|
||||
|
||||
|
||||
set(CMAKE_SYSTEM "Darwin-23.0.0")
|
||||
set(CMAKE_SYSTEM_NAME "Darwin")
|
||||
set(CMAKE_SYSTEM_VERSION "23.0.0")
|
||||
set(CMAKE_SYSTEM_PROCESSOR "x86_64")
|
||||
|
||||
set(CMAKE_CROSSCOMPILING "FALSE")
|
||||
|
||||
set(CMAKE_SYSTEM_LOADED 1)
|
||||
1
src/CMakeFiles/CMakeOutput.log
Normal file
1
src/CMakeFiles/CMakeOutput.log
Normal file
@@ -0,0 +1 @@
|
||||
The system is: Darwin - 23.0.0 - x86_64
|
||||
@@ -80,7 +80,7 @@ namespace OpenWifi {
|
||||
void DeviceStatusReceiver::DeviceStatusReceived(const std::string &Key,
|
||||
const std::string &Payload) {
|
||||
std::lock_guard G(Mutex_);
|
||||
poco_debug(Logger(), fmt::format("Device({}): Connection/Ping message.", Key));
|
||||
poco_trace(Logger(), fmt::format("Device({}): Connection/Ping message.", Key));
|
||||
Queue_.enqueueNotification(new DeviceStatusMessage(Key, Payload));
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
@@ -78,7 +78,7 @@ namespace OpenWifi {
|
||||
|
||||
void HealthReceiver::HealthReceived(const std::string &Key, const std::string &Payload) {
|
||||
std::lock_guard G(Mutex_);
|
||||
poco_debug(Logger(), fmt::format("Device({}): Health message.", Key));
|
||||
poco_trace(Logger(), fmt::format("Device({}): Health message.", Key));
|
||||
Queue_.enqueueNotification(new HealthMessage(Key, Payload));
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
@@ -13,6 +13,7 @@
|
||||
#ifdef TIP_GATEWAY_SERVICE
|
||||
#include "AP_WS_Server.h"
|
||||
#include "CapabilitiesCache.h"
|
||||
#include "RADIUSSessionTracker.h"
|
||||
#endif
|
||||
|
||||
#include "RESTAPI_GWobjects.h"
|
||||
@@ -29,6 +30,7 @@ namespace OpenWifi::GWObjects {
|
||||
field_to_json(Obj, "serialNumber", SerialNumber);
|
||||
#ifdef TIP_GATEWAY_SERVICE
|
||||
field_to_json(Obj, "deviceType", CapabilitiesCache::instance()->GetPlatform(Compatible));
|
||||
field_to_json(Obj, "hasRADIUSSessions", RADIUSSessionTracker()->HasSessions(SerialNumber));
|
||||
#endif
|
||||
field_to_json(Obj, "macAddress", MACAddress);
|
||||
field_to_json(Obj, "manufacturer", Manufacturer);
|
||||
@@ -54,6 +56,9 @@ namespace OpenWifi::GWObjects {
|
||||
field_to_json(Obj, "pendingConfiguration", pendingConfiguration);
|
||||
field_to_json(Obj, "pendingConfigurationCmd", pendingConfigurationCmd);
|
||||
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 {
|
||||
@@ -63,7 +68,7 @@ namespace OpenWifi::GWObjects {
|
||||
ConnectionState ConState;
|
||||
|
||||
if (AP_WS_Server()->GetState(SerialNumber, ConState)) {
|
||||
ConState.to_json(Obj);
|
||||
ConState.to_json(SerialNumber,Obj);
|
||||
} else {
|
||||
field_to_json(Obj, "ipAddress", "");
|
||||
field_to_json(Obj, "txBytes", (uint64_t)0);
|
||||
@@ -75,6 +80,13 @@ namespace OpenWifi::GWObjects {
|
||||
field_to_json(Obj, "associations_2G", (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, "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
|
||||
}
|
||||
@@ -84,20 +96,32 @@ namespace OpenWifi::GWObjects {
|
||||
field_from_json(Obj, "serialNumber", SerialNumber);
|
||||
field_from_json(Obj, "deviceType", DeviceType);
|
||||
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, "notes", Notes);
|
||||
field_from_json(Obj, "manufacturer", Manufacturer);
|
||||
field_from_json(Obj, "createdTimestamp", CreationTimestamp);
|
||||
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, "location", Location);
|
||||
field_from_json(Obj, "venue", Venue);
|
||||
field_from_json(Obj, "firmware", Firmware);
|
||||
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, "entity", entity);
|
||||
field_from_json(Obj, "modified", modified);
|
||||
field_from_json(Obj, "locale", locale);
|
||||
field_from_json(Obj, "restrictedDevice", restrictedDevice);
|
||||
field_from_json(Obj, "pendingConfiguration", pendingConfiguration);
|
||||
field_from_json(Obj, "pendingConfigurationCmd", pendingConfigurationCmd);
|
||||
field_from_json(Obj, "restrictionDetails", restrictionDetails);
|
||||
field_from_json(Obj, "pendingUUID", pendingUUID);
|
||||
field_from_json(Obj, "simulated", simulated);
|
||||
field_from_json(Obj, "lastRecordedContact", lastRecordedContact);
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
}
|
||||
@@ -147,6 +171,31 @@ namespace OpenWifi::GWObjects {
|
||||
field_to_json(Obj, "lastModified", LastModified);
|
||||
}
|
||||
|
||||
void DefaultFirmware::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj, "deviceType", deviceType);
|
||||
field_to_json(Obj, "description", Description);
|
||||
field_to_json(Obj, "uri", uri);
|
||||
field_to_json(Obj, "revision", revision);
|
||||
field_to_json(Obj, "imageCreationDate", imageCreationDate);
|
||||
field_to_json(Obj, "created", Created);
|
||||
field_to_json(Obj, "lastModified", LastModified);
|
||||
}
|
||||
|
||||
bool DefaultFirmware::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj, "deviceType", deviceType);
|
||||
field_from_json(Obj, "description", Description);
|
||||
field_from_json(Obj, "uri", uri);
|
||||
field_from_json(Obj, "revision", revision);
|
||||
field_from_json(Obj, "imageCreationDate", imageCreationDate);
|
||||
field_from_json(Obj, "created", Created);
|
||||
field_from_json(Obj, "lastModified", LastModified);
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CommandDetails::to_json(Poco::JSON::Object &Obj) const {
|
||||
EmbedDocument("details", Obj, Details);
|
||||
EmbedDocument("results", Obj, Results);
|
||||
@@ -165,6 +214,8 @@ namespace OpenWifi::GWObjects {
|
||||
field_to_json(Obj, "waitingForFile", WaitingForFile);
|
||||
field_to_json(Obj, "attachFile", AttachDate);
|
||||
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) {
|
||||
@@ -198,7 +249,7 @@ namespace OpenWifi::GWObjects {
|
||||
return false;
|
||||
}
|
||||
|
||||
void ConnectionState::to_json(Poco::JSON::Object &Obj) const {
|
||||
void ConnectionState::to_json([[maybe_unused]] const std::string &SerialNumber, Poco::JSON::Object &Obj) {
|
||||
field_to_json(Obj, "ipAddress", Address);
|
||||
field_to_json(Obj, "txBytes", TX);
|
||||
field_to_json(Obj, "rxBytes", RX);
|
||||
@@ -220,6 +271,22 @@ namespace OpenWifi::GWObjects {
|
||||
field_to_json(Obj, "connectionCompletionTime", connectionCompletionTime);
|
||||
field_to_json(Obj, "totalConnectionTime", Utils::Now() - started);
|
||||
field_to_json(Obj, "certificateExpiryDate", certificateExpiryDate);
|
||||
field_to_json(Obj, "connectReason", connectReason);
|
||||
|
||||
#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) {
|
||||
case NO_CERTIFICATE:
|
||||
@@ -234,6 +301,9 @@ namespace OpenWifi::GWObjects {
|
||||
case VERIFIED:
|
||||
field_to_json(Obj, "verifiedCertificate", "VERIFIED");
|
||||
break;
|
||||
case SIMULATED:
|
||||
field_to_json(Obj, "verifiedCertificate", "SIMULATED");
|
||||
break;
|
||||
default:
|
||||
field_to_json(Obj, "verifiedCertificate", "NO_CERTIFICATE");
|
||||
break;
|
||||
@@ -360,6 +430,10 @@ namespace OpenWifi::GWObjects {
|
||||
field_to_json(Obj, "acctConfig", acctConfig);
|
||||
field_to_json(Obj, "coaConfig", coaConfig);
|
||||
field_to_json(Obj, "useByDefault", useByDefault);
|
||||
field_to_json(Obj, "radsecKeepAlive", radsecKeepAlive);
|
||||
field_to_json(Obj, "poolProxyIp", poolProxyIp);
|
||||
field_to_json(Obj, "radsecPoolType", radsecPoolType);
|
||||
field_to_json(Obj, "enabled", enabled);
|
||||
}
|
||||
|
||||
bool RadiusProxyPool::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
@@ -370,6 +444,10 @@ namespace OpenWifi::GWObjects {
|
||||
field_from_json(Obj, "acctConfig", acctConfig);
|
||||
field_from_json(Obj, "coaConfig", coaConfig);
|
||||
field_from_json(Obj, "useByDefault", useByDefault);
|
||||
field_from_json(Obj, "radsecKeepAlive", radsecKeepAlive);
|
||||
field_from_json(Obj, "poolProxyIp", poolProxyIp);
|
||||
field_from_json(Obj, "radsecPoolType", radsecPoolType);
|
||||
field_from_json(Obj, "enabled", enabled);
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
}
|
||||
@@ -490,6 +568,29 @@ namespace OpenWifi::GWObjects {
|
||||
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 {
|
||||
field_to_json(Obj, "vendor", vendor);
|
||||
field_to_json(Obj, "algo", algo);
|
||||
@@ -544,4 +645,74 @@ namespace OpenWifi::GWObjects {
|
||||
(T.commands != commands) || (T.developer != developer) || (T.ssh != ssh) ||
|
||||
(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);
|
||||
field_to_json(Obj, "nasId", nasId);
|
||||
field_to_json(Obj, "calledStationId", calledStationId);
|
||||
}
|
||||
|
||||
void RADIUSSessionList::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj, "sessions", sessions);
|
||||
}
|
||||
|
||||
void RadiusCoADMParameters::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj, "accountingSessionId", accountingSessionId);
|
||||
field_to_json(Obj, "accountingMultiSessionId", accountingMultiSessionId);
|
||||
field_to_json(Obj, "callingStationId", callingStationId);
|
||||
field_to_json(Obj, "chargeableUserIdentity", chargeableUserIdentity);
|
||||
field_to_json(Obj, "userName", userName);
|
||||
}
|
||||
|
||||
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);
|
||||
field_from_json(Obj, "userName", userName);
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DeviceTransferRequest::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj, "serialNumber", serialNumber);
|
||||
field_from_json(Obj, "server", server);
|
||||
field_from_json(Obj, "port", port);
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool DeviceCertificateUpdateRequest::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj, "serialNumber", serialNumber);
|
||||
field_from_json(Obj, "encodedCertificate", encodedCertificate);
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace OpenWifi::GWObjects
|
||||
|
||||
@@ -11,9 +11,13 @@
|
||||
#include "Poco/JSON/Object.h"
|
||||
#include "RESTAPI_SecurityObjects.h"
|
||||
|
||||
#ifdef TIP_GATEWAY_SERVICE
|
||||
#include <RADIUS_helpers.h>
|
||||
#endif
|
||||
|
||||
namespace OpenWifi::GWObjects {
|
||||
|
||||
enum CertificateValidation { NO_CERTIFICATE, VALID_CERTIFICATE, MISMATCH_SERIAL, VERIFIED };
|
||||
enum CertificateValidation { NO_CERTIFICATE, VALID_CERTIFICATE, MISMATCH_SERIAL, VERIFIED, SIMULATED };
|
||||
|
||||
struct ConnectionState {
|
||||
uint64_t MessageCount = 0;
|
||||
@@ -38,8 +42,15 @@ namespace OpenWifi::GWObjects {
|
||||
uint64_t sessionId = 0;
|
||||
double connectionCompletionTime = 0.0;
|
||||
std::uint64_t certificateExpiryDate = 0;
|
||||
std::uint64_t hasRADIUSSessions = 0;
|
||||
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;
|
||||
std::string connectReason;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
void to_json(const std::string &SerialNumber, Poco::JSON::Object &Obj) ;
|
||||
};
|
||||
|
||||
struct DeviceRestrictionsKeyInfo {
|
||||
@@ -96,6 +107,9 @@ namespace OpenWifi::GWObjects {
|
||||
std::string pendingConfiguration;
|
||||
std::string pendingConfigurationCmd;
|
||||
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_with_status(Poco::JSON::Object &Obj) const;
|
||||
@@ -168,6 +182,26 @@ namespace OpenWifi::GWObjects {
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct DefaultFirmware {
|
||||
std::string deviceType;
|
||||
std::string Description;
|
||||
std::string uri;
|
||||
std::string revision;
|
||||
uint64_t imageCreationDate;
|
||||
uint64_t Created;
|
||||
uint64_t LastModified;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct DefaultFirmwareList {
|
||||
std::vector<DefaultFirmware> firmwares;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct CommandDetails {
|
||||
std::string UUID;
|
||||
std::string SerialNumber;
|
||||
@@ -188,7 +222,11 @@ namespace OpenWifi::GWObjects {
|
||||
uint64_t AttachSize = 0;
|
||||
std::string AttachType;
|
||||
double executionTime = 0.0;
|
||||
std::uint64_t lastTry = 0;
|
||||
bool deferred = false;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct BlackListedDevice {
|
||||
@@ -322,6 +360,10 @@ namespace OpenWifi::GWObjects {
|
||||
RadiusProxyServerConfig acctConfig;
|
||||
RadiusProxyServerConfig coaConfig;
|
||||
bool useByDefault = false;
|
||||
std::string radsecPoolType;
|
||||
std::string poolProxyIp;
|
||||
std::uint64_t radsecKeepAlive=25;
|
||||
bool enabled=true;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
@@ -334,4 +376,139 @@ namespace OpenWifi::GWObjects {
|
||||
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,
|
||||
nasId;
|
||||
std::uint64_t inputPackets = 0,
|
||||
outputPackets = 0,
|
||||
inputOctets = 0,
|
||||
outputOctets = 0,
|
||||
inputGigaWords = 0,
|
||||
outputGigaWords = 0;
|
||||
std::uint32_t sessionTime = 0;
|
||||
std::string calledStationId;
|
||||
|
||||
#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,
|
||||
userName;
|
||||
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
};
|
||||
|
||||
enum class RadiusPoolStrategy {
|
||||
round_robin, random, weighted, unknown
|
||||
};
|
||||
|
||||
enum class RadiusEndpointType {
|
||||
generic, radsec, globalreach, orion, unknown
|
||||
};
|
||||
|
||||
static inline RadiusEndpointType RadiusEndpointType(const std::string &T) {
|
||||
if(T=="generic") return RadiusEndpointType::generic;
|
||||
if(T=="radsec") return RadiusEndpointType::radsec;
|
||||
if(T=="globalreach") return RadiusEndpointType::globalreach;
|
||||
if(T=="orion") return RadiusEndpointType::orion;
|
||||
return RadiusEndpointType::unknown;
|
||||
}
|
||||
|
||||
static inline RadiusPoolStrategy RadiusPoolStrategy(const std::string &T) {
|
||||
if(T=="round_robin") return RadiusPoolStrategy::round_robin;
|
||||
if(T=="random") return RadiusPoolStrategy::random;
|
||||
if(T=="weighted") return RadiusPoolStrategy::weighted;
|
||||
return RadiusPoolStrategy::unknown;
|
||||
}
|
||||
|
||||
static inline std::string to_string(enum RadiusEndpointType T) {
|
||||
switch(T) {
|
||||
case RadiusEndpointType::generic: return "generic";
|
||||
case RadiusEndpointType::radsec: return "radsec";
|
||||
case RadiusEndpointType::globalreach: return "globalreach";
|
||||
case RadiusEndpointType::orion: return "orion";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
static inline std::string to_string(enum RadiusPoolStrategy T) {
|
||||
switch(T) {
|
||||
case RadiusPoolStrategy::round_robin: return "round_robin";
|
||||
case RadiusPoolStrategy::random: return "random";
|
||||
case RadiusPoolStrategy::weighted: return "weighted";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
}
|
||||
|
||||
struct DeviceTransferRequest {
|
||||
std::string serialNumber;
|
||||
std::string server;
|
||||
std::uint64_t port;
|
||||
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct DeviceCertificateUpdateRequest {
|
||||
std::string serialNumber;
|
||||
std::string encodedCertificate;
|
||||
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
} // namespace OpenWifi::GWObjects
|
||||
|
||||
@@ -78,21 +78,22 @@ namespace OpenWifi::OWLSObjects {
|
||||
return false;
|
||||
}
|
||||
|
||||
void SimulationStatus::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj, "id", id);
|
||||
field_to_json(Obj, "simulationId", simulationId);
|
||||
field_to_json(Obj, "state", state);
|
||||
field_to_json(Obj, "tx", tx);
|
||||
field_to_json(Obj, "rx", rx);
|
||||
field_to_json(Obj, "msgsTx", msgsTx);
|
||||
field_to_json(Obj, "msgsRx", msgsRx);
|
||||
field_to_json(Obj, "liveDevices", liveDevices);
|
||||
field_to_json(Obj, "timeToFullDevices", timeToFullDevices);
|
||||
field_to_json(Obj, "startTime", startTime);
|
||||
field_to_json(Obj, "endTime", endTime);
|
||||
field_to_json(Obj, "errorDevices", errorDevices);
|
||||
field_to_json(Obj, "owner", owner);
|
||||
}
|
||||
void SimulationStatus::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj, "id", id);
|
||||
field_to_json(Obj, "simulationId", simulationId);
|
||||
field_to_json(Obj, "state", state);
|
||||
field_to_json(Obj, "tx", tx);
|
||||
field_to_json(Obj, "rx", rx);
|
||||
field_to_json(Obj, "msgsTx", msgsTx);
|
||||
field_to_json(Obj, "msgsRx", msgsRx);
|
||||
field_to_json(Obj, "liveDevices", liveDevices);
|
||||
field_to_json(Obj, "timeToFullDevices", timeToFullDevices);
|
||||
field_to_json(Obj, "startTime", startTime);
|
||||
field_to_json(Obj, "endTime", endTime);
|
||||
field_to_json(Obj, "errorDevices", errorDevices);
|
||||
field_to_json(Obj, "owner", owner);
|
||||
field_to_json(Obj, "expectedDevices", expectedDevices);
|
||||
}
|
||||
|
||||
void Dashboard::to_json([[maybe_unused]] Poco::JSON::Object &Obj) const {}
|
||||
|
||||
|
||||
@@ -43,23 +43,24 @@ namespace OpenWifi::OWLSObjects {
|
||||
bool from_json(const Poco::JSON::Object::Ptr &Obj);
|
||||
};
|
||||
|
||||
struct SimulationStatus {
|
||||
std::string id;
|
||||
std::string simulationId;
|
||||
std::string state;
|
||||
uint64_t tx;
|
||||
uint64_t rx;
|
||||
uint64_t msgsTx;
|
||||
uint64_t msgsRx;
|
||||
uint64_t liveDevices;
|
||||
uint64_t timeToFullDevices;
|
||||
uint64_t startTime;
|
||||
uint64_t endTime;
|
||||
uint64_t errorDevices;
|
||||
std::string owner;
|
||||
struct SimulationStatus {
|
||||
std::string id;
|
||||
std::string simulationId;
|
||||
std::string state;
|
||||
uint64_t tx;
|
||||
uint64_t rx;
|
||||
uint64_t msgsTx;
|
||||
uint64_t msgsRx;
|
||||
uint64_t liveDevices;
|
||||
uint64_t timeToFullDevices;
|
||||
uint64_t startTime;
|
||||
uint64_t endTime;
|
||||
uint64_t errorDevices;
|
||||
std::string owner;
|
||||
uint64_t expectedDevices;
|
||||
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
};
|
||||
void to_json(Poco::JSON::Object &Obj) const;
|
||||
};
|
||||
|
||||
struct Dashboard {
|
||||
int O;
|
||||
|
||||
@@ -587,6 +587,9 @@ namespace OpenWifi::ProvObjects {
|
||||
field_to_json(Obj, "locale", locale);
|
||||
field_to_json(Obj, "realMacAddress", realMacAddress);
|
||||
field_to_json(Obj, "doNotAllowOverrides", doNotAllowOverrides);
|
||||
field_to_json(Obj, "imported", imported);
|
||||
field_to_json(Obj, "connected", connected);
|
||||
field_to_json(Obj, "platform", platform);
|
||||
}
|
||||
|
||||
bool InventoryTag::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
@@ -609,6 +612,9 @@ namespace OpenWifi::ProvObjects {
|
||||
field_from_json(Obj, "locale", locale);
|
||||
field_from_json(Obj, "realMacAddress", realMacAddress);
|
||||
field_from_json(Obj, "doNotAllowOverrides", doNotAllowOverrides);
|
||||
field_from_json(Obj, "imported", imported);
|
||||
field_from_json(Obj, "connected", connected);
|
||||
field_from_json(Obj, "platform", platform);
|
||||
return true;
|
||||
} catch (...) {
|
||||
}
|
||||
@@ -1194,4 +1200,243 @@ namespace OpenWifi::ProvObjects {
|
||||
return false;
|
||||
}
|
||||
|
||||
void GLBLRAccountInfo::to_json(Poco::JSON::Object &Obj) const {
|
||||
info.to_json(Obj);
|
||||
field_to_json(Obj, "privateKey", privateKey);
|
||||
field_to_json(Obj, "country", country);
|
||||
field_to_json(Obj, "province", province);
|
||||
field_to_json(Obj, "city", city);
|
||||
field_to_json(Obj, "organization", organization);
|
||||
field_to_json(Obj, "commonName", commonName);
|
||||
field_to_json(Obj, "CSR", CSR);
|
||||
field_to_json(Obj, "CSRPrivateKey", CSRPrivateKey);
|
||||
field_to_json(Obj, "CSRPublicKey", CSRPublicKey);
|
||||
field_to_json(Obj, "GlobalReachAcctId", GlobalReachAcctId);
|
||||
}
|
||||
|
||||
bool GLBLRAccountInfo::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
info.from_json(Obj);
|
||||
field_from_json(Obj, "privateKey", privateKey);
|
||||
field_from_json(Obj, "country", country);
|
||||
field_from_json(Obj, "province", province);
|
||||
field_from_json(Obj, "city", city);
|
||||
field_from_json(Obj, "organization", organization);
|
||||
field_from_json(Obj, "commonName", commonName);
|
||||
field_from_json(Obj, "CSR", CSR);
|
||||
field_from_json(Obj, "CSRPrivateKey", CSRPrivateKey);
|
||||
field_from_json(Obj, "CSRPublicKey", CSRPublicKey);
|
||||
field_from_json(Obj, "GlobalReachAcctId", GlobalReachAcctId);
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void GLBLRCertificateInfo::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj, "id", id);
|
||||
field_to_json(Obj, "name", name);
|
||||
field_to_json(Obj, "accountId", accountId);
|
||||
field_to_json(Obj, "csr", csr);
|
||||
field_to_json(Obj, "certificate", certificate);
|
||||
field_to_json(Obj, "certificateChain", certificateChain);
|
||||
field_to_json(Obj, "certificateId", certificateId);
|
||||
field_to_json(Obj, "expiresAt", expiresAt);
|
||||
field_to_json(Obj, "created", created);
|
||||
}
|
||||
|
||||
bool GLBLRCertificateInfo::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj, "id", id);
|
||||
field_from_json(Obj, "name", name);
|
||||
field_from_json(Obj, "accountId", accountId);
|
||||
field_from_json(Obj, "csr", csr);
|
||||
field_from_json(Obj, "certificate", certificate);
|
||||
field_from_json(Obj, "certificateChain", certificateChain);
|
||||
field_from_json(Obj, "certificateId", certificateId);
|
||||
field_from_json(Obj, "expiresAt", expiresAt);
|
||||
field_from_json(Obj, "created", created);
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void GooglOrionAccountInfo::to_json(Poco::JSON::Object &Obj) const {
|
||||
info.to_json(Obj);
|
||||
field_to_json(Obj, "privateKey", privateKey);
|
||||
field_to_json(Obj, "certificate", certificate);
|
||||
field_to_json(Obj, "cacerts", cacerts);
|
||||
}
|
||||
|
||||
bool GooglOrionAccountInfo::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
info.from_json(Obj);
|
||||
field_from_json(Obj, "privateKey", privateKey);
|
||||
field_from_json(Obj, "certificate", certificate);
|
||||
field_from_json(Obj, "cacerts", cacerts);
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void RADIUSServer::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj, "Hostname", Hostname);
|
||||
field_to_json(Obj, "IP", IP);
|
||||
field_to_json(Obj, "Port", Port);
|
||||
field_to_json(Obj, "Secret", Secret);
|
||||
}
|
||||
|
||||
bool RADIUSServer::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj, "Hostname", Hostname);
|
||||
field_from_json(Obj, "IP", IP);
|
||||
field_from_json(Obj, "Port", Port);
|
||||
field_from_json(Obj, "Secret", Secret);
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void RADIUSEndPointRadiusType::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj, "Authentication", Authentication);
|
||||
field_to_json(Obj, "Accounting", Accounting);
|
||||
field_to_json(Obj, "CoA", CoA);
|
||||
field_to_json(Obj, "AccountingInterval", AccountingInterval);
|
||||
}
|
||||
|
||||
bool RADIUSEndPointRadiusType::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj, "Authentication", Authentication);
|
||||
field_from_json(Obj, "Accounting", Accounting);
|
||||
field_from_json(Obj, "CoA", CoA);
|
||||
field_from_json(Obj, "AccountingInterval", AccountingInterval);
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void RADIUSEndPointRadsecType::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj, "Hostname", Hostname);
|
||||
field_to_json(Obj, "IP", IP);
|
||||
field_to_json(Obj, "Port", Port);
|
||||
field_to_json(Obj, "Secret", Secret);
|
||||
field_to_json(Obj, "OpenRoamingType", OpenRoamingType);
|
||||
field_to_json(Obj, "UseOpenRoamingAccount", UseOpenRoamingAccount);
|
||||
field_to_json(Obj, "Weight", Weight);
|
||||
field_to_json(Obj, "Certificate", Certificate);
|
||||
field_to_json(Obj, "PrivateKey", PrivateKey);
|
||||
field_to_json(Obj, "CaCerts", CaCerts);
|
||||
field_to_json(Obj, "AllowSelfSigned", AllowSelfSigned);
|
||||
}
|
||||
|
||||
bool RADIUSEndPointRadsecType::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj, "Hostname", Hostname);
|
||||
field_from_json(Obj, "IP", IP);
|
||||
field_from_json(Obj, "Port", Port);
|
||||
field_from_json(Obj, "Secret", Secret);
|
||||
field_from_json(Obj, "OpenRoamingType", OpenRoamingType);
|
||||
field_from_json(Obj, "UseOpenRoamingAccount", UseOpenRoamingAccount);
|
||||
field_from_json(Obj, "Weight", Weight);
|
||||
field_from_json(Obj, "Certificate", Certificate);
|
||||
field_from_json(Obj, "PrivateKey", PrivateKey);
|
||||
field_from_json(Obj, "CaCerts", CaCerts);
|
||||
field_from_json(Obj, "AllowSelfSigned", AllowSelfSigned);
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void RADIUSEndPoint::to_json(Poco::JSON::Object &Obj) const {
|
||||
info.to_json(Obj);
|
||||
field_to_json(Obj, "Type", Type);
|
||||
field_to_json(Obj, "RadsecServers", RadsecServers);
|
||||
field_to_json(Obj, "RadiusServers", RadiusServers);
|
||||
field_to_json(Obj, "PoolStrategy", PoolStrategy);
|
||||
field_to_json(Obj, "Index", Index);
|
||||
field_to_json(Obj, "UsedBy", UsedBy);
|
||||
field_to_json(Obj, "UseGWProxy", UseGWProxy);
|
||||
field_to_json(Obj, "NasIdentifier", NasIdentifier);
|
||||
field_to_json(Obj, "AccountingInterval", AccountingInterval);
|
||||
}
|
||||
|
||||
bool RADIUSEndPoint::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
info.from_json(Obj);
|
||||
field_from_json(Obj, "Type", Type);
|
||||
field_from_json(Obj, "RadsecServers", RadsecServers);
|
||||
field_from_json(Obj, "RadiusServers", RadiusServers);
|
||||
field_from_json(Obj, "PoolStrategy", PoolStrategy);
|
||||
field_from_json(Obj, "Index", Index);
|
||||
field_from_json(Obj, "UsedBy", UsedBy);
|
||||
field_from_json(Obj, "UseGWProxy", UseGWProxy);
|
||||
field_from_json(Obj, "NasIdentifier", NasIdentifier);
|
||||
field_from_json(Obj, "AccountingInterval", AccountingInterval);
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void RADIUSEndpointUpdateStatus::to_json(Poco::JSON::Object &Obj) const {
|
||||
field_to_json(Obj, "lastUpdate", lastUpdate);
|
||||
field_to_json(Obj, "lastConfigurationChange", lastConfigurationChange);
|
||||
}
|
||||
|
||||
bool RADIUSEndpointUpdateStatus::from_json(const Poco::JSON::Object::Ptr &Obj) {
|
||||
try {
|
||||
field_from_json(Obj, "lastUpdate", lastUpdate);
|
||||
field_from_json(Obj, "lastConfigurationChange", lastConfigurationChange);
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RADIUSEndpointUpdateStatus::Read() {
|
||||
Poco::File F(OpenWifi::MicroServiceDataDirectory()+"/RADIUSEndpointUpdateStatus.json");
|
||||
try {
|
||||
if (F.exists()) {
|
||||
Poco::JSON::Parser P;
|
||||
std::ifstream ifs(F.path(), std::ios_base::in | std::ios_base::binary);
|
||||
auto Obj = P.parse(ifs);
|
||||
return from_json(Obj.extract<Poco::JSON::Object::Ptr>());
|
||||
}
|
||||
} catch (...) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RADIUSEndpointUpdateStatus::Save() {
|
||||
Poco::File F(OpenWifi::MicroServiceDataDirectory()+"/RADIUSEndpointUpdateStatus.json");
|
||||
try {
|
||||
Poco::JSON::Object Obj;
|
||||
to_json(Obj);
|
||||
std::ofstream O(F.path(), std::ios_base::out | std::ios_base::trunc | std::ios_base::binary);
|
||||
Poco::JSON::Stringifier::stringify(Obj, O);
|
||||
return true;
|
||||
} catch (...) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool RADIUSEndpointUpdateStatus::ChangeConfiguration() {
|
||||
Read();
|
||||
lastConfigurationChange = Utils::Now();
|
||||
return Save();
|
||||
}
|
||||
|
||||
} // namespace OpenWifi::ProvObjects
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -61,7 +61,7 @@ namespace OpenWifi {
|
||||
|
||||
void StateReceiver::StateReceived(const std::string &Key, const std::string &Payload) {
|
||||
std::lock_guard G(Mutex_);
|
||||
poco_debug(Logger(), fmt::format("Device({}): State message.", Key));
|
||||
poco_trace(Logger(), fmt::format("Device({}): State message.", Key));
|
||||
Queue_.enqueueNotification(new StateMessage(Key, Payload));
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ namespace OpenWifi {
|
||||
Utils::SetThreadName("venue-coord");
|
||||
Running_ = true;
|
||||
while (Running_) {
|
||||
Poco::Thread::trySleep(20000);
|
||||
Poco::Thread::trySleep(60000);
|
||||
if (!Running_)
|
||||
break;
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace OpenWifi {
|
||||
Response.set("Connection", "keep-alive");
|
||||
Response.setVersion(Poco::Net::HTTPMessage::HTTP_1_1);
|
||||
std::ostream &Answer = Response.send();
|
||||
Answer << "process Alive and kicking!";
|
||||
Answer << ALBHealthCheckServer()->CallbackText();
|
||||
} catch (...) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +37,8 @@ namespace OpenWifi {
|
||||
inline static std::atomic_uint64_t req_id_ = 1;
|
||||
};
|
||||
|
||||
typedef std::string ALBHealthMessageCallback();
|
||||
|
||||
class ALBHealthCheckServer : public SubSystemServer {
|
||||
public:
|
||||
ALBHealthCheckServer();
|
||||
@@ -48,10 +50,22 @@ namespace OpenWifi {
|
||||
|
||||
int Start() override;
|
||||
void Stop() override;
|
||||
inline void RegisterExtendedHealthMessage(ALBHealthMessageCallback *F) {
|
||||
Callback_=F;
|
||||
};
|
||||
|
||||
inline std::string CallbackText() {
|
||||
if(Callback_== nullptr) {
|
||||
return "process Alive and kicking!";
|
||||
} else {
|
||||
return Callback_();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::unique_ptr<Poco::Net::HTTPServer> Server_;
|
||||
std::unique_ptr<Poco::Net::ServerSocket> Socket_;
|
||||
ALBHealthMessageCallback *Callback_= nullptr;
|
||||
int Port_ = 0;
|
||||
mutable std::atomic_bool Running_ = false;
|
||||
};
|
||||
|
||||
@@ -11,10 +11,12 @@
|
||||
|
||||
#include "Poco/File.h"
|
||||
#include "Poco/StreamCopier.h"
|
||||
#include "Poco/JSON/Object.h"
|
||||
#include "Poco/JSON/Parser.h"
|
||||
|
||||
#include "framework/MicroServiceFuncs.h"
|
||||
|
||||
#include "nlohmann/json.hpp"
|
||||
// #include "nlohmann/json.hpp"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
@@ -28,11 +30,11 @@ namespace OpenWifi {
|
||||
if (F.exists()) {
|
||||
std::ostringstream OS;
|
||||
std::ifstream IF(FileName);
|
||||
Poco::StreamCopier::copyStream(IF, OS);
|
||||
Registry_ = nlohmann::json::parse(OS.str());
|
||||
Poco::JSON::Parser P;
|
||||
Registry_ = P.parse(IF).extract<Poco::JSON::Object::Ptr>();
|
||||
}
|
||||
} catch (...) {
|
||||
Registry_ = nlohmann::json::parse("{}");
|
||||
Registry_ = Poco::makeShared<Poco::JSON::Object>();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -44,54 +46,47 @@ namespace OpenWifi {
|
||||
inline ~AppServiceRegistry() { Save(); }
|
||||
|
||||
inline void Save() {
|
||||
std::istringstream IS(to_string(Registry_));
|
||||
std::ofstream OF;
|
||||
OF.open(FileName, std::ios::binary | std::ios::trunc);
|
||||
Poco::StreamCopier::copyStream(IS, OF);
|
||||
Registry_->stringify(OF);
|
||||
}
|
||||
|
||||
inline void Set(const char *Key, uint64_t Value) {
|
||||
Registry_[Key] = Value;
|
||||
void Set(const char *key, const std::vector<std::string> &V) {
|
||||
Poco::JSON::Array Arr;
|
||||
for(const auto &s:V) {
|
||||
Arr.add(s);
|
||||
}
|
||||
Registry_->set(key,Arr);
|
||||
Save();
|
||||
}
|
||||
|
||||
template<class T> void Set(const char *key, const T &Value) {
|
||||
Registry_->set(key,Value);
|
||||
Save();
|
||||
}
|
||||
|
||||
inline void Set(const char *Key, const std::string &Value) {
|
||||
Registry_[Key] = Value;
|
||||
Save();
|
||||
}
|
||||
bool Get(const char *key, std::vector<std::string> &Value) {
|
||||
if(Registry_->has(key) && !Registry_->isNull(key) && Registry_->isArray(key)) {
|
||||
auto Arr = Registry_->get(key);
|
||||
for(const auto &v:Arr) {
|
||||
Value.emplace_back(v);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline void Set(const char *Key, bool Value) {
|
||||
Registry_[Key] = Value;
|
||||
Save();
|
||||
}
|
||||
|
||||
inline bool Get(const char *Key, bool &Value) {
|
||||
if (Registry_[Key].is_boolean()) {
|
||||
Value = Registry_[Key].get<bool>();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool Get(const char *Key, uint64_t &Value) {
|
||||
if (Registry_[Key].is_number_unsigned()) {
|
||||
Value = Registry_[Key].get<uint64_t>();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool Get(const char *Key, std::string &Value) {
|
||||
if (Registry_[Key].is_string()) {
|
||||
Value = Registry_[Key].get<std::string>();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
template<class T> bool Get(const char *key, T &Value) {
|
||||
if(Registry_->has(key) && !Registry_->isNull(key)) {
|
||||
Value = Registry_->getValue<T>(key);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private:
|
||||
std::string FileName;
|
||||
nlohmann::json Registry_;
|
||||
Poco::JSON::Object::Ptr Registry_;
|
||||
};
|
||||
|
||||
inline auto AppServiceRegistry() { return AppServiceRegistry::instance(); }
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -17,33 +17,42 @@
|
||||
namespace OpenWifi {
|
||||
class ConfigurationValidator : public SubSystemServer {
|
||||
public:
|
||||
|
||||
enum class ConfigurationType { AP = 0 , SWITCH = 1};
|
||||
|
||||
static auto instance() {
|
||||
static auto instance_ = new ConfigurationValidator;
|
||||
return instance_;
|
||||
}
|
||||
|
||||
bool Validate(const std::string &C, std::vector<std::string> &Errors, bool Strict);
|
||||
bool Validate(ConfigurationType Type, const std::string &C, std::string &Errors, bool Strict);
|
||||
int Start() override;
|
||||
void Stop() override;
|
||||
void reinitialize(Poco::Util::Application &self) override;
|
||||
|
||||
inline static ConfigurationType GetType(const std::string &type) {
|
||||
std::string Type = Poco::toUpper(type);
|
||||
if (Type == "AP")
|
||||
return ConfigurationType::AP;
|
||||
if (Type == "SWITCH")
|
||||
return ConfigurationType::SWITCH;
|
||||
return ConfigurationType::AP;
|
||||
}
|
||||
|
||||
private:
|
||||
bool Initialized_ = false;
|
||||
bool Working_ = false;
|
||||
void Init();
|
||||
std::unique_ptr<valijson::Schema> RootSchema_;
|
||||
std::unique_ptr<valijson::SchemaParser> SchemaParser_;
|
||||
std::unique_ptr<valijson::adapters::PocoJsonAdapter> PocoJsonAdapter_;
|
||||
Poco::JSON::Object::Ptr SchemaDocPtr_;
|
||||
bool SetSchema(const std::string &SchemaStr);
|
||||
std::array<valijson::Schema,2> RootSchema_;
|
||||
bool SetSchema(ConfigurationType Type, const std::string &SchemaStr);
|
||||
|
||||
ConfigurationValidator()
|
||||
: SubSystemServer("ConfigValidator", "CFG-VALIDATOR", "config.validator") {}
|
||||
};
|
||||
|
||||
inline auto ConfigurationValidator() { return ConfigurationValidator::instance(); }
|
||||
inline bool ValidateUCentralConfiguration(const std::string &C, std::vector<std::string> &Error,
|
||||
inline bool ValidateUCentralConfiguration(ConfigurationValidator::ConfigurationType Type, const std::string &C, std::string &Errors,
|
||||
bool strict) {
|
||||
return ConfigurationValidator::instance()->Validate(C, Error, strict);
|
||||
return ConfigurationValidator::instance()->Validate(Type, C, Errors, strict);
|
||||
}
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -9,29 +9,27 @@
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
EventBusManager::EventBusManager(Poco::Logger &L) : Logger_(L) {}
|
||||
|
||||
void EventBusManager::run() {
|
||||
Running_ = true;
|
||||
Utils::SetThreadName("fmwk:EventMgr");
|
||||
auto Msg = MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_JOIN);
|
||||
auto Msg = (MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_JOIN));
|
||||
KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS, MicroServicePrivateEndPoint(), Msg,
|
||||
false);
|
||||
while (Running_) {
|
||||
Poco::Thread::trySleep((unsigned long)MicroServiceDaemonBusTimer());
|
||||
if (!Running_)
|
||||
break;
|
||||
Msg = MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE);
|
||||
if(!Poco::Thread::trySleep((unsigned long)MicroServiceDaemonBusTimer())) {
|
||||
break;
|
||||
}
|
||||
Msg = (MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE));
|
||||
KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS, MicroServicePrivateEndPoint(),
|
||||
Msg, false);
|
||||
}
|
||||
Msg = MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_LEAVE);
|
||||
Msg = (MicroServiceMakeSystemEventMessage(KafkaTopics::ServiceEvents::EVENT_LEAVE));
|
||||
KafkaManager()->PostMessage(KafkaTopics::SERVICE_EVENTS, MicroServicePrivateEndPoint(), Msg,
|
||||
false);
|
||||
};
|
||||
|
||||
void EventBusManager::Start() {
|
||||
poco_information(Logger(), "Starting...");
|
||||
poco_information(Logger_, "Starting...");
|
||||
if (KafkaManager()->Enabled()) {
|
||||
Thread_.start(*this);
|
||||
}
|
||||
@@ -39,11 +37,11 @@ namespace OpenWifi {
|
||||
|
||||
void EventBusManager::Stop() {
|
||||
if (KafkaManager()->Enabled()) {
|
||||
poco_information(Logger(), "Stopping...");
|
||||
poco_information(Logger_, "Stopping...");
|
||||
Running_ = false;
|
||||
Thread_.wakeUp();
|
||||
Thread_.join();
|
||||
poco_information(Logger(), "Stopped...");
|
||||
poco_information(Logger_, "Stopped...");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,16 @@ namespace OpenWifi {
|
||||
|
||||
class EventBusManager : public Poco::Runnable {
|
||||
public:
|
||||
explicit EventBusManager(Poco::Logger &L);
|
||||
EventBusManager() :
|
||||
Logger_(Poco::Logger::create(
|
||||
"EventBusManager", Poco::Logger::root().getChannel(), Poco::Logger::root().getLevel())) {
|
||||
}
|
||||
|
||||
static auto instance() {
|
||||
static auto instance_ = new EventBusManager;
|
||||
return instance_;
|
||||
}
|
||||
|
||||
void run() final;
|
||||
void Start();
|
||||
void Stop();
|
||||
@@ -24,4 +33,6 @@ namespace OpenWifi {
|
||||
Poco::Logger &Logger_;
|
||||
};
|
||||
|
||||
inline auto EventBusManager() { return EventBusManager::instance(); }
|
||||
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
|
||||
#include "fmt/format.h"
|
||||
#include "framework/MicroServiceFuncs.h"
|
||||
#include "cppkafka/utils/consumer_dispatcher.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
@@ -78,8 +79,10 @@ namespace OpenWifi {
|
||||
Utils::SetThreadName("Kafka:Prod");
|
||||
cppkafka::Configuration Config(
|
||||
{{"client.id", MicroServiceConfigGetString("openwifi.kafka.client.id", "")},
|
||||
{"metadata.broker.list",
|
||||
MicroServiceConfigGetString("openwifi.kafka.brokerlist", "")}});
|
||||
{"metadata.broker.list",MicroServiceConfigGetString("openwifi.kafka.brokerlist", "")} // ,
|
||||
// {"send.buffer.bytes", KafkaManager()->KafkaManagerMaximumPayloadSize() }
|
||||
}
|
||||
);
|
||||
|
||||
AddKafkaSecurity(Config);
|
||||
|
||||
@@ -99,9 +102,21 @@ namespace OpenWifi {
|
||||
try {
|
||||
auto Msg = dynamic_cast<KafkaMessage *>(Note.get());
|
||||
if (Msg != nullptr) {
|
||||
Producer.produce(cppkafka::MessageBuilder(Msg->Topic())
|
||||
.key(Msg->Key())
|
||||
.payload(Msg->Payload()));
|
||||
auto NewMessage = cppkafka::MessageBuilder(Msg->Topic());
|
||||
NewMessage.key(Msg->Key());
|
||||
NewMessage.partition(0);
|
||||
NewMessage.payload(Msg->Payload());
|
||||
Producer.produce(NewMessage);
|
||||
if (Queue_.size() < 100) {
|
||||
// use flush when internal queue is lightly loaded, i.e. flush after each
|
||||
// message
|
||||
Producer.flush();
|
||||
}
|
||||
else {
|
||||
// use poll when internal queue is loaded to allow messages to be sent in
|
||||
// batches
|
||||
Producer.poll((std::chrono::milliseconds) 0);
|
||||
}
|
||||
}
|
||||
} catch (const cppkafka::HandleException &E) {
|
||||
poco_warning(Logger_,
|
||||
@@ -111,8 +126,13 @@ namespace OpenWifi {
|
||||
} catch (...) {
|
||||
poco_error(Logger_, "std::exception");
|
||||
}
|
||||
if (Queue_.size() == 0) {
|
||||
// message queue is empty, flush all previously sent messages
|
||||
Producer.flush();
|
||||
}
|
||||
Note = Queue_.waitDequeueNotification();
|
||||
}
|
||||
Producer.flush();
|
||||
poco_information(Logger_, "Stopped...");
|
||||
}
|
||||
|
||||
@@ -156,43 +176,49 @@ namespace OpenWifi {
|
||||
}
|
||||
});
|
||||
|
||||
bool AutoCommit = MicroServiceConfigGetBool("openwifi.kafka.auto.commit", false);
|
||||
auto BatchSize = MicroServiceConfigGetInt("openwifi.kafka.consumer.batchsize", 20);
|
||||
// bool AutoCommit = MicroServiceConfigGetBool("openwifi.kafka.auto.commit", false);
|
||||
// auto BatchSize = MicroServiceConfigGetInt("openwifi.kafka.consumer.batchsize", 100);
|
||||
|
||||
Types::StringVec Topics;
|
||||
KafkaManager()->Topics(Topics);
|
||||
std::for_each(Topics_.begin(),Topics_.end(),
|
||||
[&](const std::string & T) { Topics.emplace_back(T); });
|
||||
Consumer.subscribe(Topics);
|
||||
|
||||
Running_ = true;
|
||||
while (Running_) {
|
||||
try {
|
||||
std::vector<cppkafka::Message> MsgVec =
|
||||
Consumer.poll_batch(BatchSize, std::chrono::milliseconds(100));
|
||||
for (auto const &Msg : MsgVec) {
|
||||
if (!Msg)
|
||||
continue;
|
||||
if (Msg.get_error()) {
|
||||
if (!Msg.is_eof()) {
|
||||
poco_error(Logger_,
|
||||
fmt::format("Error: {}", Msg.get_error().to_string()));
|
||||
std::vector<cppkafka::Message> MsgVec;
|
||||
|
||||
Dispatcher_ = std::make_unique<cppkafka::ConsumerDispatcher>(Consumer);
|
||||
|
||||
Dispatcher_->run(
|
||||
// Callback executed whenever a new message is consumed
|
||||
[&](cppkafka::Message msg) {
|
||||
// Print the key (if any)
|
||||
std::lock_guard G(ConsumerMutex_);
|
||||
auto It = Notifiers_.find(msg.get_topic());
|
||||
if (It != Notifiers_.end()) {
|
||||
const auto &FL = It->second;
|
||||
for (const auto &[CallbackFunc, _] : FL) {
|
||||
try {
|
||||
CallbackFunc(msg.get_key(), msg.get_payload());
|
||||
} catch(const Poco::Exception &E) {
|
||||
|
||||
} catch(...) {
|
||||
|
||||
}
|
||||
if (!AutoCommit)
|
||||
Consumer.async_commit(Msg);
|
||||
continue;
|
||||
}
|
||||
KafkaManager()->Dispatch(Msg.get_topic(), Msg.get_key(), Msg.get_payload());
|
||||
if (!AutoCommit)
|
||||
Consumer.async_commit(Msg);
|
||||
}
|
||||
} catch (const cppkafka::HandleException &E) {
|
||||
poco_warning(Logger_,
|
||||
fmt::format("Caught a Kafka exception (consumer): {}", E.what()));
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.log(E);
|
||||
} catch (...) {
|
||||
poco_error(Logger_, "std::exception");
|
||||
Consumer.commit(msg);
|
||||
},
|
||||
// Whenever there's an error (other than the EOF soft error)
|
||||
[&Logger_](cppkafka::Error error) {
|
||||
poco_warning(Logger_,fmt::format("Error: {}", error.to_string()));
|
||||
},
|
||||
// Whenever EOF is reached on a partition, print this
|
||||
[&Logger_](cppkafka::ConsumerDispatcher::EndOfFile, const cppkafka::TopicPartition& topic_partition) {
|
||||
poco_debug(Logger_,fmt::format("Partition {} EOF", topic_partition.get_partition()));
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
Consumer.unsubscribe();
|
||||
poco_information(Logger_, "Stopped...");
|
||||
}
|
||||
@@ -212,7 +238,7 @@ namespace OpenWifi {
|
||||
}
|
||||
}
|
||||
|
||||
void KafkaProducer::Produce(const std::string &Topic, const std::string &Key,
|
||||
void KafkaProducer::Produce(const char *Topic, const std::string &Key,
|
||||
const std::string &Payload) {
|
||||
std::lock_guard G(Mutex_);
|
||||
Queue_.enqueueNotification(new KafkaMessage(Topic, Key, Payload));
|
||||
@@ -220,7 +246,6 @@ namespace OpenWifi {
|
||||
|
||||
void KafkaConsumer::Start() {
|
||||
if (!Running_) {
|
||||
Running_ = true;
|
||||
Worker_.start(*this);
|
||||
}
|
||||
}
|
||||
@@ -228,29 +253,16 @@ namespace OpenWifi {
|
||||
void KafkaConsumer::Stop() {
|
||||
if (Running_) {
|
||||
Running_ = false;
|
||||
Worker_.wakeUp();
|
||||
if(Dispatcher_) {
|
||||
Dispatcher_->stop();
|
||||
}
|
||||
Worker_.join();
|
||||
}
|
||||
}
|
||||
|
||||
void KafkaDispatcher::Start() {
|
||||
if (!Running_) {
|
||||
Running_ = true;
|
||||
Worker_.start(*this);
|
||||
}
|
||||
}
|
||||
|
||||
void KafkaDispatcher::Stop() {
|
||||
if (Running_) {
|
||||
Running_ = false;
|
||||
Queue_.wakeUpAll();
|
||||
Worker_.join();
|
||||
}
|
||||
}
|
||||
|
||||
auto KafkaDispatcher::RegisterTopicWatcher(const std::string &Topic,
|
||||
std::uint64_t KafkaConsumer::RegisterTopicWatcher(const std::string &Topic,
|
||||
Types::TopicNotifyFunction &F) {
|
||||
std::lock_guard G(Mutex_);
|
||||
std::lock_guard G(ConsumerMutex_);
|
||||
auto It = Notifiers_.find(Topic);
|
||||
if (It == Notifiers_.end()) {
|
||||
Types::TopicNotifyFunctionList L;
|
||||
@@ -259,11 +271,12 @@ namespace OpenWifi {
|
||||
} else {
|
||||
It->second.emplace(It->second.end(), std::make_pair(F, FunctionId_));
|
||||
}
|
||||
Topics_.insert(Topic);
|
||||
return FunctionId_++;
|
||||
}
|
||||
|
||||
void KafkaDispatcher::UnregisterTopicWatcher(const std::string &Topic, int Id) {
|
||||
std::lock_guard G(Mutex_);
|
||||
void KafkaConsumer::UnregisterTopicWatcher(const std::string &Topic, int Id) {
|
||||
std::lock_guard G(ConsumerMutex_);
|
||||
auto It = Notifiers_.find(Topic);
|
||||
if (It != Notifiers_.end()) {
|
||||
Types::TopicNotifyFunctionList &L = It->second;
|
||||
@@ -275,56 +288,18 @@ namespace OpenWifi {
|
||||
}
|
||||
}
|
||||
|
||||
void KafkaDispatcher::Dispatch(const std::string &Topic, const std::string &Key,
|
||||
const std::string &Payload) {
|
||||
std::lock_guard G(Mutex_);
|
||||
auto It = Notifiers_.find(Topic);
|
||||
if (It != Notifiers_.end()) {
|
||||
Queue_.enqueueNotification(new KafkaMessage(Topic, Key, Payload));
|
||||
}
|
||||
}
|
||||
|
||||
void KafkaDispatcher::run() {
|
||||
Poco::Logger &Logger_ =
|
||||
Poco::Logger::create("KAFKA-DISPATCHER", KafkaManager()->Logger().getChannel());
|
||||
poco_information(Logger_, "Starting...");
|
||||
Poco::AutoPtr<Poco::Notification> Note(Queue_.waitDequeueNotification());
|
||||
Utils::SetThreadName("kafka:dispatch");
|
||||
while (Note && Running_) {
|
||||
auto Msg = dynamic_cast<KafkaMessage *>(Note.get());
|
||||
if (Msg != nullptr) {
|
||||
auto It = Notifiers_.find(Msg->Topic());
|
||||
if (It != Notifiers_.end()) {
|
||||
const auto &FL = It->second;
|
||||
for (const auto &[CallbackFunc, _] : FL) {
|
||||
CallbackFunc(Msg->Key(), Msg->Payload());
|
||||
}
|
||||
}
|
||||
}
|
||||
Note = Queue_.waitDequeueNotification();
|
||||
}
|
||||
poco_information(Logger_, "Stopped...");
|
||||
}
|
||||
|
||||
void KafkaDispatcher::Topics(std::vector<std::string> &T) {
|
||||
T.clear();
|
||||
for (const auto &[TopicName, _] : Notifiers_)
|
||||
T.push_back(TopicName);
|
||||
}
|
||||
|
||||
int KafkaManager::Start() {
|
||||
if (!KafkaEnabled_)
|
||||
return 0;
|
||||
MaxPayloadSize_ = MicroServiceConfigGetInt("openwifi.kafka.max.payload", 250000);
|
||||
ConsumerThr_.Start();
|
||||
ProducerThr_.Start();
|
||||
Dispatcher_.Start();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void KafkaManager::Stop() {
|
||||
if (KafkaEnabled_) {
|
||||
poco_information(Logger(), "Stopping...");
|
||||
Dispatcher_.Stop();
|
||||
ProducerThr_.Stop();
|
||||
ConsumerThr_.Stop();
|
||||
poco_information(Logger(), "Stopped...");
|
||||
@@ -332,39 +307,27 @@ namespace OpenWifi {
|
||||
}
|
||||
}
|
||||
|
||||
void KafkaManager::PostMessage(const std::string &topic, const std::string &key,
|
||||
const std::string &PayLoad, bool WrapMessage) {
|
||||
void KafkaManager::PostMessage(const char *topic, const std::string &key,
|
||||
const std::string & PayLoad, bool WrapMessage) {
|
||||
if (KafkaEnabled_) {
|
||||
ProducerThr_.Produce(topic, key, WrapMessage ? WrapSystemId(PayLoad) : PayLoad);
|
||||
}
|
||||
}
|
||||
|
||||
void KafkaManager::Dispatch(const std::string &Topic, const std::string &Key,
|
||||
const std::string &Payload) {
|
||||
Dispatcher_.Dispatch(Topic, Key, Payload);
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string KafkaManager::WrapSystemId(const std::string &PayLoad) {
|
||||
return SystemInfoWrapper_ + PayLoad + "}";
|
||||
}
|
||||
|
||||
uint64_t KafkaManager::RegisterTopicWatcher(const std::string &Topic,
|
||||
Types::TopicNotifyFunction &F) {
|
||||
void KafkaManager::PostMessage(const char *topic, const std::string &key,
|
||||
const Poco::JSON::Object &Object, bool WrapMessage) {
|
||||
if (KafkaEnabled_) {
|
||||
return Dispatcher_.RegisterTopicWatcher(Topic, F);
|
||||
} else {
|
||||
return 0;
|
||||
std::ostringstream ObjectStr;
|
||||
Object.stringify(ObjectStr);
|
||||
ProducerThr_.Produce(topic, key, WrapMessage ? WrapSystemId(ObjectStr.str()) : ObjectStr.str());
|
||||
}
|
||||
}
|
||||
|
||||
void KafkaManager::UnregisterTopicWatcher(const std::string &Topic, uint64_t Id) {
|
||||
if (KafkaEnabled_) {
|
||||
Dispatcher_.UnregisterTopicWatcher(Topic, Id);
|
||||
}
|
||||
[[nodiscard]] std::string KafkaManager::WrapSystemId(const std::string & PayLoad) {
|
||||
return fmt::format( R"lit({{ "system" : {{ "id" : {}, "host" : "{}" }}, "payload" : {} }})lit",
|
||||
MicroServiceID(), MicroServicePrivateEndPoint(), PayLoad ) ;
|
||||
}
|
||||
|
||||
void KafkaManager::Topics(std::vector<std::string> &T) { Dispatcher_.Topics(T); }
|
||||
|
||||
void KafkaManager::PartitionAssignment(const cppkafka::TopicPartitionList &partitions) {
|
||||
poco_information(
|
||||
Logger(), fmt::format("Partition assigned: {}...", partitions.front().get_partition()));
|
||||
@@ -375,4 +338,4 @@ namespace OpenWifi {
|
||||
partitions.front().get_partition()));
|
||||
}
|
||||
|
||||
} // namespace OpenWifi
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
#include "Poco/Notification.h"
|
||||
#include "Poco/NotificationQueue.h"
|
||||
|
||||
#include "Poco/JSON/Object.h"
|
||||
#include "framework/KafkaTopics.h"
|
||||
#include "framework/OpenWifiTypes.h"
|
||||
#include "framework/SubSystemServer.h"
|
||||
@@ -18,15 +18,15 @@ namespace OpenWifi {
|
||||
|
||||
class KafkaMessage : public Poco::Notification {
|
||||
public:
|
||||
KafkaMessage(const std::string &Topic, const std::string &Key, const std::string &Payload)
|
||||
KafkaMessage(const char * Topic, const std::string &Key, const std::string &Payload)
|
||||
: Topic_(Topic), Key_(Key), Payload_(Payload) {}
|
||||
|
||||
inline const std::string &Topic() { return Topic_; }
|
||||
inline const char * Topic() { return Topic_; }
|
||||
inline const std::string &Key() { return Key_; }
|
||||
inline const std::string &Payload() { return Payload_; }
|
||||
|
||||
private:
|
||||
std::string Topic_;
|
||||
const char *Topic_;
|
||||
std::string Key_;
|
||||
std::string Payload_;
|
||||
};
|
||||
@@ -36,10 +36,10 @@ namespace OpenWifi {
|
||||
void run() override;
|
||||
void Start();
|
||||
void Stop();
|
||||
void Produce(const std::string &Topic, const std::string &Key, const std::string &Payload);
|
||||
void Produce(const char *Topic, const std::string &Key, const std::string & Payload);
|
||||
|
||||
private:
|
||||
std::recursive_mutex Mutex_;
|
||||
std::mutex Mutex_;
|
||||
Poco::Thread Worker_;
|
||||
mutable std::atomic_bool Running_ = false;
|
||||
Poco::NotificationQueue Queue_;
|
||||
@@ -47,33 +47,22 @@ namespace OpenWifi {
|
||||
|
||||
class KafkaConsumer : public Poco::Runnable {
|
||||
public:
|
||||
void run() override;
|
||||
void Start();
|
||||
void Stop();
|
||||
|
||||
private:
|
||||
std::recursive_mutex Mutex_;
|
||||
Poco::Thread Worker_;
|
||||
std::mutex ConsumerMutex_;
|
||||
Types::NotifyTable Notifiers_;
|
||||
Poco::Thread Worker_;
|
||||
mutable std::atomic_bool Running_ = false;
|
||||
};
|
||||
uint64_t FunctionId_ = 1;
|
||||
std::unique_ptr<cppkafka::ConsumerDispatcher> Dispatcher_;
|
||||
std::set<std::string> Topics_;
|
||||
|
||||
class KafkaDispatcher : public Poco::Runnable {
|
||||
public:
|
||||
void Start();
|
||||
void Stop();
|
||||
auto RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction &F);
|
||||
void run() override;
|
||||
friend class KafkaManager;
|
||||
std::uint64_t RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction &F);
|
||||
void UnregisterTopicWatcher(const std::string &Topic, int Id);
|
||||
void Dispatch(const std::string &Topic, const std::string &Key, const std::string &Payload);
|
||||
void run() override;
|
||||
void Topics(std::vector<std::string> &T);
|
||||
|
||||
private:
|
||||
std::recursive_mutex Mutex_;
|
||||
Types::NotifyTable Notifiers_;
|
||||
Poco::Thread Worker_;
|
||||
mutable std::atomic_bool Running_ = false;
|
||||
uint64_t FunctionId_ = 1;
|
||||
Poco::NotificationQueue Queue_;
|
||||
};
|
||||
|
||||
class KafkaManager : public SubSystemServer {
|
||||
@@ -91,21 +80,28 @@ namespace OpenWifi {
|
||||
int Start() override;
|
||||
void Stop() override;
|
||||
|
||||
void PostMessage(const std::string &topic, const std::string &key,
|
||||
void PostMessage(const char *topic, const std::string &key,
|
||||
const std::string &PayLoad, bool WrapMessage = true);
|
||||
void Dispatch(const std::string &Topic, const std::string &Key, const std::string &Payload);
|
||||
[[nodiscard]] std::string WrapSystemId(const std::string &PayLoad);
|
||||
void PostMessage(const char *topic, const std::string &key,
|
||||
const Poco::JSON::Object &Object, bool WrapMessage = true);
|
||||
|
||||
[[nodiscard]] std::string WrapSystemId(const std::string & PayLoad);
|
||||
[[nodiscard]] inline bool Enabled() const { return KafkaEnabled_; }
|
||||
uint64_t RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction &F);
|
||||
void UnregisterTopicWatcher(const std::string &Topic, uint64_t Id);
|
||||
void Topics(std::vector<std::string> &T);
|
||||
inline std::uint64_t RegisterTopicWatcher(const std::string &Topic, Types::TopicNotifyFunction &F) {
|
||||
return ConsumerThr_.RegisterTopicWatcher(Topic,F);
|
||||
}
|
||||
inline void UnregisterTopicWatcher(const std::string &Topic, uint64_t Id) {
|
||||
return ConsumerThr_.UnregisterTopicWatcher(Topic,Id);
|
||||
}
|
||||
|
||||
std::uint64_t KafkaManagerMaximumPayloadSize() const { return MaxPayloadSize_; }
|
||||
|
||||
private:
|
||||
bool KafkaEnabled_ = false;
|
||||
std::string SystemInfoWrapper_;
|
||||
KafkaProducer ProducerThr_;
|
||||
KafkaConsumer ConsumerThr_;
|
||||
KafkaDispatcher Dispatcher_;
|
||||
std::uint64_t MaxPayloadSize_ = 250000;
|
||||
|
||||
void PartitionAssignment(const cppkafka::TopicPartitionList &partitions);
|
||||
void PartitionRevocation(const cppkafka::TopicPartitionList &partitions);
|
||||
|
||||
@@ -10,32 +10,33 @@
|
||||
|
||||
#include <string>
|
||||
namespace OpenWifi::KafkaTopics {
|
||||
static const std::string HEALTHCHECK{"healthcheck"};
|
||||
static const std::string STATE{"state"};
|
||||
static const std::string CONNECTION{"connection"};
|
||||
static const std::string WIFISCAN{"wifiscan"};
|
||||
static const std::string ALERTS{"alerts"};
|
||||
static const std::string COMMAND{"command"};
|
||||
static const std::string SERVICE_EVENTS{"service_events"};
|
||||
static const std::string DEVICE_EVENT_QUEUE{"device_event_queue"};
|
||||
static const std::string DEVICE_TELEMETRY{"device_telemetry"};
|
||||
static const std::string PROVISIONING_CHANGE{"provisioning_change"};
|
||||
inline const char * HEALTHCHECK = "healthcheck";
|
||||
inline const char * STATE = "state";
|
||||
inline const char * CONNECTION = "connection";
|
||||
inline const char * WIFISCAN = "wifiscan";
|
||||
inline const char * ALERTS = "alerts";
|
||||
inline const char * COMMAND = "command";
|
||||
inline const char * SERVICE_EVENTS = "service_events";
|
||||
inline const char * DEVICE_EVENT_QUEUE = "device_event_queue";
|
||||
inline const char * DEVICE_TELEMETRY = "device_telemetry";
|
||||
inline const char * PROVISIONING_CHANGE = "provisioning_change";
|
||||
inline const char * RRM = "rrm";
|
||||
|
||||
namespace ServiceEvents {
|
||||
static const std::string EVENT_JOIN{"join"};
|
||||
static const std::string EVENT_LEAVE{"leave"};
|
||||
static const std::string EVENT_KEEP_ALIVE{"keep-alive"};
|
||||
static const std::string EVENT_REMOVE_TOKEN{"remove-token"};
|
||||
inline const char * EVENT_JOIN = "join";
|
||||
inline const char * EVENT_LEAVE = "leave";
|
||||
inline const char * EVENT_KEEP_ALIVE = "keep-alive";
|
||||
inline const char * EVENT_REMOVE_TOKEN = "remove-token";
|
||||
|
||||
namespace Fields {
|
||||
static const std::string EVENT{"event"};
|
||||
static const std::string ID{"id"};
|
||||
static const std::string TYPE{"type"};
|
||||
static const std::string PUBLIC{"publicEndPoint"};
|
||||
static const std::string PRIVATE{"privateEndPoint"};
|
||||
static const std::string KEY{"key"};
|
||||
static const std::string VRSN{"version"};
|
||||
static const std::string TOKEN{"token"};
|
||||
inline const char * EVENT = "event";
|
||||
inline const char * ID = "id";
|
||||
inline const char * TYPE = "type";
|
||||
inline const char * PUBLIC = "publicEndPoint";
|
||||
inline const char * PRIVATE = "privateEndPoint";
|
||||
inline const char * KEY = "key";
|
||||
inline const char * VRSN = "version";
|
||||
inline const char * TOKEN = "token";
|
||||
} // namespace Fields
|
||||
} // namespace ServiceEvents
|
||||
} // namespace OpenWifi::KafkaTopics
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
//
|
||||
//
|
||||
// Created by stephane bourque on 2022-10-26.
|
||||
//
|
||||
|
||||
@@ -29,13 +30,29 @@
|
||||
#include "framework/WebSocketLogger.h"
|
||||
#include "framework/utils.h"
|
||||
|
||||
#ifdef USE_MEDUSA_CLIENT
|
||||
#include <medusa/MedusaClient.h>
|
||||
#endif
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
void MicroService::Exit(int Reason) { std::exit(Reason); }
|
||||
static std::string MakeServiceListString(const Types::MicroServiceMetaMap &Services) {
|
||||
std::string SvcList;
|
||||
for (const auto &Svc : Services) {
|
||||
if (SvcList.empty())
|
||||
SvcList = Svc.second.Type;
|
||||
else
|
||||
SvcList += ", " + Svc.second.Type;
|
||||
}
|
||||
return SvcList;
|
||||
}
|
||||
|
||||
void MicroService::BusMessageReceived([[maybe_unused]] const std::string &Key,
|
||||
const std::string &Payload) {
|
||||
std::lock_guard G(InfraMutex_);
|
||||
|
||||
Poco::Logger &BusLogger = EventBusManager()->Logger();
|
||||
|
||||
try {
|
||||
Poco::JSON::Parser P;
|
||||
auto Object = P.parse(Payload).extract<Poco::JSON::Object::Ptr>();
|
||||
@@ -55,13 +72,10 @@ namespace OpenWifi {
|
||||
Object->has(KafkaTopics::ServiceEvents::Fields::KEY)) {
|
||||
auto PrivateEndPoint =
|
||||
Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE).toString();
|
||||
if (Event == KafkaTopics::ServiceEvents::EVENT_KEEP_ALIVE &&
|
||||
Services_.find(PrivateEndPoint) != Services_.end()) {
|
||||
Services_[PrivateEndPoint].LastUpdate = Utils::Now();
|
||||
} else if (Event == KafkaTopics::ServiceEvents::EVENT_LEAVE) {
|
||||
if (Event == KafkaTopics::ServiceEvents::EVENT_LEAVE) {
|
||||
Services_.erase(PrivateEndPoint);
|
||||
poco_debug(
|
||||
logger(),
|
||||
poco_information(
|
||||
BusLogger,
|
||||
fmt::format(
|
||||
"Service {} ID={} leaving system.",
|
||||
Object->get(KafkaTopics::ServiceEvents::Fields::PRIVATE)
|
||||
@@ -69,14 +83,7 @@ namespace OpenWifi {
|
||||
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{
|
||||
auto ServiceInfo = Types::MicroServiceMeta{
|
||||
.Id = ID,
|
||||
.Type = Poco::toLower(
|
||||
Object->get(KafkaTopics::ServiceEvents::Fields::TYPE)
|
||||
@@ -94,20 +101,46 @@ namespace OpenWifi {
|
||||
.toString(),
|
||||
.LastUpdate = Utils::Now()};
|
||||
|
||||
std::string SvcList;
|
||||
for (const auto &Svc : Services_) {
|
||||
if (SvcList.empty())
|
||||
SvcList = Svc.second.Type;
|
||||
else
|
||||
SvcList += ", " + Svc.second.Type;
|
||||
auto s1 = MakeServiceListString(Services_);
|
||||
auto PreviousSize = Services_.size();
|
||||
Services_[PrivateEndPoint] = ServiceInfo;
|
||||
auto CurrentSize = Services_.size();
|
||||
if(Event == KafkaTopics::ServiceEvents::EVENT_JOIN) {
|
||||
if(!s1.empty()) {
|
||||
poco_information(
|
||||
BusLogger,
|
||||
fmt::format(
|
||||
"Service {} ID={} is joining the system.",
|
||||
Object
|
||||
->get(
|
||||
KafkaTopics::ServiceEvents::Fields::PRIVATE)
|
||||
.toString(),
|
||||
ID));
|
||||
}
|
||||
std::string SvcList;
|
||||
for (const auto &Svc : Services_) {
|
||||
if (SvcList.empty())
|
||||
SvcList = Svc.second.Type;
|
||||
else
|
||||
SvcList += ", " + Svc.second.Type;
|
||||
}
|
||||
poco_information(
|
||||
BusLogger,
|
||||
fmt::format("Current list of microservices: {}", SvcList));
|
||||
} else if(CurrentSize!=PreviousSize) {
|
||||
poco_information(
|
||||
BusLogger,
|
||||
fmt::format(
|
||||
"Service {} ID={} is being added back in.",
|
||||
Object
|
||||
->get(KafkaTopics::ServiceEvents::Fields::PRIVATE)
|
||||
.toString(),
|
||||
ID));
|
||||
}
|
||||
poco_information(
|
||||
logger(),
|
||||
fmt::format("Current list of microservices: {}", SvcList));
|
||||
}
|
||||
} else {
|
||||
poco_error(
|
||||
logger(),
|
||||
poco_information(
|
||||
BusLogger,
|
||||
fmt::format("KAFKA-MSG: invalid event '{}', missing a field.",
|
||||
Event));
|
||||
}
|
||||
@@ -118,30 +151,39 @@ namespace OpenWifi {
|
||||
Object->get(KafkaTopics::ServiceEvents::Fields::TOKEN).toString());
|
||||
#endif
|
||||
} else {
|
||||
poco_error(
|
||||
logger(),
|
||||
poco_information(
|
||||
BusLogger,
|
||||
fmt::format("KAFKA-MSG: invalid event '{}', missing token", Event));
|
||||
}
|
||||
} else {
|
||||
poco_error(logger(),
|
||||
poco_information(BusLogger,
|
||||
fmt::format("Unknown Event: {} Source: {}", Event, ID));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
poco_error(logger(), "Bad bus message.");
|
||||
std::ostringstream os;
|
||||
Object->stringify(std::cout);
|
||||
poco_error(BusLogger, fmt::format("Bad bus message: {}", os.str()));
|
||||
}
|
||||
|
||||
auto i = Services_.begin();
|
||||
auto ServiceHint = Services_.begin();
|
||||
auto now = Utils::Now();
|
||||
for (; i != Services_.end();) {
|
||||
if ((now - i->second.LastUpdate) > 60) {
|
||||
i = Services_.erase(i);
|
||||
auto si1 = Services_.size();
|
||||
auto ss1 = MakeServiceListString(Services_);
|
||||
while(ServiceHint!=Services_.end()) {
|
||||
if ((now - ServiceHint->second.LastUpdate) > 120) {
|
||||
poco_information(BusLogger, fmt::format("ZombieService: Removing service {}, ", ServiceHint->second.PublicEndPoint));
|
||||
ServiceHint = Services_.erase(ServiceHint);
|
||||
} else
|
||||
++i;
|
||||
++ServiceHint;
|
||||
}
|
||||
if(Services_.size() != si1) {
|
||||
auto ss2 = MakeServiceListString(Services_);
|
||||
poco_information(BusLogger, fmt::format("Current list of microservices: {} -> {}", ss1, ss2));
|
||||
}
|
||||
|
||||
} catch (const Poco::Exception &E) {
|
||||
logger().log(E);
|
||||
BusLogger.log(E);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -165,25 +207,29 @@ namespace OpenWifi {
|
||||
Res.push_back(ServiceRec);
|
||||
}
|
||||
return Res;
|
||||
|
||||
}
|
||||
|
||||
void MicroService::LoadConfigurationFile() {
|
||||
std::string Location = Poco::Environment::get(DAEMON_CONFIG_ENV_VAR, ".");
|
||||
ConfigFileName_ =
|
||||
ConfigFileName_.empty() ? Location + "/" + DAEMON_PROPERTIES_FILENAME : ConfigFileName_;
|
||||
Poco::Path ConfigFile(ConfigFileName_);
|
||||
if(ConfigContent_.empty()) {
|
||||
std::string Location = Poco::Environment::get(DAEMON_CONFIG_ENV_VAR, ".");
|
||||
ConfigFileName_ =
|
||||
ConfigFileName_.empty() ? Location + "/" + DAEMON_PROPERTIES_FILENAME : ConfigFileName_;
|
||||
Poco::Path ConfigFile(ConfigFileName_);
|
||||
|
||||
if (!ConfigFile.isFile()) {
|
||||
std::cerr << DAEMON_APP_NAME << ": Configuration " << ConfigFile.toString()
|
||||
<< " does not seem to exist. Please set " + DAEMON_CONFIG_ENV_VAR +
|
||||
" env variable the path of the " + DAEMON_PROPERTIES_FILENAME +
|
||||
" file."
|
||||
<< std::endl;
|
||||
std::exit(Poco::Util::Application::EXIT_CONFIG);
|
||||
}
|
||||
|
||||
// loadConfiguration(ConfigFile.toString());
|
||||
PropConfigurationFile_ = new Poco::Util::PropertyFileConfiguration(ConfigFile.toString());
|
||||
if (!ConfigFile.isFile()) {
|
||||
std::cerr << DAEMON_APP_NAME << ": Configuration " << ConfigFile.toString()
|
||||
<< " does not seem to exist. Please set " + DAEMON_CONFIG_ENV_VAR +
|
||||
" env variable the path of the " + DAEMON_PROPERTIES_FILENAME +
|
||||
" file."
|
||||
<< std::endl;
|
||||
std::exit(Poco::Util::Application::EXIT_CONFIG);
|
||||
}
|
||||
PropConfigurationFile_ = new Poco::Util::PropertyFileConfiguration(ConfigFile.toString());
|
||||
} else {
|
||||
std::istringstream is(ConfigContent_);
|
||||
PropConfigurationFile_ = new Poco::Util::PropertyFileConfiguration(is);
|
||||
}
|
||||
configPtr()->addWriteable(PropConfigurationFile_, PRIO_DEFAULT);
|
||||
}
|
||||
|
||||
@@ -386,49 +432,69 @@ namespace OpenWifi {
|
||||
|
||||
void DaemonPostInitialization(Poco::Util::Application &self);
|
||||
|
||||
void MicroService::initialize(Poco::Util::Application &self) {
|
||||
// add the default services
|
||||
LoadConfigurationFile();
|
||||
InitializeLoggingSystem();
|
||||
void MicroService::StartEverything(Poco::Util::Application &self) {
|
||||
LoadConfigurationFile();
|
||||
InitializeLoggingSystem();
|
||||
|
||||
SubSystems_.push_back(KafkaManager());
|
||||
SubSystems_.push_back(ALBHealthCheckServer());
|
||||
SubSystems_.push_back(RESTAPI_ExtServer());
|
||||
SubSystems_.push_back(RESTAPI_IntServer());
|
||||
static bool InitializedBaseService=false;
|
||||
if(!InitializedBaseService) {
|
||||
InitializedBaseService = true;
|
||||
SubSystems_.push_back(KafkaManager());
|
||||
SubSystems_.push_back(ALBHealthCheckServer());
|
||||
SubSystems_.push_back(RESTAPI_ExtServer());
|
||||
SubSystems_.push_back(RESTAPI_IntServer());
|
||||
#ifndef TIP_SECURITY_SERVICE
|
||||
SubSystems_.push_back(AuthClient());
|
||||
SubSystems_.push_back(AuthClient());
|
||||
#endif
|
||||
Poco::Net::initializeSSL();
|
||||
Poco::Net::HTTPStreamFactory::registerFactory();
|
||||
Poco::Net::HTTPSStreamFactory::registerFactory();
|
||||
Poco::Net::FTPStreamFactory::registerFactory();
|
||||
Poco::Net::FTPSStreamFactory::registerFactory();
|
||||
|
||||
Poco::File DataDir(ConfigPath("openwifi.system.data"));
|
||||
DataDir_ = DataDir.path();
|
||||
if (!DataDir.exists()) {
|
||||
try {
|
||||
DataDir.createDirectory();
|
||||
} catch (const Poco::Exception &E) {
|
||||
logger().log(E);
|
||||
}
|
||||
}
|
||||
WWWAssetsDir_ = ConfigPath("openwifi.restapi.wwwassets", "");
|
||||
if (WWWAssetsDir_.empty())
|
||||
WWWAssetsDir_ = DataDir_;
|
||||
Poco::Net::initializeSSL();
|
||||
Poco::Net::HTTPStreamFactory::registerFactory();
|
||||
Poco::Net::HTTPSStreamFactory::registerFactory();
|
||||
Poco::Net::FTPStreamFactory::registerFactory();
|
||||
Poco::Net::FTPSStreamFactory::registerFactory();
|
||||
}
|
||||
|
||||
LoadMyConfig();
|
||||
Poco::File DataDir(ConfigPath("openwifi.system.data"));
|
||||
DataDir_ = DataDir.path();
|
||||
if (!DataDir.exists()) {
|
||||
try {
|
||||
DataDir.createDirectory();
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.log(E);
|
||||
}
|
||||
}
|
||||
WWWAssetsDir_ = ConfigPath("openwifi.restapi.wwwassets", "");
|
||||
if (WWWAssetsDir_.empty())
|
||||
WWWAssetsDir_ = DataDir_;
|
||||
|
||||
AllowExternalMicroServices_ = ConfigGetBool("allowexternalmicroservices", true);
|
||||
LoadMyConfig();
|
||||
|
||||
InitializeSubSystemServers();
|
||||
ServerApplication::initialize(self);
|
||||
DaemonPostInitialization(self);
|
||||
AllowExternalMicroServices_ = ConfigGetBool("allowexternalmicroservices", true);
|
||||
|
||||
Types::TopicNotifyFunction F = [this](const std::string &Key, const std::string &Payload) {
|
||||
this->BusMessageReceived(Key, Payload);
|
||||
};
|
||||
KafkaManager()->RegisterTopicWatcher(KafkaTopics::SERVICE_EVENTS, F);
|
||||
InitializeSubSystemServers();
|
||||
ServerApplication::initialize(self);
|
||||
DaemonPostInitialization(self);
|
||||
|
||||
Types::TopicNotifyFunction F = [this](const std::string &Key, const std::string &Payload) {
|
||||
this->BusMessageReceived(Key, Payload);
|
||||
};
|
||||
KafkaManager()->RegisterTopicWatcher(KafkaTopics::SERVICE_EVENTS, F);
|
||||
}
|
||||
|
||||
void MicroService::StopEverything([[maybe_unused]] Poco::Util::Application &self) {
|
||||
LoadConfigurationFile();
|
||||
InitializeLoggingSystem();
|
||||
|
||||
Types::TopicNotifyFunction F = [this](const std::string &Key, const std::string &Payload) {
|
||||
this->BusMessageReceived(Key, Payload);
|
||||
};
|
||||
KafkaManager()->RegisterTopicWatcher(KafkaTopics::SERVICE_EVENTS, F);
|
||||
}
|
||||
|
||||
void MicroService::initialize([[maybe_unused]] Poco::Util::Application &self) {
|
||||
#ifndef USE_MEDUSA_CLIENT
|
||||
StartEverything(self);
|
||||
#endif
|
||||
}
|
||||
|
||||
void MicroService::uninitialize() {
|
||||
@@ -528,14 +594,12 @@ namespace OpenWifi {
|
||||
for (auto i : SubSystems_) {
|
||||
i->Start();
|
||||
}
|
||||
EventBusManager_ = std::make_unique<EventBusManager>(Poco::Logger::create(
|
||||
"EventBusManager", Poco::Logger::root().getChannel(), Poco::Logger::root().getLevel()));
|
||||
EventBusManager_->Start();
|
||||
EventBusManager()->Start();
|
||||
}
|
||||
|
||||
void MicroService::StopSubSystemServers() {
|
||||
AddActivity("Stopping");
|
||||
EventBusManager_->Stop();
|
||||
EventBusManager()->Stop();
|
||||
for (auto i = SubSystems_.rbegin(); i != SubSystems_.rend(); ++i) {
|
||||
(*i)->Stop();
|
||||
}
|
||||
@@ -695,7 +759,7 @@ namespace OpenWifi {
|
||||
auto APIKEY = Request.get("X-API-KEY");
|
||||
return APIKEY == MyHash_;
|
||||
} catch (const Poco::Exception &E) {
|
||||
logger().log(E);
|
||||
Logger_.log(E);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -716,6 +780,8 @@ namespace OpenWifi {
|
||||
MicroServiceErrorHandler ErrorHandler(*this);
|
||||
Poco::ErrorHandler::set(&ErrorHandler);
|
||||
|
||||
Args_ = args;
|
||||
|
||||
if (!HelpRequested_) {
|
||||
SavePID();
|
||||
|
||||
@@ -731,11 +797,18 @@ namespace OpenWifi {
|
||||
poco_information(logger, "Starting as a daemon.");
|
||||
}
|
||||
|
||||
#ifdef USE_MEDUSA_CLIENT
|
||||
MedusaClient::instance()->SetSubSystems(SubSystems_);
|
||||
MedusaClient::instance()->Start();
|
||||
waitForTerminationRequest();
|
||||
MedusaClient::instance()->Stop();
|
||||
#else
|
||||
poco_information(logger, fmt::format("System ID set to {}", ID_));
|
||||
StartSubSystemServers();
|
||||
waitForTerminationRequest();
|
||||
StopSubSystemServers();
|
||||
logger.notice(fmt::format("Stopped {}...", DAEMON_APP_NAME));
|
||||
#endif
|
||||
}
|
||||
|
||||
return Application::EXIT_OK;
|
||||
|
||||
@@ -55,9 +55,6 @@ namespace OpenWifi {
|
||||
#include "nlohmann/json.hpp"
|
||||
#include "ow_version.h"
|
||||
|
||||
#define _OWDEBUG_ std::cout << __FILE__ << ":" << __LINE__ << std::endl;
|
||||
// #define _OWDEBUG_ Logger().debug(Poco::format("%s: %lu",__FILE__,__LINE__));
|
||||
|
||||
namespace OpenWifi {
|
||||
|
||||
class MicroService : public Poco::Util::ServerApplication {
|
||||
@@ -70,7 +67,6 @@ namespace OpenWifi {
|
||||
SubSystems_(std::move(Subsystems)), Logger_(Poco::Logger::get("FRAMEWORK")) {
|
||||
instance_ = this;
|
||||
RandomEngine_.seed(std::chrono::steady_clock::now().time_since_epoch().count());
|
||||
// Logger_ = Poco::Logger::root().get("BASE-SVC");
|
||||
}
|
||||
|
||||
inline static const char *ExtraConfigurationFilename = "/configuration_override.json";
|
||||
@@ -92,7 +88,7 @@ namespace OpenWifi {
|
||||
inline uint64_t DaemonBusTimer() const { return DAEMON_BUS_TIMER; };
|
||||
[[nodiscard]] const std::string &AppName() { return DAEMON_APP_NAME; }
|
||||
static inline uint64_t GetPID() { return Poco::Process::id(); };
|
||||
[[nodiscard]] inline const std::string GetPublicAPIEndPoint() {
|
||||
[[nodiscard]] inline std::string GetPublicAPIEndPoint() const {
|
||||
return MyPublicEndPoint_ + "/api/v1";
|
||||
};
|
||||
[[nodiscard]] inline const std::string &GetUIURI() const { return UIURI_; };
|
||||
@@ -107,7 +103,8 @@ namespace OpenWifi {
|
||||
}
|
||||
static MicroService &instance() { return *instance_; }
|
||||
|
||||
inline void Exit(int Reason);
|
||||
inline void Exit(int Reason) { std::exit(Reason); }
|
||||
|
||||
void BusMessageReceived(const std::string &Key, const std::string &Payload);
|
||||
Types::MicroServiceMetaVec GetServices(const std::string &Type);
|
||||
Types::MicroServiceMetaVec GetServices();
|
||||
@@ -115,7 +112,9 @@ namespace OpenWifi {
|
||||
void Reload();
|
||||
void LoadMyConfig();
|
||||
void initialize(Poco::Util::Application &self) override;
|
||||
void uninitialize() override;
|
||||
void StartEverything(Poco::Util::Application &self);
|
||||
void StopEverything(Poco::Util::Application &self);
|
||||
void uninitialize() override;
|
||||
void reinitialize(Poco::Util::Application &self) override;
|
||||
void defineOptions(Poco::Util::OptionSet &options) override;
|
||||
void handleHelp(const std::string &name, const std::string &value);
|
||||
@@ -132,7 +131,7 @@ namespace OpenWifi {
|
||||
void Reload(const std::string &Sub);
|
||||
Types::StringVec GetSubSystems() const;
|
||||
Types::StringPairVec GetLogLevels();
|
||||
const Types::StringVec &GetLogLevelNames();
|
||||
static const Types::StringVec &GetLogLevelNames();
|
||||
uint64_t ConfigGetInt(const std::string &Key, uint64_t Default);
|
||||
uint64_t ConfigGetInt(const std::string &Key);
|
||||
uint64_t ConfigGetBool(const std::string &Key, bool Default);
|
||||
@@ -166,12 +165,25 @@ namespace OpenWifi {
|
||||
const std::string &FormatterPattern,
|
||||
const std::string &root_env_var);
|
||||
inline bool AllowExternalMicroServices() const { return AllowExternalMicroServices_; }
|
||||
const ArgVec &Args() const { return Args_; }
|
||||
|
||||
inline void SetConfigContent(const std::string &Content) { ConfigContent_ = Content; }
|
||||
|
||||
inline std::optional<OpenWifi::Types::MicroServiceMeta> GetPrivateEndPointServiceKey( const std::string & ServicePrivateEndPoint ) {
|
||||
std::lock_guard G(InfraMutex_);
|
||||
auto K = Services_.find(ServicePrivateEndPoint);
|
||||
if(K==end(Services_)) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return K->second;
|
||||
}
|
||||
|
||||
private:
|
||||
static MicroService *instance_;
|
||||
bool HelpRequested_ = false;
|
||||
std::string LogDir_;
|
||||
std::string ConfigFileName_;
|
||||
std::string ConfigContent_;
|
||||
uint64_t ID_ = 1;
|
||||
Poco::SharedPtr<Poco::Crypto::RSAKey> AppKey_;
|
||||
bool DebugMode_ = false;
|
||||
@@ -201,7 +213,7 @@ namespace OpenWifi {
|
||||
Poco::JWT::Signer Signer_;
|
||||
Poco::Logger &Logger_;
|
||||
Poco::ThreadPool TimerPool_{"timer:pool", 2, 32};
|
||||
std::unique_ptr<EventBusManager> EventBusManager_;
|
||||
ArgVec Args_;
|
||||
};
|
||||
|
||||
inline MicroService *MicroService::instance_ = nullptr;
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include "framework/MicroServiceFuncs.h"
|
||||
#include "framework/MicroService.h"
|
||||
|
||||
#include "framework/ALBserver.h"
|
||||
|
||||
namespace OpenWifi {
|
||||
const std::string &MicroServiceDataDirectory() { return MicroService::instance().DataDir(); }
|
||||
|
||||
@@ -47,11 +49,11 @@ namespace OpenWifi {
|
||||
|
||||
void MicroServiceReload(const std::string &Type) { MicroService::instance().Reload(Type); }
|
||||
|
||||
const Types::StringVec MicroServiceGetLogLevelNames() {
|
||||
Types::StringVec MicroServiceGetLogLevelNames() {
|
||||
return MicroService::instance().GetLogLevelNames();
|
||||
}
|
||||
|
||||
const Types::StringVec MicroServiceGetSubSystems() {
|
||||
Types::StringVec MicroServiceGetSubSystems() {
|
||||
return MicroService::instance().GetSubSystems();
|
||||
}
|
||||
|
||||
@@ -79,7 +81,7 @@ namespace OpenWifi {
|
||||
|
||||
std::string MicroServiceGetUIURI() { return MicroService::instance().GetUIURI(); }
|
||||
|
||||
const SubSystemVec MicroServiceGetFullSubSystems() {
|
||||
SubSystemVec MicroServiceGetFullSubSystems() {
|
||||
return MicroService::instance().GetFullSubSystems();
|
||||
}
|
||||
|
||||
@@ -87,7 +89,7 @@ namespace OpenWifi {
|
||||
|
||||
std::uint64_t MicroServiceDaemonBusTimer() { return MicroService::instance().DaemonBusTimer(); }
|
||||
|
||||
std::string MicroServiceMakeSystemEventMessage(const std::string &Type) {
|
||||
std::string MicroServiceMakeSystemEventMessage(const char *Type) {
|
||||
return MicroService::instance().MakeSystemEventMessage(Type);
|
||||
}
|
||||
|
||||
@@ -123,4 +125,16 @@ namespace OpenWifi {
|
||||
return MicroService::instance().AllowExternalMicroServices();
|
||||
}
|
||||
|
||||
void MicroServiceALBCallback( std::string Callback()) {
|
||||
return ALBHealthCheckServer()->RegisterExtendedHealthMessage(Callback);
|
||||
}
|
||||
|
||||
std::string MicroServiceAccessKey() {
|
||||
return MicroService::instance().Hash();
|
||||
}
|
||||
|
||||
std::optional<OpenWifi::Types::MicroServiceMeta> MicroServicePrivateAccessKey(const std::string &servicePrivateEndPoint) {
|
||||
return MicroService::instance().GetPrivateEndPointServiceKey(servicePrivateEndPoint);
|
||||
}
|
||||
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -22,7 +22,10 @@ namespace OpenWifi {
|
||||
std::string MicroServicePublicEndPoint();
|
||||
std::string MicroServiceConfigGetString(const std::string &Key,
|
||||
const std::string &DefaultValue);
|
||||
bool MicroServiceConfigGetBool(const std::string &Key, bool DefaultValue);
|
||||
std::string MicroServiceAccessKey();
|
||||
std::optional<OpenWifi::Types::MicroServiceMeta> MicroServicePrivateAccessKey(const std::string &servicePrivateEndPoint);
|
||||
|
||||
bool MicroServiceConfigGetBool(const std::string &Key, bool DefaultValue);
|
||||
std::uint64_t MicroServiceConfigGetInt(const std::string &Key, std::uint64_t DefaultValue);
|
||||
std::string MicroServicePrivateEndPoint();
|
||||
std::uint64_t MicroServiceID();
|
||||
@@ -31,8 +34,8 @@ namespace OpenWifi {
|
||||
void MicroServiceLoadConfigurationFile();
|
||||
void MicroServiceReload();
|
||||
void MicroServiceReload(const std::string &Type);
|
||||
const Types::StringVec MicroServiceGetLogLevelNames();
|
||||
const Types::StringVec MicroServiceGetSubSystems();
|
||||
Types::StringVec MicroServiceGetLogLevelNames();
|
||||
Types::StringVec MicroServiceGetSubSystems();
|
||||
Types::StringPairVec MicroServiceGetLogLevels();
|
||||
bool MicroServiceSetSubsystemLogLevel(const std::string &SubSystem, const std::string &Level);
|
||||
void MicroServiceGetExtraConfiguration(Poco::JSON::Object &Answer);
|
||||
@@ -40,10 +43,10 @@ namespace OpenWifi {
|
||||
std::uint64_t MicroServiceUptimeTotalSeconds();
|
||||
std::uint64_t MicroServiceStartTimeEpochTime();
|
||||
std::string MicroServiceGetUIURI();
|
||||
const SubSystemVec MicroServiceGetFullSubSystems();
|
||||
SubSystemVec MicroServiceGetFullSubSystems();
|
||||
std::string MicroServiceCreateUUID();
|
||||
std::uint64_t MicroServiceDaemonBusTimer();
|
||||
std::string MicroServiceMakeSystemEventMessage(const std::string &Type);
|
||||
std::string MicroServiceMakeSystemEventMessage(const char *Type);
|
||||
Poco::ThreadPool &MicroServiceTimerPool();
|
||||
std::string MicroServiceConfigPath(const std::string &Key, const std::string &DefaultValue);
|
||||
std::string MicroServiceWWWAssetsDir();
|
||||
@@ -53,4 +56,5 @@ namespace OpenWifi {
|
||||
std::string MicroServiceGetPublicAPIEndPoint();
|
||||
void MicroServiceDeleteOverrideConfiguration();
|
||||
bool AllowExternalMicroServices();
|
||||
void MicroServiceALBCallback( std::string Callback());
|
||||
} // namespace OpenWifi
|
||||
|
||||
@@ -28,6 +28,9 @@ namespace OpenWifi::Types {
|
||||
typedef std::string UUID_t;
|
||||
typedef std::vector<UUID_t> UUIDvec_t;
|
||||
typedef std::map<std::string, std::map<uint32_t, uint64_t>> Counted3DMapSII;
|
||||
typedef std::vector<int64_t> IntList;
|
||||
typedef std::vector<uint64_t> UIntList;
|
||||
typedef std::vector<double> DoubleList;
|
||||
|
||||
struct MicroServiceMeta {
|
||||
uint64_t Id = 0;
|
||||
|
||||
@@ -574,7 +574,37 @@ namespace OpenWifi {
|
||||
Poco::JSON::Stringifier::stringify(Object, Answer);
|
||||
}
|
||||
|
||||
inline void ReturnRawJSON(const std::string &json_doc) {
|
||||
inline void ReturnObject(const std::vector<std::string> &Strings) {
|
||||
Poco::JSON::Array Arr;
|
||||
for(const auto &String:Strings) {
|
||||
Arr.add(String);
|
||||
}
|
||||
std::ostringstream os;
|
||||
Arr.stringify(os);
|
||||
return ReturnRawJSON(os.str());
|
||||
}
|
||||
|
||||
template<class T> void ReturnObject(const std::vector<T> &Objects) {
|
||||
Poco::JSON::Array Arr;
|
||||
for(const auto &Object:Objects) {
|
||||
Poco::JSON::Object O;
|
||||
Object.to_json(O);
|
||||
Arr.add(O);
|
||||
}
|
||||
std::ostringstream os;
|
||||
Arr.stringify(os);
|
||||
return ReturnRawJSON(os.str());
|
||||
}
|
||||
|
||||
template<class T> void ReturnObject(const T &Object) {
|
||||
Poco::JSON::Object O;
|
||||
Object.to_json(O);
|
||||
std::ostringstream os;
|
||||
O.stringify(os);
|
||||
return ReturnRawJSON(os.str());
|
||||
}
|
||||
|
||||
inline void ReturnRawJSON(const std::string &json_doc) {
|
||||
PrepareResponse();
|
||||
if (Request != nullptr) {
|
||||
// can we compress ???
|
||||
|
||||
@@ -24,50 +24,63 @@ namespace OpenWifi {
|
||||
Server, TransactionId, Internal) {}
|
||||
static auto PathName() { return std::list<std::string>{"/api/v1/system"}; }
|
||||
|
||||
inline void DoGet() {
|
||||
inline void DoGet() final {
|
||||
std::string Arg;
|
||||
if (HasParameter("command", Arg) && Arg == "info") {
|
||||
Poco::JSON::Object Answer;
|
||||
Answer.set(RESTAPI::Protocol::VERSION, MicroServiceVersion());
|
||||
Answer.set(RESTAPI::Protocol::UPTIME, MicroServiceUptimeTotalSeconds());
|
||||
Answer.set(RESTAPI::Protocol::START, MicroServiceStartTimeEpochTime());
|
||||
Answer.set(RESTAPI::Protocol::OS, Poco::Environment::osName());
|
||||
Answer.set(RESTAPI::Protocol::PROCESSORS, Poco::Environment::processorCount());
|
||||
Answer.set(RESTAPI::Protocol::HOSTNAME, Poco::Environment::nodeName());
|
||||
Answer.set(RESTAPI::Protocol::UI, MicroServiceGetUIURI());
|
||||
if (HasParameter("command", Arg)) {
|
||||
if (Arg == "info") {
|
||||
Poco::JSON::Object Answer;
|
||||
Answer.set(RESTAPI::Protocol::VERSION, MicroServiceVersion());
|
||||
Answer.set(RESTAPI::Protocol::UPTIME, MicroServiceUptimeTotalSeconds());
|
||||
Answer.set(RESTAPI::Protocol::START, MicroServiceStartTimeEpochTime());
|
||||
Answer.set(RESTAPI::Protocol::OS, Poco::Environment::osName());
|
||||
Answer.set(RESTAPI::Protocol::PROCESSORS, Poco::Environment::processorCount());
|
||||
Answer.set(RESTAPI::Protocol::HOSTNAME, Poco::Environment::nodeName());
|
||||
Answer.set(RESTAPI::Protocol::UI, MicroServiceGetUIURI());
|
||||
|
||||
Poco::JSON::Array Certificates;
|
||||
auto SubSystems = MicroServiceGetFullSubSystems();
|
||||
std::set<std::string> CertNames;
|
||||
Poco::JSON::Array Certificates;
|
||||
auto SubSystems = MicroServiceGetFullSubSystems();
|
||||
std::set<std::string> CertNames;
|
||||
|
||||
for (const auto &i : SubSystems) {
|
||||
auto Hosts = i->HostSize();
|
||||
for (uint64_t j = 0; j < Hosts; ++j) {
|
||||
auto CertFileName = i->Host(j).CertFile();
|
||||
if (!CertFileName.empty()) {
|
||||
Poco::File F1(CertFileName);
|
||||
if (F1.exists()) {
|
||||
auto InsertResult = CertNames.insert(CertFileName);
|
||||
if (InsertResult.second) {
|
||||
Poco::JSON::Object Inner;
|
||||
Poco::Path F(CertFileName);
|
||||
Inner.set("filename", F.getFileName());
|
||||
Poco::Crypto::X509Certificate C(CertFileName);
|
||||
auto ExpiresOn = C.expiresOn();
|
||||
Inner.set("expiresOn", ExpiresOn.timestamp().epochTime());
|
||||
Certificates.add(Inner);
|
||||
for (const auto &i : SubSystems) {
|
||||
auto Hosts = i->HostSize();
|
||||
for (uint64_t j = 0; j < Hosts; ++j) {
|
||||
auto CertFileName = i->Host(j).CertFile();
|
||||
if (!CertFileName.empty()) {
|
||||
Poco::File F1(CertFileName);
|
||||
if (F1.exists()) {
|
||||
auto InsertResult = CertNames.insert(CertFileName);
|
||||
if (InsertResult.second) {
|
||||
Poco::JSON::Object Inner;
|
||||
Poco::Path F(CertFileName);
|
||||
Inner.set("filename", F.getFileName());
|
||||
Poco::Crypto::X509Certificate C(CertFileName);
|
||||
auto ExpiresOn = C.expiresOn();
|
||||
Inner.set("expiresOn", ExpiresOn.timestamp().epochTime());
|
||||
Certificates.add(Inner);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Answer.set("certificates", Certificates);
|
||||
return ReturnObject(Answer);
|
||||
}
|
||||
if (Arg == "extraConfiguration") {
|
||||
Poco::JSON::Object Answer;
|
||||
MicroServiceGetExtraConfiguration(Answer);
|
||||
return ReturnObject(Answer);
|
||||
}
|
||||
if (Arg == "resources") {
|
||||
Poco::JSON::Object Answer;
|
||||
Answer.set("numberOfFileDescriptors", Utils::get_open_fds());
|
||||
std::uint64_t currRealMem, peakRealMem, currVirtMem, peakVirtMem;
|
||||
Utils::getMemory(currRealMem, peakRealMem, currVirtMem, peakVirtMem);
|
||||
Answer.set("currRealMem", currRealMem);
|
||||
Answer.set("peakRealMem", peakRealMem);
|
||||
Answer.set("currVirtMem", currVirtMem);
|
||||
Answer.set("peakVirtMem", peakVirtMem);
|
||||
return ReturnObject(Answer);
|
||||
}
|
||||
Answer.set("certificates", Certificates);
|
||||
return ReturnObject(Answer);
|
||||
}
|
||||
if (GetBoolParameter("extraConfiguration")) {
|
||||
Poco::JSON::Object Answer;
|
||||
MicroServiceGetExtraConfiguration(Answer);
|
||||
return ReturnObject(Answer);
|
||||
}
|
||||
BadRequest(RESTAPI::Errors::InvalidCommand);
|
||||
}
|
||||
|
||||
@@ -14,8 +14,15 @@
|
||||
#include "framework/OpenWifiTypes.h"
|
||||
#include "framework/utils.h"
|
||||
|
||||
#include <RESTObjects/RESTAPI_SecurityObjects.h>
|
||||
|
||||
namespace OpenWifi::RESTAPI_utils {
|
||||
|
||||
inline bool IsRootOrAdmin(const SecurityObjects::UserInfo &UI) {
|
||||
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;
|
||||
@@ -95,6 +102,20 @@ namespace OpenWifi::RESTAPI_utils {
|
||||
Obj.set(Field, A);
|
||||
}
|
||||
|
||||
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const Types::DoubleList &V) {
|
||||
Poco::JSON::Array A;
|
||||
for (const auto &i : V)
|
||||
A.add(i);
|
||||
Obj.set(Field, A);
|
||||
}
|
||||
|
||||
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const Types::IntList &V) {
|
||||
Poco::JSON::Array A;
|
||||
for (const auto &i : V)
|
||||
A.add(i);
|
||||
Obj.set(Field, A);
|
||||
}
|
||||
|
||||
inline void field_to_json(Poco::JSON::Object &Obj, const char *Field, const Types::TagList &V) {
|
||||
Poco::JSON::Array A;
|
||||
for (const auto &i : V)
|
||||
@@ -277,6 +298,28 @@ namespace OpenWifi::RESTAPI_utils {
|
||||
}
|
||||
}
|
||||
|
||||
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
|
||||
Types::DoubleList &Value) {
|
||||
if (Obj->isArray(Field) && !Obj->isNull(Field)) {
|
||||
Value.clear();
|
||||
Poco::JSON::Array::Ptr A = Obj->getArray(Field);
|
||||
for (const auto &i : *A) {
|
||||
Value.push_back(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
|
||||
Types::IntList &Value) {
|
||||
if (Obj->isArray(Field) && !Obj->isNull(Field)) {
|
||||
Value.clear();
|
||||
Poco::JSON::Array::Ptr A = Obj->getArray(Field);
|
||||
for (const auto &i : *A) {
|
||||
Value.push_back(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char *Field,
|
||||
std::vector<T> &Value) {
|
||||
|
||||
@@ -22,9 +22,8 @@ namespace OpenWifi {
|
||||
|
||||
class StorageClass : public SubSystemServer {
|
||||
public:
|
||||
StorageClass() noexcept : SubSystemServer("StorageClass", "STORAGE-SVR", "storage") {}
|
||||
|
||||
int Start() override {
|
||||
inline int Start() override {
|
||||
std::lock_guard Guard(Mutex_);
|
||||
|
||||
Logger().notice("Starting.");
|
||||
@@ -40,17 +39,24 @@ namespace OpenWifi {
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Stop() override { Pool_->shutdown(); }
|
||||
inline void Stop() override { Pool_->shutdown(); }
|
||||
|
||||
DBType Type() const { return dbType_; };
|
||||
|
||||
StorageClass() noexcept : SubSystemServer("StorageClass", "STORAGE-SVR", "storage") {
|
||||
|
||||
}
|
||||
|
||||
Poco::Data::SessionPool &Pool() { return *Pool_; }
|
||||
|
||||
private:
|
||||
inline int Setup_SQLite();
|
||||
inline int Setup_MySQL();
|
||||
inline int Setup_PostgreSQL();
|
||||
|
||||
protected:
|
||||
std::unique_ptr<Poco::Data::SessionPool> Pool_;
|
||||
|
||||
protected:
|
||||
std::shared_ptr<Poco::Data::SessionPool> Pool_;
|
||||
Poco::Data::SQLite::Connector SQLiteConn_;
|
||||
Poco::Data::PostgreSQL::Connector PostgresConn_;
|
||||
Poco::Data::MySQL::Connector MySQLConn_;
|
||||
@@ -81,7 +87,7 @@ namespace OpenWifi {
|
||||
// Poco::Data::SessionPool(SQLiteConn_.name(), DBName, 8,
|
||||
// (int)NumSessions,
|
||||
// (int)IdleTime));
|
||||
Pool_ = std::make_unique<Poco::Data::SessionPool>(SQLiteConn_.name(), DBName, 8,
|
||||
Pool_ = std::make_shared<Poco::Data::SessionPool>(SQLiteConn_.name(), DBName, 8,
|
||||
(int)NumSessions, (int)IdleTime);
|
||||
return 0;
|
||||
}
|
||||
@@ -102,7 +108,7 @@ namespace OpenWifi {
|
||||
";compress=true;auto-reconnect=true";
|
||||
|
||||
Poco::Data::MySQL::Connector::registerConnector();
|
||||
Pool_ = std::make_unique<Poco::Data::SessionPool>(MySQLConn_.name(), ConnectionStr, 8,
|
||||
Pool_ = std::make_shared<Poco::Data::SessionPool>(MySQLConn_.name(), ConnectionStr, 8,
|
||||
NumSessions, IdleTime);
|
||||
|
||||
return 0;
|
||||
@@ -126,7 +132,7 @@ namespace OpenWifi {
|
||||
" connect_timeout=" + ConnectionTimeout;
|
||||
|
||||
Poco::Data::PostgreSQL::Connector::registerConnector();
|
||||
Pool_ = std::make_unique<Poco::Data::SessionPool>(PostgresConn_.name(), ConnectionStr, 8,
|
||||
Pool_ = std::make_shared<Poco::Data::SessionPool>(PostgresConn_.name(), ConnectionStr, 8,
|
||||
NumSessions, IdleTime);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -37,6 +37,7 @@ namespace OpenWifi {
|
||||
P.cipherList = "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH";
|
||||
P.dhUse2048Bits = true;
|
||||
P.caLocation = cas_;
|
||||
// P.securityLevel =
|
||||
|
||||
auto Context = Poco::AutoPtr<Poco::Net::Context>(
|
||||
new Poco::Net::Context(Poco::Net::Context::TLS_SERVER_USE, P));
|
||||
@@ -53,7 +54,6 @@ namespace OpenWifi {
|
||||
|
||||
Context->useCertificate(Cert);
|
||||
Context->addChainCertificate(Root);
|
||||
|
||||
Context->addCertificateAuthority(Root);
|
||||
|
||||
if (level_ == Poco::Net::Context::VERIFY_STRICT) {
|
||||
@@ -76,18 +76,18 @@ namespace OpenWifi {
|
||||
L.fatal(fmt::format("Wrong Certificate({}) for Key({})", cert_file_, key_file_));
|
||||
}
|
||||
|
||||
SSL_CTX_set_verify(SSLCtx, SSL_VERIFY_PEER, nullptr);
|
||||
SSL_CTX_set_verify(SSLCtx, level_==Poco::Net::Context::VERIFY_NONE ? SSL_VERIFY_NONE : SSL_VERIFY_PEER, nullptr);
|
||||
|
||||
if (level_ == Poco::Net::Context::VERIFY_STRICT) {
|
||||
SSL_CTX_set_client_CA_list(SSLCtx, SSL_load_client_CA_file(client_cas_.c_str()));
|
||||
SSL_CTX_enable_ct(SSLCtx, SSL_CT_VALIDATION_STRICT);
|
||||
}
|
||||
SSL_CTX_enable_ct(SSLCtx, SSL_CT_VALIDATION_STRICT);
|
||||
SSL_CTX_dane_enable(SSLCtx);
|
||||
|
||||
Context->enableSessionCache();
|
||||
Context->setSessionCacheSize(0);
|
||||
Context->setSessionTimeout(60);
|
||||
Context->enableExtendedCertificateVerification(true);
|
||||
Context->enableExtendedCertificateVerification( level_!= Poco::Net::Context::VERIFY_NONE );
|
||||
Context->disableStatelessSessionResumption();
|
||||
}
|
||||
|
||||
|
||||
@@ -58,11 +58,9 @@ namespace OpenWifi {
|
||||
void UI_WebSocketClientServer::run() {
|
||||
Running_ = true;
|
||||
while (Running_) {
|
||||
Poco::Thread::trySleep(2000);
|
||||
|
||||
if (!Running_)
|
||||
break;
|
||||
|
||||
if(!Poco::Thread::trySleep(2000)) {
|
||||
break;
|
||||
}
|
||||
std::lock_guard G(LocalMutex_);
|
||||
for (const auto i : ToBeRemoved_) {
|
||||
// std::cout << "Erasing old WS UI connection..." << std::endl;
|
||||
|
||||
63
src/framework/default_device_types.h
Normal file
63
src/framework/default_device_types.h
Normal file
@@ -0,0 +1,63 @@
|
||||
//
|
||||
// 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"}};
|
||||
}
|
||||
@@ -576,8 +576,8 @@ namespace ORM {
|
||||
bool UpdateRecord(field_name_t FieldName, const T &Value, const RecordType &R) {
|
||||
try {
|
||||
assert(ValidFieldName(FieldName));
|
||||
|
||||
Poco::Data::Session Session = Pool_.get();
|
||||
Session.begin();
|
||||
Poco::Data::Statement Update(Session);
|
||||
|
||||
RecordTuple RT;
|
||||
@@ -593,6 +593,7 @@ namespace ORM {
|
||||
Update.execute();
|
||||
if (Cache_)
|
||||
Cache_->UpdateCache(R);
|
||||
Session.commit();
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.log(E);
|
||||
@@ -662,6 +663,7 @@ namespace ORM {
|
||||
assert(ValidFieldName(FieldName));
|
||||
|
||||
Poco::Data::Session Session = Pool_.get();
|
||||
Session.begin();
|
||||
Poco::Data::Statement Delete(Session);
|
||||
|
||||
std::string St = "delete from " + TableName_ + " where " + FieldName + "=?";
|
||||
@@ -671,6 +673,7 @@ namespace ORM {
|
||||
Delete.execute();
|
||||
if (Cache_)
|
||||
Cache_->Delete(FieldName, Value);
|
||||
Session.commit();
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.log(E);
|
||||
@@ -682,11 +685,13 @@ namespace ORM {
|
||||
try {
|
||||
assert(!WhereClause.empty());
|
||||
Poco::Data::Session Session = Pool_.get();
|
||||
Session.begin();
|
||||
Poco::Data::Statement Delete(Session);
|
||||
|
||||
std::string St = "delete from " + TableName_ + " where " + WhereClause;
|
||||
Delete << St;
|
||||
Delete.execute();
|
||||
Session.commit();
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
Logger_.log(E);
|
||||
|
||||
@@ -40,6 +40,7 @@ namespace OpenWifi {
|
||||
};
|
||||
}
|
||||
|
||||
#define DBGLINE std::cout << __LINE__ << ":" << __FILE__ << ", " << __func__ << std::endl;
|
||||
namespace OpenWifi::RESTAPI::Errors {
|
||||
struct msg {
|
||||
uint64_t err_num;
|
||||
@@ -397,6 +398,49 @@ namespace OpenWifi::RESTAPI::Errors {
|
||||
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 VenuesNameAlreadyExists {
|
||||
1172, "The venue name already exists."
|
||||
};
|
||||
|
||||
static const struct msg InvalidGlobalReachAccount {
|
||||
1173, "Invalid Global Reach account information."
|
||||
};
|
||||
static const struct msg CannotCreateCSR {
|
||||
1174, "Cannot create a CSR certificate."
|
||||
};
|
||||
|
||||
static const struct msg DefFirmwareNameExists { 1175, "Firmware name already exists." };
|
||||
static const struct msg NotAValidECKey { 1176, "Not a valid Signing Key." };
|
||||
static const struct msg NotAValidRadiusPoolType { 1177, "Not a valid RADIUS pool type." };
|
||||
static const struct msg InvalidRadiusTypeEndpoint { 1178, "Invalid RADIUS Server Endpoint type." };
|
||||
static const struct msg InvalidRadiusEndpointPoolStrategy { 1179, "Invalid RADIUS Server Endpoint Pool strategy." };
|
||||
static const struct msg EndpointMustHaveOneTypeOfServers { 1180, "All servers must be either RADIUS or RADSEC." };
|
||||
static const struct msg RadiusEndpointIndexInvalid { 1181, "Index must be an address between 0.0.1.1 and 0.0.2.254" };
|
||||
static const struct msg RadiusEndpointIndexMustBeUnique { 1182, "Index must be unique." };
|
||||
static const struct msg OrionAccountMustExist { 1183, "Orion account must exist." };
|
||||
static const struct msg GlobalReachCertMustExist { 1184, "Global Reach certificate must exist." };
|
||||
static const struct msg InvalidRadsecMainCertificate { 1185, "Invalid Radsec main certificate." };
|
||||
static const struct msg InvalidRadsecCaCertificate { 1186, "Invalid Radsec CA certificates." };
|
||||
static const struct msg InvalidRadsecPrivteKey { 1187, "Invalid Radsec Private key." };
|
||||
static const struct msg InvalidRadsecIPAddress { 1188, "Invalid Radsec IP Address." };
|
||||
static const struct msg InvalidRadsecPort { 1189, "Invalid Radsec Port." };
|
||||
static const struct msg InvalidRadsecSecret { 1190, "Invalid Radsec Secret." };
|
||||
static const struct msg InvalidRadiusServer { 1191, "Invalid Radius Server." };
|
||||
|
||||
static const struct msg InvalidRRMAction { 1192, "Invalid RRM Action." };
|
||||
|
||||
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
|
||||
|
||||
@@ -519,6 +563,11 @@ namespace OpenWifi::RESTAPI::Protocol {
|
||||
static const char *CONTENTDISPOSITION = "Content-Disposition";
|
||||
static const char *CONTENTTYPE = "Content-Type";
|
||||
|
||||
static const char *TRANSFER = "transfer";
|
||||
static const char *CERTUPDATE = "certupdate";
|
||||
static const char *POWERCYCLE = "powercycle";
|
||||
static const char *RRM = "rrm";
|
||||
|
||||
static const char *REQUIREMENTS = "requirements";
|
||||
static const char *PASSWORDPATTERN = "passwordPattern";
|
||||
static const char *ACCESSPOLICY = "accessPolicy";
|
||||
@@ -554,6 +603,7 @@ namespace OpenWifi::uCentralProtocol {
|
||||
static const char *HEALTHCHECK = "healthcheck";
|
||||
static const char *LOG = "log";
|
||||
static const char *CRASHLOG = "crashlog";
|
||||
static const char *REBOOTLOG = "rebootLog";
|
||||
static const char *PING = "ping";
|
||||
static const char *CFGPENDING = "cfgpending";
|
||||
static const char *RECOVERY = "recovery";
|
||||
@@ -612,6 +662,8 @@ namespace OpenWifi::uCentralProtocol {
|
||||
static const char *DEVICEUPDATE = "deviceupdate";
|
||||
static const char *FWSIGNATURE = "FWsignature";
|
||||
static const char *SIGNATURE = "signature";
|
||||
static const char *INFO = "info";
|
||||
static const char *DATE = "date";
|
||||
|
||||
static const char *SERIALNUMBER = "serialNumber";
|
||||
static const char *COMPATIBLE = "compatible";
|
||||
@@ -633,6 +685,13 @@ namespace OpenWifi::uCentralProtocol {
|
||||
static const char *RADIUSCOA = "coa";
|
||||
static const char *RADIUSDST = "dst";
|
||||
static const char *IES = "ies";
|
||||
|
||||
static const char *TRANSFER = "transfer";
|
||||
static const char *CERTUPDATE = "certupdate";
|
||||
static const char *POWERCYCLE = "powercycle";
|
||||
static const char *RRM = "rrm";
|
||||
static const char *ACTIONS = "actions";
|
||||
|
||||
} // namespace OpenWifi::uCentralProtocol
|
||||
|
||||
namespace OpenWifi::uCentralProtocol::Events {
|
||||
@@ -642,6 +701,7 @@ namespace OpenWifi::uCentralProtocol::Events {
|
||||
static const char *HEALTHCHECK = "healthcheck";
|
||||
static const char *LOG = "log";
|
||||
static const char *CRASHLOG = "crashlog";
|
||||
static const char *REBOOTLOG = "rebootLog";
|
||||
static const char *PING = "ping";
|
||||
static const char *CFGPENDING = "cfgpending";
|
||||
static const char *RECOVERY = "recovery";
|
||||
@@ -665,7 +725,8 @@ namespace OpenWifi::uCentralProtocol::Events {
|
||||
ET_VENUEBROADCAST,
|
||||
ET_EVENT,
|
||||
ET_WIFISCAN,
|
||||
ET_ALARM
|
||||
ET_ALARM,
|
||||
ET_REBOOTLOG
|
||||
};
|
||||
|
||||
inline EVENT_MSG EventFromString(const std::string &Method) {
|
||||
@@ -696,8 +757,10 @@ namespace OpenWifi::uCentralProtocol::Events {
|
||||
else if (strcmp(WIFISCAN, Method.c_str()) == 0)
|
||||
return ET_WIFISCAN;
|
||||
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
|
||||
|
||||
@@ -721,6 +784,10 @@ namespace OpenWifi::APCommands {
|
||||
telemetry,
|
||||
ping,
|
||||
script,
|
||||
rrm,
|
||||
certupdate,
|
||||
transfer,
|
||||
powercycle,
|
||||
unknown
|
||||
};
|
||||
|
||||
@@ -733,7 +800,10 @@ namespace OpenWifi::APCommands {
|
||||
RESTAPI::Protocol::LEDS, RESTAPI::Protocol::TRACE,
|
||||
RESTAPI::Protocol::REQUEST, RESTAPI::Protocol::WIFISCAN,
|
||||
RESTAPI::Protocol::EVENTQUEUE, RESTAPI::Protocol::TELEMETRY,
|
||||
RESTAPI::Protocol::PING, RESTAPI::Protocol::SCRIPT};
|
||||
RESTAPI::Protocol::PING, RESTAPI::Protocol::SCRIPT,
|
||||
RESTAPI::Protocol::RRM, RESTAPI::Protocol::CERTUPDATE,
|
||||
RESTAPI::Protocol::TRANSFER, RESTAPI::Protocol::POWERCYCLE
|
||||
};
|
||||
|
||||
inline const char *to_string(Commands Cmd) { return uCentralAPCommands[(uint8_t)Cmd]; }
|
||||
|
||||
|
||||
@@ -3,10 +3,19 @@
|
||||
//
|
||||
|
||||
#include "Poco/Path.h"
|
||||
|
||||
#include "Poco/TemporaryFile.h"
|
||||
#include "Poco/Crypto/ECKey.h"
|
||||
#include "framework/AppServiceRegistry.h"
|
||||
#include "framework/utils.h"
|
||||
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
#include <ctime>
|
||||
#include <string>
|
||||
#include <algorithm>
|
||||
|
||||
#include <resolv.h>
|
||||
|
||||
namespace OpenWifi::Utils {
|
||||
|
||||
bool NormalizeMac(std::string &Mac) {
|
||||
@@ -27,6 +36,10 @@ namespace OpenWifi::Utils {
|
||||
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) {
|
||||
if (UUID.size() > 36)
|
||||
return false;
|
||||
@@ -128,6 +141,15 @@ namespace OpenWifi::Utils {
|
||||
return std::regex_match(Hostname, HostNameRegex);
|
||||
}
|
||||
|
||||
[[nodiscard]] bool ValidNumber(const std::string &number, bool isSigned)
|
||||
{
|
||||
static std::regex IntRegex("^-?[0-9]\\d*(\\.\\d+)?$");
|
||||
if(!isSigned) {
|
||||
IntRegex = "^[0-9]\\d*(\\.\\d+)?$";
|
||||
}
|
||||
return std::regex_match(number, IntRegex);
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string ToHex(const std::vector<unsigned char> &B) {
|
||||
std::string R;
|
||||
R.reserve(B.size() * 2);
|
||||
@@ -595,4 +617,329 @@ namespace OpenWifi::Utils {
|
||||
return DT.timestamp().epochTime();
|
||||
}
|
||||
|
||||
static std::string FileToString(const std::string &Filename) {
|
||||
std::ifstream ifs(Filename.c_str(),std::ios_base::in|std::ios_base::binary);
|
||||
std::ostringstream os;
|
||||
Poco::StreamCopier::copyStream(ifs,os);
|
||||
return os.str();
|
||||
}
|
||||
|
||||
bool CreateX509CSR(const CSRCreationParameters & Parameters, CSRCreationResults & Results) {
|
||||
int ret = 0;
|
||||
RSA *r = nullptr;
|
||||
BIGNUM *bne = nullptr;
|
||||
|
||||
int nVersion = 0;
|
||||
unsigned long e = RSA_F4;
|
||||
|
||||
X509_REQ *x509_req = nullptr;
|
||||
X509_NAME *x509_name = nullptr;
|
||||
EVP_PKEY *pKey = nullptr;
|
||||
// RSA *tem = nullptr;
|
||||
// BIO *bio_err = nullptr;
|
||||
|
||||
const char *szCountry = Parameters.Country.c_str();
|
||||
const char *szProvince = Parameters.Province.c_str();
|
||||
const char *szCity = Parameters.City.c_str();
|
||||
const char *szOrganization = Parameters.Organization.c_str();
|
||||
const char *szCommon = Parameters.CommonName.c_str();
|
||||
|
||||
Poco::TemporaryFile CsrPath, PubKey, PrivateKey;
|
||||
std::string Result;
|
||||
std::ifstream ifs;
|
||||
std::ostringstream ss;
|
||||
BIO *bp_public = nullptr,
|
||||
*bp_private = nullptr,
|
||||
*bp_csr = nullptr;
|
||||
|
||||
// 1. generate rsa key
|
||||
bne = BN_new();
|
||||
ret = BN_set_word(bne,e);
|
||||
if(ret != 1){
|
||||
goto free_all;
|
||||
}
|
||||
|
||||
r = RSA_new();
|
||||
ret = RSA_generate_key_ex(r, Parameters.bits, bne, nullptr);
|
||||
if(ret != 1){
|
||||
goto free_all;
|
||||
}
|
||||
|
||||
bp_public = BIO_new_file(PubKey.path().c_str(), "w+");
|
||||
ret = PEM_write_bio_RSAPublicKey(bp_public, r);
|
||||
if(ret != 1) {
|
||||
goto free_all;
|
||||
}
|
||||
|
||||
bp_private = BIO_new_file(PrivateKey.path().c_str(), "w+");
|
||||
ret = PEM_write_bio_RSAPrivateKey(bp_private, r, NULL, NULL, 0, NULL, NULL);
|
||||
if(ret != 1) {
|
||||
goto free_all;
|
||||
}
|
||||
|
||||
// 2. set version of x509 req
|
||||
x509_req = X509_REQ_new();
|
||||
ret = X509_REQ_set_version(x509_req, nVersion);
|
||||
if (ret != 1){
|
||||
goto free_all;
|
||||
}
|
||||
|
||||
// 3. set subject of x509 req
|
||||
x509_name = X509_REQ_get_subject_name(x509_req);
|
||||
|
||||
ret = X509_NAME_add_entry_by_txt(x509_name,"C", MBSTRING_ASC, (const unsigned char*)szCountry, -1, -1, 0);
|
||||
if (ret != 1){
|
||||
goto free_all;
|
||||
}
|
||||
|
||||
ret = X509_NAME_add_entry_by_txt(x509_name,"ST", MBSTRING_ASC, (const unsigned char*)szProvince, -1, -1, 0);
|
||||
if (ret != 1){
|
||||
goto free_all;
|
||||
}
|
||||
|
||||
ret = X509_NAME_add_entry_by_txt(x509_name,"L", MBSTRING_ASC, (const unsigned char*)szCity, -1, -1, 0);
|
||||
if (ret != 1){
|
||||
goto free_all;
|
||||
}
|
||||
|
||||
ret = X509_NAME_add_entry_by_txt(x509_name,"O", MBSTRING_ASC, (const unsigned char*)szOrganization, -1, -1, 0);
|
||||
if (ret != 1){
|
||||
goto free_all;
|
||||
}
|
||||
|
||||
ret = X509_NAME_add_entry_by_txt(x509_name,"CN", MBSTRING_ASC, (const unsigned char*)szCommon, -1, -1, 0);
|
||||
if (ret != 1){
|
||||
goto free_all;
|
||||
}
|
||||
|
||||
// 4. set public key of x509 req
|
||||
pKey = EVP_PKEY_new();
|
||||
EVP_PKEY_assign_RSA(pKey, r);
|
||||
r = nullptr; // will be free rsa when EVP_PKEY_free(pKey)
|
||||
|
||||
ret = X509_REQ_set_pubkey(x509_req, pKey);
|
||||
if (ret != 1){
|
||||
goto free_all;
|
||||
}
|
||||
|
||||
// 5. set sign key of x509 req
|
||||
ret = X509_REQ_sign(x509_req, pKey, EVP_sha1()); // return x509_req->signature->length
|
||||
if (ret <= 0){
|
||||
goto free_all;
|
||||
}
|
||||
|
||||
bp_csr = BIO_new_file(CsrPath.path().c_str(),"w");
|
||||
ret = PEM_write_bio_X509_REQ(bp_csr, x509_req);
|
||||
|
||||
// 6. free
|
||||
free_all:
|
||||
X509_REQ_free(x509_req);
|
||||
BIO_free_all(bp_csr);
|
||||
BIO_free_all(bp_public);
|
||||
BIO_free_all(bp_private);
|
||||
|
||||
EVP_PKEY_free(pKey);
|
||||
BN_free(bne);
|
||||
if(ret==1) {
|
||||
Results.CSR = FileToString(CsrPath.path());
|
||||
Results.PrivateKey = FileToString(PrivateKey.path());
|
||||
Results.PublicKey = FileToString(PubKey.path());
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool VerifyECKey(const std::string &key) {
|
||||
try {
|
||||
Poco::TemporaryFile F;
|
||||
|
||||
std::ofstream of(F.path().c_str(), std::ios_base::trunc | std::ios_base::out | std::ios_base::binary);
|
||||
of << key;
|
||||
of.close();
|
||||
|
||||
auto Key = Poco::SharedPtr<Poco::Crypto::ECKey>(
|
||||
new Poco::Crypto::ECKey("", F.path(),""));
|
||||
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool VerifyRSAKey([[
|
||||
maybe_unused]] const std::string &key) {
|
||||
try {
|
||||
Poco::TemporaryFile F;
|
||||
|
||||
std::ofstream of(F.path().c_str(), std::ios_base::trunc | std::ios_base::out | std::ios_base::binary);
|
||||
of << key;
|
||||
of.close();
|
||||
|
||||
auto Key = Poco::SharedPtr<Poco::Crypto::RSAKey>(
|
||||
new Poco::Crypto::RSAKey("", F.path(),""));
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool VerifyPrivateKey(const std::string &key) {
|
||||
return VerifyECKey(key) || VerifyRSAKey(key);
|
||||
}
|
||||
|
||||
bool ValidX509Certificate([[
|
||||
maybe_unused]] const std::string &Cert) {
|
||||
try {
|
||||
Poco::TemporaryFile F;
|
||||
std::ofstream of(F.path().c_str(), std::ios_base::trunc | std::ios_base::out | std::ios_base::binary);
|
||||
of << Cert;
|
||||
of.close();
|
||||
|
||||
auto Key = Poco::SharedPtr<Poco::Crypto::X509Certificate>(
|
||||
new Poco::Crypto::X509Certificate(F.path()));
|
||||
return true;
|
||||
} catch (const Poco::Exception &E) {
|
||||
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ValidX509Certificate([[
|
||||
maybe_unused]] const std::vector<std::string> &Certs) {
|
||||
auto F = [](const std::string &C) -> bool { return ValidX509Certificate(C); };
|
||||
return std::all_of(Certs.begin(),Certs.end(), F);
|
||||
}
|
||||
|
||||
std::string generateStrongPassword(int minLength, int maxLength, int numDigits, int minLowercase, int minSpecial, int minUppercase) {
|
||||
// Define character sets for each category
|
||||
const std::string lowercaseChars = "abcdefghijklmnopqrstuvwxyz";
|
||||
const std::string uppercaseChars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
const std::string digitChars = "0123456789";
|
||||
const std::string specialChars = "!@#$%^&*()_+[]{}|;:,.<>?";
|
||||
|
||||
// Check if parameters are valid
|
||||
if (minLength < 1 || minLength > maxLength || minLowercase + minUppercase + numDigits + minSpecial > maxLength) {
|
||||
return "Invalid parameters";
|
||||
}
|
||||
|
||||
// Initialize random seed
|
||||
std::random_device rd;
|
||||
std::mt19937 g(rd());
|
||||
|
||||
// Initialize the password string
|
||||
std::string password;
|
||||
|
||||
// Generate the required number of each character type
|
||||
for (int i = 0; i < minLowercase; ++i) {
|
||||
password += lowercaseChars[g() % lowercaseChars.length()];
|
||||
}
|
||||
for (int i = 0; i < minUppercase; ++i) {
|
||||
password += uppercaseChars[g() % uppercaseChars.length()];
|
||||
}
|
||||
for (int i = 0; i < numDigits; ++i) {
|
||||
password += digitChars[g() % digitChars.length()];
|
||||
}
|
||||
for (int i = 0; i < minSpecial; ++i) {
|
||||
password += specialChars[g() % specialChars.length()];
|
||||
}
|
||||
|
||||
// Calculate how many more characters are needed
|
||||
int remainingLength = maxLength - (int)password.length();
|
||||
|
||||
// Generate random characters to fill the remaining length
|
||||
for (int i = 0; i < remainingLength; ++i) {
|
||||
int category = g() % 4; // Randomly select a category
|
||||
if (category == 0) {
|
||||
password += lowercaseChars[g() % lowercaseChars.length()];
|
||||
} else if (category == 1) {
|
||||
password += uppercaseChars[g() % uppercaseChars.length()];
|
||||
} else if (category == 2) {
|
||||
password += digitChars[g() % digitChars.length()];
|
||||
} else {
|
||||
password += specialChars[g() % specialChars.length()];
|
||||
}
|
||||
}
|
||||
|
||||
// Shuffle the password to randomize the character order
|
||||
std::shuffle(password.begin(), password.end(),g);
|
||||
|
||||
return password;
|
||||
}
|
||||
|
||||
// Function to query NAPTR records for a domain and return them in a vector
|
||||
std::vector<NAPTRRecord> getNAPTRRecords(const std::string& domain) {
|
||||
std::vector<NAPTRRecord> naptrRecords;
|
||||
|
||||
unsigned char buf[4096];
|
||||
ns_msg handle;
|
||||
ns_initparse(buf, NS_PACKETSZ, &handle);
|
||||
|
||||
// Query NAPTR records for the given domain
|
||||
int response = res_query(domain.c_str(), ns_c_in, ns_t_naptr, buf, sizeof(buf));
|
||||
if (response < 0) {
|
||||
return naptrRecords;
|
||||
}
|
||||
|
||||
if(ns_initparse(buf, response, &handle) < 0) {
|
||||
return naptrRecords;
|
||||
}
|
||||
|
||||
// Iterate through the DNS response and extract NAPTR records
|
||||
int count = ns_msg_count(handle, ns_s_an);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
ns_rr rr;
|
||||
if (ns_parserr(&handle, ns_s_an, i, &rr) == 0) {
|
||||
char rdata[256];
|
||||
ns_sprintrr(&handle, &rr, nullptr, nullptr, rdata, sizeof(rdata));
|
||||
NAPTRRecord record;
|
||||
std::istringstream os(rdata);
|
||||
os >> record.name >> record.ttl >> record.rclass >> record.rtype >> record.order >> record.preference >> record.flags
|
||||
>> record.service >> record.regexp >> record.replacement;
|
||||
naptrRecords.push_back(record);
|
||||
}
|
||||
}
|
||||
|
||||
return naptrRecords;
|
||||
}
|
||||
|
||||
std::vector<SrvRecord> getSRVRecords(const std::string& domain) {
|
||||
std::vector<SrvRecord> srvRecords;
|
||||
|
||||
// Buffer to hold the DNS response
|
||||
unsigned char buf[4096];
|
||||
ns_msg handle;
|
||||
ns_initparse(buf, NS_PACKETSZ, &handle);
|
||||
|
||||
// Query NAPTR records for the given domain
|
||||
int response = res_query(domain.c_str(), ns_c_in, ns_t_srv, buf, sizeof(buf));
|
||||
if (response < 0) {
|
||||
std::cerr << "DNS query failed for " << domain << ": " << hstrerror(h_errno) << std::endl;
|
||||
return srvRecords;
|
||||
}
|
||||
|
||||
if(ns_initparse(buf, response, &handle) < 0) {
|
||||
return srvRecords;
|
||||
}
|
||||
|
||||
// Iterate through the DNS response and extract NAPTR records
|
||||
int count = ns_msg_count(handle, ns_s_an);
|
||||
for (int i = 0; i < count; ++i) {
|
||||
ns_rr rr;
|
||||
if (ns_parserr(&handle, ns_s_an, i, &rr) == 0) {
|
||||
char rdata[256];
|
||||
ns_sprintrr(&handle, &rr, nullptr, nullptr, rdata, sizeof(rdata));
|
||||
SrvRecord record;
|
||||
std::istringstream os(rdata);
|
||||
os >> record.name >> record.ttl >> record.rclass >> record.rtype >> record.pref >> record.weight >>
|
||||
record.port >> record.srvname ;
|
||||
srvRecords.push_back(record);
|
||||
}
|
||||
}
|
||||
|
||||
return srvRecords;
|
||||
}
|
||||
|
||||
|
||||
} // namespace OpenWifi::Utils
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
||||
#include <dirent.h>
|
||||
|
||||
#include "Poco/Base64Decoder.h"
|
||||
#include "Poco/Base64Encoder.h"
|
||||
#include "Poco/File.h"
|
||||
@@ -68,8 +70,10 @@ namespace OpenWifi::Utils {
|
||||
};
|
||||
|
||||
[[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 ValidHostname(const std::string &hostname);
|
||||
[[nodiscard]] bool ValidNumber(const std::string &number, bool isSigned);
|
||||
|
||||
template <typename... Args> std::string ComputeHash(Args &&...args) {
|
||||
Poco::SHA2Engine E;
|
||||
@@ -146,4 +150,256 @@ namespace OpenWifi::Utils {
|
||||
|
||||
bool ExtractBase64CompressedData(const std::string &CompressedData,
|
||||
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;
|
||||
}
|
||||
|
||||
static inline std::uint64_t GetValue(FILE *file) {
|
||||
unsigned long v=0;
|
||||
char factor[32];
|
||||
if(fscanf(file, " %lu %31s", &v, factor)==2) {
|
||||
switch (factor[0]) {
|
||||
case 'k':
|
||||
return v * 1000;
|
||||
case 'M':
|
||||
return v * 1000000;
|
||||
case 'G':
|
||||
return v * 1000000000;
|
||||
}
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
inline bool getMemory(
|
||||
std::uint64_t &currRealMem, std::uint64_t &peakRealMem,
|
||||
std::uint64_t &currVirtMem, std::uint64_t &peakVirtMem) {
|
||||
|
||||
// stores each word in status file
|
||||
char buffer[1024] = "";
|
||||
|
||||
currRealMem = peakRealMem = currVirtMem = peakVirtMem = 0;
|
||||
|
||||
// linux file contains this-process info
|
||||
FILE * file = std::fopen("/proc/self/status", "r");
|
||||
if (file == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// read the entire file, recording mems in kB
|
||||
while (fscanf(file, " %1023s", buffer) == 1) {
|
||||
|
||||
if (strcmp(buffer, "VmRSS:") == 0) {
|
||||
currRealMem= GetValue(file);
|
||||
} else if (strcmp(buffer, "VmHWM:") == 0) {
|
||||
peakRealMem= GetValue(file);
|
||||
} else if (strcmp(buffer, "VmSize:") == 0) {
|
||||
currVirtMem= GetValue(file);
|
||||
} else if (strcmp(buffer, "VmPeak:") == 0) {
|
||||
peakVirtMem= GetValue(file);
|
||||
}
|
||||
}
|
||||
fclose(file);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
inline int get_open_fds() {
|
||||
DIR *dp = opendir("/proc/self/fd");
|
||||
struct dirent *de;
|
||||
int count = -3; // '.', '..', dp
|
||||
|
||||
if (dp == nullptr)
|
||||
return -1;
|
||||
while ((de = readdir(dp)) != nullptr)
|
||||
count++;
|
||||
(void)closedir(dp);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
inline std::uint32_t IPtoInt(const std::string &A) {
|
||||
Poco::Net::IPAddress IP;
|
||||
std::uint32_t Result=0;
|
||||
|
||||
if(Poco::Net::IPAddress::tryParse(A,IP)) {
|
||||
for(const auto i:IP.toBytes()) {
|
||||
Result <<= 8;
|
||||
Result += i;
|
||||
}
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
|
||||
inline bool ValidIP(const std::string &IPstr) {
|
||||
Poco::Net::IPAddress IP;
|
||||
return Poco::Net::IPAddress::tryParse(IPstr,IP);
|
||||
}
|
||||
|
||||
struct CSRCreationParameters {
|
||||
std::string Country, Province, City,
|
||||
Organization, CommonName;
|
||||
int bits=2048;
|
||||
};
|
||||
|
||||
struct CSRCreationResults {
|
||||
std::string CSR, PublicKey, PrivateKey;
|
||||
};
|
||||
|
||||
bool CreateX509CSR(const CSRCreationParameters & Parameters, CSRCreationResults & Results);
|
||||
std::string generateStrongPassword(int minLength, int maxLength, int numDigits, int minLowercase, int minSpecial, int minUppercase);
|
||||
bool VerifyECKey(const std::string &key);
|
||||
bool VerifyRSAKey(const std::string &key);
|
||||
bool VerifyPrivateKey(const std::string &key);
|
||||
bool ValidX509Certificate(const std::string &Cert);
|
||||
bool ValidX509Certificate(const std::vector<std::string> &Certs);
|
||||
|
||||
struct NAPTRRecord {
|
||||
std::string name;
|
||||
std::string ttl;
|
||||
std::string rclass;
|
||||
std::string rtype;
|
||||
uint32_t order=0;
|
||||
uint32_t preference=0;
|
||||
std::string flags;
|
||||
std::string service;
|
||||
std::string regexp;
|
||||
std::string replacement;
|
||||
};
|
||||
|
||||
// Function to query NAPTR records for a domain and return them in a vector
|
||||
std::vector<NAPTRRecord> getNAPTRRecords(const std::string& domain);
|
||||
struct SrvRecord {
|
||||
std::string name;
|
||||
std::string ttl;
|
||||
std::string rclass;
|
||||
std::string rtype;
|
||||
uint32_t pref = 0;
|
||||
uint32_t weight = 0;
|
||||
uint32_t port = 0;
|
||||
std::string srvname;
|
||||
};
|
||||
|
||||
std::vector<SrvRecord> getSRVRecords(const std::string& domain);
|
||||
|
||||
struct HostNameServerResult{
|
||||
std::string Hostname;
|
||||
uint32_t Port;
|
||||
};
|
||||
|
||||
class CompressedString {
|
||||
public:
|
||||
CompressedString() {
|
||||
DecompressedSize_ = 0;
|
||||
};
|
||||
|
||||
explicit CompressedString(const std::string &Data) : DecompressedSize_(Data.size()) {
|
||||
CompressIt(Data);
|
||||
}
|
||||
|
||||
CompressedString(const CompressedString &Data) {
|
||||
this->DecompressedSize_ = Data.DecompressedSize_;
|
||||
this->CompressedData_ = Data.CompressedData_;
|
||||
}
|
||||
|
||||
CompressedString& operator=(const CompressedString& rhs) {
|
||||
if (this != &rhs) {
|
||||
this->DecompressedSize_ = rhs.DecompressedSize_;
|
||||
this->CompressedData_ = rhs.CompressedData_;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
CompressedString& operator=(CompressedString&& rhs) {
|
||||
if (this != &rhs) {
|
||||
this->DecompressedSize_ = rhs.DecompressedSize_;
|
||||
this->CompressedData_ = rhs.CompressedData_;
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
~CompressedString() = default;
|
||||
|
||||
operator std::string() const {
|
||||
return DecompressIt();
|
||||
}
|
||||
|
||||
CompressedString &operator=(const std::string &Data) {
|
||||
DecompressedSize_ = Data.size();
|
||||
CompressIt(Data);
|
||||
return *this;
|
||||
}
|
||||
|
||||
auto CompressedSize() const { return CompressedData_.size(); }
|
||||
auto DecompressedSize() const { return DecompressedSize_; }
|
||||
|
||||
private:
|
||||
std::string CompressedData_;
|
||||
std::size_t DecompressedSize_;
|
||||
|
||||
inline void CompressIt(const std::string &Data) {
|
||||
z_stream strm; // = {0};
|
||||
CompressedData_.resize(Data.size());
|
||||
strm.next_in = (Bytef *)Data.data();
|
||||
strm.avail_in = Data.size();
|
||||
strm.next_out = (Bytef *)CompressedData_.data();
|
||||
strm.avail_out = Data.size();
|
||||
strm.zalloc = Z_NULL;
|
||||
strm.zfree = Z_NULL;
|
||||
strm.opaque = Z_NULL;
|
||||
deflateInit2(&strm, Z_DEFAULT_COMPRESSION, Z_DEFLATED, 15 + 16, 8, Z_DEFAULT_STRATEGY);
|
||||
deflate(&strm, Z_FINISH);
|
||||
deflateEnd(&strm);
|
||||
CompressedData_.resize(strm.total_out);
|
||||
}
|
||||
|
||||
[[nodiscard]] std::string DecompressIt() const {
|
||||
std::string Result;
|
||||
if(DecompressedSize_!=0) {
|
||||
Result.resize(DecompressedSize_);
|
||||
z_stream strm ; //= {0};
|
||||
strm.next_in = (Bytef *)CompressedData_.data();
|
||||
strm.avail_in = CompressedData_.size();
|
||||
strm.next_out = (Bytef *)Result.data();
|
||||
strm.avail_out = Result.size();
|
||||
strm.zalloc = Z_NULL;
|
||||
strm.zfree = Z_NULL;
|
||||
strm.opaque = Z_NULL;
|
||||
inflateInit2(&strm, 15 + 32);
|
||||
inflate(&strm, Z_FINISH);
|
||||
inflateEnd(&strm);
|
||||
}
|
||||
return Result;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace OpenWifi::Utils
|
||||
|
||||
Reference in New Issue
Block a user