diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 0000000..13566b8
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,8 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Editor-based HTTP Client requests
+/httpRequests/
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/markdown.xml b/.idea/markdown.xml
new file mode 100644
index 0000000..1e34094
--- /dev/null
+++ b/.idea/markdown.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 0000000..79b3c94
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 0000000..f975af6
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/wlan-cloud-analytics.iml b/.idea/wlan-cloud-analytics.iml
new file mode 100644
index 0000000..f08604b
--- /dev/null
+++ b/.idea/wlan-cloud-analytics.iml
@@ -0,0 +1,2 @@
+
+
\ No newline at end of file
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..3f4502e
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,95 @@
+cmake_minimum_required(VERSION 3.13)
+project(owanalytics VERSION 2.5.0)
+
+set(CMAKE_CXX_STANDARD 17)
+
+if(UNIX AND APPLE)
+ set(OPENSSL_ROOT_DIR /usr/local/opt/openssl)
+ set(MYSQL_ROOT_DIR /usr/local/opt/mysql-client)
+ list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake)
+endif()
+
+if(UNIX AND NOT APPLE)
+ set(PostgreSQL_TYPE_INCLUDE_DIR /usr/include/postgresql)
+ list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_LIST_DIR}/cmake)
+endif()
+
+if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/build)
+ file(READ ${CMAKE_CURRENT_SOURCE_DIR}/build BUILD_NUM)
+ if(BUILD_INCREMENT)
+ MATH(EXPR BUILD_NUM "${BUILD_NUM}+1")
+ file(WRITE ${CMAKE_CURRENT_SOURCE_DIR}/build ${BUILD_NUM})
+ endif()
+else()
+ set(BUILD_NUM 1)
+ file(WRITE ${CMAKE_CURRENT_SOURCE_DIR}/build ${BUILD_NUM})
+endif()
+
+find_package(Git QUIET)
+if(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git")
+ execute_process(COMMAND ${GIT_EXECUTABLE} describe --always --tags
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ RESULT_VARIABLE GIT_RESULT
+ OUTPUT_VARIABLE GIT_HASH)
+ if(NOT GIT_RESULT EQUAL "0")
+ message(FATAL_ERROR "git describe --always --tags failed with ${GIT_RESULT}")
+ endif()
+ string(REGEX REPLACE "\n$" "" GIT_HASH "${GIT_HASH}")
+endif()
+
+add_definitions(-DAWS_CUSTOM_MEMORY_MANAGEMENT)
+
+set(BUILD_SHARED_LIBS 1)
+set(Boost_USE_STATIC_LIBS OFF)
+set(Boost_USE_MULTITHREADED ON)
+set(Boost_USE_STATIC_RUNTIME OFF)
+
+find_package(Boost REQUIRED system)
+find_package(OpenSSL REQUIRED)
+find_package(AWSSDK REQUIRED COMPONENTS s3)
+find_package(Poco REQUIRED COMPONENTS Crypto JWT Net Util NetSSL Data DataSQLite)
+find_package(nlohmann_json REQUIRED)
+find_package(nlohmann_json_schema_validator REQUIRED)
+
+if(SMALL_BUILD)
+ find_package(Poco REQUIRED COMPONENTS Crypto JWT Net Util NetSSL Data DataSQLite)
+else()
+ find_package(CppKafka REQUIRED)
+ find_package(PostgreSQL REQUIRED)
+ find_package(MySQL REQUIRED)
+ find_package(Poco REQUIRED COMPONENTS JSON Crypto JWT Net Util NetSSL Data DataSQLite DataPostgreSQL DataMySQL)
+endif()
+
+include_directories(/usr/local/include /usr/local/opt/openssl/include src include/kafka /usr/local/opt/mysql-client/include)
+
+configure_file(src/ow_version.h.in ${PROJECT_SOURCE_DIR}/src/ow_version.h @ONLY)
+
+add_executable(owanalytics
+ build
+ src/ow_version.h.in
+ src/framework/CountryCodes.h
+ src/framework/KafkaTopics.h
+ src/framework/MicroService.h
+ src/framework/OpenWifiTypes.h
+ src/framework/orm.h
+ src/framework/RESTAPI_errors.h
+ src/framework/RESTAPI_protocol.h
+ src/framework/StorageClass.h
+ src/framework/uCentral_Protocol.h
+ src/framework/ConfigurationValidator.cpp
+ src/framework/ConfigurationValidator.h
+ src/RESTObjects/RESTAPI_SecurityObjects.h src/RESTObjects/RESTAPI_SecurityObjects.cpp
+ src/RESTObjects/RESTAPI_ProvObjects.cpp src/RESTObjects/RESTAPI_ProvObjects.h
+ src/RESTObjects/RESTAPI_GWobjects.h src/RESTObjects/RESTAPI_GWobjects.cpp
+ src/RESTObjects/RESTAPI_FMSObjects.h src/RESTObjects/RESTAPI_FMSObjects.cpp
+ src/RESTAPI/RESTAPI_routers.cpp
+ src/Daemon.cpp src/Daemon.h
+ src/Dashboard.h src/Dashboard.cpp
+ src/StorageService.cpp src/StorageService.h src/RESTObjects/RESTAPI_AnalyticsObjects.cpp src/RESTObjects/RESTAPI_AnalyticsObjects.h)
+
+target_link_libraries(owanalytics PUBLIC
+ ${Poco_LIBRARIES} ${MySQL_LIBRARIES}
+ ${Boost_LIBRARIES}
+ ${ZLIB_LIBRARIES} ${AWSSDK_LINK_LIBRARIES}
+ CppKafka::cppkafka nlohmann_json_schema_validator)
+
diff --git a/build b/build
new file mode 100644
index 0000000..56a6051
--- /dev/null
+++ b/build
@@ -0,0 +1 @@
+1
\ No newline at end of file
diff --git a/owanalytics.properties b/owanalytics.properties
new file mode 100644
index 0000000..77182f6
--- /dev/null
+++ b/owanalytics.properties
@@ -0,0 +1,98 @@
+#
+# all your devices. You can replace the * for address by the specific
+# address of one of your interfaces
+#
+#
+# REST API access
+#
+openwifi.restapi.host.0.backlog = 100
+openwifi.restapi.host.0.security = relaxed
+openwifi.restapi.host.0.rootca = $OWANALYTICS_ROOT/certs/restapi-ca.pem
+openwifi.restapi.host.0.address = *
+openwifi.restapi.host.0.port = 16009
+openwifi.restapi.host.0.cert = $OWANALYTICS_ROOT/certs/restapi-cert.pem
+openwifi.restapi.host.0.key = $OWANALYTICS_ROOT/certs/restapi-key.pem
+openwifi.restapi.host.0.key.password = mypassword
+
+openwifi.internal.restapi.host.0.backlog = 100
+openwifi.internal.restapi.host.0.security = relaxed
+openwifi.internal.restapi.host.0.rootca = $OWANALYTICS_ROOT/certs/restapi-ca.pem
+openwifi.internal.restapi.host.0.address = *
+openwifi.internal.restapi.host.0.port = 17009
+openwifi.internal.restapi.host.0.cert = $OWANALYTICS_ROOT/certs/restapi-cert.pem
+openwifi.internal.restapi.host.0.key = $OWANALYTICS_ROOT/certs/restapi-key.pem
+openwifi.internal.restapi.host.0.key.password = mypassword
+
+#
+# Generic section that all microservices must have
+#
+openwifi.service.key = $OWANALYTICS_ROOT/certs/restapi-key.pem
+openwifi.service.key.password = mypassword
+openwifi.system.data = $OWANALYTICS_ROOT/data
+openwifi.system.debug = false
+openwifi.system.uri.private = https://localhost:17009
+openwifi.system.uri.public = https://ucentral.dpaas.arilia.com:16009
+openwifi.system.commandchannel = /tmp/app.owanalytics
+openwifi.system.uri.ui = owprov-ui.arilia.com
+
+#############################
+# Generic information for all micro services
+#############################
+#
+# NLB Support
+#
+alb.enable = true
+alb.port = 16105
+
+#
+# Kafka
+#
+openwifi.kafka.group.id = analytics
+openwifi.kafka.client.id = analytics1
+openwifi.kafka.enable = true
+openwifi.kafka.brokerlist = main.arilia.com:9093
+openwifi.kafka.auto.commit = false
+openwifi.kafka.queue.buffering.max.ms = 50
+
+#
+# This section select which form of persistence you need
+# Only one selected at a time. If you select multiple, this service will die if a horrible
+# death and might make your beer flat.
+#
+storage.type = sqlite
+#storage.type = postgresql
+#storage.type = mysql
+#storage.type = odbc
+
+storage.type.sqlite.db = prov.db
+storage.type.sqlite.idletime = 120
+storage.type.sqlite.maxsessions = 128
+
+storage.type.postgresql.maxsessions = 64
+storage.type.postgresql.idletime = 60
+storage.type.postgresql.host = localhost
+storage.type.postgresql.username = stephb
+storage.type.postgresql.password = snoopy99
+storage.type.postgresql.database = ucentral
+storage.type.postgresql.port = 5432
+storage.type.postgresql.connectiontimeout = 60
+
+storage.type.mysql.maxsessions = 64
+storage.type.mysql.idletime = 60
+storage.type.mysql.host = localhost
+storage.type.mysql.username = stephb
+storage.type.mysql.password = snoopy99
+storage.type.mysql.database = ucentral
+storage.type.mysql.port = 3306
+storage.type.mysql.connectiontimeout = 60
+
+
+########################################################################
+########################################################################
+#
+# Logging: please leave as is for now.
+#
+########################################################################
+logging.type = file
+logging.path = $OWANALYTICS_ROOT/logs
+logging.level = debug
\ No newline at end of file
diff --git a/owanalytics.service b/owanalytics.service
new file mode 100644
index 0000000..e145464
--- /dev/null
+++ b/owanalytics.service
@@ -0,0 +1,22 @@
+[Unit]
+Description=OpenWiFi Analytics Service
+After=network-online.target docker.service
+Wants=network-online.target
+
+[Service]
+Type=simple
+Environment="OWANALYTICS_ROOT=/home/admin/dev/wlan-cloud-analytics"
+ExecStart=/home/admin/dev/wlan-cloud-analytics/cmake-build/owanalytics
+WorkingDirectory=/home/admin/dev/wlan-cloud-analytics
+# ExecReload=/bin/kill -s HUP $MAINPID
+User=admin
+# TimeoutSec=0
+RestartSec=2
+Restart=always
+StartLimitBurst=3
+# KillMode=process
+LimitNOFILE=500000
+LimitNPROC=500000
+
+[Install]
+WantedBy=multi-user.target
diff --git a/set_env.sh b/set_env.sh
new file mode 100755
index 0000000..306c21c
--- /dev/null
+++ b/set_env.sh
@@ -0,0 +1,4 @@
+#!/bin/bash
+
+export OWANALYTICS_CONFIG=`pwd`
+export OWANALYTICS_ROOT=`pwd`
diff --git a/src/Daemon.cpp b/src/Daemon.cpp
new file mode 100644
index 0000000..ca576b0
--- /dev/null
+++ b/src/Daemon.cpp
@@ -0,0 +1,56 @@
+//
+// License type: BSD 3-Clause License
+// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
+//
+// Created by Stephane Bourque on 2021-03-04.
+// Arilia Wireless Inc.
+//
+
+#include
+#include "Poco/Util/Application.h"
+#include "Poco/Util/Option.h"
+#include "Poco/Environment.h"
+
+#include "Daemon.h"
+#include "StorageService.h"
+
+namespace OpenWifi {
+ class Daemon *Daemon::instance_ = nullptr;
+
+ class Daemon *Daemon::instance() {
+ if (instance_ == nullptr) {
+ instance_ = new Daemon(vDAEMON_PROPERTIES_FILENAME,
+ vDAEMON_ROOT_ENV_VAR,
+ vDAEMON_CONFIG_ENV_VAR,
+ vDAEMON_APP_NAME,
+ vDAEMON_BUS_TIMER,
+ SubSystemVec{
+ OpenWifi::StorageService()
+ });
+ }
+ return instance_;
+ }
+
+ void Daemon::initialize() {
+ }
+
+ void MicroServicePostInitialization() {
+ Daemon()->initialize();
+ }
+}
+
+int main(int argc, char **argv) {
+ try {
+ auto App = OpenWifi::Daemon::instance();
+ auto ExitCode = App->run(argc, argv);
+ delete App;
+
+ return ExitCode;
+
+ } catch (Poco::Exception &exc) {
+ std::cerr << exc.displayText() << std::endl;
+ return Poco::Util::Application::EXIT_SOFTWARE;
+ }
+}
+
+// end of namespace
\ No newline at end of file
diff --git a/src/Daemon.h b/src/Daemon.h
new file mode 100644
index 0000000..0b145e7
--- /dev/null
+++ b/src/Daemon.h
@@ -0,0 +1,51 @@
+//
+// License type: BSD 3-Clause License
+// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
+//
+// Created by Stephane Bourque on 2021-03-04.
+// Arilia Wireless Inc.
+//
+
+#pragma once
+
+#include
+#include
+#include
+#include
+#include
+
+#include "Dashboard.h"
+#include "framework/MicroService.h"
+#include "framework/OpenWifiTypes.h"
+#include "RESTObjects/RESTAPI_AnalyticsObjects.h"
+
+namespace OpenWifi {
+
+ static const char * vDAEMON_PROPERTIES_FILENAME = "owanalytics.properties";
+ static const char * vDAEMON_ROOT_ENV_VAR = "OWANALYTICS_ROOT";
+ static const char * vDAEMON_CONFIG_ENV_VAR = "OWANALYTICS_CONFIG";
+ static const char * vDAEMON_APP_NAME = uSERVICE_ANALYTICS.c_str() ;
+ static const uint64_t vDAEMON_BUS_TIMER = 10000;
+
+ class Daemon : public MicroService {
+ public:
+ explicit Daemon(const std::string & PropFile,
+ const std::string & RootEnv,
+ const std::string & ConfigEnv,
+ const std::string & AppName,
+ uint64_t BusTimer,
+ const SubSystemVec & SubSystems) :
+ MicroService( PropFile, RootEnv, ConfigEnv, AppName, BusTimer, SubSystems) {};
+
+ void initialize();
+ static Daemon *instance();
+ inline OpenWifi::AnalyticsDashboard & GetDashboard() { return DB_; }
+ Poco::Logger & Log() { return Poco::Logger::get(AppName()); }
+ private:
+ static Daemon *instance_;
+ OpenWifi::AnalyticsDashboard DB_{};
+ };
+
+ inline Daemon * Daemon() { return Daemon::instance(); }
+}
+
diff --git a/src/Dashboard.cpp b/src/Dashboard.cpp
new file mode 100644
index 0000000..4c05a02
--- /dev/null
+++ b/src/Dashboard.cpp
@@ -0,0 +1,21 @@
+//
+// License type: BSD 3-Clause License
+// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
+//
+// Created by Stephane Bourque on 2021-03-04.
+// Arilia Wireless Inc.
+//
+
+#include "Dashboard.h"
+#include "StorageService.h"
+
+namespace OpenWifi {
+ void AnalyticsDashboard::Create() {
+ uint64_t Now = std::time(nullptr);
+ if(LastRun_==0 || (Now-LastRun_)>120) {
+ DB_.reset();
+ // Todo: call dashboard creation code.
+ LastRun_ = Now;
+ }
+ }
+}
diff --git a/src/Dashboard.h b/src/Dashboard.h
new file mode 100644
index 0000000..598eb12
--- /dev/null
+++ b/src/Dashboard.h
@@ -0,0 +1,23 @@
+//
+// License type: BSD 3-Clause License
+// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
+//
+// Created by Stephane Bourque on 2021-03-04.
+// Arilia Wireless Inc.
+//
+#pragma once
+
+#include "framework/OpenWifiTypes.h"
+#include "RESTObjects/RESTAPI_AnalyticsObjects.h"
+
+namespace OpenWifi {
+ class AnalyticsDashboard {
+ public:
+ void Create();
+ [[nodiscard]] const AnalyticsObjects::Report & Report() const { return DB_;}
+ inline void Reset() { LastRun_=0; DB_.reset(); }
+ private:
+ AnalyticsObjects::Report DB_{};
+ uint64_t LastRun_=0;
+ };
+}
diff --git a/src/RESTAPI/RESTAPI_routers.cpp b/src/RESTAPI/RESTAPI_routers.cpp
new file mode 100644
index 0000000..355398e
--- /dev/null
+++ b/src/RESTAPI/RESTAPI_routers.cpp
@@ -0,0 +1,23 @@
+//
+// Created by stephane bourque on 2021-10-23.
+//
+
+#include "framework/MicroService.h"
+
+namespace OpenWifi {
+
+ Poco::Net::HTTPRequestHandler * RESTAPI_ExtRouter(const char *Path, RESTAPIHandler::BindingMap &Bindings,
+ Poco::Logger & L, RESTAPI_GenericServer & S, uint64_t TransactionId) {
+ return RESTAPI_Router<
+ RESTAPI_system_command
+ >(Path,Bindings,L, S, TransactionId);
+ }
+
+ Poco::Net::HTTPRequestHandler * RESTAPI_IntRouter(const char *Path, RESTAPIHandler::BindingMap &Bindings,
+ Poco::Logger & L, RESTAPI_GenericServer & S, uint64_t TransactionId) {
+ return RESTAPI_Router_I<
+ RESTAPI_system_command
+ >(Path, Bindings, L, S, TransactionId);
+ }
+
+}
\ No newline at end of file
diff --git a/src/RESTObjects/RESTAPI_AnalyticsObjects.cpp b/src/RESTObjects/RESTAPI_AnalyticsObjects.cpp
new file mode 100644
index 0000000..1ca24a2
--- /dev/null
+++ b/src/RESTObjects/RESTAPI_AnalyticsObjects.cpp
@@ -0,0 +1,18 @@
+//
+// Created by stephane bourque on 2022-01-10.
+//
+
+#include "RESTAPI_AnalyticsObjects.h"
+
+
+namespace OpenWifi::AnalyticsObjects {
+
+ void Report::reset() {
+
+ }
+
+ void Report::to_json(Poco::JSON::Object &Obj) const {
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/RESTObjects/RESTAPI_AnalyticsObjects.h b/src/RESTObjects/RESTAPI_AnalyticsObjects.h
new file mode 100644
index 0000000..c82b3a7
--- /dev/null
+++ b/src/RESTObjects/RESTAPI_AnalyticsObjects.h
@@ -0,0 +1,22 @@
+//
+// Created by stephane bourque on 2022-01-10.
+//
+
+#pragma once
+#include "framework/MicroService.h"
+
+namespace OpenWifi {
+
+ namespace AnalyticsObjects {
+
+ struct Report {
+ uint64_t snapShot=0;
+ Types::CountedMap tenants;
+
+ void reset();
+ void to_json(Poco::JSON::Object &Obj) const;
+ };
+
+ }
+
+}
\ No newline at end of file
diff --git a/src/RESTObjects/RESTAPI_CertObjects.cpp b/src/RESTObjects/RESTAPI_CertObjects.cpp
new file mode 100644
index 0000000..f3aca35
--- /dev/null
+++ b/src/RESTObjects/RESTAPI_CertObjects.cpp
@@ -0,0 +1,178 @@
+//
+// Created by stephane bourque on 2021-12-07.
+//
+
+#include "RESTAPI_CertObjects.h"
+
+using OpenWifi::RESTAPI_utils::field_to_json;
+using OpenWifi::RESTAPI_utils::field_from_json;
+
+namespace OpenWifi {
+ namespace CertObjects {
+ void CertificateEntry::to_json(Poco::JSON::Object &Obj) const {
+ field_to_json(Obj,"id", id);
+ field_to_json(Obj,"entity", entity);
+ field_to_json(Obj,"creator", creator);
+ field_to_json(Obj,"type", type);
+ field_to_json(Obj,"status", status);
+ field_to_json(Obj,"certificate", certificate);
+ field_to_json(Obj,"key", key);
+ field_to_json(Obj,"devid", devid);
+ field_to_json(Obj,"cas", cas);
+ field_to_json(Obj,"manufacturer", manufacturer);
+ field_to_json(Obj,"model", model);
+ field_to_json(Obj,"redirector", redirector);
+ field_to_json(Obj,"commonName", commonName);
+ field_to_json(Obj,"certificateId", certificateId);
+ field_to_json(Obj,"batch", batch);
+ field_to_json(Obj,"created", created);
+ field_to_json(Obj,"modified", modified);
+ field_to_json(Obj,"revoked", revoked);
+ field_to_json(Obj,"revokeCount", revokeCount);
+ }
+
+ bool CertificateEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
+ try {
+ field_from_json(Obj,"id", id);
+ field_from_json(Obj,"entity", entity);
+ field_from_json(Obj,"creator", creator);
+ field_from_json(Obj,"type", type);
+ field_from_json(Obj,"status", status);
+ field_from_json(Obj,"certificate", certificate);
+ field_from_json(Obj,"key", key);
+ field_from_json(Obj,"devid", devid);
+ field_from_json(Obj,"cas", cas);
+ field_from_json(Obj,"manufacturer", manufacturer);
+ field_from_json(Obj,"model", model);
+ field_from_json(Obj,"redirector", redirector);
+ field_from_json(Obj,"commonName", commonName);
+ field_from_json(Obj,"certificateId", certificateId);
+ field_from_json(Obj,"batch", batch);
+ field_from_json(Obj,"created", created);
+ field_from_json(Obj,"modified", modified);
+ field_from_json(Obj,"revoked", revoked);
+ field_from_json(Obj,"revokeCount", revokeCount);
+ return true;
+ } catch (...) {
+ }
+ return false;
+ }
+
+ void EntityEntry::to_json(Poco::JSON::Object &Obj) const {
+ field_to_json(Obj,"id", id);
+ field_to_json(Obj,"creator", creator);
+ field_to_json(Obj,"name", name);
+ field_to_json(Obj,"description", description);
+ field_to_json(Obj,"defaultRedirector", defaultRedirector);
+ field_to_json(Obj,"apiKey", apiKey);
+ field_to_json(Obj,"serverEnrollmentProfile", serverEnrollmentProfile);
+ field_to_json(Obj,"clientEnrollmentProfile", clientEnrollmentProfile);
+ field_to_json(Obj,"organization", organization);
+ field_to_json(Obj,"created", created);
+ field_to_json(Obj,"modified", modified);
+ field_to_json(Obj,"suspended", suspended);
+ field_to_json(Obj,"deleted", deleted);
+ field_to_json(Obj,"notes", notes);
+ }
+
+ bool EntityEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
+ try {
+ field_from_json(Obj,"id", id);
+ field_from_json(Obj,"creator", creator);
+ field_from_json(Obj,"name", name);
+ field_from_json(Obj,"description", description);
+ field_from_json(Obj,"defaultRedirector", defaultRedirector);
+ field_from_json(Obj,"apiKey", apiKey);
+ field_from_json(Obj,"serverEnrollmentProfile", serverEnrollmentProfile);
+ field_from_json(Obj,"clientEnrollmentProfile", clientEnrollmentProfile);
+ field_from_json(Obj,"organization", organization);
+ field_from_json(Obj,"created", created);
+ field_from_json(Obj,"modified", modified);
+ field_from_json(Obj,"suspended", suspended);
+ field_from_json(Obj,"deleted", deleted);
+ field_from_json(Obj,"notes", notes);
+ return true;
+ } catch (...) {
+ }
+ return false;
+ }
+
+ void BatchEntry::to_json(Poco::JSON::Object &Obj) const {
+ field_to_json(Obj,"id", id);
+ field_to_json(Obj,"entity", entity);
+ field_to_json(Obj,"creator", creator);
+ field_to_json(Obj,"name", name);
+ field_to_json(Obj,"description", description);
+ field_to_json(Obj,"manufacturer", manufacturer);
+ field_to_json(Obj,"model", model);
+ field_to_json(Obj,"redirector", redirector);
+ field_to_json(Obj,"commonNames", commonNames);
+ field_to_json(Obj,"jobHistory", jobHistory);
+ field_to_json(Obj,"notes", notes);
+ field_to_json(Obj,"submitted", submitted);
+ field_to_json(Obj,"started", started);
+ field_to_json(Obj,"completed", completed);
+ field_to_json(Obj,"modified", modified);
+ }
+
+ bool BatchEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
+ try {
+ field_from_json(Obj,"id", id);
+ field_from_json(Obj,"entity", entity);
+ field_from_json(Obj,"creator", creator);
+ field_from_json(Obj,"name", name);
+ field_from_json(Obj,"description", description);
+ field_from_json(Obj,"manufacturer", manufacturer);
+ field_from_json(Obj,"model", model);
+ field_from_json(Obj,"redirector", redirector);
+ field_from_json(Obj,"commonNames", commonNames);
+ field_from_json(Obj,"jobHistory", jobHistory);
+ field_from_json(Obj,"notes", notes);
+ field_from_json(Obj,"submitted", submitted);
+ field_from_json(Obj,"started", started);
+ field_from_json(Obj,"completed", completed);
+ field_from_json(Obj,"modified", modified);
+ return true;
+ } catch (...) {
+ }
+ return false;
+ }
+
+ void JobEntry::to_json(Poco::JSON::Object &Obj) const {
+ field_to_json(Obj,"id", id);
+ field_to_json(Obj,"entity", entity);
+ field_to_json(Obj,"creator", creator);
+ field_to_json(Obj,"batch", batch);
+ field_to_json(Obj,"commonNames", commonNames);
+ field_to_json(Obj,"completedNames", completedNames);
+ field_to_json(Obj,"errorNames", errorNames);
+ field_to_json(Obj,"status", status);
+ field_to_json(Obj,"command", command);
+ field_to_json(Obj,"parameters", parameters);
+ field_to_json(Obj,"submitted", submitted);
+ field_to_json(Obj,"started", started);
+ field_to_json(Obj,"completed", completed);
+ }
+
+ bool JobEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
+ try {
+ field_from_json(Obj,"id", id);
+ field_from_json(Obj,"entity", entity);
+ field_from_json(Obj,"creator", creator);
+ field_from_json(Obj,"batch", batch);
+ field_from_json(Obj,"commonNames", commonNames);
+ field_from_json(Obj,"completedNames", completedNames);
+ field_from_json(Obj,"errorNames", errorNames);
+ field_from_json(Obj,"status", status);
+ field_from_json(Obj,"command", command);
+ field_from_json(Obj,"parameters", parameters);
+ field_from_json(Obj,"submitted", submitted);
+ field_from_json(Obj,"started", started);
+ field_from_json(Obj,"completed", completed);
+ return true;
+ } catch (...) {
+ }
+ return false;
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/RESTObjects/RESTAPI_CertObjects.h b/src/RESTObjects/RESTAPI_CertObjects.h
new file mode 100644
index 0000000..aeed486
--- /dev/null
+++ b/src/RESTObjects/RESTAPI_CertObjects.h
@@ -0,0 +1,101 @@
+//
+// Created by stephane bourque on 2021-12-07.
+//
+
+#pragma once
+
+#include
+#include "framework/MicroService.h"
+#include "framework/OpenWifiTypes.h"
+#include "RESTObjects/RESTAPI_SecurityObjects.h"
+
+namespace OpenWifi {
+
+ namespace CertObjects {
+
+ struct CertificateEntry {
+ OpenWifi::Types::UUID_t id;
+ OpenWifi::Types::UUID_t entity;
+ OpenWifi::Types::UUID_t creator;
+ std::string type;
+ std::string status;
+ std::string certificate;
+ std::string key;
+ std::string devid;
+ std::string cas;
+ std::string manufacturer;
+ std::string model;
+ std::string redirector;
+ std::string commonName;
+ std::string certificateId;
+ OpenWifi::Types::UUID_t batch;
+ uint64_t created = 0;
+ uint64_t modified = 0;
+ uint64_t revoked = 0;
+ uint64_t revokeCount = 0;
+
+ void to_json(Poco::JSON::Object &Obj) const;
+ bool from_json(const Poco::JSON::Object::Ptr &Obj);
+ };
+
+ struct EntityEntry {
+ OpenWifi::Types::UUID_t id;
+ OpenWifi::Types::UUID_t creator;
+ std::string name;
+ std::string description;
+ std::string defaultRedirector;
+ std::string apiKey;
+ std::string serverEnrollmentProfile;
+ std::string clientEnrollmentProfile;
+ std::string organization;
+ SecurityObjects::NoteInfoVec notes;
+ bool suspended=false;
+ bool deleted=false;
+ uint64_t created = 0 ;
+ uint64_t modified = 0 ;
+
+ void to_json(Poco::JSON::Object &Obj) const;
+ bool from_json(const Poco::JSON::Object::Ptr &Obj);
+ };
+
+ struct BatchEntry {
+ OpenWifi::Types::UUID_t id;
+ OpenWifi::Types::UUID_t entity;
+ OpenWifi::Types::UUID_t creator;
+ std::string name;
+ std::string description;
+ std::string manufacturer;
+ std::string model;
+ std::string redirector;
+ std::vector commonNames;
+ std::vector jobHistory;
+ SecurityObjects::NoteInfoVec notes;
+ uint64_t submitted = 0 ;
+ uint64_t started = 0 ;
+ uint64_t completed = 0 ;
+ uint64_t modified = 0 ;
+
+ void to_json(Poco::JSON::Object &Obj) const;
+ bool from_json(const Poco::JSON::Object::Ptr &Obj);
+ };
+
+ struct JobEntry {
+ OpenWifi::Types::UUID_t id;
+ OpenWifi::Types::UUID_t entity;
+ OpenWifi::Types::UUID_t creator;
+ OpenWifi::Types::UUID_t batch;
+ std::string command;
+ OpenWifi::Types::StringVec commonNames;
+ OpenWifi::Types::StringVec completedNames;
+ OpenWifi::Types::StringVec errorNames;
+ Types::StringPairVec parameters;
+ std::string status;
+ uint64_t submitted=0;
+ uint64_t started=0;
+ uint64_t completed=0;
+
+ void to_json(Poco::JSON::Object &Obj) const;
+ bool from_json(const Poco::JSON::Object::Ptr &Obj);
+ };
+ }
+}
\ No newline at end of file
diff --git a/src/RESTObjects/RESTAPI_FMSObjects.cpp b/src/RESTObjects/RESTAPI_FMSObjects.cpp
new file mode 100644
index 0000000..78d0062
--- /dev/null
+++ b/src/RESTObjects/RESTAPI_FMSObjects.cpp
@@ -0,0 +1,248 @@
+//
+// Created by stephane bourque on 2021-07-12.
+//
+
+#include "RESTAPI_FMSObjects.h"
+#include "framework/MicroService.h"
+
+using OpenWifi::RESTAPI_utils::field_to_json;
+using OpenWifi::RESTAPI_utils::field_from_json;
+
+namespace OpenWifi::FMSObjects {
+
+ void Firmware::to_json(Poco::JSON::Object &Obj) const {
+ field_to_json(Obj, "id", id);
+ field_to_json(Obj, "release", release);
+ field_to_json(Obj, "deviceType", deviceType);
+ field_to_json(Obj, "description", description);
+ field_to_json(Obj, "revision", revision);
+ field_to_json(Obj, "uri", uri);
+ field_to_json(Obj, "image", image);
+ field_to_json(Obj, "imageDate", imageDate);
+ field_to_json(Obj, "size", size);
+ field_to_json(Obj, "downloadCount", downloadCount);
+ field_to_json(Obj, "firmwareHash", firmwareHash);
+ field_to_json(Obj, "owner", owner);
+ field_to_json(Obj, "location", location);
+ field_to_json(Obj, "uploader", uploader);
+ field_to_json(Obj, "digest", digest);
+ field_to_json(Obj, "latest", latest);
+ field_to_json(Obj, "notes", notes);
+ field_to_json(Obj, "created", created);
+ };
+
+ bool Firmware::from_json(const Poco::JSON::Object::Ptr &Obj) {
+ try {
+ field_from_json(Obj, "id", id);
+ field_from_json(Obj, "release", release);
+ field_from_json(Obj, "deviceType", deviceType);
+ field_from_json(Obj, "description", description);
+ field_from_json(Obj, "revision", revision);
+ field_from_json(Obj, "uri", uri);
+ field_from_json(Obj, "image", image);
+ field_from_json(Obj, "imageDate", imageDate);
+ field_from_json(Obj, "size", size);
+ field_from_json(Obj, "downloadCount", downloadCount);
+ field_from_json(Obj, "firmwareHash", firmwareHash);
+ field_from_json(Obj, "owner", owner);
+ field_from_json(Obj, "location", location);
+ field_from_json(Obj, "uploader", uploader);
+ field_from_json(Obj, "digest", digest);
+ field_from_json(Obj, "latest", latest);
+ field_from_json(Obj, "notes", notes);
+ field_from_json(Obj, "created", created);
+ return true;
+ } catch (...) {
+
+ }
+ return true;
+ }
+
+ void FirmwareList::to_json(Poco::JSON::Object &Obj) const {
+ field_to_json(Obj,"firmwares",firmwares);
+ }
+
+ bool FirmwareList::from_json(const Poco::JSON::Object::Ptr &Obj) {
+ try {
+ field_from_json(Obj, "firmwares", firmwares);
+ return true;
+ } catch (...) {
+
+ }
+ return false;
+ }
+
+ void DeviceType::to_json(Poco::JSON::Object &Obj) const {
+ field_to_json(Obj, "id", id);
+ field_to_json(Obj, "deviceType", deviceType);
+ field_to_json(Obj, "manufacturer", manufacturer);
+ field_to_json(Obj, "model", model);
+ field_to_json(Obj, "policy", policy);
+ field_to_json(Obj, "notes", notes);
+ field_to_json(Obj, "lastUpdate", lastUpdate);
+ field_to_json(Obj, "created", created);
+ field_to_json(Obj, "id", id);
+ field_to_json(Obj, "id", id);
+ field_to_json(Obj, "id", id);
+ }
+
+ bool DeviceType::from_json(const Poco::JSON::Object::Ptr &Obj) {
+ try {
+ field_from_json(Obj, "id", id);
+ field_from_json(Obj, "deviceType", deviceType);
+ field_from_json(Obj, "manufacturer", manufacturer);
+ field_from_json(Obj, "model", model);
+ field_from_json(Obj, "policy", policy);
+ field_from_json(Obj, "notes", notes);
+ field_from_json(Obj, "lastUpdate", lastUpdate);
+ field_from_json(Obj, "created", created);
+ field_from_json(Obj, "id", id);
+ field_from_json(Obj, "id", id);
+ field_from_json(Obj, "id", id);
+ return true;
+ } catch (...) {
+
+ }
+ return false;
+ }
+
+ void DeviceTypeList::to_json(Poco::JSON::Object &Obj) const {
+ field_to_json(Obj,"deviceTypes", deviceTypes);
+ }
+
+ bool DeviceTypeList::from_json(const Poco::JSON::Object::Ptr &Obj) {
+ try {
+ field_from_json(Obj,"deviceTypes", deviceTypes);
+ return true;
+ } catch(...) {
+
+ }
+ return false;
+ }
+
+ void RevisionHistoryEntry::to_json(Poco::JSON::Object &Obj) const {
+ field_to_json(Obj, "id", id);
+ field_to_json(Obj, "serialNumber", serialNumber);
+ field_to_json(Obj, "fromRelease", fromRelease);
+ field_to_json(Obj, "toRelease", toRelease);
+ field_to_json(Obj, "commandUUID", commandUUID);
+ field_to_json(Obj, "revisionId", revisionId);
+ field_to_json(Obj, "upgraded", upgraded);
+ }
+
+ bool RevisionHistoryEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
+ try {
+ field_from_json(Obj, "id", id);
+ field_from_json(Obj, "serialNumber", serialNumber);
+ field_from_json(Obj, "fromRelease", fromRelease);
+ field_from_json(Obj, "toRelease", toRelease);
+ field_from_json(Obj, "commandUUID", commandUUID);
+ field_from_json(Obj, "revisionId", revisionId);
+ field_from_json(Obj, "upgraded", upgraded);
+ return true;
+ } catch(...) {
+
+ }
+ return false;
+ }
+
+ void RevisionHistoryEntryList::to_json(Poco::JSON::Object &Obj) const {
+ field_to_json(Obj,"deviceTypes", history);
+ }
+
+ bool RevisionHistoryEntryList::from_json(const Poco::JSON::Object::Ptr &Obj) {
+ try {
+ field_from_json(Obj,"deviceTypes", history);
+ return true;
+ } catch(...) {
+
+ }
+ return false;
+ }
+
+ void FirmwareAgeDetails::to_json(Poco::JSON::Object &Obj) const {
+ field_to_json(Obj,"latestId", latestId);
+ field_to_json(Obj,"image", image);
+ field_to_json(Obj,"imageDate", imageDate);
+ field_to_json(Obj,"revision", revision);
+ field_to_json(Obj,"uri", uri);
+ field_to_json(Obj,"age", age);
+ field_to_json(Obj,"latest",latest);
+ }
+
+ bool FirmwareAgeDetails::from_json(const Poco::JSON::Object::Ptr &Obj) {
+ try {
+ field_from_json(Obj,"latestId", latestId);
+ field_from_json(Obj,"image", image);
+ field_from_json(Obj,"imageDate", imageDate);
+ field_from_json(Obj,"revision", revision);
+ field_from_json(Obj,"uri", uri);
+ field_from_json(Obj,"age", age);
+ field_from_json(Obj,"latest", latest);
+ return true;
+ } catch(...) {
+
+ }
+ return false;
+ }
+
+ void DeviceConnectionInformation::to_json(Poco::JSON::Object &Obj) const {
+ field_to_json(Obj, "serialNumber", serialNumber);
+ field_to_json(Obj, "revision", revision);
+ field_to_json(Obj, "deviceType", deviceType);
+ field_to_json(Obj, "endPoint", endPoint);
+ field_to_json(Obj, "lastUpdate", lastUpdate);
+ field_to_json(Obj, "status", status);
+ }
+
+ bool DeviceConnectionInformation::from_json(const Poco::JSON::Object::Ptr &Obj) {
+ try {
+ field_from_json(Obj, "serialNumber", serialNumber);
+ field_from_json(Obj, "revision", revision);
+ field_from_json(Obj, "deviceType", deviceType);
+ field_from_json(Obj, "endPoint", endPoint);
+ field_from_json(Obj, "lastUpdate", lastUpdate);
+ field_from_json(Obj, "status", status);
+ return true;
+ } catch(...) {
+
+ }
+ return false;
+ }
+
+ void DeviceReport::to_json(Poco::JSON::Object &Obj) const {
+ field_to_json(Obj, "ouis",OUI_);
+ field_to_json(Obj, "revisions", Revisions_);
+ field_to_json(Obj, "deviceTypes", DeviceTypes_);
+ field_to_json(Obj, "status", Status_);
+ field_to_json(Obj, "endPoints", EndPoints_);
+ field_to_json(Obj, "usingLatest", UsingLatest_);
+ field_to_json(Obj, "unknownFirmwares", UnknownFirmwares_);
+ field_to_json(Obj,"snapshot",snapshot);
+ field_to_json(Obj,"numberOfDevices",numberOfDevices);
+ field_to_json(Obj, "totalSecondsOld", totalSecondsOld_);
+ }
+
+ void DeviceReport::reset() {
+ OUI_.clear();
+ Revisions_.clear();
+ DeviceTypes_.clear();
+ Status_.clear();
+ EndPoints_.clear();
+ UsingLatest_.clear();
+ UnknownFirmwares_.clear();
+ totalSecondsOld_.clear();
+ numberOfDevices = 0 ;
+ snapshot = std::time(nullptr);
+ }
+
+ bool DeviceReport::from_json(const Poco::JSON::Object::Ptr &Obj) {
+ try {
+
+ return true;
+ } catch (...) {
+
+ }
+ return false;
+ }
+}
diff --git a/src/RESTObjects/RESTAPI_FMSObjects.h b/src/RESTObjects/RESTAPI_FMSObjects.h
new file mode 100644
index 0000000..366523e
--- /dev/null
+++ b/src/RESTObjects/RESTAPI_FMSObjects.h
@@ -0,0 +1,133 @@
+//
+// Created by stephane bourque on 2021-07-12.
+//
+
+#include
+
+#ifndef UCENTRALFMS_RESTAPI_FMSOBJECTS_H
+#define UCENTRALFMS_RESTAPI_FMSOBJECTS_H
+
+
+#include "RESTAPI_SecurityObjects.h"
+#include "framework/OpenWifiTypes.h"
+
+namespace OpenWifi::FMSObjects {
+
+ struct Firmware {
+ std::string id;
+ std::string release;
+ std::string deviceType;
+ std::string description;
+ std::string revision;
+ std::string uri;
+ std::string image;
+ uint64_t imageDate=0;
+ uint64_t size=0;
+ uint64_t downloadCount=0;
+ std::string firmwareHash;
+ std::string owner;
+ std::string location;
+ std::string uploader;
+ std::string digest;
+ bool latest=0;
+ SecurityObjects::NoteInfoVec notes;
+ uint64_t created=0;
+
+ void to_json(Poco::JSON::Object &Obj) const;
+ bool from_json(const Poco::JSON::Object::Ptr &Obj);
+ };
+ typedef std::vector FirmwareVec;
+
+ struct FirmwareList {
+ FirmwareVec firmwares;
+
+ void to_json(Poco::JSON::Object &Obj) const;
+ bool from_json(const Poco::JSON::Object::Ptr &Obj);
+ };
+
+ struct DeviceType {
+ std::string id;
+ std::string deviceType;
+ std::string manufacturer;
+ std::string model;
+ std::string policy;
+ SecurityObjects::NoteInfoVec notes;
+ uint64_t lastUpdate=0;
+ uint64_t created=0;
+
+ void to_json(Poco::JSON::Object &Obj) const;
+ bool from_json(const Poco::JSON::Object::Ptr &Obj);
+ };
+ typedef std::vector DeviceTypeVec;
+
+ struct DeviceTypeList {
+ DeviceTypeVec deviceTypes;
+
+ void to_json(Poco::JSON::Object &Obj) const;
+ bool from_json(const Poco::JSON::Object::Ptr &Obj);
+ };
+
+ struct RevisionHistoryEntry {
+ std::string id;
+ std::string serialNumber;
+ std::string fromRelease;
+ std::string toRelease;
+ std::string commandUUID;
+ std::string revisionId;
+ uint64_t upgraded;
+
+ void to_json(Poco::JSON::Object &Obj) const;
+ bool from_json(const Poco::JSON::Object::Ptr &Obj);
+ };
+ typedef std::vector RevisionHistoryEntryVec;
+
+ struct RevisionHistoryEntryList {
+ RevisionHistoryEntryVec history;
+
+ void to_json(Poco::JSON::Object &Obj) const;
+ bool from_json(const Poco::JSON::Object::Ptr &Obj);
+ };
+
+ struct FirmwareAgeDetails {
+ std::string latestId;
+ std::string image;
+ uint64_t imageDate;
+ std::string revision;
+ std::string uri;
+ uint64_t age=0;
+ bool latest=true;
+
+ void to_json(Poco::JSON::Object &Obj) const;
+ bool from_json(const Poco::JSON::Object::Ptr &Obj);
+ };
+
+ struct DeviceConnectionInformation {
+ std::string serialNumber;
+ std::string revision;
+ std::string deviceType;
+ std::string endPoint;
+ uint64_t lastUpdate;
+ std::string status;
+ void to_json(Poco::JSON::Object &Obj) const;
+ bool from_json(const Poco::JSON::Object::Ptr &Obj);
+ };
+
+ struct DeviceReport {
+ uint64_t snapshot=0;
+ uint64_t numberOfDevices=0;
+ Types::CountedMap OUI_;
+ Types::CountedMap Revisions_;
+ Types::CountedMap DeviceTypes_;
+ Types::CountedMap Status_;
+ Types::CountedMap EndPoints_;
+ Types::CountedMap UsingLatest_;
+ Types::CountedMap UnknownFirmwares_;
+ Types::CountedMap totalSecondsOld_;
+ void to_json(Poco::JSON::Object &Obj) const;
+ void reset();
+ bool from_json(const Poco::JSON::Object::Ptr &Obj);
+ };
+}
+
+
+#endif //UCENTRALFMS_RESTAPI_FMSOBJECTS_H
diff --git a/src/RESTObjects/RESTAPI_GWobjects.cpp b/src/RESTObjects/RESTAPI_GWobjects.cpp
new file mode 100644
index 0000000..be66a0a
--- /dev/null
+++ b/src/RESTObjects/RESTAPI_GWobjects.cpp
@@ -0,0 +1,269 @@
+//
+// License type: BSD 3-Clause License
+// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
+//
+// Created by Stephane Bourque on 2021-03-04.
+// Arilia Wireless Inc.
+//
+
+#include "Poco/JSON/Parser.h"
+#include "Poco/JSON/Stringifier.h"
+
+#include "Daemon.h"
+#ifdef TIP_GATEWAY_SERVICE
+#include "DeviceRegistry.h"
+#include "CapabilitiesCache.h"
+#endif
+
+#include "RESTAPI_GWobjects.h"
+#include "framework/MicroService.h"
+
+using OpenWifi::RESTAPI_utils::field_to_json;
+using OpenWifi::RESTAPI_utils::field_from_json;
+using OpenWifi::RESTAPI_utils::EmbedDocument;
+
+namespace OpenWifi::GWObjects {
+
+ void Device::to_json(Poco::JSON::Object &Obj) const {
+ field_to_json(Obj,"serialNumber", SerialNumber);
+#ifdef TIP_GATEWAY_SERVICE
+ field_to_json(Obj,"deviceType", CapabilitiesCache::instance()->Get(Compatible));
+#endif
+ field_to_json(Obj,"macAddress", MACAddress);
+ field_to_json(Obj,"manufacturer", Manufacturer);
+ field_to_json(Obj,"UUID", UUID);
+ EmbedDocument("configuration", Obj, Configuration);
+ field_to_json(Obj,"notes", Notes);
+ field_to_json(Obj,"createdTimestamp", CreationTimestamp);
+ field_to_json(Obj,"lastConfigurationChange", LastConfigurationChange);
+ field_to_json(Obj,"lastConfigurationDownload", LastConfigurationDownload);
+ field_to_json(Obj,"lastFWUpdate", LastFWUpdate);
+ field_to_json(Obj,"owner", Owner);
+ field_to_json(Obj,"location", Location);
+ field_to_json(Obj,"venue", Venue);
+ field_to_json(Obj,"firmware", Firmware);
+ field_to_json(Obj,"compatible", Compatible);
+ field_to_json(Obj,"fwUpdatePolicy", FWUpdatePolicy);
+ field_to_json(Obj,"devicePassword", DevicePassword);
+ }
+
+ void Device::to_json_with_status(Poco::JSON::Object &Obj) const {
+ to_json(Obj);
+
+#ifdef TIP_GATEWAY_SERVICE
+ ConnectionState ConState;
+
+ if (DeviceRegistry()->GetState(SerialNumber, ConState)) {
+ ConState.to_json(Obj);
+ } else {
+ field_to_json(Obj,"ipAddress", "");
+ field_to_json(Obj,"txBytes", (uint64_t) 0);
+ field_to_json(Obj,"rxBytes", (uint64_t )0);
+ field_to_json(Obj,"messageCount", (uint64_t )0);
+ field_to_json(Obj,"connected", false);
+ field_to_json(Obj,"lastContact", "");
+ field_to_json(Obj,"verifiedCertificate", "NO_CERTIFICATE");
+ field_to_json(Obj,"associations_2G", (uint64_t) 0);
+ field_to_json(Obj,"associations_5G", (uint64_t) 0);
+ }
+#endif
+ }
+
+ bool Device::from_json(Poco::JSON::Object::Ptr &Obj) {
+ try {
+ field_from_json(Obj,"serialNumber",SerialNumber);
+ field_from_json(Obj,"deviceType",DeviceType);
+ field_from_json(Obj,"macAddress",MACAddress);
+ field_from_json(Obj,"configuration",Configuration);
+ field_from_json(Obj,"notes",Notes);
+ field_from_json(Obj,"manufacturer",Manufacturer);
+ field_from_json(Obj,"owner",Owner);
+ field_from_json(Obj,"location",Location);
+ field_from_json(Obj,"venue",Venue);
+ field_from_json(Obj,"compatible",Compatible);
+ return true;
+ } catch (const Poco::Exception &E) {
+ }
+ return false;
+ }
+
+ void Device::Print() const {
+ std::cout << "Device: " << SerialNumber << " DeviceType:" << DeviceType << " MACAddress:" << MACAddress << " Manufacturer:"
+ << Manufacturer << " " << Configuration << std::endl;
+ }
+
+ void Statistics::to_json(Poco::JSON::Object &Obj) const {
+ EmbedDocument("data", Obj, Data);
+ field_to_json(Obj,"UUID", UUID);
+ field_to_json(Obj,"recorded", Recorded);
+ }
+
+ void Capabilities::to_json(Poco::JSON::Object &Obj) const {
+ EmbedDocument("capabilities", Obj, Capabilities);
+ field_to_json(Obj,"firstUpdate", FirstUpdate);
+ field_to_json(Obj,"lastUpdate", LastUpdate);
+ }
+
+ void DeviceLog::to_json(Poco::JSON::Object &Obj) const {
+ EmbedDocument("data", Obj, Data);
+ field_to_json(Obj,"log", Log);
+ field_to_json(Obj,"severity", Severity);
+ field_to_json(Obj,"recorded", Recorded);
+ field_to_json(Obj,"logType", LogType);
+ field_to_json(Obj,"UUID", UUID);
+ }
+
+ void HealthCheck::to_json(Poco::JSON::Object &Obj) const {
+ EmbedDocument("values", Obj, Data);
+ field_to_json(Obj,"UUID", UUID);
+ field_to_json(Obj,"sanity", Sanity);
+ field_to_json(Obj,"recorded", Recorded);
+ }
+
+ void DefaultConfiguration::to_json(Poco::JSON::Object &Obj) const {
+ EmbedDocument("configuration", Obj, Configuration);
+ field_to_json(Obj,"name", Name);
+ field_to_json(Obj,"modelIds", Models);
+ field_to_json(Obj,"description", Description);
+ field_to_json(Obj,"created", Created);
+ field_to_json(Obj,"lastModified", LastModified);
+ }
+
+ void CommandDetails::to_json(Poco::JSON::Object &Obj) const {
+ EmbedDocument("details", Obj, Details);
+ EmbedDocument("results", Obj, Results);
+ field_to_json(Obj,"UUID", UUID);
+ field_to_json(Obj,"serialNumber", SerialNumber);
+ field_to_json(Obj,"command", Command);
+ field_to_json(Obj,"errorText", ErrorText);
+ field_to_json(Obj,"submittedBy", SubmittedBy);
+ field_to_json(Obj,"status", Status);
+ field_to_json(Obj,"submitted", Submitted);
+ field_to_json(Obj,"executed", Executed);
+ field_to_json(Obj,"completed", Completed);
+ field_to_json(Obj,"when", RunAt);
+ field_to_json(Obj,"errorCode", ErrorCode);
+ field_to_json(Obj,"custom", Custom);
+ field_to_json(Obj,"waitingForFile", WaitingForFile);
+ field_to_json(Obj,"attachFile", AttachDate);
+ field_to_json(Obj,"executionTime", executionTime);
+ }
+
+ bool DefaultConfiguration::from_json(Poco::JSON::Object::Ptr &Obj) {
+ try {
+ field_from_json(Obj,"name",Name);
+ field_from_json(Obj,"configuration",Configuration);
+ field_from_json(Obj,"modelIds",Models);
+ field_from_json(Obj,"description",Description);
+ return true;
+ } catch (const Poco::Exception &E) {
+ }
+ return false;
+ }
+
+ void BlackListedDevice::to_json(Poco::JSON::Object &Obj) const {
+ field_to_json(Obj,"serialNumber", serialNumber);
+ field_to_json(Obj,"author", author);
+ field_to_json(Obj,"reason", reason);
+ field_to_json(Obj,"created", created);
+ }
+
+ bool BlackListedDevice::from_json(Poco::JSON::Object::Ptr &Obj) {
+ try {
+ field_from_json(Obj,"serialNumber",serialNumber);
+ field_from_json(Obj,"author",author);
+ field_from_json(Obj,"reason",reason);
+ field_from_json(Obj,"created",created);
+ return true;
+ } catch (const Poco::Exception &E) {
+ }
+ return false;
+ }
+
+ void ConnectionState::to_json(Poco::JSON::Object &Obj) const {
+ field_to_json(Obj,"serialNumber", SerialNumber);
+ field_to_json(Obj,"ipAddress", Address);
+ field_to_json(Obj,"txBytes", TX);
+ field_to_json(Obj,"rxBytes", RX);
+ field_to_json(Obj,"messageCount", MessageCount);
+ field_to_json(Obj,"UUID", UUID);
+ field_to_json(Obj,"connected", Connected);
+ field_to_json(Obj,"firmware", Firmware);
+ field_to_json(Obj,"lastContact", LastContact);
+ field_to_json(Obj,"associations_2G", Associations_2G);
+ field_to_json(Obj,"associations_5G", Associations_5G);
+ field_to_json(Obj,"webSocketClients", webSocketClients);
+ field_to_json(Obj,"websocketPackets", websocketPackets);
+ field_to_json(Obj,"kafkaClients", kafkaClients);
+ field_to_json(Obj,"kafkaPackets", kafkaPackets);
+
+ switch(VerifiedCertificate) {
+ case NO_CERTIFICATE:
+ field_to_json(Obj,"verifiedCertificate", "NO_CERTIFICATE"); break;
+ case VALID_CERTIFICATE:
+ field_to_json(Obj,"verifiedCertificate", "VALID_CERTIFICATE"); break;
+ case MISMATCH_SERIAL:
+ field_to_json(Obj,"verifiedCertificate", "MISMATCH_SERIAL"); break;
+ case VERIFIED:
+ field_to_json(Obj,"verifiedCertificate", "VERIFIED"); break;
+ default:
+ field_to_json(Obj,"verifiedCertificate", "NO_CERTIFICATE"); break;
+ }
+ }
+
+ void RttySessionDetails::to_json(Poco::JSON::Object &Obj) const {
+ field_to_json(Obj,"serialNumber", SerialNumber);
+ field_to_json(Obj,"server", Server);
+ field_to_json(Obj,"port", Port);
+ field_to_json(Obj,"token",Token);
+ field_to_json(Obj,"timeout", TimeOut);
+ field_to_json(Obj,"connectionId",ConnectionId);
+ field_to_json(Obj,"commandUUID",CommandUUID);
+ field_to_json(Obj,"started", Started);
+ field_to_json(Obj,"viewport",ViewPort);
+ field_to_json(Obj,"password",DevicePassword);
+ }
+
+ void Dashboard::to_json(Poco::JSON::Object &Obj) const {
+ field_to_json(Obj,"commands",commands);
+ field_to_json(Obj,"upTimes",upTimes);
+ field_to_json(Obj,"memoryUsed",memoryUsed);
+ field_to_json(Obj,"load1",load1);
+ field_to_json(Obj,"load5",load5);
+ field_to_json(Obj,"load15",load15);
+ field_to_json(Obj,"vendors",vendors);
+ field_to_json(Obj,"status",status);
+ field_to_json(Obj,"deviceType",deviceType);
+ field_to_json(Obj,"healths",healths);
+ field_to_json(Obj,"certificates",certificates);
+ field_to_json(Obj,"lastContact",lastContact);
+ field_to_json(Obj,"associations",associations);
+ field_to_json(Obj,"snapshot",snapshot);
+ field_to_json(Obj,"numberOfDevices",numberOfDevices);
+ }
+
+ void Dashboard::reset() {
+ commands.clear();
+ upTimes.clear();
+ memoryUsed.clear();
+ load1.clear();
+ load5.clear();
+ load15.clear();
+ vendors.clear();
+ status.clear();
+ deviceType.clear();
+ healths.clear();
+ certificates.clear();
+ lastContact.clear();
+ associations.clear();
+ numberOfDevices = 0 ;
+ snapshot = std::time(nullptr);
+ }
+
+ void CapabilitiesModel::to_json(Poco::JSON::Object &Obj) const{
+ field_to_json(Obj,"deviceType", deviceType);
+ field_to_json(Obj,"capabilities", capabilities);
+ };
+
+}
+
diff --git a/src/RESTObjects/RESTAPI_GWobjects.h b/src/RESTObjects/RESTAPI_GWobjects.h
new file mode 100644
index 0000000..dfc0ca2
--- /dev/null
+++ b/src/RESTObjects/RESTAPI_GWobjects.h
@@ -0,0 +1,197 @@
+//
+// License type: BSD 3-Clause License
+// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
+//
+// Created by Stephane Bourque on 2021-03-04.
+// Arilia Wireless Inc.
+//
+
+#pragma once
+
+#include "Poco/JSON/Object.h"
+#include "RESTAPI_SecurityObjects.h"
+
+namespace OpenWifi::GWObjects {
+
+ enum CertificateValidation {
+ NO_CERTIFICATE,
+ VALID_CERTIFICATE,
+ MISMATCH_SERIAL,
+ VERIFIED
+ };
+
+ struct ConnectionState {
+ uint64_t MessageCount = 0 ;
+ std::string SerialNumber;
+ std::string Address;
+ uint64_t UUID = 0 ;
+ uint64_t PendingUUID = 0 ;
+ uint64_t TX = 0, RX = 0;
+ uint64_t Associations_2G=0;
+ uint64_t Associations_5G=0;
+ bool Connected = false;
+ uint64_t LastContact=0;
+ std::string Firmware;
+ CertificateValidation VerifiedCertificate = NO_CERTIFICATE;
+ std::string Compatible;
+ uint64_t kafkaClients=0;
+ uint64_t webSocketClients=0;
+ uint64_t kafkaPackets=0;
+ uint64_t websocketPackets=0;
+ void to_json(Poco::JSON::Object &Obj) const;
+ };
+
+ struct Device {
+ std::string SerialNumber;
+ std::string DeviceType;
+ std::string MACAddress;
+ std::string Manufacturer;
+ std::string Configuration;
+ SecurityObjects::NoteInfoVec Notes;
+ std::string Owner;
+ std::string Location;
+ std::string Firmware;
+ std::string Compatible;
+ std::string FWUpdatePolicy;
+ uint64_t UUID = 0 ;
+ uint64_t CreationTimestamp = 0 ;
+ uint64_t LastConfigurationChange = 0 ;
+ uint64_t LastConfigurationDownload = 0 ;
+ uint64_t LastFWUpdate = 0 ;
+ std::string Venue;
+ std::string DevicePassword;
+ void to_json(Poco::JSON::Object &Obj) const;
+ void to_json_with_status(Poco::JSON::Object &Obj) const;
+ bool from_json(Poco::JSON::Object::Ptr &Obj);
+ void Print() const;
+ };
+
+ struct Statistics {
+ std::string SerialNumber;
+ uint64_t UUID = 0 ;
+ std::string Data;
+ uint64_t Recorded = 0;
+ void to_json(Poco::JSON::Object &Obj) const;
+ };
+
+ struct HealthCheck {
+ std::string SerialNumber;
+ uint64_t UUID = 0 ;
+ std::string Data;
+ uint64_t Recorded = 0 ;
+ uint64_t Sanity = 0 ;
+ void to_json(Poco::JSON::Object &Obj) const;
+ };
+
+ struct Capabilities {
+ std::string Capabilities;
+ uint64_t FirstUpdate = 0 ;
+ uint64_t LastUpdate = 0 ;
+ void to_json(Poco::JSON::Object &Obj) const;
+ };
+
+ struct DeviceLog {
+ enum Level {
+ LOG_EMERG = 0, /* system is unusable */
+ LOG_ALERT = 1, /* action must be taken immediately */
+ LOG_CRIT = 2, /* critical conditions */
+ LOG_ERR = 3, /* error conditions */
+ LOG_WARNING = 4, /* warning conditions */
+ LOG_NOTICE = 5, /* normal but significant condition */
+ LOG_INFO = 6, /* informational */
+ LOG_DEBUG = 7 /* debug-level messages */
+ };
+ std::string SerialNumber;
+ std::string Log;
+ std::string Data;
+ uint64_t Severity = 0 ;
+ uint64_t Recorded = 0 ;
+ uint64_t LogType = 0 ;
+ uint64_t UUID = 0 ;
+ void to_json(Poco::JSON::Object &Obj) const;
+ };
+
+ struct DefaultConfiguration {
+ std::string Name;
+ std::string Configuration;
+ Types::StringVec Models;
+ std::string Description;
+ uint64_t Created;
+ uint64_t LastModified;
+ void to_json(Poco::JSON::Object &Obj) const;
+ bool from_json(Poco::JSON::Object::Ptr &Obj);
+ };
+
+ struct CommandDetails {
+ std::string UUID;
+ std::string SerialNumber;
+ std::string Command;
+ std::string Status;
+ std::string SubmittedBy;
+ std::string Results;
+ std::string Details;
+ std::string ErrorText;
+ uint64_t Submitted = time(nullptr);
+ uint64_t Executed = 0;
+ uint64_t Completed = 0 ;
+ uint64_t RunAt = 0 ;
+ uint64_t ErrorCode = 0 ;
+ uint64_t Custom = 0 ;
+ uint64_t WaitingForFile = 0 ;
+ uint64_t AttachDate = 0 ;
+ uint64_t AttachSize = 0 ;
+ std::string AttachType;
+ double executionTime = 0.0;
+ void to_json(Poco::JSON::Object &Obj) const;
+ };
+
+ struct BlackListedDevice {
+ std::string serialNumber;
+ std::string reason;
+ std::string author;
+ uint64_t created;
+ void to_json(Poco::JSON::Object &Obj) const;
+ bool from_json(Poco::JSON::Object::Ptr &Obj);
+ };
+
+ struct RttySessionDetails {
+ std::string SerialNumber;
+ std::string Server;
+ uint64_t Port = 0 ;
+ std::string Token;
+ uint64_t TimeOut = 0 ;
+ std::string ConnectionId;
+ uint64_t Started = 0 ;
+ std::string CommandUUID;
+ uint64_t ViewPort = 0 ;
+ std::string DevicePassword;
+ void to_json(Poco::JSON::Object &Obj) const;
+ };
+
+ struct Dashboard {
+ uint64_t snapshot = 0 ;
+ uint64_t numberOfDevices = 0 ;
+ Types::CountedMap commands;
+ Types::CountedMap upTimes;
+ Types::CountedMap memoryUsed;
+ Types::CountedMap load1;
+ Types::CountedMap load5;
+ Types::CountedMap load15;
+ Types::CountedMap vendors;
+ Types::CountedMap status;
+ Types::CountedMap deviceType;
+ Types::CountedMap healths;
+ Types::CountedMap certificates;
+ Types::CountedMap lastContact;
+ Types::CountedMap associations;
+ void to_json(Poco::JSON::Object &Obj) const;
+ void reset();
+ };
+
+ struct CapabilitiesModel {
+ std::string deviceType;
+ std::string capabilities;
+
+ void to_json(Poco::JSON::Object &Obj) const;
+ };
+}
diff --git a/src/RESTObjects/RESTAPI_ProvObjects.cpp b/src/RESTObjects/RESTAPI_ProvObjects.cpp
new file mode 100644
index 0000000..3f76c8f
--- /dev/null
+++ b/src/RESTObjects/RESTAPI_ProvObjects.cpp
@@ -0,0 +1,633 @@
+//
+// License type: BSD 3-Clause License
+// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
+//
+// Created by Stephane Bourque on 2021-03-04.
+// Arilia Wireless Inc.
+//
+
+
+#include "RESTAPI_ProvObjects.h"
+#include "framework/MicroService.h"
+
+using OpenWifi::RESTAPI_utils::field_to_json;
+using OpenWifi::RESTAPI_utils::field_from_json;
+
+namespace OpenWifi::ProvObjects {
+
+ void ObjectInfo::to_json(Poco::JSON::Object &Obj) const {
+ field_to_json(Obj,"id",id);
+ field_to_json(Obj,"name",name);
+ field_to_json(Obj,"description",description);
+ field_to_json(Obj,"created",created);
+ field_to_json(Obj,"modified",modified);
+ field_to_json(Obj,"notes",notes);
+ field_to_json(Obj,"tags",tags);
+ }
+
+ bool ObjectInfo::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,"description",description);
+ field_from_json(Obj,"created",created);
+ field_from_json(Obj,"modified",modified);
+ field_from_json(Obj,"notes",notes);
+ field_from_json(Obj,"tags",tags);
+ return true;
+ } catch(...) {
+
+ }
+ return false;
+ }
+
+ void ManagementPolicyEntry::to_json(Poco::JSON::Object &Obj) const {
+ field_to_json( Obj,"users",users);
+ field_to_json( Obj,"resources",resources);
+ field_to_json( Obj,"access",access);
+ field_to_json( Obj,"policy",policy);
+ }
+
+ bool ManagementPolicyEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
+ try {
+ field_from_json( Obj,"users",users);
+ field_from_json( Obj,"resources",resources);
+ field_from_json( Obj,"access",access);
+ field_from_json( Obj,"policy",policy);
+ return true;
+ } catch(...) {
+
+ }
+ return false;
+ }
+
+ void ManagementPolicy::to_json(Poco::JSON::Object &Obj) const {
+ info.to_json(Obj);
+ field_to_json(Obj, "entries", entries);
+ field_to_json(Obj, "inUse", inUse);
+ field_to_json(Obj, "entity", entity);
+ }
+
+ bool ManagementPolicy::from_json(const Poco::JSON::Object::Ptr &Obj) {
+ try {
+ info.from_json(Obj);
+ field_from_json(Obj, "entries", entries);
+ field_from_json(Obj, "inUse", inUse);
+ field_from_json(Obj, "entity", entity);
+ return true;
+ } catch(...) {
+
+ }
+ return false;
+ }
+
+ void Entity::to_json(Poco::JSON::Object &Obj) const {
+ info.to_json(Obj);
+ field_to_json( Obj,"parent",parent);
+ field_to_json( Obj,"venues",venues);
+ field_to_json( Obj,"children",children);
+ field_to_json( Obj,"contacts",contacts);
+ field_to_json( Obj,"locations",locations);
+ field_to_json( Obj,"managementPolicy",managementPolicy);
+ field_to_json( Obj,"deviceConfiguration",deviceConfiguration);
+ field_to_json( Obj,"devices",devices);
+ field_to_json( Obj,"rrm",rrm);
+ field_to_json( Obj,"sourceIP",sourceIP);
+ }
+
+ bool Entity::from_json(const Poco::JSON::Object::Ptr &Obj) {
+ try {
+ info.from_json(Obj);
+ field_from_json( Obj,"parent",parent);
+ field_from_json( Obj,"venues",venues);
+ field_from_json( Obj,"children",children);
+ field_from_json( Obj,"contacts",contacts);
+ field_from_json( Obj,"locations",locations);
+ field_from_json( Obj,"managementPolicy",managementPolicy);
+ field_from_json( Obj,"deviceConfiguration",deviceConfiguration);
+ field_from_json( Obj,"devices",devices);
+ field_from_json( Obj,"rrm",rrm);
+ field_from_json( Obj,"sourceIP",sourceIP);
+ return true;
+ } catch(...) {
+
+ }
+ return false;
+ }
+
+ void DiGraphEntry::to_json(Poco::JSON::Object &Obj) const {
+ field_to_json( Obj,"parent",parent);
+ field_to_json( Obj,"child",child);
+ }
+
+ bool DiGraphEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
+ try {
+ field_from_json( Obj,"parent",parent);
+ field_from_json( Obj,"child",child);
+ return true;
+ } catch (...) {
+
+ }
+ return false;
+ }
+
+ void Venue::to_json(Poco::JSON::Object &Obj) const {
+ info.to_json(Obj);
+ field_to_json( Obj,"parent",parent);
+ field_to_json( Obj,"entity",entity);
+ field_to_json( Obj,"children",children);
+ field_to_json( Obj,"devices",devices);
+ field_to_json( Obj,"topology",topology);
+ field_to_json( Obj,"parent",parent);
+ field_to_json( Obj,"design",design);
+ field_to_json( Obj,"managementPolicy",managementPolicy);
+ field_to_json( Obj,"deviceConfiguration",deviceConfiguration);
+ field_to_json( Obj,"contact",contact);
+ field_to_json( Obj,"location",location);
+ field_to_json( Obj,"rrm",rrm);
+ field_to_json( Obj,"sourceIP",sourceIP);
+ }
+
+ bool Venue::from_json(const Poco::JSON::Object::Ptr &Obj) {
+ try {
+ info.from_json(Obj);
+ field_from_json( Obj,"parent",parent);
+ field_from_json( Obj,"entity",entity);
+ field_from_json( Obj,"children",children);
+ field_from_json( Obj,"devices",devices);
+ field_from_json( Obj,"topology",topology);
+ field_from_json( Obj,"parent",parent);
+ field_from_json( Obj,"design",design);
+ field_from_json( Obj,"managementPolicy",managementPolicy);
+ field_from_json( Obj,"deviceConfiguration",deviceConfiguration);
+ field_from_json( Obj,"contact",contact);
+ field_from_json( Obj,"location",location);
+ field_from_json( Obj,"rrm",rrm);
+ field_from_json( Obj,"sourceIP",sourceIP);
+ return true;
+ } catch (...) {
+
+ }
+ return false;
+ }
+
+ void UserInfoDigest::to_json(Poco::JSON::Object &Obj) const {
+ field_to_json( Obj,"id",id);
+ field_to_json( Obj,"entity",loginId);
+ field_to_json( Obj,"children",userType);
+ }
+
+ bool UserInfoDigest::from_json(const Poco::JSON::Object::Ptr &Obj) {
+ try {
+ field_from_json( Obj,"id",id);
+ field_from_json( Obj,"entity",loginId);
+ field_from_json( Obj,"children",userType);
+ return true;
+ } catch(...) {
+ }
+ return false;
+ }
+
+ void ManagementRole::to_json(Poco::JSON::Object &Obj) const {
+ info.to_json(Obj);
+ field_to_json( Obj,"managementPolicy",managementPolicy);
+ field_to_json( Obj,"users",users);
+ field_to_json( Obj,"entity",entity);
+ }
+
+ bool ManagementRole::from_json(const Poco::JSON::Object::Ptr &Obj) {
+ try {
+ info.from_json(Obj);
+ field_from_json( Obj,"managementPolicy",managementPolicy);
+ field_from_json( Obj,"users",users);
+ field_from_json( Obj,"entity",entity);
+ return true;
+ } catch(...) {
+ }
+ return false;
+ }
+
+ void Location::to_json(Poco::JSON::Object &Obj) const {
+ info.to_json(Obj);
+ field_to_json( Obj,"type",OpenWifi::ProvObjects::to_string(type));
+ field_to_json( Obj,"buildingName",buildingName);
+ field_to_json( Obj,"addressLines",addressLines);
+ field_to_json( Obj,"city",city);
+ field_to_json( Obj,"state",state);
+ field_to_json( Obj,"postal",postal);
+ field_to_json( Obj,"country",country);
+ field_to_json( Obj,"phones",phones);
+ field_to_json( Obj,"mobiles",mobiles);
+ field_to_json( Obj,"geoCode",geoCode);
+ field_to_json( Obj,"inUse",inUse);
+ field_to_json( Obj,"entity",entity);
+ field_to_json( Obj,"managementPolicy",managementPolicy);
+ }
+
+ bool Location::from_json(const Poco::JSON::Object::Ptr &Obj) {
+ try {
+ info.from_json(Obj);
+ std::string tmp_type;
+ field_from_json( Obj,"type", tmp_type);
+ type = location_from_string(tmp_type);
+ field_from_json( Obj,"buildingName",buildingName);
+ field_from_json( Obj,"addressLines",addressLines);
+ field_from_json( Obj,"city",city);
+ field_from_json( Obj,"state",state);
+ field_from_json( Obj,"postal",postal);
+ field_from_json( Obj,"country",country);
+ field_from_json( Obj,"phones",phones);
+ field_from_json( Obj,"mobiles",mobiles);
+ field_from_json( Obj,"geoCode",geoCode);
+ field_from_json( Obj,"inUse",inUse);
+ field_from_json( Obj,"entity",entity);
+ field_from_json( Obj,"managementPolicy",managementPolicy);
+ return true;
+ } catch (...) {
+
+ }
+ return false;
+ }
+
+ void Contact::to_json(Poco::JSON::Object &Obj) const {
+ info.to_json(Obj);
+ field_to_json( Obj,"type", to_string(type));
+ field_to_json( Obj,"title",title);
+ field_to_json( Obj,"salutation",salutation);
+ field_to_json( Obj,"firstname",firstname);
+ field_to_json( Obj,"lastname",lastname);
+ field_to_json( Obj,"initials",initials);
+ field_to_json( Obj,"visual",visual);
+ field_to_json( Obj,"mobiles",mobiles);
+ field_to_json( Obj,"phones",phones);
+ field_to_json( Obj,"primaryEmail",primaryEmail);
+ field_to_json( Obj,"secondaryEmail",secondaryEmail);
+ field_to_json( Obj,"accessPIN",accessPIN);
+ field_to_json( Obj,"inUse",inUse);
+ field_to_json( Obj,"entity",entity);
+ field_to_json( Obj,"managementPolicy",managementPolicy);
+ }
+
+ bool Contact::from_json(const Poco::JSON::Object::Ptr &Obj) {
+ try {
+ info.from_json(Obj);
+ std::string tmp_type;
+ field_from_json( Obj,"type", tmp_type);
+ type = contact_from_string(tmp_type);
+ field_from_json( Obj,"title",title);
+ field_from_json( Obj,"salutation",salutation);
+ field_from_json( Obj,"firstname",firstname);
+ field_from_json( Obj,"lastname",lastname);
+ field_from_json( Obj,"initials",initials);
+ field_from_json( Obj,"visual",visual);
+ field_from_json( Obj,"mobiles",mobiles);
+ field_from_json( Obj,"phones",phones);
+ field_from_json( Obj,"primaryEmail",primaryEmail);
+ field_from_json( Obj,"secondaryEmail",secondaryEmail);
+ field_from_json( Obj,"accessPIN",accessPIN);
+ field_from_json( Obj,"inUse",inUse);
+ field_from_json( Obj,"entity",entity);
+ field_from_json( Obj,"managementPolicy",managementPolicy);
+ return true;
+ } catch (...) {
+
+ }
+ return false;
+ }
+
+ void InventoryTag::to_json(Poco::JSON::Object &Obj) const {
+ info.to_json(Obj);
+ field_to_json(Obj, "serialNumber", serialNumber);
+ field_to_json(Obj, "venue", venue);
+ field_to_json(Obj, "entity", entity);
+ field_to_json(Obj, "subscriber", subscriber);
+ field_to_json(Obj, "deviceType", deviceType);
+ field_to_json(Obj, "qrCode", qrCode);
+ field_to_json(Obj, "geoCode", geoCode);
+ field_to_json(Obj, "location", location);
+ field_to_json(Obj, "contact", contact);
+ field_to_json( Obj,"deviceConfiguration",deviceConfiguration);
+ field_to_json( Obj,"rrm",rrm);
+ field_to_json( Obj,"managementPolicy",managementPolicy);
+ }
+
+ bool InventoryTag::from_json(const Poco::JSON::Object::Ptr &Obj) {
+ try {
+ info.from_json(Obj);
+ field_from_json( Obj,"serialNumber",serialNumber);
+ field_from_json( Obj,"venue",venue);
+ field_from_json( Obj,"entity",entity);
+ field_from_json( Obj,"subscriber",subscriber);
+ field_from_json( Obj,"deviceType",deviceType);
+ field_from_json(Obj, "qrCode", qrCode);
+ field_from_json( Obj,"geoCode",geoCode);
+ field_from_json( Obj,"location",location);
+ field_from_json( Obj,"contact",contact);
+ field_from_json( Obj,"deviceConfiguration",deviceConfiguration);
+ field_from_json( Obj,"rrm",rrm);
+ field_from_json( Obj,"managementPolicy",managementPolicy);
+ return true;
+ } catch(...) {
+
+ }
+ return false;
+ }
+
+ void DeviceConfigurationElement::to_json(Poco::JSON::Object &Obj) const {
+ field_to_json( Obj,"name", name);
+ field_to_json( Obj,"description", description);
+ field_to_json( Obj,"weight", weight);
+ field_to_json( Obj,"configuration", configuration);
+ }
+
+ bool DeviceConfigurationElement::from_json(const Poco::JSON::Object::Ptr &Obj) {
+ try {
+ field_from_json( Obj,"name",name);
+ field_from_json( Obj,"description",description);
+ field_from_json( Obj,"weight",weight);
+ field_from_json( Obj,"configuration",configuration);
+ return true;
+ } catch(...) {
+
+ }
+ return false;
+ }
+
+ void DeviceConfiguration::to_json(Poco::JSON::Object &Obj) const {
+ info.to_json(Obj);
+ field_to_json( Obj,"managementPolicy",managementPolicy);
+ field_to_json( Obj,"deviceTypes",deviceTypes);
+ field_to_json( Obj,"configuration",configuration);
+ field_to_json( Obj,"inUse",inUse);
+ field_to_json( Obj,"variables",variables);
+ field_to_json( Obj,"rrm",rrm);
+ field_to_json( Obj,"firmwareUpgrade",firmwareUpgrade);
+ field_to_json( Obj,"firmwareRCOnly",firmwareRCOnly);
+ }
+
+ bool DeviceConfiguration::from_json(const Poco::JSON::Object::Ptr &Obj) {
+ try {
+ info.from_json(Obj);
+ field_from_json( Obj,"managementPolicy",managementPolicy);
+ field_from_json( Obj,"deviceTypes",deviceTypes);
+ field_from_json( Obj,"configuration",configuration);
+ field_from_json( Obj,"inUse",inUse);
+ field_from_json( Obj,"variables",variables);
+ field_from_json( Obj,"rrm",rrm);
+ field_from_json( Obj,"firmwareUpgrade",firmwareUpgrade);
+ field_from_json( Obj,"firmwareRCOnly",firmwareRCOnly);
+ return true;
+ } catch(...) {
+
+ }
+ return false;
+ }
+
+ void Report::to_json(Poco::JSON::Object &Obj) const {
+ field_to_json(Obj, "snapshot", snapShot);
+ field_to_json(Obj, "devices", tenants);
+ };
+
+ void Report::reset() {
+ tenants.clear();
+ }
+
+ void ExpandedUseEntry::to_json(Poco::JSON::Object &Obj) const {
+ field_to_json(Obj, "uuid", uuid);
+ field_to_json(Obj, "name", name);
+ field_to_json(Obj, "description", description);
+ }
+
+ bool ExpandedUseEntry::from_json(const Poco::JSON::Object::Ptr &Obj) {
+ try {
+ field_from_json( Obj,"uuid",uuid);
+ field_from_json( Obj,"name",name);
+ field_from_json( Obj,"description",description);
+ return true;
+ } catch(...) {
+
+ }
+ return false;
+ }
+
+ void ExpandedUseEntryList::to_json(Poco::JSON::Object &Obj) const {
+ field_to_json(Obj, "type", type);
+ field_to_json(Obj, "entries", entries);
+ }
+
+ bool ExpandedUseEntryList::from_json(const Poco::JSON::Object::Ptr &Obj) {
+ try {
+ field_from_json( Obj,"type",type);
+ field_from_json( Obj,"entries",entries);
+ return true;
+ } catch(...) {
+
+ }
+ return false;
+ }
+
+ void ExpandedUseEntryMapList::to_json(Poco::JSON::Object &Obj) const {
+ field_to_json(Obj, "entries", entries);
+ }
+
+ bool ExpandedUseEntryMapList::from_json(const Poco::JSON::Object::Ptr &Obj) {
+ try {
+ field_from_json( Obj,"entries",entries);
+ return true;
+ } catch(...) {
+
+ }
+ return false;
+ }
+
+ void UuidList::to_json(Poco::JSON::Object &Obj) const {
+ field_to_json(Obj, "list", list);
+ }
+
+ bool UuidList::from_json(const Poco::JSON::Object::Ptr &Obj) {
+ try {
+ field_from_json(Obj, "list", list);
+ return true;
+ } catch(...) {
+
+ }
+ return false;
+ }
+
+ void field_to_json(Poco::JSON::Object &Obj, const char * FieldName, ACLACCESS A) {
+ switch(A) {
+ case READ: Obj.set(FieldName,"read"); break;
+ case MODIFY: Obj.set(FieldName,"modify"); break;
+ case CREATE: Obj.set(FieldName,"create"); break;
+ case DELETE: Obj.set(FieldName,"delete"); break;
+ case NONE:
+ default:
+ Obj.set(FieldName,"none");
+ }
+ }
+
+ void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char * FieldName, ACLACCESS &A) {
+ if(Obj->has(FieldName)) {
+ auto V = Obj->getValue(FieldName);
+ if(V=="read")
+ A = READ;
+ else if(V=="modify")
+ A = MODIFY;
+ else if(V=="create")
+ A = CREATE;
+ else if(V=="delete")
+ A = DELETE;
+ else if(V=="none")
+ A = NONE;
+ else
+ throw Poco::Exception("invalid JSON");
+ }
+ }
+
+ void ObjectACL::to_json(Poco::JSON::Object &Obj) const {
+ RESTAPI_utils::field_to_json(Obj, "users", users);
+ RESTAPI_utils::field_to_json(Obj, "roles", roles);
+ field_to_json(Obj, "access", access);
+ }
+
+ bool ObjectACL::from_json(const Poco::JSON::Object::Ptr &Obj) {
+ try {
+ RESTAPI_utils::field_from_json(Obj, "users", users);
+ RESTAPI_utils::field_from_json(Obj, "roles", roles);
+ field_from_json(Obj, "access", access);
+ return true;
+ } catch(...) {
+
+ }
+ return false;
+ }
+
+ void ObjectACLList::to_json(Poco::JSON::Object &Obj) const {
+ RESTAPI_utils::field_to_json(Obj, "list", list);
+ }
+
+ bool ObjectACLList::from_json(const Poco::JSON::Object::Ptr &Obj) {
+ try {
+ RESTAPI_utils::field_from_json(Obj, "list", list);
+ return true;
+ } catch(...) {
+
+ }
+ return false;
+ }
+
+ std::string to_string(VISIBILITY A) {
+ switch(A) {
+ case PUBLIC: return "public";
+ case SELECT: return "select";
+ case PRIVATE:
+ default:
+ return "private";
+ }
+ }
+
+ void field_to_json(Poco::JSON::Object &Obj, const char * FieldName, VISIBILITY A) {
+ Obj.set(FieldName,to_string(A));
+ }
+
+ VISIBILITY visibility_from_string(const std::string &V) {
+ if(V=="public")
+ return PUBLIC;
+ else if(V=="select")
+ return SELECT;
+ else if(V=="private")
+ return PRIVATE;
+ throw Poco::Exception("invalid json");
+ }
+
+ void field_from_json(const Poco::JSON::Object::Ptr &Obj, const char * FieldName, VISIBILITY &A) {
+ if(Obj->has(FieldName)) {
+ auto V = Obj->getValue(FieldName);
+ A = visibility_from_string(V);
+ }
+ }
+
+ void Map::to_json(Poco::JSON::Object &Obj) const {
+ info.to_json(Obj);
+ RESTAPI_utils::field_to_json( Obj,"data",data);
+ RESTAPI_utils::field_to_json( Obj,"entity",entity);
+ RESTAPI_utils::field_to_json( Obj,"creator",creator);
+ field_to_json( Obj,"visibility",visibility);
+ RESTAPI_utils::field_to_json( Obj,"access",access);
+ }
+
+ bool Map::from_json(const Poco::JSON::Object::Ptr &Obj) {
+ try {
+ info.from_json(Obj);
+ RESTAPI_utils::field_from_json( Obj,"data",data);
+ RESTAPI_utils::field_from_json( Obj,"entity",entity);
+ RESTAPI_utils::field_from_json( Obj,"creator",creator);
+ field_from_json( Obj,"visibility",visibility);
+ RESTAPI_utils::field_from_json( Obj,"access",access);
+ return true;
+ } catch(...) {
+
+ }
+ return false;
+ }
+
+ void MapList::to_json(Poco::JSON::Object &Obj) const {
+ RESTAPI_utils::field_to_json( Obj,"list",list);
+ }
+
+ bool MapList::from_json(const Poco::JSON::Object::Ptr &Obj) {
+ try {
+ RESTAPI_utils::field_from_json( Obj,"list",list);
+ return true;
+ } catch(...) {
+
+ }
+ return false;
+ }
+
+ bool UpdateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I) {
+ uint64_t Now = std::time(nullptr);
+ if(O->has("name"))
+ I.name = O->get("name").toString();
+
+ if(I.name.empty())
+ return false;
+
+ if(O->has("description"))
+ I.description = O->get("description").toString();
+ SecurityObjects::MergeNotes(O,U,I.notes);
+ SecurityObjects::NoteInfoVec N;
+ for(auto &i:I.notes) {
+ if(i.note.empty())
+ continue;
+ N.push_back(SecurityObjects::NoteInfo{.created=Now,.createdBy=U.email,.note=i.note});
+ }
+ I.modified = Now;
+ return true;
+ }
+
+ bool CreateObjectInfo(const Poco::JSON::Object::Ptr &O, const SecurityObjects::UserInfo &U, ObjectInfo &I) {
+ uint64_t Now = std::time(nullptr);
+ if(O->has("name"))
+ I.name = O->get("name").toString();
+
+ if(I.name.empty())
+ return false;
+
+ if(O->has("description"))
+ I.description = O->get("description").toString();
+
+ SecurityObjects::NoteInfoVec N;
+ for(auto &i:I.notes) {
+ if(i.note.empty())
+ continue;
+ N.push_back(SecurityObjects::NoteInfo{.created=Now,.createdBy=U.email,.note=i.note});
+ }
+ I.notes = N;
+ I.modified = I.created = Now;
+ I.id = MicroService::CreateUUID();
+
+ return true;
+ }
+}
+
diff --git a/src/RESTObjects/RESTAPI_ProvObjects.h b/src/RESTObjects/RESTAPI_ProvObjects.h
new file mode 100644
index 0000000..6ac9b4f
--- /dev/null
+++ b/src/RESTObjects/RESTAPI_ProvObjects.h
@@ -0,0 +1,380 @@
+//
+// License type: BSD 3-Clause License
+// License copy: https://github.com/Telecominfraproject/wlan-cloud-ucentralgw/blob/master/LICENSE
+//
+// Created by Stephane Bourque on 2021-03-04.
+// Arilia Wireless Inc.
+//
+
+#pragma once
+
+#include
+#include "RESTAPI_SecurityObjects.h"
+
+namespace OpenWifi::ProvObjects {
+
+ enum FIRMWARE_UPGRADE_RULES {
+ dont_upgrade,
+ upgrade_inherit,
+ upgrade_release_only,
+ upgrade_latest
+ };
+
+ struct ObjectInfo {
+ Types::UUID_t id;
+ std::string name;
+ std::string description;
+ SecurityObjects::NoteInfoVec notes;
+ uint64_t created=0;
+ uint64_t modified=0;
+ Types::TagList tags;
+
+ void to_json(Poco::JSON::Object &Obj) const;
+ bool from_json(const Poco::JSON::Object::Ptr &Obj);
+ };
+
+ struct ManagementPolicyEntry {
+ Types::UUIDvec_t users;
+ Types::UUIDvec_t resources;
+ Types::StringVec access;
+ std::string policy;
+
+ void to_json(Poco::JSON::Object &Obj) const;
+ bool from_json(const Poco::JSON::Object::Ptr &Obj);
+ };
+
+ struct ManagementPolicy {
+ ObjectInfo info;
+ std::vector entries;
+ Types::StringVec inUse;
+ Types::UUID_t entity;
+
+ void to_json(Poco::JSON::Object &Obj) const;
+ bool from_json(const Poco::JSON::Object::Ptr &Obj);
+ };
+ typedef std::vector ManagementPolicyVec;
+
+ struct Entity {
+ ObjectInfo info;
+ Types::UUID_t parent;
+ Types::UUIDvec_t children;
+ Types::UUIDvec_t venues;
+ Types::UUIDvec_t contacts; // all contacts associated in this entity
+ Types::UUIDvec_t locations; // all locations associated in this entity
+ Types::UUID_t managementPolicy;
+ Types::UUIDvec_t deviceConfiguration;
+ Types::UUIDvec_t devices;
+ std::string rrm;
+ Types::StringVec sourceIP;
+
+ void to_json(Poco::JSON::Object &Obj) const;
+ bool from_json(const Poco::JSON::Object::Ptr &Obj);
+ };
+ typedef std::vector EntityVec;
+
+ struct DiGraphEntry {
+ Types::UUID_t parent;
+ Types::UUID_t child;
+
+ void to_json(Poco::JSON::Object &Obj) const;
+ bool from_json(const Poco::JSON::Object::Ptr &Obj);
+ };
+
+ typedef std::vector DiGraph;
+
+ struct Venue {
+ ObjectInfo info;
+ Types::UUID_t entity;
+ Types::UUID_t parent;
+ Types::UUIDvec_t children;
+ Types::UUID_t managementPolicy;
+ Types::UUIDvec_t devices;
+ DiGraph topology;
+ std::string design;
+ Types::UUIDvec_t deviceConfiguration;
+ std::string contact;
+ std::string location;
+ std::string rrm;
+ Types::StringVec sourceIP;
+
+ void to_json(Poco::JSON::Object &Obj) const;
+ bool from_json(const Poco::JSON::Object::Ptr &Obj);
+ };
+ typedef std::vector VenueVec;
+
+ struct UserInfoDigest {
+ std::string id;
+ std::string loginId;
+ std::string userType;
+
+ void to_json(Poco::JSON::Object &Obj) const;
+ bool from_json(const Poco::JSON::Object::Ptr &Obj);
+ };
+
+ struct ManagementRole {
+ ObjectInfo info;
+ Types::UUID_t managementPolicy;
+ Types::UUIDvec_t users;
+ Types::StringVec inUse;
+ Types::UUID_t entity;
+
+ void to_json(Poco::JSON::Object &Obj) const;
+ bool from_json(const Poco::JSON::Object::Ptr &Obj);
+ };
+ typedef std::vector ManagementRoleVec;
+
+ enum LocationType {
+ LT_SERVICE, LT_EQUIPMENT, LT_AUTO, LT_MANUAL,
+ LT_SPECIAL, LT_UNKNOWN, LT_CORPORATE
+ };
+
+ inline std::string to_string(LocationType L) {
+ switch(L) {
+ case LT_SERVICE: return "SERVICE";
+ case LT_EQUIPMENT: return "EQUIPMENT";
+ case LT_AUTO: return "AUTO";
+ case LT_MANUAL: return "MANUAL";
+ case LT_SPECIAL: return "SPECIAL";
+ case LT_UNKNOWN: return "UNKNOWN";
+ case LT_CORPORATE: return "CORPORATE";
+ default: return "UNKNOWN";
+ }
+ }
+
+ inline LocationType location_from_string(const std::string &S) {
+ if(!Poco::icompare(S,"SERVICE"))
+ return LT_SERVICE;
+ else if(!Poco::icompare(S,"EQUIPMENT"))
+ return LT_EQUIPMENT;
+ else if(!Poco::icompare(S,"AUTO"))
+ return LT_AUTO;
+ else if(!Poco::icompare(S,"MANUAL"))
+ return LT_MANUAL;
+ else if(!Poco::icompare(S,"SPECIAL"))
+ return LT_SPECIAL;
+ else if(!Poco::icompare(S,"UNKNOWN"))
+ return LT_UNKNOWN;
+ else if(!Poco::icompare(S,"CORPORATE"))
+ return LT_CORPORATE;
+ return LT_UNKNOWN;
+ }
+
+ struct Location {
+ ObjectInfo info;
+ LocationType type;
+ std::string buildingName;
+ Types::StringVec addressLines;
+ std::string city;
+ std::string state;
+ std::string postal;
+ std::string country;
+ Types::StringVec phones;
+ Types::StringVec mobiles;
+ std::string geoCode;
+ Types::StringVec inUse;
+ Types::UUID_t entity;
+ Types::UUID_t managementPolicy;
+
+ void to_json(Poco::JSON::Object &Obj) const;
+ bool from_json(const Poco::JSON::Object::Ptr &Obj);
+ };
+ typedef std::vector LocationVec;
+
+ enum ContactType {
+ CT_SUBSCRIBER, CT_USER, CT_INSTALLER, CT_CSR, CT_MANAGER,
+ CT_BUSINESSOWNER, CT_TECHNICIAN, CT_CORPORATE, CT_UNKNOWN
+ };
+
+ inline std::string to_string(ContactType L) {
+ switch(L) {
+ case CT_SUBSCRIBER: return "SUBSCRIBER";
+ case CT_USER: return "USER";
+ case CT_INSTALLER: return "INSTALLER";
+ case CT_CSR: return "CSR";
+ case CT_MANAGER: return "MANAGER";
+ case CT_BUSINESSOWNER: return "BUSINESSOWNER";
+ case CT_TECHNICIAN: return "TECHNICIAN";
+ case CT_CORPORATE: return "CORPORATE";
+ case CT_UNKNOWN: return "UNKNOWN";
+ default: return "UNKNOWN";
+ }
+ }
+
+ inline ContactType contact_from_string(const std::string &S) {
+ if(!Poco::icompare(S,"SUBSCRIBER"))
+ return CT_SUBSCRIBER;
+ else if(!Poco::icompare(S,"USER"))
+ return CT_USER;
+ else if(!Poco::icompare(S,"INSTALLER"))
+ return CT_INSTALLER;
+ else if(!Poco::icompare(S,"CSR"))
+ return CT_CSR;
+ else if(!Poco::icompare(S,"BUSINESSOWNER"))
+ return CT_BUSINESSOWNER;
+ else if(!Poco::icompare(S,"TECHNICIAN"))
+ return CT_TECHNICIAN;
+ else if(!Poco::icompare(S,"CORPORATE"))
+ return CT_CORPORATE;
+ else if(!Poco::icompare(S,"UNKNOWN"))
+ return CT_UNKNOWN;
+ return CT_UNKNOWN;
+ }
+
+ struct Contact {
+ ObjectInfo info;
+ ContactType type=CT_USER;
+ std::string title;
+ std::string salutation;
+ std::string firstname;
+ std::string lastname;
+ std::string initials;
+ std::string visual;
+ Types::StringVec mobiles;
+ Types::StringVec phones;
+ std::string primaryEmail;
+ std::string secondaryEmail;
+ std::string accessPIN;
+ Types::StringVec inUse;
+ Types::UUID_t entity;
+ Types::UUID_t managementPolicy;
+
+ void to_json(Poco::JSON::Object &Obj) const;
+ bool from_json(const Poco::JSON::Object::Ptr &Obj);
+ };
+ typedef std::vector ContactVec;
+
+ struct DeviceConfigurationElement {
+ std::string name;
+ std::string description;
+ uint64_t weight;
+ std::string configuration;
+
+ void to_json(Poco::JSON::Object &Obj) const;
+ bool from_json(const Poco::JSON::Object::Ptr &Obj);
+ };
+ typedef std::vector DeviceConfigurationElementVec;
+
+ struct DeviceConfiguration {
+ ObjectInfo info;
+ Types::UUID_t managementPolicy;
+ Types::StringVec deviceTypes;
+ DeviceConfigurationElementVec configuration;
+ Types::StringVec inUse;
+ Types::StringPairVec variables;
+ std::string rrm;
+ std::string firmwareUpgrade;
+ bool firmwareRCOnly=false;
+
+ void to_json(Poco::JSON::Object &Obj) const;
+ bool from_json(const Poco::JSON::Object::Ptr &Obj);
+ };
+ typedef std::vector DeviceConfigurationVec;
+
+ struct InventoryTag {
+ ObjectInfo info;
+ std::string serialNumber;
+ std::string venue;
+ std::string entity;
+ std::string subscriber;
+ std::string deviceType;
+ std::string qrCode;
+ std::string geoCode;
+ std::string location;
+ std::string contact;
+ std::string deviceConfiguration;
+ std::string rrm;
+ Types::UUID_t managementPolicy;
+
+ void to_json(Poco::JSON::Object &Obj) const;
+ bool from_json(const Poco::JSON::Object::Ptr &Obj);
+ };
+ typedef std::vector InventoryTagVec;
+
+ struct Report {
+ uint64_t snapShot=0;
+ Types::CountedMap tenants;
+
+ void reset();
+ void to_json(Poco::JSON::Object &Obj) const;
+ };
+
+ struct ExpandedUseEntry {
+ std::string uuid;
+ std::string name;
+ std::string description;
+
+ void to_json(Poco::JSON::Object &Obj) const;
+ bool from_json(const Poco::JSON::Object::Ptr &Obj);
+ };
+
+ struct ExpandedUseEntryList {
+ std::string type;
+ std::vector entries;
+
+ void to_json(Poco::JSON::Object &Obj) const;
+ bool from_json(const Poco::JSON::Object::Ptr &Obj);
+ };
+
+ struct ExpandedUseEntryMapList {
+ std::vector entries;
+
+ void to_json(Poco::JSON::Object &Obj) const;
+ bool from_json(const Poco::JSON::Object::Ptr &Obj);
+ };
+
+ struct UuidList {
+ std::vector list;
+
+ void to_json(Poco::JSON::Object &Obj) const;
+ bool from_json(const Poco::JSON::Object::Ptr &Obj);
+ };
+
+ enum ACLACCESS {
+ NONE, READ, MODIFY, CREATE, DELETE
+ };
+
+ struct ObjectACL {
+ UuidList users;
+ UuidList roles;
+ ACLACCESS access = NONE;
+
+ void to_json(Poco::JSON::Object &Obj) const;
+ bool from_json(const Poco::JSON::Object::Ptr &Obj);
+ };
+
+ struct ObjectACLList {
+ std::vector list;
+
+ void to_json(Poco::JSON::Object &Obj) const;
+ bool from_json(const Poco::JSON::Object::Ptr &Obj);
+ };
+
+ enum VISIBILITY {
+ PUBLIC, PRIVATE, SELECT
+ };
+
+ std::string to_string(VISIBILITY A);
+ VISIBILITY visibility_from_string(const std::string &V);
+
+ struct Map {
+ ObjectInfo info;
+ std::string data;
+ std::string entity;
+ std::string creator;
+ VISIBILITY visibility = PRIVATE;
+ ObjectACLList access;
+
+ void to_json(Poco::JSON::Object &Obj) const;
+ bool from_json(const Poco::JSON::Object::Ptr &Obj);
+ };
+
+ struct MapList {
+ std::vector